diff options
| author | Laurențiu Nicola <lnicola@users.noreply.github.com> | 2025-03-10 09:52:17 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-10 09:52:17 +0000 |
| commit | 52f39ffe8320955868ce03eb22d9020c568472da (patch) | |
| tree | 6e32a4f4ff812cdbfb923b455777d48dbb1c45aa /compiler/rustc_ast_lowering/src | |
| parent | af32b22982ef0244cf4cf6a7f7b63274429289f8 (diff) | |
| parent | 1d983bf7941bb89985d53e741cabcf113912a40d (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.rs | 44 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/item.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/pat.rs | 122 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/path.rs | 1 |
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 } |
