6
6
//! for their size, offset of a field, etc.).
7
7
8
8
use rustc_hir:: { def:: DefKind , def_id:: DefId , ConstContext } ;
9
- use rustc_middle:: mir:: {
10
- self ,
11
- visit:: { TyContext , Visitor } ,
12
- Constant , ConstantKind , Local , LocalDecl , Location ,
13
- } ;
14
9
use rustc_middle:: ty:: {
15
10
self ,
16
11
query:: Providers ,
17
12
subst:: SubstsRef ,
18
13
visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitor } ,
19
14
Const , Ty , TyCtxt , UnusedGenericParams ,
20
15
} ;
16
+ use rustc_middle:: {
17
+ mir:: {
18
+ self ,
19
+ visit:: { TyContext , Visitor } ,
20
+ Constant , ConstantKind , Local , LocalDecl , Location ,
21
+ } ,
22
+ ty:: Instance ,
23
+ } ;
21
24
use rustc_span:: symbol:: sym;
22
25
use std:: ops:: ControlFlow ;
26
+ use std:: { convert:: TryInto , iter} ;
23
27
24
28
use crate :: errors:: UnusedGenericParamsHint ;
25
29
@@ -32,6 +36,7 @@ pub fn provide(providers: &mut Providers) {
32
36
///
33
37
/// Returns a bitset where bits representing unused parameters are set (`is_empty` indicates all
34
38
/// parameters are used).
39
+ #[ instrument( skip( tcx) , level = "debug" ) ]
35
40
fn unused_generic_params < ' tcx > (
36
41
tcx : TyCtxt < ' tcx > ,
37
42
instance : ty:: InstanceDef < ' tcx > ,
@@ -44,6 +49,7 @@ fn unused_generic_params<'tcx>(
44
49
let def_id = instance. def_id ( ) ;
45
50
// Exit early if this instance should not be polymorphized.
46
51
if !should_polymorphize ( tcx, def_id, instance) {
52
+ debug ! ( "Should not polymorphize instance" ) ;
47
53
return UnusedGenericParams :: new_all_used ( ) ;
48
54
}
49
55
@@ -52,6 +58,7 @@ fn unused_generic_params<'tcx>(
52
58
53
59
// Exit early when there are no parameters to be unused.
54
60
if generics. count ( ) == 0 {
61
+ debug ! ( "No generics" ) ;
55
62
return UnusedGenericParams :: new_all_used ( ) ;
56
63
}
57
64
@@ -248,6 +255,29 @@ impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
248
255
}
249
256
debug ! ( ?self . unused_parameters) ;
250
257
}
258
+
259
+ fn maybe_ignore_unused_fn_def_const ( & mut self , ty : Ty < ' tcx > ) {
260
+ if let ty:: FnDef ( def_id, substs) = * ty. kind ( )
261
+ && let param_env = self . tcx . param_env ( def_id)
262
+ && let Ok ( substs) = self . tcx . try_normalize_erasing_regions ( param_env, substs)
263
+ && let Ok ( Some ( instance) ) = Instance :: resolve ( self . tcx , param_env, def_id, substs)
264
+ && let unused_params = self . tcx . unused_generic_params ( instance. def )
265
+ && !unused_params. all_used ( )
266
+ {
267
+ debug ! ( ?unused_params, "Referencing a function that has unused generic params, not marking them all as used" ) ;
268
+
269
+ for ( subst, is_unused) in iter:: zip ( substs, unused_params. iter_over_eager ( ) ) {
270
+ if let ty:: GenericArgKind :: Type ( subst_ty) = subst. unpack ( )
271
+ && let ty:: Param ( param) = subst_ty. kind ( )
272
+ && !is_unused
273
+ {
274
+ self . unused_parameters . mark_used ( param. index ) ;
275
+ }
276
+ }
277
+ } else {
278
+ ty. visit_with ( self ) ;
279
+ }
280
+ }
251
281
}
252
282
253
283
impl < ' a , ' tcx > Visitor < ' tcx > for MarkUsedGenericParams < ' a , ' tcx > {
@@ -268,7 +298,8 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
268
298
self . super_local_decl ( local, local_decl) ;
269
299
}
270
300
271
- fn visit_constant ( & mut self , ct : & Constant < ' tcx > , location : Location ) {
301
+ #[ instrument( level = "debug" , skip( self ) ) ]
302
+ fn visit_constant ( & mut self , ct : & Constant < ' tcx > , _: Location ) {
272
303
match ct. literal {
273
304
ConstantKind :: Ty ( c) => {
274
305
c. visit_with ( self ) ;
@@ -285,9 +316,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
285
316
}
286
317
}
287
318
288
- Visitor :: visit_ty ( self , ty, TyContext :: Location ( location) ) ;
319
+ self . maybe_ignore_unused_fn_def_const ( ty) ;
320
+ }
321
+ ConstantKind :: Val ( _, ty) => {
322
+ self . maybe_ignore_unused_fn_def_const ( ty) ;
289
323
}
290
- ConstantKind :: Val ( _, ty) => Visitor :: visit_ty ( self , ty, TyContext :: Location ( location) ) ,
291
324
}
292
325
}
293
326
@@ -315,7 +348,10 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
315
348
self . visit_child_body ( def. did , substs) ;
316
349
ControlFlow :: CONTINUE
317
350
}
318
- _ => c. super_visit_with ( self ) ,
351
+ _ => {
352
+ self . maybe_ignore_unused_fn_def_const ( c. ty ( ) ) ;
353
+ ControlFlow :: CONTINUE
354
+ }
319
355
}
320
356
}
321
357
0 commit comments