Skip to content

Commit 7820972

Browse files
committedJun 10, 2023
Auto merge of rust-lang#107637 - fmease:rustdoc-reelide-x-crate-def-tr-obj-lt-bnds, r=notriddle,cgillot,GuillaumeGomez
rustdoc: re-elide cross-crate default trait-object lifetime bounds Hide trait-object lifetime bounds (re-exported from an external crate) if they coincide with [their default](https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes). Partially addresses rust-lang#44306. Follow-up to rust-lang#103885. [Zulip discussion](https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/clean_middle_ty.3A.20I.20need.20to.20add.20a.20parameter/near/307143097). Most notably, if `std` exported something from `core` containing a type like `Box<dyn Fn()>`, then it would now be rendered as `Box<dyn Fn(), Global>` instead of `Box<dyn Fn() + 'static, Global>` (hiding `+ 'static` as it is the default in this case). Showing `Global` here is a separate issue, rust-lang#80379, which is on my agenda. Note that I am not really fond of the fact that I had to add a parameter to such a widely used function (30+ call sites) to address such a niche bug. CC `@GuillaumeGomez` Requesting a review from a compiler contributor or team member as recommended on Zulip. r? compiler --- `@rustbot` label T-compiler T-rustdoc A-cross-crate-reexports
2 parents ef8ee73 + 5b5d84f commit 7820972

File tree

8 files changed

+402
-68
lines changed

8 files changed

+402
-68
lines changed
 

‎src/librustdoc/clean/auto_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ where
124124
unsafety: hir::Unsafety::Normal,
125125
generics: new_generics,
126126
trait_: Some(clean_trait_ref_with_bindings(self.cx, trait_ref, ThinVec::new())),
127-
for_: clean_middle_ty(ty::Binder::dummy(ty), self.cx, None),
127+
for_: clean_middle_ty(ty::Binder::dummy(ty), self.cx, None, None),
128128
items: Vec::new(),
129129
polarity,
130130
kind: ImplKind::Auto,

‎src/librustdoc/clean/blanket_impl.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,12 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
107107
ty::Binder::dummy(trait_ref.subst_identity()),
108108
ThinVec::new(),
109109
)),
110-
for_: clean_middle_ty(ty::Binder::dummy(ty.subst_identity()), cx, None),
110+
for_: clean_middle_ty(
111+
ty::Binder::dummy(ty.subst_identity()),
112+
cx,
113+
None,
114+
None,
115+
),
111116
items: cx
112117
.tcx
113118
.associated_items(impl_def_id)
@@ -119,6 +124,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
119124
ty::Binder::dummy(trait_ref.subst_identity().self_ty()),
120125
cx,
121126
None,
127+
None,
122128
))),
123129
}))),
124130
cfg: None,

‎src/librustdoc/clean/inline.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,12 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
278278

279279
fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::Typedef> {
280280
let predicates = cx.tcx.explicit_predicates_of(did);
281-
let type_ =
282-
clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(did).subst_identity()), cx, Some(did));
281+
let type_ = clean_middle_ty(
282+
ty::Binder::dummy(cx.tcx.type_of(did).subst_identity()),
283+
cx,
284+
Some(did),
285+
None,
286+
);
283287

284288
Box::new(clean::Typedef {
285289
type_,
@@ -386,9 +390,12 @@ pub(crate) fn build_impl(
386390

387391
let for_ = match &impl_item {
388392
Some(impl_) => clean_ty(impl_.self_ty, cx),
389-
None => {
390-
clean_middle_ty(ty::Binder::dummy(tcx.type_of(did).subst_identity()), cx, Some(did))
391-
}
393+
None => clean_middle_ty(
394+
ty::Binder::dummy(tcx.type_of(did).subst_identity()),
395+
cx,
396+
Some(did),
397+
None,
398+
),
392399
};
393400

394401
// Only inline impl if the implementing type is
@@ -630,6 +637,7 @@ fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant {
630637
ty::Binder::dummy(cx.tcx.type_of(def_id).subst_identity()),
631638
cx,
632639
Some(def_id),
640+
None,
633641
),
634642
kind: clean::ConstantKind::Extern { def_id },
635643
}
@@ -641,6 +649,7 @@ fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::St
641649
ty::Binder::dummy(cx.tcx.type_of(did).subst_identity()),
642650
cx,
643651
Some(did),
652+
None,
644653
),
645654
mutability: if mutable { Mutability::Mut } else { Mutability::Not },
646655
expr: None,

‎src/librustdoc/clean/mod.rs

+186-26
Large diffs are not rendered by default.

‎src/librustdoc/clean/utils.rs

+27-16
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,39 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
7373

7474
pub(crate) fn substs_to_args<'tcx>(
7575
cx: &mut DocContext<'tcx>,
76-
substs: ty::Binder<'tcx, &[ty::subst::GenericArg<'tcx>]>,
76+
substs: ty::Binder<'tcx, &'tcx [ty::subst::GenericArg<'tcx>]>,
7777
mut skip_first: bool,
78+
container: Option<DefId>,
7879
) -> Vec<GenericArg> {
7980
let mut ret_val =
8081
Vec::with_capacity(substs.skip_binder().len().saturating_sub(if skip_first {
8182
1
8283
} else {
8384
0
8485
}));
85-
ret_val.extend(substs.iter().filter_map(|kind| match kind.skip_binder().unpack() {
86-
GenericArgKind::Lifetime(lt) => {
87-
Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
88-
}
89-
GenericArgKind::Type(_) if skip_first => {
90-
skip_first = false;
91-
None
92-
}
93-
GenericArgKind::Type(ty) => {
94-
Some(GenericArg::Type(clean_middle_ty(kind.rebind(ty), cx, None)))
95-
}
96-
GenericArgKind::Const(ct) => {
97-
Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx))))
86+
87+
ret_val.extend(substs.iter().enumerate().filter_map(|(index, kind)| {
88+
match kind.skip_binder().unpack() {
89+
GenericArgKind::Lifetime(lt) => {
90+
Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
91+
}
92+
GenericArgKind::Type(_) if skip_first => {
93+
skip_first = false;
94+
None
95+
}
96+
GenericArgKind::Type(ty) => Some(GenericArg::Type(clean_middle_ty(
97+
kind.rebind(ty),
98+
cx,
99+
None,
100+
container.map(|container| crate::clean::ContainerTy::Regular {
101+
ty: container,
102+
substs,
103+
arg: index,
104+
}),
105+
))),
106+
GenericArgKind::Const(ct) => {
107+
Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx))))
108+
}
98109
}
99110
}));
100111
ret_val
@@ -107,7 +118,7 @@ fn external_generic_args<'tcx>(
107118
bindings: ThinVec<TypeBinding>,
108119
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
109120
) -> GenericArgs {
110-
let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self);
121+
let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self, Some(did));
111122

112123
if cx.tcx.fn_trait_kind_from_def_id(did).is_some() {
113124
let ty = substs
@@ -118,7 +129,7 @@ fn external_generic_args<'tcx>(
118129
let inputs =
119130
// The trait's first substitution is the one after self, if there is one.
120131
match ty.skip_binder().kind() {
121-
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None)).collect::<Vec<_>>().into(),
132+
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None, None)).collect::<Vec<_>>().into(),
122133
_ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
123134
};
124135
let output = bindings.into_iter().next().and_then(|binding| match binding.kind {

‎tests/rustdoc/assoc-consts.rs

-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ pub fn f(_: &(ToString + 'static)) {}
4646
impl Bar {
4747
// @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \
4848
// "const F: fn(_: &(dyn ToString + 'static))"
49-
// FIXME(fmease): Hide default lifetime, render "const F: fn(_: &dyn ToString)"
5049
pub const F: fn(_: &(ToString + 'static)) = f;
5150
}
5251

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore-tidy-linelength
2+
13
pub type Ty0 = dyn for<'any> FnOnce(&'any str) -> bool;
24

35
pub type Ty1<'obj> = dyn std::fmt::Display + 'obj;
@@ -6,12 +8,60 @@ pub type Ty2 = dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>;
68

79
pub type Ty3<'s> = &'s dyn ToString;
810

9-
pub fn func0(_: &(dyn Fn() + '_)) {}
10-
11-
pub fn func1<'func>(_: &(dyn Fn() + 'func)) {}
12-
1311
pub trait Container<'r> {
1412
type Item<'a, 'ctx>;
1513
}
1614

17-
pub trait Shape<'a> {}
15+
// Trait-object types inside of a container type that has lifetime bounds ("wrapped").
16+
17+
pub fn late_bound_wrapped_elided(_: &(dyn Fn() + '_)) {}
18+
pub fn late_bound_wrapped_late0<'f>(_: &mut (dyn Fn() + 'f)) {}
19+
pub fn late_bound_wrapped_defaulted0<'f>(_: &'f mut dyn Fn()) {}
20+
pub type EarlyBoundWrappedDefaulted0<'x> = std::cell::Ref<'x, dyn Trait>;
21+
pub type EarlyBoundWrappedDefaulted1<'x> = &'x dyn Trait;
22+
pub type EarlyBoundWrappedEarly<'x, 'y> = std::cell::Ref<'x, dyn Trait + 'y>;
23+
pub type EarlyBoundWrappedStatic<'x> = std::cell::Ref<'x, dyn Trait + 'static>;
24+
pub fn late_bound_wrapped_defaulted1<'l>(_: std::cell::Ref<'l, dyn Trait>) {}
25+
pub fn late_bound_wrapped_late1<'l, 'm>(_: std::cell::Ref<'l, dyn Trait + 'm>) {}
26+
pub fn late_bound_wrapped_early<'e, 'l>(_: std::cell::Ref<'l, dyn Trait + 'e>) where 'e: {} // `'e` is early-bound
27+
pub fn elided_bound_wrapped_defaulted(_: std::cell::Ref<'_, dyn Trait>) {}
28+
pub type StaticBoundWrappedDefaulted0 = std::cell::Ref<'static, dyn Trait>;
29+
pub type StaticBoundWrappedDefaulted1 = &'static dyn Trait;
30+
pub type AmbiguousBoundWrappedEarly0<'r, 's> = AmbiguousBoundWrapper<'s, 'r, dyn Trait + 's>;
31+
pub type AmbiguousBoundWrappedEarly1<'r, 's> = AmbiguousBoundWrapper<'s, 'r, dyn Trait + 'r>;
32+
pub type AmbiguousBoundWrappedStatic<'q> = AmbiguousBoundWrapper<'q, 'q, dyn Trait + 'static>;
33+
34+
// Trait-object types inside of a container type that doesn't have lifetime bounds ("wrapped").
35+
36+
pub type NoBoundsWrappedDefaulted = Box<dyn Trait>;
37+
pub type NoBoundsWrappedEarly<'e> = Box<dyn Trait + 'e>;
38+
pub fn no_bounds_wrapped_late<'l>(_: Box<dyn Trait + 'l>) {}
39+
pub fn no_bounds_wrapped_elided(_: Box<dyn Trait + '_>) {}
40+
41+
// Trait-object types outside of a container (“bare”).
42+
43+
pub type BareNoBoundsDefaulted = dyn Trait;
44+
pub type BareNoBoundsEarly<'p> = dyn Trait + 'p;
45+
pub type BareEarlyBoundDefaulted0<'u> = dyn EarlyBoundTrait0<'u>;
46+
pub type BareEarlyBoundDefaulted1 = dyn for<'any> EarlyBoundTrait0<'any>;
47+
pub type BareEarlyBoundDefaulted2<'w> = dyn EarlyBoundTrait1<'static, 'w>;
48+
pub type BareEarlyBoundEarly<'i, 'j> = dyn EarlyBoundTrait0<'i> + 'j;
49+
pub type BareEarlyBoundStatic<'i> = dyn EarlyBoundTrait0<'i> + 'static;
50+
pub type BareStaticBoundDefaulted = dyn StaticBoundTrait;
51+
pub type BareHigherRankedBoundDefaulted0 = dyn HigherRankedBoundTrait0;
52+
pub type BareHigherRankedBoundDefaulted1<'r> = dyn HigherRankedBoundTrait1<'r>;
53+
pub type BareAmbiguousBoundEarly0<'m, 'n> = dyn AmbiguousBoundTrait<'m, 'n> + 'm;
54+
pub type BareAmbiguousBoundEarly1<'m, 'n> = dyn AmbiguousBoundTrait<'m, 'n> + 'n;
55+
pub type BareAmbiguousBoundStatic<'o> = dyn AmbiguousBoundTrait<'o, 'o> + 'static;
56+
57+
// Trait and container definitions.
58+
59+
pub trait Trait {} // no bounds
60+
pub trait EarlyBoundTrait0<'b>: 'b {}
61+
pub trait EarlyBoundTrait1<'unused, 'c>: 'c {}
62+
pub trait StaticBoundTrait: 'static {}
63+
pub trait HigherRankedBoundTrait0 where for<'a> Self: 'a {}
64+
pub trait HigherRankedBoundTrait1<'e> where for<'l> Self: 'e + 'l {}
65+
pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {}
66+
67+
pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T);
+112-13
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,130 @@
11
#![crate_name = "user"]
22

3+
// In each test case, we include the trailing semicolon to ensure that nothing extra comes
4+
// after the type like an unwanted outlives-bound.
5+
36
// aux-crate:dyn_trait=dyn_trait.rs
47
// edition:2021
58

69
// @has user/type.Ty0.html
7-
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool + 'static"
8-
// FIXME(fmease): Hide default lifetime bound `'static`
10+
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool;"
911
pub use dyn_trait::Ty0;
1012

1113
// @has user/type.Ty1.html
12-
// @has - '//*[@class="rust item-decl"]//code' "dyn Display + 'obj"
14+
// @has - '//*[@class="rust item-decl"]//code' "dyn Display + 'obj;"
1315
pub use dyn_trait::Ty1;
1416

1517
// @has user/type.Ty2.html
16-
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>"
18+
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>;"
1719
pub use dyn_trait::Ty2;
1820

1921
// @has user/type.Ty3.html
20-
// @has - '//*[@class="rust item-decl"]//code' "&'s (dyn ToString + 's)"
21-
// FIXME(fmease): Hide default lifetime bound, render "&'s dyn ToString"
22+
// @has - '//*[@class="rust item-decl"]//code' "&'s dyn ToString;"
2223
pub use dyn_trait::Ty3;
2324

24-
// @has user/fn.func0.html
25-
// @has - '//pre[@class="rust item-decl"]' "func0(_: &dyn Fn())"
26-
// FIXME(fmease): Show placeholder-lifetime bound, render "func0(_: &(dyn Fn() + '_))"
27-
pub use dyn_trait::func0;
25+
// Below we check if we correctly elide trait-object lifetime bounds if they coincide with their
26+
// default (known as "object lifetime default" or "default trait object lifetime").
27+
28+
// @has user/fn.lbwel.html
29+
// @has - '//pre[@class="rust item-decl"]' "lbwel(_: &dyn Fn())"
30+
pub use dyn_trait::late_bound_wrapped_elided as lbwel;
31+
// @has user/fn.lbwl0.html
32+
// has - '//pre[@class="rust item-decl"]' "lbwl0<'f>(_: &mut (dyn Fn() + 'f))"
33+
pub use dyn_trait::late_bound_wrapped_late0 as lbwl0;
34+
// @has user/fn.lbwd0.html
35+
// has - '//pre[@class="rust item-decl"]' "lbwd0<'f>(_: &'f mut dyn Fn())"
36+
pub use dyn_trait::late_bound_wrapped_defaulted0 as lbwd0;
37+
// @has user/type.EarlyBoundWrappedDefaulted0.html
38+
// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait>;"
39+
pub use dyn_trait::EarlyBoundWrappedDefaulted0;
40+
// @has user/type.EarlyBoundWrappedDefaulted1.html
41+
// @has - '//*[@class="rust item-decl"]//code' "&'x dyn Trait;"
42+
pub use dyn_trait::EarlyBoundWrappedDefaulted1;
43+
// @has user/type.EarlyBoundWrappedEarly.html
44+
// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait + 'y>"
45+
pub use dyn_trait::EarlyBoundWrappedEarly;
46+
// @has user/type.EarlyBoundWrappedStatic.html
47+
// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait + 'static>"
48+
pub use dyn_trait::EarlyBoundWrappedStatic;
49+
// @has user/fn.lbwd1.html
50+
// @has - '//pre[@class="rust item-decl"]' "lbwd1<'l>(_: Ref<'l, dyn Trait>)"
51+
pub use dyn_trait::late_bound_wrapped_defaulted1 as lbwd1;
52+
// @has user/fn.lbwl1.html
53+
// @has - '//pre[@class="rust item-decl"]' "lbwl1<'l, 'm>(_: Ref<'l, dyn Trait + 'm>)"
54+
pub use dyn_trait::late_bound_wrapped_late1 as lbwl1;
55+
// @has user/fn.lbwe.html
56+
// @has - '//pre[@class="rust item-decl"]' "lbwe<'e, 'l>(_: Ref<'l, dyn Trait + 'e>)"
57+
pub use dyn_trait::late_bound_wrapped_early as lbwe;
58+
// @has user/fn.ebwd.html
59+
// @has - '//pre[@class="rust item-decl"]' "ebwd(_: Ref<'_, dyn Trait>)"
60+
pub use dyn_trait::elided_bound_wrapped_defaulted as ebwd;
61+
// @has user/type.StaticBoundWrappedDefaulted0.html
62+
// @has - '//*[@class="rust item-decl"]//code' "Ref<'static, dyn Trait>;"
63+
pub use dyn_trait::StaticBoundWrappedDefaulted0;
64+
// @has user/type.StaticBoundWrappedDefaulted1.html
65+
// @has - '//*[@class="rust item-decl"]//code' "&'static dyn Trait;"
66+
pub use dyn_trait::StaticBoundWrappedDefaulted1;
67+
// @has user/type.AmbiguousBoundWrappedEarly0.html
68+
// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'s, 'r, dyn Trait + 's>;"
69+
pub use dyn_trait::AmbiguousBoundWrappedEarly0;
70+
// @has user/type.AmbiguousBoundWrappedEarly1.html
71+
// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'s, 'r, dyn Trait + 'r>;"
72+
pub use dyn_trait::AmbiguousBoundWrappedEarly1;
73+
// @has user/type.AmbiguousBoundWrappedStatic.html
74+
// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'q, 'q, dyn Trait + 'static>;"
75+
pub use dyn_trait::AmbiguousBoundWrappedStatic;
76+
77+
// @has user/type.NoBoundsWrappedDefaulted.html
78+
// @has - '//*[@class="rust item-decl"]//code' "Box<dyn Trait, Global>;"
79+
pub use dyn_trait::NoBoundsWrappedDefaulted;
80+
// @has user/type.NoBoundsWrappedEarly.html
81+
// @has - '//*[@class="rust item-decl"]//code' "Box<dyn Trait + 'e, Global>;"
82+
pub use dyn_trait::NoBoundsWrappedEarly;
83+
// @has user/fn.nbwl.html
84+
// @has - '//pre[@class="rust item-decl"]' "nbwl<'l>(_: Box<dyn Trait + 'l, Global>)"
85+
pub use dyn_trait::no_bounds_wrapped_late as nbwl;
86+
// @has user/fn.nbwel.html
87+
// @has - '//pre[@class="rust item-decl"]' "nbwel(_: Box<dyn Trait + '_, Global>)"
88+
// NB: It might seem counterintuitive to display the explicitly elided lifetime `'_` here instead of
89+
// eliding it but this behavior is correct: The default is `'static` here which != `'_`.
90+
pub use dyn_trait::no_bounds_wrapped_elided as nbwel;
2891

29-
// @has user/fn.func1.html
30-
// @has - '//pre[@class="rust item-decl"]' "func1<'func>(_: &(dyn Fn() + 'func))"
31-
pub use dyn_trait::func1;
92+
// @has user/type.BareNoBoundsDefaulted.html
93+
// @has - '//*[@class="rust item-decl"]//code' "dyn Trait;"
94+
pub use dyn_trait::BareNoBoundsDefaulted;
95+
// @has user/type.BareNoBoundsEarly.html
96+
// @has - '//*[@class="rust item-decl"]//code' "dyn Trait + 'p;"
97+
pub use dyn_trait::BareNoBoundsEarly;
98+
// @has user/type.BareEarlyBoundDefaulted0.html
99+
// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'u>;"
100+
pub use dyn_trait::BareEarlyBoundDefaulted0;
101+
// @has user/type.BareEarlyBoundDefaulted1.html
102+
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> EarlyBoundTrait0<'any>;"
103+
pub use dyn_trait::BareEarlyBoundDefaulted1;
104+
// @has user/type.BareEarlyBoundDefaulted2.html
105+
// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait1<'static, 'w>;"
106+
pub use dyn_trait::BareEarlyBoundDefaulted2;
107+
// @has user/type.BareEarlyBoundEarly.html
108+
// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'i> + 'j;"
109+
pub use dyn_trait::BareEarlyBoundEarly;
110+
// @has user/type.BareEarlyBoundStatic.html
111+
// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'i> + 'static;"
112+
pub use dyn_trait::BareEarlyBoundStatic;
113+
// @has user/type.BareStaticBoundDefaulted.html
114+
// @has - '//*[@class="rust item-decl"]//code' "dyn StaticBoundTrait;"
115+
pub use dyn_trait::BareStaticBoundDefaulted;
116+
// @has user/type.BareHigherRankedBoundDefaulted0.html
117+
// @has - '//*[@class="rust item-decl"]//code' "dyn HigherRankedBoundTrait0;"
118+
pub use dyn_trait::BareHigherRankedBoundDefaulted0;
119+
// @has user/type.BareHigherRankedBoundDefaulted1.html
120+
// @has - '//*[@class="rust item-decl"]//code' "dyn HigherRankedBoundTrait1<'r>;"
121+
pub use dyn_trait::BareHigherRankedBoundDefaulted1;
122+
// @has user/type.BareAmbiguousBoundEarly0.html
123+
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'m, 'n> + 'm;"
124+
pub use dyn_trait::BareAmbiguousBoundEarly0;
125+
// @has user/type.BareAmbiguousBoundEarly1.html
126+
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'m, 'n> + 'n;"
127+
pub use dyn_trait::BareAmbiguousBoundEarly1;
128+
// @has user/type.BareAmbiguousBoundStatic.html
129+
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;"
130+
pub use dyn_trait::BareAmbiguousBoundStatic;

0 commit comments

Comments
 (0)
Please sign in to comment.