about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast_lowering/src')
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs55
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs45
-rw-r--r--compiler/rustc_ast_lowering/src/format.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs24
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs95
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs9
6 files changed, 76 insertions, 156 deletions
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index 42d25b512f5..9bfcd232221 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -47,6 +47,7 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
 use rustc_middle::span_bug;
 use rustc_middle::ty::{Asyncness, ResolverAstLowering};
+use rustc_span::symbol::kw;
 use rustc_span::{Ident, Span, Symbol};
 use {rustc_ast as ast, rustc_hir as hir};
 
@@ -61,21 +62,6 @@ pub(crate) struct DelegationResults<'hir> {
 }
 
 impl<'hir> LoweringContext<'_, 'hir> {
-    /// Defines whether the delegatee is an associated function whose first parameter is `self`.
-    pub(crate) fn delegatee_is_method(
-        &self,
-        item_id: NodeId,
-        path_id: NodeId,
-        span: Span,
-        is_in_trait_impl: bool,
-    ) -> bool {
-        let sig_id = self.get_delegation_sig_id(item_id, path_id, span, is_in_trait_impl);
-        let Ok(sig_id) = sig_id else {
-            return false;
-        };
-        self.is_method(sig_id, span)
-    }
-
     fn is_method(&self, def_id: DefId, span: Span) -> bool {
         match self.tcx.def_kind(def_id) {
             DefKind::Fn => false,
@@ -101,10 +87,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
         match sig_id {
             Ok(sig_id) => {
+                let is_method = self.is_method(sig_id, span);
                 let (param_count, c_variadic) = self.param_count(sig_id);
                 let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
                 let sig = self.lower_delegation_sig(sig_id, decl, span);
-                let body_id = self.lower_delegation_body(delegation, param_count, span);
+                let body_id = self.lower_delegation_body(delegation, is_method, param_count, span);
                 let ident = self.lower_ident(delegation.ident);
                 let generics = self.lower_delegation_generics(span);
                 DelegationResults { body_id, sig, ident, generics }
@@ -234,10 +221,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
         hir::FnSig { decl, header, span }
     }
 
-    fn generate_param(&mut self, idx: usize, span: Span) -> (hir::Param<'hir>, NodeId) {
+    fn generate_param(
+        &mut self,
+        is_method: bool,
+        idx: usize,
+        span: Span,
+    ) -> (hir::Param<'hir>, NodeId) {
         let pat_node_id = self.next_node_id();
         let pat_id = self.lower_node_id(pat_node_id);
-        let ident = Ident::with_dummy_span(Symbol::intern(&format!("arg{idx}")));
+        // FIXME(cjgillot) AssocItem currently relies on self parameter being exactly named `self`.
+        let name = if is_method && idx == 0 {
+            kw::SelfLower
+        } else {
+            Symbol::intern(&format!("arg{idx}"))
+        };
+        let ident = Ident::with_dummy_span(name);
         let pat = self.arena.alloc(hir::Pat {
             hir_id: pat_id,
             kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, ident, None),
@@ -248,9 +246,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
         (hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id)
     }
 
-    fn generate_arg(&mut self, idx: usize, param_id: HirId, span: Span) -> hir::Expr<'hir> {
+    fn generate_arg(
+        &mut self,
+        is_method: bool,
+        idx: usize,
+        param_id: HirId,
+        span: Span,
+    ) -> hir::Expr<'hir> {
+        // FIXME(cjgillot) AssocItem currently relies on self parameter being exactly named `self`.
+        let name = if is_method && idx == 0 {
+            kw::SelfLower
+        } else {
+            Symbol::intern(&format!("arg{idx}"))
+        };
         let segments = self.arena.alloc_from_iter(iter::once(hir::PathSegment {
-            ident: Ident::with_dummy_span(Symbol::intern(&format!("arg{idx}"))),
+            ident: Ident::with_dummy_span(name),
             hir_id: self.next_id(),
             res: Res::Local(param_id),
             args: None,
@@ -264,6 +274,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_delegation_body(
         &mut self,
         delegation: &Delegation,
+        is_method: bool,
         param_count: usize,
         span: Span,
     ) -> BodyId {
@@ -274,7 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let mut args: Vec<hir::Expr<'_>> = Vec::with_capacity(param_count);
 
             for idx in 0..param_count {
-                let (param, pat_node_id) = this.generate_param(idx, span);
+                let (param, pat_node_id) = this.generate_param(is_method, idx, span);
                 parameters.push(param);
 
                 let arg = if let Some(block) = block
@@ -290,7 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id);
                     this.lower_target_expr(&block)
                 } else {
-                    this.generate_arg(idx, param.pat.hir_id, span)
+                    this.generate_arg(is_method, idx, 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 8747e624a4a..15e736261d5 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -528,7 +528,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         then: &Block,
         else_opt: Option<&Expr>,
     ) -> hir::ExprKind<'hir> {
-        let lowered_cond = self.lower_cond(cond);
+        let lowered_cond = self.lower_expr(cond);
         let then_expr = self.lower_block_expr(then);
         if let Some(rslt) = else_opt {
             hir::ExprKind::If(
@@ -541,44 +541,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    // Lowers a condition (i.e. `cond` in `if cond` or `while cond`), wrapping it in a terminating scope
-    // so that temporaries created in the condition don't live beyond it.
-    fn lower_cond(&mut self, cond: &Expr) -> &'hir hir::Expr<'hir> {
-        fn has_let_expr(expr: &Expr) -> bool {
-            match &expr.kind {
-                ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
-                ExprKind::Let(..) => true,
-                _ => false,
-            }
-        }
-
-        // We have to take special care for `let` exprs in the condition, e.g. in
-        // `if let pat = val` or `if foo && let pat = val`, as we _do_ want `val` to live beyond the
-        // condition in this case.
-        //
-        // In order to maintain the drop behavior for the non `let` parts of the condition,
-        // we still wrap them in terminating scopes, e.g. `if foo && let pat = val` essentially
-        // gets transformed into `if { let _t = foo; _t } && let pat = val`
-        match &cond.kind {
-            ExprKind::Binary(op @ Spanned { node: ast::BinOpKind::And, .. }, lhs, rhs)
-                if has_let_expr(cond) =>
-            {
-                let op = self.lower_binop(*op);
-                let lhs = self.lower_cond(lhs);
-                let rhs = self.lower_cond(rhs);
-
-                self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs)))
-            }
-            ExprKind::Let(..) => self.lower_expr(cond),
-            _ => {
-                let cond = self.lower_expr(cond);
-                let reason = DesugaringKind::CondTemporary;
-                let span_block = self.mark_span_with_reason(reason, cond.span, None);
-                self.expr_drop_temps(span_block, cond)
-            }
-        }
-    }
-
     // We desugar: `'label: while $cond $body` into:
     //
     // ```
@@ -602,7 +564,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         body: &Block,
         opt_label: Option<Label>,
     ) -> hir::ExprKind<'hir> {
-        let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond));
+        let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond));
         let then = self.lower_block_expr(body);
         let expr_break = self.expr_break(span);
         let stmt_break = self.stmt_expr(span, expr_break);
@@ -2091,7 +2053,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
     /// In terms of drop order, it has the same effect as wrapping `expr` in
     /// `{ let _t = $expr; _t }` but should provide better compile-time performance.
     ///
-    /// The drop order can be important in e.g. `if expr { .. }`.
+    /// The drop order can be important, e.g. to drop temporaries from an `async fn`
+    /// body before its parameters.
     pub(super) fn expr_drop_temps(
         &mut self,
         span: Span,
diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index 943cde90dd2..5b1dcab87b9 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -55,7 +55,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     /// Get the maximum value of int_ty. It is platform-dependent due to the byte size of isize
     fn int_ty_max(&self, int_ty: IntTy) -> u128 {
         match int_ty {
-            IntTy::Isize => self.tcx.data_layout.pointer_size.signed_int_max() as u128,
+            IntTy::Isize => self.tcx.data_layout.pointer_size().signed_int_max() as u128,
             IntTy::I8 => i8::MAX as u128,
             IntTy::I16 => i16::MAX as u128,
             IntTy::I32 => i32::MAX as u128,
@@ -67,7 +67,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     /// Get the maximum value of uint_ty. It is platform-dependent due to the byte size of usize
     fn uint_ty_max(&self, uint_ty: UintTy) -> u128 {
         match uint_ty {
-            UintTy::Usize => self.tcx.data_layout.pointer_size.unsigned_int_max(),
+            UintTy::Usize => self.tcx.data_layout.pointer_size().unsigned_int_max(),
             UintTy::U8 => u8::MAX as u128,
             UintTy::U16 => u16::MAX as u128,
             UintTy::U32 => u32::MAX as u128,
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 956cb580d10..1ef64f5a352 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -381,28 +381,16 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         })
     }
 
-    fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) {
-        // Do not visit the duplicate information in TraitItemRef. We want to
-        // map the actual nodes, not the duplicate ones in the *Ref.
-        let TraitItemRef { id, ident: _, kind: _, span: _ } = *ii;
-
-        self.visit_nested_trait_item(id);
+    fn visit_trait_item_ref(&mut self, id: &'hir TraitItemId) {
+        self.visit_nested_trait_item(*id);
     }
 
-    fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) {
-        // Do not visit the duplicate information in ImplItemRef. We want to
-        // map the actual nodes, not the duplicate ones in the *Ref.
-        let ImplItemRef { id, ident: _, kind: _, span: _, trait_item_def_id: _ } = *ii;
-
-        self.visit_nested_impl_item(id);
+    fn visit_impl_item_ref(&mut self, id: &'hir ImplItemId) {
+        self.visit_nested_impl_item(*id);
     }
 
-    fn visit_foreign_item_ref(&mut self, fi: &'hir ForeignItemRef) {
-        // Do not visit the duplicate information in ForeignItemRef. We want to
-        // map the actual nodes, not the duplicate ones in the *Ref.
-        let ForeignItemRef { id, ident: _, span: _ } = *fi;
-
-        self.visit_nested_foreign_item(id);
+    fn visit_foreign_item_ref(&mut self, id: &'hir ForeignItemId) {
+        self.visit_nested_foreign_item(*id);
     }
 
     fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index bdcb750ba26..abd70c7517c 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -393,11 +393,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         (trait_ref, lowered_ty)
                     });
 
-                let new_impl_items = self.arena.alloc_from_iter(
-                    impl_items
-                        .iter()
-                        .map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
-                );
+                let new_impl_items = self
+                    .arena
+                    .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
 
                 // `defaultness.has_value()` is never called for an `impl`, always `true` in order
                 // to not cause an assertion failure inside the `lower_defaultness` function.
@@ -419,7 +417,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     items: new_impl_items,
                 }))
             }
-            ItemKind::Trait(box Trait { is_auto, safety, ident, generics, bounds, items }) => {
+            ItemKind::Trait(box Trait {
+                constness,
+                is_auto,
+                safety,
+                ident,
+                generics,
+                bounds,
+                items,
+            }) => {
+                let constness = self.lower_constness(*constness);
                 let ident = self.lower_ident(*ident);
                 let (generics, (safety, items, bounds)) = self.lower_generics(
                     generics,
@@ -437,7 +444,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         (safety, items, bounds)
                     },
                 );
-                hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items)
+                hir::ItemKind::Trait(constness, *is_auto, safety, ident, generics, bounds, items)
             }
             ItemKind::TraitAlias(ident, generics, bounds) => {
                 let ident = self.lower_ident(*ident);
@@ -706,14 +713,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.arena.alloc(item)
     }
 
-    fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
-        hir::ForeignItemRef {
-            id: hir::ForeignItemId { owner_id: self.owner_id(i.id) },
-            // `unwrap` is safe because `ForeignItemKind::MacCall` is the only foreign item kind
-            // without an identifier and it cannot reach here.
-            ident: self.lower_ident(i.kind.ident().unwrap()),
-            span: self.lower_span(i.span),
-        }
+    fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemId {
+        hir::ForeignItemId { owner_id: self.owner_id(i.id) }
     }
 
     fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> {
@@ -972,32 +973,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.arena.alloc(item)
     }
 
-    fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
-        let (ident, kind) = match &i.kind {
-            AssocItemKind::Const(box ConstItem { ident, .. }) => {
-                (*ident, hir::AssocItemKind::Const)
-            }
-            AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, hir::AssocItemKind::Type),
-            AssocItemKind::Fn(box Fn { ident, sig, .. }) => {
-                (*ident, hir::AssocItemKind::Fn { has_self: sig.decl.has_self() })
-            }
-            AssocItemKind::Delegation(box delegation) => (
-                delegation.ident,
-                hir::AssocItemKind::Fn {
-                    has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
-                },
-            ),
-            AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
-                panic!("macros should have been expanded by now")
-            }
-        };
-        let id = hir::TraitItemId { owner_id: self.owner_id(i.id) };
-        hir::TraitItemRef {
-            id,
-            ident: self.lower_ident(ident),
-            span: self.lower_span(i.span),
-            kind,
-        }
+    fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemId {
+        hir::TraitItemId { owner_id: self.owner_id(i.id) }
     }
 
     /// Construct `ExprKind::Err` for the given `span`.
@@ -1128,41 +1105,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
             span: self.lower_span(i.span),
             defaultness,
             has_delayed_lints: !self.delayed_lints.is_empty(),
-        };
-        self.arena.alloc(item)
-    }
-
-    fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
-        hir::ImplItemRef {
-            id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
-            // `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only
-            // assoc item kinds without an identifier and they cannot reach here.
-            ident: self.lower_ident(i.kind.ident().unwrap()),
-            span: self.lower_span(i.span),
-            kind: match &i.kind {
-                AssocItemKind::Const(..) => hir::AssocItemKind::Const,
-                AssocItemKind::Type(..) => hir::AssocItemKind::Type,
-                AssocItemKind::Fn(box Fn { sig, .. }) => {
-                    hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
-                }
-                AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
-                    has_self: self.delegatee_is_method(
-                        i.id,
-                        delegation.id,
-                        i.span,
-                        is_in_trait_impl,
-                    ),
-                },
-                AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
-                    panic!("macros should have been expanded by now")
-                }
-            },
             trait_item_def_id: self
                 .resolver
                 .get_partial_res(i.id)
                 .map(|r| r.expect_full_res().opt_def_id())
                 .unwrap_or(None),
-        }
+        };
+        self.arena.alloc(item)
+    }
+
+    fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemId {
+        hir::ImplItemId { owner_id: self.owner_id(i.id) }
     }
 
     fn lower_defaultness(
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 348fe2ee40a..1c96a375035 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -42,7 +42,7 @@ use std::sync::Arc;
 
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::{self as ast, *};
-use rustc_attr_parsing::{AttributeParser, OmitDoc};
+use rustc_attr_parsing::{AttributeParser, Late, OmitDoc};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -192,7 +192,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             // interact with `gen`/`async gen` blocks
             allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),
 
-            attribute_parser: AttributeParser::new(tcx.sess, tcx.features(), registered_tools),
+            attribute_parser: AttributeParser::new(
+                tcx.sess,
+                tcx.features(),
+                registered_tools,
+                Late,
+            ),
             delayed_lints: Vec::new(),
         }
     }