Auto merge of #122735 - matthiaskrgr:rollup-pgb1s90, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #122435 (Don't trigger `unused_qualifications` on global paths) - #122556 (Extend format arg help for simple tuple index access expression) - #122634 (compiletest: Add support for `//@ aux-bin: foo.rs`) - #122677 (Fix incorrect mutable suggestion information for binding in ref pattern.) - #122691 (Fix ICE: `global_asm!()` Don't Panic When Unable to Evaluate Constant) - #122695 (Change only_local to a enum type.) - #122717 (Ensure stack before parsing dot-or-call) - #122719 (Ensure nested statics have a HIR node to prevent various queries from ICEing) - #122720 ([doc]:fix error code example) - #122724 (add test for casting pointer to union with unsized tail) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e760daa6a7
@ -55,7 +55,7 @@ pub(super) fn index_hir<'hir>(
|
||||
OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
|
||||
OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
|
||||
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
|
||||
OwnerNode::AssocOpaqueTy(..) => unreachable!(),
|
||||
OwnerNode::Synthetic => unreachable!(),
|
||||
};
|
||||
|
||||
for (local_id, node) in collector.nodes.iter_enumerated() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
|
||||
use core::ops::ControlFlow;
|
||||
use hir::ExprKind;
|
||||
use hir::{ExprKind, Param};
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
@ -725,25 +725,26 @@ fn construct_mut_suggestion_for_local_binding_patterns(
|
||||
_ => local_decl.source_info.span,
|
||||
};
|
||||
|
||||
let def_id = self.body.source.def_id();
|
||||
let hir_id = if let Some(local_def_id) = def_id.as_local()
|
||||
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
|
||||
{
|
||||
let body = self.infcx.tcx.hir().body(body_id);
|
||||
BindingFinder { span: pat_span }.visit_body(body).break_value()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// With ref-binding patterns, the mutability suggestion has to apply to
|
||||
// the binding, not the reference (which would be a type error):
|
||||
//
|
||||
// `let &b = a;` -> `let &(mut b) = a;`
|
||||
if let Some(hir_id) = hir_id
|
||||
// or
|
||||
// `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)`
|
||||
let def_id = self.body.source.def_id();
|
||||
if let Some(local_def_id) = def_id.as_local()
|
||||
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
|
||||
&& let body = self.infcx.tcx.hir().body(body_id)
|
||||
&& let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(body).break_value()
|
||||
&& let node = self.infcx.tcx.hir_node(hir_id)
|
||||
&& let hir::Node::Local(hir::Local {
|
||||
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
|
||||
..
|
||||
}) = self.infcx.tcx.hir_node(hir_id)
|
||||
})
|
||||
| hir::Node::Param(Param {
|
||||
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
|
||||
..
|
||||
}) = node
|
||||
&& let Ok(name) =
|
||||
self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
|
||||
{
|
||||
@ -1310,6 +1311,16 @@ fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) -> Self::Result {
|
||||
hir::intravisit::walk_stmt(self, s)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) -> Self::Result {
|
||||
if let hir::Pat { kind: hir::PatKind::Ref(_, _), span, .. } = param.pat
|
||||
&& *span == self.span
|
||||
{
|
||||
ControlFlow::Break(param.hir_id)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
|
||||
|
@ -2,6 +2,7 @@
|
||||
use crate::common;
|
||||
use crate::traits::*;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_middle::mir::mono::{Linkage, Visibility};
|
||||
use rustc_middle::ty;
|
||||
@ -40,23 +41,34 @@ fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) {
|
||||
.iter()
|
||||
.map(|(op, op_sp)| match *op {
|
||||
hir::InlineAsmOperand::Const { ref anon_const } => {
|
||||
let const_value = cx
|
||||
.tcx()
|
||||
.const_eval_poly(anon_const.def_id.to_def_id())
|
||||
.unwrap_or_else(|_| {
|
||||
span_bug!(*op_sp, "asm const cannot be resolved")
|
||||
});
|
||||
let ty = cx
|
||||
.tcx()
|
||||
.typeck_body(anon_const.body)
|
||||
.node_type(anon_const.hir_id);
|
||||
let string = common::asm_const_to_str(
|
||||
cx.tcx(),
|
||||
*op_sp,
|
||||
const_value,
|
||||
cx.layout_of(ty),
|
||||
);
|
||||
GlobalAsmOperandRef::Const { string }
|
||||
match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) {
|
||||
Ok(const_value) => {
|
||||
let ty = cx
|
||||
.tcx()
|
||||
.typeck_body(anon_const.body)
|
||||
.node_type(anon_const.hir_id);
|
||||
let string = common::asm_const_to_str(
|
||||
cx.tcx(),
|
||||
*op_sp,
|
||||
const_value,
|
||||
cx.layout_of(ty),
|
||||
);
|
||||
GlobalAsmOperandRef::Const { string }
|
||||
}
|
||||
Err(ErrorHandled::Reported { .. }) => {
|
||||
// An error has already been reported and
|
||||
// compilation is guaranteed to fail if execution
|
||||
// hits this path. So an empty string instead of
|
||||
// a stringified constant value will suffice.
|
||||
GlobalAsmOperandRef::Const { string: String::new() }
|
||||
}
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
span_bug!(
|
||||
*op_sp,
|
||||
"asm const cannot be resolved; too generic"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::InlineAsmOperand::SymFn { ref anon_const } => {
|
||||
let ty = cx
|
||||
|
@ -111,6 +111,8 @@ fn intern_as_new_static<'tcx>(
|
||||
feed.generics_of(tcx.generics_of(static_id).clone());
|
||||
feed.def_ident_span(tcx.def_ident_span(static_id));
|
||||
feed.explicit_predicates_of(tcx.explicit_predicates_of(static_id));
|
||||
|
||||
feed.feed_hir()
|
||||
}
|
||||
|
||||
/// How a constant value should be interned.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -124,7 +124,7 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZero<u
|
||||
pub use accepted::ACCEPTED_FEATURES;
|
||||
pub use builtin_attrs::AttributeDuplicates;
|
||||
pub use builtin_attrs::{
|
||||
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
|
||||
deprecated_attributes, encode_cross_crate, find_gated_cfg, is_builtin_attr_name,
|
||||
is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute,
|
||||
GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
|
||||
};
|
||||
|
@ -2552,11 +2552,6 @@ pub struct OpaqueTy<'hir> {
|
||||
pub in_trait: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||
pub struct AssocOpaqueTy {
|
||||
// Add some data if necessary
|
||||
}
|
||||
|
||||
/// From whence the opaque type came.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
|
||||
pub enum OpaqueTyOrigin {
|
||||
@ -3367,7 +3362,7 @@ pub enum OwnerNode<'hir> {
|
||||
TraitItem(&'hir TraitItem<'hir>),
|
||||
ImplItem(&'hir ImplItem<'hir>),
|
||||
Crate(&'hir Mod<'hir>),
|
||||
AssocOpaqueTy(&'hir AssocOpaqueTy),
|
||||
Synthetic,
|
||||
}
|
||||
|
||||
impl<'hir> OwnerNode<'hir> {
|
||||
@ -3377,7 +3372,7 @@ pub fn ident(&self) -> Option<Ident> {
|
||||
| OwnerNode::ForeignItem(ForeignItem { ident, .. })
|
||||
| OwnerNode::ImplItem(ImplItem { ident, .. })
|
||||
| OwnerNode::TraitItem(TraitItem { ident, .. }) => Some(*ident),
|
||||
OwnerNode::Crate(..) | OwnerNode::AssocOpaqueTy(..) => None,
|
||||
OwnerNode::Crate(..) | OwnerNode::Synthetic => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3390,7 +3385,7 @@ pub fn span(&self) -> &'hir Span {
|
||||
| OwnerNode::ImplItem(ImplItem { span, .. })
|
||||
| OwnerNode::TraitItem(TraitItem { span, .. }) => span,
|
||||
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => inner_span,
|
||||
OwnerNode::AssocOpaqueTy(..) => unreachable!(),
|
||||
OwnerNode::Synthetic => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -3449,7 +3444,7 @@ pub fn def_id(self) -> OwnerId {
|
||||
| OwnerNode::ImplItem(ImplItem { owner_id, .. })
|
||||
| OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
|
||||
OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
|
||||
OwnerNode::AssocOpaqueTy(..) => unreachable!(),
|
||||
OwnerNode::Synthetic => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -3493,7 +3488,7 @@ fn into(self) -> Node<'hir> {
|
||||
OwnerNode::ImplItem(n) => Node::ImplItem(n),
|
||||
OwnerNode::TraitItem(n) => Node::TraitItem(n),
|
||||
OwnerNode::Crate(n) => Node::Crate(n),
|
||||
OwnerNode::AssocOpaqueTy(n) => Node::AssocOpaqueTy(n),
|
||||
OwnerNode::Synthetic => Node::Synthetic,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3531,7 +3526,8 @@ pub enum Node<'hir> {
|
||||
WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
|
||||
// FIXME: Merge into `Node::Infer`.
|
||||
ArrayLenInfer(&'hir InferArg),
|
||||
AssocOpaqueTy(&'hir AssocOpaqueTy),
|
||||
// Created by query feeding
|
||||
Synthetic,
|
||||
// Span by reference to minimize `Node`'s size
|
||||
#[allow(rustc::pass_by_value)]
|
||||
Err(&'hir Span),
|
||||
@ -3582,7 +3578,7 @@ pub fn ident(&self) -> Option<Ident> {
|
||||
| Node::Infer(..)
|
||||
| Node::WhereBoundPredicate(..)
|
||||
| Node::ArrayLenInfer(..)
|
||||
| Node::AssocOpaqueTy(..)
|
||||
| Node::Synthetic
|
||||
| Node::Err(..) => None,
|
||||
}
|
||||
}
|
||||
@ -3695,7 +3691,7 @@ pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
|
||||
Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
|
||||
Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
|
||||
Node::Crate(i) => Some(OwnerNode::Crate(i)),
|
||||
Node::AssocOpaqueTy(i) => Some(OwnerNode::AssocOpaqueTy(i)),
|
||||
Node::Synthetic => Some(OwnerNode::Synthetic),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorG
|
||||
hir::OwnerNode::TraitItem(item) => check_trait_item(tcx, item),
|
||||
hir::OwnerNode::ImplItem(item) => check_impl_item(tcx, item),
|
||||
hir::OwnerNode::ForeignItem(item) => check_foreign_item(tcx, item),
|
||||
hir::OwnerNode::AssocOpaqueTy(..) => unreachable!(),
|
||||
hir::OwnerNode::Synthetic => unreachable!(),
|
||||
};
|
||||
|
||||
if let Some(generics) = node.generics() {
|
||||
|
@ -262,7 +262,7 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
|
||||
visitor.visit_impl_item(item)
|
||||
}
|
||||
hir::OwnerNode::Crate(_) => {}
|
||||
hir::OwnerNode::AssocOpaqueTy(..) => unreachable!(),
|
||||
hir::OwnerNode::Synthetic => unreachable!(),
|
||||
}
|
||||
|
||||
let mut rl = ResolveBoundVars::default();
|
||||
|
@ -121,7 +121,7 @@ fn print_node(&mut self, node: Node<'_>) {
|
||||
self.print_bounds(":", pred.bounds);
|
||||
}
|
||||
Node::ArrayLenInfer(_) => self.word("_"),
|
||||
Node::AssocOpaqueTy(..) => unreachable!(),
|
||||
Node::Synthetic => unreachable!(),
|
||||
Node::Err(_) => self.word("/*ERROR*/"),
|
||||
}
|
||||
}
|
||||
|
@ -2553,7 +2553,7 @@ fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) {
|
||||
hir::OwnerNode::ImplItem(i) => visitor.visit_impl_item(i),
|
||||
hir::OwnerNode::TraitItem(i) => visitor.visit_trait_item(i),
|
||||
hir::OwnerNode::Crate(_) => bug!("OwnerNode::Crate doesn't not have generics"),
|
||||
hir::OwnerNode::AssocOpaqueTy(..) => unreachable!(),
|
||||
hir::OwnerNode::Synthetic => unreachable!(),
|
||||
}
|
||||
|
||||
let ast_generics = self.tcx.hir().get_generics(lifetime_scope).unwrap();
|
||||
|
@ -191,7 +191,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
|
||||
levels.add_id(hir::CRATE_HIR_ID);
|
||||
levels.visit_mod(mod_, mod_.spans.inner_span, hir::CRATE_HIR_ID)
|
||||
}
|
||||
hir::OwnerNode::AssocOpaqueTy(..) => unreachable!(),
|
||||
hir::OwnerNode::Synthetic => unreachable!(),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -817,8 +817,8 @@ struct AnalyzeAttrState {
|
||||
#[inline]
|
||||
fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState) -> bool {
|
||||
let mut should_encode = false;
|
||||
if rustc_feature::is_builtin_only_local(attr.name_or_empty()) {
|
||||
// Attributes marked local-only don't need to be encoded for downstream crates.
|
||||
if !rustc_feature::encode_cross_crate(attr.name_or_empty()) {
|
||||
// Attributes not marked encode-cross-crate don't need to be encoded for downstream crates.
|
||||
} else if attr.doc_str().is_some() {
|
||||
// We keep all doc comments reachable to rustdoc because they might be "imported" into
|
||||
// downstream crates if they use `#[doc(inline)]` to copy an item's documentation into
|
||||
|
@ -914,7 +914,7 @@ pub fn span_with_body(self, hir_id: HirId) -> Span {
|
||||
Node::Crate(item) => item.spans.inner_span,
|
||||
Node::WhereBoundPredicate(pred) => pred.span,
|
||||
Node::ArrayLenInfer(inf) => inf.span,
|
||||
Node::AssocOpaqueTy(..) => unreachable!(),
|
||||
Node::Synthetic => unreachable!(),
|
||||
Node::Err(span) => *span,
|
||||
}
|
||||
}
|
||||
@ -1179,7 +1179,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
||||
Node::Crate(..) => String::from("(root_crate)"),
|
||||
Node::WhereBoundPredicate(_) => node_str("where bound predicate"),
|
||||
Node::ArrayLenInfer(_) => node_str("array len infer"),
|
||||
Node::AssocOpaqueTy(..) => unreachable!(),
|
||||
Node::Synthetic => unreachable!(),
|
||||
Node::Err(_) => node_str("error"),
|
||||
}
|
||||
}
|
||||
|
@ -596,6 +596,27 @@ pub fn def_id(&self) -> LocalDefId {
|
||||
pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
|
||||
TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
|
||||
}
|
||||
|
||||
// Fills in all the important parts needed by HIR queries
|
||||
pub fn feed_hir(&self) {
|
||||
self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
|
||||
|
||||
let node = hir::OwnerNode::Synthetic;
|
||||
let bodies = Default::default();
|
||||
let attrs = hir::AttributeMap::EMPTY;
|
||||
|
||||
let (opt_hash_including_bodies, _) = self.tcx.hash_owner_nodes(node, &bodies, &attrs.map);
|
||||
let node = node.into();
|
||||
self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
|
||||
opt_hash_including_bodies,
|
||||
nodes: IndexVec::from_elem_n(
|
||||
hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
|
||||
1,
|
||||
),
|
||||
bodies,
|
||||
})));
|
||||
self.feed_owner_id().hir_attrs(attrs);
|
||||
}
|
||||
}
|
||||
|
||||
/// The central data structure of the compiler. It stores references
|
||||
|
@ -1752,9 +1752,8 @@ pub fn get_attrs(
|
||||
let filter_fn = move |a: &&ast::Attribute| a.has_name(attr);
|
||||
if let Some(did) = did.as_local() {
|
||||
self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
|
||||
} else if cfg!(debug_assertions) && rustc_feature::is_builtin_only_local(attr) {
|
||||
bug!("tried to access the `only_local` attribute `{}` from an extern crate", attr);
|
||||
} else {
|
||||
debug_assert!(rustc_feature::encode_cross_crate(attr));
|
||||
self.item_attrs(did).iter().filter(filter_fn)
|
||||
}
|
||||
}
|
||||
@ -1786,12 +1785,7 @@ pub fn get_attr(self, did: impl Into<DefId>, attr: Symbol) -> Option<&'tcx ast::
|
||||
|
||||
/// Determines whether an item is annotated with an attribute.
|
||||
pub fn has_attr(self, did: impl Into<DefId>, attr: Symbol) -> bool {
|
||||
let did: DefId = did.into();
|
||||
if cfg!(debug_assertions) && !did.is_local() && rustc_feature::is_builtin_only_local(attr) {
|
||||
bug!("tried to access the `only_local` attribute `{}` from an extern crate", attr);
|
||||
} else {
|
||||
self.get_attrs(did, attr).next().is_some()
|
||||
}
|
||||
self.get_attrs(did, attr).next().is_some()
|
||||
}
|
||||
|
||||
/// Returns `true` if this is an `auto trait`.
|
||||
|
@ -943,7 +943,10 @@ pub(super) fn parse_expr_dot_or_call_with(
|
||||
// Stitch the list of outer attributes onto the return value.
|
||||
// A little bit ugly, but the best way given the current code
|
||||
// structure
|
||||
let res = self.parse_expr_dot_or_call_with_(e0, lo);
|
||||
let res = ensure_sufficient_stack(
|
||||
// this expr demonstrates the recursion it guards against
|
||||
|| self.parse_expr_dot_or_call_with_(e0, lo),
|
||||
);
|
||||
if attrs.is_empty() {
|
||||
res
|
||||
} else {
|
||||
|
@ -907,25 +907,47 @@ fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>)
|
||||
let byte_pos = self.to_span_index(end);
|
||||
let start = InnerOffset(byte_pos.0 + 1);
|
||||
let field = self.argument(start);
|
||||
// We can only parse `foo.bar` field access, any deeper nesting,
|
||||
// or another type of expression, like method calls, are not supported
|
||||
// We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any
|
||||
// deeper nesting, or another type of expression, like method calls, are not supported
|
||||
if !self.consume('}') {
|
||||
return;
|
||||
}
|
||||
if let ArgumentNamed(_) = arg.position {
|
||||
if let ArgumentNamed(_) = field.position {
|
||||
self.errors.insert(
|
||||
0,
|
||||
ParseError {
|
||||
description: "field access isn't supported".to_string(),
|
||||
note: None,
|
||||
label: "not supported".to_string(),
|
||||
span: InnerSpan::new(arg.position_span.start, field.position_span.end),
|
||||
secondary_label: None,
|
||||
suggestion: Suggestion::UsePositional,
|
||||
},
|
||||
);
|
||||
}
|
||||
match field.position {
|
||||
ArgumentNamed(_) => {
|
||||
self.errors.insert(
|
||||
0,
|
||||
ParseError {
|
||||
description: "field access isn't supported".to_string(),
|
||||
note: None,
|
||||
label: "not supported".to_string(),
|
||||
span: InnerSpan::new(
|
||||
arg.position_span.start,
|
||||
field.position_span.end,
|
||||
),
|
||||
secondary_label: None,
|
||||
suggestion: Suggestion::UsePositional,
|
||||
},
|
||||
);
|
||||
}
|
||||
ArgumentIs(_) => {
|
||||
self.errors.insert(
|
||||
0,
|
||||
ParseError {
|
||||
description: "tuple index access isn't supported".to_string(),
|
||||
note: None,
|
||||
label: "not supported".to_string(),
|
||||
span: InnerSpan::new(
|
||||
arg.position_span.start,
|
||||
field.position_span.end,
|
||||
),
|
||||
secondary_label: None,
|
||||
suggestion: Suggestion::UsePositional,
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
|
||||
| Node::Field(_)
|
||||
| Node::Ty(_)
|
||||
| Node::Crate(_)
|
||||
| Node::AssocOpaqueTy(..) => {}
|
||||
| Node::Synthetic => {}
|
||||
_ => {
|
||||
bug!(
|
||||
"found unexpected node kind in worklist: {} ({:?})",
|
||||
|
@ -4665,6 +4665,13 @@ fn resolve_doc_links(&mut self, attrs: &[Attribute], maybe_exported: MaybeExport
|
||||
}
|
||||
|
||||
fn lint_unused_qualifications(&mut self, path: &[Segment], ns: Namespace, finalize: Finalize) {
|
||||
// Don't lint on global paths because the user explicitly wrote out the full path.
|
||||
if let Some(seg) = path.first()
|
||||
&& seg.ident.name == kw::PathRoot
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if path.iter().any(|seg| seg.ident.span.from_expansion()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{self as hir, HirId};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt, TyCtxtFeed};
|
||||
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
|
||||
use rustc_span::symbol::kw;
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
@ -238,28 +237,6 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn feed_hir(feed: &TyCtxtFeed<'_, LocalDefId>) {
|
||||
feed.local_def_id_to_hir_id(HirId::make_owner(feed.def_id()));
|
||||
|
||||
let node = hir::OwnerNode::AssocOpaqueTy(&hir::AssocOpaqueTy {});
|
||||
let bodies = Default::default();
|
||||
let attrs = hir::AttributeMap::EMPTY;
|
||||
|
||||
let (opt_hash_including_bodies, _) = feed.tcx.hash_owner_nodes(node, &bodies, &attrs.map);
|
||||
feed.opt_hir_owner_nodes(Some(feed.tcx.arena.alloc(hir::OwnerNodes {
|
||||
opt_hash_including_bodies,
|
||||
nodes: IndexVec::from_elem_n(
|
||||
hir::ParentedNode {
|
||||
parent: hir::ItemLocalId::INVALID,
|
||||
node: hir::Node::AssocOpaqueTy(&hir::AssocOpaqueTy {}),
|
||||
},
|
||||
1,
|
||||
),
|
||||
bodies,
|
||||
})));
|
||||
feed.feed_owner_id().hir_attrs(attrs);
|
||||
}
|
||||
|
||||
/// Given an `opaque_ty_def_id` corresponding to an `impl Trait` in an associated
|
||||
/// function from a trait, synthesize an associated type for that `impl Trait`
|
||||
/// that inherits properties that we infer from the method and the opaque type.
|
||||
@ -281,7 +258,7 @@ fn associated_type_for_impl_trait_in_trait(
|
||||
let local_def_id = trait_assoc_ty.def_id();
|
||||
let def_id = local_def_id.to_def_id();
|
||||
|
||||
feed_hir(&trait_assoc_ty);
|
||||
trait_assoc_ty.feed_hir();
|
||||
|
||||
// Copy span of the opaque.
|
||||
trait_assoc_ty.def_ident_span(Some(span));
|
||||
@ -335,7 +312,7 @@ fn associated_type_for_impl_trait_in_impl(
|
||||
let local_def_id = impl_assoc_ty.def_id();
|
||||
let def_id = local_def_id.to_def_id();
|
||||
|
||||
feed_hir(&impl_assoc_ty);
|
||||
impl_assoc_ty.feed_hir();
|
||||
|
||||
// Copy span of the opaque.
|
||||
impl_assoc_ty.def_ident_span(Some(span));
|
||||
|
@ -1337,7 +1337,7 @@ impl<T> SizedTypeProperties for T {}
|
||||
/// type B = Wrapper<u8, i8>;
|
||||
///
|
||||
/// // Not necessarily identical even though `u8` and `i8` have the same layout!
|
||||
/// // assert!(mem::offset_of!(A, 1), mem::offset_of!(B, 1));
|
||||
/// // assert_eq!(mem::offset_of!(A, 1), mem::offset_of!(B, 1));
|
||||
///
|
||||
/// #[repr(transparent)]
|
||||
/// struct U8(u8);
|
||||
@ -1345,12 +1345,12 @@ impl<T> SizedTypeProperties for T {}
|
||||
/// type C = Wrapper<u8, U8>;
|
||||
///
|
||||
/// // Not necessarily identical even though `u8` and `U8` have the same layout!
|
||||
/// // assert!(mem::offset_of!(A, 1), mem::offset_of!(C, 1));
|
||||
/// // assert_eq!(mem::offset_of!(A, 1), mem::offset_of!(C, 1));
|
||||
///
|
||||
/// struct Empty<T>(core::marker::PhantomData<T>);
|
||||
///
|
||||
/// // Not necessarily identical even though `PhantomData` always has the same layout!
|
||||
/// // assert!(mem::offset_of!(Empty<u8>, 0), mem::offset_of!(Empty<i8>, 0));
|
||||
/// // assert_eq!(mem::offset_of!(Empty<u8>, 0), mem::offset_of!(Empty<i8>, 0));
|
||||
/// ```
|
||||
///
|
||||
/// [explicit `repr` attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations
|
||||
|
@ -36,6 +36,7 @@ pub fn load(config: &Config) -> Self {
|
||||
#[derive(Default)]
|
||||
pub struct EarlyProps {
|
||||
pub aux: Vec<String>,
|
||||
pub aux_bin: Vec<String>,
|
||||
pub aux_crate: Vec<(String, String)>,
|
||||
pub revisions: Vec<String>,
|
||||
}
|
||||
@ -59,6 +60,12 @@ pub fn from_reader<R: Read>(config: &Config, testfile: &Path, rdr: R) -> Self {
|
||||
config.push_name_value_directive(ln, directives::AUX_BUILD, &mut props.aux, |r| {
|
||||
r.trim().to_string()
|
||||
});
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
directives::AUX_BIN,
|
||||
&mut props.aux_bin,
|
||||
|r| r.trim().to_string(),
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
directives::AUX_CRATE,
|
||||
@ -95,6 +102,8 @@ pub struct TestProps {
|
||||
// directory as the test, but for backwards compatibility reasons
|
||||
// we also check the auxiliary directory)
|
||||
pub aux_builds: Vec<String>,
|
||||
// Auxiliary crates that should be compiled as `#![crate_type = "bin"]`.
|
||||
pub aux_bins: Vec<String>,
|
||||
// Similar to `aux_builds`, but a list of NAME=somelib.rs of dependencies
|
||||
// to build and pass with the `--extern` flag.
|
||||
pub aux_crates: Vec<(String, String)>,
|
||||
@ -217,6 +226,7 @@ mod directives {
|
||||
pub const PRETTY_EXPANDED: &'static str = "pretty-expanded";
|
||||
pub const PRETTY_MODE: &'static str = "pretty-mode";
|
||||
pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only";
|
||||
pub const AUX_BIN: &'static str = "aux-bin";
|
||||
pub const AUX_BUILD: &'static str = "aux-build";
|
||||
pub const AUX_CRATE: &'static str = "aux-crate";
|
||||
pub const EXEC_ENV: &'static str = "exec-env";
|
||||
@ -252,6 +262,7 @@ pub fn new() -> Self {
|
||||
run_flags: None,
|
||||
pp_exact: None,
|
||||
aux_builds: vec![],
|
||||
aux_bins: vec![],
|
||||
aux_crates: vec![],
|
||||
revisions: vec![],
|
||||
rustc_env: vec![("RUSTC_ICE".to_string(), "0".to_string())],
|
||||
@ -417,6 +428,9 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
config.push_name_value_directive(ln, AUX_BUILD, &mut self.aux_builds, |r| {
|
||||
r.trim().to_string()
|
||||
});
|
||||
config.push_name_value_directive(ln, AUX_BIN, &mut self.aux_bins, |r| {
|
||||
r.trim().to_string()
|
||||
});
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
AUX_CRATE,
|
||||
@ -683,6 +697,7 @@ pub fn line_directive<'line>(
|
||||
const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
"assembly-output",
|
||||
"aux-bin",
|
||||
"aux-build",
|
||||
"aux-crate",
|
||||
"build-aux-docs",
|
||||
|
@ -82,21 +82,21 @@ fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
|
||||
}
|
||||
|
||||
/// The platform-specific library name
|
||||
pub fn get_lib_name(lib: &str, dylib: bool) -> String {
|
||||
// In some casess (e.g. MUSL), we build a static
|
||||
// library, rather than a dynamic library.
|
||||
// In this case, the only path we can pass
|
||||
// with '--extern-meta' is the '.lib' file
|
||||
if !dylib {
|
||||
return format!("lib{}.rlib", lib);
|
||||
}
|
||||
|
||||
if cfg!(windows) {
|
||||
format!("{}.dll", lib)
|
||||
} else if cfg!(target_os = "macos") {
|
||||
format!("lib{}.dylib", lib)
|
||||
} else {
|
||||
format!("lib{}.so", lib)
|
||||
fn get_lib_name(lib: &str, aux_type: AuxType) -> Option<String> {
|
||||
match aux_type {
|
||||
AuxType::Bin => None,
|
||||
// In some cases (e.g. MUSL), we build a static
|
||||
// library, rather than a dynamic library.
|
||||
// In this case, the only path we can pass
|
||||
// with '--extern-meta' is the '.rlib' file
|
||||
AuxType::Lib => Some(format!("lib{}.rlib", lib)),
|
||||
AuxType::Dylib => Some(if cfg!(windows) {
|
||||
format!("{}.dll", lib)
|
||||
} else if cfg!(target_os = "macos") {
|
||||
format!("lib{}.dylib", lib)
|
||||
} else {
|
||||
format!("lib{}.so", lib)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -2098,19 +2098,36 @@ fn aux_output_dir(&self) -> PathBuf {
|
||||
create_dir_all(&aux_dir).unwrap();
|
||||
}
|
||||
|
||||
if !self.props.aux_bins.is_empty() {
|
||||
let aux_bin_dir = self.aux_bin_output_dir_name();
|
||||
let _ = fs::remove_dir_all(&aux_bin_dir);
|
||||
create_dir_all(&aux_bin_dir).unwrap();
|
||||
}
|
||||
|
||||
aux_dir
|
||||
}
|
||||
|
||||
fn build_all_auxiliary(&self, of: &TestPaths, aux_dir: &Path, rustc: &mut Command) {
|
||||
for rel_ab in &self.props.aux_builds {
|
||||
self.build_auxiliary(of, rel_ab, &aux_dir);
|
||||
self.build_auxiliary(of, rel_ab, &aux_dir, false /* is_bin */);
|
||||
}
|
||||
|
||||
for rel_ab in &self.props.aux_bins {
|
||||
self.build_auxiliary(of, rel_ab, &aux_dir, true /* is_bin */);
|
||||
}
|
||||
|
||||
for (aux_name, aux_path) in &self.props.aux_crates {
|
||||
let is_dylib = self.build_auxiliary(of, &aux_path, &aux_dir);
|
||||
let aux_type = self.build_auxiliary(of, &aux_path, &aux_dir, false /* is_bin */);
|
||||
let lib_name =
|
||||
get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), is_dylib);
|
||||
rustc.arg("--extern").arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name));
|
||||
get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), aux_type);
|
||||
if let Some(lib_name) = lib_name {
|
||||
rustc.arg("--extern").arg(format!(
|
||||
"{}={}/{}",
|
||||
aux_name,
|
||||
aux_dir.display(),
|
||||
lib_name
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2129,12 +2146,23 @@ fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) ->
|
||||
}
|
||||
|
||||
/// Builds an aux dependency.
|
||||
///
|
||||
/// Returns whether or not it is a dylib.
|
||||
fn build_auxiliary(&self, of: &TestPaths, source_path: &str, aux_dir: &Path) -> bool {
|
||||
fn build_auxiliary(
|
||||
&self,
|
||||
of: &TestPaths,
|
||||
source_path: &str,
|
||||
aux_dir: &Path,
|
||||
is_bin: bool,
|
||||
) -> AuxType {
|
||||
let aux_testpaths = self.compute_aux_test_paths(of, source_path);
|
||||
let aux_props = self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
|
||||
let aux_output = TargetLocation::ThisDirectory(aux_dir.to_path_buf());
|
||||
let mut aux_dir = aux_dir.to_path_buf();
|
||||
if is_bin {
|
||||
// On unix, the binary of `auxiliary/foo.rs` will be named
|
||||
// `auxiliary/foo` which clashes with the _dir_ `auxiliary/foo`, so
|
||||
// put bins in a `bin` subfolder.
|
||||
aux_dir.push("bin");
|
||||
}
|
||||
let aux_output = TargetLocation::ThisDirectory(aux_dir.clone());
|
||||
let aux_cx = TestCx {
|
||||
config: self.config,
|
||||
props: &aux_props,
|
||||
@ -2152,15 +2180,17 @@ fn build_auxiliary(&self, of: &TestPaths, source_path: &str, aux_dir: &Path) ->
|
||||
LinkToAux::No,
|
||||
Vec::new(),
|
||||
);
|
||||
aux_cx.build_all_auxiliary(of, aux_dir, &mut aux_rustc);
|
||||
aux_cx.build_all_auxiliary(of, &aux_dir, &mut aux_rustc);
|
||||
|
||||
for key in &aux_props.unset_rustc_env {
|
||||
aux_rustc.env_remove(key);
|
||||
}
|
||||
aux_rustc.envs(aux_props.rustc_env.clone());
|
||||
|
||||
let (dylib, crate_type) = if aux_props.no_prefer_dynamic {
|
||||
(true, None)
|
||||
let (aux_type, crate_type) = if is_bin {
|
||||
(AuxType::Bin, Some("bin"))
|
||||
} else if aux_props.no_prefer_dynamic {
|
||||
(AuxType::Dylib, None)
|
||||
} else if self.config.target.contains("emscripten")
|
||||
|| (self.config.target.contains("musl")
|
||||
&& !aux_props.force_host
|
||||
@ -2185,9 +2215,9 @@ fn build_auxiliary(&self, of: &TestPaths, source_path: &str, aux_dir: &Path) ->
|
||||
// Coverage tests want static linking by default so that coverage
|
||||
// mappings in auxiliary libraries can be merged into the final
|
||||
// executable.
|
||||
(false, Some("lib"))
|
||||
(AuxType::Lib, Some("lib"))
|
||||
} else {
|
||||
(true, Some("dylib"))
|
||||
(AuxType::Dylib, Some("dylib"))
|
||||
};
|
||||
|
||||
if let Some(crate_type) = crate_type {
|
||||
@ -2211,7 +2241,7 @@ fn build_auxiliary(&self, of: &TestPaths, source_path: &str, aux_dir: &Path) ->
|
||||
&auxres,
|
||||
);
|
||||
}
|
||||
dylib
|
||||
aux_type
|
||||
}
|
||||
|
||||
fn read2_abbreviated(&self, child: Child) -> (Output, Truncated) {
|
||||
@ -2677,6 +2707,12 @@ fn aux_output_dir_name(&self) -> PathBuf {
|
||||
.with_extra_extension(self.config.mode.aux_dir_disambiguator())
|
||||
}
|
||||
|
||||
/// Gets the directory where auxiliary binaries are written.
|
||||
/// E.g., `/.../testname.revision.mode/auxiliary/bin`.
|
||||
fn aux_bin_output_dir_name(&self) -> PathBuf {
|
||||
self.aux_output_dir_name().join("bin")
|
||||
}
|
||||
|
||||
/// Generates a unique name for the test, such as `testname.revision.mode`.
|
||||
fn output_testname_unique(&self) -> PathBuf {
|
||||
output_testname_unique(self.config, self.testpaths, self.safe_revision())
|
||||
@ -4826,3 +4862,9 @@ enum LinkToAux {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
enum AuxType {
|
||||
Bin,
|
||||
Lib,
|
||||
Dylib,
|
||||
}
|
||||
|
@ -3463,7 +3463,6 @@
|
||||
"ui/pattern/issue-106552.rs",
|
||||
"ui/pattern/issue-106862.rs",
|
||||
"ui/pattern/issue-110508.rs",
|
||||
"ui/pattern/issue-114896.rs",
|
||||
"ui/pattern/issue-115599.rs",
|
||||
"ui/pattern/issue-11577.rs",
|
||||
"ui/pattern/issue-117626.rs",
|
||||
|
11
tests/ui/asm/fail-const-eval-issue-121099.rs
Normal file
11
tests/ui/asm/fail-const-eval-issue-121099.rs
Normal file
@ -0,0 +1,11 @@
|
||||
//@ build-fail
|
||||
//@ needs-asm-support
|
||||
#![feature(asm_const)]
|
||||
|
||||
use std::arch::global_asm;
|
||||
|
||||
fn main() {}
|
||||
|
||||
global_asm!("/* {} */", const 1 << 500); //~ ERROR evaluation of constant value failed [E0080]
|
||||
|
||||
global_asm!("/* {} */", const 1 / 0); //~ ERROR evaluation of constant value failed [E0080]
|
15
tests/ui/asm/fail-const-eval-issue-121099.stderr
Normal file
15
tests/ui/asm/fail-const-eval-issue-121099.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/fail-const-eval-issue-121099.rs:9:31
|
||||
|
|
||||
LL | global_asm!("/* {} */", const 1 << 500);
|
||||
| ^^^^^^^^ attempt to shift left by `500_i32`, which would overflow
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/fail-const-eval-issue-121099.rs:11:31
|
||||
|
|
||||
LL | global_asm!("/* {} */", const 1 / 0);
|
||||
| ^^^^^ attempt to divide `1_i32` by zero
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
14
tests/ui/cast/unsized-union-ice.rs
Normal file
14
tests/ui/cast/unsized-union-ice.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/122581
|
||||
// This used to ICE, because the union was unsized and the pointer casting code
|
||||
// assumed that non-struct ADTs must be sized.
|
||||
|
||||
union Union {
|
||||
val: std::mem::ManuallyDrop<[u8]>,
|
||||
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
}
|
||||
|
||||
fn cast(ptr: *const ()) -> *const Union {
|
||||
ptr as _
|
||||
}
|
||||
|
||||
fn main() {}
|
23
tests/ui/cast/unsized-union-ice.stderr
Normal file
23
tests/ui/cast/unsized-union-ice.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/unsized-union-ice.rs:6:10
|
||||
|
|
||||
LL | val: std::mem::ManuallyDrop<[u8]>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `ManuallyDrop<[u8]>`, the trait `Sized` is not implemented for `[u8]`, which is required by `ManuallyDrop<[u8]>: Sized`
|
||||
note: required because it appears within the type `ManuallyDrop<[u8]>`
|
||||
--> $SRC_DIR/core/src/mem/manually_drop.rs:LL:COL
|
||||
= note: no field of a union may have a dynamically sized type
|
||||
= help: change the field's type to have a statically known size
|
||||
help: borrowed types always have a statically known size
|
||||
|
|
||||
LL | val: &std::mem::ManuallyDrop<[u8]>,
|
||||
| +
|
||||
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
||||
|
|
||||
LL | val: Box<std::mem::ManuallyDrop<[u8]>>,
|
||||
| ++++ +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
println!("it works");
|
||||
}
|
9
tests/ui/compiletest-self-test/test-aux-bin.rs
Normal file
9
tests/ui/compiletest-self-test/test-aux-bin.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//@ ignore-cross-compile because we run the compiled code
|
||||
//@ aux-bin: print-it-works.rs
|
||||
//@ run-pass
|
||||
|
||||
fn main() {
|
||||
let stdout =
|
||||
std::process::Command::new("auxiliary/bin/print-it-works").output().unwrap().stdout;
|
||||
assert_eq!(stdout, b"it works\n");
|
||||
}
|
10
tests/ui/fmt/format-args-non-identifier-diagnostics.fixed
Normal file
10
tests/ui/fmt/format-args-non-identifier-diagnostics.fixed
Normal file
@ -0,0 +1,10 @@
|
||||
// Checks that there is a suggestion for simple tuple index access expression (used where an
|
||||
// identifier is expected in a format arg) to use positional arg instead.
|
||||
// Issue: <https://github.com/rust-lang/rust/issues/122535>.
|
||||
//@ run-rustfix
|
||||
|
||||
fn main() {
|
||||
let x = (1,);
|
||||
println!("{0}", x.0);
|
||||
//~^ ERROR invalid format string
|
||||
}
|
10
tests/ui/fmt/format-args-non-identifier-diagnostics.rs
Normal file
10
tests/ui/fmt/format-args-non-identifier-diagnostics.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// Checks that there is a suggestion for simple tuple index access expression (used where an
|
||||
// identifier is expected in a format arg) to use positional arg instead.
|
||||
// Issue: <https://github.com/rust-lang/rust/issues/122535>.
|
||||
//@ run-rustfix
|
||||
|
||||
fn main() {
|
||||
let x = (1,);
|
||||
println!("{x.0}");
|
||||
//~^ ERROR invalid format string
|
||||
}
|
13
tests/ui/fmt/format-args-non-identifier-diagnostics.stderr
Normal file
13
tests/ui/fmt/format-args-non-identifier-diagnostics.stderr
Normal file
@ -0,0 +1,13 @@
|
||||
error: invalid format string: tuple index access isn't supported
|
||||
--> $DIR/format-args-non-identifier-diagnostics.rs:8:16
|
||||
|
|
||||
LL | println!("{x.0}");
|
||||
| ^^^ not supported in format string
|
||||
|
|
||||
help: consider using a positional formatting argument instead
|
||||
|
|
||||
LL | println!("{0}", x.0);
|
||||
| ~ +++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -16,7 +16,6 @@ fn main() {
|
||||
let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
|
||||
|
||||
let _ = String::new(); //~ ERROR: unnecessary qualification
|
||||
let _ = std::env::current_dir(); //~ ERROR: unnecessary qualification
|
||||
|
||||
let _: Vec<String> = Vec::<String>::new();
|
||||
//~^ ERROR: unnecessary qualification
|
||||
@ -27,7 +26,7 @@ fn main() {
|
||||
let _: std::fmt::Result = Ok(());
|
||||
// don't report unnecessary qualification because fix(#122373) for issue #121331
|
||||
|
||||
let _ = <bool as Default>::default(); // issue #121999
|
||||
let _ = <bool as Default>::default(); // issue #121999 (modified)
|
||||
//~^ ERROR: unnecessary qualification
|
||||
|
||||
macro_rules! m { ($a:ident, $b:ident) => {
|
||||
|
@ -16,7 +16,6 @@ fn main() {
|
||||
let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
|
||||
|
||||
let _ = std::string::String::new(); //~ ERROR: unnecessary qualification
|
||||
let _ = ::std::env::current_dir(); //~ ERROR: unnecessary qualification
|
||||
|
||||
let _: std::vec::Vec<String> = std::vec::Vec::<String>::new();
|
||||
//~^ ERROR: unnecessary qualification
|
||||
@ -27,7 +26,7 @@ fn main() {
|
||||
let _: std::fmt::Result = Ok(());
|
||||
// don't report unnecessary qualification because fix(#122373) for issue #121331
|
||||
|
||||
let _ = <bool as ::std::default::Default>::default(); // issue #121999
|
||||
let _ = <bool as std::default::Default>::default(); // issue #121999 (modified)
|
||||
//~^ ERROR: unnecessary qualification
|
||||
|
||||
macro_rules! m { ($a:ident, $b:ident) => {
|
||||
|
@ -40,19 +40,7 @@ LL + let _ = String::new();
|
||||
|
|
||||
|
||||
error: unnecessary qualification
|
||||
--> $DIR/lint-qualification.rs:19:13
|
||||
|
|
||||
LL | let _ = ::std::env::current_dir();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the unnecessary path segments
|
||||
|
|
||||
LL - let _ = ::std::env::current_dir();
|
||||
LL + let _ = std::env::current_dir();
|
||||
|
|
||||
|
||||
error: unnecessary qualification
|
||||
--> $DIR/lint-qualification.rs:21:12
|
||||
--> $DIR/lint-qualification.rs:20:12
|
||||
|
|
||||
LL | let _: std::vec::Vec<String> = std::vec::Vec::<String>::new();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -64,7 +52,7 @@ LL + let _: Vec<String> = std::vec::Vec::<String>::new();
|
||||
|
|
||||
|
||||
error: unnecessary qualification
|
||||
--> $DIR/lint-qualification.rs:21:36
|
||||
--> $DIR/lint-qualification.rs:20:36
|
||||
|
|
||||
LL | let _: std::vec::Vec<String> = std::vec::Vec::<String>::new();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -76,7 +64,7 @@ LL + let _: std::vec::Vec<String> = Vec::<String>::new();
|
||||
|
|
||||
|
||||
error: unused import: `std::fmt`
|
||||
--> $DIR/lint-qualification.rs:25:9
|
||||
--> $DIR/lint-qualification.rs:24:9
|
||||
|
|
||||
LL | use std::fmt;
|
||||
| ^^^^^^^^
|
||||
@ -88,16 +76,16 @@ LL | #![deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: unnecessary qualification
|
||||
--> $DIR/lint-qualification.rs:30:13
|
||||
--> $DIR/lint-qualification.rs:29:13
|
||||
|
|
||||
LL | let _ = <bool as ::std::default::Default>::default(); // issue #121999
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | let _ = <bool as std::default::Default>::default(); // issue #121999 (modified)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the unnecessary path segments
|
||||
|
|
||||
LL - let _ = <bool as ::std::default::Default>::default(); // issue #121999
|
||||
LL + let _ = <bool as Default>::default(); // issue #121999
|
||||
LL - let _ = <bool as std::default::Default>::default(); // issue #121999 (modified)
|
||||
LL + let _ = <bool as Default>::default(); // issue #121999 (modified)
|
||||
|
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
12
tests/ui/lint/unused-qualifications-global-paths.rs
Normal file
12
tests/ui/lint/unused-qualifications-global-paths.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// Checks that `unused_qualifications` don't fire on explicit global paths.
|
||||
// Issue: <https://github.com/rust-lang/rust/issues/122374>.
|
||||
|
||||
//@ check-pass
|
||||
|
||||
#![deny(unused_qualifications)]
|
||||
|
||||
pub fn bar() -> u64 {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
fn main() {}
|
4907
tests/ui/parser/survive-peano-lesson-queue.rs
Normal file
4907
tests/ui/parser/survive-peano-lesson-queue.rs
Normal file
File diff suppressed because one or more lines are too long
10
tests/ui/pattern/patkind-ref-binding-issue-114896.fixed
Normal file
10
tests/ui/pattern/patkind-ref-binding-issue-114896.fixed
Normal file
@ -0,0 +1,10 @@
|
||||
//@ run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn main() {
|
||||
fn x(a: &char) {
|
||||
let &(mut b) = a;
|
||||
b.make_ascii_uppercase();
|
||||
//~^ cannot borrow `b` as mutable, as it is not declared as mutable
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
//@ run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn main() {
|
||||
fn x(a: &char) {
|
||||
let &b = a;
|
@ -1,5 +1,5 @@
|
||||
error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable
|
||||
--> $DIR/issue-114896.rs:4:9
|
||||
--> $DIR/patkind-ref-binding-issue-114896.rs:7:9
|
||||
|
|
||||
LL | let &b = a;
|
||||
| -- help: consider changing this to be mutable: `&(mut b)`
|
11
tests/ui/pattern/patkind-ref-binding-issue-122415.fixed
Normal file
11
tests/ui/pattern/patkind-ref-binding-issue-122415.fixed
Normal file
@ -0,0 +1,11 @@
|
||||
//@ run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn mutate(_y: &mut i32) {}
|
||||
|
||||
fn foo(&(mut x): &i32) {
|
||||
mutate(&mut x);
|
||||
//~^ ERROR cannot borrow `x` as mutable
|
||||
}
|
||||
|
||||
fn main() {}
|
11
tests/ui/pattern/patkind-ref-binding-issue-122415.rs
Normal file
11
tests/ui/pattern/patkind-ref-binding-issue-122415.rs
Normal file
@ -0,0 +1,11 @@
|
||||
//@ run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn mutate(_y: &mut i32) {}
|
||||
|
||||
fn foo(&x: &i32) {
|
||||
mutate(&mut x);
|
||||
//~^ ERROR cannot borrow `x` as mutable
|
||||
}
|
||||
|
||||
fn main() {}
|
11
tests/ui/pattern/patkind-ref-binding-issue-122415.stderr
Normal file
11
tests/ui/pattern/patkind-ref-binding-issue-122415.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
|
||||
--> $DIR/patkind-ref-binding-issue-122415.rs:7:12
|
||||
|
|
||||
LL | fn foo(&x: &i32) {
|
||||
| -- help: consider changing this to be mutable: `&(mut x)`
|
||||
LL | mutate(&mut x);
|
||||
| ^^^^^^ cannot borrow as mutable
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0596`.
|
Loading…
Reference in New Issue
Block a user