Skip to content

Commit 3f091ba

Browse files
committed
Auto merge of #75260 - davidtwco:polymorphization-promoted-substs, r=lcnr
polymorphize: unevaluated constants This PR makes polymorphization visit the promoted MIR of unevaluated constants with available promoted MIR instead of visiting the substitutions of that constant - which will mark all of the generic parameters as used; in addition polymorphization will now visit non-promoted unevaluated constants rather than visit their substs. r? @lcnr
2 parents 2bac92b + d97f89b commit 3f091ba

File tree

8 files changed

+104
-15
lines changed

8 files changed

+104
-15
lines changed

src/librustc_mir/monomorphize/polymorphize.rs

+32-13
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_middle::ty::{
1515
self,
1616
fold::{TypeFoldable, TypeVisitor},
1717
query::Providers,
18+
subst::SubstsRef,
1819
Const, Ty, TyCtxt,
1920
};
2021
use rustc_span::symbol::sym;
@@ -209,6 +210,25 @@ struct UsedGenericParametersVisitor<'a, 'tcx> {
209210
unused_parameters: &'a mut FiniteBitSet<u32>,
210211
}
211212

213+
impl<'a, 'tcx> UsedGenericParametersVisitor<'a, 'tcx> {
214+
/// Invoke `unused_generic_params` on a body contained within the current item (e.g.
215+
/// a closure, generator or constant).
216+
fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) {
217+
let unused = self.tcx.unused_generic_params(def_id);
218+
debug!(
219+
"visit_child_body: unused_parameters={:?} unused={:?}",
220+
self.unused_parameters, unused
221+
);
222+
for (i, arg) in substs.iter().enumerate() {
223+
let i = i.try_into().unwrap();
224+
if !unused.contains(i).unwrap_or(false) {
225+
arg.visit_with(self);
226+
}
227+
}
228+
debug!("visit_child_body: unused_parameters={:?}", self.unused_parameters);
229+
}
230+
}
231+
212232
impl<'a, 'tcx> Visitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {
213233
fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
214234
debug!("visit_local_decl: local_decl={:?}", local_decl);
@@ -249,6 +269,17 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {
249269
self.unused_parameters.clear(param.index);
250270
false
251271
}
272+
ty::ConstKind::Unevaluated(_, _, Some(p)) => {
273+
// If there is a promoted, don't look at the substs - since it will always contain
274+
// the generic parameters, instead, traverse the promoted MIR.
275+
let promoted = self.tcx.promoted_mir(self.def_id);
276+
self.visit_body(&promoted[p]);
277+
false
278+
}
279+
ty::ConstKind::Unevaluated(def_id, unevaluated_substs, None) => {
280+
self.visit_child_body(def_id.did, unevaluated_substs);
281+
false
282+
}
252283
_ => c.super_visit_with(self),
253284
}
254285
}
@@ -269,19 +300,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {
269300

270301
// Consider any generic parameters used by any closures/generators as used in the
271302
// parent.
272-
let unused = self.tcx.unused_generic_params(def_id);
273-
debug!(
274-
"visit_ty: unused_parameters={:?} unused={:?}",
275-
self.unused_parameters, unused
276-
);
277-
for (i, arg) in substs.iter().enumerate() {
278-
let i = i.try_into().unwrap();
279-
if !unused.contains(i).unwrap_or(false) {
280-
arg.visit_with(self);
281-
}
282-
}
283-
debug!("visit_ty: unused_parameters={:?}", self.unused_parameters);
284-
303+
self.visit_child_body(def_id, substs);
285304
false
286305
}
287306
ty::Param(param) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// build-fail
2+
// compile-flags: -Zpolymorphize=on
3+
#![crate_type = "lib"]
4+
#![feature(rustc_attrs)]
5+
6+
fn foo<'a>(_: &'a ()) {}
7+
8+
#[rustc_polymorphize_error]
9+
pub fn test<T>() {
10+
//~^ ERROR item has unused generic parameters
11+
foo(&());
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: item has unused generic parameters
2+
--> $DIR/promoted-function-1.rs:9:8
3+
|
4+
LL | pub fn test<T>() {
5+
| ^^^^ - generic parameter `T` is unused
6+
7+
error: aborting due to previous error
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// build-fail
2+
// compile-flags:-Zpolymorphize=on
3+
#![crate_type = "lib"]
4+
#![feature(lazy_normalization_consts, rustc_attrs)]
5+
//~^ WARN the feature `lazy_normalization_consts` is incomplete
6+
7+
#[rustc_polymorphize_error]
8+
fn test<T>() {
9+
//~^ ERROR item has unused generic parameters
10+
let x = [0; 3 + 4];
11+
}
12+
13+
pub fn caller() {
14+
test::<String>();
15+
test::<Vec<String>>();
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the feature `lazy_normalization_consts` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/promoted-function-2.rs:4:12
3+
|
4+
LL | #![feature(lazy_normalization_consts, rustc_attrs)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
= note: see issue #72219 <https://github.com/rust-lang/rust/issues/72219> for more information
9+
10+
error: item has unused generic parameters
11+
--> $DIR/promoted-function-2.rs:8:4
12+
|
13+
LL | fn test<T>() {
14+
| ^^^^ - generic parameter `T` is unused
15+
16+
error: aborting due to previous error; 1 warning emitted
17+

src/test/ui/polymorphization/promoted-function.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// run-pass
2+
// compile-flags:-Zpolymorphize=on
3+
24
fn fop<T>() {}
35

46
fn bar<T>() -> &'static fn() {

src/test/ui/polymorphization/unsized_cast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn foo<T: Default>() {
1717
fn foo2<T: Default>() {
1818
let _: T = Default::default();
1919
(|| {
20+
//~^ ERROR item has unused generic parameters
2021
let call: extern "rust-call" fn(_, _) = Fn::call;
2122
call(&|| {}, ());
2223
//~^ ERROR item has unused generic parameters

src/test/ui/polymorphization/unsized_cast.stderr

+16-2
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,27 @@ LL | (|| Box::new(|| {}) as Box<dyn Fn()>)();
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
error: item has unused generic parameters
20-
--> $DIR/unsized_cast.rs:21:15
20+
--> $DIR/unsized_cast.rs:22:15
2121
|
2222
LL | fn foo2<T: Default>() {
2323
| - generic parameter `T` is unused
2424
...
2525
LL | call(&|| {}, ());
2626
| ^^^^^
2727

28-
error: aborting due to 3 previous errors
28+
error: item has unused generic parameters
29+
--> $DIR/unsized_cast.rs:19:5
30+
|
31+
LL | fn foo2<T: Default>() {
32+
| - generic parameter `T` is unused
33+
LL | let _: T = Default::default();
34+
LL | / (|| {
35+
LL | |
36+
LL | | let call: extern "rust-call" fn(_, _) = Fn::call;
37+
LL | | call(&|| {}, ());
38+
LL | |
39+
LL | | })();
40+
| |______^
41+
42+
error: aborting due to 4 previous errors
2943

0 commit comments

Comments
 (0)