about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2020-08-09 11:22:50 +0100
committerDavid Wood <david@davidtw.co>2020-08-10 13:23:19 +0100
commit20f4e168249ca0828b7297942d47040c59376fbe (patch)
tree65af6a6519afdd83ec8ace1762ac573b960167cf
parent3f091baba4fa656adb4c1a57b64aa831002d801d (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.rs14
-rw-r--r--src/test/ui/polymorphization/promoted-function-3.rs14
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);
+}