From 8b9d41c435e95d5fd6573ff38ae208f0ac4611b4 Mon Sep 17 00:00:00 2001 From: "addie.sh" Date: Tue, 21 Jul 2026 11:49:20 -0400 Subject: [PATCH] Next steps for FnDef binder changes (instantiate most FnDef binders) --- .../rustc_hir_analysis/src/collect/type_of.rs | 47 +++++++++---------- .../src/hir_ty_lowering/mod.rs | 14 ++---- compiler/rustc_middle/src/mir/statement.rs | 8 ++-- compiler/rustc_middle/src/ty/sty.rs | 19 +++++++- .../rustc_mir_build/src/builder/expr/into.rs | 9 +--- .../src/builder/matches/test.rs | 13 ++--- compiler/rustc_mir_build/src/thir/cx/expr.rs | 42 +++++++---------- .../rustc_mir_transform/src/elaborate_drop.rs | 47 +++++++------------ compiler/rustc_mir_transform/src/shim.rs | 6 +-- .../src/shim/async_destructor_ctor.rs | 16 +------ .../src/canonical/mod.rs | 1 + compiler/rustc_type_ir/src/relate.rs | 19 ++++---- .../src/relate/solver_relating.rs | 1 + .../casts/confusing_method_to_numeric_cast.rs | 3 +- tests/crashes/133613.rs | 8 ---- .../incremental/hashes/function_interfaces.rs | 4 +- tests/incremental/hashes/inherent_impls.rs | 12 ++--- tests/incremental/hashes/trait_defs.rs | 8 ++-- tests/incremental/hashes/trait_impls.rs | 8 ++-- .../binder-arg-overflow-regression-133613.rs | 18 +++++++ ...nder-arg-overflow-regression-133613.stderr | 36 ++++++++++++++ .../ui/thir-print/thir-tree-match-for.stdout | 12 ++--- 22 files changed, 185 insertions(+), 166 deletions(-) delete mode 100644 tests/crashes/133613.rs create mode 100644 tests/ui/generics/binder-arg-overflow-regression-133613.rs create mode 100644 tests/ui/generics/binder-arg-overflow-regression-133613.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 68b7d50c2ee9b..6709fab48d9ab 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -63,13 +63,26 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let icx = ItemCtxt::new(tcx, def_id); + let new_bound_fn_def = |hir: HirId, did| { + let args = ty::GenericArgs::identity_for_item(tcx, def_id); + Ty::new_fn_def_raw( + tcx, + did, + match &tcx + .late_bound_vars_map(hir.owner) + .get(&hir.local_id) + .cloned() + .map(|x| tcx.mk_bound_variable_kinds(&x)) + { + Some(late_bound) => ty::Binder::bind_with_vars(args, late_bound), + None => ty::Binder::dummy(args), + }, + ) + }; + let output = match tcx.hir_node(hir_id) { Node::TraitItem(item) => match item.kind { - TraitItemKind::Fn(..) => { - let args = ty::GenericArgs::identity_for_item(tcx, def_id); - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - Ty::new_fn_def(tcx, def_id.to_def_id(), ty::Binder::dummy(args)) - } + TraitItemKind::Fn(_, _) => new_bound_fn_def(item.hir_id(), def_id.to_def_id()), TraitItemKind::Const(ty, rhs) => rhs .and_then(|rhs| { ty.is_suggestable_infer_ty().then(|| { @@ -92,11 +105,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ }, Node::ImplItem(item) => match item.kind { - ImplItemKind::Fn(..) => { - let args = ty::GenericArgs::identity_for_item(tcx, def_id); - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - Ty::new_fn_def(tcx, def_id.to_def_id(), ty::Binder::dummy(args)) - } + ImplItemKind::Fn(_, _) => new_bound_fn_def(item.hir_id(), def_id.to_def_id()), ImplItemKind::Const(ty, rhs) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( @@ -171,11 +180,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } _ => icx.lower_ty(self_ty), }, - ItemKind::Fn { .. } => { - let args = ty::GenericArgs::identity_for_item(tcx, def_id); - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - Ty::new_fn_def(tcx, def_id.to_def_id(), ty::Binder::dummy(args)) - } + ItemKind::Fn { .. } => new_bound_fn_def(item.hir_id(), def_id.to_def_id()), ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => { let def = tcx.adt_def(def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id); @@ -196,10 +201,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).instantiate_identity().skip_norm_wip(), Node::ForeignItem(foreign_item) => match foreign_item.kind { - ForeignItemKind::Fn(..) => { - let args = ty::GenericArgs::identity_for_item(tcx, def_id); - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - Ty::new_fn_def(tcx, def_id.to_def_id(), ty::Binder::dummy(args)) + ForeignItemKind::Fn(_, _, _generics) => { + new_bound_fn_def(foreign_item.hir_id(), def_id.to_def_id()) } ForeignItemKind::Static(ty, _, _) => { let ty = icx.lower_ty(ty); @@ -219,11 +222,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ VariantData::Unit(..) | VariantData::Struct { .. } => { tcx.type_of(tcx.hir_get_parent_item(hir_id)).instantiate_identity().skip_norm_wip() } - VariantData::Tuple(_, _, ctor) => { - let args = ty::GenericArgs::identity_for_item(tcx, def_id); - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - Ty::new_fn_def(tcx, ctor.to_def_id(), ty::Binder::dummy(args)) - } + VariantData::Tuple(_, hir_id, ctor) => new_bound_fn_def(*hir_id, ctor.to_def_id()), }, Node::Field(field) => icx.lower_ty(field.ty), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 497ff02c9b407..fa3dca042ba0c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1483,13 +1483,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Ok(ct) } TypeRelativePath::Ctor { ctor_def_id, args } => match tcx.def_kind(ctor_def_id) { - DefKind::Ctor(_, CtorKind::Fn) => { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - Ok(ty::Const::zero_sized( - tcx, - Ty::new_fn_def(tcx, ctor_def_id, ty::Binder::dummy(args)), - )) - } + DefKind::Ctor(_, CtorKind::Fn) => Ok(ty::Const::zero_sized( + tcx, + tcx.type_of(ctor_def_id).instantiate(tcx, args).skip_norm_wip(), + )), DefKind::Ctor(ctor_of, CtorKind::Const) => { Ok(self.construct_const_ctor_value(ctor_def_id, ctor_of, args)) } @@ -2913,8 +2910,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &path.segments[generic_segments[0].1], ); - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, ty::Binder::dummy(args))) + ty::Const::zero_sized(tcx, tcx.type_of(did).instantiate(tcx, args).skip_norm_wip()) } Res::Def(DefKind::AssocConst { .. }, did) => { let trait_segment = if let [modules @ .., trait_, _item] = path.segments { diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 5215dffed0717..9712ac02775d4 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -620,11 +620,13 @@ impl<'tcx> Operand<'tcx> { pub fn function_handle( tcx: TyCtxt<'tcx>, def_id: DefId, - args: ty::Binder<'tcx, impl IntoIterator>>, + args: &[GenericArg<'tcx>], span: Span, ) -> Self { - let ty = Ty::new_fn_def(tcx, def_id, args); - Operand::zero_sized_constant(ty, span) + Operand::zero_sized_constant( + tcx.type_of(def_id).instantiate(tcx, args).skip_norm_wip(), + span, + ) } /// Convenience helper to make a constant that refers to the given `DefId` and args. Since this diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ff787c0ede7f7..f8fb476ca3ef1 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -725,6 +725,23 @@ impl<'tcx> Ty<'tcx> { T::collect_and_apply(iter, |ts| Ty::new_tup(tcx, ts)) } + /// Prefer using the [TyCtxt::type_of] query over this, that makes it easier to get all the pieces correct + #[inline] + pub fn new_fn_def_raw( + tcx: TyCtxt<'tcx>, + def_id: DefId, + args: ty::Binder<'tcx, impl IntoIterator>>>, + ) -> Ty<'tcx> { + debug_assert_matches!( + tcx.def_kind(def_id), + DefKind::AssocFn | DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) + ); + + let args = args.map_bound(|args| tcx.check_and_mk_args(def_id, args)); + + Ty::new(tcx, FnDef(def_id, args)) + } + #[inline] pub fn new_fn_def( tcx: TyCtxt<'tcx>, @@ -1113,7 +1130,7 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> { def_id: DefId, args: ty::Binder<'tcx, ty::GenericArgsRef<'tcx>>, ) -> Self { - Ty::new_fn_def(interner, def_id, args) + Ty::new_fn_def_raw(interner, def_id, args) } fn new_fn_ptr(interner: TyCtxt<'tcx>, sig: ty::Binder<'tcx, ty::FnSig<'tcx>>) -> Self { diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index f04247491ccfa..bdf45e0c85cb5 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -532,13 +532,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let success = this.cfg.start_new_block(); let clone_trait = this.tcx.require_lang_item(LangItem::Clone, span); let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0]; - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - let func = Operand::function_handle( - this.tcx, - clone_fn, - ty::Binder::dummy([ty.into()]), - expr_span, - ); + let func = + Operand::function_handle(this.tcx, clone_fn, &[ty.into()], expr_span); let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty); let ref_place = this.temp(ref_ty, span); this.cfg.push_assign( diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index a1087b9ff98a0..1c234bb8d70dc 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -348,8 +348,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = self.source_info(span); let re_erased = self.tcx.lifetimes.re_erased; let trait_item = self.tcx.require_lang_item(trait_item, span); - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - let method = trait_method(self.tcx, trait_item, method, ty::Binder::dummy([ty])); + let method = trait_method(self.tcx, trait_item, method, &[ty.into()]); let ref_src = self.temp(Ty::new_ref(self.tcx, re_erased, ty, mutability), span); // `let ref_src = &src_place;` // or `let ref_src = &mut src_place;` @@ -422,9 +421,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { let str_ty = self.tcx.types.str_; let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, source_info.span); - let method = - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - trait_method(self.tcx, eq_def_id, sym::eq, ty::Binder::dummy([str_ty, str_ty])); + let method = trait_method(self.tcx, eq_def_id, sym::eq, &[str_ty.into(), str_ty.into()]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); @@ -471,7 +468,7 @@ fn trait_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, method_name: Symbol, - args: ty::Binder<'tcx, impl IntoIterator>>>, + args: &[GenericArg<'tcx>], ) -> Const<'tcx> { // The unhygienic comparison here is acceptable because this is only // used on known traits. @@ -481,7 +478,5 @@ fn trait_method<'tcx>( .find(|item| item.is_fn()) .expect("trait method not found"); - let method_ty = Ty::new_fn_def(tcx, item.def_id, args); - - Const::zero_sized(method_ty) + Const::zero_sized(tcx.type_of(item.def_id).instantiate(tcx, args).skip_norm_wip()) } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 10dc59a8950fd..2f39be4214e46 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -199,12 +199,11 @@ impl<'tcx> ThirBuildCx<'tcx> { // We don't need to do call adjust_span here since // deref coercions always start with a built-in deref. let call_def_id = deref.method_call(self.tcx); - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - let overloaded_callee = Ty::new_fn_def( - self.tcx, - call_def_id, - ty::Binder::dummy(self.tcx.mk_args(&[expr.ty.into()])), - ); + let overloaded_callee = self + .tcx + .type_of(call_def_id) + .instantiate(self.tcx, self.tcx.mk_args(&[expr.ty.into()])) + .skip_norm_wip(); expr = Expr { temp_scope_id, @@ -855,12 +854,10 @@ impl<'tcx> ThirBuildCx<'tcx> { }; let mk_call = |thir: &mut Thir<'tcx>, ty: Ty<'tcx>, variant: VariantIdx, field: FieldIdx| { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - let fun_ty = Ty::new_fn_def( - tcx, - offset_of_intrinsic, - ty::Binder::dummy([ty::GenericArg::from(ty)]), - ); + let fun_ty = tcx + .type_of(offset_of_intrinsic) + .instantiate(tcx, &[ty.into()]) + .skip_norm_wip(); let fun = thir .exprs .push(mk_expr(ExprKind::ZstLiteral { user_ty: None }, fun_ty)); @@ -1211,12 +1208,10 @@ impl<'tcx> ThirBuildCx<'tcx> { let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id)); debug!("method_callee: user_ty={:?}", user_ty); ( - // FIXME: instantiate binder correctly (turbofish/fndex) - Ty::new_fn_def( - self.tcx, - def_id, - ty::Binder::dummy(self.typeck_results.node_args(expr.hir_id)), - ), + self.tcx + .type_of(def_id) + .instantiate(self.tcx, self.typeck_results.node_args(expr.hir_id)) + .skip_norm_wip(), user_ty, ) } @@ -1250,12 +1245,11 @@ impl<'tcx> ThirBuildCx<'tcx> { Expr { temp_scope_id: expr.hir_id.local_id, - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - ty: Ty::new_fn_def( - self.tcx, - def_id, - ty::Binder::dummy(self.typeck_results.node_args(expr.hir_id)), - ), + ty: self + .tcx + .type_of(def_id) + .instantiate(self.tcx, self.typeck_results.node_args(expr.hir_id)) + .skip_norm_wip(), span, kind: ExprKind::ZstLiteral { user_ty }, } diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index c2c702dbf2470..bc46c0f460aea 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -247,11 +247,19 @@ where // Resolving async_drop_in_place function for drop_ty tcx.require_lang_item(LangItem::AsyncDropInPlace, span) }; + let async_drop_fn_sig = tcx.fn_sig(async_drop_fn_def_id); let fut_ty = tcx .instantiate_bound_regions_with_erased( - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - Ty::new_fn_def(tcx, async_drop_fn_def_id, ty::Binder::dummy([drop_ty])).fn_sig(tcx), + Ty::new_fn_def_raw( + tcx, + async_drop_fn_def_id, + async_drop_fn_sig + .instantiate(tcx, &[drop_ty.into()]) + .skip_norm_wip() + .rebind([drop_ty]), + ) + .fn_sig(tcx), ) .output(); let fut = self.new_temp(fut_ty); @@ -373,13 +381,7 @@ where unwind_with_dead, vec![self.storage_live(fut)], TerminatorKind::Call { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - func: Operand::function_handle( - tcx, - async_drop_fn_def_id, - ty::Binder::dummy([drop_ty.into()]), - span, - ), + func: Operand::function_handle(tcx, async_drop_fn_def_id, &[drop_ty.into()], span), args: [dummy_spanned(drop_arg)].into(), destination: fut.into(), target: Some(succ_yield_loop), @@ -407,8 +409,7 @@ where func: Operand::function_handle( tcx, pin_obj_new_unchecked_fn, - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - ty::Binder::dummy([obj_ref_ty.into()]), + &[obj_ref_ty.into()], span, ), args: [dummy_spanned(Operand::Move(obj_ref_place))].into(), @@ -573,13 +574,7 @@ where unwind, Vec::new(), TerminatorKind::Call { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - func: Operand::function_handle( - tcx, - poll_fn, - ty::Binder::dummy([fut_ty.into()]), - source_info.span, - ), + func: Operand::function_handle(tcx, poll_fn, &[fut_ty.into()], source_info.span), args: [ dummy_spanned(Operand::Move(fut_pin_local.into())), dummy_spanned(Operand::Move(context_ref_local.into())), @@ -608,11 +603,7 @@ where func: Operand::function_handle( tcx, get_context_fn, - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - ty::Binder::dummy([ - tcx.lifetimes.re_erased.into(), - tcx.lifetimes.re_erased.into(), - ]), + &[tcx.lifetimes.re_erased.into(), tcx.lifetimes.re_erased.into()], source_info.span, ), args: [dummy_spanned(Operand::Move(entry_resume_local.into()))].into(), @@ -642,7 +633,7 @@ where func: Operand::function_handle( tcx, fut_pin_new_unchecked_fn, - ty::Binder::dummy([fut_ref_ty.into()]), + &[fut_ref_ty.into()], source_info.span, ), args: [dummy_spanned(Operand::Move(fut_ref_local.into()))].into(), @@ -1265,13 +1256,7 @@ where ), )], TerminatorKind::Call { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - func: Operand::function_handle( - tcx, - drop_fn, - ty::Binder::dummy([ty.into()]), - self.source_info.span, - ), + func: Operand::function_handle(tcx, drop_fn, &[ty.into()], self.source_info.span), args: [dummy_spanned(Operand::Move(Place::from(ref_place)))].into(), destination: unit_temp, target: Some(succ), diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 519e32baae75f..2ecc9822a84b6 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -327,11 +327,10 @@ pub fn build_drop_shim<'tcx>( start.terminator = Some(Terminator { source_info, kind: TerminatorKind::Call { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) func: Operand::function_handle( tcx, def_id, - ty::Binder::dummy([ty::GenericArg::from(slice_ty)]), + &[ty::GenericArg::from(slice_ty)], span, ), args: Box::new([Spanned { span, node: Operand::Move(Place::from(erased_local)) }]), @@ -624,8 +623,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { let tcx = self.tcx; // `func == Clone::clone(&ty) -> ty` - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - let func_ty = Ty::new_fn_def(tcx, self.def_id, ty::Binder::dummy([ty])); + let func_ty = tcx.type_of(self.def_id).instantiate(tcx, &[ty.into()]).skip_norm_wip(); let func = Operand::Constant(Box::new(ConstOperand { span: self.span, user_ty: None, diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index ccb361cdb0804..194f242fe6cc7 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -371,13 +371,7 @@ fn build_adrop_for_adrop_shim<'tcx>( Some(Terminator { source_info, kind: TerminatorKind::Call { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - func: Operand::function_handle( - tcx, - pin_fn, - ty::Binder::dummy([cor_ref.into()]), - span, - ), + func: Operand::function_handle(tcx, pin_fn, &[cor_ref.into()], span), args: [dummy_spanned(Operand::Move(cor_ref_place))].into(), destination: cor_pin_place, target: Some(call_bb), @@ -398,13 +392,7 @@ fn build_adrop_for_adrop_shim<'tcx>( Some(Terminator { source_info, kind: TerminatorKind::Call { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - func: Operand::function_handle( - tcx, - poll_fn, - ty::Binder::dummy([impl_ty.into()]), - span, - ), + func: Operand::function_handle(tcx, poll_fn, &[impl_ty.into()], span), args: [ dummy_spanned(Operand::Move(cor_pin_place)), dummy_spanned(Operand::Move(resume_ctx)), diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index 1e4e3a90f9c4a..560bb15a4db30 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -294,6 +294,7 @@ where relate_args_invariantly(self, a_args, b_args)?; Ok(a_ty) } + fn relate_with_variance>( &mut self, _variance: ty::Variance, diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index fa2e6154ce4f2..d263a0cca9a1e 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -66,8 +66,8 @@ pub trait TypeRelation: Sized { a_ty: I::Ty, b_ty: I::Ty, ty_def_id: I::DefId, - a_arg: I::GenericArgs, - b_arg: I::GenericArgs, + a_args: I::GenericArgs, + b_args: I::GenericArgs, mk: impl FnOnce(I::GenericArgs) -> I::Ty, ) -> RelateResult; @@ -503,12 +503,15 @@ pub fn structurally_relate_tys>( if a_args.skip_binder().is_empty() { Ok(a) } else { - let a_args = a_args.no_bound_vars().unwrap(); - let b_args = b_args.no_bound_vars().unwrap(); - relation.relate_ty_args(a, b, a_def_id.into(), a_args, b_args, |args| { - // FIXME(156581): actually instantiate the binder correctly (turbofishing/fndef changes) - Ty::new_fn_def(cx, a_def_id, ty::Binder::dummy(args)) - }) + let x = relation.relate_ty_args( + a, + b, + a_def_id.into(), + a_args.skip_binder(), + b_args.skip_binder(), + |args| Ty::new_fn_def(cx, a_def_id, a_args.rebind(args)), + ); + x } } diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index 930eaa965dfcf..d22f1bf038a7f 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -124,6 +124,7 @@ where combine_ty_args(self.infcx, self, a_ty, b_ty, variances, a_args, b_args, |_| a_ty) } } + fn relate_with_variance>( &mut self, variance: ty::Variance, diff --git a/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs b/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs index 740326d2f9420..93a08d3a12d49 100644 --- a/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs +++ b/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs @@ -65,8 +65,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, if let ty::FnDef(def_id, generics) = cast_from.kind() && let Some(method_name) = cx.tcx.opt_item_name(*def_id) - && let Some((const_name, ty_name)) = - get_const_name_and_ty_name(cx, method_name, *def_id, generics.no_bound_vars().unwrap().as_slice()) + && let Some((const_name, ty_name)) = get_const_name_and_ty_name(cx, method_name, *def_id, generics.no_bound_vars().unwrap().as_slice()) { let mut applicability = Applicability::MaybeIncorrect; let from_snippet = snippet_with_applicability(cx, cast_expr.span, "..", &mut applicability); diff --git a/tests/crashes/133613.rs b/tests/crashes/133613.rs deleted file mode 100644 index 066c50b494772..0000000000000 --- a/tests/crashes/133613.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ needs-rustc-debug-assertions -//@ known-bug: #133613 - -struct Wrapper<'a>(); - -trait IntFactory { - fn stream(&self) -> impl IntFactory>; -} diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs index 8e9830e0d83d4..cb98d56534e1f 100644 --- a/tests/incremental/hashes/function_interfaces.rs +++ b/tests/incremental/hashes/function_interfaces.rs @@ -156,9 +156,9 @@ pub fn type_parameter() {} pub fn lifetime_parameter () {} #[cfg(not(any(bpass1,bpass4)))] -#[rustc_clean(cfg = "bpass2", except = "hir_owner, generics_of,fn_sig")] +#[rustc_clean(cfg = "bpass2", except = "hir_owner, generics_of, fn_sig, type_of")] #[rustc_clean(cfg = "bpass3")] -#[rustc_clean(cfg = "bpass5", except = "hir_owner, generics_of,fn_sig")] +#[rustc_clean(cfg = "bpass5", except = "hir_owner, generics_of, fn_sig, type_of")] #[rustc_clean(cfg = "bpass6")] pub fn lifetime_parameter<'a>() {} diff --git a/tests/incremental/hashes/inherent_impls.rs b/tests/incremental/hashes/inherent_impls.rs index edda93ec55127..fa57fa4415fcf 100644 --- a/tests/incremental/hashes/inherent_impls.rs +++ b/tests/incremental/hashes/inherent_impls.rs @@ -146,12 +146,12 @@ impl Foo { impl Foo { #[rustc_clean( cfg="bpass2", - except="hir_owner,fn_sig,generics_of,typeck_root,associated_item,optimized_mir", + except="hir_owner,fn_sig,type_of,generics_of,typeck_root,associated_item,optimized_mir", )] #[rustc_clean(cfg="bpass3")] #[rustc_clean( cfg="bpass5", - except="hir_owner,fn_sig,generics_of,typeck_root,associated_item,optimized_mir", + except="hir_owner,fn_sig,type_of,generics_of,typeck_root,associated_item,optimized_mir", )] #[rustc_clean(cfg="bpass6")] pub fn method_selfness(&self) { } @@ -421,9 +421,9 @@ impl Foo { // ---------------------------------------------------------- // ----------------------------------------------------------- // ---------------------------------------------------------- - // -------------------------------------------------------------- + // ---------------------------------------------------------------------- // ------------------------- - // -------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------- // ------------------------- pub fn add_lifetime_parameter_to_method (&self) { } } @@ -443,9 +443,9 @@ impl Foo { // if we lower generics before the body, then the `HirId` for // things in the body will be affected. So if you start to see // `typeck_root` appear dirty, that might be the cause. -nmatsakis - #[rustc_clean(cfg="bpass2", except="hir_owner,fn_sig")] + #[rustc_clean(cfg="bpass2", except="hir_owner,fn_sig,type_of")] #[rustc_clean(cfg="bpass3")] - #[rustc_clean(cfg="bpass5", except="hir_owner,fn_sig,generics_of")] + #[rustc_clean(cfg="bpass5", except="hir_owner,fn_sig,type_of,generics_of")] #[rustc_clean(cfg="bpass6")] pub fn add_lifetime_parameter_to_method<'a>(&self) { } } diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index bb66ad51d993e..e45f6654c3962 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs @@ -380,9 +380,9 @@ trait TraitChangeModeSelfOwnToRef { #[rustc_clean(except="hir_owner,predicates_of", cfg="bpass5")] #[rustc_clean(cfg="bpass6")] trait TraitChangeModeSelfOwnToRef { - #[rustc_clean(except="hir_owner,fn_sig,generics_of", cfg="bpass2")] + #[rustc_clean(except="hir_owner,fn_sig,type_of,generics_of", cfg="bpass2")] #[rustc_clean(cfg="bpass3")] - #[rustc_clean(except="hir_owner,fn_sig,generics_of", cfg="bpass5")] + #[rustc_clean(except="hir_owner,fn_sig,type_of,generics_of", cfg="bpass5")] #[rustc_clean(cfg="bpass6")] fn method(&self); } @@ -509,9 +509,9 @@ trait TraitAddLifetimeParameterToMethod { #[rustc_clean(except="hir_owner,predicates_of", cfg="bpass5")] #[rustc_clean(cfg="bpass6")] trait TraitAddLifetimeParameterToMethod { - #[rustc_clean(except="hir_owner,fn_sig,generics_of", cfg="bpass2")] + #[rustc_clean(except="hir_owner,fn_sig,type_of,generics_of", cfg="bpass2")] #[rustc_clean(cfg="bpass3")] - #[rustc_clean(except="hir_owner,fn_sig,generics_of", cfg="bpass5")] + #[rustc_clean(except="hir_owner,fn_sig,type_of,generics_of", cfg="bpass5")] #[rustc_clean(cfg="bpass6")] fn method<'a>(); } diff --git a/tests/incremental/hashes/trait_impls.rs b/tests/incremental/hashes/trait_impls.rs index 06b2934cb8a8f..9c773b2920e98 100644 --- a/tests/incremental/hashes/trait_impls.rs +++ b/tests/incremental/hashes/trait_impls.rs @@ -148,12 +148,12 @@ pub trait ChangeMethodSelfnessTrait { #[rustc_clean(cfg="bpass6")] impl ChangeMethodSelfnessTrait for Foo { #[rustc_clean( - except="hir_owner,associated_item,generics_of,fn_sig,typeck_root,optimized_mir", + except="hir_owner,associated_item,generics_of,fn_sig,type_of,typeck_root,optimized_mir", cfg="bpass2", )] #[rustc_clean(cfg="bpass3")] #[rustc_clean( - except="hir_owner,associated_item,generics_of,fn_sig,typeck_root,optimized_mir", + except="hir_owner,associated_item,generics_of,fn_sig,type_of,typeck_root,optimized_mir", cfg="bpass5", )] #[rustc_clean(cfg="bpass6")] @@ -186,12 +186,12 @@ pub trait RemoveMethodSelfnessTrait { #[rustc_clean(cfg="bpass6")] impl RemoveMethodSelfnessTrait for Foo { #[rustc_clean( - except="hir_owner,associated_item,generics_of,fn_sig,typeck_root,optimized_mir", + except="hir_owner,associated_item,generics_of,fn_sig,type_of,typeck_root,optimized_mir", cfg="bpass2", )] #[rustc_clean(cfg="bpass3")] #[rustc_clean( - except="hir_owner,associated_item,generics_of,fn_sig,typeck_root,optimized_mir", + except="hir_owner,associated_item,generics_of,fn_sig,type_of,typeck_root,optimized_mir", cfg="bpass5", )] #[rustc_clean(cfg="bpass6")] diff --git a/tests/ui/generics/binder-arg-overflow-regression-133613.rs b/tests/ui/generics/binder-arg-overflow-regression-133613.rs new file mode 100644 index 0000000000000..ad4e6c70eb8fe --- /dev/null +++ b/tests/ui/generics/binder-arg-overflow-regression-133613.rs @@ -0,0 +1,18 @@ +//! Regression test for #133613 +//! This was a crash regarding bound vars and generic arg indexing. +//! The bound var index was used to index self.args, and caused OOB. +//! Because of new changes to how the compiler handles binders, this was fixed. + +//@ needs-rustc-debug-assertions + +struct Wrapper<'a>(); + +// FIXME: these errors are probably wrong +trait IntFactory { + fn stream(&self) -> impl IntFactory>; + //~^ ERROR: cycle detected when looking up late bound vars inside `IntFactory::stream` [E0391] + //~^^ ERROR: return type notation is experimental + //~^^^ ERROR: return type notation is experimental +} + +fn main() {} diff --git a/tests/ui/generics/binder-arg-overflow-regression-133613.stderr b/tests/ui/generics/binder-arg-overflow-regression-133613.stderr new file mode 100644 index 0000000000000..e56467ea507e9 --- /dev/null +++ b/tests/ui/generics/binder-arg-overflow-regression-133613.stderr @@ -0,0 +1,36 @@ +error[E0658]: return type notation is experimental + --> $DIR/binder-arg-overflow-regression-133613.rs:12:47 + | +LL | fn stream(&self) -> impl IntFactory>; + | ^^^^ + | + = note: see issue #109417 for more information + = help: add `#![feature(return_type_notation)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: return type notation is experimental + --> $DIR/binder-arg-overflow-regression-133613.rs:12:70 + | +LL | fn stream(&self) -> impl IntFactory>; + | ^^^^ + | + = note: see issue #109417 for more information + = help: add `#![feature(return_type_notation)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0391]: cycle detected when looking up late bound vars inside `IntFactory::stream` + --> $DIR/binder-arg-overflow-regression-133613.rs:12:5 + | +LL | fn stream(&self) -> impl IntFactory>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: ...which requires resolving lifetimes for `IntFactory::stream`... + = note: ...which requires computing function signature of `IntFactory::stream`... + = note: ...which again requires looking up late bound vars inside `IntFactory::stream`, completing the cycle + = note: cycle used when computing type of `IntFactory::stream` + = note: for more information, see and + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0391, E0658. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/thir-print/thir-tree-match-for.stdout b/tests/ui/thir-print/thir-tree-match-for.stdout index 0cf759c40c4ff..9d8f1677fe62f 100644 --- a/tests/ui/thir-print/thir-tree-match-for.stdout +++ b/tests/ui/thir-print/thir-tree-match-for.stdout @@ -560,12 +560,12 @@ body: span: $DIR/thir-tree-match-for.rs:16:12: 16:16 (#7) kind: Call { - ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [] }) + ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [Region(BrNamed(DefId(N:M ~ core::iter::traits::iterator::Iterator::next::'_)))] }) from_hir_call: true fn_span: $DIR/thir-tree-match-for.rs:16:12: 16:16 (#7) fun: Expr { - ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [] }) + ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [Region(BrNamed(DefId(N:M ~ core::iter::traits::iterator::Iterator::next::'_)))] }) temp_scope_id: 34 span: $DIR/thir-tree-match-for.rs:16:12: 16:16 (#7) kind: @@ -574,7 +574,7 @@ body: hir_id: HirId(DefId(N:M ~ thir_tree_match_for::match_from_for).34) value: Expr { - ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [] }) + ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [Region(BrNamed(DefId(N:M ~ core::iter::traits::iterator::Iterator::next::'_)))] }) temp_scope_id: 34 span: $DIR/thir-tree-match-for.rs:16:12: 16:16 (#7) kind: @@ -1117,12 +1117,12 @@ body: span: $DIR/thir-tree-match-for.rs:25:13: 25:38 (#0) kind: Call { - ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [] }) + ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [Region(BrNamed(DefId(N:M ~ core::iter::traits::iterator::Iterator::next::'_)))] }) from_hir_call: true fn_span: $DIR/thir-tree-match-for.rs:25:13: 25:38 (#0) fun: Expr { - ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [] }) + ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [Region(BrNamed(DefId(N:M ~ core::iter::traits::iterator::Iterator::next::'_)))] }) temp_scope_id: 25 span: $DIR/thir-tree-match-for.rs:25:13: 25:27 (#0) kind: @@ -1131,7 +1131,7 @@ body: hir_id: HirId(DefId(N:M ~ thir_tree_match_for::match_loop_nonfor).25) value: Expr { - ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [] }) + ty: FnDef(DefId(N:M ~ core::iter::traits::iterator::Iterator::next), Binder { value: [std::ops::Range], bound_vars: [Region(BrNamed(DefId(N:M ~ core::iter::traits::iterator::Iterator::next::'_)))] }) temp_scope_id: 25 span: $DIR/thir-tree-match-for.rs:25:13: 25:27 (#0) kind: