Auto merge of #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 #44306. Follow-up to #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, #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
This commit is contained in:
commit
7820972f86
8 changed files with 402 additions and 68 deletions
|
|
@ -46,7 +46,6 @@ pub fn f(_: &(ToString + 'static)) {}
|
|||
impl Bar {
|
||||
// @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \
|
||||
// "const F: fn(_: &(dyn ToString + 'static))"
|
||||
// FIXME(fmease): Hide default lifetime, render "const F: fn(_: &dyn ToString)"
|
||||
pub const F: fn(_: &(ToString + 'static)) = f;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// ignore-tidy-linelength
|
||||
|
||||
pub type Ty0 = dyn for<'any> FnOnce(&'any str) -> bool;
|
||||
|
||||
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> = ()>;
|
|||
|
||||
pub type Ty3<'s> = &'s dyn ToString;
|
||||
|
||||
pub fn func0(_: &(dyn Fn() + '_)) {}
|
||||
|
||||
pub fn func1<'func>(_: &(dyn Fn() + 'func)) {}
|
||||
|
||||
pub trait Container<'r> {
|
||||
type Item<'a, 'ctx>;
|
||||
}
|
||||
|
||||
pub trait Shape<'a> {}
|
||||
// Trait-object types inside of a container type that has lifetime bounds ("wrapped").
|
||||
|
||||
pub fn late_bound_wrapped_elided(_: &(dyn Fn() + '_)) {}
|
||||
pub fn late_bound_wrapped_late0<'f>(_: &mut (dyn Fn() + 'f)) {}
|
||||
pub fn late_bound_wrapped_defaulted0<'f>(_: &'f mut dyn Fn()) {}
|
||||
pub type EarlyBoundWrappedDefaulted0<'x> = std::cell::Ref<'x, dyn Trait>;
|
||||
pub type EarlyBoundWrappedDefaulted1<'x> = &'x dyn Trait;
|
||||
pub type EarlyBoundWrappedEarly<'x, 'y> = std::cell::Ref<'x, dyn Trait + 'y>;
|
||||
pub type EarlyBoundWrappedStatic<'x> = std::cell::Ref<'x, dyn Trait + 'static>;
|
||||
pub fn late_bound_wrapped_defaulted1<'l>(_: std::cell::Ref<'l, dyn Trait>) {}
|
||||
pub fn late_bound_wrapped_late1<'l, 'm>(_: std::cell::Ref<'l, dyn Trait + 'm>) {}
|
||||
pub fn late_bound_wrapped_early<'e, 'l>(_: std::cell::Ref<'l, dyn Trait + 'e>) where 'e: {} // `'e` is early-bound
|
||||
pub fn elided_bound_wrapped_defaulted(_: std::cell::Ref<'_, dyn Trait>) {}
|
||||
pub type StaticBoundWrappedDefaulted0 = std::cell::Ref<'static, dyn Trait>;
|
||||
pub type StaticBoundWrappedDefaulted1 = &'static dyn Trait;
|
||||
pub type AmbiguousBoundWrappedEarly0<'r, 's> = AmbiguousBoundWrapper<'s, 'r, dyn Trait + 's>;
|
||||
pub type AmbiguousBoundWrappedEarly1<'r, 's> = AmbiguousBoundWrapper<'s, 'r, dyn Trait + 'r>;
|
||||
pub type AmbiguousBoundWrappedStatic<'q> = AmbiguousBoundWrapper<'q, 'q, dyn Trait + 'static>;
|
||||
|
||||
// Trait-object types inside of a container type that doesn't have lifetime bounds ("wrapped").
|
||||
|
||||
pub type NoBoundsWrappedDefaulted = Box<dyn Trait>;
|
||||
pub type NoBoundsWrappedEarly<'e> = Box<dyn Trait + 'e>;
|
||||
pub fn no_bounds_wrapped_late<'l>(_: Box<dyn Trait + 'l>) {}
|
||||
pub fn no_bounds_wrapped_elided(_: Box<dyn Trait + '_>) {}
|
||||
|
||||
// Trait-object types outside of a container (“bare”).
|
||||
|
||||
pub type BareNoBoundsDefaulted = dyn Trait;
|
||||
pub type BareNoBoundsEarly<'p> = dyn Trait + 'p;
|
||||
pub type BareEarlyBoundDefaulted0<'u> = dyn EarlyBoundTrait0<'u>;
|
||||
pub type BareEarlyBoundDefaulted1 = dyn for<'any> EarlyBoundTrait0<'any>;
|
||||
pub type BareEarlyBoundDefaulted2<'w> = dyn EarlyBoundTrait1<'static, 'w>;
|
||||
pub type BareEarlyBoundEarly<'i, 'j> = dyn EarlyBoundTrait0<'i> + 'j;
|
||||
pub type BareEarlyBoundStatic<'i> = dyn EarlyBoundTrait0<'i> + 'static;
|
||||
pub type BareStaticBoundDefaulted = dyn StaticBoundTrait;
|
||||
pub type BareHigherRankedBoundDefaulted0 = dyn HigherRankedBoundTrait0;
|
||||
pub type BareHigherRankedBoundDefaulted1<'r> = dyn HigherRankedBoundTrait1<'r>;
|
||||
pub type BareAmbiguousBoundEarly0<'m, 'n> = dyn AmbiguousBoundTrait<'m, 'n> + 'm;
|
||||
pub type BareAmbiguousBoundEarly1<'m, 'n> = dyn AmbiguousBoundTrait<'m, 'n> + 'n;
|
||||
pub type BareAmbiguousBoundStatic<'o> = dyn AmbiguousBoundTrait<'o, 'o> + 'static;
|
||||
|
||||
// Trait and container definitions.
|
||||
|
||||
pub trait Trait {} // no bounds
|
||||
pub trait EarlyBoundTrait0<'b>: 'b {}
|
||||
pub trait EarlyBoundTrait1<'unused, 'c>: 'c {}
|
||||
pub trait StaticBoundTrait: 'static {}
|
||||
pub trait HigherRankedBoundTrait0 where for<'a> Self: 'a {}
|
||||
pub trait HigherRankedBoundTrait1<'e> where for<'l> Self: 'e + 'l {}
|
||||
pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {}
|
||||
|
||||
pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T);
|
||||
|
|
|
|||
|
|
@ -1,31 +1,130 @@
|
|||
#![crate_name = "user"]
|
||||
|
||||
// In each test case, we include the trailing semicolon to ensure that nothing extra comes
|
||||
// after the type like an unwanted outlives-bound.
|
||||
|
||||
// aux-crate:dyn_trait=dyn_trait.rs
|
||||
// edition:2021
|
||||
|
||||
// @has user/type.Ty0.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool + 'static"
|
||||
// FIXME(fmease): Hide default lifetime bound `'static`
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool;"
|
||||
pub use dyn_trait::Ty0;
|
||||
|
||||
// @has user/type.Ty1.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn Display + 'obj"
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn Display + 'obj;"
|
||||
pub use dyn_trait::Ty1;
|
||||
|
||||
// @has user/type.Ty2.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>"
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>;"
|
||||
pub use dyn_trait::Ty2;
|
||||
|
||||
// @has user/type.Ty3.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "&'s (dyn ToString + 's)"
|
||||
// FIXME(fmease): Hide default lifetime bound, render "&'s dyn ToString"
|
||||
// @has - '//*[@class="rust item-decl"]//code' "&'s dyn ToString;"
|
||||
pub use dyn_trait::Ty3;
|
||||
|
||||
// @has user/fn.func0.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "func0(_: &dyn Fn())"
|
||||
// FIXME(fmease): Show placeholder-lifetime bound, render "func0(_: &(dyn Fn() + '_))"
|
||||
pub use dyn_trait::func0;
|
||||
// Below we check if we correctly elide trait-object lifetime bounds if they coincide with their
|
||||
// default (known as "object lifetime default" or "default trait object lifetime").
|
||||
|
||||
// @has user/fn.func1.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "func1<'func>(_: &(dyn Fn() + 'func))"
|
||||
pub use dyn_trait::func1;
|
||||
// @has user/fn.lbwel.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "lbwel(_: &dyn Fn())"
|
||||
pub use dyn_trait::late_bound_wrapped_elided as lbwel;
|
||||
// @has user/fn.lbwl0.html
|
||||
// has - '//pre[@class="rust item-decl"]' "lbwl0<'f>(_: &mut (dyn Fn() + 'f))"
|
||||
pub use dyn_trait::late_bound_wrapped_late0 as lbwl0;
|
||||
// @has user/fn.lbwd0.html
|
||||
// has - '//pre[@class="rust item-decl"]' "lbwd0<'f>(_: &'f mut dyn Fn())"
|
||||
pub use dyn_trait::late_bound_wrapped_defaulted0 as lbwd0;
|
||||
// @has user/type.EarlyBoundWrappedDefaulted0.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait>;"
|
||||
pub use dyn_trait::EarlyBoundWrappedDefaulted0;
|
||||
// @has user/type.EarlyBoundWrappedDefaulted1.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "&'x dyn Trait;"
|
||||
pub use dyn_trait::EarlyBoundWrappedDefaulted1;
|
||||
// @has user/type.EarlyBoundWrappedEarly.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait + 'y>"
|
||||
pub use dyn_trait::EarlyBoundWrappedEarly;
|
||||
// @has user/type.EarlyBoundWrappedStatic.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait + 'static>"
|
||||
pub use dyn_trait::EarlyBoundWrappedStatic;
|
||||
// @has user/fn.lbwd1.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "lbwd1<'l>(_: Ref<'l, dyn Trait>)"
|
||||
pub use dyn_trait::late_bound_wrapped_defaulted1 as lbwd1;
|
||||
// @has user/fn.lbwl1.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "lbwl1<'l, 'm>(_: Ref<'l, dyn Trait + 'm>)"
|
||||
pub use dyn_trait::late_bound_wrapped_late1 as lbwl1;
|
||||
// @has user/fn.lbwe.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "lbwe<'e, 'l>(_: Ref<'l, dyn Trait + 'e>)"
|
||||
pub use dyn_trait::late_bound_wrapped_early as lbwe;
|
||||
// @has user/fn.ebwd.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "ebwd(_: Ref<'_, dyn Trait>)"
|
||||
pub use dyn_trait::elided_bound_wrapped_defaulted as ebwd;
|
||||
// @has user/type.StaticBoundWrappedDefaulted0.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "Ref<'static, dyn Trait>;"
|
||||
pub use dyn_trait::StaticBoundWrappedDefaulted0;
|
||||
// @has user/type.StaticBoundWrappedDefaulted1.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "&'static dyn Trait;"
|
||||
pub use dyn_trait::StaticBoundWrappedDefaulted1;
|
||||
// @has user/type.AmbiguousBoundWrappedEarly0.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'s, 'r, dyn Trait + 's>;"
|
||||
pub use dyn_trait::AmbiguousBoundWrappedEarly0;
|
||||
// @has user/type.AmbiguousBoundWrappedEarly1.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'s, 'r, dyn Trait + 'r>;"
|
||||
pub use dyn_trait::AmbiguousBoundWrappedEarly1;
|
||||
// @has user/type.AmbiguousBoundWrappedStatic.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'q, 'q, dyn Trait + 'static>;"
|
||||
pub use dyn_trait::AmbiguousBoundWrappedStatic;
|
||||
|
||||
// @has user/type.NoBoundsWrappedDefaulted.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "Box<dyn Trait, Global>;"
|
||||
pub use dyn_trait::NoBoundsWrappedDefaulted;
|
||||
// @has user/type.NoBoundsWrappedEarly.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "Box<dyn Trait + 'e, Global>;"
|
||||
pub use dyn_trait::NoBoundsWrappedEarly;
|
||||
// @has user/fn.nbwl.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "nbwl<'l>(_: Box<dyn Trait + 'l, Global>)"
|
||||
pub use dyn_trait::no_bounds_wrapped_late as nbwl;
|
||||
// @has user/fn.nbwel.html
|
||||
// @has - '//pre[@class="rust item-decl"]' "nbwel(_: Box<dyn Trait + '_, Global>)"
|
||||
// NB: It might seem counterintuitive to display the explicitly elided lifetime `'_` here instead of
|
||||
// eliding it but this behavior is correct: The default is `'static` here which != `'_`.
|
||||
pub use dyn_trait::no_bounds_wrapped_elided as nbwel;
|
||||
|
||||
// @has user/type.BareNoBoundsDefaulted.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn Trait;"
|
||||
pub use dyn_trait::BareNoBoundsDefaulted;
|
||||
// @has user/type.BareNoBoundsEarly.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn Trait + 'p;"
|
||||
pub use dyn_trait::BareNoBoundsEarly;
|
||||
// @has user/type.BareEarlyBoundDefaulted0.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'u>;"
|
||||
pub use dyn_trait::BareEarlyBoundDefaulted0;
|
||||
// @has user/type.BareEarlyBoundDefaulted1.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> EarlyBoundTrait0<'any>;"
|
||||
pub use dyn_trait::BareEarlyBoundDefaulted1;
|
||||
// @has user/type.BareEarlyBoundDefaulted2.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait1<'static, 'w>;"
|
||||
pub use dyn_trait::BareEarlyBoundDefaulted2;
|
||||
// @has user/type.BareEarlyBoundEarly.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'i> + 'j;"
|
||||
pub use dyn_trait::BareEarlyBoundEarly;
|
||||
// @has user/type.BareEarlyBoundStatic.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'i> + 'static;"
|
||||
pub use dyn_trait::BareEarlyBoundStatic;
|
||||
// @has user/type.BareStaticBoundDefaulted.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn StaticBoundTrait;"
|
||||
pub use dyn_trait::BareStaticBoundDefaulted;
|
||||
// @has user/type.BareHigherRankedBoundDefaulted0.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn HigherRankedBoundTrait0;"
|
||||
pub use dyn_trait::BareHigherRankedBoundDefaulted0;
|
||||
// @has user/type.BareHigherRankedBoundDefaulted1.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn HigherRankedBoundTrait1<'r>;"
|
||||
pub use dyn_trait::BareHigherRankedBoundDefaulted1;
|
||||
// @has user/type.BareAmbiguousBoundEarly0.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'m, 'n> + 'm;"
|
||||
pub use dyn_trait::BareAmbiguousBoundEarly0;
|
||||
// @has user/type.BareAmbiguousBoundEarly1.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'m, 'n> + 'n;"
|
||||
pub use dyn_trait::BareAmbiguousBoundEarly1;
|
||||
// @has user/type.BareAmbiguousBoundStatic.html
|
||||
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;"
|
||||
pub use dyn_trait::BareAmbiguousBoundStatic;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue