-
Notifications
You must be signed in to change notification settings - Fork 13.4k
rustdoc: fix cross-crate impl Sized
& impl ?Sized
#114059
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -835,7 +835,6 @@ fn clean_ty_generics<'tcx>( | |
.into_iter() | ||
.flatten() | ||
.cloned() | ||
.filter(|b| !b.is_sized_bound(cx)), | ||
); | ||
|
||
if let Some(proj) = projection | ||
|
@@ -862,8 +861,27 @@ fn clean_ty_generics<'tcx>( | |
.collect::<Vec<_>>(); | ||
|
||
for (param, mut bounds) in impl_trait { | ||
let mut has_sized = false; | ||
bounds.retain(|b| { | ||
if b.is_sized_bound(cx) { | ||
has_sized = true; | ||
Comment on lines
+866
to
+867
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at this, I don't think it handles Edit: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That answers the question then. ;) |
||
false | ||
} else { | ||
true | ||
} | ||
}); | ||
if !has_sized { | ||
bounds.push(GenericBound::maybe_sized(cx)); | ||
} | ||
|
||
// Move trait bounds to the front. | ||
bounds.sort_by_key(|b| !matches!(b, GenericBound::TraitBound(..))); | ||
bounds.sort_by_key(|b| !b.is_trait_bound()); | ||
|
||
// Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`). | ||
// Since all potential trait bounds are at the front we can just check the first bound. | ||
if bounds.first().map_or(true, |b| !b.is_trait_bound()) { | ||
bounds.insert(0, GenericBound::sized(cx)); | ||
} | ||
|
||
let crate::core::ImplTraitParam::ParamIndex(idx) = param else { unreachable!() }; | ||
if let Some(proj) = impl_trait_proj.remove(&idx) { | ||
|
@@ -2107,7 +2125,6 @@ fn clean_middle_opaque_bounds<'tcx>( | |
cx: &mut DocContext<'tcx>, | ||
bounds: Vec<ty::Clause<'tcx>>, | ||
) -> Type { | ||
let mut regions = vec![]; | ||
let mut has_sized = false; | ||
let mut bounds = bounds | ||
.iter() | ||
|
@@ -2116,10 +2133,7 @@ fn clean_middle_opaque_bounds<'tcx>( | |
let trait_ref = match bound_predicate.skip_binder() { | ||
ty::ClauseKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref), | ||
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => { | ||
if let Some(r) = clean_middle_region(reg) { | ||
regions.push(GenericBound::Outlives(r)); | ||
} | ||
return None; | ||
return clean_middle_region(reg).map(GenericBound::Outlives); | ||
} | ||
_ => return None, | ||
}; | ||
|
@@ -2155,10 +2169,20 @@ fn clean_middle_opaque_bounds<'tcx>( | |
Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, bindings)) | ||
}) | ||
.collect::<Vec<_>>(); | ||
bounds.extend(regions); | ||
if !has_sized && !bounds.is_empty() { | ||
bounds.insert(0, GenericBound::maybe_sized(cx)); | ||
|
||
if !has_sized { | ||
bounds.push(GenericBound::maybe_sized(cx)); | ||
} | ||
|
||
// Move trait bounds to the front. | ||
bounds.sort_by_key(|b| !b.is_trait_bound()); | ||
|
||
// Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`). | ||
// Since all potential trait bounds are at the front we can just check the first bound. | ||
if bounds.first().map_or(true, |b| !b.is_trait_bound()) { | ||
bounds.insert(0, GenericBound::sized(cx)); | ||
} | ||
|
||
ImplTrait(bounds) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use std::fmt::Debug; | ||
|
||
pub fn sized(x: impl Sized) -> impl Sized { | ||
x | ||
} | ||
|
||
pub fn sized_outlives<'a>(x: impl Sized + 'a) -> impl Sized + 'a { | ||
x | ||
} | ||
|
||
pub fn maybe_sized(x: &impl ?Sized) -> &impl ?Sized { | ||
x | ||
} | ||
|
||
pub fn debug_maybe_sized(x: &(impl Debug + ?Sized)) -> &(impl Debug + ?Sized) { | ||
x | ||
} | ||
|
||
pub fn maybe_sized_outlives<'t>(x: &(impl ?Sized + 't)) -> &(impl ?Sized + 't) { | ||
x | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#![crate_name = "user"] | ||
|
||
// aux-crate:impl_sized=impl-sized.rs | ||
// edition:2021 | ||
|
||
// @has user/fn.sized.html | ||
// @has - '//pre[@class="rust item-decl"]' "sized(x: impl Sized) -> impl Sized" | ||
pub use impl_sized::sized; | ||
|
||
// @has user/fn.sized_outlives.html | ||
// @has - '//pre[@class="rust item-decl"]' \ | ||
// "sized_outlives<'a>(x: impl Sized + 'a) -> impl Sized + 'a" | ||
pub use impl_sized::sized_outlives; | ||
|
||
// @has user/fn.maybe_sized.html | ||
// @has - '//pre[@class="rust item-decl"]' "maybe_sized(x: &impl ?Sized) -> &impl ?Sized" | ||
pub use impl_sized::maybe_sized; | ||
|
||
// @has user/fn.debug_maybe_sized.html | ||
// @has - '//pre[@class="rust item-decl"]' \ | ||
// "debug_maybe_sized(x: &(impl Debug + ?Sized)) -> &(impl Debug + ?Sized)" | ||
pub use impl_sized::debug_maybe_sized; | ||
|
||
// @has user/fn.maybe_sized_outlives.html | ||
// @has - '//pre[@class="rust item-decl"]' \ | ||
// "maybe_sized_outlives<'t>(x: &(impl ?Sized + 't)) -> &(impl ?Sized + 't)" | ||
pub use impl_sized::maybe_sized_outlives; |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This further enlarges the preexisting bound cleaning duplication of
clean_ty_generics
andclean_middle_opaque_bounds
. Let me know if this is okay for the time being, I plan on consolidating these implementations when I overhaul bound cleaning next to fix #113015.