@@ -7,6 +7,31 @@ use rustc_middle::ty::Ty;
7
7
use rustc_span:: Span ;
8
8
use rustc_trait_selection:: traits;
9
9
10
+ /// A declaration is an abstraction of [hir::Local] and [hir::Let].
11
+ ///
12
+ /// It must have a hir_id, as this is how we connect gather_locals to the check functions.
13
+ pub ( super ) struct Declaration < ' a > {
14
+ pub hir_id : hir:: HirId ,
15
+ pub pat : & ' a hir:: Pat < ' a > ,
16
+ pub ty : Option < & ' a hir:: Ty < ' a > > ,
17
+ pub span : Span ,
18
+ pub init : Option < & ' a hir:: Expr < ' a > > ,
19
+ }
20
+
21
+ impl < ' a > From < & ' a hir:: Local < ' a > > for Declaration < ' a > {
22
+ fn from ( local : & ' a hir:: Local < ' a > ) -> Self {
23
+ let hir:: Local { hir_id, pat, ty, span, init, .. } = * local;
24
+ Declaration { hir_id, pat, ty, span, init }
25
+ }
26
+ }
27
+
28
+ impl < ' a > From < & ' a hir:: Let < ' a > > for Declaration < ' a > {
29
+ fn from ( let_expr : & ' a hir:: Let < ' a > ) -> Self {
30
+ let hir:: Let { hir_id, pat, ty, span, init } = * let_expr;
31
+ Declaration { hir_id, pat, ty, span, init : Some ( init) }
32
+ }
33
+ }
34
+
10
35
pub ( super ) struct GatherLocalsVisitor < ' a , ' tcx > {
11
36
fcx : & ' a FnCtxt < ' a , ' tcx > ,
12
37
// parameters are special cases of patterns, but we want to handle them as
@@ -41,18 +66,12 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
41
66
}
42
67
}
43
68
}
44
- }
45
-
46
- impl < ' a , ' tcx > Visitor < ' tcx > for GatherLocalsVisitor < ' a , ' tcx > {
47
- type Map = intravisit:: ErasedMap < ' tcx > ;
48
69
49
- fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
50
- NestedVisitorMap :: None
51
- }
52
-
53
- // Add explicitly-declared locals.
54
- fn visit_local ( & mut self , local : & ' tcx hir:: Local < ' tcx > ) {
55
- let local_ty = match local. ty {
70
+ /// Allocates a [LocalTy] for a declaration, which may have a type annotation. If it does have
71
+ /// a type annotation, then the LocalTy stored will be the resolved type. This may be found
72
+ /// again during type checking by querying [FnCtxt::local_ty] for the same hir_id.
73
+ fn declare ( & mut self , decl : Declaration < ' tcx > ) {
74
+ let local_ty = match decl. ty {
56
75
Some ( ref ty) => {
57
76
let o_ty = self . fcx . to_ty ( & ty) ;
58
77
@@ -68,41 +87,31 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
68
87
}
69
88
None => None ,
70
89
} ;
71
- self . assign ( local . span , local . hir_id , local_ty) ;
90
+ self . assign ( decl . span , decl . hir_id , local_ty) ;
72
91
73
92
debug ! (
74
93
"local variable {:?} is assigned type {}" ,
75
- local . pat,
76
- self . fcx. ty_to_string( & * self . fcx. locals. borrow( ) . get( & local . hir_id) . unwrap( ) . decl_ty)
94
+ decl . pat,
95
+ self . fcx. ty_to_string( & * self . fcx. locals. borrow( ) . get( & decl . hir_id) . unwrap( ) . decl_ty)
77
96
) ;
78
- intravisit:: walk_local ( self , local) ;
79
97
}
98
+ }
80
99
81
- fn visit_let_expr ( & mut self , let_expr : & ' tcx hir:: Let < ' tcx > ) {
82
- let local_ty = match let_expr. ty {
83
- Some ( ref ty) => {
84
- let o_ty = self . fcx . to_ty ( & ty) ;
100
+ impl < ' a , ' tcx > Visitor < ' tcx > for GatherLocalsVisitor < ' a , ' tcx > {
101
+ type Map = intravisit:: ErasedMap < ' tcx > ;
85
102
86
- let c_ty = self . fcx . inh . infcx . canonicalize_user_type_annotation ( UserType :: Ty ( o_ty) ) ;
87
- debug ! ( "visit_let_expr: ty.hir_id={:?} o_ty={:?} c_ty={:?}" , ty. hir_id, o_ty, c_ty) ;
88
- self . fcx
89
- . typeck_results
90
- . borrow_mut ( )
91
- . user_provided_types_mut ( )
92
- . insert ( ty. hir_id , c_ty) ;
103
+ fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
104
+ NestedVisitorMap :: None
105
+ }
93
106
94
- Some ( LocalTy { decl_ty : o_ty , revealed_ty : o_ty } )
95
- }
96
- None => None ,
97
- } ;
98
- self . assign ( let_expr . span , let_expr . hir_id , local_ty ) ;
107
+ // Add explicitly-declared locals.
108
+ fn visit_local ( & mut self , local : & ' tcx hir :: Local < ' tcx > ) {
109
+ self . declare ( local . into ( ) ) ;
110
+ intravisit :: walk_local ( self , local ) ;
111
+ }
99
112
100
- debug ! (
101
- "local variable {:?} is assigned type {}" ,
102
- let_expr. pat,
103
- self . fcx
104
- . ty_to_string( & * self . fcx. locals. borrow( ) . get( & let_expr. hir_id) . unwrap( ) . decl_ty)
105
- ) ;
113
+ fn visit_let_expr ( & mut self , let_expr : & ' tcx hir:: Let < ' tcx > ) {
114
+ self . declare ( let_expr. into ( ) ) ;
106
115
intravisit:: walk_let_expr ( self , let_expr) ;
107
116
}
108
117
0 commit comments