diff options
| author | lcnr <rust@lcnr.de> | 2025-02-11 13:09:15 +0100 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-02-13 20:19:11 +0000 |
| commit | 05bd5ced2d9af5f155ed8a72b5c1399838c1d653 (patch) | |
| tree | 01f75b31a713654691a0d1441f33f01da1a7f9c6 /compiler/rustc_next_trait_solver | |
| parent | de273e459e4b0cbbcf7be68294a7d1fb25632b29 (diff) | |
rework pointee handling for the new rigid alias approach
Diffstat (limited to 'compiler/rustc_next_trait_solver')
| -rw-r--r-- | compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs | 146 |
1 files changed, 79 insertions, 67 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index e3d16719e28..88002e1a88a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -538,80 +538,92 @@ where let cx = ecx.cx(); let metadata_def_id = cx.require_lang_item(TraitSolverLangItem::Metadata); assert_eq!(metadata_def_id, goal.predicate.def_id()); - ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { - let metadata_ty = match goal.predicate.self_ty().kind() { - ty::Bool - | ty::Char - | ty::Int(..) - | ty::Uint(..) - | ty::Float(..) - | ty::Array(..) - | ty::Pat(..) - | ty::RawPtr(..) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Never - | ty::Foreign(..) - | ty::Dynamic(_, _, ty::DynStar) => Ty::new_unit(cx), - - ty::Error(e) => Ty::new_error(cx, e), - - ty::Str | ty::Slice(_) => Ty::new_usize(cx), - - ty::Dynamic(_, _, ty::Dyn) => { - let dyn_metadata = cx.require_lang_item(TraitSolverLangItem::DynMetadata); - cx.type_of(dyn_metadata) - .instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())]) - } + let metadata_ty = match goal.predicate.self_ty().kind() { + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Array(..) + | ty::Pat(..) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Never + | ty::Foreign(..) + | ty::Dynamic(_, _, ty::DynStar) => Ty::new_unit(cx), - ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { - // This is the "fallback impl" for type parameters, unnormalizable projections - // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`. - // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't - // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`. - let sized_predicate = ty::TraitRef::new( - cx, - cx.require_lang_item(TraitSolverLangItem::Sized), - [I::GenericArg::from(goal.predicate.self_ty())], - ); - // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`? - ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate)); - Ty::new_unit(cx) - } + ty::Error(e) => Ty::new_error(cx, e), - ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(cx) { - None => Ty::new_unit(cx), - Some(tail_ty) => { - Ty::new_projection(cx, metadata_def_id, [tail_ty.instantiate(cx, args)]) - } - }, - ty::Adt(_, _) => Ty::new_unit(cx), + ty::Str | ty::Slice(_) => Ty::new_usize(cx), - ty::Tuple(elements) => match elements.last() { - None => Ty::new_unit(cx), - Some(tail_ty) => Ty::new_projection(cx, metadata_def_id, [tail_ty]), - }, + ty::Dynamic(_, _, ty::Dyn) => { + let dyn_metadata = cx.require_lang_item(TraitSolverLangItem::DynMetadata); + cx.type_of(dyn_metadata) + .instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())]) + } - ty::UnsafeBinder(_) => { - // FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders. - todo!() + ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { + // This is the "fallback impl" for type parameters, unnormalizable projections + // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`. + // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't + // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`. + let alias_bound_result = + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + let sized_predicate = ty::TraitRef::new( + cx, + cx.require_lang_item(TraitSolverLangItem::Sized), + [I::GenericArg::from(goal.predicate.self_ty())], + ); + ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate)); + ecx.instantiate_normalizes_to_term(goal, Ty::new_unit(cx).into()); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }); + // In case the dummy alias-bound candidate does not apply, we instead treat this projection + // as rigid. + return alias_bound_result.or_else(|NoSolution| { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|this| { + this.structurally_instantiate_normalizes_to_term( + goal, + goal.predicate.alias, + ); + this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + }); + } + + ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(cx) { + None => Ty::new_unit(cx), + Some(tail_ty) => { + Ty::new_projection(cx, metadata_def_id, [tail_ty.instantiate(cx, args)]) } + }, + ty::Adt(_, _) => Ty::new_unit(cx), - ty::Infer( - ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_), - ) - | ty::Bound(..) => panic!( - "unexpected self ty `{:?}` when normalizing `<T as Pointee>::Metadata`", - goal.predicate.self_ty() - ), - }; + ty::Tuple(elements) => match elements.last() { + None => Ty::new_unit(cx), + Some(tail_ty) => Ty::new_projection(cx, metadata_def_id, [tail_ty]), + }, + ty::UnsafeBinder(_) => { + // FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders. + todo!() + } + + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) + | ty::Bound(..) => panic!( + "unexpected self ty `{:?}` when normalizing `<T as Pointee>::Metadata`", + goal.predicate.self_ty() + ), + }; + + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { ecx.instantiate_normalizes_to_term(goal, metadata_ty.into()); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) |
