diff --git a/Cargo.lock b/Cargo.lock index 4d54b5aeb4e1..22b3e8280d62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3301,6 +3301,7 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_ast", + "rustc_data_structures", "rustc_lexer", "rustc_span", "thin-vec", @@ -3621,6 +3622,7 @@ version = "0.0.0" dependencies = [ "annotate-snippets 0.11.4", "derive_setters", + "rustc_abi", "rustc_ast", "rustc_ast_pretty", "rustc_data_structures", @@ -3718,6 +3720,7 @@ name = "rustc_hir_analysis" version = "0.0.0" dependencies = [ "itertools", + "rustc_abi", "rustc_arena", "rustc_ast", "rustc_attr", @@ -3906,6 +3909,7 @@ dependencies = [ name = "rustc_lint" version = "0.0.0" dependencies = [ + "rustc_abi", "rustc_ast", "rustc_ast_pretty", "rustc_attr", @@ -3980,6 +3984,7 @@ dependencies = [ "bitflags 2.6.0", "libloading", "odht", + "rustc_abi", "rustc_ast", "rustc_attr", "rustc_data_structures", @@ -4029,6 +4034,7 @@ dependencies = [ "rustc_hir", "rustc_hir_pretty", "rustc_index", + "rustc_lint_defs", "rustc_macros", "rustc_query_system", "rustc_serialize", @@ -4073,6 +4079,7 @@ version = "0.0.0" dependencies = [ "polonius-engine", "regex", + "rustc_abi", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -4094,6 +4101,7 @@ version = "0.0.0" dependencies = [ "either", "itertools", + "rustc_abi", "rustc_arena", "rustc_ast", "rustc_attr", @@ -4186,6 +4194,7 @@ dependencies = [ name = "rustc_passes" version = "0.0.0" dependencies = [ + "rustc_abi", "rustc_ast", "rustc_ast_pretty", "rustc_attr", @@ -4212,6 +4221,7 @@ name = "rustc_pattern_analysis" version = "0.0.0" dependencies = [ "rustc-hash 2.0.0", + "rustc_abi", "rustc_apfloat", "rustc_arena", "rustc_data_structures", @@ -4351,6 +4361,7 @@ dependencies = [ "bitflags 2.6.0", "getopts", "libc", + "rustc_abi", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -4414,6 +4425,7 @@ version = "0.0.0" dependencies = [ "punycode", "rustc-demangle", + "rustc_abi", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -4495,6 +4507,7 @@ name = "rustc_transmute" version = "0.0.0" dependencies = [ "itertools", + "rustc_abi", "rustc_ast_ir", "rustc_data_structures", "rustc_hir", @@ -4502,7 +4515,6 @@ dependencies = [ "rustc_macros", "rustc_middle", "rustc_span", - "rustc_target", "tracing", ] diff --git a/RELEASES.md b/RELEASES.md index ac72a1d885cb..40ddba6dbc52 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -68,15 +68,15 @@ Stabilized APIs - [`impl Default for std::collections::vec_deque::Iter`](https://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.Iter.html#impl-Default-for-Iter%3C'_,+T%3E) - [`impl Default for std::collections::vec_deque::IterMut`](https://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.IterMut.html#impl-Default-for-IterMut%3C'_,+T%3E) - [`Rc::new_uninit`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new_uninit) -- [`Rc::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init) +- [`Rc>::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init) - [`Rc<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new_uninit_slice) - [`Rc<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init-1) - [`Arc::new_uninit`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.new_uninit) -- [`Arc::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init) +- [`Arc>::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init) - [`Arc<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.new_uninit_slice) - [`Arc<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init-1) - [`Box::new_uninit`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.new_uninit) -- [`Box::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init) +- [`Box>::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init) - [`Box<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.new_uninit_slice) - [`Box<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init-1) - [`core::arch::x86_64::_bextri_u64`](https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bextri_u64.html) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 0340d1bd6bcd..86de39b8f975 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -7,7 +7,7 @@ use tracing::debug; use crate::{ Abi, AbiAndPrefAlign, Align, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, - LayoutS, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, + LayoutData, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, Variants, WrappingRange, }; @@ -26,9 +26,9 @@ fn absent<'a, FieldIdx, VariantIdx, F>(fields: &IndexSlice) -> bool where FieldIdx: Idx, VariantIdx: Idx, - F: Deref> + fmt::Debug, + F: Deref> + fmt::Debug, { - let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited()); + let uninhabited = fields.iter().any(|f| f.is_uninhabited()); // We cannot ignore alignment; that might lead us to entirely discard a variant and // produce an enum that is less aligned than it should be! let is_1zst = fields.iter().all(|f| f.is_1zst()); @@ -89,7 +89,7 @@ impl LayoutCalculatorError { } type LayoutCalculatorResult = - Result, LayoutCalculatorError>; + Result, LayoutCalculatorError>; #[derive(Clone, Copy, Debug)] pub struct LayoutCalculator { @@ -105,7 +105,7 @@ impl LayoutCalculator { &self, a: Scalar, b: Scalar, - ) -> LayoutS { + ) -> LayoutData { let dl = self.cx.data_layout(); let b_align = b.align(dl); let align = a.align(dl).max(b_align).max(dl.aggregate_align); @@ -119,7 +119,7 @@ impl LayoutCalculator { .chain(Niche::from_scalar(dl, Size::ZERO, a)) .max_by_key(|niche| niche.available(dl)); - LayoutS { + LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Arbitrary { offsets: [Size::ZERO, b_offset].into(), @@ -138,7 +138,7 @@ impl LayoutCalculator { 'a, FieldIdx: Idx, VariantIdx: Idx, - F: Deref> + fmt::Debug + Copy, + F: Deref> + fmt::Debug + Copy, >( &self, fields: &IndexSlice, @@ -211,9 +211,9 @@ impl LayoutCalculator { pub fn layout_of_never_type( &self, - ) -> LayoutS { + ) -> LayoutData { let dl = self.cx.data_layout(); - LayoutS { + LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Primitive, abi: Abi::Uninhabited, @@ -229,7 +229,7 @@ impl LayoutCalculator { 'a, FieldIdx: Idx, VariantIdx: Idx, - F: Deref> + fmt::Debug + Copy, + F: Deref> + fmt::Debug + Copy, >( &self, repr: &ReprOptions, @@ -292,7 +292,7 @@ impl LayoutCalculator { 'a, FieldIdx: Idx, VariantIdx: Idx, - F: Deref> + fmt::Debug + Copy, + F: Deref> + fmt::Debug + Copy, >( &self, repr: &ReprOptions, @@ -384,7 +384,7 @@ impl LayoutCalculator { return Err(LayoutCalculatorError::EmptyUnion); }; - Ok(LayoutS { + Ok(LayoutData { variants: Variants::Single { index: only_variant_idx }, fields: FieldsShape::Union(union_field_count), abi, @@ -401,7 +401,7 @@ impl LayoutCalculator { 'a, FieldIdx: Idx, VariantIdx: Idx, - F: Deref> + fmt::Debug + Copy, + F: Deref> + fmt::Debug + Copy, >( &self, repr: &ReprOptions, @@ -501,7 +501,7 @@ impl LayoutCalculator { 'a, FieldIdx: Idx, VariantIdx: Idx, - F: Deref> + fmt::Debug + Copy, + F: Deref> + fmt::Debug + Copy, >( &self, repr: &ReprOptions, @@ -516,8 +516,8 @@ impl LayoutCalculator { // overall LayoutS. Store the overall LayoutS // and the variant LayoutSs here until then. struct TmpLayout { - layout: LayoutS, - variants: IndexVec>, + layout: LayoutData, + variants: IndexVec>, } let dl = self.cx.data_layout(); @@ -649,7 +649,7 @@ impl LayoutCalculator { Abi::Aggregate { sized: true } }; - let layout = LayoutS { + let layout = LayoutData { variants: Variants::Multiple { tag: niche_scalar, tag_encoding: TagEncoding::Niche { @@ -681,7 +681,7 @@ impl LayoutCalculator { let discr_type = repr.discr_type(); let bits = Integer::from_attr(dl, discr_type).size().bits(); for (i, mut val) in discriminants { - if !repr.c() && variants[i].iter().any(|f| f.abi.is_uninhabited()) { + if !repr.c() && variants[i].iter().any(|f| f.is_uninhabited()) { continue; } if discr_type.is_signed() { @@ -958,7 +958,7 @@ impl LayoutCalculator { let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag); - let tagged_layout = LayoutS { + let tagged_layout = LayoutData { variants: Variants::Multiple { tag, tag_encoding: TagEncoding::Direct, @@ -1013,7 +1013,7 @@ impl LayoutCalculator { 'a, FieldIdx: Idx, VariantIdx: Idx, - F: Deref> + fmt::Debug + Copy, + F: Deref> + fmt::Debug + Copy, >( &self, fields: &IndexSlice, @@ -1341,7 +1341,7 @@ impl LayoutCalculator { unadjusted_abi_align }; - Ok(LayoutS { + Ok(LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Arbitrary { offsets, memory_index }, abi, @@ -1357,10 +1357,10 @@ impl LayoutCalculator { 'a, FieldIdx: Idx, VariantIdx: Idx, - F: Deref> + fmt::Debug, + F: Deref> + fmt::Debug, >( &self, - layout: &LayoutS, + layout: &LayoutData, fields: &IndexSlice, ) -> String { let dl = self.cx.data_layout(); diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index c6812c4d4c07..e029e1426b21 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -58,7 +58,7 @@ rustc_index::newtype_index! { } #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)] #[rustc_pass_by_value] -pub struct Layout<'a>(pub Interned<'a, LayoutS>); +pub struct Layout<'a>(pub Interned<'a, LayoutData>); impl<'a> fmt::Debug for Layout<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -68,8 +68,8 @@ impl<'a> fmt::Debug for Layout<'a> { } impl<'a> Deref for Layout<'a> { - type Target = &'a LayoutS; - fn deref(&self) -> &&'a LayoutS { + type Target = &'a LayoutData; + fn deref(&self) -> &&'a LayoutData { &self.0.0 } } @@ -142,8 +142,8 @@ impl<'a, Ty: fmt::Display> fmt::Debug for TyAndLayout<'a, Ty> { } impl<'a, Ty> Deref for TyAndLayout<'a, Ty> { - type Target = &'a LayoutS; - fn deref(&self) -> &&'a LayoutS { + type Target = &'a LayoutData; + fn deref(&self) -> &&'a LayoutData { &self.layout.0.0 } } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 8e90130da4c0..41922aee6487 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1485,7 +1485,7 @@ pub enum Variants { tag: Scalar, tag_encoding: TagEncoding, tag_field: usize, - variants: IndexVec>, + variants: IndexVec>, }, } @@ -1603,7 +1603,7 @@ impl Niche { // NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage. #[derive(PartialEq, Eq, Hash, Clone)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub struct LayoutS { +pub struct LayoutData { /// Says where the fields are located within the layout. pub fields: FieldsShape, @@ -1643,7 +1643,7 @@ pub struct LayoutS { pub unadjusted_abi_align: Align, } -impl LayoutS { +impl LayoutData { /// Returns `true` if this is an aggregate type (including a ScalarPair!) pub fn is_aggregate(&self) -> bool { match self.abi { @@ -1652,11 +1652,16 @@ impl LayoutS { } } + /// Returns `true` if this is an uninhabited type + pub fn is_uninhabited(&self) -> bool { + self.abi.is_uninhabited() + } + pub fn scalar(cx: &C, scalar: Scalar) -> Self { let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar); let size = scalar.size(cx); let align = scalar.align(cx); - LayoutS { + LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Primitive, abi: Abi::Scalar(scalar), @@ -1669,7 +1674,7 @@ impl LayoutS { } } -impl fmt::Debug for LayoutS +impl fmt::Debug for LayoutData where FieldsShape: fmt::Debug, Variants: fmt::Debug, @@ -1678,7 +1683,7 @@ where // This is how `Layout` used to print before it become // `Interned`. We print it like this to avoid having to update // expected output in a lot of tests. - let LayoutS { + let LayoutData { size, align, abi, @@ -1723,7 +1728,7 @@ pub struct PointeeInfo { pub safe: Option, } -impl LayoutS { +impl LayoutData { /// Returns `true` if the layout corresponds to an unsized type. #[inline] pub fn is_unsized(&self) -> bool { diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 02cb6f188a71..8e4f4c8e71a2 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2697,7 +2697,7 @@ impl fmt::Debug for ImplPolarity { } /// The polarity of a trait bound. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)] #[derive(HashStable_Generic)] pub enum BoundPolarity { /// `Type: Trait` @@ -2719,7 +2719,7 @@ impl BoundPolarity { } /// The constness of a trait bound. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)] #[derive(HashStable_Generic)] pub enum BoundConstness { /// `Type: Trait` diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index b73412a4b1de..9311af28f545 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -223,7 +223,7 @@ impl AttrItem { self.args.span().map_or(self.path.span, |args_span| self.path.span.to(args_span)) } - fn meta_item_list(&self) -> Option> { + pub fn meta_item_list(&self) -> Option> { match &self.args { AttrArgs::Delimited(args) if args.delim == Delimiter::Parenthesis => { MetaItemKind::list_from_tokens(args.tokens.clone()) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 1d6abbef06c9..3b9edef06159 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -368,7 +368,7 @@ impl Clone for TokenKind { // a copy. This is faster than the `derive(Clone)` version which has a // separate path for every variant. match self { - Interpolated(nt) => Interpolated(nt.clone()), + Interpolated(nt) => Interpolated(Lrc::clone(nt)), _ => unsafe { std::ptr::read(self) }, } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 207ec7106505..eb71ec5f4ec9 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -135,7 +135,7 @@ pub trait Visitor<'ast>: Sized { /// or `ControlFlow`. type Result: VisitorResult = (); - fn visit_ident(&mut self, _ident: Ident) -> Self::Result { + fn visit_ident(&mut self, _ident: &'ast Ident) -> Self::Result { Self::Result::output() } fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result { @@ -173,9 +173,6 @@ pub trait Visitor<'ast>: Sized { fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { self.visit_expr(ex) } - fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { - Self::Result::output() - } fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result { walk_ty(self, t) } @@ -317,12 +314,12 @@ pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::R } pub fn walk_label<'a, V: Visitor<'a>>(visitor: &mut V, Label { ident }: &'a Label) -> V::Result { - visitor.visit_ident(*ident) + visitor.visit_ident(ident) } pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) -> V::Result { let Lifetime { id: _, ident } = lifetime; - visitor.visit_ident(*ident) + visitor.visit_ident(ident) } pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result @@ -429,7 +426,7 @@ impl WalkItemKind for ItemKind { }) => { try_visit!(walk_qself(visitor, qself)); try_visit!(visitor.visit_path(path, *id)); - visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_ident, rename); visit_opt!(visitor, visit_block, body); } ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { @@ -437,9 +434,9 @@ impl WalkItemKind for ItemKind { try_visit!(visitor.visit_path(prefix, *id)); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { - visitor.visit_ident(*ident); + visitor.visit_ident(ident); if let Some(rename) = rename { - visitor.visit_ident(*rename); + visitor.visit_ident(rename); } } } @@ -472,7 +469,7 @@ where let Variant { attrs, id: _, span: _, vis, ident, data, disr_expr, is_placeholder: _ } = variant; walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_variant_data(data)); visit_opt!(visitor, visit_variant_discr, disr_expr); V::Result::output() @@ -481,7 +478,7 @@ where pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result { let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = f; walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_expr(expr)); V::Result::output() } @@ -489,7 +486,7 @@ pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result { let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp; walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_pat(pat)); V::Result::output() } @@ -564,7 +561,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>( match kind { UseTreeKind::Simple(rename) => { // The extra IDs are handled during AST lowering. - visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_ident, rename); } UseTreeKind::Glob => {} UseTreeKind::Nested { ref items, span: _ } => { @@ -581,7 +578,7 @@ pub fn walk_path_segment<'a, V: Visitor<'a>>( segment: &'a PathSegment, ) -> V::Result { let PathSegment { ident, id: _, args } = segment; - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); visit_opt!(visitor, visit_generic_args, args); V::Result::output() } @@ -627,7 +624,7 @@ pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>( constraint: &'a AssocItemConstraint, ) -> V::Result { let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint; - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); visit_opt!(visitor, visit_generic_args, gen_args); match kind { AssocItemConstraintKind::Equality { term } => match term { @@ -665,7 +662,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res try_visit!(visitor.visit_pat(subpattern)); } PatKind::Ident(_bmode, ident, optional_subpattern) => { - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); visit_opt!(visitor, visit_pat, optional_subpattern); } PatKind::Lit(expression) => try_visit!(visitor.visit_expr(expression)), @@ -751,7 +748,7 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>( let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } = param; walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); match kind { GenericParamKind::Lifetime => (), @@ -889,7 +886,7 @@ impl WalkItemKind for AssocItemKind { }) => { try_visit!(walk_qself(visitor, qself)); try_visit!(visitor.visit_path(path, *id)); - visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_ident, rename); visit_opt!(visitor, visit_block, body); } AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { @@ -897,9 +894,9 @@ impl WalkItemKind for AssocItemKind { try_visit!(visitor.visit_path(prefix, id)); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { - visitor.visit_ident(*ident); + visitor.visit_ident(ident); if let Some(rename) = rename { - visitor.visit_ident(*rename); + visitor.visit_ident(rename); } } } @@ -915,7 +912,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>( item: &'a Item, ctxt: AssocCtxt, ) -> V::Result { - let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; + let Item { id: _, span: _, ident, vis, attrs, kind, tokens: _ } = item; walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); try_visit!(visitor.visit_ident(ident)); @@ -935,7 +932,7 @@ pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field; walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); - visit_opt!(visitor, visit_ident, *ident); + visit_opt!(visitor, visit_ident, ident); try_visit!(visitor.visit_ty(ty)); V::Result::output() } @@ -1017,7 +1014,7 @@ pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs for FormatArgument { kind, expr } in arguments.all_args() { match kind { FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { - try_visit!(visitor.visit_ident(*ident)) + try_visit!(visitor.visit_ident(ident)) } FormatArgumentKind::Normal => {} } @@ -1137,7 +1134,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V } ExprKind::Field(subexpression, ident) => { try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); } ExprKind::Index(main_expression, index_expression, _span) => { try_visit!(visitor.visit_expr(main_expression)); @@ -1172,7 +1169,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)), ExprKind::OffsetOf(container, fields) => { try_visit!(visitor.visit_ty(container)); - walk_list!(visitor, visit_ident, fields.iter().copied()); + walk_list!(visitor, visit_ident, fields.iter()); } ExprKind::Yield(optional_expression) => { visit_opt!(visitor, visit_expr, optional_expression); @@ -1185,7 +1182,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V ExprKind::Dummy => {} } - visitor.visit_expr_post(expression) + V::Result::output() } pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::Result { diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 88cdb2ec3639..6585a7de2459 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -49,7 +49,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | asm::InlineAsmArch::RiscV64 | asm::InlineAsmArch::LoongArch64 ); - if !is_stable && !self.tcx.features().asm_experimental_arch { + if !is_stable && !self.tcx.features().asm_experimental_arch() { feature_err( &self.tcx.sess, sym::asm_experimental_arch, @@ -65,7 +65,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { { self.dcx().emit_err(AttSyntaxOnlyX86 { span: sp }); } - if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind { + if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind() { feature_err( &self.tcx.sess, sym::asm_unwind, @@ -237,7 +237,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } InlineAsmOperand::Label { block } => { - if !self.tcx.features().asm_goto { + if !self.tcx.features().asm_goto() { feature_err( sess, sym::asm_goto, diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 9d2b5690c23d..20d3ce65facc 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -10,17 +10,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { b: &Block, targeted_by_break: bool, ) -> &'hir hir::Block<'hir> { - self.arena.alloc(self.lower_block_noalloc(b, targeted_by_break)) + let hir_id = self.lower_node_id(b.id); + self.arena.alloc(self.lower_block_noalloc(hir_id, b, targeted_by_break)) } pub(super) fn lower_block_noalloc( &mut self, + hir_id: hir::HirId, b: &Block, targeted_by_break: bool, ) -> hir::Block<'hir> { let (stmts, expr) = self.lower_stmts(&b.stmts); let rules = self.lower_block_check_mode(&b.rules); - let hir_id = self.lower_node_id(b.id); hir::Block { hir_id, stmts, expr, rules, span: self.lower_span(b.span), targeted_by_break } } diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 3b85f1737bdd..70c94f4019ae 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -259,10 +259,11 @@ impl<'hir> LoweringContext<'_, 'hir> { self_param_id: pat_node_id, }; self_resolver.visit_block(block); + // Target expr needs to lower `self` path. + this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id); this.lower_target_expr(&block) } else { - let pat_hir_id = this.lower_node_id(pat_node_id); - this.generate_arg(pat_hir_id, span) + this.generate_arg(param.pat.hir_id, span) }; args.push(arg); } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index ae1e1b3f8a21..b7cf2d252dcf 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -3,6 +3,7 @@ use std::assert_matches::assert_matches; use rustc_ast::ptr::P as AstP; use rustc_ast::*; use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def::{DefKind, Res}; @@ -70,8 +71,8 @@ impl<'hir> LoweringContext<'_, 'hir> { _ => (), } - let hir_id = self.lower_node_id(e.id); - self.lower_attrs(hir_id, &e.attrs); + let expr_hir_id = self.lower_node_id(e.id); + self.lower_attrs(expr_hir_id, &e.attrs); let kind = match &e.kind { ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), @@ -143,7 +144,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::IncludedBytes(bytes) => { let lit = self.arena.alloc(respan( self.lower_span(e.span), - LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), + LitKind::ByteStr(Lrc::clone(bytes), StrStyle::Cooked), )); hir::ExprKind::Lit(lit) } @@ -175,18 +176,25 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::If(cond, then, else_opt) => { self.lower_expr_if(cond, then, else_opt.as_deref()) } - ExprKind::While(cond, body, opt_label) => self.with_loop_scope(e.id, |this| { - let span = this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None); - this.lower_expr_while_in_loop_scope(span, cond, body, *opt_label) - }), - ExprKind::Loop(body, opt_label, span) => self.with_loop_scope(e.id, |this| { - hir::ExprKind::Loop( - this.lower_block(body, false), - this.lower_label(*opt_label), - hir::LoopSource::Loop, - this.lower_span(*span), - ) - }), + ExprKind::While(cond, body, opt_label) => { + self.with_loop_scope(expr_hir_id, |this| { + let span = + this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None); + let opt_label = this.lower_label(*opt_label, e.id, expr_hir_id); + this.lower_expr_while_in_loop_scope(span, cond, body, opt_label) + }) + } + ExprKind::Loop(body, opt_label, span) => { + self.with_loop_scope(expr_hir_id, |this| { + let opt_label = this.lower_label(*opt_label, e.id, expr_hir_id); + hir::ExprKind::Loop( + this.lower_block(body, false), + opt_label, + hir::LoopSource::Loop, + this.lower_span(*span), + ) + }) + } ExprKind::TryBlock(body) => self.lower_expr_try_block(body), ExprKind::Match(expr, arms, kind) => hir::ExprKind::Match( self.lower_expr(expr), @@ -212,7 +220,7 @@ impl<'hir> LoweringContext<'_, 'hir> { binder, *capture_clause, e.id, - hir_id, + expr_hir_id, *coroutine_kind, fn_decl, body, @@ -223,7 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> { binder, *capture_clause, e.id, - hir_id, + expr_hir_id, *constness, *movability, fn_decl, @@ -250,8 +258,16 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } ExprKind::Block(blk, opt_label) => { - let opt_label = self.lower_label(*opt_label); - hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label) + // Different from loops, label of block resolves to block id rather than + // expr node id. + let block_hir_id = self.lower_node_id(blk.id); + let opt_label = self.lower_label(*opt_label, blk.id, block_hir_id); + let hir_block = self.arena.alloc(self.lower_block_noalloc( + block_hir_id, + blk, + opt_label.is_some(), + )); + hir::ExprKind::Block(hir_block, opt_label) } ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span), ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp( @@ -354,7 +370,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span), }; - hir::Expr { hir_id, kind, span: self.lower_span(e.span) } + hir::Expr { hir_id: expr_hir_id, kind, span: self.lower_span(e.span) } }) } @@ -504,7 +520,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let if_expr = self.expr(span, if_kind); let block = self.block_expr(self.arena.alloc(if_expr)); let span = self.lower_span(span.with_hi(cond.span.hi())); - let opt_label = self.lower_label(opt_label); hir::ExprKind::Loop(block, opt_label, hir::LoopSource::While, span) } @@ -512,8 +527,9 @@ impl<'hir> LoweringContext<'_, 'hir> { /// `try { ; }` into `{ ; ::std::ops::Try::from_output(()) }` /// and save the block id to use it as a break target for desugaring of the `?` operator. fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> { - self.with_catch_scope(body.id, |this| { - let mut block = this.lower_block_noalloc(body, true); + let body_hir_id = self.lower_node_id(body.id); + self.with_catch_scope(body_hir_id, |this| { + let mut block = this.lower_block_noalloc(body_hir_id, body, true); // Final expression of the block (if present) or `()` with span at the end of block let (try_span, tail_expr) = if let Some(expr) = block.expr.take() { @@ -521,7 +537,7 @@ impl<'hir> LoweringContext<'_, 'hir> { this.mark_span_with_reason( DesugaringKind::TryBlock, expr.span, - Some(this.allow_try_trait.clone()), + Some(Lrc::clone(&this.allow_try_trait)), ), expr, ) @@ -529,7 +545,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let try_span = this.mark_span_with_reason( DesugaringKind::TryBlock, this.tcx.sess.source_map().end_point(body.span), - Some(this.allow_try_trait.clone()), + Some(Lrc::clone(&this.allow_try_trait)), ); (try_span, this.expr_unit(try_span)) @@ -575,7 +591,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } else { // Either `body.is_none()` or `is_never_pattern` here. if !is_never_pattern { - if self.tcx.features().never_patterns { + if self.tcx.features().never_patterns() { // If the feature is off we already emitted the error after parsing. let suggestion = span.shrink_to_hi(); self.dcx().emit_err(MatchArmWithNoBody { span, suggestion }); @@ -638,7 +654,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::Async, self.lower_span(span), - Some(self.allow_gen_future.clone()), + Some(Lrc::clone(&self.allow_gen_future)), ); let resume_ty = self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span, None); @@ -717,14 +733,14 @@ impl<'hir> LoweringContext<'_, 'hir> { outer_hir_id: HirId, inner_hir_id: HirId, ) { - if self.tcx.features().async_fn_track_caller + if self.tcx.features().async_fn_track_caller() && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) && attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)) { let unstable_span = self.mark_span_with_reason( DesugaringKind::Async, span, - Some(self.allow_gen_future.clone()), + Some(Lrc::clone(&self.allow_gen_future)), ); self.lower_attrs(inner_hir_id, &[Attribute { kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new( @@ -800,13 +816,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let features = match await_kind { FutureKind::Future => None, - FutureKind::AsyncIterator => Some(self.allow_for_await.clone()), + FutureKind::AsyncIterator => Some(Lrc::clone(&self.allow_for_await)), }; let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, features); let gen_future_span = self.mark_span_with_reason( DesugaringKind::Await, full_span, - Some(self.allow_gen_future.clone()), + Some(Lrc::clone(&self.allow_gen_future)), ); let expr_hir_id = expr.hir_id; @@ -869,7 +885,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let x_expr = self.expr_ident(gen_future_span, x_ident, x_pat_hid); let ready_field = self.single_pat_field(gen_future_span, x_pat); let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field); - let break_x = self.with_loop_scope(loop_node_id, move |this| { + let break_x = self.with_loop_scope(loop_hir_id, move |this| { let expr_break = hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); this.arena.alloc(this.expr(gen_future_span, expr_break)) @@ -1101,8 +1117,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::CoroutineSource::Closure, ); - let hir_id = this.lower_node_id(coroutine_kind.closure_id()); - this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id); + this.maybe_forward_track_caller(body.span, closure_hir_id, expr.hir_id); (parameters, expr) }); @@ -1465,8 +1480,16 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } - fn lower_label(&self, opt_label: Option