@@ -26,7 +26,7 @@ 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
31
}
32
32
@@ -43,14 +43,14 @@ struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
43
43
impl < ' a , ' gcx , ' tcx > CheckWfFcxBuilder < ' a , ' gcx , ' tcx > {
44
44
fn with_fcx < F > ( & ' tcx mut self , f : F ) where
45
45
F : for < ' b > FnOnce ( & FnCtxt < ' b , ' gcx , ' tcx > ,
46
- & mut CheckTypeWellFormedVisitor < ' b , ' gcx > ) -> Vec < Ty < ' tcx > >
46
+ & mut CheckTypeWellFormed < ' b , ' gcx > ) -> Vec < Ty < ' tcx > >
47
47
{
48
48
let id = self . id ;
49
49
let span = self . span ;
50
50
let param_env = self . param_env ;
51
51
self . inherited . enter ( |inh| {
52
52
let fcx = FnCtxt :: new ( & inh, param_env, id) ;
53
- let wf_tys = f ( & fcx, & mut CheckTypeWellFormedVisitor {
53
+ let wf_tys = f ( & fcx, & mut CheckTypeWellFormed {
54
54
tcx : fcx. tcx . global_tcx ( ) ,
55
55
} ) ;
56
56
fcx. select_all_obligations_or_error ( ) ;
@@ -59,10 +59,10 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
59
59
}
60
60
}
61
61
62
- impl < ' a , ' gcx > CheckTypeWellFormedVisitor < ' a , ' gcx > {
62
+ impl < ' a , ' gcx > CheckTypeWellFormed < ' a , ' gcx > {
63
63
pub fn new ( tcx : TyCtxt < ' a , ' gcx , ' gcx > )
64
- -> CheckTypeWellFormedVisitor < ' a , ' gcx > {
65
- CheckTypeWellFormedVisitor {
64
+ -> CheckTypeWellFormed < ' a , ' gcx > {
65
+ CheckTypeWellFormed {
66
66
tcx,
67
67
}
68
68
}
@@ -78,11 +78,14 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
78
78
/// We do this check as a pre-pass before checking fn bodies because if these constraints are
79
79
/// not included it frequently leads to confusing errors in fn bodies. So it's better to check
80
80
/// the types first.
81
- fn check_item_well_formed ( & mut self , item : & hir :: Item ) {
81
+ pub fn check_item_well_formed ( & mut self , def_id : DefId ) {
82
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
+
83
86
debug ! ( "check_item_well_formed(it.id={}, it.name={})" ,
84
87
item. id,
85
- tcx. item_path_str( tcx . hir . local_def_id ( item . id ) ) ) ;
88
+ tcx. item_path_str( def_id ) ) ;
86
89
87
90
match item. node {
88
91
// Right now we check that every default trait implementation
@@ -259,7 +262,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
259
262
260
263
// All field types must be well-formed.
261
264
for field in & variant. fields {
262
- fcx. register_wf_obligation ( field. ty , field. span , ObligationCauseCode :: MiscObligation )
265
+ fcx. register_wf_obligation ( field. ty , field. span ,
266
+ ObligationCauseCode :: MiscObligation )
263
267
}
264
268
}
265
269
@@ -333,7 +337,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
333
337
None => {
334
338
let self_ty = fcx. tcx . type_of ( item_def_id) ;
335
339
let self_ty = fcx. normalize_associated_types_in ( item. span , & self_ty) ;
336
- fcx. register_wf_obligation ( self_ty, ast_self_ty. span , ObligationCauseCode :: MiscObligation ) ;
340
+ fcx. register_wf_obligation ( self_ty, ast_self_ty. span ,
341
+ ObligationCauseCode :: MiscObligation ) ;
337
342
}
338
343
}
339
344
@@ -368,7 +373,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
368
373
// parameter includes another (e.g., <T, U = T>). In those cases, we can't
369
374
// be sure if it will error or not as user might always specify the other.
370
375
if !ty. needs_subst ( ) {
371
- fcx. register_wf_obligation ( ty, fcx. tcx . def_span ( d) , ObligationCauseCode :: MiscObligation ) ;
376
+ fcx. register_wf_obligation ( ty, fcx. tcx . def_span ( d) ,
377
+ ObligationCauseCode :: MiscObligation ) ;
372
378
}
373
379
}
374
380
@@ -642,14 +648,28 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) {
642
648
}
643
649
}
644
650
651
+ pub struct CheckTypeWellFormedVisitor < ' a , ' tcx : ' a > {
652
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
653
+ }
654
+
655
+ impl < ' a , ' gcx > CheckTypeWellFormedVisitor < ' a , ' gcx > {
656
+ pub fn new ( tcx : TyCtxt < ' a , ' gcx , ' gcx > )
657
+ -> CheckTypeWellFormedVisitor < ' a , ' gcx > {
658
+ CheckTypeWellFormedVisitor {
659
+ tcx,
660
+ }
661
+ }
662
+ }
663
+
645
664
impl < ' a , ' tcx , ' v > Visitor < ' v > for CheckTypeWellFormedVisitor < ' a , ' tcx > {
646
665
fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' v > {
647
666
NestedVisitorMap :: None
648
667
}
649
668
650
669
fn visit_item ( & mut self , i : & hir:: Item ) {
651
670
debug ! ( "visit_item: {:?}" , i) ;
652
- self . check_item_well_formed ( i) ;
671
+ let def_id = self . tcx . hir . local_def_id ( i. id ) ;
672
+ ty:: maps:: queries:: check_item_well_formed:: ensure ( self . tcx , def_id) ;
653
673
intravisit:: walk_item ( self , i) ;
654
674
}
655
675
@@ -659,7 +679,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> {
659
679
hir:: TraitItemKind :: Method ( ref sig, _) => Some ( sig) ,
660
680
_ => None
661
681
} ;
662
- self . check_associated_item ( trait_item. id , trait_item. span , method_sig) ;
682
+ CheckTypeWellFormed :: new ( self . tcx )
683
+ . check_associated_item ( trait_item. id , trait_item. span , method_sig) ;
663
684
intravisit:: walk_trait_item ( self , trait_item)
664
685
}
665
686
@@ -669,7 +690,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> {
669
690
hir:: ImplItemKind :: Method ( ref sig, _) => Some ( sig) ,
670
691
_ => None
671
692
} ;
672
- self . check_associated_item ( impl_item. id , impl_item. span , method_sig) ;
693
+ CheckTypeWellFormed :: new ( self . tcx )
694
+ . check_associated_item ( impl_item. id , impl_item. span , method_sig) ;
673
695
intravisit:: walk_impl_item ( self , impl_item)
674
696
}
675
697
}
0 commit comments