Elaborate param_env predicates when checking if type outlives involving projection holds
This commit is contained in:
parent
e012a191d7
commit
ad57295fc9
6 changed files with 90 additions and 6 deletions
|
@ -164,7 +164,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
||||||
"cannot process registered region obligations in a snapshot"
|
"cannot process registered region obligations in a snapshot"
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!("process_registered_region_obligations()");
|
debug!(?param_env, "process_registered_region_obligations()");
|
||||||
|
|
||||||
let my_region_obligations = self.take_registered_region_obligations();
|
let my_region_obligations = self.take_registered_region_obligations();
|
||||||
|
|
||||||
|
@ -356,6 +356,8 @@ where
|
||||||
let trait_bounds: Vec<_> =
|
let trait_bounds: Vec<_> =
|
||||||
self.verify_bound.projection_declared_bounds_from_trait(projection_ty).collect();
|
self.verify_bound.projection_declared_bounds_from_trait(projection_ty).collect();
|
||||||
|
|
||||||
|
debug!(?trait_bounds);
|
||||||
|
|
||||||
// Compute the bounds we can derive from the environment. This
|
// Compute the bounds we can derive from the environment. This
|
||||||
// is an "approximate" match -- in some cases, these bounds
|
// is an "approximate" match -- in some cases, these bounds
|
||||||
// may not apply.
|
// may not apply.
|
||||||
|
|
|
@ -241,10 +241,19 @@ impl<'tcx> Elaborator<'tcx> {
|
||||||
|
|
||||||
Component::UnresolvedInferenceVariable(_) => None,
|
Component::UnresolvedInferenceVariable(_) => None,
|
||||||
|
|
||||||
Component::Projection(_) | Component::EscapingProjection(_) => {
|
Component::Projection(projection) => {
|
||||||
// We can probably do more here. This
|
// We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
|
||||||
// corresponds to a case like `<T as
|
// With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
|
||||||
// Foo<'a>>::U: 'b`.
|
let ty =
|
||||||
|
tcx.mk_projection(projection.item_def_id, projection.substs);
|
||||||
|
Some(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
|
||||||
|
ty, r_min,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
Component::EscapingProjection(_) => {
|
||||||
|
// We might be able to do more here, but we don't
|
||||||
|
// want to deal with escaping vars right now.
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -206,7 +206,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
})?);
|
})?);
|
||||||
|
|
||||||
if let ty::Projection(..) = placeholder_self_ty.kind() {
|
if let ty::Projection(..) = placeholder_self_ty.kind() {
|
||||||
for predicate in tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates {
|
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates;
|
||||||
|
debug!(?predicates, "projection predicates");
|
||||||
|
for predicate in predicates {
|
||||||
let normalized = normalize_with_depth_to(
|
let normalized = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
|
|
27
src/test/ui/generic-associated-types/issue-92096.rs
Normal file
27
src/test/ui/generic-associated-types/issue-92096.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// edition:2018
|
||||||
|
// check-fail
|
||||||
|
// FIXME(generic_associated_types): this should pass, but we end up
|
||||||
|
// essentially requiring that `for<'s> C: 's`
|
||||||
|
|
||||||
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
|
trait Client {
|
||||||
|
type Connecting<'a>: Future + Send
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
fn connect(&'_ self) -> Self::Connecting<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
|
||||||
|
//~^ ERROR the parameter
|
||||||
|
//~| ERROR the parameter
|
||||||
|
where
|
||||||
|
C: Client + Send + Sync,
|
||||||
|
{
|
||||||
|
async move { c.connect().await }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
18
src/test/ui/generic-associated-types/issue-92096.stderr
Normal file
18
src/test/ui/generic-associated-types/issue-92096.stderr
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
error[E0311]: the parameter type `C` may not live long enough
|
||||||
|
--> $DIR/issue-92096.rs:18:33
|
||||||
|
|
|
||||||
|
LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
|
||||||
|
| - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
|
||||||
|
| |
|
||||||
|
| help: consider adding an explicit lifetime bound...: `C: 'a`
|
||||||
|
|
||||||
|
error[E0311]: the parameter type `C` may not live long enough
|
||||||
|
--> $DIR/issue-92096.rs:18:33
|
||||||
|
|
|
||||||
|
LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
|
||||||
|
| - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
|
||||||
|
| |
|
||||||
|
| help: consider adding an explicit lifetime bound...: `C: 'a`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
26
src/test/ui/generic-associated-types/issue-92280.rs
Normal file
26
src/test/ui/generic-associated-types/issue-92280.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(generic_associated_types)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
|
trait HasAssoc {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Iterate<S: HasAssoc> {
|
||||||
|
type Iter<'a>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct KeySegment_Broken<T> {
|
||||||
|
key: T,
|
||||||
|
}
|
||||||
|
impl<S: HasAssoc> Iterate<S> for KeySegment_Broken<S::Assoc> {
|
||||||
|
type Iter<'a>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
= ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue