Skip to content

Commit b4901a8

Browse files
committed
error on manually implementing field traits
1 parent 154f5cb commit b4901a8

File tree

7 files changed

+82
-0
lines changed

7 files changed

+82
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
`UnalignedField` or `Field` was manually implemented, which is not allowed.
2+
3+
Erroneous code examples:
4+
5+
```compile_fail,E0806
6+
use std::field::UnalignedField;
7+
8+
pub struct MyStruct;
9+
10+
unsafe impl UnalignedField for MyStruct {
11+
type Base = ();
12+
type Type = ();
13+
const OFFSET: usize = 0;
14+
}
15+
```
16+
17+
```compile_fail,E0806
18+
use std::field::{Field, field_of};
19+
20+
pub struct MyStruct(usize);
21+
22+
unsafe impl Field for field_of!(MyStruct, 0) {}
23+
```

compiler/rustc_error_codes/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ E0802: 0802,
548548
E0803: 0803,
549549
E0804: 0804,
550550
E0805: 0805,
551+
E0806: 0806,
551552
);
552553
)
553554
}

compiler/rustc_hir_analysis/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ hir_analysis_drop_impl_on_wrong_item =
161161
the `{$trait_}` trait may only be implemented for local structs, enums, and unions
162162
.label = must be a struct, enum, or union in the current crate
163163
164+
hir_analysis_field_trait_impl =
165+
the `{$trait_}` trait may not be implemented manually
166+
164167
hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported
165168
166169
hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice

compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ pub(super) fn check_trait<'tcx>(
5252
lang_items.coerce_pointee_validated_trait(),
5353
visit_implementation_of_coerce_pointee_validity,
5454
)?;
55+
checker.check(lang_items.unaligned_field_trait(), visit_implementation_of_field_trait)?;
56+
checker.check(lang_items.field_trait(), visit_implementation_of_field_trait)?;
5557
Ok(())
5658
}
5759

@@ -374,6 +376,18 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
374376
}
375377
}
376378

379+
fn visit_implementation_of_field_trait(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
380+
let tcx = checker.tcx;
381+
let impl_did = checker.impl_def_id;
382+
383+
let span = tcx.span_of_impl(impl_did.into()).expect("impl_did is local");
384+
385+
Err(tcx.dcx().emit_err(errors::FieldTraitImpl {
386+
span,
387+
trait_: tcx.item_name(checker.impl_header.trait_ref.skip_binder().def_id),
388+
}))
389+
}
390+
377391
pub(crate) fn coerce_unsized_info<'tcx>(
378392
tcx: TyCtxt<'tcx>,
379393
impl_did: LocalDefId,

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,14 @@ pub(crate) struct DropImplOnWrongItem {
208208
pub trait_: Symbol,
209209
}
210210

211+
#[derive(Diagnostic)]
212+
#[diag(hir_analysis_field_trait_impl, code = E0806)]
213+
pub(crate) struct FieldTraitImpl {
214+
#[primary_span]
215+
pub span: Span,
216+
pub trait_: Symbol,
217+
}
218+
211219
#[derive(Diagnostic)]
212220
pub(crate) enum FieldAlreadyDeclared {
213221
#[diag(hir_analysis_field_already_declared, code = E0124)]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![allow(incomplete_features)]
2+
#![feature(field_projections)]
3+
4+
use std::field::{Field, UnalignedField, field_of};
5+
6+
#[repr(packed)]
7+
pub struct MyStruct(usize);
8+
9+
unsafe impl UnalignedField for MyStruct {
10+
//~^ ERROR: the `UnalignedField` trait may not be implemented manually [E0806]
11+
type Base = ();
12+
type Type = ();
13+
const OFFSET: usize = 0;
14+
}
15+
16+
unsafe impl Field for field_of!(MyStruct, 0) {} //~ ERROR: the `Field` trait may not be implemented manually [E0806]
17+
18+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0806]: the `UnalignedField` trait may not be implemented manually
2+
--> $DIR/deny-manual-impl.rs:9:1
3+
|
4+
LL | unsafe impl UnalignedField for MyStruct {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error[E0806]: the `Field` trait may not be implemented manually
8+
--> $DIR/deny-manual-impl.rs:16:1
9+
|
10+
LL | unsafe impl Field for field_of!(MyStruct, 0) {}
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0806`.

0 commit comments

Comments
 (0)