1
Fork 0

Actually use placeholder regions for trait method late bound regions in collect_return_position_impl_trait_in_trait_tys

This commit is contained in:
Michael Goulet 2024-11-24 22:39:19 +00:00
parent 15b663e684
commit 15dff274d0
8 changed files with 77 additions and 23 deletions

View file

@ -523,8 +523,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let impl_sig = ocx.normalize( let impl_sig = ocx.normalize(
&misc_cause, &misc_cause,
param_env, param_env,
tcx.liberate_late_bound_regions( infcx.instantiate_binder_with_fresh_vars(
impl_m.def_id, return_span,
infer::HigherRankedType,
tcx.fn_sig(impl_m.def_id).instantiate_identity(), 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. // them with inference variables.
// We will use these inference variables to collect the hidden types of RPITITs. // 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 mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_def_id);
let unnormalized_trait_sig = infcx let unnormalized_trait_sig = tcx
.instantiate_binder_with_fresh_vars( .liberate_late_bound_regions(
return_span, impl_m.def_id,
infer::HigherRankedType,
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args), tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args),
) )
.fold_with(&mut collector); .fold_with(&mut collector);

View file

@ -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}");
}

View file

@ -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`.

View file

@ -11,12 +11,12 @@ note: type in trait
| |
LL | fn early<'early, T>(x: &'early T) -> impl Sized; LL | fn early<'early, T>(x: &'early T) -> impl Sized;
| ^^^^^^^^^ | ^^^^^^^^^
= note: expected signature `fn(&T)` = note: expected signature `fn(&'early T)`
found signature `fn(&'late ())` found signature `fn(&())`
help: change the parameter type to match the trait 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 error: aborting due to 1 previous error

View file

@ -6,9 +6,9 @@ LL | fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
| |
= note: the pointer is valid for the static lifetime = note: the pointer is valid for the static lifetime
note: but the referenced data is only valid for the anonymous lifetime defined here 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 error: aborting due to 1 previous error

View file

@ -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 --> $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>> { 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 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`.

View file

@ -75,7 +75,7 @@ impl AsyncTrait for Struct {
buff: &'b [u8], buff: &'b [u8],
t: T, t: T,
) -> impl Future<Output = Vec<u8>> { ) -> 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 { async move {
let _t = t; let _t = t;
vec![] vec![]

View file

@ -1,10 +1,11 @@
error: return type captures more lifetimes than trait definition error: return type captures more lifetimes than trait definition
--> $DIR/rpitit-impl-captures-too-much.rs:10:39 --> $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<'_> {} LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {}
| -- ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
| this lifetime was captured
| |
note: hidden type must only reference lifetimes captured by this impl trait note: hidden type must only reference lifetimes captured by this impl trait
--> $DIR/rpitit-impl-captures-too-much.rs:6:39 --> $DIR/rpitit-impl-captures-too-much.rs:6:39