diff options
| author | David Wood <david@davidtw.co> | 2020-08-09 11:22:50 +0100 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2020-08-10 13:23:19 +0100 |
| commit | 20f4e168249ca0828b7297942d47040c59376fbe (patch) | |
| tree | 65af6a6519afdd83ec8ace1762ac573b960167cf | |
| parent | 3f091baba4fa656adb4c1a57b64aa831002d801d (diff) | |
polymorphize: constrain unevaluated const handling
This commit constrains the support added for handling unevaluated consts in polymorphization (introduced in #75260) by: - Skipping associated constants as this causes cycle errors. - Skipping promoted constants when they contain `Self` as this ensures `T` is used in constants of the form `<Self as Foo<T>>`. Signed-off-by: David Wood <david@davidtw.co>
| -rw-r--r-- | src/librustc_mir/monomorphize/polymorphize.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/polymorphization/promoted-function-3.rs | 14 |
2 files changed, 24 insertions, 4 deletions
diff --git a/src/librustc_mir/monomorphize/polymorphize.rs b/src/librustc_mir/monomorphize/polymorphize.rs index a996b6fb9d9..fc9f7f1af62 100644 --- a/src/librustc_mir/monomorphize/polymorphize.rs +++ b/src/librustc_mir/monomorphize/polymorphize.rs @@ -269,15 +269,21 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> { self.unused_parameters.clear(param.index); false } - ty::ConstKind::Unevaluated(_, _, Some(p)) => { + ty::ConstKind::Unevaluated(def, _, Some(p)) + // Avoid considering `T` unused when constants are of the form: + // `<Self as Foo<T>>::foo::promoted[p]` + if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self => + { // If there is a promoted, don't look at the substs - since it will always contain // the generic parameters, instead, traverse the promoted MIR. - let promoted = self.tcx.promoted_mir(self.def_id); + let promoted = self.tcx.promoted_mir(def.did); self.visit_body(&promoted[p]); false } - ty::ConstKind::Unevaluated(def_id, unevaluated_substs, None) => { - self.visit_child_body(def_id.did, unevaluated_substs); + ty::ConstKind::Unevaluated(def, unevaluated_substs, None) + if self.tcx.def_kind(def.did) == DefKind::AnonConst => + { + self.visit_child_body(def.did, unevaluated_substs); false } _ => c.super_visit_with(self), diff --git a/src/test/ui/polymorphization/promoted-function-3.rs b/src/test/ui/polymorphization/promoted-function-3.rs new file mode 100644 index 00000000000..1c84df13e10 --- /dev/null +++ b/src/test/ui/polymorphization/promoted-function-3.rs @@ -0,0 +1,14 @@ +// run-pass +// compile-flags: -Zpolymorphize=on -Zmir-opt-level=3 + +fn caller<T, U>() -> &'static usize { + callee::<U>() +} + +fn callee<T>() -> &'static usize { + &std::mem::size_of::<T>() +} + +fn main() { + assert_eq!(caller::<(), ()>(), &0); +} |
