1
+ // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2
+ // file at the top-level directory of this distribution and at
3
+ // http://rust-lang.org/COPYRIGHT.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
+ // option. This file may not be copied, modified, or distributed
9
+ // except according to those terms.
10
+
1
11
use rustc_data_structures:: indexed_vec:: IndexVec ;
2
12
use rustc:: ty:: { self , TyCtxt , Ty , TypeFoldable , Instance , ParamTy } ;
3
13
use rustc:: ty:: fold:: TypeFolder ;
4
14
use rustc:: ty:: subst:: Kind ;
5
- use rustc:: mir:: Promoted ;
15
+ use rustc:: middle:: const_val:: ConstVal ;
16
+ use rustc:: mir:: { Mir , Rvalue , Promoted , Location } ;
6
17
use rustc:: mir:: visit:: { Visitor , TyContext } ;
7
18
8
19
/// Replace substs which arent used by the function with TyError,
9
20
/// so that it doesnt end up in the binary multiple times
10
- pub ( crate ) fn collapse_interchangable_instances < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , mut inst : Instance < ' tcx > ) -> Instance < ' tcx > {
21
+ pub ( crate ) fn collapse_interchangable_instances < ' a , ' tcx > (
22
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
23
+ mut inst : Instance < ' tcx >
24
+ ) -> Instance < ' tcx > {
11
25
info ! ( "replace_unused_substs_with_ty_error({:?})" , inst) ;
12
26
13
27
if inst. substs . is_noop ( ) || !tcx. is_mir_available ( inst. def_id ( ) ) {
@@ -28,14 +42,16 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx,
28
42
if let Some ( ty) = subst. as_type ( ) {
29
43
let ty = if used_substs. substs . iter ( ) . find ( |p|p. idx == i as u32 ) . is_some ( ) {
30
44
ty. into ( )
31
- } else if let ty:: TyParam ( ref _param) = ty. sty { // Dont replace <closure_kind> and other internal params
45
+ } else if let ty:: TyParam ( ref _param) = ty. sty {
46
+ //^ Dont replace <closure_kind> and other internal params
32
47
if false /*param.name.as_str().starts_with("<")*/ {
33
48
ty. into ( )
34
49
} else {
35
50
tcx. mk_ty ( ty:: TyNever )
36
51
}
37
52
} else {
38
- tcx. mk_ty ( ty:: TyNever ) // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn
53
+ // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn
54
+ tcx. mk_ty ( ty:: TyNever )
39
55
} ;
40
56
Kind :: from ( ty)
41
57
} else {
@@ -54,59 +70,88 @@ pub struct UsedSubsts {
54
70
55
71
impl_stable_hash_for ! { struct UsedSubsts { substs, promoted } }
56
72
57
- fn used_substs_for_instance < ' a , ' tcx : ' a > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , instance : Instance < ' tcx > ) -> UsedSubsts {
58
- struct SubstsVisitor < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > ( TyCtxt < ' a , ' gcx , ' tcx > , UsedSubsts ) ;
73
+ struct SubstsVisitor < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > (
74
+ TyCtxt < ' a , ' gcx , ' tcx > ,
75
+ & ' tcx Mir < ' tcx > ,
76
+ UsedSubsts
77
+ ) ;
78
+
79
+ impl < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > Visitor < ' tcx > for SubstsVisitor < ' a , ' gcx , ' tcx > {
80
+ fn visit_ty ( & mut self , ty : & Ty < ' tcx > , _: TyContext ) {
81
+ self . fold_ty ( ty) ;
82
+ }
83
+
84
+ fn visit_const ( & mut self , constant : & & ' tcx ty:: Const < ' tcx > , _location : Location ) {
85
+ if let ConstVal :: Unevaluated ( _def_id, substs) = constant. val {
86
+ for subst in substs {
87
+ if let Some ( ty) = subst. as_type ( ) {
88
+ ty. fold_with ( self ) ;
89
+ }
90
+ }
91
+ }
92
+ }
59
93
60
- impl < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > Visitor < ' tcx > for SubstsVisitor < ' a , ' gcx , ' tcx > {
61
- fn visit_ty ( & mut self , ty : & Ty < ' tcx > , _: TyContext ) {
62
- self . fold_ty ( ty) ;
94
+ fn visit_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > , location : Location ) {
95
+ let tcx = self . 0 ;
96
+ match * rvalue {
97
+ Rvalue :: Cast ( _kind, ref op, ty) => {
98
+ self . fold_ty ( op. ty ( & self . 1 . local_decls , tcx) ) ;
99
+ self . fold_ty ( ty) ;
100
+ }
101
+ _ => { }
63
102
}
103
+ self . super_rvalue ( rvalue, location) ;
64
104
}
105
+ }
65
106
66
- impl < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > TypeFolder < ' gcx , ' tcx > for SubstsVisitor < ' a , ' gcx , ' tcx > {
67
- fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' tcx > {
68
- self . 0
107
+ impl < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > TypeFolder < ' gcx , ' tcx > for SubstsVisitor < ' a , ' gcx , ' tcx > {
108
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' tcx > {
109
+ self . 0
110
+ }
111
+ fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
112
+ if !ty. needs_subst ( ) {
113
+ return ty;
69
114
}
70
- fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
71
- if !ty. needs_subst ( ) {
72
- return ty;
115
+ match ty. sty {
116
+ ty:: TyParam ( param) => {
117
+ self . 2 . substs . push ( param) ;
118
+ ty
73
119
}
74
- match ty. sty {
75
- ty:: TyParam ( param) => {
76
- self . 1 . substs . push ( param) ;
77
- ty
78
- }
79
- ty:: TyFnDef ( _, substs) => {
80
- for subst in substs {
81
- if let Some ( ty) = subst. as_type ( ) {
82
- ty. fold_with ( self ) ;
83
- }
120
+ ty:: TyFnDef ( _, substs) => {
121
+ for subst in substs {
122
+ if let Some ( ty) = subst. as_type ( ) {
123
+ ty. fold_with ( self ) ;
84
124
}
85
- ty. super_fold_with ( self )
86
125
}
87
- ty:: TyClosure ( _, closure_substs) => {
88
- for subst in closure_substs. substs {
89
- if let Some ( ty) = subst. as_type ( ) {
90
- ty. fold_with ( self ) ;
91
- }
126
+ ty. super_fold_with ( self )
127
+ }
128
+ ty:: TyClosure ( _, closure_substs) => {
129
+ for subst in closure_substs. substs {
130
+ if let Some ( ty) = subst. as_type ( ) {
131
+ ty. fold_with ( self ) ;
92
132
}
93
- ty. super_fold_with ( self )
94
133
}
95
- _ => ty. super_fold_with ( self )
134
+ ty. super_fold_with ( self )
96
135
}
136
+ _ => ty. super_fold_with ( self )
97
137
}
98
138
}
139
+ }
99
140
141
+ fn used_substs_for_instance < ' a , ' tcx : ' a > (
142
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
143
+ instance : Instance < ' tcx >
144
+ ) -> UsedSubsts {
100
145
let mir = tcx. instance_mir ( instance. def ) ;
101
146
let sig = :: rustc:: ty:: ty_fn_sig ( tcx, instance. ty ( tcx) ) ;
102
147
let sig = tcx. erase_late_bound_regions_and_normalize ( & sig) ;
103
- let mut substs_visitor = SubstsVisitor ( tcx, UsedSubsts :: default ( ) ) ;
148
+ let mut substs_visitor = SubstsVisitor ( tcx, mir , UsedSubsts :: default ( ) ) ;
104
149
substs_visitor. visit_mir ( mir) ;
105
150
for ty in sig. inputs ( ) . iter ( ) {
106
151
ty. fold_with ( & mut substs_visitor) ;
107
152
}
108
153
sig. output ( ) . fold_with ( & mut substs_visitor) ;
109
- let mut used_substs = substs_visitor. 1 ;
154
+ let mut used_substs = substs_visitor. 2 ;
110
155
used_substs. substs . sort_by_key ( |s|s. idx ) ;
111
156
used_substs. substs . dedup_by_key ( |s|s. idx ) ;
112
157
used_substs
0 commit comments