summaryrefslogtreecommitdiffstats
path: root/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs')
-rw-r--r--src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs b/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
new file mode 100644
index 000000000..d9de73a38
--- /dev/null
+++ b/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
@@ -0,0 +1,51 @@
+// A test exploiting the bug behind #25860 except with
+// implied trait bounds which currently don't exist without `-Zchalk`.
+use std::marker::PhantomData;
+struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>)
+where
+ T: Convert<'a, 'b>;
+
+trait Convert<'a, 'b>: Sized {
+ fn cast(&'a self) -> &'b Self;
+}
+impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
+ fn cast(&'long self) -> &'short T {
+ self
+ }
+}
+
+// This function will compile once we add implied trait bounds.
+//
+// If we're not careful with our impl, the transformations
+// in `bad` would succeed, which is unsound ✨
+//
+// FIXME: the error is pretty bad, this should say
+//
+// `T: Convert<'in_, 'out>` is not implemented
+//
+// help: needed by `Foo<'in_, 'out, T>`
+//
+// Please ping @lcnr if your changes end up causing `badboi` to compile.
+fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
+ //~^ ERROR lifetime mismatch
+ sadness.cast()
+}
+
+fn bad<'short, T>(value: &'short T) -> &'static T {
+ let x: for<'in_, 'out> fn(Foo<'in_, 'out, T>, &'in_ T) -> &'out T = badboi;
+ let x: for<'out> fn(Foo<'short, 'out, T>, &'short T) -> &'out T = x;
+ let x: for<'out> fn(Foo<'static, 'out, T>, &'short T) -> &'out T = x;
+ let x: fn(Foo<'static, 'static, T>, &'short T) -> &'static T = x;
+ x(Foo(PhantomData), value)
+}
+
+// Use `bad` to cause a segfault.
+fn main() {
+ let mut outer: Option<&'static u32> = Some(&3);
+ let static_ref: &'static &'static u32 = match outer {
+ Some(ref reference) => bad(reference),
+ None => unreachable!(),
+ };
+ outer = None;
+ println!("{}", static_ref);
+}