@@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate};
15
15
use crate :: solve:: inspect:: ProbeKind ;
16
16
use crate :: solve:: {
17
17
BuiltinImplSource , CandidateSource , Certainty , EvalCtxt , Goal , GoalSource , MaybeCause ,
18
- NoSolution , QueryResult ,
18
+ NoSolution , QueryResult , Reveal ,
19
19
} ;
20
20
21
21
impl < D , I > EvalCtxt < ' _ , D >
@@ -37,10 +37,61 @@ where
37
37
match normalize_result {
38
38
Ok ( res) => Ok ( res) ,
39
39
Err ( NoSolution ) => {
40
- let Goal { param_env, predicate : NormalizesTo { alias, term } } = goal;
41
- self . relate_rigid_alias_non_alias ( param_env, alias, ty:: Invariant , term) ?;
42
- self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
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
+ match param_env. reveal ( ) {
75
+ // In user-facing mode, paques are only rigid if we may not define it.
76
+ Reveal :: UserFacing => {
77
+ if rigid_alias
78
+ . def_id
79
+ . as_local ( )
80
+ . is_some_and ( |def_id| self . can_define_opaque_ty ( def_id) )
81
+ {
82
+ Err ( NoSolution )
83
+ } else {
84
+ Ok ( ( ) )
85
+ }
86
+ }
87
+ // Opaques are never rigid in reveal-all mode.
88
+ Reveal :: All => Err ( NoSolution ) ,
89
+ }
43
90
}
91
+ // FIXME(generic_const_exprs): we would need to support generic consts here
92
+ ty:: AliasTermKind :: UnevaluatedConst => Err ( NoSolution ) ,
93
+ // Inherent and weak types are never rigid. This type must not be well-formed.
94
+ ty:: AliasTermKind :: WeakTy | ty:: AliasTermKind :: InherentTy => Err ( NoSolution ) ,
44
95
}
45
96
}
46
97
@@ -124,6 +175,7 @@ where
124
175
ecx. instantiate_normalizes_to_term ( goal, assumption_projection_pred. term ) ;
125
176
126
177
// Add GAT where clauses from the trait's definition
178
+ // FIXME: We don't need these, since these are the type's own WF obligations.
127
179
ecx. add_goals (
128
180
GoalSource :: Misc ,
129
181
cx. own_predicates_of ( goal. predicate . def_id ( ) )
@@ -179,7 +231,8 @@ where
179
231
. map ( |pred| goal. with ( cx, pred) ) ;
180
232
ecx. add_goals ( GoalSource :: ImplWhereBound , where_clause_bounds) ;
181
233
182
- // Add GAT where clauses from the trait's definition
234
+ // Add GAT where clauses from the trait's definition.
235
+ // FIXME: We don't need these, since these are the type's own WF obligations.
183
236
ecx. add_goals (
184
237
GoalSource :: Misc ,
185
238
cx. own_predicates_of ( goal. predicate . def_id ( ) )
0 commit comments