3030 ) -> QueryResult < I > {
3131 self . set_is_normalizes_to_goal ( ) ;
3232 debug_assert ! ( self . term_is_fully_unconstrained( goal) ) ;
33- let normalize_result = self
34- . probe ( |& result| ProbeKind :: TryNormalizeNonRigid { result } )
35- . enter ( |this| this. normalize_at_least_one_step ( goal) ) ;
36-
37- match normalize_result {
38- Ok ( res) => Ok ( res) ,
39- Err ( NoSolution ) => {
40- self . probe ( |& result| ProbeKind :: RigidAlias { result } ) . enter ( |this| {
41- let Goal { param_env, predicate : NormalizesTo { alias, term } } = goal;
42- this. add_rigid_constraints ( param_env, alias) ?;
43- this. relate_rigid_alias_non_alias ( param_env, alias, ty:: Invariant , term) ?;
44- this. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
45- } )
46- }
47- }
48- }
49-
50- /// Register any obligations that are used to validate that an alias should be
51- /// treated as rigid.
52- ///
53- /// An alias may be considered rigid if it fails normalization, but we also don't
54- /// want to consider aliases that are not well-formed to be rigid simply because
55- /// they fail normalization.
56- ///
57- /// For example, some `<T as Trait>::Assoc` where `T: Trait` does not hold, or an
58- /// opaque type whose hidden type doesn't actually satisfy the opaque item bounds.
59- fn add_rigid_constraints (
60- & mut self ,
61- param_env : I :: ParamEnv ,
62- rigid_alias : ty:: AliasTerm < I > ,
63- ) -> Result < ( ) , NoSolution > {
64- let cx = self . cx ( ) ;
65- match rigid_alias. kind ( cx) {
66- // Projections are rigid only if their trait ref holds,
67- // and the GAT where-clauses hold.
68- ty:: AliasTermKind :: ProjectionTy | ty:: AliasTermKind :: ProjectionConst => {
69- let trait_ref = rigid_alias. trait_ref ( cx) ;
70- self . add_goal ( GoalSource :: AliasWellFormed , Goal :: new ( cx, param_env, trait_ref) ) ;
71- Ok ( ( ) )
72- }
73- ty:: AliasTermKind :: OpaqueTy => {
74- if self . opaque_type_is_rigid ( rigid_alias. def_id ) {
75- Ok ( ( ) )
76- } else {
77- Err ( NoSolution )
78- }
79- }
80- // FIXME(generic_const_exprs): we would need to support generic consts here
81- ty:: AliasTermKind :: UnevaluatedConst => Err ( NoSolution ) ,
82- // Inherent and weak types are never rigid. This type must not be well-formed.
83- ty:: AliasTermKind :: WeakTy | ty:: AliasTermKind :: InherentTy => Err ( NoSolution ) ,
84- }
85- }
86-
87- /// Normalize the given alias by at least one step. If the alias is rigid, this
88- /// returns `NoSolution`.
89- #[ instrument( level = "trace" , skip( self ) , ret) ]
90- fn normalize_at_least_one_step ( & mut self , goal : Goal < I , NormalizesTo < I > > ) -> QueryResult < I > {
9133 let cx = self . cx ( ) ;
9234 match goal. predicate . alias . kind ( cx) {
9335 ty:: AliasTermKind :: ProjectionTy | ty:: AliasTermKind :: ProjectionConst => {
9840 goal. with ( cx, goal. predicate . alias . trait_ref ( cx) ) ;
9941 ecx. compute_trait_goal ( trait_goal)
10042 } ) ?;
101- self . merge_candidates ( proven_via, candidates)
43+ self . merge_candidates ( proven_via, candidates, |ecx| {
44+ ecx. probe ( |& result| ProbeKind :: RigidAlias { result } ) . enter ( |this| {
45+ this. structurally_instantiate_normalizes_to_term (
46+ goal,
47+ goal. predicate . alias ,
48+ ) ;
49+ this. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
50+ } )
51+ } )
10252 }
10353 ty:: AliasTermKind :: InherentTy => self . normalize_inherent_associated_type ( goal) ,
10454 ty:: AliasTermKind :: OpaqueTy => self . normalize_opaque_type ( goal) ,
@@ -120,6 +70,17 @@ where
12070 self . eq ( goal. param_env , goal. predicate . term , term)
12171 . expect ( "expected goal term to be fully unconstrained" ) ;
12272 }
73+
74+ /// Unlike `instantiate_normalizes_to_term` this instantiates the expected term
75+ /// with a rigid alias. Using this is pretty much always wrong.
76+ pub fn structurally_instantiate_normalizes_to_term (
77+ & mut self ,
78+ goal : Goal < I , NormalizesTo < I > > ,
79+ term : ty:: AliasTerm < I > ,
80+ ) {
81+ self . relate_rigid_alias_non_alias ( goal. param_env , term, ty:: Invariant , goal. predicate . term )
82+ . expect ( "expected goal term to be fully unconstrained" ) ;
83+ }
12384}
12485
12586impl < D , I > assembly:: GoalKind < D > for NormalizesTo < I >
@@ -850,12 +811,14 @@ where
850811 todo ! ( "discr subgoal..." )
851812 }
852813
853- // We do not call `Ty::discriminant_ty` on alias, param, or placeholder
854- // types, which return `<self_ty as DiscriminantKind>::Discriminant`
855- // (or ICE in the case of placeholders). Projecting a type to itself
856- // is never really productive.
814+ // Given an alias, parameter, or placeholder we add an impl candidate normalizing to a rigid
815+ // alias. In case there's a where-bound further constraining this alias it is preferred over
816+ // this impl candidate anyways. It's still a bit scuffed.
857817 ty:: Alias ( _, _) | ty:: Param ( _) | ty:: Placeholder ( ..) => {
858- return Err ( NoSolution ) ;
818+ return ecx. probe_builtin_trait_candidate ( BuiltinImplSource :: Misc ) . enter ( |ecx| {
819+ ecx. structurally_instantiate_normalizes_to_term ( goal, goal. predicate . alias ) ;
820+ ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
821+ } ) ;
859822 }
860823
861824 ty:: Infer ( ty:: TyVar ( _) | ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) )
@@ -902,12 +865,14 @@ where
902865 todo ! ( )
903866 }
904867
905- // We do not call `Ty::async_destructor_ty` on alias, param, or placeholder
906- // types, which return `<self_ty as AsyncDestruct>::AsyncDestructor`
907- // (or ICE in the case of placeholders). Projecting a type to itself
908- // is never really productive.
868+ // Given an alias, parameter, or placeholder we add an impl candidate normalizing to a rigid
869+ // alias. In case there's a where-bound further constraining this alias it is preferred over
870+ // this impl candidate anyways. It's still a bit scuffed.
909871 ty:: Alias ( _, _) | ty:: Param ( _) | ty:: Placeholder ( ..) => {
910- return Err ( NoSolution ) ;
872+ return ecx. probe_builtin_trait_candidate ( BuiltinImplSource :: Misc ) . enter ( |ecx| {
873+ ecx. structurally_instantiate_normalizes_to_term ( goal, goal. predicate . alias ) ;
874+ ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
875+ } ) ;
911876 }
912877
913878 ty:: Infer ( ty:: TyVar ( _) | ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) )
0 commit comments