1
Fork 0

Don't elaborate !Sized to !Sized + Sized

This commit is contained in:
León Orell Valerian Liehr 2023-12-27 23:04:12 +01:00
parent a251974015
commit 32cea61c86
No known key found for this signature in database
GPG key ID: D17A07215F68E713

View file

@ -26,23 +26,36 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
span: Span, span: Span,
) { ) {
let tcx = self.tcx(); let tcx = self.tcx();
let sized_def_id = tcx.lang_items().sized_trait();
let mut seen_negative_sized_bound = false;
// Try to find an unbound in bounds. // Try to find an unbound in bounds.
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| { let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
for ab in ast_bounds { for ab in ast_bounds {
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab { let hir::GenericBound::Trait(ptr, modifier) = ab else {
unbounds.push(ptr) continue;
};
match modifier {
hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
hir::TraitBoundModifier::Negative => {
if let Some(sized_def_id) = sized_def_id
&& ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
{
seen_negative_sized_bound = true;
}
}
_ => {}
} }
} }
}; };
search_bounds(ast_bounds); search_bounds(ast_bounds);
if let Some((self_ty, where_clause)) = self_ty_where_predicates { if let Some((self_ty, where_clause)) = self_ty_where_predicates {
for clause in where_clause { for clause in where_clause {
if let hir::WherePredicate::BoundPredicate(pred) = clause { if let hir::WherePredicate::BoundPredicate(pred) = clause
if pred.is_param_bound(self_ty.to_def_id()) { && pred.is_param_bound(self_ty.to_def_id())
search_bounds(pred.bounds); {
} search_bounds(pred.bounds);
} }
} }
} }
@ -53,15 +66,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}); });
} }
let sized_def_id = tcx.lang_items().sized_trait();
let mut seen_sized_unbound = false; let mut seen_sized_unbound = false;
for unbound in unbounds { for unbound in unbounds {
if let Some(sized_def_id) = sized_def_id { if let Some(sized_def_id) = sized_def_id
if unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) { && unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
seen_sized_unbound = true; {
continue; seen_sized_unbound = true;
} continue;
} }
// There was a `?Trait` bound, but it was not `?Sized`; warn. // There was a `?Trait` bound, but it was not `?Sized`; warn.
tcx.dcx().span_warn( tcx.dcx().span_warn(
@ -71,15 +82,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
); );
} }
// If the above loop finished there was no `?Sized` bound; add implicitly sized if `Sized` is available. if seen_sized_unbound || seen_negative_sized_bound {
if sized_def_id.is_none() { // There was in fact a `?Sized` or `!Sized` bound;
// No lang item for `Sized`, so we can't add it as a bound. // we don't need to do anything.
return; } else if sized_def_id.is_some() {
} // There was no `?Sized` or `!Sized` bound;
if seen_sized_unbound { // add `Sized` if it's available.
// There was in fact a `?Sized` bound, return without doing anything
} else {
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
bounds.push_sized(tcx, self_ty, span); bounds.push_sized(tcx, self_ty, span);
} }
} }