diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 9b6bfaadef05a..fb9d71b52a8a6 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2890,6 +2890,20 @@ pub struct Fn { pub body: Option>, } +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct StaticItem { + pub ty: P, + pub mutability: Mutability, + pub expr: Option>, +} + +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct ConstItem { + pub defaultness: Defaultness, + pub ty: P, + pub expr: Option>, +} + #[derive(Clone, Encodable, Decodable, Debug)] pub enum ItemKind { /// An `extern crate` item, with the optional *original* crate name if the crate was renamed. @@ -2903,11 +2917,11 @@ pub enum ItemKind { /// A static item (`static`). /// /// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`. - Static(P, Mutability, Option>), + Static(Box), /// A constant item (`const`). /// /// E.g., `const FOO: i32 = 42;`. - Const(Defaultness, P, Option>), + Const(Box), /// A function declaration (`fn`). /// /// E.g., `fn foo(bar: usize) -> usize { .. }`. @@ -3023,7 +3037,7 @@ pub type AssocItem = Item; pub enum AssocItemKind { /// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`. /// If `def` is parsed, then the constant is provided, and otherwise required. - Const(Defaultness, P, Option>), + Const(Box), /// An associated function. Fn(Box), /// An associated type. @@ -3035,7 +3049,7 @@ pub enum AssocItemKind { impl AssocItemKind { pub fn defaultness(&self) -> Defaultness { match *self { - Self::Const(defaultness, ..) + Self::Const(box ConstItem { defaultness, .. }) | Self::Fn(box Fn { defaultness, .. }) | Self::Type(box TyAlias { defaultness, .. }) => defaultness, Self::MacCall(..) => Defaultness::Final, @@ -3046,7 +3060,7 @@ impl AssocItemKind { impl From for ItemKind { fn from(assoc_item_kind: AssocItemKind) -> ItemKind { match assoc_item_kind { - AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c), + AssocItemKind::Const(item) => ItemKind::Const(item), AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind), AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind), AssocItemKind::MacCall(a) => ItemKind::MacCall(a), @@ -3059,7 +3073,7 @@ impl TryFrom for AssocItemKind { fn try_from(item_kind: ItemKind) -> Result { Ok(match item_kind { - ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c), + ItemKind::Const(item) => AssocItemKind::Const(item), ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind), ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind), ItemKind::MacCall(a) => AssocItemKind::MacCall(a), @@ -3084,7 +3098,9 @@ pub enum ForeignItemKind { impl From for ItemKind { fn from(foreign_item_kind: ForeignItemKind) -> ItemKind { match foreign_item_kind { - ForeignItemKind::Static(a, b, c) => ItemKind::Static(a, b, c), + ForeignItemKind::Static(a, b, c) => { + ItemKind::Static(StaticItem { ty: a, mutability: b, expr: c }.into()) + } ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind), ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind), ForeignItemKind::MacCall(a) => ItemKind::MacCall(a), @@ -3097,7 +3113,9 @@ impl TryFrom for ForeignItemKind { fn try_from(item_kind: ItemKind) -> Result { Ok(match item_kind { - ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c), + ItemKind::Static(box StaticItem { ty: a, mutability: b, expr: c }) => { + ForeignItemKind::Static(a, b, c) + } ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind), ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind), ItemKind::MacCall(a) => ForeignItemKind::MacCall(a), @@ -3114,8 +3132,8 @@ mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // tidy-alphabetical-start - static_assert_size!(AssocItem, 104); - static_assert_size!(AssocItemKind, 32); + static_assert_size!(AssocItem, 88); + static_assert_size!(AssocItemKind, 16); static_assert_size!(Attribute, 32); static_assert_size!(Block, 32); static_assert_size!(Expr, 72); diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 514978f5569a7..2424073ae53ad 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -7,10 +7,10 @@ //! a `MutVisitor` renaming item names in a module will miss all of those //! that are created by the expansion of a macro. -use crate::ast::*; use crate::ptr::P; use crate::token::{self, Token}; use crate::tokenstream::*; +use crate::{ast::*, StaticItem}; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_data_structures::sync::Lrc; @@ -1030,14 +1030,12 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { match kind { ItemKind::ExternCrate(_orig_name) => {} ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), - ItemKind::Static(ty, _, expr) => { + ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => { vis.visit_ty(ty); visit_opt(expr, |expr| vis.visit_expr(expr)); } - ItemKind::Const(defaultness, ty, expr) => { - visit_defaultness(defaultness, vis); - vis.visit_ty(ty); - visit_opt(expr, |expr| vis.visit_expr(expr)); + ItemKind::Const(item) => { + visit_const_item(item, vis); } ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { visit_defaultness(defaultness, vis); @@ -1120,10 +1118,8 @@ pub fn noop_flat_map_assoc_item( visitor.visit_vis(vis); visit_attrs(attrs, visitor); match kind { - AssocItemKind::Const(defaultness, ty, expr) => { - visit_defaultness(defaultness, visitor); - visitor.visit_ty(ty); - visit_opt(expr, |expr| visitor.visit_expr(expr)); + AssocItemKind::Const(item) => { + visit_const_item(item, visitor); } AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { visit_defaultness(defaultness, visitor); @@ -1153,6 +1149,15 @@ pub fn noop_flat_map_assoc_item( smallvec![item] } +fn visit_const_item( + ConstItem { defaultness, ty, expr }: &mut ConstItem, + visitor: &mut T, +) { + visit_defaultness(defaultness, visitor); + visitor.visit_ty(ty); + visit_opt(expr, |expr| visitor.visit_expr(expr)); +} + pub fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) { let FnHeader { unsafety, asyncness, constness, ext: _ } = header; visit_constness(constness, vis); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index e5a0ad1f1e481..3b08467fde2bf 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -13,7 +13,7 @@ //! instance, a walker looking for item names in a module will miss all of //! those that are created by the expansion of a macro. -use crate::ast::*; +use crate::{ast::*, StaticItem}; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -305,8 +305,9 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { match &item.kind { ItemKind::ExternCrate(_) => {} ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, item.id, false), - ItemKind::Static(typ, _, expr) | ItemKind::Const(_, typ, expr) => { - visitor.visit_ty(typ); + ItemKind::Static(box StaticItem { ty, mutability: _, expr }) + | ItemKind::Const(box ConstItem { ty, expr, .. }) => { + visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { @@ -674,7 +675,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, visitor.visit_ident(ident); walk_list!(visitor, visit_attribute, attrs); match kind { - AssocItemKind::Const(_, ty, expr) => { + AssocItemKind::Const(box ConstItem { ty, expr, .. }) => { visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 2efffbb6dc5e3..f89e254a2f54d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -229,12 +229,12 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs) } - ItemKind::Static(t, m, e) => { + ItemKind::Static(box ast::StaticItem { ty: t, mutability: m, expr: e }) => { let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); hir::ItemKind::Static(ty, *m, body_id) } - ItemKind::Const(_, t, e) => { - let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); + ItemKind::Const(box ast::ConstItem { ty, expr, .. }) => { + let (ty, body_id) = self.lower_const_item(ty, span, expr.as_deref()); hir::ItemKind::Const(ty, body_id) } ItemKind::Fn(box Fn { @@ -708,10 +708,10 @@ impl<'hir> LoweringContext<'_, 'hir> { let trait_item_def_id = hir_id.expect_owner(); let (generics, kind, has_default) = match &i.kind { - AssocItemKind::Const(_, ty, default) => { + AssocItemKind::Const(box ConstItem { ty, expr, .. }) => { let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); - let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); + let body = expr.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some()) } AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => { @@ -809,7 +809,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_attrs(hir_id, &i.attrs); let (generics, kind) = match &i.kind { - AssocItemKind::Const(_, ty, expr) => { + AssocItemKind::Const(box ConstItem { ty, expr, .. }) => { let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); ( diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 44b6c77fc4195..236ebd04ae88d 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -9,8 +9,8 @@ use itertools::{Either, Itertools}; use rustc_ast::ptr::P; use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}; -use rustc_ast::walk_list; use rustc_ast::*; +use rustc_ast::{walk_list, StaticItem}; use rustc_ast_pretty::pprust::{self, State}; use rustc_data_structures::fx::FxIndexMap; use rustc_macros::Subdiagnostic; @@ -983,14 +983,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.err_handler().emit_err(errors::FieldlessUnion { span: item.span }); } } - ItemKind::Const(def, .., None) => { - self.check_defaultness(item.span, *def); + ItemKind::Const(box ConstItem { defaultness, expr: None, .. }) => { + self.check_defaultness(item.span, *defaultness); self.session.emit_err(errors::ConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), }); } - ItemKind::Static(.., None) => { + ItemKind::Static(box StaticItem { expr: None, .. }) => { self.session.emit_err(errors::StaticWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), @@ -1259,13 +1259,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if ctxt == AssocCtxt::Impl { match &item.kind { - AssocItemKind::Const(_, _, body) => { - if body.is_none() { - self.session.emit_err(errors::AssocConstWithoutBody { - span: item.span, - replace_span: self.ending_semi_or_hi(item.span), - }); - } + AssocItemKind::Const(box ConstItem { expr: None, .. }) => { + self.session.emit_err(errors::AssocConstWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + }); } AssocItemKind::Fn(box Fn { body, .. }) => { if body.is_none() { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index de94c1bc47794..b3923b651eb3b 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -485,17 +485,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { if let Some(args) = constraint.gen_args.as_ref() && matches!( args, - ast::GenericArgs::ReturnTypeNotation(..) | ast::GenericArgs::Parenthesized(..) + ast::GenericArgs::ReturnTypeNotation(..) ) { - // RTN is gated elsewhere, and parenthesized args will turn into - // another error. - if matches!(args, ast::GenericArgs::Parenthesized(..)) { - self.sess.delay_span_bug( - constraint.span, - "should have emitted a parenthesized generics error", - ); - } + // RTN is gated below with a `gate_all`. } else { gate_feature_post!( &self, diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index bf2c73a66a2cb..c465f8c948a80 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -2,6 +2,7 @@ use crate::pp::Breaks::Inconsistent; use crate::pprust::state::delimited::IterDelimited; use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT}; +use ast::StaticItem; use rustc_ast as ast; use rustc_ast::GenericBound; use rustc_ast::ModKind; @@ -156,7 +157,7 @@ impl<'a> State<'a> { self.print_use_tree(tree); self.word(";"); } - ast::ItemKind::Static(ty, mutbl, body) => { + ast::ItemKind::Static(box StaticItem { ty, mutability: mutbl, expr: body }) => { let def = ast::Defaultness::Final; self.print_item_const( item.ident, @@ -167,8 +168,15 @@ impl<'a> State<'a> { def, ); } - ast::ItemKind::Const(def, ty, body) => { - self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, *def); + ast::ItemKind::Const(box ast::ConstItem { defaultness, ty, expr }) => { + self.print_item_const( + item.ident, + None, + ty, + expr.as_deref(), + &item.vis, + *defaultness, + ); } ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { self.print_fn_full( @@ -507,8 +515,8 @@ impl<'a> State<'a> { ast::AssocItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs); } - ast::AssocItemKind::Const(def, ty, body) => { - self.print_item_const(ident, None, ty, body.as_deref(), vis, *def); + ast::AssocItemKind::Const(box ast::ConstItem { defaultness, ty, expr }) => { + self.print_item_const(ident, None, ty, expr.as_deref(), vis, *defaultness); } ast::AssocItemKind::Type(box ast::TyAlias { defaultness, diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index 8023ef60d2052..2c387edfef073 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -63,7 +63,7 @@ impl LocalUseMap { elements: &RegionValueElements, body: &Body<'_>, ) -> Self { - let nones = IndexVec::from_elem_n(None, body.local_decls.len()); + let nones = IndexVec::from_elem(None, &body.local_decls); let mut local_use_map = LocalUseMap { first_def_at: nones.clone(), first_use_at: nones.clone(), @@ -76,7 +76,7 @@ impl LocalUseMap { } let mut locals_with_use_data: IndexVec = - IndexVec::from_elem_n(false, body.local_decls.len()); + IndexVec::from_elem(false, &body.local_decls); live_locals.iter().for_each(|&local| locals_with_use_data[local] = true); LocalUseMapBuild { local_use_map: &mut local_use_map, elements, locals_with_use_data } diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 41b51bae73645..866cc5adbf3b1 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -25,12 +25,12 @@ pub fn expand( // FIXME - if we get deref patterns, use them to reduce duplication here let (item, is_stmt, ty_span) = if let Annotatable::Item(item) = &item - && let ItemKind::Static(ty, ..) = &item.kind + && let ItemKind::Static(box ast::StaticItem { ty, ..}) = &item.kind { (item, false, ecx.with_def_site_ctxt(ty.span)) } else if let Annotatable::Stmt(stmt) = &item && let StmtKind::Item(item) = &stmt.kind - && let ItemKind::Static(ty, ..) = &item.kind + && let ItemKind::Static(box ast::StaticItem { ty, ..}) = &item.kind { (item, true, ecx.with_def_site_ctxt(ty.span)) } else { diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 44b9c4718a75f..a76ed4ee6cee3 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -254,25 +254,27 @@ pub fn expand_test_or_bench( let location_info = get_location_info(cx, &item); - let mut test_const = cx.item( - sp, - Ident::new(item.ident.name, sp), - thin_vec![ - // #[cfg(test)] - cx.attr_nested_word(sym::cfg, sym::test, attr_sp), - // #[rustc_test_marker = "test_case_sort_key"] - cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp), - ], - // const $ident: test::TestDescAndFn = - ast::ItemKind::Const( - ast::Defaultness::Final, - cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), - // test::TestDescAndFn { - Some( - cx.expr_struct( - sp, - test_path("TestDescAndFn"), - thin_vec![ + let mut test_const = + cx.item( + sp, + Ident::new(item.ident.name, sp), + thin_vec![ + // #[cfg(test)] + cx.attr_nested_word(sym::cfg, sym::test, attr_sp), + // #[rustc_test_marker = "test_case_sort_key"] + cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp), + ], + // const $ident: test::TestDescAndFn = + ast::ItemKind::Const( + ast::ConstItem { + defaultness: ast::Defaultness::Final, + ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), + // test::TestDescAndFn { + expr: Some( + cx.expr_struct( + sp, + test_path("TestDescAndFn"), + thin_vec![ // desc: test::TestDesc { field( "desc", @@ -359,10 +361,12 @@ pub fn expand_test_or_bench( // testfn: test::StaticTestFn(...) | test::StaticBenchFn(...) field("testfn", test_fn), // } ], - ), // } + ), // } + ), + } + .into(), ), - ), - ); + ); test_const = test_const.map(|mut tc| { tc.vis.kind = ast::VisibilityKind::Public; tc diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index ff25d1e38236d..280f0207116f3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -165,11 +165,15 @@ fn calculate_debuginfo_offset< mir::ProjectionElem::Downcast(_, variant) => { place = place.downcast(bx, variant); } - _ => span_bug!( - var.source_info.span, - "unsupported var debuginfo place `{:?}`", - mir::Place { local, projection: var.projection }, - ), + _ => { + // Sanity check for `can_use_in_debuginfo`. + debug_assert!(!elem.can_use_in_debuginfo()); + span_bug!( + var.source_info.span, + "unsupported var debuginfo place `{:?}`", + mir::Place { local, projection: var.projection }, + ) + } } } diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 8d5192bca67e5..5310ef0bb3ed0 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -612,14 +612,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { span: Option, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { - // FIXME(const_prop): normalization needed b/c const prop lint in - // `mir_drops_elaborated_and_const_checked`, which happens before - // optimized MIR. Only after optimizing the MIR can we guarantee - // that the `RevealAll` pass has happened and that the body's consts - // are normalized, so any call to resolve before that needs to be - // manually normalized. - let val = self.tcx.normalize_erasing_regions(self.param_env, *val); - match val { + match *val { mir::ConstantKind::Ty(ct) => { let ty = ct.ty(); let valtree = self.eval_ty_constant(ct, span)?; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 558253f727bcc..e798c9d236e1a 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -5,13 +5,12 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use rustc_infer::traits::Reveal; use rustc_middle::mir::interpret::Scalar; -use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; -use rustc_middle::mir::visit::{PlaceContext, Visitor}; +use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{ traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location, MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, - TerminatorKind, UnOp, START_BLOCK, + TerminatorKind, UnOp, VarDebugInfo, VarDebugInfoContents, START_BLOCK, }; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_mir_dataflow::impls::MaybeStorageLive; @@ -419,13 +418,49 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.super_projection_elem(local, proj_base, elem, context, location); } + fn visit_var_debug_info(&mut self, debuginfo: &VarDebugInfo<'tcx>) { + let check_place = |place: Place<'_>| { + if place.projection.iter().any(|p| !p.can_use_in_debuginfo()) { + self.fail( + START_BLOCK.start_location(), + format!("illegal place {:?} in debuginfo for {:?}", place, debuginfo.name), + ); + } + }; + match debuginfo.value { + VarDebugInfoContents::Const(_) => {} + VarDebugInfoContents::Place(place) => check_place(place), + VarDebugInfoContents::Composite { ty, ref fragments } => { + for f in fragments { + check_place(f.contents); + if ty.is_union() || ty.is_enum() { + self.fail( + START_BLOCK.start_location(), + format!("invalid type {:?} for composite debuginfo", ty), + ); + } + if f.projection.iter().any(|p| !matches!(p, PlaceElem::Field(..))) { + self.fail( + START_BLOCK.start_location(), + format!( + "illegal projection {:?} in debuginfo for {:?}", + f.projection, debuginfo.name + ), + ); + } + } + } + } + self.super_var_debug_info(debuginfo); + } + fn visit_place(&mut self, place: &Place<'tcx>, cntxt: PlaceContext, location: Location) { // Set off any `bug!`s in the type computation code let _ = place.ty(&self.body.local_decls, self.tcx); if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) && place.projection.len() > 1 - && cntxt != PlaceContext::NonUse(VarDebugInfo) + && cntxt != PlaceContext::NonUse(NonUseContext::VarDebugInfo) && place.projection[1..].contains(&ProjectionElem::Deref) { self.fail(location, format!("{:?}, has deref at the wrong place", place)); diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 8a16143311b8f..264f30fb10a12 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -620,10 +620,15 @@ impl<'a> ExtCtxt<'a> { span: Span, name: Ident, ty: P, - mutbl: ast::Mutability, + mutability: ast::Mutability, expr: P, ) -> P { - self.item(span, name, AttrVec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr))) + self.item( + span, + name, + AttrVec::new(), + ast::ItemKind::Static(ast::StaticItem { ty, mutability, expr: Some(expr) }.into()), + ) } pub fn item_const( @@ -633,8 +638,13 @@ impl<'a> ExtCtxt<'a> { ty: P, expr: P, ) -> P { - let def = ast::Defaultness::Final; - self.item(span, name, AttrVec::new(), ast::ItemKind::Const(def, ty, Some(expr))) + let defaultness = ast::Defaultness::Final; + self.item( + span, + name, + AttrVec::new(), + ast::ItemKind::Const(ast::ConstItem { defaultness, ty, expr: Some(expr) }.into()), + ) } // Builds `#[name]`. diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 5945de2302a56..16cf9ae5cfc28 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -129,6 +129,17 @@ impl IndexVec { IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData } } + /// Creates a new vector with a copy of `elem` for each index in `universe`. + /// + /// Thus `IndexVec::from_elem(elem, &universe)` is equivalent to + /// `IndexVec::::from_elem_n(elem, universe.len())`. That can help + /// type inference as it ensures that the resulting vector uses the same + /// index type as `universe`, rather than something potentially surprising. + /// + /// For example, if you want to store data for each local in a MIR body, + /// using `let mut uses = IndexVec::from_elem(vec![], &body.local_decls);` + /// ensures that `uses` is an `IndexVec`, and thus can give + /// better error messages later if one accidentally mismatches indices. #[inline] pub fn from_elem(elem: T, universe: &IndexSlice) -> Self where diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 9e2bdb7f510b3..f298b95ca35b1 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -203,7 +203,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Tracks the `VarSubVar` constraints generated for each region vid. We // later use this to expand across vids. - let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len()); + let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values); // Tracks the changed region vids. let mut changes = Vec::new(); for constraint in self.data.constraints.keys() { diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 42e59f92840e0..ad328006051f1 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -805,7 +805,9 @@ trait UnusedDelimLint { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { use ast::ItemKind::*; - if let Const(.., Some(expr)) | Static(.., Some(expr)) = &item.kind { + if let Const(box ast::ConstItem { expr: Some(expr), .. }) + | Static(box ast::StaticItem { expr: Some(expr), .. }) = &item.kind + { self.check_unused_delims_expr( cx, expr, diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 44fd8478be9b5..b88a315cec132 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1036,8 +1036,7 @@ impl<'tcx> LocalDecl<'tcx> { #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] pub enum VarDebugInfoContents<'tcx> { - /// NOTE(eddyb) There's an unenforced invariant that this `Place` is - /// based on a `Local`, not a `Static`, and contains no indexing. + /// This `Place` only contains projection which satisfy `can_use_in_debuginfo`. Place(Place<'tcx>), Const(Constant<'tcx>), /// The user variable's data is split across several fragments, @@ -1047,6 +1046,7 @@ pub enum VarDebugInfoContents<'tcx> { /// the underlying debuginfo feature this relies on. Composite { /// Type of the original user variable. + /// This cannot contain a union or an enum. ty: Ty<'tcx>, /// All the parts of the original user variable, which ended /// up in disjoint places, due to optimizations. @@ -1075,17 +1075,16 @@ pub struct VarDebugInfoFragment<'tcx> { /// Where in the composite user variable this fragment is, /// represented as a "projection" into the composite variable. /// At lower levels, this corresponds to a byte/bit range. - // NOTE(eddyb) there's an unenforced invariant that this contains - // only `Field`s, and not into `enum` variants or `union`s. - // FIXME(eddyb) support this for `enum`s by either using DWARF's + /// + /// This can only contain `PlaceElem::Field`. + // FIXME support this for `enum`s by either using DWARF's // more advanced control-flow features (unsupported by LLVM?) // to match on the discriminant, or by using custom type debuginfo // with non-overlapping variants for the composite variable. pub projection: Vec>, /// Where the data for this fragment can be found. - // NOTE(eddyb) There's an unenforced invariant that this `Place` is - // contains no indexing (with a non-constant index). + /// This `Place` only contains projection which satisfy `can_use_in_debuginfo`. pub contents: Place<'tcx>, } @@ -1538,6 +1537,17 @@ impl ProjectionElem { pub fn is_field_to(&self, f: FieldIdx) -> bool { matches!(*self, Self::Field(x, _) if x == f) } + + /// Returns `true` if this is accepted inside `VarDebugInfoContents::Place`. + pub fn can_use_in_debuginfo(&self) -> bool { + match self { + Self::Deref | Self::Downcast(_, _) | Self::Field(_, _) => true, + Self::ConstantIndex { .. } + | Self::Index(_) + | Self::OpaqueCast(_) + | Self::Subslice { .. } => false, + } + } } /// Alias for projections as they appear in `UserTypeProjection`, where we diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 578cd82aa4c2a..7c59879a187fe 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -193,9 +193,9 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> { let arg = self.param_env.and(arg); self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!( - "Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead", - arg.value - )) + "Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead", + arg.value + )) } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index e619e095496bc..29f7cae3d3fec 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -1154,8 +1154,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { fn wildcards_from_tys( cx: &MatchCheckCtxt<'p, 'tcx>, tys: impl IntoIterator>, + span: Span, ) -> Self { - Fields::from_iter(cx, tys.into_iter().map(DeconstructedPat::wildcard)) + Fields::from_iter(cx, tys.into_iter().map(|ty| DeconstructedPat::wildcard(ty, span))) } // In the cases of either a `#[non_exhaustive]` field list or a non-public field, we hide @@ -1191,18 +1192,18 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { pub(super) fn wildcards(pcx: &PatCtxt<'_, 'p, 'tcx>, constructor: &Constructor<'tcx>) -> Self { let ret = match constructor { Single | Variant(_) => match pcx.ty.kind() { - ty::Tuple(fs) => Fields::wildcards_from_tys(pcx.cx, fs.iter()), - ty::Ref(_, rty, _) => Fields::wildcards_from_tys(pcx.cx, once(*rty)), + ty::Tuple(fs) => Fields::wildcards_from_tys(pcx.cx, fs.iter(), pcx.span), + ty::Ref(_, rty, _) => Fields::wildcards_from_tys(pcx.cx, once(*rty), pcx.span), ty::Adt(adt, substs) => { if adt.is_box() { // The only legal patterns of type `Box` (outside `std`) are `_` and box // patterns. If we're here we can assume this is a box pattern. - Fields::wildcards_from_tys(pcx.cx, once(substs.type_at(0))) + Fields::wildcards_from_tys(pcx.cx, once(substs.type_at(0)), pcx.span) } else { let variant = &adt.variant(constructor.variant_index_for_adt(*adt)); let tys = Fields::list_variant_nonhidden_fields(pcx.cx, pcx.ty, variant) .map(|(_, ty)| ty); - Fields::wildcards_from_tys(pcx.cx, tys) + Fields::wildcards_from_tys(pcx.cx, tys, pcx.span) } } _ => bug!("Unexpected type for `Single` constructor: {:?}", pcx), @@ -1210,7 +1211,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { Slice(slice) => match *pcx.ty.kind() { ty::Slice(ty) | ty::Array(ty, _) => { let arity = slice.arity(); - Fields::wildcards_from_tys(pcx.cx, (0..arity).map(|_| ty)) + Fields::wildcards_from_tys(pcx.cx, (0..arity).map(|_| ty), pcx.span) } _ => bug!("bad slice pattern {:?} {:?}", constructor, pcx), }, @@ -1251,8 +1252,8 @@ pub(crate) struct DeconstructedPat<'p, 'tcx> { } impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { - pub(super) fn wildcard(ty: Ty<'tcx>) -> Self { - Self::new(Wildcard, Fields::empty(), ty, DUMMY_SP) + pub(super) fn wildcard(ty: Ty<'tcx>, span: Span) -> Self { + Self::new(Wildcard, Fields::empty(), ty, span) } pub(super) fn new( @@ -1269,7 +1270,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { /// `Some(_)`. pub(super) fn wild_from_ctor(pcx: &PatCtxt<'_, 'p, 'tcx>, ctor: Constructor<'tcx>) -> Self { let fields = Fields::wildcards(pcx, &ctor); - DeconstructedPat::new(ctor, fields, pcx.ty, DUMMY_SP) + DeconstructedPat::new(ctor, fields, pcx.ty, pcx.span) } /// Clone this value. This method emphasizes that cloning loses reachability information and @@ -1298,7 +1299,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { ty::Tuple(fs) => { ctor = Single; let mut wilds: SmallVec<[_; 2]> = - fs.iter().map(DeconstructedPat::wildcard).collect(); + fs.iter().map(|ty| DeconstructedPat::wildcard(ty, pat.span)).collect(); for pat in subpatterns { wilds[pat.field.index()] = mkpat(&pat.pattern); } @@ -1317,11 +1318,11 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { // normally or through box-patterns. We'll have to figure out a proper // solution when we introduce generalized deref patterns. Also need to // prevent mixing of those two options. - let pat = subpatterns.into_iter().find(|pat| pat.field.index() == 0); - let pat = if let Some(pat) = pat { + let pattern = subpatterns.into_iter().find(|pat| pat.field.index() == 0); + let pat = if let Some(pat) = pattern { mkpat(&pat.pattern) } else { - DeconstructedPat::wildcard(substs.type_at(0)) + DeconstructedPat::wildcard(substs.type_at(0), pat.span) }; ctor = Single; fields = Fields::singleton(cx, pat); @@ -1343,7 +1344,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { ty }); let mut wilds: SmallVec<[_; 2]> = - tys.map(DeconstructedPat::wildcard).collect(); + tys.map(|ty| DeconstructedPat::wildcard(ty, pat.span)).collect(); for pat in subpatterns { if let Some(i) = field_id_to_id[pat.field.index()] { wilds[i] = mkpat(&pat.pattern); @@ -1566,8 +1567,10 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { }; let prefix = &self.fields.fields[..prefix]; let suffix = &self.fields.fields[self_slice.arity() - suffix..]; - let wildcard: &_ = - pcx.cx.pattern_arena.alloc(DeconstructedPat::wildcard(inner_ty)); + let wildcard: &_ = pcx + .cx + .pattern_arena + .alloc(DeconstructedPat::wildcard(inner_ty, pcx.span)); let extra_wildcards = other_slice.arity() - self_slice.arity(); let extra_wildcards = (0..extra_wildcards).map(|_| wildcard); prefix.iter().chain(extra_wildcards).chain(suffix).collect() diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 9edd7967e7a4a..a324c3a622806 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -604,7 +604,7 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> { let new_patterns = if pcx.is_non_exhaustive { // Here we don't want the user to try to list all variants, we want them to add // a wildcard, so we only suggest that. - vec![DeconstructedPat::wildcard(pcx.ty)] + vec![DeconstructedPat::wildcard(pcx.ty, pcx.span)] } else { let mut split_wildcard = SplitWildcard::new(pcx); split_wildcard.split(pcx, matrix.heads().map(DeconstructedPat::ctor)); @@ -631,7 +631,7 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> { .collect(); if hide_variant_show_wild { - new.push(DeconstructedPat::wildcard(pcx.ty)); + new.push(DeconstructedPat::wildcard(pcx.ty, pcx.span)); } new @@ -734,7 +734,7 @@ impl<'p, 'tcx> Witness<'p, 'tcx> { let arity = ctor.arity(pcx); let pats = self.0.drain((len - arity)..).rev(); let fields = Fields::from_iter(pcx.cx, pats); - DeconstructedPat::new(ctor.clone(), fields, pcx.ty, DUMMY_SP) + DeconstructedPat::new(ctor.clone(), fields, pcx.ty, pcx.span) }; self.0.push(pat); @@ -977,7 +977,7 @@ pub(crate) fn compute_match_usefulness<'p, 'tcx>( }) .collect(); - let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty)); + let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty, DUMMY_SP)); let v = PatStack::from_pattern(wild_pattern); let usefulness = is_useful(cx, &matrix, &v, FakeExtraWildcard, scrut_hir_id, false, true); let non_exhaustiveness_witnesses = match usefulness { diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index d7696a5700061..176027b3b93e4 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -284,7 +284,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&c.literal, Some(c.span), None)) + // Normalization needed b/c const prop lint runs in + // `mir_drops_elaborated_and_const_checked`, which happens before + // optimized MIR. Only after optimizing the MIR can we guarantee + // that the `RevealAll` pass has happened and that the body's consts + // are normalized, so any call to resolve before that needs to be + // manually normalized. + let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.literal).ok()?; + + self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&val, Some(c.span), None)) } /// Returns the value, if any, of evaluating `place`. diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 689d6c71361dd..6a73f2a657813 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -37,8 +37,7 @@ impl CoverageGraph { // `SwitchInt` to have multiple targets to the same destination `BasicBlock`, so // de-duplication is required. This is done without reordering the successors. - let bcbs_len = bcbs.len(); - let mut seen = IndexVec::from_elem_n(false, bcbs_len); + let mut seen = IndexVec::from_elem(false, &bcbs); let successors = IndexVec::from_fn_n( |bcb| { for b in seen.iter_mut() { @@ -60,7 +59,7 @@ impl CoverageGraph { bcbs.len(), ); - let mut predecessors = IndexVec::from_elem_n(Vec::new(), bcbs.len()); + let mut predecessors = IndexVec::from_elem(Vec::new(), &bcbs); for (bcb, bcb_successors) in successors.iter_enumerated() { for &successor in bcb_successors { predecessors[successor].push(bcb); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index ae8fe90e9d611..6422b8ac1ba45 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -3,6 +3,7 @@ use crate::errors; use super::diagnostics::{dummy_arg, ConsumeClosingDelim}; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken}; +use ast::StaticItem; use rustc_ast::ast::*; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, TokenKind}; @@ -227,7 +228,7 @@ impl<'a> Parser<'a> { self.bump(); // `static` let m = self.parse_mutability(); let (ident, ty, expr) = self.parse_item_global(Some(m))?; - (ident, ItemKind::Static(ty, m, expr)) + (ident, ItemKind::Static(Box::new(StaticItem { ty, mutability: m, expr }))) } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) { // CONST ITEM if self.token.is_keyword(kw::Impl) { @@ -236,7 +237,7 @@ impl<'a> Parser<'a> { } else { self.recover_const_mut(const_span); let (ident, ty, expr) = self.parse_item_global(None)?; - (ident, ItemKind::Const(def_(), ty, expr)) + (ident, ItemKind::Const(Box::new(ConstItem { defaultness: def_(), ty, expr }))) } } else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() { // TRAIT ITEM @@ -862,9 +863,13 @@ impl<'a> Parser<'a> { let kind = match AssocItemKind::try_from(kind) { Ok(kind) => kind, Err(kind) => match kind { - ItemKind::Static(a, _, b) => { + ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => { self.sess.emit_err(errors::AssociatedStaticItemNotAllowed { span }); - AssocItemKind::Const(Defaultness::Final, a, b) + AssocItemKind::Const(Box::new(ConstItem { + defaultness: Defaultness::Final, + ty, + expr, + })) } _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"), }, @@ -1114,12 +1119,12 @@ impl<'a> Parser<'a> { let kind = match ForeignItemKind::try_from(kind) { Ok(kind) => kind, Err(kind) => match kind { - ItemKind::Const(_, a, b) => { + ItemKind::Const(box ConstItem { ty, expr, .. }) => { self.sess.emit_err(errors::ExternItemCannotBeConst { ident_span: ident.span, const_span: span.with_hi(ident.span.lo()), }); - ForeignItemKind::Static(a, Mutability::Not, b) + ForeignItemKind::Static(ty, Mutability::Not, expr) } _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"), }, diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 19ccb3a6484af..49c41470a1514 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -688,8 +688,8 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } // These items live in the value namespace. - ItemKind::Static(_, mt, _) => { - let res = Res::Def(DefKind::Static(mt), def_id); + ItemKind::Static(box ast::StaticItem { mutability, .. }) => { + let res = Res::Def(DefKind::Static(mutability), def_id); self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); } ItemKind::Const(..) => { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b82b07bcf0cc8..19f46d45af678 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2346,7 +2346,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { }); } - ItemKind::Static(ref ty, _, ref expr) | ItemKind::Const(_, ref ty, ref expr) => { + ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) + | ItemKind::Const(box ast::ConstItem { ref ty, ref expr, .. }) => { self.with_static_rib(|this| { this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| { this.visit_ty(ty); @@ -2624,11 +2625,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { for item in trait_items { self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id)); match &item.kind { - AssocItemKind::Const(_, ty, default) => { + AssocItemKind::Const(box ast::ConstItem { ty, expr, .. }) => { self.visit_ty(ty); // Only impose the restrictions of `ConstRibKind` for an // actual constant expression in a provided default. - if let Some(expr) = default { + if let Some(expr) = expr { // We allow arbitrary const expressions inside of associated consts, // even if they are potentially not const evaluatable. // @@ -2799,7 +2800,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { use crate::ResolutionError::*; self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis))); match &item.kind { - AssocItemKind::Const(_, ty, default) => { + AssocItemKind::Const(box ast::ConstItem { ty, expr, .. }) => { debug!("resolve_implementation AssocItemKind::Const"); // If this is a trait impl, ensure the const // exists in trait @@ -2814,7 +2815,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ); self.visit_ty(ty); - if let Some(expr) = default { + if let Some(expr) = expr { // We allow arbitrary const expressions inside of associated consts, // even if they are potentially not const evaluatable. // diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 73f86f74d14f1..e8155520c9b78 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -522,7 +522,7 @@ fn generator_saved_local_eligibility( use SavedLocalEligibility::*; let mut assignments: IndexVec = - IndexVec::from_elem_n(Unassigned, info.field_tys.len()); + IndexVec::from_elem(Unassigned, &info.field_tys); // The saved locals not eligible for overlap. These will get // "promoted" to the prefix of our generator. diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0895bb510d481..02b358e863b66 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1142,22 +1142,21 @@ fn fmt_type<'cx>( // the ugliness comes from inlining across crates where // everything comes in as a fully resolved QPath (hard to // look at). - match href(trait_.def_id(), cx) { - Ok((ref url, _, ref path)) if !f.alternate() => { - write!( - f, - "{name}{args}", - url = url, - shortty = ItemType::AssocType, - name = assoc.name, - path = join_with_double_colon(path), - args = assoc.args.print(cx), - )?; - } - _ => write!(f, "{}{:#}", assoc.name, assoc.args.print(cx))?, - } - Ok(()) + if !f.alternate() && let Ok((url, _, path)) = href(trait_.def_id(), cx) { + write!( + f, + "{name}", + shortty = ItemType::AssocType, + name = assoc.name, + path = join_with_double_colon(&path), + ) + } else { + write!(f, "{}", assoc.name) + }?; + + // Carry `f.alternate()` into this display w/o branching manually. + fmt::Display::fmt(&assoc.args.print(cx), f) } } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 060062db0027a..c959bb3701ab5 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -421,12 +421,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | hir::ItemKind::TyAlias(..) - | hir::ItemKind::OpaqueTy(..) + | hir::ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias, .. + }) | hir::ItemKind::Static(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => { self.add_to_current_mod(item, renamed, import_id); } + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::AsyncFn(_) | hir::OpaqueTyOrigin::FnReturn(_), + .. + }) => { + // return-position impl traits are never nameable, and should never be documented. + } hir::ItemKind::Const(..) => { // Underscore constants do not correspond to a nameable item and // so are never useful in documentation. diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs index 44bf824aa0e2d..11b908e7e53d1 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; -use rustc_ast::ast::{Item, ItemKind, Ty, TyKind}; +use rustc_ast::ast::{Item, ItemKind, Ty, TyKind, StaticItem, ConstItem}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -100,13 +100,13 @@ impl EarlyLintPass for RedundantStaticLifetimes { } if !item.span.from_expansion() { - if let ItemKind::Const(_, ref var_type, _) = item.kind { + if let ItemKind::Const(box ConstItem { ty: ref var_type, .. }) = item.kind { Self::visit_type(var_type, cx, "constants have by default a `'static` lifetime"); // Don't check associated consts because `'static` cannot be elided on those (issue // #2438) } - if let ItemKind::Static(ref var_type, _, _) = item.kind { + if let ItemKind::Static(box StaticItem { ty: ref var_type,.. }) = item.kind { Self::visit_type(var_type, cx, "statics have by default a `'static` lifetime"); } } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index d2dedc2043957..c5b58b0c060c0 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -286,8 +286,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { match (l, r) { (ExternCrate(l), ExternCrate(r)) => l == r, (Use(l), Use(r)) => eq_use_tree(l, r), - (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re), - (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re), + (Static(box ast::StaticItem { ty: lt, mutability: lm, expr: le}), Static(box ast::StaticItem { ty: rt, mutability: rm, expr: re})) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re), + (Const(box ast::ConstItem { defaultness: ld, ty: lt, expr: le}), Const(box ast::ConstItem { defaultness: rd, ty: rt, expr: re} )) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re), ( Fn(box ast::Fn { defaultness: ld, @@ -451,7 +451,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { use AssocItemKind::*; match (l, r) { - (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re), + (Const(box ast::ConstItem { defaultness: ld, ty: lt, expr: le}), Const(box ast::ConstItem { defaultness: rd, ty: rt, expr: re})) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re), ( Fn(box ast::Fn { defaultness: ld, diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 25e8a024857ce..43779cfaecd3a 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -1804,13 +1804,15 @@ pub(crate) struct StaticParts<'a> { impl<'a> StaticParts<'a> { pub(crate) fn from_item(item: &'a ast::Item) -> Self { - let (defaultness, prefix, ty, mutability, expr) = match item.kind { - ast::ItemKind::Static(ref ty, mutability, ref expr) => { - (None, "static", ty, mutability, expr) - } - ast::ItemKind::Const(defaultness, ref ty, ref expr) => { - (Some(defaultness), "const", ty, ast::Mutability::Not, expr) - } + let (defaultness, prefix, ty, mutability, expr) = match &item.kind { + ast::ItemKind::Static(s) => (None, "static", &s.ty, s.mutability, &s.expr), + ast::ItemKind::Const(c) => ( + Some(c.defaultness), + "const", + &c.ty, + ast::Mutability::Not, + &c.expr, + ), _ => unreachable!(), }; StaticParts { @@ -1826,10 +1828,8 @@ impl<'a> StaticParts<'a> { } pub(crate) fn from_trait_item(ti: &'a ast::AssocItem) -> Self { - let (defaultness, ty, expr_opt) = match ti.kind { - ast::AssocItemKind::Const(defaultness, ref ty, ref expr_opt) => { - (defaultness, ty, expr_opt) - } + let (defaultness, ty, expr_opt) = match &ti.kind { + ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr), _ => unreachable!(), }; StaticParts { @@ -1845,8 +1845,8 @@ impl<'a> StaticParts<'a> { } pub(crate) fn from_impl_item(ii: &'a ast::AssocItem) -> Self { - let (defaultness, ty, expr) = match ii.kind { - ast::AssocItemKind::Const(defaultness, ref ty, ref expr) => (defaultness, ty, expr), + let (defaultness, ty, expr) = match &ii.kind { + ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr), _ => unreachable!(), }; StaticParts { diff --git a/tests/rustdoc/async-fn-opaque-item.rs b/tests/rustdoc/async-fn-opaque-item.rs new file mode 100644 index 0000000000000..a73e84f3fdc4e --- /dev/null +++ b/tests/rustdoc/async-fn-opaque-item.rs @@ -0,0 +1,15 @@ +// compile-flags: --document-private-items --crate-type=lib +// edition: 2021 + +// Issue 109931 -- test against accidentally documenting the `impl Future` +// that comes from an async fn desugaring. + +// Check that we don't document an unnamed opaque type +// @!has async_fn_opaque_item/opaque..html + +// Checking there is only a "Functions" header and no "Opaque types". +// @has async_fn_opaque_item/index.html +// @count - '//*[@class="small-section-header"]' 1 +// @has - '//*[@class="small-section-header"]' 'Functions' + +pub async fn test() {} diff --git a/tests/rustdoc/generic-associated-types/issue-109488.rs b/tests/rustdoc/generic-associated-types/issue-109488.rs new file mode 100644 index 0000000000000..99ae8a6c36c52 --- /dev/null +++ b/tests/rustdoc/generic-associated-types/issue-109488.rs @@ -0,0 +1,18 @@ +// Make sure that we escape the arguments of the GAT projection even if we fail to compute +// the href of the corresponding trait (in this case it is private). +// Further, test that we also linkify the GAT arguments. + +// @has 'issue_109488/type.A.html' +// @has - '//pre[@class="rust item-decl"]' '::P>' +// @has - '//pre[@class="rust item-decl"]//a[@class="enum"]/@href' '{{channel}}/core/option/enum.Option.html' +pub type A = ::P>; + +/*private*/ trait Tr { + type P; +} + +pub struct S; + +impl Tr for S { + type P = (); +} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index 75aa25906aa0f..2f9a1d1c76e06 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -10,11 +10,13 @@ trait Trait { fn foo>() {} //~^ ERROR argument types not allowed with return type notation +//~| ERROR associated type bounds are unstable fn bar (): Send>>() {} //~^ ERROR return type not allowed with return type notation fn baz>() {} //~^ ERROR return type notation arguments must be elided with `..` +//~| ERROR associated type bounds are unstable fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index 5b075a0fa2921..b354a6805d6e5 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -1,9 +1,27 @@ error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:14:28 + --> $DIR/bad-inputs-and-output.rs:15:28 | LL | fn bar (): Send>>() {} | ^^^^^ help: remove the return type +error[E0658]: associated type bounds are unstable + --> $DIR/bad-inputs-and-output.rs:11:17 + | +LL | fn foo>() {} + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #52662 for more information + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable + +error[E0658]: associated type bounds are unstable + --> $DIR/bad-inputs-and-output.rs:18:17 + | +LL | fn baz>() {} + | ^^^^^^^^^^^^^^ + | + = note: see issue #52662 for more information + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable + warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bad-inputs-and-output.rs:3:12 | @@ -28,10 +46,11 @@ LL | fn foo>() {} | ^^^^^ help: remove the input types: `(..)` error: return type notation arguments must be elided with `..` - --> $DIR/bad-inputs-and-output.rs:17:23 + --> $DIR/bad-inputs-and-output.rs:18:23 | LL | fn baz>() {} | ^^ help: add `..`: `(..)` -error: aborting due to 3 previous errors; 2 warnings emitted +error: aborting due to 5 previous errors; 2 warnings emitted +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.rs b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.rs new file mode 100644 index 0000000000000..9129f37e0c6b6 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.rs @@ -0,0 +1,11 @@ +// edition: 2021 +// compile-flags: -Zunpretty=expanded + +trait Trait { + async fn method() {} +} + +fn foo>() {} +//~^ ERROR associated type bounds are unstable + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stderr b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stderr new file mode 100644 index 0000000000000..77e015b4160bb --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stderr @@ -0,0 +1,12 @@ +error[E0658]: associated type bounds are unstable + --> $DIR/unpretty-parenthesized.rs:8:17 + | +LL | fn foo>() {} + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #52662 for more information + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout new file mode 100644 index 0000000000000..b3dea8f6eca71 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout @@ -0,0 +1,15 @@ +#![feature(prelude_import)] +#[prelude_import] +use std::prelude::rust_2021::*; +#[macro_use] +extern crate std; +// edition: 2021 +// compile-flags: -Zunpretty=expanded + +trait Trait { + async fn method() {} +} + +fn foo>() {} + +fn main() {} diff --git a/tests/ui/lifetimes/issue-93911.rs b/tests/ui/lifetimes/issue-93911.rs new file mode 100644 index 0000000000000..b7ccac1ee521c --- /dev/null +++ b/tests/ui/lifetimes/issue-93911.rs @@ -0,0 +1,18 @@ +// check-pass +// edition:2021 + +#![allow(dead_code)] + +struct Foo<'a>(&'a u32); + +impl<'a> Foo<'a> { + async fn foo() { + struct Bar<'b>(&'b u32); + + impl<'b> Bar<'b> { + async fn bar() {} + } + } +} + +fn main() {} diff --git a/tests/ui/mir/issue-109743.rs b/tests/ui/mir/issue-109743.rs new file mode 100644 index 0000000000000..73f3405e3ad76 --- /dev/null +++ b/tests/ui/mir/issue-109743.rs @@ -0,0 +1,51 @@ +// build-pass +// compile-flags: --crate-type=lib + +use std::marker::PhantomData; + +pub trait StreamOnce { + type Token; +} + +impl StreamOnce for &str { + type Token = (); +} + +pub trait Parser { + type PartialState: Default; + fn parse_mode(&self, _state: &Self::PartialState) {} + fn parse_mode_impl() {} +} + +pub fn parse_bool<'a>() -> impl Parser<&'a str> { + pub struct TokensCmp + where + Input: StreamOnce, + { + _cmp: C, + _marker: PhantomData, + } + + impl Parser for TokensCmp + where + C: FnMut(Input::Token), + Input: StreamOnce, + { + type PartialState = (); + } + + TokensCmp { _cmp: |_| (), _marker: PhantomData } +} + +pub struct ParseBool; + +impl<'a> Parser<&'a str> for ParseBool +where + &'a str: StreamOnce, +{ + type PartialState = (); + + fn parse_mode_impl() { + parse_bool().parse_mode(&Default::default()) + } +} diff --git a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs index 7ef1d635d9ce7..3482af74752f8 100644 --- a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs +++ b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs @@ -194,6 +194,14 @@ fn main() { let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit; //~^ refutable pattern in local binding + // Check that matching on a reference results in a correctly spanned diagnostic + #[deny(non_exhaustive_omitted_patterns)] + match &non_enum { + NonExhaustiveEnum::Unit => {} + NonExhaustiveEnum::Tuple(_) => {} + _ => {} + } + //~^^ some variants are not matched explicitly } #[deny(non_exhaustive_omitted_patterns)] diff --git a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr index 617c629a4fe07..520a90322c1ca 100644 --- a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr +++ b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr @@ -198,6 +198,20 @@ help: you might want to use `let else` to handle the variant that isn't matched LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() }; | ++++++++++++++++ -error: aborting due to 9 previous errors; 6 warnings emitted +error: some variants are not matched explicitly + --> $DIR/omitted-patterns.rs:202:9 + | +LL | _ => {} + | ^ pattern `NonExhaustiveEnum::Struct { .. }` not covered + | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found +note: the lint level is defined here + --> $DIR/omitted-patterns.rs:198:12 + | +LL | #[deny(non_exhaustive_omitted_patterns)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 10 previous errors; 6 warnings emitted For more information about this error, try `rustc --explain E0005`. diff --git a/tests/ui/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr index ee62d8f2d25ce..d723ff538a886 100644 --- a/tests/ui/stats/hir-stats.stderr +++ b/tests/ui/stats/hir-stats.stderr @@ -15,45 +15,45 @@ ast-stats-1 Arm 96 ( 1.5%) 2 48 ast-stats-1 ForeignItem 96 ( 1.5%) 1 96 ast-stats-1 - Fn 96 ( 1.5%) 1 ast-stats-1 FnDecl 120 ( 1.8%) 5 24 -ast-stats-1 FieldDef 160 ( 2.4%) 2 80 -ast-stats-1 Stmt 160 ( 2.4%) 5 32 +ast-stats-1 FieldDef 160 ( 2.5%) 2 80 +ast-stats-1 Stmt 160 ( 2.5%) 5 32 ast-stats-1 - Local 32 ( 0.5%) 1 ast-stats-1 - MacCall 32 ( 0.5%) 1 ast-stats-1 - Expr 96 ( 1.5%) 3 -ast-stats-1 Param 160 ( 2.4%) 4 40 -ast-stats-1 Block 192 ( 2.9%) 6 32 +ast-stats-1 Param 160 ( 2.5%) 4 40 +ast-stats-1 Block 192 ( 3.0%) 6 32 ast-stats-1 Variant 208 ( 3.2%) 2 104 -ast-stats-1 GenericBound 224 ( 3.4%) 4 56 -ast-stats-1 - Trait 224 ( 3.4%) 4 -ast-stats-1 AssocItem 416 ( 6.3%) 4 104 -ast-stats-1 - Type 208 ( 3.2%) 2 -ast-stats-1 - Fn 208 ( 3.2%) 2 -ast-stats-1 GenericParam 480 ( 7.3%) 5 96 -ast-stats-1 Pat 504 ( 7.7%) 7 72 +ast-stats-1 GenericBound 224 ( 3.5%) 4 56 +ast-stats-1 - Trait 224 ( 3.5%) 4 +ast-stats-1 AssocItem 352 ( 5.4%) 4 88 +ast-stats-1 - Type 176 ( 2.7%) 2 +ast-stats-1 - Fn 176 ( 2.7%) 2 +ast-stats-1 GenericParam 480 ( 7.4%) 5 96 +ast-stats-1 Pat 504 ( 7.8%) 7 72 ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Wild 72 ( 1.1%) 1 ast-stats-1 - Ident 360 ( 5.5%) 5 -ast-stats-1 Expr 576 ( 8.8%) 8 72 +ast-stats-1 Expr 576 ( 8.9%) 8 72 ast-stats-1 - Path 72 ( 1.1%) 1 ast-stats-1 - Match 72 ( 1.1%) 1 ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Lit 144 ( 2.2%) 2 ast-stats-1 - Block 216 ( 3.3%) 3 -ast-stats-1 PathSegment 720 (11.0%) 30 24 -ast-stats-1 Ty 896 (13.7%) 14 64 +ast-stats-1 PathSegment 720 (11.1%) 30 24 +ast-stats-1 Ty 896 (13.8%) 14 64 ast-stats-1 - Ptr 64 ( 1.0%) 1 ast-stats-1 - Ref 64 ( 1.0%) 1 ast-stats-1 - ImplicitSelf 128 ( 2.0%) 2 -ast-stats-1 - Path 640 ( 9.8%) 10 -ast-stats-1 Item 1_224 (18.7%) 9 136 +ast-stats-1 - Path 640 ( 9.9%) 10 +ast-stats-1 Item 1_224 (18.9%) 9 136 ast-stats-1 - Trait 136 ( 2.1%) 1 ast-stats-1 - Enum 136 ( 2.1%) 1 ast-stats-1 - ForeignMod 136 ( 2.1%) 1 ast-stats-1 - Impl 136 ( 2.1%) 1 ast-stats-1 - Fn 272 ( 4.2%) 2 -ast-stats-1 - Use 408 ( 6.2%) 3 +ast-stats-1 - Use 408 ( 6.3%) 3 ast-stats-1 ---------------------------------------------------------------- -ast-stats-1 Total 6_552 +ast-stats-1 Total 6_488 ast-stats-1 ast-stats-2 POST EXPANSION AST STATS ast-stats-2 Name Accumulated Size Count Item Size @@ -65,32 +65,32 @@ ast-stats-2 ExprField 48 ( 0.7%) 1 48 ast-stats-2 WherePredicate 56 ( 0.8%) 1 56 ast-stats-2 - BoundPredicate 56 ( 0.8%) 1 ast-stats-2 Local 72 ( 1.0%) 1 72 -ast-stats-2 Arm 96 ( 1.3%) 2 48 -ast-stats-2 ForeignItem 96 ( 1.3%) 1 96 -ast-stats-2 - Fn 96 ( 1.3%) 1 +ast-stats-2 Arm 96 ( 1.4%) 2 48 +ast-stats-2 ForeignItem 96 ( 1.4%) 1 96 +ast-stats-2 - Fn 96 ( 1.4%) 1 ast-stats-2 InlineAsm 120 ( 1.7%) 1 120 ast-stats-2 FnDecl 120 ( 1.7%) 5 24 ast-stats-2 Attribute 128 ( 1.8%) 4 32 -ast-stats-2 - DocComment 32 ( 0.4%) 1 -ast-stats-2 - Normal 96 ( 1.3%) 3 -ast-stats-2 FieldDef 160 ( 2.2%) 2 80 -ast-stats-2 Stmt 160 ( 2.2%) 5 32 -ast-stats-2 - Local 32 ( 0.4%) 1 -ast-stats-2 - Semi 32 ( 0.4%) 1 -ast-stats-2 - Expr 96 ( 1.3%) 3 -ast-stats-2 Param 160 ( 2.2%) 4 40 +ast-stats-2 - DocComment 32 ( 0.5%) 1 +ast-stats-2 - Normal 96 ( 1.4%) 3 +ast-stats-2 FieldDef 160 ( 2.3%) 2 80 +ast-stats-2 Stmt 160 ( 2.3%) 5 32 +ast-stats-2 - Local 32 ( 0.5%) 1 +ast-stats-2 - Semi 32 ( 0.5%) 1 +ast-stats-2 - Expr 96 ( 1.4%) 3 +ast-stats-2 Param 160 ( 2.3%) 4 40 ast-stats-2 Block 192 ( 2.7%) 6 32 ast-stats-2 Variant 208 ( 2.9%) 2 104 -ast-stats-2 GenericBound 224 ( 3.1%) 4 56 -ast-stats-2 - Trait 224 ( 3.1%) 4 -ast-stats-2 AssocItem 416 ( 5.8%) 4 104 -ast-stats-2 - Type 208 ( 2.9%) 2 -ast-stats-2 - Fn 208 ( 2.9%) 2 -ast-stats-2 GenericParam 480 ( 6.7%) 5 96 -ast-stats-2 Pat 504 ( 7.0%) 7 72 +ast-stats-2 GenericBound 224 ( 3.2%) 4 56 +ast-stats-2 - Trait 224 ( 3.2%) 4 +ast-stats-2 AssocItem 352 ( 5.0%) 4 88 +ast-stats-2 - Type 176 ( 2.5%) 2 +ast-stats-2 - Fn 176 ( 2.5%) 2 +ast-stats-2 GenericParam 480 ( 6.8%) 5 96 +ast-stats-2 Pat 504 ( 7.1%) 7 72 ast-stats-2 - Struct 72 ( 1.0%) 1 ast-stats-2 - Wild 72 ( 1.0%) 1 -ast-stats-2 - Ident 360 ( 5.0%) 5 +ast-stats-2 - Ident 360 ( 5.1%) 5 ast-stats-2 Expr 648 ( 9.1%) 9 72 ast-stats-2 - Path 72 ( 1.0%) 1 ast-stats-2 - Match 72 ( 1.0%) 1 @@ -98,22 +98,22 @@ ast-stats-2 - Struct 72 ( 1.0%) 1 ast-stats-2 - InlineAsm 72 ( 1.0%) 1 ast-stats-2 - Lit 144 ( 2.0%) 2 ast-stats-2 - Block 216 ( 3.0%) 3 -ast-stats-2 PathSegment 792 (11.1%) 33 24 -ast-stats-2 Ty 896 (12.5%) 14 64 +ast-stats-2 PathSegment 792 (11.2%) 33 24 +ast-stats-2 Ty 896 (12.6%) 14 64 ast-stats-2 - Ptr 64 ( 0.9%) 1 ast-stats-2 - Ref 64 ( 0.9%) 1 ast-stats-2 - ImplicitSelf 128 ( 1.8%) 2 -ast-stats-2 - Path 640 ( 8.9%) 10 -ast-stats-2 Item 1_496 (20.9%) 11 136 +ast-stats-2 - Path 640 ( 9.0%) 10 +ast-stats-2 Item 1_496 (21.1%) 11 136 ast-stats-2 - Trait 136 ( 1.9%) 1 ast-stats-2 - Enum 136 ( 1.9%) 1 ast-stats-2 - ExternCrate 136 ( 1.9%) 1 ast-stats-2 - ForeignMod 136 ( 1.9%) 1 ast-stats-2 - Impl 136 ( 1.9%) 1 ast-stats-2 - Fn 272 ( 3.8%) 2 -ast-stats-2 - Use 544 ( 7.6%) 4 +ast-stats-2 - Use 544 ( 7.7%) 4 ast-stats-2 ---------------------------------------------------------------- -ast-stats-2 Total 7_152 +ast-stats-2 Total 7_088 ast-stats-2 hir-stats HIR STATS hir-stats Name Accumulated Size Count Item Size