diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index acd7eb69ffc37..e47c434454602 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -209,7 +209,7 @@ impl<'a> AstValidator<'a> { // Mirrors `visit::walk_ty`, but tracks relevant state. fn walk_ty(&mut self, t: &'a Ty) { - match t.kind { + match &t.kind { TyKind::ImplTrait(..) => { self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) } @@ -217,7 +217,7 @@ impl<'a> AstValidator<'a> { .with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| { visit::walk_ty(this, t) }), - TyKind::Path(ref qself, ref path) => { + TyKind::Path(qself, path) => { // We allow these: // - `Option` // - `option::Option` @@ -231,7 +231,7 @@ impl<'a> AstValidator<'a> { // (for cases like `::Foo>`) // but we allow `impl Trait` in `GenericArgs` // iff there are no more PathSegments. - if let Some(ref qself) = *qself { + if let Some(qself) = qself { // `impl Trait` in `qself` is always illegal self.with_banned_impl_trait(|this| this.visit_ty(&qself.ty)); } @@ -738,8 +738,8 @@ impl<'a> AstValidator<'a> { } fn visit_ty_common(&mut self, ty: &'a Ty) { - match ty.kind { - TyKind::BareFn(ref bfty) => { + match &ty.kind { + TyKind::BareFn(bfty) => { self.check_fn_decl(&bfty.decl, SelfSemantic::No); Self::check_decl_no_pat(&bfty.decl, |span, _, _| { struct_span_err!( @@ -756,10 +756,10 @@ impl<'a> AstValidator<'a> { self.maybe_lint_missing_abi(sig_span, ty.id); } } - TyKind::TraitObject(ref bounds, ..) => { + TyKind::TraitObject(bounds, ..) => { let mut any_lifetime_bounds = false; for bound in bounds { - if let GenericBound::Outlives(ref lifetime) = *bound { + if let GenericBound::Outlives(lifetime) = bound { if any_lifetime_bounds { struct_span_err!( self.session, @@ -774,7 +774,7 @@ impl<'a> AstValidator<'a> { } } } - TyKind::ImplTrait(_, ref bounds) => { + TyKind::ImplTrait(_, bounds) => { if self.is_impl_trait_banned { struct_span_err!( self.session, @@ -842,8 +842,8 @@ fn validate_generic_param_order( let (kind, bounds, span) = (¶m.kind, ¶m.bounds, ident.span); let (ord_kind, ident) = match ¶m.kind { GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident.to_string()), - GenericParamKind::Type { default: _ } => (ParamKindOrd::TypeOrConst, ident.to_string()), - GenericParamKind::Const { ref ty, kw_span: _, default: _ } => { + GenericParamKind::Type { .. } => (ParamKindOrd::TypeOrConst, ident.to_string()), + GenericParamKind::Const { ty, .. } => { let ty = pprust::ty_to_string(ty); (ParamKindOrd::TypeOrConst, format!("const {}: {}", ident, ty)) } @@ -948,8 +948,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ExprKind::Paren(local_expr) => { fn has_let_expr(expr: &Expr) -> bool { - match expr.kind { - ExprKind::Binary(_, ref lhs, ref rhs) => has_let_expr(lhs) || has_let_expr(rhs), + match &expr.kind { + ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), ExprKind::Let(..) => true, _ => false, } @@ -1005,18 +1005,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_nomangle_item_asciionly(item.ident, item.span); } - match item.kind { + match &item.kind { ItemKind::Impl(box Impl { unsafety, polarity, defaultness: _, constness, - ref generics, - of_trait: Some(ref t), - ref self_ty, - ref items, + generics, + of_trait: Some(t), + self_ty, + items, }) => { - self.with_in_trait_impl(true, Some(constness), |this| { + self.with_in_trait_impl(true, Some(*constness), |this| { this.invalid_visibility(&item.vis, None); if let TyKind::Err = self_ty.kind { this.err_handler() @@ -1027,7 +1027,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .help("use `auto trait Trait {}` instead") .emit(); } - if let (Unsafe::Yes(span), ImplPolarity::Negative(sp)) = (unsafety, polarity) { + if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity) + { struct_span_err!( this.session, sp.to(t.path.span), @@ -1061,7 +1062,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { constness, generics: _, of_trait: None, - ref self_ty, + self_ty, items: _, }) => { let error = |annotation_span, annotation| { @@ -1078,25 +1079,25 @@ impl<'a> Visitor<'a> for AstValidator<'a> { &item.vis, Some(InvalidVisibilityNote::IndividualImplItems), ); - if let Unsafe::Yes(span) = unsafety { + if let &Unsafe::Yes(span) = unsafety { error(span, "unsafe").code(error_code!(E0197)).emit(); } - if let ImplPolarity::Negative(span) = polarity { + if let &ImplPolarity::Negative(span) = polarity { error(span, "negative").emit(); } - if let Defaultness::Default(def_span) = defaultness { + if let &Defaultness::Default(def_span) = defaultness { error(def_span, "`default`") .note("only trait implementations may be annotated with `default`") .emit(); } - if let Const::Yes(span) = constness { + if let &Const::Yes(span) = constness { error(span, "`const`") .note("only trait implementations may be annotated with `const`") .emit(); } } - ItemKind::Fn(box Fn { defaultness, ref sig, ref generics, ref body }) => { - self.check_defaultness(item.span, defaultness); + ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => { + self.check_defaultness(item.span, *defaultness); if body.is_none() { self.session.emit_err(FnWithoutBody { @@ -1132,7 +1133,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { &item.vis, Some(InvalidVisibilityNote::IndividualForeignItems), ); - if let Unsafe::Yes(span) = unsafety { + if let &Unsafe::Yes(span) = unsafety { self.err_handler().span_err(span, "extern block cannot be declared unsafe"); } if abi.is_none() { @@ -1142,7 +1143,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.extern_mod = old_item; return; // Avoid visiting again. } - ItemKind::Enum(ref def, _) => { + ItemKind::Enum(def, _) => { for variant in &def.variants { self.invalid_visibility(&variant.vis, None); for field in variant.data.fields() { @@ -1150,8 +1151,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - ItemKind::Trait(box Trait { is_auto, ref generics, ref bounds, ref items, .. }) => { - if is_auto == IsAuto::Yes { + ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => { + if *is_auto == IsAuto::Yes { // Auto traits cannot have generics, super traits nor contain items. self.deny_generic_params(generics, item.ident.span); self.deny_super_traits(bounds, item.ident.span); @@ -1171,8 +1172,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again } - ItemKind::Mod(unsafety, ref mod_kind) => { - if let Unsafe::Yes(span) = unsafety { + ItemKind::Mod(unsafety, mod_kind) => { + if let &Unsafe::Yes(span) = unsafety { self.err_handler().span_err(span, "module cannot be declared unsafe"); } // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). @@ -1182,13 +1183,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_mod_file_item_asciionly(item.ident); } } - ItemKind::Union(ref vdata, ..) => { + ItemKind::Union(vdata, ..) => { if vdata.fields().is_empty() { self.err_handler().span_err(item.span, "unions cannot have zero fields"); } } ItemKind::Const(def, .., None) => { - self.check_defaultness(item.span, def); + self.check_defaultness(item.span, *def); self.session.emit_err(ConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), @@ -1200,14 +1201,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { replace_span: self.ending_semi_or_hi(item.span), }); } - ItemKind::TyAlias(box TyAlias { - defaultness, - where_clauses, - ref bounds, - ref ty, - .. - }) => { - self.check_defaultness(item.span, defaultness); + ItemKind::TyAlias(box TyAlias { defaultness, where_clauses, bounds, ty, .. }) => { + self.check_defaultness(item.span, *defaultness); if ty.is_none() { self.session.emit_err(TyAliasWithoutBody { span: item.span, @@ -1266,8 +1261,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Mirrors `visit::walk_generic_args`, but tracks relevant state. fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) { - match *generic_args { - GenericArgs::AngleBracketed(ref data) => { + match generic_args { + GenericArgs::AngleBracketed(data) => { self.check_generic_args_before_constraints(data); for arg in &data.args { @@ -1283,7 +1278,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - GenericArgs::Parenthesized(ref data) => { + GenericArgs::Parenthesized(data) => { walk_list!(self, visit_ty, &data.inputs); if let FnRetTy::Ty(ty) = &data.output { // `-> Foo` syntax is essentially an associated type binding, @@ -1319,7 +1314,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { validate_generic_param_order(self.err_handler(), &generics.params, generics.span); for predicate in &generics.where_clause.predicates { - if let WherePredicate::EqPredicate(ref predicate) = *predicate { + if let WherePredicate::EqPredicate(predicate) = predicate { deny_equality_constraints(self, predicate, generics); } } @@ -1368,7 +1363,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) { - if let GenericBound::Trait(ref poly, modify) = *bound { + if let GenericBound::Trait(poly, modify) = bound { match (ctxt, modify) { (BoundKind::SuperTraits, TraitBoundModifier::Maybe) => { let mut err = self @@ -1573,8 +1568,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_item_named(item.ident, "const"); } - match item.kind { - AssocItemKind::Type(box TyAlias { ref generics, ref bounds, ref ty, .. }) + match &item.kind { + AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) if ctxt == AssocCtxt::Trait => { self.visit_vis(&item.vis); @@ -1586,7 +1581,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }); walk_list!(self, visit_ty, ty); } - AssocItemKind::Fn(box Fn { ref sig, ref generics, ref body, .. }) + AssocItemKind::Fn(box Fn { sig, generics, body, .. }) if self.in_const_trait_impl || ctxt == AssocCtxt::Trait || matches!(sig.header.constness, Const::Yes(_)) => diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 546010135a725..32f45f8b59e90 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -198,8 +198,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_item(&mut self, i: &'a ast::Item) { - match i.kind { - ast::ItemKind::ForeignMod(ref foreign_module) => { + match &i.kind { + ast::ItemKind::ForeignMod(foreign_module) => { if let Some(abi) = foreign_module.abi { self.check_abi(abi, ast::Const::No); } @@ -233,8 +233,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, ref of_trait, .. }) => { - if let ast::ImplPolarity::Negative(span) = polarity { + ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, of_trait, .. }) => { + if let &ast::ImplPolarity::Negative(span) = polarity { gate_feature_post!( &self, negative_impls, @@ -267,7 +267,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, decl_macro, i.span, msg); } - ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ref ty), .. }) => { + ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => { self.check_impl_trait(&ty) } @@ -302,8 +302,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_ty(&mut self, ty: &'a ast::Ty) { - match ty.kind { - ast::TyKind::BareFn(ref bare_fn_ty) => { + match &ty.kind { + ast::TyKind::BareFn(bare_fn_ty) => { // Function pointers cannot be `const` self.check_extern(bare_fn_ty.ext, ast::Const::No); } @@ -319,7 +319,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) { - if let ast::FnRetTy::Ty(ref output_ty) = *ret_ty { + if let ast::FnRetTy::Ty(output_ty) = ret_ty { if let ast::TyKind::Never = output_ty.kind { // Do nothing. } else { @@ -455,9 +455,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { - let is_fn = match i.kind { + let is_fn = match &i.kind { ast::AssocItemKind::Fn(_) => true, - ast::AssocItemKind::Type(box ast::TyAlias { ref ty, .. }) => { + ast::AssocItemKind::Type(box ast::TyAlias { ty, .. }) => { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { gate_feature_post!( &self, diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 7a9243c511b92..374e0a97063e3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -11,7 +11,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; use rustc_ast::util::parser; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, Mutability, PatKind}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind}; use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; use rustc_ast::{GenericArg, GenericBound, SelfKind, TraitBoundModifier}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; @@ -64,6 +64,7 @@ impl<'a> Comments<'a> { Comments { sm, comments, current: 0 } } + // FIXME: This shouldn't probably clone lmao pub fn next(&self) -> Option { self.comments.get(self.current).cloned() } @@ -268,10 +269,10 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn maybe_print_comment(&mut self, pos: BytePos) -> bool { let mut has_comment = false; - while let Some(ref cmnt) = self.next_comment() { + while let Some(cmnt) = self.next_comment() { if cmnt.pos < pos { has_comment = true; - self.print_comment(cmnt); + self.print_comment(&cmnt); } else { break; } @@ -366,8 +367,8 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere if self.next_comment().is_none() { self.hardbreak(); } - while let Some(ref cmnt) = self.next_comment() { - self.print_comment(cmnt) + while let Some(cmnt) = self.next_comment() { + self.print_comment(&cmnt) } } @@ -446,8 +447,8 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.hardbreak_if_not_bol(); } self.maybe_print_comment(attr.span.lo()); - match attr.kind { - ast::AttrKind::Normal(ref normal) => { + match &attr.kind { + ast::AttrKind::Normal(normal) => { match attr.style { ast::AttrStyle::Inner => self.word("#!["), ast::AttrStyle::Outer => self.word("#["), @@ -456,7 +457,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.word("]"); } ast::AttrKind::DocComment(comment_kind, data) => { - self.word(doc_comment_to_string(comment_kind, attr.style, data)); + self.word(doc_comment_to_string(*comment_kind, attr.style, *data)); self.hardbreak() } } @@ -497,22 +498,22 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) { match item { - ast::NestedMetaItem::MetaItem(ref mi) => self.print_meta_item(mi), - ast::NestedMetaItem::Lit(ref lit) => self.print_meta_item_lit(lit), + ast::NestedMetaItem::MetaItem(mi) => self.print_meta_item(mi), + ast::NestedMetaItem::Lit(lit) => self.print_meta_item_lit(lit), } } fn print_meta_item(&mut self, item: &ast::MetaItem) { self.ibox(INDENT_UNIT); - match item.kind { + match &item.kind { ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), - ast::MetaItemKind::NameValue(ref value) => { + ast::MetaItemKind::NameValue(value) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); self.print_meta_item_lit(value); } - ast::MetaItemKind::List(ref items) => { + ast::MetaItemKind::List(items) => { self.print_path(&item.path, false, 0); self.popen(); self.commasep(Consistent, &items, |s, i| s.print_meta_list_item(i)); @@ -657,7 +658,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_path_segment(&mut self, segment: &ast::PathSegment, colons_before_params: bool) { if segment.ident.name != kw::PathRoot { self.print_ident(segment.ident); - if let Some(ref args) = segment.args { + if let Some(args) = &segment.args { self.print_generic_args(args, colons_before_params); } } @@ -712,19 +713,19 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } fn nonterminal_to_string(&self, nt: &Nonterminal) -> String { - match *nt { - token::NtExpr(ref e) => self.expr_to_string(e), - token::NtMeta(ref e) => self.attr_item_to_string(e), - token::NtTy(ref e) => self.ty_to_string(e), - token::NtPath(ref e) => self.path_to_string(e), - token::NtItem(ref e) => self.item_to_string(e), - token::NtBlock(ref e) => self.block_to_string(e), - token::NtStmt(ref e) => self.stmt_to_string(e), - token::NtPat(ref e) => self.pat_to_string(e), - token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(), + match nt { + token::NtExpr(e) => self.expr_to_string(e), + token::NtMeta(e) => self.attr_item_to_string(e), + token::NtTy(e) => self.ty_to_string(e), + token::NtPath(e) => self.path_to_string(e), + token::NtItem(e) => self.item_to_string(e), + token::NtBlock(e) => self.block_to_string(e), + token::NtStmt(e) => self.stmt_to_string(e), + token::NtPat(e) => self.pat_to_string(e), + token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(*e, *is_raw).to_string(), token::NtLifetime(e) => e.to_string(), - token::NtLiteral(ref e) => self.expr_to_string(e), - token::NtVis(ref e) => self.vis_to_string(e), + token::NtLiteral(e) => self.expr_to_string(e), + token::NtVis(e) => self.vis_to_string(e), } } @@ -917,8 +918,8 @@ impl<'a> PrintState<'a> for State<'a> { self.word("::") } - match *args { - ast::GenericArgs::AngleBracketed(ref data) => { + match args { + ast::GenericArgs::AngleBracketed(data) => { self.word("<"); self.commasep(Inconsistent, &data.args, |s, arg| match arg { ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a), @@ -927,7 +928,7 @@ impl<'a> PrintState<'a> for State<'a> { self.word(">") } - ast::GenericArgs::Parenthesized(ref data) => { + ast::GenericArgs::Parenthesized(data) => { self.word("("); self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(ty)); self.word(")"); @@ -1011,17 +1012,17 @@ impl<'a> State<'a> { pub fn print_type(&mut self, ty: &ast::Ty) { self.maybe_print_comment(ty.span.lo()); self.ibox(0); - match ty.kind { - ast::TyKind::Slice(ref ty) => { + match &ty.kind { + ast::TyKind::Slice(ty) => { self.word("["); self.print_type(ty); self.word("]"); } - ast::TyKind::Ptr(ref mt) => { + ast::TyKind::Ptr(mt) => { self.word("*"); self.print_mt(mt, true); } - ast::TyKind::Rptr(ref lifetime, ref mt) => { + ast::TyKind::Rptr(lifetime, mt) => { self.word("&"); self.print_opt_lifetime(lifetime); self.print_mt(mt, false); @@ -1029,7 +1030,7 @@ impl<'a> State<'a> { ast::TyKind::Never => { self.word("!"); } - ast::TyKind::Tup(ref elts) => { + ast::TyKind::Tup(elts) => { self.popen(); self.commasep(Inconsistent, &elts, |s, ty| s.print_type(ty)); if elts.len() == 1 { @@ -1037,36 +1038,36 @@ impl<'a> State<'a> { } self.pclose(); } - ast::TyKind::Paren(ref typ) => { + ast::TyKind::Paren(typ) => { self.popen(); self.print_type(typ); self.pclose(); } - ast::TyKind::BareFn(ref f) => { + ast::TyKind::BareFn(f) => { self.print_ty_fn(f.ext, f.unsafety, &f.decl, None, &f.generic_params); } - ast::TyKind::Path(None, ref path) => { + ast::TyKind::Path(None, path) => { self.print_path(path, false, 0); } - ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false), - ast::TyKind::TraitObject(ref bounds, syntax) => { - if syntax == ast::TraitObjectSyntax::Dyn { + ast::TyKind::Path(Some(qself), path) => self.print_qpath(path, qself, false), + ast::TyKind::TraitObject(bounds, syntax) => { + if *syntax == ast::TraitObjectSyntax::Dyn { self.word_nbsp("dyn"); } self.print_type_bounds(bounds); } - ast::TyKind::ImplTrait(_, ref bounds) => { + ast::TyKind::ImplTrait(_, bounds) => { self.word_nbsp("impl"); self.print_type_bounds(bounds); } - ast::TyKind::Array(ref ty, ref length) => { + ast::TyKind::Array(ty, length) => { self.word("["); self.print_type(ty); self.word("; "); self.print_expr(&length.value); self.word("]"); } - ast::TyKind::Typeof(ref e) => { + ast::TyKind::Typeof(e) => { self.word("typeof("); self.print_expr(&e.value); self.word(")"); @@ -1082,7 +1083,7 @@ impl<'a> State<'a> { ast::TyKind::ImplicitSelf => { self.word("Self"); } - ast::TyKind::MacCall(ref m) => { + ast::TyKind::MacCall(m) => { self.print_mac(m); } ast::TyKind::CVarArgs => { @@ -1111,8 +1112,8 @@ impl<'a> State<'a> { pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) { self.maybe_print_comment(st.span.lo()); - match st.kind { - ast::StmtKind::Local(ref loc) => { + match &st.kind { + ast::StmtKind::Local(loc) => { self.print_outer_attributes(&loc.attrs); self.space_if_not_bol(); self.ibox(INDENT_UNIT); @@ -1135,15 +1136,15 @@ impl<'a> State<'a> { self.word(";"); self.end(); // `let` ibox } - ast::StmtKind::Item(ref item) => self.print_item(item), - ast::StmtKind::Expr(ref expr) => { + ast::StmtKind::Item(item) => self.print_item(item), + ast::StmtKind::Expr(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); if classify::expr_requires_semi_to_be_stmt(expr) { self.word(";"); } } - ast::StmtKind::Semi(ref expr) => { + ast::StmtKind::Semi(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); self.word(";"); @@ -1152,7 +1153,7 @@ impl<'a> State<'a> { self.space_if_not_bol(); self.word(";"); } - ast::StmtKind::MacCall(ref mac) => { + ast::StmtKind::MacCall(mac) => { self.space_if_not_bol(); self.print_outer_attributes(&mac.attrs); self.print_mac(&mac.mac); @@ -1193,8 +1194,8 @@ impl<'a> State<'a> { let has_attrs = self.print_inner_attributes(attrs); for (i, st) in blk.stmts.iter().enumerate() { - match st.kind { - ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => { + match &st.kind { + ast::StmtKind::Expr(expr) if i == blk.stmts.len() - 1 => { self.maybe_print_comment(st.span.lo()); self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); @@ -1362,7 +1363,7 @@ impl<'a> State<'a> { pub(crate) fn print_local_decl(&mut self, loc: &ast::Local) { self.print_pat(&loc.pat); - if let Some(ref ty) = loc.ty { + if let Some(ty) = &loc.ty { self.word_space(":"); self.print_type(ty); } @@ -1386,7 +1387,7 @@ impl<'a> State<'a> { for item_segment in &path.segments[qself.position..] { self.word("::"); self.print_ident(item_segment.ident); - if let Some(ref args) = item_segment.args { + if let Some(args) = &item_segment.args { self.print_generic_args(args, colons_before_params) } } @@ -1397,23 +1398,23 @@ impl<'a> State<'a> { self.ann.pre(self, AnnNode::Pat(pat)); /* Pat isn't normalized, but the beauty of it is that it doesn't matter */ - match pat.kind { + match &pat.kind { PatKind::Wild => self.word("_"), - PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, ref sub) => { - if by_ref == ByRef::Yes { + PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => { + if *by_ref == ByRef::Yes { self.word_nbsp("ref"); } - if mutbl == Mutability::Mut { + if mutbl.is_mut() { self.word_nbsp("mut"); } - self.print_ident(ident); - if let Some(ref p) = *sub { + self.print_ident(*ident); + if let Some(p) = sub { self.space(); self.word_space("@"); self.print_pat(p); } } - PatKind::TupleStruct(ref qself, ref path, ref elts) => { + PatKind::TupleStruct(qself, path, elts) => { if let Some(qself) = qself { self.print_qpath(path, qself, true); } else { @@ -1423,16 +1424,16 @@ impl<'a> State<'a> { self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); self.pclose(); } - PatKind::Or(ref pats) => { + PatKind::Or(pats) => { self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(p)); } - PatKind::Path(None, ref path) => { + PatKind::Path(None, path) => { self.print_path(path, true, 0); } - PatKind::Path(Some(ref qself), ref path) => { + PatKind::Path(Some(qself), path) => { self.print_qpath(path, qself, false); } - PatKind::Struct(ref qself, ref path, ref fields, etc) => { + PatKind::Struct(qself, path, fields, etc) => { if let Some(qself) = qself { self.print_qpath(path, qself, true); } else { @@ -1458,7 +1459,7 @@ impl<'a> State<'a> { }, |f| f.pat.span, ); - if etc { + if *etc { if !fields.is_empty() { self.word_space(","); } @@ -1469,7 +1470,7 @@ impl<'a> State<'a> { } self.word("}"); } - PatKind::Tuple(ref elts) => { + PatKind::Tuple(elts) => { self.popen(); self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); if elts.len() == 1 { @@ -1477,13 +1478,13 @@ impl<'a> State<'a> { } self.pclose(); } - PatKind::Box(ref inner) => { + PatKind::Box(inner) => { self.word("box "); self.print_pat(inner); } - PatKind::Ref(ref inner, mutbl) => { + PatKind::Ref(inner, mutbl) => { self.word("&"); - if mutbl == Mutability::Mut { + if mutbl.is_mut() { self.word("mut "); } if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind { @@ -1494,12 +1495,12 @@ impl<'a> State<'a> { self.print_pat(inner); } } - PatKind::Lit(ref e) => self.print_expr(&**e), - PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => { + PatKind::Lit(e) => self.print_expr(&**e), + PatKind::Range(begin, end, Spanned { node: end_kind, .. }) => { if let Some(e) = begin { self.print_expr(e); } - match *end_kind { + match end_kind { RangeEnd::Included(RangeSyntax::DotDotDot) => self.word("..."), RangeEnd::Included(RangeSyntax::DotDotEq) => self.word("..="), RangeEnd::Excluded => self.word(".."), @@ -1508,36 +1509,36 @@ impl<'a> State<'a> { self.print_expr(e); } } - PatKind::Slice(ref elts) => { + PatKind::Slice(elts) => { self.word("["); self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); self.word("]"); } PatKind::Rest => self.word(".."), - PatKind::Paren(ref inner) => { + PatKind::Paren(inner) => { self.popen(); self.print_pat(inner); self.pclose(); } - PatKind::MacCall(ref m) => self.print_mac(m), + PatKind::MacCall(m) => self.print_mac(m), } self.ann.post(self, AnnNode::Pat(pat)) } fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) { - match explicit_self.node { + match &explicit_self.node { SelfKind::Value(m) => { - self.print_mutability(m, false); + self.print_mutability(*m, false); self.word("self") } - SelfKind::Region(ref lt, m) => { + SelfKind::Region(lt, m) => { self.word("&"); self.print_opt_lifetime(lt); - self.print_mutability(m, false); + self.print_mutability(*m, false); self.word("self") } - SelfKind::Explicit(ref typ, m) => { - self.print_mutability(m, false); + SelfKind::Explicit(typ, m) => { + self.print_mutability(*m, false); self.word("self"); self.word_space(":"); self.print_type(typ) @@ -1599,7 +1600,7 @@ impl<'a> State<'a> { self.commasep(Inconsistent, &generic_params, |s, param| { s.print_outer_attributes_inline(¶m.attrs); - match param.kind { + match ¶m.kind { ast::GenericParamKind::Lifetime => { let lt = ast::Lifetime { id: param.id, ident: param.ident }; s.print_lifetime(lt); @@ -1608,19 +1609,19 @@ impl<'a> State<'a> { s.print_lifetime_bounds(¶m.bounds) } } - ast::GenericParamKind::Type { ref default } => { + ast::GenericParamKind::Type { default } => { s.print_ident(param.ident); if !param.bounds.is_empty() { s.word_nbsp(":"); s.print_type_bounds(¶m.bounds); } - if let Some(ref default) = default { + if let Some(default) = default { s.space(); s.word_space("="); s.print_type(default) } } - ast::GenericParamKind::Const { ref ty, kw_span: _, ref default } => { + ast::GenericParamKind::Const { ty, default, .. } => { s.word_space("const"); s.print_ident(param.ident); s.space(); @@ -1630,7 +1631,7 @@ impl<'a> State<'a> { s.word_nbsp(":"); s.print_type_bounds(¶m.bounds); } - if let Some(ref default) = default { + if let Some(default) = default { s.space(); s.word_space("="); s.print_expr(&default.value); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index f4d77549eff4c..81483ac30d1de 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -8,9 +8,9 @@ use rustc_ast::{self as ast, BlockCheckMode}; impl<'a> State<'a> { fn print_else(&mut self, els: Option<&ast::Expr>) { if let Some(_else) = els { - match _else.kind { + match &_else.kind { // Another `else if` block. - ast::ExprKind::If(ref i, ref then, ref e) => { + ast::ExprKind::If(i, then, e) => { self.cbox(INDENT_UNIT - 1); self.ibox(0); self.word(" else if "); @@ -20,7 +20,7 @@ impl<'a> State<'a> { self.print_else(e.as_deref()) } // Final `else` block. - ast::ExprKind::Block(ref b, _) => { + ast::ExprKind::Block(b, _) => { self.cbox(INDENT_UNIT - 1); self.ibox(0); self.word(" else "); @@ -202,7 +202,7 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX); self.word("."); self.print_ident(segment.ident); - if let Some(ref args) = segment.args { + if let Some(args) = &segment.args { self.print_generic_args(args, true); } self.print_call_post(base_args) @@ -284,73 +284,66 @@ impl<'a> State<'a> { self.ibox(INDENT_UNIT); self.ann.pre(self, AnnNode::Expr(expr)); - match expr.kind { - ast::ExprKind::Box(ref expr) => { + match &expr.kind { + ast::ExprKind::Box(expr) => { self.word_space("box"); self.print_expr_maybe_paren(expr, parser::PREC_PREFIX); } - ast::ExprKind::Array(ref exprs) => { + ast::ExprKind::Array(exprs) => { self.print_expr_vec(exprs); } - ast::ExprKind::ConstBlock(ref anon_const) => { + ast::ExprKind::ConstBlock(anon_const) => { self.print_expr_anon_const(anon_const, attrs); } - ast::ExprKind::Repeat(ref element, ref count) => { + ast::ExprKind::Repeat(element, count) => { self.print_expr_repeat(element, count); } - ast::ExprKind::Struct(ref se) => { + ast::ExprKind::Struct(se) => { self.print_expr_struct(&se.qself, &se.path, &se.fields, &se.rest); } - ast::ExprKind::Tup(ref exprs) => { + ast::ExprKind::Tup(exprs) => { self.print_expr_tup(exprs); } - ast::ExprKind::Call(ref func, ref args) => { + ast::ExprKind::Call(func, args) => { self.print_expr_call(func, &args); } - ast::ExprKind::MethodCall(box ast::MethodCall { - ref seg, - ref receiver, - ref args, - .. - }) => { + ast::ExprKind::MethodCall(box ast::MethodCall { seg, receiver, args, .. }) => { self.print_expr_method_call(seg, &receiver, &args); } - ast::ExprKind::Binary(op, ref lhs, ref rhs) => { - self.print_expr_binary(op, lhs, rhs); + ast::ExprKind::Binary(op, lhs, rhs) => { + self.print_expr_binary(*op, lhs, rhs); } - ast::ExprKind::Unary(op, ref expr) => { - self.print_expr_unary(op, expr); + ast::ExprKind::Unary(op, expr) => { + self.print_expr_unary(*op, expr); } - ast::ExprKind::AddrOf(k, m, ref expr) => { - self.print_expr_addr_of(k, m, expr); + ast::ExprKind::AddrOf(k, m, expr) => { + self.print_expr_addr_of(*k, *m, expr); } ast::ExprKind::Lit(token_lit) => { - self.print_token_literal(token_lit, expr.span); + self.print_token_literal(*token_lit, expr.span); } - ast::ExprKind::IncludedBytes(ref bytes) => { + ast::ExprKind::IncludedBytes(bytes) => { let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit(); self.print_token_literal(lit, expr.span) } - ast::ExprKind::Cast(ref expr, ref ty) => { + ast::ExprKind::Cast(expr, ty) => { let prec = AssocOp::As.precedence() as i8; self.print_expr_maybe_paren(expr, prec); self.space(); self.word_space("as"); self.print_type(ty); } - ast::ExprKind::Type(ref expr, ref ty) => { + ast::ExprKind::Type(expr, ty) => { let prec = AssocOp::Colon.precedence() as i8; self.print_expr_maybe_paren(expr, prec); self.word_space(":"); self.print_type(ty); } - ast::ExprKind::Let(ref pat, ref scrutinee, _) => { + ast::ExprKind::Let(pat, scrutinee, _) => { self.print_let(pat, scrutinee); } - ast::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(test, blk, elseopt.as_deref()) - } - ast::ExprKind::While(ref test, ref blk, opt_label) => { + ast::ExprKind::If(test, blk, elseopt) => self.print_if(test, blk, elseopt.as_deref()), + ast::ExprKind::While(test, blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -362,7 +355,7 @@ impl<'a> State<'a> { self.space(); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_label) => { + ast::ExprKind::ForLoop(pat, iter, blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -377,7 +370,7 @@ impl<'a> State<'a> { self.space(); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Loop(ref blk, opt_label, _) => { + ast::ExprKind::Loop(blk, opt_label, _) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -387,7 +380,7 @@ impl<'a> State<'a> { self.word_nbsp("loop"); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Match(ref expr, ref arms) => { + ast::ExprKind::Match(expr, arms) => { self.cbox(0); self.ibox(0); self.word_nbsp("match"); @@ -402,18 +395,18 @@ impl<'a> State<'a> { self.bclose(expr.span, empty); } ast::ExprKind::Closure(box ast::Closure { - ref binder, + binder, capture_clause, asyncness, movability, - ref fn_decl, - ref body, + fn_decl, + body, fn_decl_span: _, }) => { self.print_closure_binder(binder); - self.print_movability(movability); - self.print_asyncness(asyncness); - self.print_capture_clause(capture_clause); + self.print_movability(*movability); + self.print_asyncness(*asyncness); + self.print_capture_clause(*capture_clause); self.print_fn_params_and_ret(fn_decl, true); self.space(); @@ -425,7 +418,7 @@ impl<'a> State<'a> { // empty box to satisfy the close. self.ibox(0); } - ast::ExprKind::Block(ref blk, opt_label) => { + ast::ExprKind::Block(blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -436,26 +429,26 @@ impl<'a> State<'a> { self.ibox(0); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Async(capture_clause, _, ref blk) => { + ast::ExprKind::Async(capture_clause, _, blk) => { self.word_nbsp("async"); - self.print_capture_clause(capture_clause); + self.print_capture_clause(*capture_clause); // cbox/ibox in analogy to the `ExprKind::Block` arm above self.cbox(0); self.ibox(0); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Await(ref expr) => { + ast::ExprKind::Await(expr) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word(".await"); } - ast::ExprKind::Assign(ref lhs, ref rhs, _) => { + ast::ExprKind::Assign(lhs, rhs, _) => { let prec = AssocOp::Assign.precedence() as i8; self.print_expr_maybe_paren(lhs, prec + 1); self.space(); self.word_space("="); self.print_expr_maybe_paren(rhs, prec); } - ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => { + ast::ExprKind::AssignOp(op, lhs, rhs) => { let prec = AssocOp::Assign.precedence() as i8; self.print_expr_maybe_paren(lhs, prec + 1); self.space(); @@ -463,45 +456,44 @@ impl<'a> State<'a> { self.word_space("="); self.print_expr_maybe_paren(rhs, prec); } - ast::ExprKind::Field(ref expr, ident) => { + ast::ExprKind::Field(expr, ident) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word("."); - self.print_ident(ident); + self.print_ident(*ident); } - ast::ExprKind::Index(ref expr, ref index) => { + ast::ExprKind::Index(expr, index) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word("["); self.print_expr(index); self.word("]"); } - ast::ExprKind::Range(ref start, ref end, limits) => { + ast::ExprKind::Range(start, end, limits) => { // Special case for `Range`. `AssocOp` claims that `Range` has higher precedence // than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`. // Here we use a fake precedence value so that any child with lower precedence than // a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.) let fake_prec = AssocOp::LOr.precedence() as i8; - if let Some(ref e) = *start { + if let Some(e) = start { self.print_expr_maybe_paren(e, fake_prec); } - if limits == ast::RangeLimits::HalfOpen { - self.word(".."); - } else { - self.word("..="); + match limits { + ast::RangeLimits::HalfOpen => self.word(".."), + ast::RangeLimits::Closed => self.word("..="), } - if let Some(ref e) = *end { + if let Some(e) = end { self.print_expr_maybe_paren(e, fake_prec); } } ast::ExprKind::Underscore => self.word("_"), - ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0), - ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true), - ast::ExprKind::Break(opt_label, ref opt_expr) => { + ast::ExprKind::Path(None, path) => self.print_path(path, true, 0), + ast::ExprKind::Path(Some(qself), path) => self.print_qpath(path, qself, true), + ast::ExprKind::Break(opt_label, opt_expr) => { self.word("break"); if let Some(label) = opt_label { self.space(); self.print_ident(label.ident); } - if let Some(ref expr) = *opt_expr { + if let Some(expr) = opt_expr { self.space(); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } @@ -513,45 +505,45 @@ impl<'a> State<'a> { self.print_ident(label.ident); } } - ast::ExprKind::Ret(ref result) => { + ast::ExprKind::Ret(result) => { self.word("return"); - if let Some(ref expr) = *result { + if let Some(expr) = result { self.word(" "); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::Yeet(ref result) => { + ast::ExprKind::Yeet(result) => { self.word("do"); self.word(" "); self.word("yeet"); - if let Some(ref expr) = *result { + if let Some(expr) = result { self.word(" "); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::InlineAsm(ref a) => { + ast::ExprKind::InlineAsm(a) => { self.word("asm!"); self.print_inline_asm(a); } - ast::ExprKind::MacCall(ref m) => self.print_mac(m), - ast::ExprKind::Paren(ref e) => { + ast::ExprKind::MacCall(m) => self.print_mac(m), + ast::ExprKind::Paren(e) => { self.popen(); self.print_expr(e); self.pclose(); } - ast::ExprKind::Yield(ref e) => { + ast::ExprKind::Yield(e) => { self.word("yield"); - if let Some(ref expr) = *e { + if let Some(expr) = e { self.space(); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::Try(ref e) => { + ast::ExprKind::Try(e) => { self.print_expr_maybe_paren(e, parser::PREC_POSTFIX); self.word("?") } - ast::ExprKind::TryBlock(ref blk) => { + ast::ExprKind::TryBlock(blk) => { self.cbox(0); self.ibox(0); self.word_nbsp("try"); @@ -578,15 +570,15 @@ impl<'a> State<'a> { self.print_outer_attributes(&arm.attrs); self.print_pat(&arm.pat); self.space(); - if let Some(ref e) = arm.guard { + if let Some(e) = &arm.guard { self.word_space("if"); self.print_expr(e); self.space(); } self.word_space("=>"); - match arm.body.kind { - ast::ExprKind::Block(ref blk, opt_label) => { + match &arm.body.kind { + ast::ExprKind::Block(blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 9c4425701e039..c52f15401abe3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -136,10 +136,10 @@ impl<'a> State<'a> { self.maybe_print_comment(item.span.lo()); self.print_outer_attributes(&item.attrs); self.ann.pre(self, AnnNode::Item(item)); - match item.kind { + match &item.kind { ast::ItemKind::ExternCrate(orig_name) => { self.head(visibility_qualified(&item.vis, "extern crate")); - if let Some(orig_name) = orig_name { + if let &Some(orig_name) = orig_name { self.print_name(orig_name); self.space(); self.word("as"); @@ -150,35 +150,41 @@ impl<'a> State<'a> { self.end(); // end inner head-block self.end(); // end outer head-block } - ast::ItemKind::Use(ref tree) => { + ast::ItemKind::Use(tree) => { self.print_visibility(&item.vis); self.word_nbsp("use"); self.print_use_tree(tree); self.word(";"); } - ast::ItemKind::Static(ref ty, mutbl, ref body) => { + ast::ItemKind::Static(ty, mutbl, body) => { let def = ast::Defaultness::Final; - self.print_item_const(item.ident, Some(mutbl), ty, body.as_deref(), &item.vis, def); + self.print_item_const( + item.ident, + Some(*mutbl), + ty, + body.as_deref(), + &item.vis, + def, + ); } - ast::ItemKind::Const(def, ref ty, ref body) => { - self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def); + ast::ItemKind::Const(def, ty, body) => { + self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, *def); } - ast::ItemKind::Fn(box ast::Fn { defaultness, ref sig, ref generics, ref body }) => { - let body = body.as_deref(); + ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { self.print_fn_full( sig, item.ident, generics, &item.vis, - defaultness, - body, + *defaultness, + body.as_deref(), &item.attrs, ); } - ast::ItemKind::Mod(unsafety, ref mod_kind) => { + ast::ItemKind::Mod(unsafety, mod_kind) => { self.head(Self::to_string(|s| { s.print_visibility(&item.vis); - s.print_unsafety(unsafety); + s.print_unsafety(*unsafety); s.word("mod"); })); self.print_ident(item.ident); @@ -201,7 +207,7 @@ impl<'a> State<'a> { } } } - ast::ItemKind::ForeignMod(ref nmod) => { + ast::ItemKind::ForeignMod(nmod) => { self.head(Self::to_string(|s| { s.print_unsafety(nmod.unsafety); s.word("extern"); @@ -215,7 +221,7 @@ impl<'a> State<'a> { let empty = item.attrs.is_empty() && nmod.items.is_empty(); self.bclose(item.span, empty); } - ast::ItemKind::GlobalAsm(ref asm) => { + ast::ItemKind::GlobalAsm(asm) => { self.head(visibility_qualified(&item.vis, "global_asm!")); self.print_inline_asm(asm); self.word(";"); @@ -224,32 +230,31 @@ impl<'a> State<'a> { } ast::ItemKind::TyAlias(box ast::TyAlias { defaultness, - ref generics, + generics, where_clauses, where_predicates_split, - ref bounds, - ref ty, + bounds, + ty, }) => { - let ty = ty.as_deref(); self.print_associated_type( item.ident, generics, - where_clauses, - where_predicates_split, + *where_clauses, + *where_predicates_split, bounds, - ty, + ty.as_deref(), &item.vis, - defaultness, + *defaultness, ); } - ast::ItemKind::Enum(ref enum_definition, ref params) => { + ast::ItemKind::Enum(enum_definition, params) => { self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis); } - ast::ItemKind::Struct(ref struct_def, ref generics) => { + ast::ItemKind::Struct(struct_def, generics) => { self.head(visibility_qualified(&item.vis, "struct")); self.print_struct(struct_def, generics, item.ident, item.span, true); } - ast::ItemKind::Union(ref struct_def, ref generics) => { + ast::ItemKind::Union(struct_def, generics) => { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident, item.span, true); } @@ -258,15 +263,15 @@ impl<'a> State<'a> { polarity, defaultness, constness, - ref generics, - ref of_trait, - ref self_ty, - ref items, + generics, + of_trait, + self_ty, + items, }) => { self.head(""); self.print_visibility(&item.vis); - self.print_defaultness(defaultness); - self.print_unsafety(unsafety); + self.print_defaultness(*defaultness); + self.print_unsafety(*unsafety); self.word("impl"); if generics.params.is_empty() { @@ -276,13 +281,13 @@ impl<'a> State<'a> { self.space(); } - self.print_constness(constness); + self.print_constness(*constness); if let ast::ImplPolarity::Negative(_) = polarity { self.word("!"); } - if let Some(ref t) = *of_trait { + if let Some(t) = of_trait { self.print_trait_ref(t); self.space(); self.word_space("for"); @@ -303,21 +308,21 @@ impl<'a> State<'a> { ast::ItemKind::Trait(box ast::Trait { is_auto, unsafety, - ref generics, - ref bounds, - ref items, + generics, + bounds, + items, .. }) => { self.head(""); self.print_visibility(&item.vis); - self.print_unsafety(unsafety); - self.print_is_auto(is_auto); + self.print_unsafety(*unsafety); + self.print_is_auto(*is_auto); self.word_nbsp("trait"); self.print_ident(item.ident); self.print_generic_params(&generics.params); let mut real_bounds = Vec::with_capacity(bounds.len()); for b in bounds.iter() { - if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b { + if let GenericBound::Trait(ptr, ast::TraitBoundModifier::Maybe) = b { self.space(); self.word_space("for ?"); self.print_trait_ref(&ptr.trait_ref); @@ -339,14 +344,14 @@ impl<'a> State<'a> { let empty = item.attrs.is_empty() && items.is_empty(); self.bclose(item.span, empty); } - ast::ItemKind::TraitAlias(ref generics, ref bounds) => { + ast::ItemKind::TraitAlias(generics, bounds) => { self.head(visibility_qualified(&item.vis, "trait")); self.print_ident(item.ident); self.print_generic_params(&generics.params); let mut real_bounds = Vec::with_capacity(bounds.len()); // FIXME(durka) this seems to be some quite outdated syntax for b in bounds.iter() { - if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b { + if let GenericBound::Trait(ptr, ast::TraitBoundModifier::Maybe) = b { self.space(); self.word_space("for ?"); self.print_trait_ref(&ptr.trait_ref); @@ -364,13 +369,13 @@ impl<'a> State<'a> { self.end(); // end inner head-block self.end(); // end outer head-block } - ast::ItemKind::MacCall(ref mac) => { + ast::ItemKind::MacCall(mac) => { self.print_mac(mac); if mac.args.need_semicolon() { self.word(";"); } } - ast::ItemKind::MacroDef(ref macro_def) => { + ast::ItemKind::MacroDef(macro_def) => { self.print_mac_def(macro_def, &item.ident, item.span, |state| { state.print_visibility(&item.vis) }); @@ -412,11 +417,11 @@ impl<'a> State<'a> { } pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) { - match vis.kind { + match &vis.kind { ast::VisibilityKind::Public => self.word_nbsp("pub"), - ast::VisibilityKind::Restricted { ref path, id: _, shorthand } => { + ast::VisibilityKind::Restricted { path, shorthand, .. } => { let path = Self::to_string(|s| s.print_path(path, false, 0)); - if shorthand && (path == "crate" || path == "self" || path == "super") { + if *shorthand && (path == "crate" || path == "self" || path == "super") { self.word_nbsp(format!("pub({})", path)) } else { self.word_nbsp(format!("pub(in {})", path)) @@ -465,7 +470,7 @@ impl<'a> State<'a> { ) { self.print_ident(ident); self.print_generic_params(&generics.params); - match struct_def { + match &struct_def { ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { if let ast::VariantData::Tuple(..) = struct_def { self.popen(); @@ -484,7 +489,7 @@ impl<'a> State<'a> { self.end(); self.end(); // Close the outer-box. } - ast::VariantData::Struct(ref fields, ..) => { + ast::VariantData::Struct(fields, ..) => { self.print_where_clause(&generics.where_clause); self.print_record_struct_body(fields, span); } @@ -496,7 +501,7 @@ impl<'a> State<'a> { self.print_visibility(&v.vis); let generics = ast::Generics::default(); self.print_struct(&v.data, &generics, v.ident, v.span, false); - if let Some(ref d) = v.disr_expr { + if let Some(d) = &v.disr_expr { self.space(); self.word_space("="); self.print_expr(&d.value) @@ -657,10 +662,10 @@ impl<'a> State<'a> { } fn print_use_tree(&mut self, tree: &ast::UseTree) { - match tree.kind { + match &tree.kind { ast::UseTreeKind::Simple(rename, ..) => { self.print_path(&tree.prefix, false, 0); - if let Some(rename) = rename { + if let &Some(rename) = rename { self.nbsp(); self.word_nbsp("as"); self.print_ident(rename); @@ -673,7 +678,7 @@ impl<'a> State<'a> { } self.word("*"); } - ast::UseTreeKind::Nested(ref items) => { + ast::UseTreeKind::Nested(items) => { if !tree.prefix.segments.is_empty() { self.print_path(&tree.prefix, false, 0); self.word("::"); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index b35abbd107b9c..90e2b6b698cf8 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1705,6 +1705,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); } + #[instrument(level = "debug", skip(self, infcx, errors_buffer))] fn check_member_constraints( &self, infcx: &InferCtxt<'tcx>, @@ -1712,22 +1713,21 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) { let member_constraints = self.member_constraints.clone(); for m_c_i in member_constraints.all_indices() { - debug!("check_member_constraint(m_c_i={:?})", m_c_i); + debug!(?m_c_i); let m_c = &member_constraints[m_c_i]; let member_region_vid = m_c.member_region_vid; debug!( - "check_member_constraint: member_region_vid={:?} with value {}", - member_region_vid, - self.region_value_str(member_region_vid), + ?member_region_vid, + value = ?self.region_value_str(member_region_vid), ); let choice_regions = member_constraints.choice_regions(m_c_i); - debug!("check_member_constraint: choice_regions={:?}", choice_regions); + debug!(?choice_regions); // Did the member region wind up equal to any of the option regions? if let Some(o) = choice_regions.iter().find(|&&o_r| self.eval_equal(o_r, m_c.member_region_vid)) { - debug!("check_member_constraint: evaluated as equal to {:?}", o); + debug!("evaluated as equal to {:?}", o); continue; } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index bc3a94a402706..c9f5dd0f2c68b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -292,30 +292,33 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> { } fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) { - let mut target_features = llvm_target_features(tm); + let mut llvm_target_features = llvm_target_features(tm); + let mut known_llvm_target_features = FxHashSet::<&'static str>::default(); let mut rustc_target_features = supported_target_features(sess) .iter() - .filter_map(|(feature, _gate)| { - for llvm_feature in to_llvm_features(sess, *feature) { + .map(|(feature, _gate)| { + let desc = if let Some(llvm_feature) = to_llvm_features(sess, *feature).first() { // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings. - match target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok().map( - |index| { - let (_f, desc) = target_features.remove(index); - (*feature, desc) - }, - ) { - Some(v) => return Some(v), - None => {} + match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() { + Some(index) => { + known_llvm_target_features.insert(llvm_feature); + llvm_target_features[index].1 + } + None => "", } - } - None + } else { + "" + }; + (*feature, desc) }) .collect::>(); rustc_target_features.extend_from_slice(&[( "crt-static", "Enables C Run-time Libraries to be statically linked", )]); - let max_feature_len = target_features + llvm_target_features.retain(|(f, _d)| !known_llvm_target_features.contains(f)); + + let max_feature_len = llvm_target_features .iter() .chain(rustc_target_features.iter()) .map(|(feature, _desc)| feature.len()) @@ -327,10 +330,10 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) { println!(" {1:0$} - {2}.", max_feature_len, feature, desc); } println!("\nCode-generation features supported by LLVM for this target:"); - for (feature, desc) in &target_features { + for (feature, desc) in &llvm_target_features { println!(" {1:0$} - {2}.", max_feature_len, feature, desc); } - if target_features.is_empty() { + if llvm_target_features.is_empty() { println!(" Target features listing is not supported by this LLVM version."); } println!("\nUse +feature to enable a feature, or -feature to disable it."); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 638dd6d756b58..d623e72613944 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -33,7 +33,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs} use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, ToPredicate, Ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1366,12 +1366,14 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate "predicates_defined_on: inferred_outlives_of({:?}) = {:?}", def_id, inferred_outlives, ); + let inferred_outlives_iter = + inferred_outlives.iter().map(|(clause, span)| ((*clause).to_predicate(tcx), *span)); if result.predicates.is_empty() { - result.predicates = inferred_outlives; + result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter); } else { - result.predicates = tcx - .arena - .alloc_from_iter(result.predicates.iter().chain(inferred_outlives).copied()); + result.predicates = tcx.arena.alloc_from_iter( + result.predicates.into_iter().copied().chain(inferred_outlives_iter), + ); } } diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index c8f37176836c5..81fe32000d307 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -3,7 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt}; +use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -17,7 +17,7 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers }; } -fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate<'_>, Span)] { +fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Clause<'_>, Span)] { let id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local()); if matches!(tcx.def_kind(item_def_id), hir::def::DefKind::AnonConst) && tcx.lazy_normalization() @@ -50,12 +50,10 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate if tcx.has_attr(item_def_id, sym::rustc_outlives) { let mut pred: Vec = predicates .iter() - .map(|(out_pred, _)| match out_pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::RegionOutlives(p)) => { - p.to_string() - } - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(p)) => p.to_string(), - err => bug!("unexpected predicate {:?}", err), + .map(|(out_pred, _)| match out_pred { + ty::Clause::RegionOutlives(p) => p.to_string(), + ty::Clause::TypeOutlives(p) => p.to_string(), + err => bug!("unexpected clause {:?}", err), }) .collect(); pred.sort(); @@ -103,19 +101,11 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { |(ty::OutlivesPredicate(kind1, region2), &span)| { match kind1.unpack() { GenericArgKind::Type(ty1) => Some(( - ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::TypeOutlives( - ty::OutlivesPredicate(ty1, *region2), - ))) - .to_predicate(tcx), + ty::Clause::TypeOutlives(ty::OutlivesPredicate(ty1, *region2)), span, )), GenericArgKind::Lifetime(region1) => Some(( - ty::Binder::dummy(ty::PredicateKind::Clause( - ty::Clause::RegionOutlives(ty::OutlivesPredicate( - region1, *region2, - )), - )) - .to_predicate(tcx), + ty::Clause::RegionOutlives(ty::OutlivesPredicate(region1, *region2)), span, )), GenericArgKind::Const(_) => { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 93d81125f4885..825093384fba7 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2046,16 +2046,13 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN impl ExplicitOutlivesRequirements { fn lifetimes_outliving_lifetime<'tcx>( - inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], + inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)], def_id: DefId, ) -> Vec> { inferred_outlives .iter() - .filter_map(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::RegionOutlives(ty::OutlivesPredicate( - a, - b, - ))) => match *a { + .filter_map(|(clause, _)| match *clause { + ty::Clause::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a { ty::ReEarlyBound(ebr) if ebr.def_id == def_id => Some(b), _ => None, }, @@ -2065,16 +2062,15 @@ impl ExplicitOutlivesRequirements { } fn lifetimes_outliving_type<'tcx>( - inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], + inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)], index: u32, ) -> Vec> { inferred_outlives .iter() - .filter_map(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate( - a, - b, - ))) => a.is_param(index).then_some(b), + .filter_map(|(clause, _)| match *clause { + ty::Clause::TypeOutlives(ty::OutlivesPredicate(a, b)) => { + a.is_param(index).then_some(b) + } _ => None, }) .collect() diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index c51b8f96c7151..6b60577c9023f 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -353,7 +353,7 @@ define_tables! { explicit_predicates_of: Table>>, generics_of: Table>, // As an optimization, a missing entry indicates an empty `&[]`. - inferred_outlives_of: Table, Span)>>, + inferred_outlives_of: Table, Span)>>, super_predicates_of: Table>>, type_of: Table>>, variances_of: Table>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 38b72ec923193..e1220320eea1b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -562,7 +562,7 @@ rustc_queries! { /// Returns the inferred outlives predicates (e.g., for `struct /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). - query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] { + query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index b22b3961f34ea..75f2d45eadb81 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -345,6 +345,14 @@ impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> } } +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] { + fn decode(decoder: &mut D) -> &'tcx Self { + decoder.interner().arena.alloc_from_iter( + (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::>(), + ) + } +} + impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::List { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 595b73986a87b..7be9fee3b0cf6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -734,7 +734,7 @@ pub struct CratePredicatesMap<'tcx> { /// For each struct with outlive bounds, maps to a vector of the /// predicate of its outlive bounds. If an item has no outlives /// bounds, it will have no entry. - pub predicates: FxHashMap, Span)]>, + pub predicates: FxHashMap, Span)]>, } impl<'tcx> Predicate<'tcx> { @@ -1167,6 +1167,13 @@ impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, PredicateKind<'tc } } +impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Clause<'tcx> { + #[inline(always)] + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { + tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::Clause(self))) + } +} + impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> { #[inline(always)] fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index b2bcf0e29cd9d..c7d6c6abd1c22 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -5,7 +5,7 @@ use rustc_index::vec::{Idx, IndexVec}; use crate::middle::exported_symbols::ExportedSymbol; use crate::mir::Body; use crate::ty::{ - self, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty, + self, Clause, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty, }; pub trait ParameterizedOverTcx: 'static { @@ -121,6 +121,7 @@ parameterized_over_tcx! { TraitRef, Const, Predicate, + Clause, GeneratorDiagnosticData, Body, ExportedSymbol, diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 73ea06a6370d4..e7c3c712852dd 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -116,6 +116,17 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> { intravisit::walk_expr(self, expr) } + + fn visit_inline_asm(&mut self, asm: &'tcx hir::InlineAsm<'tcx>, id: hir::HirId) { + for (op, _) in asm.operands { + if let hir::InlineAsmOperand::SymStatic { def_id, .. } = op { + if let Some(def_id) = def_id.as_local() { + self.reachable_symbols.insert(def_id); + } + } + } + intravisit::walk_inline_asm(self, asm, id); + } } impl<'tcx> ReachableContext<'tcx> { diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index c61d2a9c2d0c6..ac9653b90071c 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -818,6 +818,12 @@ impl<'a, 'tcx> Decodable> for &'tcx [(ty::Predicate<'tcx> } } +impl<'a, 'tcx> Decodable> for &'tcx [(ty::Clause<'tcx>, Span)] { + fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { + RefDecodable::decode(d) + } +} + impl<'a, 'tcx> Decodable> for &'tcx [rustc_ast::InlineAsmTemplatePiece] { fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { RefDecodable::decode(d) diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs index a6cdd32f23b8e..7dad9aa01fafd 100644 --- a/compiler/rustc_serialize/src/leb128.rs +++ b/compiler/rustc_serialize/src/leb128.rs @@ -1,22 +1,19 @@ -#![macro_use] - -macro_rules! max_leb128_len { - ($int_ty:ty) => { - // The longest LEB128 encoding for an integer uses 7 bits per byte. - (std::mem::size_of::<$int_ty>() * 8 + 6) / 7 - }; +/// Returns the length of the longest LEB128 encoding for `T`, assuming `T` is an integer type +pub const fn max_leb128_len() -> usize { + // The longest LEB128 encoding for an integer uses 7 bits per byte. + (std::mem::size_of::() * 8 + 6) / 7 } -/// Returns the longest LEB128 encoding of all supported integer types. -pub const fn max_leb128_len() -> usize { - max_leb128_len!(u128) +/// Returns the length of the longest LEB128 encoding of all supported integer types. +pub const fn largest_max_leb128_len() -> usize { + max_leb128_len::() } macro_rules! impl_write_unsigned_leb128 { ($fn_name:ident, $int_ty:ty) => { #[inline] pub fn $fn_name( - out: &mut [::std::mem::MaybeUninit; max_leb128_len!($int_ty)], + out: &mut [::std::mem::MaybeUninit; max_leb128_len::<$int_ty>()], mut value: $int_ty, ) -> &[u8] { let mut i = 0; @@ -90,7 +87,7 @@ macro_rules! impl_write_signed_leb128 { ($fn_name:ident, $int_ty:ty) => { #[inline] pub fn $fn_name( - out: &mut [::std::mem::MaybeUninit; max_leb128_len!($int_ty)], + out: &mut [::std::mem::MaybeUninit; max_leb128_len::<$int_ty>()], mut value: $int_ty, ) -> &[u8] { let mut i = 0; diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 7c54df809f179..0afeb86fceb24 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -1,4 +1,4 @@ -use crate::leb128::{self, max_leb128_len}; +use crate::leb128::{self, largest_max_leb128_len}; use crate::serialize::{Decodable, Decoder, Encodable, Encoder}; use std::convert::TryInto; use std::fs::File; @@ -32,7 +32,7 @@ impl MemEncoder { macro_rules! write_leb128 { ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{ - const MAX_ENCODED_LEN: usize = max_leb128_len!($int_ty); + const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>(); let old_len = $enc.data.len(); if MAX_ENCODED_LEN > $enc.data.capacity() - old_len { @@ -186,12 +186,12 @@ impl FileEncoder { pub fn with_capacity>(path: P, capacity: usize) -> io::Result { // Require capacity at least as large as the largest LEB128 encoding // here, so that we don't have to check or handle this on every write. - assert!(capacity >= max_leb128_len()); + assert!(capacity >= largest_max_leb128_len()); // Require capacity small enough such that some capacity checks can be // done using guaranteed non-overflowing add rather than sub, which // shaves an instruction off those code paths (on x86 at least). - assert!(capacity <= usize::MAX - max_leb128_len()); + assert!(capacity <= usize::MAX - largest_max_leb128_len()); // Create the file for reading and writing, because some encoders do both // (e.g. the metadata encoder when -Zmeta-stats is enabled) @@ -411,7 +411,7 @@ impl Drop for FileEncoder { macro_rules! file_encoder_write_leb128 { ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{ - const MAX_ENCODED_LEN: usize = max_leb128_len!($int_ty); + const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>(); // We ensure this during `FileEncoder` construction. debug_assert!($enc.capacity() >= MAX_ENCODED_LEN); diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 1a583cf781371..0f8cfd7f5385c 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1250,8 +1250,8 @@ supported_targets! { ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl), - ("aarch64-unknown-nto-qnx7.1.0", aarch64_unknown_nto_qnx_710), - ("x86_64-pc-nto-qnx7.1.0", x86_64_pc_nto_qnx710), + ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710), + ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 627ed4674b0e9..fe5135661b5f8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -9,225 +9,18 @@ use hir::LangItem; use rustc_hir as hir; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Ty, TypeVisitable}; use rustc_target::spec::abi::Abi; use crate::traits; -use crate::traits::coherence::Conflict; use crate::traits::query::evaluate_obligation::InferCtxtExt; -use crate::traits::{util, SelectionResult}; -use crate::traits::{ErrorReporting, Overflow, Unimplemented}; +use crate::traits::util; use super::BuiltinImplConditions; -use super::IntercrateAmbiguityCause; -use super::OverflowError; -use super::SelectionCandidate::{self, *}; -use super::{EvaluatedCandidate, SelectionCandidateSet, SelectionContext, TraitObligationStack}; +use super::SelectionCandidate::*; +use super::{SelectionCandidateSet, SelectionContext, TraitObligationStack}; impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] - pub(super) fn candidate_from_obligation<'o>( - &mut self, - stack: &TraitObligationStack<'o, 'tcx>, - ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - // Watch out for overflow. This intentionally bypasses (and does - // not update) the cache. - self.check_recursion_limit(&stack.obligation, &stack.obligation)?; - - // Check the cache. Note that we freshen the trait-ref - // separately rather than using `stack.fresh_trait_ref` -- - // this is because we want the unbound variables to be - // replaced with fresh types starting from index 0. - let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate); - debug!(?cache_fresh_trait_pred); - debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars()); - - if let Some(c) = - self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred) - { - debug!("CACHE HIT"); - return c; - } - - // If no match, compute result and insert into cache. - // - // FIXME(nikomatsakis) -- this cache is not taking into - // account cycles that may have occurred in forming the - // candidate. I don't know of any specific problems that - // result but it seems awfully suspicious. - let (candidate, dep_node) = - self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); - - debug!("CACHE MISS"); - self.insert_candidate_cache( - stack.obligation.param_env, - cache_fresh_trait_pred, - dep_node, - candidate.clone(), - ); - candidate - } - - fn candidate_from_obligation_no_cache<'o>( - &mut self, - stack: &TraitObligationStack<'o, 'tcx>, - ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - if let Err(conflict) = self.is_knowable(stack) { - debug!("coherence stage: not knowable"); - if self.intercrate_ambiguity_causes.is_some() { - debug!("evaluate_stack: intercrate_ambiguity_causes is some"); - // Heuristics: show the diagnostics when there are no candidates in crate. - if let Ok(candidate_set) = self.assemble_candidates(stack) { - let mut no_candidates_apply = true; - - for c in candidate_set.vec.iter() { - if self.evaluate_candidate(stack, &c)?.may_apply() { - no_candidates_apply = false; - break; - } - } - - if !candidate_set.ambiguous && no_candidates_apply { - let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; - let self_ty = trait_ref.self_ty(); - let (trait_desc, self_desc) = with_no_trimmed_paths!({ - let trait_desc = trait_ref.print_only_trait_path().to_string(); - let self_desc = if self_ty.has_concrete_skeleton() { - Some(self_ty.to_string()) - } else { - None - }; - (trait_desc, self_desc) - }); - let cause = if let Conflict::Upstream = conflict { - IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } - } else { - IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } - }; - debug!(?cause, "evaluate_stack: pushing cause"); - self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause); - } - } - } - return Ok(None); - } - - let candidate_set = self.assemble_candidates(stack)?; - - if candidate_set.ambiguous { - debug!("candidate set contains ambig"); - return Ok(None); - } - - let candidates = candidate_set.vec; - - debug!(?stack, ?candidates, "assembled {} candidates", candidates.len()); - - // At this point, we know that each of the entries in the - // candidate set is *individually* applicable. Now we have to - // figure out if they contain mutual incompatibilities. This - // frequently arises if we have an unconstrained input type -- - // for example, we are looking for `$0: Eq` where `$0` is some - // unconstrained type variable. In that case, we'll get a - // candidate which assumes $0 == int, one that assumes `$0 == - // usize`, etc. This spells an ambiguity. - - let mut candidates = self.filter_impls(candidates, stack.obligation); - - // If there is more than one candidate, first winnow them down - // by considering extra conditions (nested obligations and so - // forth). We don't winnow if there is exactly one - // candidate. This is a relatively minor distinction but it - // can lead to better inference and error-reporting. An - // example would be if there was an impl: - // - // impl Vec { fn push_clone(...) { ... } } - // - // and we were to see some code `foo.push_clone()` where `boo` - // is a `Vec` and `Bar` does not implement `Clone`. If - // we were to winnow, we'd wind up with zero candidates. - // Instead, we select the right impl now but report "`Bar` does - // not implement `Clone`". - if candidates.len() == 1 { - return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation); - } - - // Winnow, but record the exact outcome of evaluation, which - // is needed for specialization. Propagate overflow if it occurs. - let mut candidates = candidates - .into_iter() - .map(|c| match self.evaluate_candidate(stack, &c) { - Ok(eval) if eval.may_apply() => { - Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) - } - Ok(_) => Ok(None), - Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)), - Err(OverflowError::ErrorReporting) => Err(ErrorReporting), - Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))), - }) - .flat_map(Result::transpose) - .collect::, _>>()?; - - debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len()); - - let needs_infer = stack.obligation.predicate.has_non_region_infer(); - - // If there are STILL multiple candidates, we can further - // reduce the list by dropping duplicates -- including - // resolving specializations. - if candidates.len() > 1 { - let mut i = 0; - while i < candidates.len() { - let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| { - self.candidate_should_be_dropped_in_favor_of( - &candidates[i], - &candidates[j], - needs_infer, - ) - }); - if is_dup { - debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len()); - candidates.swap_remove(i); - } else { - debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len()); - i += 1; - - // If there are *STILL* multiple candidates, give up - // and report ambiguity. - if i > 1 { - debug!("multiple matches, ambig"); - return Ok(None); - } - } - } - } - - // If there are *NO* candidates, then there are no impls -- - // that we know of, anyway. Note that in the case where there - // are unbound type variables within the obligation, it might - // be the case that you could still satisfy the obligation - // from another crate by instantiating the type variables with - // a type from another crate that does have an impl. This case - // is checked for in `evaluate_stack` (and hence users - // who might care about this case, like coherence, should use - // that function). - if candidates.is_empty() { - // If there's an error type, 'downgrade' our result from - // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid - // emitting additional spurious errors, since we're guaranteed - // to have emitted at least one. - if stack.obligation.predicate.references_error() { - debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous"); - return Ok(None); - } - return Err(Unimplemented); - } - - // Just one candidate left. - self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation) - } - #[instrument(skip(self, stack), level = "debug")] pub(super) fn assemble_candidates<'o>( &mut self, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a2d2d44fbc28f..515f3a3498886 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -30,6 +30,7 @@ use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::project::ProjectAndUnifyResult; use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; +use crate::traits::Unimplemented; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -55,6 +56,7 @@ use std::fmt::{self, Display}; use std::iter; pub use rustc_middle::traits::select::*; +use rustc_middle::ty::print::with_no_trimmed_paths; mod candidate_assembly; mod confirmation; @@ -305,6 +307,208 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.candidate_from_obligation(&stack) } + #[instrument(level = "debug", skip(self), ret)] + fn candidate_from_obligation<'o>( + &mut self, + stack: &TraitObligationStack<'o, 'tcx>, + ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { + // Watch out for overflow. This intentionally bypasses (and does + // not update) the cache. + self.check_recursion_limit(&stack.obligation, &stack.obligation)?; + + // Check the cache. Note that we freshen the trait-ref + // separately rather than using `stack.fresh_trait_ref` -- + // this is because we want the unbound variables to be + // replaced with fresh types starting from index 0. + let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate); + debug!(?cache_fresh_trait_pred); + debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars()); + + if let Some(c) = + self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred) + { + debug!("CACHE HIT"); + return c; + } + + // If no match, compute result and insert into cache. + // + // FIXME(nikomatsakis) -- this cache is not taking into + // account cycles that may have occurred in forming the + // candidate. I don't know of any specific problems that + // result but it seems awfully suspicious. + let (candidate, dep_node) = + self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); + + debug!("CACHE MISS"); + self.insert_candidate_cache( + stack.obligation.param_env, + cache_fresh_trait_pred, + dep_node, + candidate.clone(), + ); + candidate + } + + fn candidate_from_obligation_no_cache<'o>( + &mut self, + stack: &TraitObligationStack<'o, 'tcx>, + ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { + if let Err(conflict) = self.is_knowable(stack) { + debug!("coherence stage: not knowable"); + if self.intercrate_ambiguity_causes.is_some() { + debug!("evaluate_stack: intercrate_ambiguity_causes is some"); + // Heuristics: show the diagnostics when there are no candidates in crate. + if let Ok(candidate_set) = self.assemble_candidates(stack) { + let mut no_candidates_apply = true; + + for c in candidate_set.vec.iter() { + if self.evaluate_candidate(stack, &c)?.may_apply() { + no_candidates_apply = false; + break; + } + } + + if !candidate_set.ambiguous && no_candidates_apply { + let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; + let self_ty = trait_ref.self_ty(); + let (trait_desc, self_desc) = with_no_trimmed_paths!({ + let trait_desc = trait_ref.print_only_trait_path().to_string(); + let self_desc = if self_ty.has_concrete_skeleton() { + Some(self_ty.to_string()) + } else { + None + }; + (trait_desc, self_desc) + }); + let cause = if let Conflict::Upstream = conflict { + IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } + } else { + IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } + }; + debug!(?cause, "evaluate_stack: pushing cause"); + self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause); + } + } + } + return Ok(None); + } + + let candidate_set = self.assemble_candidates(stack)?; + + if candidate_set.ambiguous { + debug!("candidate set contains ambig"); + return Ok(None); + } + + let candidates = candidate_set.vec; + + debug!(?stack, ?candidates, "assembled {} candidates", candidates.len()); + + // At this point, we know that each of the entries in the + // candidate set is *individually* applicable. Now we have to + // figure out if they contain mutual incompatibilities. This + // frequently arises if we have an unconstrained input type -- + // for example, we are looking for `$0: Eq` where `$0` is some + // unconstrained type variable. In that case, we'll get a + // candidate which assumes $0 == int, one that assumes `$0 == + // usize`, etc. This spells an ambiguity. + + let mut candidates = self.filter_impls(candidates, stack.obligation); + + // If there is more than one candidate, first winnow them down + // by considering extra conditions (nested obligations and so + // forth). We don't winnow if there is exactly one + // candidate. This is a relatively minor distinction but it + // can lead to better inference and error-reporting. An + // example would be if there was an impl: + // + // impl Vec { fn push_clone(...) { ... } } + // + // and we were to see some code `foo.push_clone()` where `boo` + // is a `Vec` and `Bar` does not implement `Clone`. If + // we were to winnow, we'd wind up with zero candidates. + // Instead, we select the right impl now but report "`Bar` does + // not implement `Clone`". + if candidates.len() == 1 { + return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation); + } + + // Winnow, but record the exact outcome of evaluation, which + // is needed for specialization. Propagate overflow if it occurs. + let mut candidates = candidates + .into_iter() + .map(|c| match self.evaluate_candidate(stack, &c) { + Ok(eval) if eval.may_apply() => { + Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) + } + Ok(_) => Ok(None), + Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)), + Err(OverflowError::ErrorReporting) => Err(ErrorReporting), + Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))), + }) + .flat_map(Result::transpose) + .collect::, _>>()?; + + debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len()); + + let needs_infer = stack.obligation.predicate.has_non_region_infer(); + + // If there are STILL multiple candidates, we can further + // reduce the list by dropping duplicates -- including + // resolving specializations. + if candidates.len() > 1 { + let mut i = 0; + while i < candidates.len() { + let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| { + self.candidate_should_be_dropped_in_favor_of( + &candidates[i], + &candidates[j], + needs_infer, + ) + }); + if is_dup { + debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len()); + candidates.swap_remove(i); + } else { + debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len()); + i += 1; + + // If there are *STILL* multiple candidates, give up + // and report ambiguity. + if i > 1 { + debug!("multiple matches, ambig"); + return Ok(None); + } + } + } + } + + // If there are *NO* candidates, then there are no impls -- + // that we know of, anyway. Note that in the case where there + // are unbound type variables within the obligation, it might + // be the case that you could still satisfy the obligation + // from another crate by instantiating the type variables with + // a type from another crate that does have an impl. This case + // is checked for in `evaluate_stack` (and hence users + // who might care about this case, like coherence, should use + // that function). + if candidates.is_empty() { + // If there's an error type, 'downgrade' our result from + // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid + // emitting additional spurious errors, since we're guaranteed + // to have emitted at least one. + if stack.obligation.predicate.references_error() { + debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous"); + return Ok(None); + } + return Err(Unimplemented); + } + + // Just one candidate left. + self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation) + } + /////////////////////////////////////////////////////////////////////////// // EVALUATION // @@ -2140,6 +2344,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.match_impl(impl_def_id, impl_trait_ref, obligation) { Ok(substs) => substs, Err(()) => { + // FIXME: A rematch may fail when a candidate cache hit occurs + // on thefreshened form of the trait predicate, but the match + // fails for some reason that is not captured in the freshened + // cache key. For example, equating an impl trait ref against + // the placeholder trait ref may fail due the Generalizer relation + // raising a CyclicalTy error due to a sub_root_var relation + // for a variable being generalized... self.infcx.tcx.sess.delay_span_bug( obligation.cause.span, &format!( diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs index b0c55ca4f5139..5f8748206d764 100644 --- a/library/core/src/str/converts.rs +++ b/library/core/src/str/converts.rs @@ -77,7 +77,7 @@ use super::Utf8Error; /// let sparkle_heart = [240, 159, 146, 150]; /// /// // We know these bytes are valid, so just use `unwrap()`. -/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap(); +/// let sparkle_heart: &str = str::from_utf8(&sparkle_heart).unwrap(); /// /// assert_eq!("💖", sparkle_heart); /// ``` diff --git a/library/std/src/path.rs b/library/std/src/path.rs index af88b9070c189..6c957c2fa90eb 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1463,6 +1463,30 @@ impl PathBuf { true } + /// Yields a mutable reference to the underlying [`OsString`] instance. + /// + /// # Examples + /// + /// ``` + /// #![feature(path_as_mut_os_str)] + /// use std::path::{Path, PathBuf}; + /// + /// let mut path = PathBuf::from("/foo"); + /// + /// path.push("bar"); + /// assert_eq!(path, Path::new("/foo/bar")); + /// + /// // OsString's `push` does not add a separator. + /// path.as_mut_os_string().push("baz"); + /// assert_eq!(path, Path::new("/foo/barbaz")); + /// ``` + #[unstable(feature = "path_as_mut_os_str", issue = "105021")] + #[must_use] + #[inline] + pub fn as_mut_os_string(&mut self) -> &mut OsString { + &mut self.inner + } + /// Consumes the `PathBuf`, yielding its internal [`OsString`] storage. /// /// # Examples @@ -1993,6 +2017,28 @@ impl Path { &self.inner } + /// Yields a mutable reference to the underlying [`OsStr`] slice. + /// + /// # Examples + /// + /// ``` + /// #![feature(path_as_mut_os_str)] + /// use std::path::{Path, PathBuf}; + /// + /// let mut path = PathBuf::from("/Foo.TXT").into_boxed_path(); + /// + /// assert_ne!(&*path, Path::new("/foo.txt")); + /// + /// path.as_mut_os_str().make_ascii_lowercase(); + /// assert_eq!(&*path, Path::new("/foo.txt")); + /// ``` + #[unstable(feature = "path_as_mut_os_str", issue = "105021")] + #[must_use] + #[inline] + pub fn as_mut_os_str(&mut self) -> &mut OsStr { + &mut self.inner + } + /// Yields a [`&str`] slice if the `Path` is valid unicode. /// /// This conversion may entail doing a check for UTF-8 validity. diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs index af297ff1ec75b..6fb92c037ee4f 100644 --- a/library/std/src/sys/hermit/fs.rs +++ b/library/std/src/sys/hermit/fs.rs @@ -1,10 +1,8 @@ -use crate::convert::TryFrom; -use crate::ffi::{CStr, CString, OsString}; +use crate::ffi::{CStr, OsString}; use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::io::{self, Error, ErrorKind}; use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; -use crate::os::unix::ffi::OsStrExt; use crate::path::{Path, PathBuf}; use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::cvt; diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index e53a1fea6a0dc..8f65544a9e894 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -5,6 +5,7 @@ use crate::ffi::CStr; use crate::io; use crate::mem; use crate::num::NonZeroUsize; +use crate::ptr; use crate::sys::hermit::abi; use crate::sys::hermit::thread_local_dtor::run_dtors; use crate::time::Duration; @@ -47,7 +48,7 @@ impl Thread { extern "C" fn thread_start(main: usize) { unsafe { // Finally, let's run some code. - Box::from_raw(main as *mut Box)(); + Box::from_raw(ptr::from_exposed_addr::>(main).cast_mut())(); // run all destructors run_dtors(); diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 57128685d9110..2d5018d934e2e 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -441,6 +441,7 @@ def download_toolchain(self): self.fix_bin_or_dylib("{}/bin/rustc".format(bin_root)) self.fix_bin_or_dylib("{}/bin/rustdoc".format(bin_root)) + self.fix_bin_or_dylib("{}/libexec/rust-analyzer-proc-macro-srv".format(bin_root)) lib_dir = "{}/lib".format(bin_root) for lib in os.listdir(lib_dir): if lib.endswith(".so"): diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index d0f389df97344..6ae283f32a5f3 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -360,6 +360,7 @@ impl Config { self.fix_bin_or_dylib(&bin_root.join("bin").join("rustc")); self.fix_bin_or_dylib(&bin_root.join("bin").join("rustdoc")); + self.fix_bin_or_dylib(&bin_root.join("libexec").join("rust-analyzer-proc-macro-srv")); let lib_dir = bin_root.join("lib"); for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) { let lib = t!(lib); diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 27e911c6be5a2..d0c3ddf260624 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -214,7 +214,7 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | -[`aarch64-unknown-nto-qnx7.1.0`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.1 RTOS | +[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.1 RTOS | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) @@ -305,7 +305,7 @@ target | std | host | notes `x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64 `x86_64-apple-tvos` | * | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator -[`x86_64-pc-nto-qnx7.1.0`](platform-support/nto-qnx.md) | ? | | x86 64-bit QNX Neutrino 7.1 RTOS | +[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ? | | x86 64-bit QNX Neutrino 7.1 RTOS | [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `x86_64-pc-windows-msvc` | * | | 64-bit Windows XP support `x86_64-sun-solaris` | ? | | Deprecated target for 64-bit Solaris 10/11, illumos diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 2f6ea94d113a9..37d0c31976c77 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -93,15 +93,15 @@ Run the following: ```bash env \ - CC_aarch64-unknown-nto-qnx7.1.0="qcc" \ - CFLAGS_aarch64-unknown-nto-qnx7.1.0="-Vgcc_ntoaarch64le_cxx" \ - CXX_aarch64-unknown-nto-qnx7.1.0="qcc" \ - AR_aarch64_unknown_nto_qnx7.1.0="ntoaarch64-ar" \ - CC_x86_64-pc-nto-qnx7.1.0="qcc" \ - CFLAGS_x86_64-pc-nto-qnx7.1.0="-Vgcc_ntox86_64_cxx" \ - CXX_x86_64-pc-nto-qnx7.1.0="qcc" \ - AR_x86_64_pc_nto_qnx7.1.0="ntox86_64-ar" \ - ./x.py build --target aarch64-unknown-nto-qnx7.1.0 --target x86_64-pc-nto-qnx7.1.0 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/ + CC_aarch64-unknown-nto-qnx710="qcc" \ + CFLAGS_aarch64-unknown-nto-qnx710="-Vgcc_ntoaarch64le_cxx" \ + CXX_aarch64-unknown-nto-qnx710="qcc" \ + AR_aarch64_unknown_nto_qnx710="ntoaarch64-ar" \ + CC_x86_64-pc-nto-qnx710="qcc" \ + CFLAGS_x86_64-pc-nto-qnx710="-Vgcc_ntox86_64_cxx" \ + CXX_x86_64-pc-nto-qnx710="qcc" \ + AR_x86_64_pc_nto_qnx710="ntox86_64-ar" \ + ./x.py build --target aarch64-unknown-nto-qnx710 --target x86_64-pc-nto-qnx710 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/ ``` ## Building Rust programs diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md index df9131ce84afd..95932db14e1f6 100644 --- a/src/doc/rustc/src/target-tier-policy.md +++ b/src/doc/rustc/src/target-tier-policy.md @@ -158,6 +158,8 @@ approved by the appropriate team for that shared code before acceptance. the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it. + - If possible, use only letters, numbers, dashes and underscores for the name. + Periods (`.`) are known to cause issues in Cargo. - Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users. diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index cf5592da43205..de882e66f43de 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1511,13 +1511,11 @@ details.rustdoc-toggle > summary.hideme > span { } details.rustdoc-toggle > summary::before { - background-image: url("toggle-plus-1092eb4930d581b0.svg"); + background: url("toggle-plus-1092eb4930d581b0.svg") no-repeat top left; content: ""; cursor: pointer; width: 16px; height: 16px; - background-repeat: no-repeat; - background-position: top left; display: inline-block; vertical-align: middle; opacity: .5; @@ -1598,11 +1596,9 @@ details.rustdoc-toggle[open] > summary.hideme > span { details.rustdoc-toggle[open] > summary::before, details.rustdoc-toggle[open] > summary.hideme::before { - background-image: url("toggle-minus-31bbd6e4c77f5c96.svg"); + background: url("toggle-minus-31bbd6e4c77f5c96.svg") no-repeat top left; width: 16px; height: 16px; - background-repeat: no-repeat; - background-position: top left; display: inline-block; content: ""; } diff --git a/src/test/codegen-units/item-collection/asm-sym.rs b/src/test/codegen-units/item-collection/asm-sym.rs new file mode 100644 index 0000000000000..8bafb95bc16d9 --- /dev/null +++ b/src/test/codegen-units/item-collection/asm-sym.rs @@ -0,0 +1,20 @@ +// needs-asm-support +// compile-flags: -Ccodegen-units=1 -Zprint-mono-items=lazy --crate-type=lib + +#[inline(always)] +pub unsafe fn f() { + //~ MONO_ITEM static f::S @@ asm_sym-cgu.0[External] + static S: usize = 1; + //~ MONO_ITEM fn f::fun @@ asm_sym-cgu.0[External] + fn fun() {} + core::arch::asm!("/* {0} {1} */", sym S, sym fun); +} + +//~ MONO_ITEM fn g @@ asm_sym-cgu.0[External] +pub unsafe fn g() { + //~ MONO_ITEM static g::S @@ asm_sym-cgu.0[Internal] + static S: usize = 2; + //~ MONO_ITEM fn g::fun @@ asm_sym-cgu.0[Internal] + fn fun() {} + core::arch::asm!("/* {0} {1} */", sym S, sym fun); +} diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs new file mode 100644 index 0000000000000..ee9bce15d3478 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +trait Callable { + type Output; + fn call() -> Self::Output; +} + +impl<'a> Callable for &'a () { + type Output = impl Sized; + fn call() -> Self::Output {} +} + +fn test<'a>() -> impl Sized { + <&'a () as Callable>::call() +} + +fn want_static(_: T) {} + +fn test2<'a>() { + want_static(<&'a () as Callable>::call()); +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs new file mode 100644 index 0000000000000..ae21a9134a416 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs @@ -0,0 +1,38 @@ +#![feature(type_alias_impl_trait)] + +trait Callable { + type Output; + fn call(x: Self) -> Self::Output; +} + +trait PlusOne { + fn plus_one(&mut self); +} + +impl<'a> PlusOne for &'a mut i32 { + fn plus_one(&mut self) { + **self += 1; + } +} + +impl Callable for T { + type Output = impl PlusOne; + fn call(t: T) -> Self::Output { t } +} + +fn test<'a>(y: &'a mut i32) -> impl PlusOne { + <&'a mut i32 as Callable>::call(y) + //~^ ERROR hidden type for `impl PlusOne` captures lifetime that does not appear in bounds +} + +fn main() { + let mut z = 42; + let mut thing = test(&mut z); + let mut thing2 = test(&mut z); + thing.plus_one(); + assert_eq!(z, 43); + thing2.plus_one(); + assert_eq!(z, 44); + thing.plus_one(); + assert_eq!(z, 45); +} diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr new file mode 100644 index 0000000000000..0ed8a703b6dc5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr @@ -0,0 +1,16 @@ +error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds + --> $DIR/imply_bounds_from_bounds_param.rs:24:5 + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne { + | -- hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here +LL | <&'a mut i32 as Callable>::call(y) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/type-alias-impl-trait/self_implication.rs b/src/test/ui/type-alias-impl-trait/self_implication.rs new file mode 100644 index 0000000000000..4e805ee308f4d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self_implication.rs @@ -0,0 +1,38 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +fn foo() { + struct Foo<'a> { + x: &'a mut u8, + } + impl<'a> Foo<'a> { + fn foo(&self) -> impl Sized {} + } + // use site + let mut x = 5; + let y = Foo { x: &mut x }; + let z = y.foo(); + let _a = &x; // invalidate the `&'a mut`in `y` + let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live +} + +fn bar() { + struct Foo<'a> { + x: &'a mut u8, + } + + // desugared + type FooX<'a> = impl Sized; + impl<'a> Foo<'a> { + fn foo(&self) -> FooX<'a> {} + } + + // use site + let mut x = 5; + let y = Foo { x: &mut x }; + let z = y.foo(); + let _a = &x; // invalidate the `&'a mut`in `y` + let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live +} + +fn main() {} diff --git a/src/tools/tier-check/src/main.rs b/src/tools/tier-check/src/main.rs index a41e2d6e3aa45..c74d37c61e887 100644 --- a/src/tools/tier-check/src/main.rs +++ b/src/tools/tier-check/src/main.rs @@ -44,7 +44,23 @@ fn main() { target, filename, src ); } - if !missing.is_empty() || !extra.is_empty() { + // Check target names for unwanted characters like `.` that can cause problems e.g. in Cargo. + // See also Tier 3 target policy. + // If desired, target names can ignore this check. + let ignore_target_names = + vec!["thumbv8m.base-none-eabi", "thumbv8m.main-none-eabi", "thumbv8m.main-none-eabihf"]; + let mut invalid_target_name_found = false; + for target in &target_list { + if !ignore_target_names.contains(target) + && !target.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') + { + invalid_target_name_found = true; + eprintln!( + "error: Target name `{target}` contains other characters than ASCII alphanumeric (a-z, A-Z, 0-9), dash (-) or underscore (_)." + ); + } + } + if !missing.is_empty() || !extra.is_empty() || invalid_target_name_found { std::process::exit(1); } }