Skip to content

Commit cae6344

Browse files
committed
Make #[repr(Rust)] and #[repr(C)] incompatible with one another
1 parent 1bc0463 commit cae6344

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-4
lines changed

compiler/rustc_passes/src/check_attr.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,6 +1767,7 @@ impl CheckAttrVisitor<'_> {
17671767
.collect();
17681768

17691769
let mut int_reprs = 0;
1770+
let mut is_explicit_rust = false;
17701771
let mut is_c = false;
17711772
let mut is_simd = false;
17721773
let mut is_transparent = false;
@@ -1778,7 +1779,9 @@ impl CheckAttrVisitor<'_> {
17781779
}
17791780

17801781
match hint.name_or_empty() {
1781-
sym::Rust => {}
1782+
sym::Rust => {
1783+
is_explicit_rust = true;
1784+
}
17821785
sym::C => {
17831786
is_c = true;
17841787
match target {
@@ -1888,12 +1891,16 @@ impl CheckAttrVisitor<'_> {
18881891

18891892
// Error on repr(transparent, <anything else>).
18901893
if is_transparent && hints.len() > 1 {
1891-
let hint_spans: Vec<_> = hint_spans.clone().collect();
1894+
let hint_spans = hint_spans.clone().collect();
18921895
self.tcx.sess.emit_err(errors::TransparentIncompatible {
18931896
hint_spans,
18941897
target: target.to_string(),
18951898
});
18961899
}
1900+
if is_explicit_rust && is_c {
1901+
let hint_spans = hint_spans.clone().collect();
1902+
self.tcx.sess.emit_err(errors::ReprConflicting { hint_spans });
1903+
}
18971904
// Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8)
18981905
if (int_reprs > 1)
18991906
|| (is_simd && is_c)
@@ -1910,7 +1917,7 @@ impl CheckAttrVisitor<'_> {
19101917
CONFLICTING_REPR_HINTS,
19111918
hir_id,
19121919
hint_spans.collect::<Vec<Span>>(),
1913-
errors::ReprConflicting,
1920+
errors::ReprConflictingLint,
19141921
);
19151922
}
19161923
}

compiler/rustc_passes/src/errors.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,16 @@ pub struct ReprIdent {
558558
pub span: Span,
559559
}
560560

561+
#[derive(Diagnostic)]
562+
#[diag(passes_repr_conflicting, code = "E0566")]
563+
pub struct ReprConflicting {
564+
#[primary_span]
565+
pub hint_spans: Vec<Span>,
566+
}
567+
561568
#[derive(LintDiagnostic)]
562569
#[diag(passes_repr_conflicting, code = "E0566")]
563-
pub struct ReprConflicting;
570+
pub struct ReprConflictingLint;
564571

565572
#[derive(Diagnostic)]
566573
#[diag(passes_used_static)]

tests/ui/repr/repr-c-explicit-rust.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#[repr(C, Rust)] //~ ERROR conflicting representation hints
2+
struct S {
3+
a: i32,
4+
}
5+
6+
7+
#[repr(Rust)] //~ ERROR conflicting representation hints
8+
#[repr(C)]
9+
struct T {
10+
a: i32,
11+
}
12+
13+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0566]: conflicting representation hints
2+
--> $DIR/repr-c-explicit-rust.rs:1:8
3+
|
4+
LL | #[repr(C, Rust)]
5+
| ^ ^^^^
6+
7+
error[E0566]: conflicting representation hints
8+
--> $DIR/repr-c-explicit-rust.rs:7:8
9+
|
10+
LL | #[repr(Rust)]
11+
| ^^^^
12+
LL | #[repr(C)]
13+
| ^
14+
15+
error: aborting due to 2 previous errors
16+
17+
For more information about this error, try `rustc --explain E0566`.

0 commit comments

Comments
 (0)