From 7c8c6d24973a19e92f3c9822d293452c9168aef4 Mon Sep 17 00:00:00 2001 From: Boxy Date: Sat, 11 Jan 2025 18:55:32 +0000 Subject: [PATCH] Semantic changes from new hir representation Always lower to `GenericArg::Infer` Update `PlaceholderCollector` Update closure lifetime binder infer var visitor Fallback visitor handle ambig infer args Ensure type infer args have their type recorded --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 25 +++--------------- .../src/collect/resolve_bound_vars.rs | 16 +++++++----- .../src/hir_ty_lowering/generics.rs | 26 +++++++++++-------- compiler/rustc_hir_typeck/src/fallback.rs | 17 +++++++----- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 8 +++--- .../rustc_hir_typeck/src/method/confirm.rs | 6 ++--- 7 files changed, 47 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b4a9bbd09fd..933079938ae 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1085,7 +1085,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(lt)), ast::GenericArg::Type(ty) => { match &ty.kind { - TyKind::Infer if self.tcx.features().generic_arg_infer() => { + TyKind::Infer => { return GenericArg::Infer(hir::InferArg { hir_id: self.lower_node_id(ty.id), span: self.lower_span(ty.span), diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e0babf497e0..c44d386bc9f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -139,29 +139,12 @@ pub(crate) struct HirPlaceholderCollector { } impl<'v> Visitor<'v> for HirPlaceholderCollector { - fn visit_ty(&mut self, t: &'v hir::Ty<'v>) { - if let hir::TyKind::Infer = t.kind { - self.spans.push(t.span); - } - intravisit::walk_ty(self, t) - } - fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) { - match generic_arg { - hir::GenericArg::Infer(inf) => { - self.spans.push(inf.span); - self.may_contain_const_infer = true; - intravisit::walk_inf(self, inf); - } - hir::GenericArg::Type(t) => self.visit_ty(t), - _ => {} - } - } - fn visit_const_arg(&mut self, const_arg: &'v hir::ConstArg<'v>) { - if let hir::ConstArgKind::Infer(span) = const_arg.kind { + fn visit_infer(&mut self, _inf_id: HirId, inf_span: Span, kind: InferKind<'v>) -> Self::Result { + self.spans.push(inf_span); + + if let InferKind::Const(_) | InferKind::Ambig(_) = kind { self.may_contain_const_infer = true; - self.spans.push(span); } - intravisit::walk_const_arg(self, const_arg) } } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 2fae1a23f32..1c8a7d2d0be 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -489,15 +489,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { struct FindInferInClosureWithBinder; impl<'v> Visitor<'v> for FindInferInClosureWithBinder { type Result = ControlFlow; - fn visit_ty(&mut self, t: &'v hir::Ty<'v>) -> Self::Result { - if matches!(t.kind, hir::TyKind::Infer) { - ControlFlow::Break(t.span) - } else { - intravisit::walk_ty(self, t) - } + + fn visit_infer( + &mut self, + _inf_id: HirId, + inf_span: Span, + _kind: InferKind<'v>, + ) -> Self::Result { + ControlFlow::Break(inf_span) } } - FindInferInClosureWithBinder.visit_ty(ty).break_value() + FindInferInClosureWithBinder.visit_unambig_ty(ty).break_value() } let infer_in_rt_sp = match fn_decl.output { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index af83d412631..fe3dcb35639 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -40,17 +40,6 @@ fn generic_arg_mismatch_err( param.kind.descr(), ); - if let GenericParamDefKind::Const { .. } = param.kind { - if matches!(arg, GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. })) { - err.help("const arguments cannot yet be inferred with `_`"); - tcx.disabled_nightly_features( - &mut err, - param.def_id.as_local().map(|local| tcx.local_def_id_to_hir_id(local)), - [(String::new(), sym::generic_arg_infer)], - ); - } - } - let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut Diag<'_>| { let suggestions = vec![ (arg.span().shrink_to_lo(), String::from("{ ")), @@ -269,6 +258,21 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( GenericParamDefKind::Const { .. }, _, ) => { + if let GenericParamDefKind::Const { .. } = param.kind + && let GenericArg::Infer(inf) = arg + && !tcx.features().generic_arg_infer() + { + rustc_session::parse::feature_err( + tcx.sess, + sym::generic_arg_infer, + inf.span, + "const arguments cannot yet be inferred with `_`", + ) + .emit(); + } + + // We lower to an infer even when the feature gate is not enabled + // as it is useful for diagnostics to be able to see a `ConstKind::Infer` args.push(ctx.provided_kind(&args, param, arg)); args_iter.next(); params.next(); diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index c128485d93e..1f3f03b9929 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::intravisit::Visitor; +use rustc_hir::intravisit::{InferKind, Visitor}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; @@ -641,16 +641,21 @@ impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> { impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { type Result = ControlFlow; - fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result { + fn visit_infer( + &mut self, + inf_id: HirId, + inf_span: Span, + _kind: InferKind<'tcx>, + ) -> Self::Result { // Try to replace `_` with `()`. - if let hir::TyKind::Infer = hir_ty.kind - && let Some(ty) = self.fcx.typeck_results.borrow().node_type_opt(hir_ty.hir_id) + if let Some(ty) = self.fcx.typeck_results.borrow().node_type_opt(inf_id) && let Some(vid) = self.fcx.root_vid(ty) && self.reachable_vids.contains(&vid) { - return ControlFlow::Break(errors::SuggestAnnotation::Unit(hir_ty.span)); + return ControlFlow::Break(errors::SuggestAnnotation::Unit(inf_span)); } - hir::intravisit::walk_ty(self, hir_ty) + + ControlFlow::Continue(()) } fn visit_qpath( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ca9b6e47527..d526e1ab306 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1272,17 +1272,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .lower_lifetime(lt, RegionInferReason::Param(param)) .into(), (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { - // We handle the ambig portions of `Ty` in match arms below + // We handle the ambig portions of `Ty` in match arm below self.fcx.lower_ty(ty.as_unambig_ty()).raw.into() } + (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { + self.fcx.lower_ty(&inf.to_ty()).raw.into() + } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self .fcx // Ambiguous parts of `ConstArg` are handled in the match arms below .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id)) .into(), - (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { - self.fcx.ty_infer(Some(param), inf.span).into() - } (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { self.fcx.ct_infer(Some(param), inf.span).into() } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index ced5a55712c..880ee83c80a 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -428,14 +428,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // We handle the ambig portions of `Ty` in the match arms below self.cfcx.lower_ty(ty.as_unambig_ty()).raw.into() } + (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { + self.cfcx.lower_ty(&inf.to_ty()).raw.into() + } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self .cfcx // We handle the ambig portions of `ConstArg` in the match arms below .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id)) .into(), - (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { - self.cfcx.ty_infer(Some(param), inf.span).into() - } (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { self.cfcx.ct_infer(Some(param), inf.span).into() }