Skip to content

Commit 32cea61

Browse files
committed
Don't elaborate !Sized to !Sized + Sized
1 parent a251974 commit 32cea61

File tree

1 file changed

+30
-22
lines changed
  • compiler/rustc_hir_analysis/src/astconv

1 file changed

+30
-22
lines changed

compiler/rustc_hir_analysis/src/astconv/bounds.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,36 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
2626
span: Span,
2727
) {
2828
let tcx = self.tcx();
29+
let sized_def_id = tcx.lang_items().sized_trait();
30+
let mut seen_negative_sized_bound = false;
2931

3032
// Try to find an unbound in bounds.
3133
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
3234
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
3335
for ab in ast_bounds {
34-
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
35-
unbounds.push(ptr)
36+
let hir::GenericBound::Trait(ptr, modifier) = ab else {
37+
continue;
38+
};
39+
match modifier {
40+
hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
41+
hir::TraitBoundModifier::Negative => {
42+
if let Some(sized_def_id) = sized_def_id
43+
&& ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
44+
{
45+
seen_negative_sized_bound = true;
46+
}
47+
}
48+
_ => {}
3649
}
3750
}
3851
};
3952
search_bounds(ast_bounds);
4053
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
4154
for clause in where_clause {
42-
if let hir::WherePredicate::BoundPredicate(pred) = clause {
43-
if pred.is_param_bound(self_ty.to_def_id()) {
44-
search_bounds(pred.bounds);
45-
}
55+
if let hir::WherePredicate::BoundPredicate(pred) = clause
56+
&& pred.is_param_bound(self_ty.to_def_id())
57+
{
58+
search_bounds(pred.bounds);
4659
}
4760
}
4861
}
@@ -53,15 +66,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
5366
});
5467
}
5568

56-
let sized_def_id = tcx.lang_items().sized_trait();
57-
5869
let mut seen_sized_unbound = false;
5970
for unbound in unbounds {
60-
if let Some(sized_def_id) = sized_def_id {
61-
if unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) {
62-
seen_sized_unbound = true;
63-
continue;
64-
}
71+
if let Some(sized_def_id) = sized_def_id
72+
&& unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
73+
{
74+
seen_sized_unbound = true;
75+
continue;
6576
}
6677
// There was a `?Trait` bound, but it was not `?Sized`; warn.
6778
tcx.dcx().span_warn(
@@ -71,15 +82,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
7182
);
7283
}
7384

74-
// If the above loop finished there was no `?Sized` bound; add implicitly sized if `Sized` is available.
75-
if sized_def_id.is_none() {
76-
// No lang item for `Sized`, so we can't add it as a bound.
77-
return;
78-
}
79-
if seen_sized_unbound {
80-
// There was in fact a `?Sized` bound, return without doing anything
81-
} else {
82-
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
85+
if seen_sized_unbound || seen_negative_sized_bound {
86+
// There was in fact a `?Sized` or `!Sized` bound;
87+
// we don't need to do anything.
88+
} else if sized_def_id.is_some() {
89+
// There was no `?Sized` or `!Sized` bound;
90+
// add `Sized` if it's available.
8391
bounds.push_sized(tcx, self_ty, span);
8492
}
8593
}

0 commit comments

Comments
 (0)