about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-11-21 20:16:36 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-11-21 20:16:36 +0000
commitca57832db636fedeeb529a1cc1feab0befef2ab0 (patch)
treee14e400a20af862b72e6565b3e9c1f6f5e3eeb1c
parent7fe6f36224e92db6fbde952e0b7e50863161f6ee (diff)
downloadrust-ca57832db636fedeeb529a1cc1feab0befef2ab0.tar.gz
rust-ca57832db636fedeeb529a1cc1feab0befef2ab0.zip
Add more regression tests
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs12
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs38
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/self_implication.rs38
5 files changed, 123 insertions, 6 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index b35abbd107b..90e2b6b698c 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1705,6 +1705,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         });
     }
 
+    #[instrument(level = "debug", skip(self, infcx, errors_buffer))]
     fn check_member_constraints(
         &self,
         infcx: &InferCtxt<'tcx>,
@@ -1712,22 +1713,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) {
         let member_constraints = self.member_constraints.clone();
         for m_c_i in member_constraints.all_indices() {
-            debug!("check_member_constraint(m_c_i={:?})", m_c_i);
+            debug!(?m_c_i);
             let m_c = &member_constraints[m_c_i];
             let member_region_vid = m_c.member_region_vid;
             debug!(
-                "check_member_constraint: member_region_vid={:?} with value {}",
-                member_region_vid,
-                self.region_value_str(member_region_vid),
+                ?member_region_vid,
+                value = ?self.region_value_str(member_region_vid),
             );
             let choice_regions = member_constraints.choice_regions(m_c_i);
-            debug!("check_member_constraint: choice_regions={:?}", choice_regions);
+            debug!(?choice_regions);
 
             // Did the member region wind up equal to any of the option regions?
             if let Some(o) =
                 choice_regions.iter().find(|&&o_r| self.eval_equal(o_r, m_c.member_region_vid))
             {
-                debug!("check_member_constraint: evaluated as equal to {:?}", o);
+                debug!("evaluated as equal to {:?}", o);
                 continue;
             }
 
diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
new file mode 100644
index 00000000000..ee9bce15d34
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait Callable {
+    type Output;
+    fn call() -> Self::Output;
+}
+
+impl<'a> Callable for &'a () {
+    type Output = impl Sized;
+    fn call() -> Self::Output {}
+}
+
+fn test<'a>() -> impl Sized {
+    <&'a () as Callable>::call()
+}
+
+fn want_static<T: 'static>(_: T) {}
+
+fn test2<'a>() {
+    want_static(<&'a () as Callable>::call());
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs
new file mode 100644
index 00000000000..ae21a9134a4
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs
@@ -0,0 +1,38 @@
+#![feature(type_alias_impl_trait)]
+
+trait Callable {
+    type Output;
+    fn call(x: Self) -> Self::Output;
+}
+
+trait PlusOne {
+    fn plus_one(&mut self);
+}
+
+impl<'a> PlusOne for &'a mut i32 {
+    fn plus_one(&mut self) {
+        **self += 1;
+    }
+}
+
+impl<T: PlusOne> Callable for T {
+    type Output = impl PlusOne;
+    fn call(t: T) -> Self::Output { t }
+}
+
+fn test<'a>(y: &'a mut i32) -> impl PlusOne {
+    <&'a mut i32 as Callable>::call(y)
+    //~^ ERROR hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
+}
+
+fn main() {
+    let mut z = 42;
+    let mut thing = test(&mut z);
+    let mut thing2 = test(&mut z);
+    thing.plus_one();
+    assert_eq!(z, 43);
+    thing2.plus_one();
+    assert_eq!(z, 44);
+    thing.plus_one();
+    assert_eq!(z, 45);
+}
diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr
new file mode 100644
index 00000000000..0ed8a703b6d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr
@@ -0,0 +1,16 @@
+error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
+  --> $DIR/imply_bounds_from_bounds_param.rs:24:5
+   |
+LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne {
+   |         -- hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here
+LL |     <&'a mut i32 as Callable>::call(y)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound
+   |
+LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a {
+   |                                             ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/type-alias-impl-trait/self_implication.rs b/src/test/ui/type-alias-impl-trait/self_implication.rs
new file mode 100644
index 00000000000..4e805ee308f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self_implication.rs
@@ -0,0 +1,38 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+fn foo() {
+    struct Foo<'a> {
+        x: &'a mut u8,
+    }
+    impl<'a> Foo<'a> {
+        fn foo(&self) -> impl Sized {}
+    }
+    // use site
+    let mut x = 5;
+    let y = Foo { x: &mut x };
+    let z = y.foo();
+    let _a = &x; // invalidate the `&'a mut`in `y`
+    let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live
+}
+
+fn bar() {
+    struct Foo<'a> {
+        x: &'a mut u8,
+    }
+
+    // desugared
+    type FooX<'a> = impl Sized;
+    impl<'a> Foo<'a> {
+        fn foo(&self) -> FooX<'a> {}
+    }
+
+    // use site
+    let mut x = 5;
+    let y = Foo { x: &mut x };
+    let z = y.foo();
+    let _a = &x; // invalidate the `&'a mut`in `y`
+    let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live
+}
+
+fn main() {}