diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9a7564cb213d7..652deb558b3a6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1767,6 +1767,7 @@ impl CheckAttrVisitor<'_> { .collect(); let mut int_reprs = 0; + let mut is_explicit_rust = false; let mut is_c = false; let mut is_simd = false; let mut is_transparent = false; @@ -1778,7 +1779,9 @@ impl CheckAttrVisitor<'_> { } match hint.name_or_empty() { - sym::Rust => {} + sym::Rust => { + is_explicit_rust = true; + } sym::C => { is_c = true; match target { @@ -1888,12 +1891,16 @@ impl CheckAttrVisitor<'_> { // Error on repr(transparent, ). if is_transparent && hints.len() > 1 { - let hint_spans: Vec<_> = hint_spans.clone().collect(); + let hint_spans = hint_spans.clone().collect(); self.tcx.sess.emit_err(errors::TransparentIncompatible { hint_spans, target: target.to_string(), }); } + if is_explicit_rust && is_c { + let hint_spans: Vec<_> = hint_spans.clone().collect(); + self.tcx.sess.emit_err(errors::ReprConflicting { hint_spans }); + } // Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8) if (int_reprs > 1) || (is_simd && is_c) @@ -1910,7 +1917,7 @@ impl CheckAttrVisitor<'_> { CONFLICTING_REPR_HINTS, hir_id, hint_spans.collect::>(), - errors::ReprConflicting, + errors::ReprConflictingLint, ); } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index bcf5abbfe7d9d..f4a6bf017d65c 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -558,9 +558,16 @@ pub struct ReprIdent { pub span: Span, } +#[derive(Diagnostic)] +#[diag(passes_repr_conflicting, code = "E0566")] +pub struct ReprConflicting { + #[primary_span] + pub hint_spans: Vec, +} + #[derive(LintDiagnostic)] #[diag(passes_repr_conflicting, code = "E0566")] -pub struct ReprConflicting; +pub struct ReprConflictingLint; #[derive(Diagnostic)] #[diag(passes_used_static)] diff --git a/tests/ui/repr/repr-c-explicit-rust.rs b/tests/ui/repr/repr-c-explicit-rust.rs new file mode 100644 index 0000000000000..91405e6bf6d6c --- /dev/null +++ b/tests/ui/repr/repr-c-explicit-rust.rs @@ -0,0 +1,13 @@ +#[repr(C, Rust)] //~ ERROR conflicting representation hints +struct S { + a: i32, +} + + +#[repr(Rust)] //~ ERROR conflicting representation hints +#[repr(C)] +struct T { + a: i32, +} + +fn main() {} diff --git a/tests/ui/repr/repr-c-explicit-rust.stderr b/tests/ui/repr/repr-c-explicit-rust.stderr new file mode 100644 index 0000000000000..3ed9609914198 --- /dev/null +++ b/tests/ui/repr/repr-c-explicit-rust.stderr @@ -0,0 +1,17 @@ +error[E0566]: conflicting representation hints + --> $DIR/repr-c-explicit-rust.rs:1:8 + | +LL | #[repr(C, Rust)] + | ^ ^^^^ + +error[E0566]: conflicting representation hints + --> $DIR/repr-c-explicit-rust.rs:7:8 + | +LL | #[repr(Rust)] + | ^^^^ +LL | #[repr(C)] + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0566`.