@@ -26,17 +26,15 @@ use errors::{DiagnosticBuilder, DiagnosticId};
26
26
use rustc:: hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
27
27
use rustc:: hir;
28
28
29
- pub struct CheckTypeWellFormedVisitor < ' a , ' tcx : ' a > {
29
+ pub struct CheckTypeWellFormed < ' a , ' tcx : ' a > {
30
30
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
31
- code : ObligationCauseCode < ' tcx > ,
32
31
}
33
32
34
33
/// Helper type of a temporary returned by .for_item(...).
35
34
/// Necessary because we can't write the following bound:
36
35
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>).
37
36
struct CheckWfFcxBuilder < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
38
37
inherited : super :: InheritedBuilder < ' a , ' gcx , ' tcx > ,
39
- code : ObligationCauseCode < ' gcx > ,
40
38
id : ast:: NodeId ,
41
39
span : Span ,
42
40
param_env : ty:: ParamEnv < ' tcx > ,
@@ -45,30 +43,27 @@ struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
45
43
impl < ' a , ' gcx , ' tcx > CheckWfFcxBuilder < ' a , ' gcx , ' tcx > {
46
44
fn with_fcx < F > ( & ' tcx mut self , f : F ) where
47
45
F : for < ' b > FnOnce ( & FnCtxt < ' b , ' gcx , ' tcx > ,
48
- & mut CheckTypeWellFormedVisitor < ' b , ' gcx > ) -> Vec < Ty < ' tcx > >
46
+ & mut CheckTypeWellFormed < ' b , ' gcx > ) -> Vec < Ty < ' tcx > >
49
47
{
50
- let code = self . code . clone ( ) ;
51
48
let id = self . id ;
52
49
let span = self . span ;
53
50
let param_env = self . param_env ;
54
51
self . inherited . enter ( |inh| {
55
52
let fcx = FnCtxt :: new ( & inh, param_env, id) ;
56
- let wf_tys = f ( & fcx, & mut CheckTypeWellFormedVisitor {
53
+ let wf_tys = f ( & fcx, & mut CheckTypeWellFormed {
57
54
tcx : fcx. tcx . global_tcx ( ) ,
58
- code,
59
55
} ) ;
60
56
fcx. select_all_obligations_or_error ( ) ;
61
57
fcx. regionck_item ( id, span, & wf_tys) ;
62
58
} ) ;
63
59
}
64
60
}
65
61
66
- impl < ' a , ' gcx > CheckTypeWellFormedVisitor < ' a , ' gcx > {
62
+ impl < ' a , ' gcx > CheckTypeWellFormed < ' a , ' gcx > {
67
63
pub fn new ( tcx : TyCtxt < ' a , ' gcx , ' gcx > )
68
- -> CheckTypeWellFormedVisitor < ' a , ' gcx > {
69
- CheckTypeWellFormedVisitor {
64
+ -> CheckTypeWellFormed < ' a , ' gcx > {
65
+ CheckTypeWellFormed {
70
66
tcx,
71
- code : ObligationCauseCode :: MiscObligation
72
67
}
73
68
}
74
69
@@ -83,11 +78,14 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
83
78
/// We do this check as a pre-pass before checking fn bodies because if these constraints are
84
79
/// not included it frequently leads to confusing errors in fn bodies. So it's better to check
85
80
/// the types first.
86
- fn check_item_well_formed ( & mut self , item : & hir :: Item ) {
81
+ pub fn check_item_well_formed ( & mut self , def_id : DefId ) {
87
82
let tcx = self . tcx ;
83
+ let node_id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
84
+ let item = tcx. hir . expect_item ( node_id) ;
85
+
88
86
debug ! ( "check_item_well_formed(it.id={}, it.name={})" ,
89
87
item. id,
90
- tcx. item_path_str( tcx . hir . local_def_id ( item . id ) ) ) ;
88
+ tcx. item_path_str( def_id ) ) ;
91
89
92
90
match item. node {
93
91
// Right now we check that every default trait implementation
@@ -161,11 +159,34 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
161
159
}
162
160
}
163
161
162
+ pub fn check_trait_item ( & mut self , def_id : DefId ) {
163
+ let node_id = self . tcx . hir . as_local_node_id ( def_id) . unwrap ( ) ;
164
+ let trait_item = self . tcx . hir . expect_trait_item ( node_id) ;
165
+
166
+ let method_sig = match trait_item. node {
167
+ hir:: TraitItemKind :: Method ( ref sig, _) => Some ( sig) ,
168
+ _ => None
169
+ } ;
170
+ CheckTypeWellFormed :: new ( self . tcx )
171
+ . check_associated_item ( trait_item. id , trait_item. span , method_sig) ;
172
+ }
173
+
174
+ pub fn check_impl_item ( & mut self , def_id : DefId ) {
175
+ let node_id = self . tcx . hir . as_local_node_id ( def_id) . unwrap ( ) ;
176
+ let impl_item = self . tcx . hir . expect_impl_item ( node_id) ;
177
+
178
+ let method_sig = match impl_item. node {
179
+ hir:: ImplItemKind :: Method ( ref sig, _) => Some ( sig) ,
180
+ _ => None
181
+ } ;
182
+ self . check_associated_item ( impl_item. id , impl_item. span , method_sig) ;
183
+ }
184
+
164
185
fn check_associated_item ( & mut self ,
165
186
item_id : ast:: NodeId ,
166
187
span : Span ,
167
188
sig_if_method : Option < & hir:: MethodSig > ) {
168
- let code = self . code . clone ( ) ;
189
+ let code = ObligationCauseCode :: MiscObligation ;
169
190
self . for_id ( item_id, span) . with_fcx ( |fcx, this| {
170
191
let item = fcx. tcx . associated_item ( fcx. tcx . hir . local_def_id ( item_id) ) ;
171
192
@@ -213,7 +234,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
213
234
let def_id = self . tcx . hir . local_def_id ( id) ;
214
235
CheckWfFcxBuilder {
215
236
inherited : Inherited :: build ( self . tcx , def_id) ,
216
- code : self . code . clone ( ) ,
217
237
id,
218
238
span,
219
239
param_env : self . tcx . param_env ( def_id) ,
@@ -265,7 +285,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
265
285
266
286
// All field types must be well-formed.
267
287
for field in & variant. fields {
268
- fcx. register_wf_obligation ( field. ty , field. span , this. code . clone ( ) )
288
+ fcx. register_wf_obligation ( field. ty , field. span ,
289
+ ObligationCauseCode :: MiscObligation )
269
290
}
270
291
}
271
292
@@ -300,11 +321,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
300
321
{
301
322
debug ! ( "check_item_type: {:?}" , item) ;
302
323
303
- self . for_item ( item) . with_fcx ( |fcx, this | {
324
+ self . for_item ( item) . with_fcx ( |fcx, _this | {
304
325
let ty = fcx. tcx . type_of ( fcx. tcx . hir . local_def_id ( item. id ) ) ;
305
326
let item_ty = fcx. normalize_associated_types_in ( item. span , & ty) ;
306
327
307
- fcx. register_wf_obligation ( item_ty, item. span , this . code . clone ( ) ) ;
328
+ fcx. register_wf_obligation ( item_ty, item. span , ObligationCauseCode :: MiscObligation ) ;
308
329
309
330
vec ! [ ] // no implied bounds in a const etc
310
331
} ) ;
@@ -339,7 +360,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
339
360
None => {
340
361
let self_ty = fcx. tcx . type_of ( item_def_id) ;
341
362
let self_ty = fcx. normalize_associated_types_in ( item. span , & self_ty) ;
342
- fcx. register_wf_obligation ( self_ty, ast_self_ty. span , this. code . clone ( ) ) ;
363
+ fcx. register_wf_obligation ( self_ty, ast_self_ty. span ,
364
+ ObligationCauseCode :: MiscObligation ) ;
343
365
}
344
366
}
345
367
@@ -374,7 +396,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
374
396
// parameter includes another (e.g., <T, U = T>). In those cases, we can't
375
397
// be sure if it will error or not as user might always specify the other.
376
398
if !ty. needs_subst ( ) {
377
- fcx. register_wf_obligation ( ty, fcx. tcx . def_span ( d) , self . code . clone ( ) ) ;
399
+ fcx. register_wf_obligation ( ty, fcx. tcx . def_span ( d) ,
400
+ ObligationCauseCode :: MiscObligation ) ;
378
401
}
379
402
}
380
403
@@ -458,11 +481,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
458
481
let sig = fcx. tcx . liberate_late_bound_regions ( def_id, & sig) ;
459
482
460
483
for input_ty in sig. inputs ( ) {
461
- fcx. register_wf_obligation ( & input_ty, span, self . code . clone ( ) ) ;
484
+ fcx. register_wf_obligation ( & input_ty, span, ObligationCauseCode :: MiscObligation ) ;
462
485
}
463
486
implied_bounds. extend ( sig. inputs ( ) ) ;
464
487
465
- fcx. register_wf_obligation ( sig. output ( ) , span, self . code . clone ( ) ) ;
488
+ fcx. register_wf_obligation ( sig. output ( ) , span, ObligationCauseCode :: MiscObligation ) ;
466
489
467
490
// FIXME(#25759) return types should not be implied bounds
468
491
implied_bounds. push ( sig. output ( ) ) ;
@@ -648,34 +671,42 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) {
648
671
}
649
672
}
650
673
674
+ pub struct CheckTypeWellFormedVisitor < ' a , ' tcx : ' a > {
675
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
676
+ }
677
+
678
+ impl < ' a , ' gcx > CheckTypeWellFormedVisitor < ' a , ' gcx > {
679
+ pub fn new ( tcx : TyCtxt < ' a , ' gcx , ' gcx > )
680
+ -> CheckTypeWellFormedVisitor < ' a , ' gcx > {
681
+ CheckTypeWellFormedVisitor {
682
+ tcx,
683
+ }
684
+ }
685
+ }
686
+
651
687
impl < ' a , ' tcx , ' v > Visitor < ' v > for CheckTypeWellFormedVisitor < ' a , ' tcx > {
652
688
fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' v > {
653
689
NestedVisitorMap :: None
654
690
}
655
691
656
692
fn visit_item ( & mut self , i : & hir:: Item ) {
657
693
debug ! ( "visit_item: {:?}" , i) ;
658
- self . check_item_well_formed ( i) ;
694
+ let def_id = self . tcx . hir . local_def_id ( i. id ) ;
695
+ ty:: maps:: queries:: check_item_well_formed:: ensure ( self . tcx , def_id) ;
659
696
intravisit:: walk_item ( self , i) ;
660
697
}
661
698
662
699
fn visit_trait_item ( & mut self , trait_item : & ' v hir:: TraitItem ) {
663
700
debug ! ( "visit_trait_item: {:?}" , trait_item) ;
664
- let method_sig = match trait_item. node {
665
- hir:: TraitItemKind :: Method ( ref sig, _) => Some ( sig) ,
666
- _ => None
667
- } ;
668
- self . check_associated_item ( trait_item. id , trait_item. span , method_sig) ;
701
+ let def_id = self . tcx . hir . local_def_id ( trait_item. id ) ;
702
+ ty:: maps:: queries:: check_trait_item_well_formed:: ensure ( self . tcx , def_id) ;
669
703
intravisit:: walk_trait_item ( self , trait_item)
670
704
}
671
705
672
706
fn visit_impl_item ( & mut self , impl_item : & ' v hir:: ImplItem ) {
673
707
debug ! ( "visit_impl_item: {:?}" , impl_item) ;
674
- let method_sig = match impl_item. node {
675
- hir:: ImplItemKind :: Method ( ref sig, _) => Some ( sig) ,
676
- _ => None
677
- } ;
678
- self . check_associated_item ( impl_item. id , impl_item. span , method_sig) ;
708
+ let def_id = self . tcx . hir . local_def_id ( impl_item. id ) ;
709
+ ty:: maps:: queries:: check_impl_item_well_formed:: ensure ( self . tcx , def_id) ;
679
710
intravisit:: walk_impl_item ( self , impl_item)
680
711
}
681
712
}
0 commit comments