Skip to content

Commit 9835b90

Browse files
authored
Rollup merge of #92710 - jackh726:issue-92280, r=nikomatsakis
Include Projections when elaborating TypeOutlives Fixes #92280 In `Elaborator`, we elaborate that `Foo<<Bar as Baz>::Assoc>: 'a` -> `<Bar as Baz>::Assoc: 'a`. This is the same rule that would be applied to any other `Param`. If there are escaping vars, we continue to do nothing. r? `@nikomatsakis`
2 parents 039d6dc + ea562ae commit 9835b90

File tree

6 files changed

+92
-6
lines changed

6 files changed

+92
-6
lines changed

compiler/rustc_infer/src/infer/outlives/obligations.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
164164
"cannot process registered region obligations in a snapshot"
165165
);
166166

167-
debug!("process_registered_region_obligations()");
167+
debug!(?param_env, "process_registered_region_obligations()");
168168

169169
let my_region_obligations = self.take_registered_region_obligations();
170170

@@ -356,6 +356,8 @@ where
356356
let trait_bounds: Vec<_> =
357357
self.verify_bound.projection_declared_bounds_from_trait(projection_ty).collect();
358358

359+
debug!(?trait_bounds);
360+
359361
// Compute the bounds we can derive from the environment. This
360362
// is an "approximate" match -- in some cases, these bounds
361363
// may not apply.

compiler/rustc_infer/src/traits/util.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,19 @@ impl<'tcx> Elaborator<'tcx> {
241241

242242
Component::UnresolvedInferenceVariable(_) => None,
243243

244-
Component::Projection(_) | Component::EscapingProjection(_) => {
245-
// We can probably do more here. This
246-
// corresponds to a case like `<T as
247-
// Foo<'a>>::U: 'b`.
244+
Component::Projection(projection) => {
245+
// We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
246+
// With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
247+
let ty =
248+
tcx.mk_projection(projection.item_def_id, projection.substs);
249+
Some(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
250+
ty, r_min,
251+
)))
252+
}
253+
254+
Component::EscapingProjection(_) => {
255+
// We might be able to do more here, but we don't
256+
// want to deal with escaping vars right now.
248257
None
249258
}
250259
})

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
206206
})?);
207207

208208
if let ty::Projection(..) = placeholder_self_ty.kind() {
209-
for predicate in tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates {
209+
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates;
210+
debug!(?predicates, "projection predicates");
211+
for predicate in predicates {
210212
let normalized = normalize_with_depth_to(
211213
self,
212214
obligation.param_env,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0311]: the parameter type `C` may not live long enough
2+
--> $DIR/issue-92096.rs:20:33
3+
|
4+
LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
5+
| - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
6+
| |
7+
| help: consider adding an explicit lifetime bound...: `C: 'a`
8+
9+
error[E0311]: the parameter type `C` may not live long enough
10+
--> $DIR/issue-92096.rs:20:33
11+
|
12+
LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
13+
| - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
14+
| |
15+
| help: consider adding an explicit lifetime bound...: `C: 'a`
16+
17+
error: aborting due to 2 previous errors
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// edition:2018
2+
// [nll] check-pass
3+
// revisions: migrate nll
4+
// Explicitly testing nll with revision, so ignore compare-mode=nll
5+
// ignore-compare-mode-nll
6+
7+
#![cfg_attr(nll, feature(nll))]
8+
#![feature(generic_associated_types)]
9+
10+
use std::future::Future;
11+
12+
trait Client {
13+
type Connecting<'a>: Future + Send
14+
where
15+
Self: 'a;
16+
17+
fn connect(&'_ self) -> Self::Connecting<'_>;
18+
}
19+
20+
fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
21+
//[migrate]~^ ERROR the parameter
22+
//[migrate]~| ERROR the parameter
23+
where
24+
C: Client + Send + Sync,
25+
{
26+
async move { c.connect().await }
27+
}
28+
29+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// check-pass
2+
3+
#![feature(generic_associated_types)]
4+
#![allow(non_camel_case_types)]
5+
6+
trait HasAssoc {
7+
type Assoc;
8+
}
9+
10+
trait Iterate<S: HasAssoc> {
11+
type Iter<'a>
12+
where
13+
Self: 'a;
14+
}
15+
16+
struct KeySegment_Broken<T> {
17+
key: T,
18+
}
19+
impl<S: HasAssoc> Iterate<S> for KeySegment_Broken<S::Assoc> {
20+
type Iter<'a>
21+
where
22+
Self: 'a,
23+
= ();
24+
}
25+
26+
fn main() {}

0 commit comments

Comments
 (0)