@@ -4,7 +4,7 @@ use rustc::infer::InferCtxt;
4
4
use rustc:: hir:: def_id:: DefId ;
5
5
use rustc:: mir:: ProjectionKind ;
6
6
use rustc:: mir:: tcx:: PlaceTy ;
7
- use rustc:: traits:: query:: type_op:: ascribe_user_type:: AscribeUserType ;
7
+ use rustc:: traits:: query:: type_op:: ascribe_user_type:: { AscribeUserType , AscribeUserTypeWellFormed } ;
8
8
use rustc:: traits:: query:: type_op:: eq:: Eq ;
9
9
use rustc:: traits:: query:: type_op:: normalize:: Normalize ;
10
10
use rustc:: traits:: query:: type_op:: prove_predicate:: ProvePredicate ;
@@ -17,6 +17,7 @@ use rustc::ty::query::Providers;
17
17
use rustc:: ty:: subst:: { Kind , Subst , UserSubsts , UserSelfTy } ;
18
18
use rustc:: ty:: {
19
19
FnSig , Lift , ParamEnv , ParamEnvAnd , PolyFnSig , Predicate , Ty , TyCtxt , TypeFoldable , Variance ,
20
+ UserTypeAnnotation ,
20
21
} ;
21
22
use rustc_data_structures:: sync:: Lrc ;
22
23
use std:: fmt;
@@ -26,6 +27,7 @@ use syntax_pos::DUMMY_SP;
26
27
crate fn provide ( p : & mut Providers ) {
27
28
* p = Providers {
28
29
type_op_ascribe_user_type,
30
+ type_op_ascribe_user_type_well_formed,
29
31
type_op_eq,
30
32
type_op_prove_predicate,
31
33
type_op_subtype,
@@ -48,7 +50,7 @@ fn type_op_ascribe_user_type<'tcx>(
48
50
) = key. into_parts ( ) ;
49
51
50
52
debug ! (
51
- "type_op_user_type_relation : mir_ty={:?} variance={:?} def_id={:?} \
53
+ "type_op_ascribe_user_type : mir_ty={:?} variance={:?} def_id={:?} \
52
54
user_substs={:?} projs={:?}",
53
55
mir_ty, variance, def_id, user_substs, projs
54
56
) ;
@@ -60,6 +62,28 @@ fn type_op_ascribe_user_type<'tcx>(
60
62
} )
61
63
}
62
64
65
+ fn type_op_ascribe_user_type_well_formed < ' tcx > (
66
+ tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
67
+ canonicalized : Canonical < ' tcx , ParamEnvAnd < ' tcx , AscribeUserTypeWellFormed < ' tcx > > > ,
68
+ ) -> Result < Lrc < Canonical < ' tcx , QueryResponse < ' tcx , ( ) > > > , NoSolution > {
69
+ tcx. infer_ctxt ( )
70
+ . enter_canonical_trait_query ( & canonicalized, |infcx, fulfill_cx, key| {
71
+ let (
72
+ param_env, AscribeUserTypeWellFormed { user_type_annotation }
73
+ ) = key. into_parts ( ) ;
74
+
75
+ debug ! (
76
+ "type_op_ascribe_user_type_well_formed: user_type_annotation={:?}" ,
77
+ user_type_annotation,
78
+ ) ;
79
+
80
+ let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx } ;
81
+ cx. well_formed ( user_type_annotation) ?;
82
+
83
+ Ok ( ( ) )
84
+ } )
85
+ }
86
+
63
87
struct AscribeUserTypeCx < ' me , ' gcx : ' tcx , ' tcx : ' me > {
64
88
infcx : & ' me InferCtxt < ' me , ' gcx , ' tcx > ,
65
89
param_env : ParamEnv < ' tcx > ,
@@ -109,6 +133,56 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> {
109
133
value. subst ( self . tcx ( ) , substs)
110
134
}
111
135
136
+ fn well_formed (
137
+ & mut self ,
138
+ type_annotation : UserTypeAnnotation < ' tcx >
139
+ ) -> Result < ( ) , NoSolution > {
140
+ match type_annotation {
141
+ UserTypeAnnotation :: Ty ( ty) => {
142
+ self . prove_predicate ( Predicate :: WellFormed ( ty) ) ;
143
+ Ok ( ( ) )
144
+ } ,
145
+ UserTypeAnnotation :: TypeOf ( did, user_substs) => {
146
+ let UserSubsts {
147
+ user_self_ty,
148
+ substs,
149
+ } = user_substs;
150
+
151
+ let ty = self . tcx ( ) . type_of ( did) ;
152
+ let ty = self . subst ( ty, substs) ;
153
+ debug ! ( "relate_type_and_user_type: ty of def-id is {:?}" , ty) ;
154
+ let ty = self . normalize ( ty) ;
155
+
156
+ if let Some ( UserSelfTy {
157
+ impl_def_id,
158
+ self_ty,
159
+ } ) = user_self_ty {
160
+ let impl_self_ty = self . tcx ( ) . type_of ( impl_def_id) ;
161
+ let impl_self_ty = self . subst ( impl_self_ty, & substs) ;
162
+ let impl_self_ty = self . normalize ( impl_self_ty) ;
163
+
164
+ self . relate ( self_ty, Variance :: Invariant , impl_self_ty) ?;
165
+
166
+ self . prove_predicate ( Predicate :: WellFormed ( impl_self_ty) ) ;
167
+ }
168
+
169
+ // In addition to proving the predicates, we have to
170
+ // prove that `ty` is well-formed -- this is because
171
+ // the WF of `ty` is predicated on the substs being
172
+ // well-formed, and we haven't proven *that*. We don't
173
+ // want to prove the WF of types from `substs` directly because they
174
+ // haven't been normalized.
175
+ //
176
+ // FIXME(nmatsakis): Well, perhaps we should normalize
177
+ // them? This would only be relevant if some input
178
+ // type were ill-formed but did not appear in `ty`,
179
+ // which...could happen with normalization...
180
+ self . prove_predicate ( Predicate :: WellFormed ( ty) ) ;
181
+ Ok ( ( ) )
182
+ } ,
183
+ }
184
+ }
185
+
112
186
fn relate_mir_and_user_ty (
113
187
& mut self ,
114
188
mir_ty : Ty < ' tcx > ,
@@ -118,7 +192,7 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> {
118
192
projs : & [ ProjectionKind < ' tcx > ] ,
119
193
) -> Result < ( ) , NoSolution > {
120
194
let UserSubsts {
121
- user_self_ty,
195
+ user_self_ty : _ ,
122
196
substs,
123
197
} = user_substs;
124
198
let tcx = self . tcx ( ) ;
@@ -158,19 +232,6 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> {
158
232
self . relate ( mir_ty, variance, ty) ?;
159
233
}
160
234
161
- if let Some ( UserSelfTy {
162
- impl_def_id,
163
- self_ty,
164
- } ) = user_self_ty {
165
- let impl_self_ty = self . tcx ( ) . type_of ( impl_def_id) ;
166
- let impl_self_ty = self . subst ( impl_self_ty, & substs) ;
167
- let impl_self_ty = self . normalize ( impl_self_ty) ;
168
-
169
- self . relate ( self_ty, Variance :: Invariant , impl_self_ty) ?;
170
-
171
- self . prove_predicate ( Predicate :: WellFormed ( impl_self_ty) ) ;
172
- }
173
-
174
235
// Prove the predicates coming along with `def_id`.
175
236
//
176
237
// Also, normalize the `instantiated_predicates`
@@ -184,19 +245,6 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> {
184
245
self . prove_predicate ( instantiated_predicate) ;
185
246
}
186
247
187
- // In addition to proving the predicates, we have to
188
- // prove that `ty` is well-formed -- this is because
189
- // the WF of `ty` is predicated on the substs being
190
- // well-formed, and we haven't proven *that*. We don't
191
- // want to prove the WF of types from `substs` directly because they
192
- // haven't been normalized.
193
- //
194
- // FIXME(nmatsakis): Well, perhaps we should normalize
195
- // them? This would only be relevant if some input
196
- // type were ill-formed but did not appear in `ty`,
197
- // which...could happen with normalization...
198
- self . prove_predicate ( Predicate :: WellFormed ( ty) ) ;
199
-
200
248
Ok ( ( ) )
201
249
}
202
250
}
0 commit comments