Skip to content

Commit c03c902

Browse files
committed
Error when only is not applied to a sizedness trait
1 parent 8e86a1c commit c03c902

3 files changed

Lines changed: 55 additions & 1 deletion

File tree

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,6 +2219,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
22192219

22202220
if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
22212221
self.validate_relaxed_bound(trait_ref, *span, rbp);
2222+
} else if let ast::BoundPolarity::Only(_) = modifiers.polarity {
2223+
self.validate_only_bound(trait_ref, *span);
22222224
}
22232225

22242226
hir::PolyTraitRef {
@@ -2229,6 +2231,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
22292231
}
22302232
}
22312233

2234+
fn validate_only_bound(&self, trait_ref: hir::TraitRef<'_>, span: Span) {
2235+
if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res
2236+
&& !(self.tcx.is_lang_item(def_id, hir::LangItem::MetaSized)
2237+
|| self.tcx.is_lang_item(def_id, hir::LangItem::Sized)
2238+
|| self.tcx.is_lang_item(def_id, hir::LangItem::PointeeSized))
2239+
{
2240+
self.dcx()
2241+
.struct_span_err(span, "`only` may only be applied to sizedness traits")
2242+
.emit();
2243+
}
2244+
}
2245+
22322246
fn validate_relaxed_bound(
22332247
&self,
22342248
trait_ref: hir::TraitRef<'_>,

tests/ui/trait-bounds/only-bound.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,26 @@ trait OnlyPointeeSized: only PointeeSized {
2828
}
2929
}
3030

31+
trait NonSizedOnly1: only Debug {}
32+
//~^ ERROR `only` may only be applied to sizedness traits
33+
34+
trait Trait {}
35+
36+
trait NonSizedOnly2: only Trait {}
37+
//~^ ERROR `only` may only be applied to sizedness traits
38+
39+
trait OnlyOnly: only OnlyPointeeSized {}
40+
//~^ ERROR `only` may only be applied to sizedness traits
41+
42+
trait DoubleOnly: only PointeeSized + only MetaSized {}
43+
// Redundant, but not illegal.
44+
45+
trait InheritedOnly: OnlyPointeeSized {
46+
fn foo(&self) {
47+
size_of_val(self);
48+
// This works fine, `only` is not transitive, this trait still has the
49+
// `MetaSized` default supertrait.
50+
}
51+
}
52+
3153
fn main() {}

tests/ui/trait-bounds/only-bound.stderr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
error: `only` may only be applied to sizedness traits
2+
--> $DIR/only-bound.rs:31:22
3+
|
4+
LL | trait NonSizedOnly1: only Debug {}
5+
| ^^^^^^^^^^
6+
7+
error: `only` may only be applied to sizedness traits
8+
--> $DIR/only-bound.rs:36:22
9+
|
10+
LL | trait NonSizedOnly2: only Trait {}
11+
| ^^^^^^^^^^
12+
13+
error: `only` may only be applied to sizedness traits
14+
--> $DIR/only-bound.rs:39:17
15+
|
16+
LL | trait OnlyOnly: only OnlyPointeeSized {}
17+
| ^^^^^^^^^^^^^^^^^^^^^
18+
119
error[E0277]: the size for values of type `T` cannot be known at compilation time
220
--> $DIR/only-bound.rs:11:30
321
|
@@ -59,6 +77,6 @@ LL | size_of_val(&self);
5977
LL | size_of_val(&mut self);
6078
| ++++
6179

62-
error: aborting due to 4 previous errors
80+
error: aborting due to 7 previous errors
6381

6482
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)