about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-06-29 17:59:33 +0530
committerGitHub <noreply@github.com>2022-06-29 17:59:33 +0530
commit7b9a7ef218fbdc3cbb9f7828bc9f032bcfd9a6dc (patch)
tree1a20e3c4807adcb5f5e189520416932434661241
parent3f2ba251591410016a1e056c6cdafc30c965db29 (diff)
parent1e40200b353926308a9a8a5f3349df8dc6bf8f80 (diff)
downloadrust-7b9a7ef218fbdc3cbb9f7828bc9f032bcfd9a6dc.tar.gz
rust-7b9a7ef218fbdc3cbb9f7828bc9f032bcfd9a6dc.zip
Rollup merge of #98499 - JulianKnodt:erase_lifetime, r=lcnr
Erase regions in New Abstract Consts

When an abstract const is constructed, we previously included lifetimes in the set of substitutes, so it was not able to unify two abstract consts if their lifetimes did not match but the values did, despite the values not depending on the lifetimes. This caused code that should have compiled to not compile.

Fixes #98452

r? ```@lcnr```
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs3
-rw-r--r--src/test/ui/const-generics/try_unify_ignore_lifetimes.rs33
2 files changed, 35 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 5d08ea99ac6..424eff2f621 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -236,7 +236,7 @@ impl<'tcx> AbstractConst<'tcx> {
     ) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> {
         let inner = tcx.thir_abstract_const_opt_const_arg(uv.def)?;
         debug!("AbstractConst::new({:?}) = {:?}", uv, inner);
-        Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs }))
+        Ok(inner.map(|inner| AbstractConst { inner, substs: tcx.erase_regions(uv.substs) }))
     }
 
     pub fn from_const(
@@ -416,6 +416,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
                     // `AbstractConst`s should not contain any promoteds as they require references which
                     // are not allowed.
                     assert_eq!(ct.promoted, None);
+                    assert_eq!(ct, self.tcx.erase_regions(ct));
                 }
             }
         }
diff --git a/src/test/ui/const-generics/try_unify_ignore_lifetimes.rs b/src/test/ui/const-generics/try_unify_ignore_lifetimes.rs
new file mode 100644
index 00000000000..2ae0ae70dd9
--- /dev/null
+++ b/src/test/ui/const-generics/try_unify_ignore_lifetimes.rs
@@ -0,0 +1,33 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Num<const N: usize>;
+
+trait NumT {
+    const VALUE: usize;
+}
+
+impl<const N: usize> NumT for Num<N> {
+    const VALUE: usize = N;
+}
+
+struct Foo<'a, N: NumT>(&'a [u32; N::VALUE]) where [(); N::VALUE]:;
+
+trait Bar {
+    type Size: NumT;
+
+    fn bar<'a>(foo: &Foo<'a, Self::Size>) where [(); Self::Size::VALUE]: {
+        todo!();
+    }
+}
+
+trait Baz<'a> {
+    type Size: NumT;
+
+    fn baz(foo: &Foo<'a, Self::Size>) where [(); Self::Size::VALUE]: {
+        todo!();
+    }
+}
+
+fn main() {}