Skip to content

Commit 9b14abc

Browse files
committed
Auto merge of rust-lang#129543 - fmease:obj-lt-def-gat, r=<try>
[WIP] Properly deduce object lifetime defaults in projections & trait refs FIXME: Proper explainer (several things fall out of this PR) Fixes rust-lang#115379. r? ghost
2 parents d6c1e45 + 514c364 commit 9b14abc

12 files changed

+318
-152
lines changed

Diff for: compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+208-133
Large diffs are not rendered by default.

Diff for: compiler/rustc_metadata/src/rmeta/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14761476
if let Some(name) = tcx.intrinsic(def_id) {
14771477
record!(self.tables.intrinsic[def_id] <- name);
14781478
}
1479-
if let DefKind::TyParam = def_kind {
1479+
if let DefKind::TyParam | DefKind::Trait = def_kind {
14801480
let default = self.tcx.object_lifetime_default(def_id);
14811481
record!(self.tables.object_lifetime_default[def_id] <- default);
14821482
}

Diff for: compiler/rustc_passes/src/check_attr.rs

+12-14
Original file line numberDiff line numberDiff line change
@@ -703,20 +703,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
703703
/// Debugging aid for `object_lifetime_default` query.
704704
fn check_object_lifetime_default(&self, hir_id: HirId) {
705705
let tcx = self.tcx;
706-
if let Some(owner_id) = hir_id.as_owner()
707-
&& let Some(generics) = tcx.hir_get_generics(owner_id.def_id)
708-
{
709-
for p in generics.params {
710-
let hir::GenericParamKind::Type { .. } = p.kind else { continue };
711-
let default = tcx.object_lifetime_default(p.def_id);
712-
let repr = match default {
713-
ObjectLifetimeDefault::Empty => "BaseDefault".to_owned(),
714-
ObjectLifetimeDefault::Static => "'static".to_owned(),
715-
ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(),
716-
ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(),
717-
};
718-
tcx.dcx().emit_err(errors::ObjectLifetimeErr { span: p.span, repr });
719-
}
706+
let Some(owner_id) = hir_id.as_owner() else { return };
707+
for param in &tcx.generics_of(owner_id.def_id).own_params {
708+
let ty::GenericParamDefKind::Type { .. } = param.kind else { continue };
709+
let default = tcx.object_lifetime_default(param.def_id);
710+
let repr = match default {
711+
ObjectLifetimeDefault::Empty => "Empty".to_owned(),
712+
ObjectLifetimeDefault::Static => "'static".to_owned(),
713+
ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(),
714+
ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(),
715+
};
716+
tcx.dcx()
717+
.emit_err(errors::ObjectLifetimeErr { span: tcx.def_span(param.def_id), repr });
720718
}
721719
}
722720

Diff for: src/librustdoc/clean/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1994,6 +1994,8 @@ impl<'tcx> ContainerTy<'_, 'tcx> {
19941994
match self {
19951995
Self::Ref(region) => ObjectLifetimeDefault::Arg(region),
19961996
Self::Regular { ty: container, args, arg: index } => {
1997+
// FIXME: Update this to handle AssocTys.
1998+
19971999
let (DefKind::Struct
19982000
| DefKind::Union
19992001
| DefKind::Enum
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// FIXME: Explainer.
2+
//@ check-pass
3+
4+
trait Outer { type Ty; }
5+
trait Inner {}
6+
7+
impl<'a> Outer for dyn Inner + 'a { type Ty = &'a (); }
8+
9+
fn f<'r>(x: &'r <dyn Inner as Outer>::Ty) { g(x) }
10+
fn g<'r>(x: &'r <dyn Inner + 'static as Outer>::Ty) {}
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// FIXME: Explainer
2+
//@ check-pass
3+
4+
// FIXME: Test both bound and where-clause form
5+
// trait Outer<'a> where Self: 'a { type Ty; }
6+
trait Outer<'a>: 'a { type Ty; }
7+
trait Inner {}
8+
9+
impl<'a> Outer<'a> for dyn Inner + 'a { type Ty = &'a (); }
10+
11+
fn f<'r>(x: <dyn Inner + 'r as Outer<'r>>::Ty) { g(x) }
12+
fn g<'r>(x: <dyn Inner as Outer<'r>>::Ty) {}
13+
14+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Properly deduce the object lifetime default in generic associated type (GAT) *paths*.
2+
// issue: <https://github.com/rust-lang/rust/issues/115379>
3+
//@ check-pass
4+
5+
mod own { // the object lifetime default comes from the own generics
6+
trait Outer {
7+
type Ty<'a, T: ?Sized + 'a>;
8+
}
9+
impl Outer for () {
10+
type Ty<'a, T: ?Sized + 'a> = &'a T;
11+
}
12+
trait Inner {}
13+
14+
fn f<'r>(x: <() as Outer>::Ty<'r, dyn Inner + 'r>) { g(x) }
15+
fn g<'r>(_: <() as Outer>::Ty<'r, dyn Inner>) {}
16+
}
17+
18+
mod parent { // the object lifetime default comes from the parent generics
19+
trait Outer<'a> {
20+
type Ty<T: ?Sized + 'a>;
21+
}
22+
impl<'a> Outer<'a> for () {
23+
type Ty<T: ?Sized + 'a> = &'a T;
24+
}
25+
trait Inner {}
26+
27+
fn f<'r>(x: <() as Outer<'r>>::Ty<dyn Inner + 'r>) { g(x) }
28+
fn g<'r>(_: <() as Outer<'r>>::Ty<dyn Inner>) {}
29+
}
30+
31+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// FIXME: Explainer
2+
3+
trait Outer { type Ty<'a, T: 'a + ?Sized>; }
4+
trait Inner {}
5+
6+
fn f<'r, T: Outer>(x: T::Ty<'r, dyn Inner>) {}
7+
//~^ ERROR lifetime bound for this object type cannot be deduced from context
8+
9+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
2+
--> $DIR/object-lifetime-default-gat-type-relative.rs:6:33
3+
|
4+
LL | fn f<'r, T: Outer>(x: T::Ty<'r, dyn Inner>) {}
5+
| ^^^^^^^^^
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0228`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// FIXME: Explainer (used to fail: "inderminate" due to an off by one :^))
2+
//@ check-pass
3+
4+
trait Inner {}
5+
trait Outer<'a, T: 'a + ?Sized> {}
6+
7+
fn bound0<'r, T>() where T: Outer<'r, dyn Inner + 'r> { bound1::<'r, T>() }
8+
fn bound1<'r, T>() where T: Outer<'r, dyn Inner> {}
9+
10+
fn dyn0<'r>(x: Box<dyn Outer<'r, dyn Inner + 'r>>) { dyn1(x) }
11+
fn dyn1<'r>(_: Box<dyn Outer<'r, dyn Inner>>) {}
12+
13+
fn impl0<'r>(x: impl Outer<'r, dyn Inner + 'r>) { impl1(x) }
14+
fn impl1<'r>(_: impl Outer<'r, dyn Inner>) {}
15+
16+
fn main() {}

Diff for: tests/ui/object-lifetime/object-lifetime-default.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
#[rustc_object_lifetime_default]
44
struct A<
5-
T, //~ ERROR BaseDefault
5+
T, //~ ERROR Empty
66
>(T);
77

88
#[rustc_object_lifetime_default]
99
struct B<
1010
'a,
11-
T, //~ ERROR BaseDefault
11+
T, //~ ERROR Empty
1212
>(&'a (), T);
1313

1414
#[rustc_object_lifetime_default]

Diff for: tests/ui/object-lifetime/object-lifetime-default.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: BaseDefault
1+
error: Empty
22
--> $DIR/object-lifetime-default.rs:5:5
33
|
44
LL | T,
55
| ^
66

7-
error: BaseDefault
7+
error: Empty
88
--> $DIR/object-lifetime-default.rs:11:5
99
|
1010
LL | T,

0 commit comments

Comments
 (0)