about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering/src
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@users.noreply.github.com>2025-03-10 09:52:17 +0000
committerGitHub <noreply@github.com>2025-03-10 09:52:17 +0000
commit52f39ffe8320955868ce03eb22d9020c568472da (patch)
tree6e32a4f4ff812cdbfb923b455777d48dbb1c45aa /compiler/rustc_ast_lowering/src
parentaf32b22982ef0244cf4cf6a7f7b63274429289f8 (diff)
parent1d983bf7941bb89985d53e741cabcf113912a40d (diff)
Merge pull request #19331 from lnicola/sync-from-rust
minor: Sync from downstream
Diffstat (limited to 'compiler/rustc_ast_lowering/src')
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs44
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs30
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs122
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs1
5 files changed, 148 insertions, 50 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 9c3db7abc1c..acf35b75e4d 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -13,7 +13,7 @@ use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::errors::report_lit_error;
 use rustc_span::source_map::{Spanned, respan};
-use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
+use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym};
 use thin_vec::{ThinVec, thin_vec};
 use visit::{Visitor, walk_expr};
 
@@ -207,6 +207,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     },
                 ),
                 ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr),
+                ExprKind::Use(expr, use_kw_span) => self.lower_expr_use(*use_kw_span, expr),
                 ExprKind::Closure(box Closure {
                     binder,
                     capture_clause,
@@ -483,7 +484,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             if legacy_args_idx.contains(&idx) {
                 let parent_def_id = self.current_hir_id_owner.def_id;
                 let node_id = self.next_node_id();
-                self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
+                self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, f.span);
                 let mut visitor = WillCreateDefIdsVisitor {};
                 let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) {
                     AstP(Expr {
@@ -1067,6 +1068,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         )
     }
 
+    fn lower_expr_use(&mut self, use_kw_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
+        hir::ExprKind::Use(self.lower_expr(expr), use_kw_span)
+    }
+
     fn lower_expr_closure(
         &mut self,
         binder: &ClosureBinder,
@@ -1690,6 +1695,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let yielded =
             opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
 
+        if !self.tcx.features().yield_expr()
+            && !self.tcx.features().coroutines()
+            && !self.tcx.features().gen_blocks()
+        {
+            rustc_session::parse::feature_err(
+                &self.tcx.sess,
+                sym::yield_expr,
+                span,
+                fluent_generated::ast_lowering_yield,
+            )
+            .emit();
+        }
+
         let is_async_gen = match self.coroutine_kind {
             Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false,
             Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
@@ -1714,28 +1732,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     None,
                 );
             }
-            Some(hir::CoroutineKind::Coroutine(_)) => {
-                if !self.tcx.features().coroutines() {
-                    rustc_session::parse::feature_err(
-                        &self.tcx.sess,
-                        sym::coroutines,
-                        span,
-                        fluent_generated::ast_lowering_yield,
-                    )
-                    .emit();
-                }
-                false
-            }
+            Some(hir::CoroutineKind::Coroutine(_)) => false,
             None => {
-                if !self.tcx.features().coroutines() {
-                    rustc_session::parse::feature_err(
-                        &self.tcx.sess,
-                        sym::coroutines,
-                        span,
-                        fluent_generated::ast_lowering_yield,
-                    )
-                    .emit();
-                }
                 let suggestion = self.current_item.map(|s| s.shrink_to_lo());
                 self.dcx().emit_err(YieldInClosure { span, suggestion });
                 self.coroutine_kind = Some(hir::CoroutineKind::Coroutine(Movability::Movable));
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 15802101f71..5e89321e6ec 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1728,6 +1728,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
         let hir_id = self.lower_node_id(pred.id);
         let span = self.lower_span(pred.span);
+        self.lower_attrs(hir_id, &pred.attrs, span);
         let kind = self.arena.alloc(match &pred.kind {
             WherePredicateKind::BoundPredicate(WhereBoundPredicate {
                 bound_generic_params,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 13edcc10c9e..4cecc56909e 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -38,7 +38,6 @@
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::sync::Arc;
@@ -136,6 +135,7 @@ struct LoweringContext<'a, 'hir> {
 
     allow_try_trait: Arc<[Symbol]>,
     allow_gen_future: Arc<[Symbol]>,
+    allow_pattern_type: Arc<[Symbol]>,
     allow_async_iterator: Arc<[Symbol]>,
     allow_for_await: Arc<[Symbol]>,
     allow_async_fn_traits: Arc<[Symbol]>,
@@ -176,6 +176,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             impl_trait_defs: Vec::new(),
             impl_trait_bounds: Vec::new(),
             allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
+            allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
             allow_gen_future: if tcx.features().async_fn_track_caller() {
                 [sym::gen_future, sym::closure_track_caller].into()
             } else {
@@ -492,7 +493,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         parent: LocalDefId,
         node_id: ast::NodeId,
-        name: Symbol,
+        name: Option<Symbol>,
         def_kind: DefKind,
         span: Span,
     ) -> LocalDefId {
@@ -772,7 +773,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 let _def_id = self.create_def(
                     self.current_hir_id_owner.def_id,
                     param,
-                    kw::UnderscoreLifetime,
+                    Some(kw::UnderscoreLifetime),
                     DefKind::LifetimeParam,
                     ident.span,
                 );
@@ -926,7 +927,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     if let Some(first_char) = constraint.ident.as_str().chars().next()
                         && first_char.is_ascii_lowercase()
                     {
-                        tracing::info!(?data, ?data.inputs);
                         let err = match (&data.inputs[..], &data.output) {
                             ([_, ..], FnRetTy::Default(_)) => {
                                 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
@@ -1094,7 +1094,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             .and_then(|partial_res| partial_res.full_res())
                         {
                             if !res.matches_ns(Namespace::TypeNS)
-                                && path.is_potential_trivial_const_arg()
+                                && path.is_potential_trivial_const_arg(false)
                             {
                                 debug!(
                                     "lower_generic_arg: Lowering type argument as const argument: {:?}",
@@ -1365,7 +1365,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
             }
             TyKind::Pat(ty, pat) => {
-                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
+                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
             }
             TyKind::MacCall(_) => {
                 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
@@ -2061,8 +2061,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> &'hir hir::ConstArg<'hir> {
         let tcx = self.tcx;
 
-        // FIXME(min_generic_const_args): we only allow one-segment const paths for now
-        let ct_kind = if path.is_potential_trivial_const_arg()
+        let ct_kind = if path
+            .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
             && (tcx.features().min_generic_const_args()
                 || matches!(res, Res::Def(DefKind::ConstParam, _)))
         {
@@ -2072,7 +2072,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 path,
                 ParamMode::Optional,
                 AllowReturnTypeNotation::No,
-                // FIXME(min_generic_const_args): update for `fn foo() -> Bar<FOO<impl Trait>>` support
+                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 None,
             );
@@ -2088,8 +2088,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             // We're lowering a const argument that was originally thought to be a type argument,
             // so the def collector didn't create the def ahead of time. That's why we have to do
             // it here.
-            let def_id =
-                self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span);
+            let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span);
             let hir_id = self.lower_node_id(node_id);
 
             let path_expr = Expr {
@@ -2136,19 +2135,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         };
         let maybe_res =
             self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
-        // FIXME(min_generic_const_args): we only allow one-segment const paths for now
-        if let ExprKind::Path(None, path) = &expr.kind
-            && path.is_potential_trivial_const_arg()
+        if let ExprKind::Path(qself, path) = &expr.kind
+            && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
             && (tcx.features().min_generic_const_args()
                 || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
         {
             let qpath = self.lower_qpath(
                 expr.id,
-                &None,
+                qself,
                 path,
                 ParamMode::Optional,
                 AllowReturnTypeNotation::No,
-                // FIXME(min_generic_const_args): update for `fn foo() -> Bar<FOO<impl Trait>>` support
+                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 None,
             );
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2dcfe7c745d..07cc64a1358 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -3,11 +3,11 @@ use std::sync::Arc;
 use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_hir as hir;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{self as hir, LangItem};
 use rustc_middle::span_bug;
 use rustc_span::source_map::{Spanned, respan};
-use rustc_span::{Ident, Span};
+use rustc_span::{DesugaringKind, Ident, Span};
 
 use super::errors::{
     ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
@@ -430,22 +430,124 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
     }
 
-    pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> {
-        self.arena.alloc(self.lower_ty_pat_mut(pattern))
+    pub(crate) fn lower_ty_pat(
+        &mut self,
+        pattern: &TyPat,
+        base_type: Span,
+    ) -> &'hir hir::TyPat<'hir> {
+        self.arena.alloc(self.lower_ty_pat_mut(pattern, base_type))
     }
 
-    fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> {
+    fn lower_ty_pat_mut(&mut self, pattern: &TyPat, base_type: Span) -> hir::TyPat<'hir> {
         // loop here to avoid recursion
         let pat_hir_id = self.lower_node_id(pattern.id);
         let node = match &pattern.kind {
-            TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
-                e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
-                e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
-                self.lower_range_end(end, e2.is_some()),
+            TyPatKind::Range(e1, e2, Spanned { node: end, span }) => hir::TyPatKind::Range(
+                e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)).unwrap_or_else(|| {
+                    self.lower_ty_pat_range_end(
+                        hir::LangItem::RangeMin,
+                        span.shrink_to_lo(),
+                        base_type,
+                    )
+                }),
+                e2.as_deref()
+                    .map(|e| match end {
+                        RangeEnd::Included(..) => self.lower_anon_const_to_const_arg(e),
+                        RangeEnd::Excluded => self.lower_excluded_range_end(e),
+                    })
+                    .unwrap_or_else(|| {
+                        self.lower_ty_pat_range_end(
+                            hir::LangItem::RangeMax,
+                            span.shrink_to_hi(),
+                            base_type,
+                        )
+                    }),
             ),
             TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
         };
 
         hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
     }
+
+    /// Lowers the range end of an exclusive range (`2..5`) to an inclusive range 2..=(5 - 1).
+    /// This way the type system doesn't have to handle the distinction between inclusive/exclusive ranges.
+    fn lower_excluded_range_end(&mut self, e: &AnonConst) -> &'hir hir::ConstArg<'hir> {
+        let span = self.lower_span(e.value.span);
+        let unstable_span = self.mark_span_with_reason(
+            DesugaringKind::PatTyRange,
+            span,
+            Some(Arc::clone(&self.allow_pattern_type)),
+        );
+        let anon_const = self.with_new_scopes(span, |this| {
+            let def_id = this.local_def_id(e.id);
+            let hir_id = this.lower_node_id(e.id);
+            let body = this.lower_body(|this| {
+                // Need to use a custom function as we can't just subtract `1` from a `char`.
+                let kind = hir::ExprKind::Path(this.make_lang_item_qpath(
+                    hir::LangItem::RangeSub,
+                    unstable_span,
+                    None,
+                ));
+                let fn_def = this.arena.alloc(hir::Expr { hir_id: this.next_id(), kind, span });
+                let args = this.arena.alloc([this.lower_expr_mut(&e.value)]);
+                (
+                    &[],
+                    hir::Expr {
+                        hir_id: this.next_id(),
+                        kind: hir::ExprKind::Call(fn_def, args),
+                        span,
+                    },
+                )
+            });
+            hir::AnonConst { def_id, hir_id, body, span }
+        });
+        self.arena.alloc(hir::ConstArg {
+            hir_id: self.next_id(),
+            kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)),
+        })
+    }
+
+    /// When a range has no end specified (`1..` or `1..=`) or no start specified (`..5` or `..=5`),
+    /// we instead use a constant of the MAX/MIN of the type.
+    /// This way the type system does not have to handle the lack of a start/end.
+    fn lower_ty_pat_range_end(
+        &mut self,
+        lang_item: LangItem,
+        span: Span,
+        base_type: Span,
+    ) -> &'hir hir::ConstArg<'hir> {
+        let parent_def_id = self.current_hir_id_owner.def_id;
+        let node_id = self.next_node_id();
+
+        // Add a definition for the in-band const def.
+        // We're generating a range end that didn't exist in the AST,
+        // so the def collector didn't create the def ahead of time. That's why we have to do
+        // it here.
+        let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span);
+        let hir_id = self.lower_node_id(node_id);
+
+        let unstable_span = self.mark_span_with_reason(
+            DesugaringKind::PatTyRange,
+            self.lower_span(span),
+            Some(Arc::clone(&self.allow_pattern_type)),
+        );
+        let span = self.lower_span(base_type);
+
+        let path_expr = hir::Expr {
+            hir_id: self.next_id(),
+            kind: hir::ExprKind::Path(self.make_lang_item_qpath(lang_item, unstable_span, None)),
+            span,
+        };
+
+        let ct = self.with_new_scopes(span, |this| {
+            self.arena.alloc(hir::AnonConst {
+                def_id,
+                hir_id,
+                body: this.lower_body(|_this| (&[], path_expr)),
+                span,
+            })
+        });
+        let hir_id = self.next_id();
+        self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id })
+    }
 }
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 6b6244b05aa..d00c797755f 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -268,7 +268,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
                 GenericArgs::Parenthesized(data) => match generic_args_mode {
                     GenericArgsMode::ReturnTypeNotation => {
-                        tracing::info!(?data, ?data.inputs);
                         let err = match (&data.inputs[..], &data.output) {
                             ([_, ..], FnRetTy::Default(_)) => {
                                 BadReturnTypeNotation::Inputs { span: data.inputs_span }