diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index a5f1cbc96daa7..6529f11100d2d 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -19,7 +19,6 @@ #![feature(rustc_attrs)] #![cfg_attr(test, feature(test))] #![feature(strict_provenance)] -#![feature(ptr_const_cast)] use smallvec::SmallVec; diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 870a7c0be33dc..2809f0b719f7b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1338,14 +1338,13 @@ pub enum ExprKind { /// /// The `PathSegment` represents the method name and its generic arguments /// (within the angle brackets). - /// The first element of the vector of an `Expr` is the expression that evaluates - /// to the object on which the method is being called on (the receiver), - /// and the remaining elements are the rest of the arguments. - /// Thus, `x.foo::(a, b, c, d)` is represented as - /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. + /// The standalone `Expr` is the receiver expression. + /// The vector of `Expr` is the arguments. + /// `x.foo::(a, b, c, d)` is represented as + /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d])`. /// This `Span` is the span of the function, without the dot and receiver /// (e.g. `foo(a, b)` in `x.foo(a, b)` - MethodCall(PathSegment, Vec>, Span), + MethodCall(PathSegment, P, Vec>, Span), /// A tuple (e.g., `(a, b, c, d)`). Tup(Vec>), /// A binary operation (e.g., `a + b`, `a * b`). @@ -3030,22 +3029,25 @@ pub type ForeignItem = Item; #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { use super::*; + use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - rustc_data_structures::static_assert_size!(AssocItemKind, 72); - rustc_data_structures::static_assert_size!(Attribute, 152); - rustc_data_structures::static_assert_size!(Block, 48); - rustc_data_structures::static_assert_size!(Expr, 104); - rustc_data_structures::static_assert_size!(Fn, 192); - rustc_data_structures::static_assert_size!(ForeignItemKind, 72); - rustc_data_structures::static_assert_size!(GenericBound, 88); - rustc_data_structures::static_assert_size!(Generics, 72); - rustc_data_structures::static_assert_size!(Impl, 200); - rustc_data_structures::static_assert_size!(Item, 200); - rustc_data_structures::static_assert_size!(ItemKind, 112); - rustc_data_structures::static_assert_size!(Lit, 48); - rustc_data_structures::static_assert_size!(Pat, 120); - rustc_data_structures::static_assert_size!(Path, 40); - rustc_data_structures::static_assert_size!(PathSegment, 24); - rustc_data_structures::static_assert_size!(Stmt, 32); - rustc_data_structures::static_assert_size!(Ty, 96); + static_assert_size!(AssocItem, 160); + static_assert_size!(AssocItemKind, 72); + static_assert_size!(Attribute, 152); + static_assert_size!(Block, 48); + static_assert_size!(Expr, 104); + static_assert_size!(Fn, 192); + static_assert_size!(ForeignItem, 160); + static_assert_size!(ForeignItemKind, 72); + static_assert_size!(GenericBound, 88); + static_assert_size!(Generics, 72); + static_assert_size!(Impl, 200); + static_assert_size!(Item, 200); + static_assert_size!(ItemKind, 112); + static_assert_size!(Lit, 48); + static_assert_size!(Pat, 120); + static_assert_size!(Path, 40); + static_assert_size!(PathSegment, 24); + static_assert_size!(Stmt, 32); + static_assert_size!(Ty, 96); } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 01bd498b37780..230c73c88e909 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1302,10 +1302,11 @@ pub fn noop_visit_expr( vis.visit_expr(f); visit_exprs(args, vis); } - ExprKind::MethodCall(PathSegment { ident, id, args }, exprs, span) => { + ExprKind::MethodCall(PathSegment { ident, id, args }, receiver, exprs, span) => { vis.visit_ident(ident); vis.visit_id(id); visit_opt(args, |args| vis.visit_generic_args(args)); + vis.visit_expr(receiver); visit_exprs(exprs, vis); vis.visit_span(span); } diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 74b7fe9e24955..5edeb54be5f0f 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -396,9 +396,9 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool { contains_exterior_struct_lit(&x) } - ast::ExprKind::MethodCall(.., ref exprs, _) => { + ast::ExprKind::MethodCall(_, ref receiver, _, _) => { // X { y: 1 }.bar(...) - contains_exterior_struct_lit(&exprs[0]) + contains_exterior_struct_lit(&receiver) } _ => false, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index d9594b323dd0d..bedbb02f033c7 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -813,8 +813,9 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { visitor.visit_expr(callee_expression); walk_list!(visitor, visit_expr, arguments); } - ExprKind::MethodCall(ref segment, ref arguments, _span) => { + ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _span) => { visitor.visit_path_segment(expression.span, segment); + visitor.visit_expr(receiver); walk_list!(visitor, visit_expr, arguments); } ExprKind::Binary(_, ref left_expression, ref right_expression) => { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index fb6715ff17ee9..c7d35fdb1fd56 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -62,7 +62,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Call(f, self.lower_exprs(args)) } } - ExprKind::MethodCall(ref seg, ref args, span) => { + ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => { let hir_seg = self.arena.alloc(self.lower_path_segment( e.span, seg, @@ -70,7 +70,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ParenthesizedGenericArgs::Err, ImplTraitContext::Disallowed(ImplTraitPosition::Path), )); - let args = self.lower_exprs(args); + let args = self.arena.alloc_from_iter( + [&*receiver].into_iter().chain(args.iter()).map(|x| self.lower_expr_mut(x)), + ); hir::ExprKind::MethodCall(hir_seg, args, self.lower_span(span)) } ExprKind::Binary(binop, ref lhs, ref rhs) => { diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 60560b1c00e25..d94f8a9af884b 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -13,9 +13,7 @@ use rustc_ast::walk_list; use rustc_ast::*; use rustc_ast_pretty::pprust::{self, State}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{ - error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, -}; +use rustc_errors::{error_code, pluralize, struct_span_err, Applicability, Diagnostic}; use rustc_parse::validate_attr; use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY, @@ -477,7 +475,7 @@ impl<'a> AstValidator<'a> { ctx: &str, msg: &str, sugg: &str, - help: impl FnOnce(&mut DiagnosticBuilder<'_, ErrorGuaranteed>), + help: impl FnOnce(&mut Diagnostic), ) { let source_map = self.session.source_map(); let end = source_map.end_point(sp); @@ -1196,7 +1194,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { let msg = "free function without a body"; let ext = sig.header.ext; - let f = |e: &mut DiagnosticBuilder<'_, _>| { + let f = |e: &mut Diagnostic| { if let Extern::Implicit(start_span) | Extern::Explicit(_, start_span) = &ext { let start_suggestion = if let Extern::Explicit(abi, _) = ext { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index ead38caee287f..bcefa8ce0b9ce 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -193,9 +193,13 @@ impl<'a> State<'a> { self.print_call_post(args) } - fn print_expr_method_call(&mut self, segment: &ast::PathSegment, args: &[P]) { - let base_args = &args[1..]; - self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX); + fn print_expr_method_call( + &mut self, + segment: &ast::PathSegment, + receiver: &ast::Expr, + base_args: &[P], + ) { + self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX); self.word("."); self.print_ident(segment.ident); if let Some(ref args) = segment.args { @@ -303,8 +307,8 @@ impl<'a> State<'a> { ast::ExprKind::Call(ref func, ref args) => { self.print_expr_call(func, &args); } - ast::ExprKind::MethodCall(ref segment, ref args, _) => { - self.print_expr_method_call(segment, &args); + ast::ExprKind::MethodCall(ref segment, ref receiver, ref args, _) => { + self.print_expr_method_call(segment, &receiver, &args); } ast::ExprKind::Binary(op, ref lhs, ref rhs) => { self.print_expr_binary(op, lhs, rhs); diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 8bc8964bbd7cc..84a0d4ba7ba10 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -451,7 +451,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn suggest_borrow_fn_like( &self, - err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, + err: &mut Diagnostic, ty: Ty<'tcx>, move_sites: &[MoveSite], value_name: &str, @@ -526,12 +526,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { true } - fn suggest_adding_copy_bounds( - &self, - err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, - ty: Ty<'tcx>, - span: Span, - ) { + fn suggest_adding_copy_bounds(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) { let tcx = self.infcx.tcx; let generics = tcx.generics_of(self.mir_def_id()); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 176090c3b7a14..bd3a2a3d69496 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -783,7 +783,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn maybe_suggest_constrain_dyn_trait_impl( &self, - diag: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, + diag: &mut Diagnostic, f: Region<'tcx>, o: Region<'tcx>, category: &ConstraintCategory<'tcx>, diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index dcea883a5a378..c04d04020cc67 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -240,8 +240,8 @@ impl<'cx, 'a> Context<'cx, 'a> { self.manage_cond_expr(prefix); self.manage_cond_expr(suffix); } - ExprKind::MethodCall(_, ref mut local_exprs, _) => { - for local_expr in local_exprs.iter_mut().skip(1) { + ExprKind::MethodCall(_, _,ref mut local_exprs, _) => { + for local_expr in local_exprs.iter_mut() { self.manage_cond_expr(local_expr); } } @@ -377,14 +377,12 @@ impl<'cx, 'a> Context<'cx, 'a> { id: DUMMY_NODE_ID, ident: Ident::new(sym::try_capture, self.span), }, - vec![ - expr_paren(self.cx, self.span, self.cx.expr_addr_of(self.span, wrapper)), - expr_addr_of_mut( - self.cx, - self.span, - self.cx.expr_path(Path::from_ident(capture)), - ), - ], + expr_paren(self.cx, self.span, self.cx.expr_addr_of(self.span, wrapper)), + vec![expr_addr_of_mut( + self.cx, + self.span, + self.cx.expr_path(Path::from_ident(capture)), + )], self.span, )) .add_trailing_semicolon(); @@ -442,10 +440,11 @@ fn expr_addr_of_mut(cx: &ExtCtxt<'_>, sp: Span, e: P) -> P { fn expr_method_call( cx: &ExtCtxt<'_>, path: PathSegment, + receiver: P, args: Vec>, span: Span, ) -> P { - cx.expr(span, ExprKind::MethodCall(path, args, span)) + cx.expr(span, ExprKind::MethodCall(path, receiver, args, span)) } fn expr_paren(cx: &ExtCtxt<'_>, sp: Span, e: P) -> P { diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 94ba62c160c98..fe80a55dfd28c 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -823,9 +823,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { use super::*; + use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - rustc_data_structures::static_assert_size!(Immediate, 56); - rustc_data_structures::static_assert_size!(ImmTy<'_>, 72); - rustc_data_structures::static_assert_size!(Operand, 64); - rustc_data_structures::static_assert_size!(OpTy<'_>, 88); + static_assert_size!(Immediate, 56); + static_assert_size!(ImmTy<'_>, 72); + static_assert_size!(Operand, 64); + static_assert_size!(OpTy<'_>, 88); } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index f4571a1ca3d8a..97fe23cb5bcf3 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -891,10 +891,11 @@ where #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { use super::*; + use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - rustc_data_structures::static_assert_size!(MemPlaceMeta, 24); - rustc_data_structures::static_assert_size!(MemPlace, 40); - rustc_data_structures::static_assert_size!(MPlaceTy<'_>, 64); - rustc_data_structures::static_assert_size!(Place, 48); - rustc_data_structures::static_assert_size!(PlaceTy<'_>, 72); + static_assert_size!(MemPlaceMeta, 24); + static_assert_size!(MemPlace, 40); + static_assert_size!(MPlaceTy<'_>, 64); + static_assert_size!(Place, 48); + static_assert_size!(PlaceTy<'_>, 72); } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index f7e1575afbf42..e009e4f7c68d0 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -14,7 +14,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; use rustc_feature::Features; use rustc_lint_defs::builtin::{ RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, @@ -608,11 +608,7 @@ enum ExplainDocComment { }, } -fn annotate_doc_comment( - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, - sm: &SourceMap, - span: Span, -) { +fn annotate_doc_comment(err: &mut Diagnostic, sm: &SourceMap, span: Span) { if let Ok(src) = sm.span_to_snippet(span) { if src.starts_with("///") || src.starts_with("/**") { err.subdiagnostic(ExplainDocComment::Outer { span }); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 617433a9803d5..7a87a3e488260 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3491,16 +3491,16 @@ impl<'hir> Node<'hir> { mod size_asserts { use super::*; // These are in alphabetical order, which is easy to maintain. - rustc_data_structures::static_assert_size!(Block<'static>, 48); - rustc_data_structures::static_assert_size!(Expr<'static>, 56); - rustc_data_structures::static_assert_size!(ForeignItem<'static>, 72); - rustc_data_structures::static_assert_size!(GenericBound<'_>, 48); - rustc_data_structures::static_assert_size!(Generics<'static>, 56); - rustc_data_structures::static_assert_size!(ImplItem<'static>, 88); - rustc_data_structures::static_assert_size!(Impl<'static>, 80); - rustc_data_structures::static_assert_size!(Item<'static>, 80); - rustc_data_structures::static_assert_size!(Pat<'static>, 88); - rustc_data_structures::static_assert_size!(QPath<'static>, 24); - rustc_data_structures::static_assert_size!(TraitItem<'static>, 96); - rustc_data_structures::static_assert_size!(Ty<'static>, 72); + static_assert_size!(Block<'static>, 48); + static_assert_size!(Expr<'static>, 56); + static_assert_size!(ForeignItem<'static>, 72); + static_assert_size!(GenericBound<'_>, 48); + static_assert_size!(Generics<'static>, 56); + static_assert_size!(ImplItem<'static>, 88); + static_assert_size!(Impl<'static>, 80); + static_assert_size!(Item<'static>, 80); + static_assert_size!(Pat<'static>, 88); + static_assert_size!(QPath<'static>, 24); + static_assert_size!(TraitItem<'static>, 96); + static_assert_size!(Ty<'static>, 72); } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 4e7ba1c6ce4fa..58b2f0a44161c 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -608,8 +608,7 @@ trait UnusedDelimLint { ref call_or_other => { let (args_to_check, ctx) = match *call_or_other { Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg), - // first "argument" is self (which sometimes needs delims) - MethodCall(_, ref args, _) => (&args[1..], UnusedDelimsCtx::MethodArg), + MethodCall(_, _, ref args, _) => (&args[..], UnusedDelimsCtx::MethodArg), // actual catch-all arm _ => { return; diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index b856af1d8f835..5e26a52900eaf 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -814,8 +814,8 @@ impl<'tcx> fmt::Display for Pat<'tcx> { mod size_asserts { use super::*; // These are in alphabetical order, which is easy to maintain. - rustc_data_structures::static_assert_size!(Block, 56); - rustc_data_structures::static_assert_size!(Expr<'_>, 104); - rustc_data_structures::static_assert_size!(Pat<'_>, 24); - rustc_data_structures::static_assert_size!(Stmt<'_>, 120); + static_assert_size!(Block, 56); + static_assert_size!(Expr<'_>, 104); + static_assert_size!(Pat<'_>, 24); + static_assert_size!(Stmt<'_>, 120); } diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index cefb5f36b6a94..ce38283724dac 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -170,7 +170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut arm_candidates = self.create_match_candidates(scrutinee_place.clone(), &arms); - let match_has_guard = arms.iter().copied().any(|arm| self.thir[arm].guard.is_some()); + let match_has_guard = arm_candidates.iter().any(|(_, candidate)| candidate.has_guard); let mut candidates = arm_candidates.iter_mut().map(|(_, candidate)| candidate).collect::>(); diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index 76b4cdd2ecd3c..7652223368964 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -70,7 +70,6 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> { build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did); let ptr_local = self.patch.new_temp(ptr_ty, source_info.span); - self.local_decls.push(LocalDecl::new(ptr_ty, source_info.span)); self.patch.add_statement(location, StatementKind::StorageLive(ptr_local)); @@ -125,13 +124,6 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs { index += 1; } - if let Some(terminator) = terminator - && !matches!(terminator.kind, TerminatorKind::Yield{..}) - { - let location = Location { block, statement_index: index }; - visitor.visit_terminator(terminator, location); - } - let location = Location { block, statement_index: index }; match terminator { // yielding into a box is handled when lowering generators diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a2155ac1d1ad4..f4c6b33a52924 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -19,7 +19,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult, }; -use rustc_errors::{pluralize, struct_span_err, Diagnostic, EmissionGuarantee, ErrorGuaranteed}; +use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, Ident}; @@ -228,13 +228,13 @@ struct MultiSugg { } impl MultiSugg { - fn emit(self, err: &mut DiagnosticBuilder<'_, G>) { + fn emit(self, err: &mut Diagnostic) { err.multipart_suggestion(&self.msg, self.patches, self.applicability); } /// Overrides individual messages and applicabilities. - fn emit_many( - err: &mut DiagnosticBuilder<'_, G>, + fn emit_many( + err: &mut Diagnostic, msg: &str, applicability: Applicability, suggestions: impl Iterator, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b8bd960a5b3d6..2880ef78c8d27 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -850,7 +850,7 @@ impl<'a> Parser<'a> { ExprKind::Index(_, _) => "indexing", ExprKind::Try(_) => "`?`", ExprKind::Field(_, _) => "a field access", - ExprKind::MethodCall(_, _, _) => "a method call", + ExprKind::MethodCall(_, _, _, _) => "a method call", ExprKind::Call(_, _) => "a function call", ExprKind::Await(_) => "`.await`", ExprKind::Err => return Ok(with_postfix), @@ -859,7 +859,7 @@ impl<'a> Parser<'a> { ); let mut err = self.struct_span_err(span, &msg); - let suggest_parens = |err: &mut DiagnosticBuilder<'_, _>| { + let suggest_parens = |err: &mut Diagnostic| { let suggestions = vec![ (span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string()), @@ -1280,12 +1280,14 @@ impl<'a> Parser<'a> { if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { // Method call `expr.f()` - let mut args = self.parse_paren_expr_seq()?; - args.insert(0, self_arg); - + let args = self.parse_paren_expr_seq()?; let fn_span = fn_span_lo.to(self.prev_token.span); let span = lo.to(self.prev_token.span); - Ok(self.mk_expr(span, ExprKind::MethodCall(segment, args, fn_span), AttrVec::new())) + Ok(self.mk_expr( + span, + ExprKind::MethodCall(segment, self_arg, args, fn_span), + AttrVec::new(), + )) } else { // Field access `expr.f` if let Some(args) = segment.args { diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index a3be827a7ccec..ec070e6a9c5c6 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -21,21 +21,55 @@ enum Id { None, } -struct NodeData { +struct NodeStats { count: usize, size: usize, } +impl NodeStats { + fn new() -> NodeStats { + NodeStats { count: 0, size: 0 } + } +} + +struct Node { + stats: NodeStats, + subnodes: FxHashMap<&'static str, NodeStats>, +} + +impl Node { + fn new() -> Node { + Node { stats: NodeStats::new(), subnodes: FxHashMap::default() } + } +} + +/// This type measures the size of AST and HIR nodes, by implementing the AST +/// and HIR `Visitor` traits. But we don't measure every visited type because +/// that could cause double counting. +/// +/// For example, `ast::Visitor` has `visit_ident`, but `Ident`s are always +/// stored inline within other AST nodes, so we don't implement `visit_ident` +/// here. In constrast, we do implement `visit_expr` because `ast::Expr` is +/// always stored as `P`, and every such expression should be +/// measured separately. +/// +/// In general, a `visit_foo` method should be implemented here if the +/// corresponding `Foo` type is always stored on its own, e.g.: `P`, +/// `Box`, `Vec`, `Box<[Foo]>`. +/// +/// There are some types in the AST and HIR tree that the visitors do not have +/// a `visit_*` method for, and so we cannot measure these, which is +/// unfortunate. struct StatCollector<'k> { krate: Option>, - data: FxHashMap<&'static str, NodeData>, + nodes: FxHashMap<&'static str, Node>, seen: FxHashSet, } pub fn print_hir_stats(tcx: TyCtxt<'_>) { let mut collector = StatCollector { krate: Some(tcx.hir()), - data: FxHashMap::default(), + nodes: FxHashMap::default(), seen: FxHashSet::default(), }; tcx.hir().walk_toplevel_module(&mut collector); @@ -44,49 +78,88 @@ pub fn print_hir_stats(tcx: TyCtxt<'_>) { } pub fn print_ast_stats(krate: &ast::Crate, title: &str) { + use rustc_ast::visit::Visitor; + let mut collector = - StatCollector { krate: None, data: FxHashMap::default(), seen: FxHashSet::default() }; - ast_visit::walk_crate(&mut collector, krate); + StatCollector { krate: None, nodes: FxHashMap::default(), seen: FxHashSet::default() }; + collector.visit_crate(krate); collector.print(title); } impl<'k> StatCollector<'k> { - fn record(&mut self, label: &'static str, id: Id, node: &T) { + // Record a top-level node. + fn record(&mut self, label: &'static str, id: Id, val: &T) { + self.record_inner(label, None, id, val); + } + + // Record a two-level entry, with a top-level enum type and a variant. + fn record_variant(&mut self, label1: &'static str, label2: &'static str, id: Id, val: &T) { + self.record_inner(label1, Some(label2), id, val); + } + + fn record_inner( + &mut self, + label1: &'static str, + label2: Option<&'static str>, + id: Id, + val: &T, + ) { if id != Id::None && !self.seen.insert(id) { return; } - let entry = self.data.entry(label).or_insert(NodeData { count: 0, size: 0 }); + let node = self.nodes.entry(label1).or_insert(Node::new()); + node.stats.count += 1; + node.stats.size = std::mem::size_of_val(val); - entry.count += 1; - entry.size = std::mem::size_of_val(node); + if let Some(label2) = label2 { + let subnode = node.subnodes.entry(label2).or_insert(NodeStats::new()); + subnode.count += 1; + subnode.size = std::mem::size_of_val(val); + } } fn print(&self, title: &str) { - let mut stats: Vec<_> = self.data.iter().collect(); - - stats.sort_by_key(|&(_, ref d)| d.count * d.size); + let mut nodes: Vec<_> = self.nodes.iter().collect(); + nodes.sort_by_key(|&(_, ref node)| node.stats.count * node.stats.size); - let mut total_size = 0; + let total_size = nodes.iter().map(|(_, node)| node.stats.count * node.stats.size).sum(); eprintln!("\n{}\n", title); eprintln!("{:<18}{:>18}{:>14}{:>14}", "Name", "Accumulated Size", "Count", "Item Size"); eprintln!("----------------------------------------------------------------"); - for (label, data) in stats { + let percent = |m, n| (m * 100) as f64 / n as f64; + + for (label, node) in nodes { + let size = node.stats.count * node.stats.size; eprintln!( - "{:<18}{:>18}{:>14}{:>14}", + "{:<18}{:>10} ({:4.1}%){:>14}{:>14}", label, - to_readable_str(data.count * data.size), - to_readable_str(data.count), - to_readable_str(data.size) + to_readable_str(size), + percent(size, total_size), + to_readable_str(node.stats.count), + to_readable_str(node.stats.size) ); - - total_size += data.count * data.size; + if !node.subnodes.is_empty() { + let mut subnodes: Vec<_> = node.subnodes.iter().collect(); + subnodes.sort_by_key(|&(_, ref subnode)| subnode.count * subnode.size); + + for (label, subnode) in subnodes { + let size = subnode.count * subnode.size; + eprintln!( + "- {:<18}{:>10} ({:4.1}%){:>14}", + label, + to_readable_str(size), + percent(size, total_size), + to_readable_str(subnode.count), + ); + } + } } eprintln!("----------------------------------------------------------------"); - eprintln!("{:<18}{:>18}\n", "Total", to_readable_str(total_size)); + eprintln!("{:<18}{:>10}\n", "Total", to_readable_str(total_size)); } } @@ -228,6 +301,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_path(self, path) } + // `PathSegment` has one inline use (in `ast::ExprKind::MethodCall`) and + // one non-inline use (in `Path::segments`). The latter case is more common + // than the former case, so we implement this visitor and tolerate the + // double counting in the former case. fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v hir::PathSegment<'v>) { self.record("PathSegment", Id::None, path_segment); hir_visit::walk_path_segment(self, path_span, path_segment) @@ -243,14 +320,54 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { } } +// Used to avoid boilerplate for types with many variants. +macro_rules! record_variants { + ( + ($self:ident, $val:expr, $kind:expr, $ty:ty, $tykind:ident), // mandatory pieces + [$($variant:ident),*] + ) => { + match $kind { + $( + ast::$tykind::$variant { .. } => { + $self.record_variant(stringify!($ty), stringify!($variant), Id::None, $val) + } + )* + } + }; +} + impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { fn visit_foreign_item(&mut self, i: &'v ast::ForeignItem) { - self.record("ForeignItem", Id::None, i); + record_variants!( + (self, i, i.kind, ForeignItem, ForeignItemKind), + [Static, Fn, TyAlias, MacCall] + ); ast_visit::walk_foreign_item(self, i) } fn visit_item(&mut self, i: &'v ast::Item) { - self.record("Item", Id::None, i); + record_variants!( + (self, i, i.kind, Item, ItemKind), + [ + ExternCrate, + Use, + Static, + Const, + Fn, + Mod, + ForeignMod, + GlobalAsm, + TyAlias, + Enum, + Struct, + Union, + Trait, + TraitAlias, + Impl, + MacCall, + MacroDef + ] + ); ast_visit::walk_item(self, i) } @@ -265,47 +382,116 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { } fn visit_stmt(&mut self, s: &'v ast::Stmt) { - self.record("Stmt", Id::None, s); + record_variants!( + (self, s, s.kind, Stmt, StmtKind), + [Local, Item, Expr, Semi, Empty, MacCall] + ); ast_visit::walk_stmt(self, s) } + fn visit_param(&mut self, p: &'v ast::Param) { + self.record("Param", Id::None, p); + ast_visit::walk_param(self, p) + } + fn visit_arm(&mut self, a: &'v ast::Arm) { self.record("Arm", Id::None, a); ast_visit::walk_arm(self, a) } fn visit_pat(&mut self, p: &'v ast::Pat) { - self.record("Pat", Id::None, p); + record_variants!( + (self, p, p.kind, Pat, PatKind), + [ + Wild, + Ident, + Struct, + TupleStruct, + Or, + Path, + Tuple, + Box, + Ref, + Lit, + Range, + Slice, + Rest, + Paren, + MacCall + ] + ); ast_visit::walk_pat(self, p) } - fn visit_expr(&mut self, ex: &'v ast::Expr) { - self.record("Expr", Id::None, ex); - ast_visit::walk_expr(self, ex) + fn visit_expr(&mut self, e: &'v ast::Expr) { + record_variants!( + (self, e, e.kind, Expr, ExprKind), + [ + Box, Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let, + If, While, ForLoop, Loop, Match, Closure, Block, Async, Await, TryBlock, Assign, + AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret, + InlineAsm, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, Err + ] + ); + ast_visit::walk_expr(self, e) } fn visit_ty(&mut self, t: &'v ast::Ty) { - self.record("Ty", Id::None, t); + record_variants!( + (self, t, t.kind, Ty, TyKind), + [ + Slice, + Array, + Ptr, + Rptr, + BareFn, + Never, + Tup, + Path, + TraitObject, + ImplTrait, + Paren, + Typeof, + Infer, + ImplicitSelf, + MacCall, + Err, + CVarArgs + ] + ); + ast_visit::walk_ty(self, t) } + fn visit_generic_param(&mut self, g: &'v ast::GenericParam) { + self.record("GenericParam", Id::None, g); + ast_visit::walk_generic_param(self, g) + } + + fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) { + record_variants!( + (self, p, p, WherePredicate, WherePredicate), + [BoundPredicate, RegionPredicate, EqPredicate] + ); + ast_visit::walk_where_predicate(self, p) + } + fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, s: Span, _: NodeId) { self.record("FnDecl", Id::None, fk.decl()); ast_visit::walk_fn(self, fk, s) } - fn visit_assoc_item(&mut self, item: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) { - let label = match ctxt { - ast_visit::AssocCtxt::Trait => "TraitItem", - ast_visit::AssocCtxt::Impl => "ImplItem", - }; - self.record(label, Id::None, item); - ast_visit::walk_assoc_item(self, item, ctxt); + fn visit_assoc_item(&mut self, i: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) { + record_variants!( + (self, i, i.kind, AssocItem, AssocItemKind), + [Const, Fn, TyAlias, MacCall] + ); + ast_visit::walk_assoc_item(self, i, ctxt); } - fn visit_param_bound(&mut self, bounds: &'v ast::GenericBound, _ctxt: BoundKind) { - self.record("GenericBound", Id::None, bounds); - ast_visit::walk_param_bound(self, bounds) + fn visit_param_bound(&mut self, b: &'v ast::GenericBound, _ctxt: BoundKind) { + record_variants!((self, b, b, GenericBound, GenericBound), [Trait, Outlives]); + ast_visit::walk_param_bound(self, b) } fn visit_field_def(&mut self, s: &'v ast::FieldDef) { @@ -318,27 +504,42 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ast_visit::walk_variant(self, v) } - fn visit_lifetime(&mut self, lifetime: &'v ast::Lifetime, _: ast_visit::LifetimeCtxt) { - self.record("Lifetime", Id::None, lifetime); - ast_visit::walk_lifetime(self, lifetime) - } - - fn visit_mac_call(&mut self, mac: &'v ast::MacCall) { - self.record("MacCall", Id::None, mac); - ast_visit::walk_mac(self, mac) - } + // `UseTree` has one inline use (in `ast::ItemKind::Use`) and one + // non-inline use (in `ast::UseTreeKind::Nested). The former case is more + // common, so we don't implement `visit_use_tree` and tolerate the missed + // coverage in the latter case. fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v ast::PathSegment) { self.record("PathSegment", Id::None, path_segment); ast_visit::walk_path_segment(self, path_span, path_segment) } - fn visit_assoc_constraint(&mut self, constraint: &'v ast::AssocConstraint) { - self.record("AssocConstraint", Id::None, constraint); - ast_visit::walk_assoc_constraint(self, constraint) + // `GenericArgs` has one inline use (in `ast::AssocConstraint::gen_args`) and one + // non-inline use (in `ast::PathSegment::args`). The latter case is more + // common, so we implement `visit_generic_args` and tolerate the double + // counting in the former case. + fn visit_generic_args(&mut self, sp: Span, g: &'v ast::GenericArgs) { + record_variants!((self, g, g, GenericArgs, GenericArgs), [AngleBracketed, Parenthesized]); + ast_visit::walk_generic_args(self, sp, g) } fn visit_attribute(&mut self, attr: &'v ast::Attribute) { - self.record("Attribute", Id::None, attr); + record_variants!((self, attr, attr.kind, Attribute, AttrKind), [Normal, DocComment]); + ast_visit::walk_attribute(self, attr) + } + + fn visit_expr_field(&mut self, f: &'v ast::ExprField) { + self.record("ExprField", Id::None, f); + ast_visit::walk_expr_field(self, f) + } + + fn visit_crate(&mut self, krate: &'v ast::Crate) { + self.record("Crate", Id::None, krate); + ast_visit::walk_crate(self, krate) + } + + fn visit_inline_asm(&mut self, asm: &'v ast::InlineAsm) { + self.record("InlineAsm", Id::None, asm); + ast_visit::walk_inline_asm(self, asm) } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ac8d26fb0724a..cbd0ca49c99bc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3796,9 +3796,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ExprKind::Field(ref subexpression, _) => { self.resolve_expr(subexpression, Some(expr)); } - ExprKind::MethodCall(ref segment, ref arguments, _) => { - let mut arguments = arguments.iter(); - self.resolve_expr(arguments.next().unwrap(), Some(expr)); + ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _) => { + self.resolve_expr(receiver, Some(expr)); for argument in arguments { self.resolve_expr(argument, None); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 2b1f2b88ec445..cb133841bca5a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2021,9 +2021,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn suggest_introducing_lifetime( &self, - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + err: &mut Diagnostic, name: Option<&str>, - suggest: impl Fn(&mut DiagnosticBuilder<'_, ErrorGuaranteed>, bool, Span, &str, String) -> bool, + suggest: impl Fn(&mut Diagnostic, bool, Span, &str, String) -> bool, ) { let mut suggest_note = true; for rib in self.lifetime_ribs.iter().rev() { @@ -2149,7 +2149,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { pub(crate) fn add_missing_lifetime_specifiers_label( &mut self, - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + err: &mut Diagnostic, lifetime_refs: Vec, function_param_lifetimes: Option<(Vec, Vec)>, ) { diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 8a5c7fee697d1..758f1ef97664f 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -16,7 +16,8 @@ use crate::require_c_abi_if_c_variadic; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ - struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan, + struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError, + MultiSpan, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; @@ -2106,7 +2107,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { pub fn prohibit_generics<'a>( &self, segments: impl Iterator> + Clone, - extend: impl Fn(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>), + extend: impl Fn(&mut Diagnostic), ) -> bool { let args = segments.clone().flat_map(|segment| segment.args().args); @@ -2984,11 +2985,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } /// Make sure that we are in the condition to suggest the blanket implementation. - fn maybe_lint_blanket_trait_impl( - &self, - self_ty: &hir::Ty<'_>, - diag: &mut DiagnosticBuilder<'_, T>, - ) { + fn maybe_lint_blanket_trait_impl(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) { let tcx = self.tcx(); let parent_id = tcx.hir().get_parent_item(self_ty.hir_id); if let hir::Node::Item(hir::Item { @@ -3081,7 +3078,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { sugg, Applicability::MachineApplicable, ); - self.maybe_lint_blanket_trait_impl::<()>(&self_ty, &mut diag); + self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag); diag.emit(); }, ); diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index 7aaddc2bd7aab..6c7b2a2889fa4 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -32,6 +32,7 @@ use super::FnCtxt; use crate::hir::def_id::DefId; use crate::type_error_struct; +use hir::def_id::LOCAL_CRATE; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; @@ -40,7 +41,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable, VariantDef}; use rustc_session::lint; use rustc_session::Session; use rustc_span::symbol::sym; @@ -173,6 +174,7 @@ pub enum CastError { /// or "a length". If this argument is None, then the metadata is unknown, for example, /// when we're typechecking a type parameter with a ?Sized bound. IntToFatCast(Option<&'static str>), + ForeignNonExhaustiveAdt, } impl From for CastError { @@ -591,6 +593,17 @@ impl<'a, 'tcx> CastCheck<'tcx> { } err.emit(); } + CastError::ForeignNonExhaustiveAdt => { + make_invalid_casting_error( + fcx.tcx.sess, + self.span, + self.expr_ty, + self.cast_ty, + fcx, + ) + .note("cannot cast an enum with a non-exhaustive variant when it's defined in another crate") + .emit(); + } } } @@ -789,6 +802,14 @@ impl<'a, 'tcx> CastCheck<'tcx> { _ => return Err(CastError::NonScalar), }; + if let ty::Adt(adt_def, _) = *self.expr_ty.kind() { + if adt_def.did().krate != LOCAL_CRATE { + if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) { + return Err(CastError::ForeignNonExhaustiveAdt); + } + } + } + match (t_from, t_cast) { // These types have invariants! can't cast into them. (_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar), diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 6e3ef15f88433..5cdb2acd9f3c5 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -1525,9 +1525,7 @@ fn detect_discriminant_duplicate<'tcx>( ) { // Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate. // Here `idx` refers to the order of which the discriminant appears, and its index in `vs` - let report = |dis: Discr<'tcx>, - idx: usize, - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>| { + let report = |dis: Discr<'tcx>, idx: usize, err: &mut Diagnostic| { let var = &vs[idx]; // HIR for the duplicate discriminant let (span, display_discr) = match var.disr_expr { Some(ref expr) => { diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 49dc5532abdc9..6c6bbfa22e30c 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1585,9 +1585,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } } } - fn note_unreachable_loop_return<'a>( + fn note_unreachable_loop_return( &self, - err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>, + err: &mut Diagnostic, expr: &hir::Expr<'tcx>, ret_exprs: &Vec<&'tcx hir::Expr<'tcx>>, ) { diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index a685add7f56a6..6a6c03a8cba83 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -28,7 +28,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, - EmissionGuarantee, ErrorGuaranteed, + ErrorGuaranteed, }; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; @@ -879,7 +879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lhs: &'tcx hir::Expr<'tcx>, err_code: &'static str, op_span: Span, - adjust_err: impl FnOnce(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>), + adjust_err: impl FnOnce(&mut Diagnostic), ) { if lhs.is_syntactic_place_expr() { return; @@ -1089,8 +1089,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); - let suggest_deref_binop = |err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, - rhs_ty: Ty<'tcx>| { + let suggest_deref_binop = |err: &mut Diagnostic, rhs_ty: Ty<'tcx>| { if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) { // Can only assign if the type is sized, so if `DerefMut` yields a type that is // unsized, do not suggest dereferencing it. @@ -2205,9 +2204,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx().ty_error() } - fn check_call_constructor( + fn check_call_constructor( &self, - err: &mut DiagnosticBuilder<'_, G>, + err: &mut Diagnostic, base: &'tcx hir::Expr<'tcx>, def_id: DefId, ) { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 660e7e4e39931..1d1f755947fdc 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1778,7 +1778,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn label_fn_like( &self, - err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>, + err: &mut Diagnostic, callable_def_id: Option, callee_ty: Option>, ) { diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index f73d0fbb27716..44c7c148c7533 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -904,7 +904,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - let label_span_not_found = |err: &mut DiagnosticBuilder<'_, _>| { + let label_span_not_found = |err: &mut Diagnostic| { if unsatisfied_predicates.is_empty() { err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); let is_string_or_ref_str = match actual.kind() { @@ -1154,7 +1154,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty: Ty<'tcx>, expr: &hir::Expr<'_>, item_name: Ident, - err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, + err: &mut Diagnostic, ) -> bool { let tcx = self.tcx; let field_receiver = self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() { @@ -1331,7 +1331,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_for_field_method( &self, - err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, + err: &mut Diagnostic, source: SelfSource<'tcx>, span: Span, actual: Ty<'tcx>, @@ -1380,7 +1380,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_for_unwrap_self( &self, - err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, + err: &mut Diagnostic, source: SelfSource<'tcx>, span: Span, actual: Ty<'tcx>, diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index b73d9a9eb7599..1b50209ee64cc 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -104,7 +104,7 @@ use crate::astconv::AstConv; use crate::check::gather_locals::GatherLocalsVisitor; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ - pluralize, struct_span_err, Applicability, DiagnosticBuilder, EmissionGuarantee, MultiSpan, + pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan, }; use rustc_hir as hir; use rustc_hir::def::Res; @@ -973,12 +973,7 @@ fn has_expected_num_generic_args<'tcx>( /// * `span` - The span of the snippet /// * `params` - The number of parameters the constructor accepts /// * `err` - A mutable diagnostic builder to add the suggestion to -fn suggest_call_constructor( - span: Span, - kind: CtorOf, - params: usize, - err: &mut DiagnosticBuilder<'_, G>, -) { +fn suggest_call_constructor(span: Span, kind: CtorOf, params: usize, err: &mut Diagnostic) { // Note: tuple-structs don't have named fields, so just use placeholders let args = vec!["_"; params].join(", "); let applicable = if params > 0 { diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 920b3e688089b..eb0c51bb2f979 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -59,7 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // Suppress this error, since we already emitted // a deref suggestion in check_overloaded_binop - err.delay_as_bug(); + err.downgrade_to_delayed_bug(); } } }); diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 2cd6e23c71a3e..c0f609a01b5c8 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -95,8 +95,8 @@ impl *const T { /// /// This is a bit safer than `as` because it wouldn't silently change the type if the code is /// refactored. - #[unstable(feature = "ptr_const_cast", issue = "92675")] - #[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")] + #[stable(feature = "ptr_const_cast", since = "1.65.0")] + #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] pub const fn cast_mut(self) -> *mut T { self as _ } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 56ad5f7658e3d..7059d0008c4c4 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -100,8 +100,8 @@ impl *mut T { /// coercion. /// /// [`cast_mut`]: #method.cast_mut - #[unstable(feature = "ptr_const_cast", issue = "92675")] - #[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")] + #[stable(feature = "ptr_const_cast", since = "1.65.0")] + #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] pub const fn cast_const(self) -> *const T { self as _ } diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 36a3fa6023bfb..7db3065dee083 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -116,11 +116,9 @@ impl Thread { debug_assert_eq!(ret, 0); } - #[cfg(any(target_os = "linux", target_os = "android"))] + #[cfg(target_os = "android")] pub fn set_name(name: &CStr) { const PR_SET_NAME: libc::c_int = 15; - // pthread wrapper only appeared in glibc 2.12, so we use syscall - // directly. unsafe { libc::prctl( PR_SET_NAME, @@ -132,6 +130,14 @@ impl Thread { } } + #[cfg(target_os = "linux")] + pub fn set_name(name: &CStr) { + unsafe { + // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20. + libc::pthread_setname_np(libc::pthread_self(), name.as_ptr()); + } + } + #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))] pub fn set_name(name: &CStr) { unsafe { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index ed1d883d0dca6..baad0c75295a5 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -924,6 +924,11 @@ fn compare_browser_ui_test_version(installed_version: &str, src: &Path) { one used in the CI (`{}`)", installed_version, v ); + eprintln!( + "You can install this version using `npm update browser-ui-test` or by using \ + `npm install browser-ui-test@{}`", + v, + ); } } Err(e) => eprintln!("Couldn't find the CI browser-ui-test version: {:?}", e), diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 01dd95e6e4093..da15c3c2b1fab 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -120,7 +120,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { items: cx.tcx .associated_items(impl_def_id) .in_definition_order() - .map(|x| x.clean(cx)) + .map(|x| clean_middle_assoc_item(x, cx)) .collect::>(), polarity: ty::ImplPolarity::Positive, kind: ImplKind::Blanket(Box::new(clean_middle_ty(trait_ref.0.self_ty(), cx, None))), diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 4e9456ba7cb71..e56a715e85780 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -16,9 +16,10 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use crate::clean::{ - self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_field, - clean_middle_ty, clean_trait_ref_with_bindings, clean_ty, clean_ty_generics, clean_variant_def, - clean_visibility, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId, Type, Visibility, + self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item, + clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty, + clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt, + ImplKind, ItemId, Type, Visibility, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -217,7 +218,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean // which causes methods to have a `pub` prefix, which is invalid since items in traits // can not have a visibility prefix. Thus we override the visibility here manually. // See https://github.com/rust-lang/rust/issues/81274 - clean::Item { visibility: Visibility::Inherited, ..item.clean(cx) } + clean::Item { visibility: Visibility::Inherited, ..clean_middle_assoc_item(item, cx) } }) .collect(); @@ -452,7 +453,7 @@ pub(crate) fn build_impl( item.visibility(tcx).is_public() } }) - .map(|item| item.clean(cx)) + .map(|item| clean_middle_assoc_item(item, cx)) .collect::>(), clean::enter_impl_trait(cx, |cx| { clean_ty_generics(cx, tcx.generics_of(did), predicates) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 402e4f29860a2..6e24638548979 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -123,7 +123,7 @@ fn clean_generic_bound<'tcx>( let trait_ref = ty::TraitRef::identity(cx.tcx, def_id).skip_binder(); - let generic_args = generic_args.clean(cx); + let generic_args = clean_generic_args(generic_args, cx); let GenericArgs::AngleBracketed { bindings, .. } = generic_args else { bug!("clean: parenthesized `GenericBound::LangItemTrait`"); @@ -1092,199 +1092,201 @@ pub(crate) fn clean_impl_item<'tcx>( }) } -impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { - let tcx = cx.tcx; - let kind = match self.kind { - ty::AssocKind::Const => { - let ty = clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)); - - let provided = match self.container { - ty::ImplContainer => true, - ty::TraitContainer => tcx.impl_defaultness(self.def_id).has_value(), - }; - if provided { - AssocConstItem(ty, ConstantKind::Extern { def_id: self.def_id }) - } else { - TyAssocConstItem(ty) - } +pub(crate) fn clean_middle_assoc_item<'tcx>( + assoc_item: &ty::AssocItem, + cx: &mut DocContext<'tcx>, +) -> Item { + let tcx = cx.tcx; + let kind = match assoc_item.kind { + ty::AssocKind::Const => { + let ty = clean_middle_ty(tcx.type_of(assoc_item.def_id), cx, Some(assoc_item.def_id)); + + let provided = match assoc_item.container { + ty::ImplContainer => true, + ty::TraitContainer => tcx.impl_defaultness(assoc_item.def_id).has_value(), + }; + if provided { + AssocConstItem(ty, ConstantKind::Extern { def_id: assoc_item.def_id }) + } else { + TyAssocConstItem(ty) } - ty::AssocKind::Fn => { - let generics = clean_ty_generics( - cx, - tcx.generics_of(self.def_id), - tcx.explicit_predicates_of(self.def_id), - ); - let sig = tcx.fn_sig(self.def_id); - let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(self.def_id), sig); - - if self.fn_has_self_parameter { - let self_ty = match self.container { - ty::ImplContainer => tcx.type_of(self.container_id(tcx)), - ty::TraitContainer => tcx.types.self_param, - }; - let self_arg_ty = sig.input(0).skip_binder(); - if self_arg_ty == self_ty { - decl.inputs.values[0].type_ = Generic(kw::SelfUpper); - } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() { - if ty == self_ty { - match decl.inputs.values[0].type_ { - BorrowedRef { ref mut type_, .. } => { - **type_ = Generic(kw::SelfUpper) - } - _ => unreachable!(), - } + } + ty::AssocKind::Fn => { + let generics = clean_ty_generics( + cx, + tcx.generics_of(assoc_item.def_id), + tcx.explicit_predicates_of(assoc_item.def_id), + ); + let sig = tcx.fn_sig(assoc_item.def_id); + let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig); + + if assoc_item.fn_has_self_parameter { + let self_ty = match assoc_item.container { + ty::ImplContainer => tcx.type_of(assoc_item.container_id(tcx)), + ty::TraitContainer => tcx.types.self_param, + }; + let self_arg_ty = sig.input(0).skip_binder(); + if self_arg_ty == self_ty { + decl.inputs.values[0].type_ = Generic(kw::SelfUpper); + } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() { + if ty == self_ty { + match decl.inputs.values[0].type_ { + BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper), + _ => unreachable!(), } } } + } - let provided = match self.container { - ty::ImplContainer => true, - ty::TraitContainer => self.defaultness(tcx).has_value(), + let provided = match assoc_item.container { + ty::ImplContainer => true, + ty::TraitContainer => assoc_item.defaultness(tcx).has_value(), + }; + if provided { + let defaultness = match assoc_item.container { + ty::ImplContainer => Some(assoc_item.defaultness(tcx)), + ty::TraitContainer => None, }; - if provided { - let defaultness = match self.container { - ty::ImplContainer => Some(self.defaultness(tcx)), - ty::TraitContainer => None, - }; - MethodItem(Box::new(Function { generics, decl }), defaultness) - } else { - TyMethodItem(Box::new(Function { generics, decl })) - } + MethodItem(Box::new(Function { generics, decl }), defaultness) + } else { + TyMethodItem(Box::new(Function { generics, decl })) } - ty::AssocKind::Type => { - let my_name = self.name; - - fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool { - match (¶m.kind, arg) { - (GenericParamDefKind::Type { .. }, GenericArg::Type(Type::Generic(ty))) - if *ty == param.name => - { - true - } - ( - GenericParamDefKind::Lifetime { .. }, - GenericArg::Lifetime(Lifetime(lt)), - ) if *lt == param.name => true, - (GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => { - match &c.kind { - ConstantKind::TyConst { expr } => expr == param.name.as_str(), - _ => false, - } - } - _ => false, + } + ty::AssocKind::Type => { + let my_name = assoc_item.name; + + fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool { + match (¶m.kind, arg) { + (GenericParamDefKind::Type { .. }, GenericArg::Type(Type::Generic(ty))) + if *ty == param.name => + { + true + } + (GenericParamDefKind::Lifetime { .. }, GenericArg::Lifetime(Lifetime(lt))) + if *lt == param.name => + { + true } + (GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &c.kind { + ConstantKind::TyConst { expr } => expr == param.name.as_str(), + _ => false, + }, + _ => false, } + } - if let ty::TraitContainer = self.container { - let bounds = tcx.explicit_item_bounds(self.def_id); - let predicates = ty::GenericPredicates { parent: None, predicates: bounds }; - let mut generics = - clean_ty_generics(cx, tcx.generics_of(self.def_id), predicates); - // Filter out the bounds that are (likely?) directly attached to the associated type, - // as opposed to being located in the where clause. - let mut bounds = generics - .where_predicates - .drain_filter(|pred| match *pred { - WherePredicate::BoundPredicate { - ty: QPath { ref assoc, ref self_type, ref trait_, .. }, - .. - } => { - if assoc.name != my_name { - return false; - } - if trait_.def_id() != self.container_id(tcx) { - return false; - } - match **self_type { - Generic(ref s) if *s == kw::SelfUpper => {} - _ => return false, - } - match &assoc.args { - GenericArgs::AngleBracketed { args, bindings } => { - if !bindings.is_empty() - || generics - .params - .iter() - .zip(args.iter()) - .any(|(param, arg)| !param_eq_arg(param, arg)) - { - return false; - } - } - GenericArgs::Parenthesized { .. } => { - // The only time this happens is if we're inside the rustdoc for Fn(), - // which only has one associated type, which is not a GAT, so whatever. + if let ty::TraitContainer = assoc_item.container { + let bounds = tcx.explicit_item_bounds(assoc_item.def_id); + let predicates = ty::GenericPredicates { parent: None, predicates: bounds }; + let mut generics = + clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), predicates); + // Filter out the bounds that are (likely?) directly attached to the associated type, + // as opposed to being located in the where clause. + let mut bounds = generics + .where_predicates + .drain_filter(|pred| match *pred { + WherePredicate::BoundPredicate { + ty: QPath { ref assoc, ref self_type, ref trait_, .. }, + .. + } => { + if assoc.name != my_name { + return false; + } + if trait_.def_id() != assoc_item.container_id(tcx) { + return false; + } + match **self_type { + Generic(ref s) if *s == kw::SelfUpper => {} + _ => return false, + } + match &assoc.args { + GenericArgs::AngleBracketed { args, bindings } => { + if !bindings.is_empty() + || generics + .params + .iter() + .zip(args.iter()) + .any(|(param, arg)| !param_eq_arg(param, arg)) + { + return false; } } - true - } - _ => false, - }) - .flat_map(|pred| { - if let WherePredicate::BoundPredicate { bounds, .. } = pred { - bounds - } else { - unreachable!() + GenericArgs::Parenthesized { .. } => { + // The only time this happens is if we're inside the rustdoc for Fn(), + // which only has one associated type, which is not a GAT, so whatever. + } } - }) - .collect::>(); - // Our Sized/?Sized bound didn't get handled when creating the generics - // because we didn't actually get our whole set of bounds until just now - // (some of them may have come from the trait). If we do have a sized - // bound, we remove it, and if we don't then we add the `?Sized` bound - // at the end. - match bounds.iter().position(|b| b.is_sized_bound(cx)) { - Some(i) => { - bounds.remove(i); + true } - None => bounds.push(GenericBound::maybe_sized(cx)), + _ => false, + }) + .flat_map(|pred| { + if let WherePredicate::BoundPredicate { bounds, .. } = pred { + bounds + } else { + unreachable!() + } + }) + .collect::>(); + // Our Sized/?Sized bound didn't get handled when creating the generics + // because we didn't actually get our whole set of bounds until just now + // (some of them may have come from the trait). If we do have a sized + // bound, we remove it, and if we don't then we add the `?Sized` bound + // at the end. + match bounds.iter().position(|b| b.is_sized_bound(cx)) { + Some(i) => { + bounds.remove(i); } + None => bounds.push(GenericBound::maybe_sized(cx)), + } - if tcx.impl_defaultness(self.def_id).has_value() { - AssocTypeItem( - Box::new(Typedef { - type_: clean_middle_ty( - tcx.type_of(self.def_id), - cx, - Some(self.def_id), - ), - generics, - // FIXME: should we obtain the Type from HIR and pass it on here? - item_type: None, - }), - bounds, - ) - } else { - TyAssocTypeItem(Box::new(generics), bounds) - } - } else { - // FIXME: when could this happen? Associated items in inherent impls? + if tcx.impl_defaultness(assoc_item.def_id).has_value() { AssocTypeItem( Box::new(Typedef { - type_: clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)), - generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, + type_: clean_middle_ty( + tcx.type_of(assoc_item.def_id), + cx, + Some(assoc_item.def_id), + ), + generics, + // FIXME: should we obtain the Type from HIR and pass it on here? item_type: None, }), - Vec::new(), + bounds, ) + } else { + TyAssocTypeItem(Box::new(generics), bounds) } + } else { + // FIXME: when could this happen? Associated items in inherent impls? + AssocTypeItem( + Box::new(Typedef { + type_: clean_middle_ty( + tcx.type_of(assoc_item.def_id), + cx, + Some(assoc_item.def_id), + ), + generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, + item_type: None, + }), + Vec::new(), + ) } - }; + } + }; - let mut what_rustc_thinks = - Item::from_def_id_and_parts(self.def_id, Some(self.name), kind, cx); + let mut what_rustc_thinks = + Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx); - let impl_ref = tcx.impl_trait_ref(tcx.parent(self.def_id)); + let impl_ref = tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)); - // Trait impl items always inherit the impl's visibility -- - // we don't want to show `pub`. - if impl_ref.is_some() { - what_rustc_thinks.visibility = Visibility::Inherited; - } - - what_rustc_thinks + // Trait impl items always inherit the impl's visibility -- + // we don't want to show `pub`. + if impl_ref.is_some() { + what_rustc_thinks.visibility = Visibility::Inherited; } + + what_rustc_thinks } fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type { @@ -1824,39 +1826,44 @@ fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path { Path { res: path.res, segments: path.segments.iter().map(|x| x.clean(cx)).collect() } } -impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericArgs { - if self.parenthesized { - let output = clean_ty(self.bindings[0].ty(), cx); - let output = - if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None }; - let inputs = self.inputs().iter().map(|x| clean_ty(x, cx)).collect::>().into(); - GenericArgs::Parenthesized { inputs, output } - } else { - let args = self - .args - .iter() - .map(|arg| match arg { - hir::GenericArg::Lifetime(lt) if !lt.is_elided() => { - GenericArg::Lifetime(clean_lifetime(*lt, cx)) - } - hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), - hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)), - hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))), - hir::GenericArg::Infer(_inf) => GenericArg::Infer, - }) - .collect::>() - .into(); - let bindings = - self.bindings.iter().map(|x| clean_type_binding(x, cx)).collect::>().into(); - GenericArgs::AngleBracketed { args, bindings } - } +fn clean_generic_args<'tcx>( + generic_args: &hir::GenericArgs<'tcx>, + cx: &mut DocContext<'tcx>, +) -> GenericArgs { + if generic_args.parenthesized { + let output = clean_ty(generic_args.bindings[0].ty(), cx); + let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None }; + let inputs = + generic_args.inputs().iter().map(|x| clean_ty(x, cx)).collect::>().into(); + GenericArgs::Parenthesized { inputs, output } + } else { + let args = generic_args + .args + .iter() + .map(|arg| match arg { + hir::GenericArg::Lifetime(lt) if !lt.is_elided() => { + GenericArg::Lifetime(clean_lifetime(*lt, cx)) + } + hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), + hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)), + hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))), + hir::GenericArg::Infer(_inf) => GenericArg::Infer, + }) + .collect::>() + .into(); + let bindings = generic_args + .bindings + .iter() + .map(|x| clean_type_binding(x, cx)) + .collect::>() + .into(); + GenericArgs::AngleBracketed { args, bindings } } } impl<'tcx> Clean<'tcx, PathSegment> for hir::PathSegment<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> PathSegment { - PathSegment { name: self.ident.name, args: self.args().clean(cx) } + PathSegment { name: self.ident.name, args: clean_generic_args(self.args(), cx) } } } @@ -2226,7 +2233,10 @@ fn clean_type_binding<'tcx>( cx: &mut DocContext<'tcx>, ) -> TypeBinding { TypeBinding { - assoc: PathSegment { name: type_binding.ident.name, args: type_binding.gen_args.clean(cx) }, + assoc: PathSegment { + name: type_binding.ident.name, + args: clean_generic_args(type_binding.gen_args, cx), + }, kind: match type_binding.kind { hir::TypeBindingKind::Equality { ref term } => { TypeBindingKind::Equality { term: clean_hir_term(term, cx) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0e6de842cc267..91d5758077c94 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2495,14 +2495,15 @@ impl SubstParam { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { use super::*; + use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - rustc_data_structures::static_assert_size!(Crate, 72); // frequently moved by-value - rustc_data_structures::static_assert_size!(DocFragment, 32); - rustc_data_structures::static_assert_size!(GenericArg, 80); - rustc_data_structures::static_assert_size!(GenericArgs, 32); - rustc_data_structures::static_assert_size!(GenericParamDef, 56); - rustc_data_structures::static_assert_size!(Item, 56); - rustc_data_structures::static_assert_size!(ItemKind, 112); - rustc_data_structures::static_assert_size!(PathSegment, 40); - rustc_data_structures::static_assert_size!(Type, 72); + static_assert_size!(Crate, 72); // frequently moved by-value + static_assert_size!(DocFragment, 32); + static_assert_size!(GenericArg, 80); + static_assert_size!(GenericArgs, 32); + static_assert_size!(GenericParamDef, 56); + static_assert_size!(Item, 56); + static_assert_size!(ItemKind, 112); + static_assert_size!(PathSegment, 40); + static_assert_size!(Type, 72); } diff --git a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff index f2d4bee1bf94d..73fdf14049896 100644 --- a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff @@ -12,8 +12,6 @@ let mut _7: std::boxed::Box; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 let mut _8: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 let mut _9: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 - let mut _10: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 - let mut _11: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 scope 1 { debug x => _1; // in scope 1 at $DIR/boxes.rs:+1:9: +1:10 } diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff index deaba70e082ed..5dfcd2d54ca27 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff @@ -10,15 +10,14 @@ let mut _5: std::boxed::Box>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 let mut _7: *const std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - let mut _8: *const std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 -+ let mut _9: &mut std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ let mut _8: &mut std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 scope 1 { debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11 } scope 2 { } + scope 3 (inlined Vec::::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43 -+ let mut _10: alloc::raw_vec::RawVec; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ let mut _9: alloc::raw_vec::RawVec; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + } bb0: { @@ -37,10 +36,10 @@ StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 _7 = (((_5.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 - (*_7) = Vec::::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -+ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -+ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -+ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ _10 = const alloc::raw_vec::RawVec::::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ _9 = const alloc::raw_vec::RawVec::::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL // mir::Constant - // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 - // + user_ty: UserType(1) @@ -51,11 +50,11 @@ + // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // + user_ty: UserType(0) + // + literal: Const { ty: alloc::raw_vec::RawVec, val: Unevaluated(alloc::raw_vec::RawVec::::NEW, [u32], None) } -+ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ ((*_9).0: alloc::raw_vec::RawVec) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ Deinit((*_8)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_8).0: alloc::raw_vec::RawVec) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff index deaba70e082ed..5dfcd2d54ca27 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff @@ -10,15 +10,14 @@ let mut _5: std::boxed::Box>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 let mut _7: *const std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - let mut _8: *const std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 -+ let mut _9: &mut std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ let mut _8: &mut std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 scope 1 { debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11 } scope 2 { } + scope 3 (inlined Vec::::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43 -+ let mut _10: alloc::raw_vec::RawVec; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ let mut _9: alloc::raw_vec::RawVec; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + } bb0: { @@ -37,10 +36,10 @@ StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 _7 = (((_5.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 - (*_7) = Vec::::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -+ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -+ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -+ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ _10 = const alloc::raw_vec::RawVec::::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ _9 = const alloc::raw_vec::RawVec::::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL // mir::Constant - // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 - // + user_ty: UserType(1) @@ -51,11 +50,11 @@ + // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // + user_ty: UserType(0) + // + literal: Const { ty: alloc::raw_vec::RawVec, val: Unevaluated(alloc::raw_vec::RawVec::::NEW, [u32], None) } -+ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ ((*_9).0: alloc::raw_vec::RawVec) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ Deinit((*_8)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_8).0: alloc::raw_vec::RawVec) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs index a679b7b4e1913..0d9c9350efca4 100644 --- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs @@ -74,10 +74,10 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P)) { 2 => { let seg = PathSegment::from_ident(Ident::from_str("x")); iter_exprs(depth - 1, &mut |e| { - g(ExprKind::MethodCall(seg.clone(), vec![e, make_x()], DUMMY_SP)) + g(ExprKind::MethodCall(seg.clone(), e, vec![make_x()], DUMMY_SP)) }); iter_exprs(depth - 1, &mut |e| { - g(ExprKind::MethodCall(seg.clone(), vec![make_x(), e], DUMMY_SP)) + g(ExprKind::MethodCall(seg.clone(), make_x(), vec![e], DUMMY_SP)) }); } 3..=8 => { diff --git a/src/test/ui/cfg/cfg-method-receiver.rs b/src/test/ui/cfg/cfg-method-receiver.rs new file mode 100644 index 0000000000000..78a072f503fab --- /dev/null +++ b/src/test/ui/cfg/cfg-method-receiver.rs @@ -0,0 +1,12 @@ +macro_rules! cbor_map { + ($key:expr) => { + $key.signum(); + //~^ ERROR can't call method `signum` on ambiguous numeric type `{integer}` [E0689] + }; +} + +fn main() { + cbor_map! { #[cfg(test)] 4}; + //~^ ERROR attributes on expressions are experimental + //~| ERROR removing an expression is not supported in this position +} diff --git a/src/test/ui/cfg/cfg-method-receiver.stderr b/src/test/ui/cfg/cfg-method-receiver.stderr new file mode 100644 index 0000000000000..517fc8168e72d --- /dev/null +++ b/src/test/ui/cfg/cfg-method-receiver.stderr @@ -0,0 +1,34 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/cfg-method-receiver.rs:9:17 + | +LL | cbor_map! { #[cfg(test)] 4}; + | ^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error: removing an expression is not supported in this position + --> $DIR/cfg-method-receiver.rs:9:17 + | +LL | cbor_map! { #[cfg(test)] 4}; + | ^^^^^^^^^^^^ + +error[E0689]: can't call method `signum` on ambiguous numeric type `{integer}` + --> $DIR/cfg-method-receiver.rs:3:14 + | +LL | $key.signum(); + | ^^^^^^ +... +LL | cbor_map! { #[cfg(test)] 4}; + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `cbor_map` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you must specify a concrete type for this numeric value, like `i32` + | +LL | cbor_map! { #[cfg(test)] 4_i32}; + | ~~~~~ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0658, E0689. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs b/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs index d9657bac77685..5dce8180f5920 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs @@ -1,5 +1,4 @@ // aux-build:enums.rs -// run-pass extern crate enums; @@ -7,11 +6,6 @@ use enums::FieldLessWithNonExhaustiveVariant; fn main() { let e = FieldLessWithNonExhaustiveVariant::default(); - // FIXME: https://github.com/rust-lang/rust/issues/91161 - // This `as` cast *should* be an error, since it would fail - // if the non-exhaustive variant got fields. But today it - // doesn't. The fix for that will update this test to - // show an error (and not be run-pass any more). - let d = e as u8; + let d = e as u8; //~ ERROR casting `FieldLessWithNonExhaustiveVariant` as `u8` is invalid [E0606] assert_eq!(d, 0); } diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.stderr new file mode 100644 index 0000000000000..a61dcf8399f17 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.stderr @@ -0,0 +1,11 @@ +error[E0606]: casting `FieldLessWithNonExhaustiveVariant` as `u8` is invalid + --> $DIR/enum-as-cast.rs:9:13 + | +LL | let d = e as u8; + | ^^^^^^^ + | + = note: cannot cast an enum with a non-exhaustive variant when it's defined in another crate + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0606`. diff --git a/src/test/ui/stats/hir-stats.rs b/src/test/ui/stats/hir-stats.rs new file mode 100644 index 0000000000000..a24b3ada57e59 --- /dev/null +++ b/src/test/ui/stats/hir-stats.rs @@ -0,0 +1,41 @@ +// check-pass +// compile-flags: -Zhir-stats +// only-x86_64 + +// The aim here is to include at least one of every different type of top-level +// AST/HIR node reported by `-Zhir-stats`. + +#![allow(dead_code)] + +use std::arch::asm; +use std::fmt::Debug; +use std::ffi::c_void; + +extern "C" { fn f(p: *mut c_void); } + +/// An enum. +enum E<'a, T: Copy> { A { t: T }, B(&'a u32) } + +trait Go { + type G: Debug; + fn go(self) -> u32; +} + +impl<'a, T: Copy> Go for E<'a, T> { + type G = bool; + fn go(self) -> u32 { + 99 + } +} + +fn f2(t: T) where T: Debug {} + +fn main() { + let x = E::A { t: 3 }; + match x { + E::A { .. } => {} + _ => {} + } + + unsafe { asm!("mov rdi, 1"); } +} diff --git a/src/test/ui/stats/hir-stats.stderr b/src/test/ui/stats/hir-stats.stderr new file mode 100644 index 0000000000000..f4874408c9094 --- /dev/null +++ b/src/test/ui/stats/hir-stats.stderr @@ -0,0 +1,151 @@ + +PRE EXPANSION AST STATS + +Name Accumulated Size Count Item Size +---------------------------------------------------------------- +ExprField 48 ( 0.5%) 1 48 +GenericArgs 64 ( 0.7%) 1 64 +- AngleBracketed 64 ( 0.7%) 1 +Local 72 ( 0.8%) 1 72 +WherePredicate 72 ( 0.8%) 1 72 +- BoundPredicate 72 ( 0.8%) 1 +Crate 72 ( 0.8%) 1 72 +Arm 96 ( 1.0%) 2 48 +FieldDef 160 ( 1.7%) 2 80 +ForeignItem 160 ( 1.7%) 1 160 +- Fn 160 ( 1.7%) 1 +Stmt 160 ( 1.7%) 5 32 +- Local 32 ( 0.3%) 1 +- MacCall 32 ( 0.3%) 1 +- Expr 96 ( 1.0%) 3 +Param 160 ( 1.7%) 4 40 +FnDecl 200 ( 2.2%) 5 40 +Variant 240 ( 2.6%) 2 120 +Block 288 ( 3.1%) 6 48 +Attribute 304 ( 3.3%) 2 152 +- Normal 152 ( 1.7%) 1 +- DocComment 152 ( 1.7%) 1 +GenericBound 352 ( 3.8%) 4 88 +- Trait 352 ( 3.8%) 4 +GenericParam 520 ( 5.7%) 5 104 +AssocItem 640 ( 7.0%) 4 160 +- TyAlias 320 ( 3.5%) 2 +- Fn 320 ( 3.5%) 2 +PathSegment 720 ( 7.9%) 30 24 +Expr 832 ( 9.1%) 8 104 +- Path 104 ( 1.1%) 1 +- Match 104 ( 1.1%) 1 +- Struct 104 ( 1.1%) 1 +- Lit 208 ( 2.3%) 2 +- Block 312 ( 3.4%) 3 +Pat 840 ( 9.2%) 7 120 +- Struct 120 ( 1.3%) 1 +- Wild 120 ( 1.3%) 1 +- Ident 600 ( 6.6%) 5 +Ty 1_344 (14.7%) 14 96 +- Rptr 96 ( 1.0%) 1 +- Ptr 96 ( 1.0%) 1 +- ImplicitSelf 192 ( 2.1%) 2 +- Path 960 (10.5%) 10 +Item 1_800 (19.7%) 9 200 +- Trait 200 ( 2.2%) 1 +- Enum 200 ( 2.2%) 1 +- ForeignMod 200 ( 2.2%) 1 +- Impl 200 ( 2.2%) 1 +- Fn 400 ( 4.4%) 2 +- Use 600 ( 6.6%) 3 +---------------------------------------------------------------- +Total 9_144 + + +POST EXPANSION AST STATS + +Name Accumulated Size Count Item Size +---------------------------------------------------------------- +ExprField 48 ( 0.5%) 1 48 +GenericArgs 64 ( 0.6%) 1 64 +- AngleBracketed 64 ( 0.6%) 1 +Local 72 ( 0.7%) 1 72 +WherePredicate 72 ( 0.7%) 1 72 +- BoundPredicate 72 ( 0.7%) 1 +Crate 72 ( 0.7%) 1 72 +Arm 96 ( 0.9%) 2 48 +InlineAsm 120 ( 1.2%) 1 120 +FieldDef 160 ( 1.6%) 2 80 +ForeignItem 160 ( 1.6%) 1 160 +- Fn 160 ( 1.6%) 1 +Stmt 160 ( 1.6%) 5 32 +- Local 32 ( 0.3%) 1 +- Semi 32 ( 0.3%) 1 +- Expr 96 ( 0.9%) 3 +Param 160 ( 1.6%) 4 40 +FnDecl 200 ( 2.0%) 5 40 +Variant 240 ( 2.4%) 2 120 +Block 288 ( 2.8%) 6 48 +GenericBound 352 ( 3.5%) 4 88 +- Trait 352 ( 3.5%) 4 +GenericParam 520 ( 5.1%) 5 104 +Attribute 608 ( 6.0%) 4 152 +- DocComment 152 ( 1.5%) 1 +- Normal 456 ( 4.5%) 3 +AssocItem 640 ( 6.3%) 4 160 +- TyAlias 320 ( 3.2%) 2 +- Fn 320 ( 3.2%) 2 +PathSegment 792 ( 7.8%) 33 24 +Pat 840 ( 8.3%) 7 120 +- Struct 120 ( 1.2%) 1 +- Wild 120 ( 1.2%) 1 +- Ident 600 ( 5.9%) 5 +Expr 936 ( 9.2%) 9 104 +- Path 104 ( 1.0%) 1 +- Match 104 ( 1.0%) 1 +- Struct 104 ( 1.0%) 1 +- InlineAsm 104 ( 1.0%) 1 +- Lit 208 ( 2.1%) 2 +- Block 312 ( 3.1%) 3 +Ty 1_344 (13.2%) 14 96 +- Rptr 96 ( 0.9%) 1 +- Ptr 96 ( 0.9%) 1 +- ImplicitSelf 192 ( 1.9%) 2 +- Path 960 ( 9.5%) 10 +Item 2_200 (21.7%) 11 200 +- Trait 200 ( 2.0%) 1 +- Enum 200 ( 2.0%) 1 +- ExternCrate 200 ( 2.0%) 1 +- ForeignMod 200 ( 2.0%) 1 +- Impl 200 ( 2.0%) 1 +- Fn 400 ( 3.9%) 2 +- Use 800 ( 7.9%) 4 +---------------------------------------------------------------- +Total 10_144 + + +HIR STATS + +Name Accumulated Size Count Item Size +---------------------------------------------------------------- +Param 64 ( 0.7%) 2 32 +Local 64 ( 0.7%) 1 64 +ForeignItem 72 ( 0.7%) 1 72 +FieldDef 96 ( 1.0%) 2 48 +Arm 96 ( 1.0%) 2 48 +Stmt 96 ( 1.0%) 3 32 +FnDecl 120 ( 1.2%) 3 40 +Lifetime 128 ( 1.3%) 4 32 +Variant 160 ( 1.6%) 2 80 +ImplItem 176 ( 1.8%) 2 88 +GenericBound 192 ( 2.0%) 4 48 +TraitItem 192 ( 2.0%) 2 96 +WherePredicate 216 ( 2.2%) 3 72 +Block 288 ( 3.0%) 6 48 +QPath 408 ( 4.2%) 17 24 +Pat 440 ( 4.5%) 5 88 +Attribute 608 ( 6.2%) 4 152 +Expr 672 ( 6.9%) 12 56 +Item 960 ( 9.9%) 12 80 +Ty 1_152 (11.8%) 16 72 +Path 1_296 (13.3%) 27 48 +PathSegment 2_240 (23.0%) 40 56 +---------------------------------------------------------------- +Total 9_736 + diff --git a/src/tools/clippy/clippy_lints/src/double_parens.rs b/src/tools/clippy/clippy_lints/src/double_parens.rs index a33ef5ce6e37c..0f1d701865e7d 100644 --- a/src/tools/clippy/clippy_lints/src/double_parens.rs +++ b/src/tools/clippy/clippy_lints/src/double_parens.rs @@ -61,9 +61,8 @@ impl EarlyLintPass for DoubleParens { } } }, - ExprKind::MethodCall(_, ref params, _) => { - if params.len() == 2 { - let param = ¶ms[1]; + ExprKind::MethodCall(_, _, ref params, _) => { + if let [ref param] = params[..] { if let ExprKind::Paren(_) = param.kind { span_lint(cx, DOUBLE_PARENS, param.span, msg); } diff --git a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs index 3f5286ba097b5..d9ee031c9f975 100644 --- a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs @@ -37,9 +37,9 @@ declare_lint_pass!(OptionEnvUnwrap => [OPTION_ENV_UNWRAP]); impl EarlyLintPass for OptionEnvUnwrap { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { if_chain! { - if let ExprKind::MethodCall(path_segment, args, _) = &expr.kind; + if let ExprKind::MethodCall(path_segment, receiver, _, _) = &expr.kind; if matches!(path_segment.ident.name, sym::expect | sym::unwrap); - if let ExprKind::Call(caller, _) = &args[0].kind; + if let ExprKind::Call(caller, _) = &receiver.kind; if is_direct_expn_of(caller.span, "option_env").is_some(); then { span_lint_and_help( diff --git a/src/tools/clippy/clippy_lints/src/precedence.rs b/src/tools/clippy/clippy_lints/src/precedence.rs index cc0533c9f5d1a..e6e3ad05ad70a 100644 --- a/src/tools/clippy/clippy_lints/src/precedence.rs +++ b/src/tools/clippy/clippy_lints/src/precedence.rs @@ -109,12 +109,12 @@ impl EarlyLintPass for Precedence { let mut arg = operand; let mut all_odd = true; - while let ExprKind::MethodCall(path_segment, args, _) = &arg.kind { + while let ExprKind::MethodCall(path_segment, receiver, _, _) = &arg.kind { let path_segment_str = path_segment.ident.name.as_str(); all_odd &= ALLOWED_ODD_FUNCTIONS .iter() .any(|odd_function| **odd_function == *path_segment_str); - arg = args.first().expect("A method always has a receiver."); + arg = receiver; } if_chain! { diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs index fe8859905953f..5d36f0f5ff8bc 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs @@ -595,7 +595,7 @@ fn ident_difference_expr_with_base_location( | (Unary(_, _), Unary(_, _)) | (Binary(_, _, _), Binary(_, _, _)) | (Tup(_), Tup(_)) - | (MethodCall(_, _, _), MethodCall(_, _, _)) + | (MethodCall(_, _, _, _), MethodCall(_, _, _, _)) | (Call(_, _), Call(_, _)) | (ConstBlock(_), ConstBlock(_)) | (Array(_), Array(_)) diff --git a/src/tools/clippy/clippy_lints/src/unused_rounding.rs b/src/tools/clippy/clippy_lints/src/unused_rounding.rs index 306afe4414847..e1ec357838dbd 100644 --- a/src/tools/clippy/clippy_lints/src/unused_rounding.rs +++ b/src/tools/clippy/clippy_lints/src/unused_rounding.rs @@ -30,11 +30,10 @@ declare_clippy_lint! { declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]); fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> { - if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind + if let ExprKind::MethodCall(name_ident, receiver, _, _) = &expr.kind && let method_name = name_ident.ident.name.as_str() && (method_name == "ceil" || method_name == "round" || method_name == "floor") - && !args.is_empty() - && let ExprKind::Lit(spanned) = &args[0].kind + && let ExprKind::Lit(spanned) = &receiver.kind && let LitKind::Float(symbol, ty) = spanned.kind { let f = symbol.as_str().parse::().unwrap(); let f_str = symbol.to_string() + if let LitFloatType::Suffixed(ty) = ty { diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index b226026323be8..9f74729bdfa18 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -147,7 +147,9 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value), (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)), - (MethodCall(lc, la, _), MethodCall(rc, ra, _)) => eq_path_seg(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)), + (MethodCall(lc, ls, la, _), MethodCall(rc, rs, ra, _)) => { + eq_path_seg(lc, rc) && eq_expr(ls, rs) && over(la, ra, |l, r| eq_expr(l, r)) + }, (Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr), (Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r), (Lit(l), Lit(r)) => l.kind == r.kind, diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index a512185036915..70d5f94472f6b 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -201,6 +201,19 @@ async function main(argv) { process.setMaxListeners(opts["jobs"] + 1); } + // We catch this "event" to display a nicer message in case of unexpected exit (because of a + // missing `--no-sandbox`). + const exitHandling = (code) => { + if (!opts["no_sandbox"]) { + console.log(""); + console.log( + "`browser-ui-test` crashed unexpectedly. Please try again with adding `--test-args \ +--no-sandbox` at the end. For example: `x.py test src/test/rustdoc-gui --test-args --no-sandbox`"); + console.log(""); + } + }; + process.on('exit', exitHandling); + const tests_queue = []; let results = { successful: [], @@ -247,6 +260,9 @@ async function main(argv) { } status_bar.finish(); + // We don't need this listener anymore. + process.removeListener("exit", exitHandling); + if (debug) { results.successful.sort(by_filename); results.successful.forEach(r => { diff --git a/src/tools/rustfmt/src/chains.rs b/src/tools/rustfmt/src/chains.rs index e26e24ec55ad6..fcc02eca42987 100644 --- a/src/tools/rustfmt/src/chains.rs +++ b/src/tools/rustfmt/src/chains.rs @@ -145,7 +145,7 @@ impl ChainItemKind { fn from_ast(context: &RewriteContext<'_>, expr: &ast::Expr) -> (ChainItemKind, Span) { let (kind, span) = match expr.kind { - ast::ExprKind::MethodCall(ref segment, ref expressions, _) => { + ast::ExprKind::MethodCall(ref segment, ref receiver, ref expressions, _) => { let types = if let Some(ref generic_args) = segment.args { if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args { data.args @@ -163,7 +163,7 @@ impl ChainItemKind { } else { vec![] }; - let span = mk_sp(expressions[0].span.hi(), expr.span.hi()); + let span = mk_sp(receiver.span.hi(), expr.span.hi()); let kind = ChainItemKind::MethodCall(segment.clone(), types, expressions.clone()); (kind, span) } @@ -253,7 +253,7 @@ impl ChainItem { format!("::<{}>", type_list.join(", ")) }; let callee_str = format!(".{}{}", rewrite_ident(context, method_name), type_str); - rewrite_call(context, &callee_str, &args[1..], span, shape) + rewrite_call(context, &callee_str, &args, span, shape) } } @@ -400,8 +400,8 @@ impl Chain { // is a try! macro, we'll convert it to shorthand when the option is set. fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext<'_>) -> Option { match expr.kind { - ast::ExprKind::MethodCall(_, ref expressions, _) => { - Some(Self::convert_try(&expressions[0], context)) + ast::ExprKind::MethodCall(_, ref receiver, _, _) => { + Some(Self::convert_try(&receiver, context)) } ast::ExprKind::Field(ref subexpr, _) | ast::ExprKind::Try(ref subexpr)