about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-11-24 22:39:19 +0000
committerMichael Goulet <michael@errs.io>2024-11-24 23:11:49 +0000
commit15dff274d07621283b38e4ca0008f7e6145c2519 (patch)
tree390791cd81c4980eeecd34185fae56c58db72bdc
parent15b663e684d0acf1b4299b7ad6b4f4ab106395bd (diff)
downloadrust-15dff274d07621283b38e4ca0008f7e6145c2519.tar.gz
rust-15dff274d07621283b38e4ca0008f7e6145c2519.zip
Actually use placeholder regions for trait method late bound regions in collect_return_position_impl_trait_in_trait_tys
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs12
-rw-r--r--tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.rs30
-rw-r--r--tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.stderr22
-rw-r--r--tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr8
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr4
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr15
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.rs2
-rw-r--r--tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr7
8 files changed, 77 insertions, 23 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index f86ca95a954..dd106255890 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -523,8 +523,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     let impl_sig = ocx.normalize(
         &misc_cause,
         param_env,
-        tcx.liberate_late_bound_regions(
-            impl_m.def_id,
+        infcx.instantiate_binder_with_fresh_vars(
+            return_span,
+            infer::HigherRankedType,
             tcx.fn_sig(impl_m.def_id).instantiate_identity(),
         ),
     );
@@ -536,10 +537,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     // them with inference variables.
     // We will use these inference variables to collect the hidden types of RPITITs.
     let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_def_id);
-    let unnormalized_trait_sig = infcx
-        .instantiate_binder_with_fresh_vars(
-            return_span,
-            infer::HigherRankedType,
+    let unnormalized_trait_sig = tcx
+        .liberate_late_bound_regions(
+            impl_m.def_id,
             tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args),
         )
         .fold_with(&mut collector);
diff --git a/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.rs b/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.rs
new file mode 100644
index 00000000000..30ca3d271b8
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.rs
@@ -0,0 +1,30 @@
+// Make sure that we don't accidentally collect an RPITIT hidden type that does not
+// hold for all instantiations of the trait signature.
+
+trait MkStatic {
+    fn mk_static(self) -> &'static str;
+}
+
+impl MkStatic for &'static str {
+    fn mk_static(self) -> &'static str { self }
+}
+
+trait Foo {
+    fn foo<'a: 'static, 'late>(&'late self) -> impl MkStatic;
+}
+
+impl Foo for str {
+    fn foo<'a: 'static>(&'a self) -> impl MkStatic + 'static {
+    //~^ ERROR method not compatible with trait
+        self
+    }
+}
+
+fn call_foo<T: Foo + ?Sized>(t: &T) -> &'static str {
+    t.foo().mk_static()
+}
+
+fn main() {
+    let s = call_foo(String::from("hello, world").as_str());
+    println!("> {s}");
+}
diff --git a/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.stderr b/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.stderr
new file mode 100644
index 00000000000..95d8699e19f
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.stderr
@@ -0,0 +1,22 @@
+error[E0308]: method not compatible with trait
+  --> $DIR/do-not-imply-from-trait-impl.rs:17:38
+   |
+LL |     fn foo<'a: 'static>(&'a self) -> impl MkStatic + 'static {
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
+   |
+   = note: expected signature `fn(&'late _) -> _`
+              found signature `fn(&'a _) -> _`
+note: the lifetime `'late` as defined here...
+  --> $DIR/do-not-imply-from-trait-impl.rs:13:25
+   |
+LL |     fn foo<'a: 'static, 'late>(&'late self) -> impl MkStatic;
+   |                         ^^^^^
+note: ...does not necessarily outlive the lifetime `'a` as defined here
+  --> $DIR/do-not-imply-from-trait-impl.rs:17:12
+   |
+LL |     fn foo<'a: 'static>(&'a self) -> impl MkStatic + 'static {
+   |            ^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
index 6f6b787b6fe..a23879eb6c3 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
@@ -11,12 +11,12 @@ note: type in trait
    |
 LL |     fn early<'early, T>(x: &'early T) -> impl Sized;
    |                            ^^^^^^^^^
-   = note: expected signature `fn(&T)`
-              found signature `fn(&'late ())`
+   = note: expected signature `fn(&'early T)`
+              found signature `fn(&())`
 help: change the parameter type to match the trait
    |
-LL |     fn early<'late, T>(_: &T) {}
-   |                           ~~
+LL |     fn early<'late, T>(_: &'early T) {}
+   |                           ~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
index 3430055dab1..4c10422f985 100644
--- a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
@@ -6,9 +6,9 @@ LL |     fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
    |
    = note: the pointer is valid for the static lifetime
 note: but the referenced data is only valid for the anonymous lifetime defined here
-  --> $DIR/rpitit-hidden-types-self-implied-wf.rs:6:18
+  --> $DIR/rpitit-hidden-types-self-implied-wf.rs:2:18
    |
-LL |     fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+LL |     fn extend(_: &str) -> (impl Sized + '_, &'static str);
    |                  ^^^^
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr
index 56b83cbca77..b27d7870955 100644
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr
@@ -1,14 +1,15 @@
-error[E0623]: lifetime mismatch
+error[E0477]: the type `impl Future<Output = Vec<u8>>` does not fulfill the required lifetime
   --> $DIR/signature-mismatch.rs:77:10
    |
-LL |         &'a self,
-   |         -------- this parameter and the return type are declared with different lifetimes...
-...
 LL |     ) -> impl Future<Output = Vec<u8>> {
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |          |
-   |          ...but data from `buff` is returned here
+   |
+note: type must outlive the lifetime `'a` as defined here as required by this binding
+  --> $DIR/signature-mismatch.rs:73:32
+   |
+LL |     fn async_fn_reduce_outlive<'a, 'b, T>(
+   |                                ^^
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0623`.
+For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.rs b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
index 55b9a0de5ff..a9885c6a298 100644
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.rs
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
@@ -75,7 +75,7 @@ impl AsyncTrait for Struct {
         buff: &'b [u8],
         t: T,
     ) -> impl Future<Output = Vec<u8>> {
-        //[failure]~^ ERROR lifetime mismatch
+        //[failure]~^ ERROR the type `impl Future<Output = Vec<u8>>` does not fulfill the required lifetime
         async move {
             let _t = t;
             vec![]
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr b/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr
index e1856b92910..360f0d7e7f3 100644
--- a/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr
+++ b/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr
@@ -1,10 +1,11 @@
 error: return type captures more lifetimes than trait definition
   --> $DIR/rpitit-impl-captures-too-much.rs:10:39
    |
+LL |     fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>;
+   |                               -- this lifetime was captured
+...
 LL |     fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {}
-   |                               --      ^^^^^^^^^^^^^^^^^^^^
-   |                               |
-   |                               this lifetime was captured
+   |                                       ^^^^^^^^^^^^^^^^^^^^
    |
 note: hidden type must only reference lifetimes captured by this impl trait
   --> $DIR/rpitit-impl-captures-too-much.rs:6:39