Skip to content

Commit ea99593

Browse files
committed
Auto merge of #115722 - Mark-Simulacrum:beta-backport, r=Mark-Simulacrum
[beta] backport This PR backports: - #115559: implied bounds: do not ICE on unconstrained region vars - #115446: fix version for abi_thiscall to 1.73.0, which was forgotten to change when stabilized and (later) moved to beta - #115276: rustdoc: correctly deal with self ty params when eliding default object lifetimes r? `@Mark-Simulacrum`
2 parents 9f37cd4 + 309468c commit ea99593

File tree

8 files changed

+111
-18
lines changed

8 files changed

+111
-18
lines changed

compiler/rustc_feature/src/accepted.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ declare_features! (
5454
/// instead of just the platforms on which it is the C ABI.
5555
(accepted, abi_sysv64, "1.24.0", Some(36167), None),
5656
/// Allows using the `thiscall` ABI.
57-
(accepted, abi_thiscall, "1.19.0", None, None),
57+
(accepted, abi_thiscall, "1.73.0", None, None),
5858
/// Allows using ADX intrinsics from `core::arch::{x86, x86_64}`.
5959
(accepted, adx_target_feature, "1.61.0", Some(44839), None),
6060
/// Allows explicit discriminants on non-unit enum variants.

compiler/rustc_trait_selection/src/traits/outlives_bounds.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,12 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
5757
let ty = OpportunisticRegionResolver::new(self).fold_ty(ty);
5858

5959
// We do not expect existential variables in implied bounds.
60-
// We may however encounter unconstrained lifetime variables in invalid
61-
// code. See #110161 for context.
60+
// We may however encounter unconstrained lifetime variables
61+
// in very rare cases.
62+
//
63+
// See `ui/implied-bounds/implied-bounds-unconstrained-2.rs` for
64+
// an example.
6265
assert!(!ty.has_non_region_infer());
63-
if ty.has_infer() {
64-
self.tcx.sess.delay_span_bug(
65-
self.tcx.def_span(body_id),
66-
"skipped implied_outlives_bounds due to unconstrained lifetimes",
67-
);
68-
return vec![];
69-
}
7066

7167
let mut canonical_var_values = OriginalQueryValues::default();
7268
let canonical_ty =

src/librustdoc/clean/mod.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -1959,31 +1959,44 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
19591959
#[derive(Debug)]
19601960
pub(crate) enum ContainerTy<'tcx> {
19611961
Ref(ty::Region<'tcx>),
1962-
Regular { ty: DefId, args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, arg: usize },
1962+
Regular {
1963+
ty: DefId,
1964+
args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
1965+
has_self: bool,
1966+
arg: usize,
1967+
},
19631968
}
19641969

19651970
impl<'tcx> ContainerTy<'tcx> {
19661971
fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> {
19671972
match self {
19681973
Self::Ref(region) => ObjectLifetimeDefault::Arg(region),
1969-
Self::Regular { ty: container, args, arg: index } => {
1974+
Self::Regular { ty: container, args, has_self, arg: index } => {
19701975
let (DefKind::Struct
19711976
| DefKind::Union
19721977
| DefKind::Enum
19731978
| DefKind::TyAlias { .. }
1974-
| DefKind::Trait
1975-
| DefKind::AssocTy
1976-
| DefKind::Variant) = tcx.def_kind(container)
1979+
| DefKind::Trait) = tcx.def_kind(container)
19771980
else {
19781981
return ObjectLifetimeDefault::Empty;
19791982
};
19801983

19811984
let generics = tcx.generics_of(container);
1982-
let param = generics.params[index].def_id;
1983-
let default = tcx.object_lifetime_default(param);
1985+
debug_assert_eq!(generics.parent_count, 0);
1986+
1987+
// If the container is a trait object type, the arguments won't contain the self type but the
1988+
// generics of the corresponding trait will. In such a case, offset the index by one.
1989+
// For comparison, if the container is a trait inside a bound, the arguments do contain the
1990+
// self type.
1991+
let offset =
1992+
if !has_self && generics.parent.is_none() && generics.has_self { 1 } else { 0 };
1993+
let param = generics.params[index + offset].def_id;
19841994

1995+
let default = tcx.object_lifetime_default(param);
19851996
match default {
19861997
rbv::ObjectLifetimeDefault::Param(lifetime) => {
1998+
// The index is relative to the parent generics but since we don't have any,
1999+
// we don't need to translate it.
19872000
let index = generics.param_def_id_to_index[&lifetime];
19882001
let arg = args.skip_binder()[index as usize].expect_region();
19892002
ObjectLifetimeDefault::Arg(arg)

src/librustdoc/clean/utils.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,10 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
7777
pub(crate) fn ty_args_to_args<'tcx>(
7878
cx: &mut DocContext<'tcx>,
7979
args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
80-
mut skip_first: bool,
80+
has_self: bool,
8181
container: Option<DefId>,
8282
) -> Vec<GenericArg> {
83+
let mut skip_first = has_self;
8384
let mut ret_val =
8485
Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 }));
8586

@@ -99,6 +100,7 @@ pub(crate) fn ty_args_to_args<'tcx>(
99100
container.map(|container| crate::clean::ContainerTy::Regular {
100101
ty: container,
101102
args,
103+
has_self,
102104
arg: index,
103105
}),
104106
))),

tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs

+19
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,22 @@ pub trait HigherRankedBoundTrait1<'e> where for<'l> Self: 'e + 'l {}
6565
pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {}
6666

6767
pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T);
68+
69+
// Trait objects inside of another trait object, a trait bound or an associated type.
70+
71+
pub trait Inner {}
72+
pub trait Outer<T: ?Sized> {}
73+
pub trait Base {
74+
type Type<T: ?Sized>;
75+
}
76+
impl Base for () {
77+
type Type<T: ?Sized> = ();
78+
}
79+
80+
pub type NestedTraitObjects = dyn Outer<dyn Inner>;
81+
82+
pub fn apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner> {
83+
o
84+
}
85+
86+
pub type AssocTy = <() as Base>::Type<dyn Inner>;

tests/rustdoc/inline_cross/dyn_trait.rs

+15
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,18 @@ pub use dyn_trait::BareAmbiguousBoundEarly1;
128128
// @has user/type.BareAmbiguousBoundStatic.html
129129
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;"
130130
pub use dyn_trait::BareAmbiguousBoundStatic;
131+
132+
// Regression test for issue #115179:
133+
134+
// @has user/type.NestedTraitObjects.html
135+
// @has - '//*[@class="rust item-decl"]//code' "dyn Outer<dyn Inner>;"
136+
pub use dyn_trait::NestedTraitObjects;
137+
138+
// @has user/fn.apit_rpit.html
139+
// @has - '//pre[@class="rust item-decl"]' \
140+
// "apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner>"
141+
pub use dyn_trait::apit_rpit;
142+
143+
// @has user/type.AssocTy.html
144+
// @has - '//*[@class="rust item-decl"]//code' "<() as Base>::Type<dyn Inner>"
145+
pub use dyn_trait::AssocTy;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// check-pass
2+
3+
// Regression test for #112832.
4+
pub trait QueryDb {
5+
type Db;
6+
}
7+
8+
pub struct QueryTable<Q, DB> {
9+
db: DB,
10+
storage: Q,
11+
}
12+
13+
// We normalize `<Q as QueryDb>::Db` to `<Q as AsyncQueryFunction<'d>>::SendDb`
14+
// using the where-bound. 'd is an unconstrained region variable which previously
15+
// triggered an assert.
16+
impl<Q> QueryTable<Q, <Q as QueryDb>::Db> where Q: for<'d> AsyncQueryFunction<'d> {}
17+
18+
pub trait AsyncQueryFunction<'d>: QueryDb<Db = <Self as AsyncQueryFunction<'d>>::SendDb> {
19+
type SendDb: 'd;
20+
}
21+
22+
pub trait QueryStorageOpsAsync<Q>
23+
where
24+
Q: for<'d> AsyncQueryFunction<'d>,
25+
{
26+
}
27+
28+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// check-pass
2+
3+
// Another minimized regression test for #112832.
4+
trait Trait {
5+
type Assoc;
6+
}
7+
8+
trait Sub<'a>: Trait<Assoc = <Self as Sub<'a>>::SubAssoc> {
9+
type SubAssoc;
10+
}
11+
12+
// By using the where-clause we normalize `<T as Trait>::Assoc` to
13+
// `<T as Sub<'a>>::SubAssoc` where `'a` is an unconstrained region
14+
// variable.
15+
fn foo<T>(x: <T as Trait>::Assoc)
16+
where
17+
for<'a> T: Sub<'a>,
18+
{}
19+
20+
fn main() {}

0 commit comments

Comments
 (0)