diff --git a/compiler/rustc_attr/messages.ftl b/compiler/rustc_attr/messages.ftl
index 7281282fec3..eb51e568f81 100644
--- a/compiler/rustc_attr/messages.ftl
+++ b/compiler/rustc_attr/messages.ftl
@@ -27,10 +27,16 @@ attr_incorrect_meta_item =
 attr_incorrect_repr_format_align_one_arg =
     incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
 
+attr_incorrect_repr_format_expect_literal_integer =
+    incorrect `repr(align)` attribute format: `align` expects a literal integer as argument
+
 attr_incorrect_repr_format_generic =
     incorrect `repr({$repr_arg})` attribute format
     .suggestion = use parentheses instead
 
+attr_incorrect_repr_format_packed_expect_integer =
+    incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument
+
 attr_incorrect_repr_format_packed_one_or_zero_arg =
     incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
 
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index f414ff746bb..3d2cf25e98b 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -984,17 +984,24 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
                 }
             } else if let Some((name, value)) = item.name_value_literal() {
                 let mut literal_error = None;
+                let mut err_span = item.span();
                 if name == sym::align {
                     recognised = true;
                     match parse_alignment(&value.kind) {
                         Ok(literal) => acc.push(ReprAlign(literal)),
-                        Err(message) => literal_error = Some(message),
+                        Err(message) => {
+                            err_span = value.span;
+                            literal_error = Some(message)
+                        }
                     };
                 } else if name == sym::packed {
                     recognised = true;
                     match parse_alignment(&value.kind) {
                         Ok(literal) => acc.push(ReprPacked(literal)),
-                        Err(message) => literal_error = Some(message),
+                        Err(message) => {
+                            err_span = value.span;
+                            literal_error = Some(message)
+                        }
                     };
                 } else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent)
                     || int_type_of_word(name).is_some()
@@ -1007,7 +1014,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
                 }
                 if let Some(literal_error) = literal_error {
                     sess.dcx().emit_err(session_diagnostics::InvalidReprGeneric {
-                        span: item.span(),
+                        span: err_span,
                         repr_arg: name.to_ident_string(),
                         error_part: literal_error,
                     });
@@ -1039,21 +1046,37 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
                             });
                         }
                     }
-                    MetaItemKind::List(_) => {
+                    MetaItemKind::List(nested_items) => {
                         if meta_item.has_name(sym::align) {
                             recognised = true;
-                            sess.dcx().emit_err(
-                                session_diagnostics::IncorrectReprFormatAlignOneArg {
-                                    span: meta_item.span,
-                                },
-                            );
+                            if nested_items.len() == 1 {
+                                sess.dcx().emit_err(
+                                    session_diagnostics::IncorrectReprFormatExpectInteger {
+                                        span: nested_items[0].span(),
+                                    },
+                                );
+                            } else {
+                                sess.dcx().emit_err(
+                                    session_diagnostics::IncorrectReprFormatAlignOneArg {
+                                        span: meta_item.span,
+                                    },
+                                );
+                            }
                         } else if meta_item.has_name(sym::packed) {
                             recognised = true;
-                            sess.dcx().emit_err(
-                                session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
-                                    span: meta_item.span,
-                                },
-                            );
+                            if nested_items.len() == 1 {
+                                sess.dcx().emit_err(
+                                    session_diagnostics::IncorrectReprFormatPackedExpectInteger {
+                                        span: nested_items[0].span(),
+                                    },
+                                );
+                            } else {
+                                sess.dcx().emit_err(
+                                    session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
+                                        span: meta_item.span,
+                                    },
+                                );
+                            }
                         } else if matches!(
                             meta_item.name_or_empty(),
                             sym::Rust | sym::C | sym::simd | sym::transparent
diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs
index 8cbd401d300..f489cc87bc7 100644
--- a/compiler/rustc_attr/src/session_diagnostics.rs
+++ b/compiler/rustc_attr/src/session_diagnostics.rs
@@ -170,6 +170,12 @@ pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
     #[primary_span]
     pub span: Span,
 }
+#[derive(Diagnostic)]
+#[diag(attr_incorrect_repr_format_packed_expect_integer, code = E0552)]
+pub(crate) struct IncorrectReprFormatPackedExpectInteger {
+    #[primary_span]
+    pub span: Span,
+}
 
 #[derive(Diagnostic)]
 #[diag(attr_invalid_repr_hint_no_paren, code = E0552)]
@@ -252,6 +258,13 @@ pub(crate) struct IncorrectReprFormatAlignOneArg {
     pub span: Span,
 }
 
+#[derive(Diagnostic)]
+#[diag(attr_incorrect_repr_format_expect_literal_integer, code = E0693)]
+pub(crate) struct IncorrectReprFormatExpectInteger {
+    #[primary_span]
+    pub span: Span,
+}
+
 #[derive(Diagnostic)]
 #[diag(attr_incorrect_repr_format_generic, code = E0693)]
 pub(crate) struct IncorrectReprFormatGeneric<'a> {
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 9e23757fcee..9c9e134f033 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -441,7 +441,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                         .map_err(|msg| {
                             struct_span_code_err!(
                                 tcx.dcx(),
-                                attr.span,
+                                literal.span,
                                 E0589,
                                 "invalid `repr(align)` attribute: {}",
                                 msg
diff --git a/tests/ui/attributes/arg-error-issue-121425.rs b/tests/ui/attributes/arg-error-issue-121425.rs
new file mode 100644
index 00000000000..c15b276ad4e
--- /dev/null
+++ b/tests/ui/attributes/arg-error-issue-121425.rs
@@ -0,0 +1,32 @@
+//@ compile-flags: -Zdeduplicate-diagnostics=yes
+
+const N: usize = 8;
+#[repr(align(N))]
+//~^ ERROR: incorrect `repr(align)` attribute format
+struct T;
+
+#[repr(align('a'))]
+//~^ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer [E0589]
+struct H;
+
+#[repr(align("str"))]
+//~^ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer [E0589]
+struct L;
+
+#[repr(align())]
+//~^ ERROR: attribute format: `align` takes exactly one argument in parentheses
+struct X;
+
+const P: usize = 8;
+#[repr(packed(P))]
+//~^ ERROR: attribute format: `packed` expects a literal integer as argument
+struct A;
+
+#[repr(packed())]
+//~^ ERROR: attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
+struct B;
+
+#[repr(packed)]
+struct C;
+
+fn main() {}
diff --git a/tests/ui/attributes/arg-error-issue-121425.stderr b/tests/ui/attributes/arg-error-issue-121425.stderr
new file mode 100644
index 00000000000..1beb99b1703
--- /dev/null
+++ b/tests/ui/attributes/arg-error-issue-121425.stderr
@@ -0,0 +1,40 @@
+error[E0693]: incorrect `repr(align)` attribute format: `align` expects a literal integer as argument
+  --> $DIR/arg-error-issue-121425.rs:4:14
+   |
+LL | #[repr(align(N))]
+   |              ^
+
+error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
+  --> $DIR/arg-error-issue-121425.rs:8:14
+   |
+LL | #[repr(align('a'))]
+   |              ^^^
+
+error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
+  --> $DIR/arg-error-issue-121425.rs:12:14
+   |
+LL | #[repr(align("str"))]
+   |              ^^^^^
+
+error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
+  --> $DIR/arg-error-issue-121425.rs:16:8
+   |
+LL | #[repr(align())]
+   |        ^^^^^^^
+
+error[E0552]: incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument
+  --> $DIR/arg-error-issue-121425.rs:21:15
+   |
+LL | #[repr(packed(P))]
+   |               ^
+
+error[E0552]: incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
+  --> $DIR/arg-error-issue-121425.rs:25:8
+   |
+LL | #[repr(packed())]
+   |        ^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0552, E0589, E0693.
+For more information about an error, try `rustc --explain E0552`.
diff --git a/tests/ui/attributes/nonterminal-expansion.rs b/tests/ui/attributes/nonterminal-expansion.rs
index 97bf225f0cc..6db7aea0745 100644
--- a/tests/ui/attributes/nonterminal-expansion.rs
+++ b/tests/ui/attributes/nonterminal-expansion.rs
@@ -1,10 +1,11 @@
+//@ compile-flags: -Zdeduplicate-diagnostics=yes
+
 // Macros were previously expanded in `Expr` nonterminal tokens, now they are not.
 
 macro_rules! pass_nonterminal {
     ($n:expr) => {
         #[repr(align($n))]
         //~^ ERROR expected unsuffixed literal or identifier, found `n!()`
-        //~| ERROR incorrect `repr(align)` attribute format
         struct S;
     };
 }
@@ -14,5 +15,6 @@ macro_rules! n {
 }
 
 pass_nonterminal!(n!());
+//~^ ERROR incorrect `repr(align)` attribute format: `align` expects a literal integer as argument [E0693]
 
 fn main() {}
diff --git a/tests/ui/attributes/nonterminal-expansion.stderr b/tests/ui/attributes/nonterminal-expansion.stderr
index 52376ac1911..78541495b32 100644
--- a/tests/ui/attributes/nonterminal-expansion.stderr
+++ b/tests/ui/attributes/nonterminal-expansion.stderr
@@ -1,5 +1,5 @@
 error: expected unsuffixed literal or identifier, found `n!()`
-  --> $DIR/nonterminal-expansion.rs:5:22
+  --> $DIR/nonterminal-expansion.rs:7:22
    |
 LL |         #[repr(align($n))]
    |                      ^^
@@ -9,16 +9,11 @@ LL | pass_nonterminal!(n!());
    |
    = note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
-  --> $DIR/nonterminal-expansion.rs:5:16
+error[E0693]: incorrect `repr(align)` attribute format: `align` expects a literal integer as argument
+  --> $DIR/nonterminal-expansion.rs:17:19
    |
-LL |         #[repr(align($n))]
-   |                ^^^^^^^^^
-...
 LL | pass_nonterminal!(n!());
-   | ----------------------- in this macro invocation
-   |
-   = note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
+   |                   ^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/repr/repr-align.stderr b/tests/ui/repr/repr-align.stderr
index 84d33a08a6f..bb0e17ba395 100644
--- a/tests/ui/repr/repr-align.stderr
+++ b/tests/ui/repr/repr-align.stderr
@@ -1,84 +1,84 @@
 error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
-  --> $DIR/repr-align.rs:3:8
+  --> $DIR/repr-align.rs:3:14
    |
 LL | #[repr(align(16.0))]
-   |        ^^^^^^^^^^^
+   |              ^^^^
 
 error[E0589]: invalid `repr(align)` attribute: not a power of two
-  --> $DIR/repr-align.rs:7:8
+  --> $DIR/repr-align.rs:7:14
    |
 LL | #[repr(align(15))]
-   |        ^^^^^^^^^
+   |              ^^
 
 error[E0589]: invalid `repr(align)` attribute: larger than 2^29
-  --> $DIR/repr-align.rs:11:8
+  --> $DIR/repr-align.rs:11:14
    |
 LL | #[repr(align(4294967296))]
-   |        ^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^
 
 error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
-  --> $DIR/repr-align.rs:18:8
+  --> $DIR/repr-align.rs:18:14
    |
 LL | #[repr(align(16.0))]
-   |        ^^^^^^^^^^^
+   |              ^^^^
 
 error[E0589]: invalid `repr(align)` attribute: not a power of two
-  --> $DIR/repr-align.rs:22:8
+  --> $DIR/repr-align.rs:22:14
    |
 LL | #[repr(align(15))]
-   |        ^^^^^^^^^
+   |              ^^
 
 error[E0589]: invalid `repr(align)` attribute: larger than 2^29
-  --> $DIR/repr-align.rs:26:8
+  --> $DIR/repr-align.rs:26:14
    |
 LL | #[repr(align(4294967296))]
-   |        ^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^
 
 error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
-  --> $DIR/repr-align.rs:3:8
+  --> $DIR/repr-align.rs:3:14
    |
 LL | #[repr(align(16.0))]
-   |        ^^^^^^^^^^^
+   |              ^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0589]: invalid `repr(align)` attribute: not a power of two
-  --> $DIR/repr-align.rs:7:8
+  --> $DIR/repr-align.rs:7:14
    |
 LL | #[repr(align(15))]
-   |        ^^^^^^^^^
+   |              ^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0589]: invalid `repr(align)` attribute: larger than 2^29
-  --> $DIR/repr-align.rs:11:8
+  --> $DIR/repr-align.rs:11:14
    |
 LL | #[repr(align(4294967296))]
-   |        ^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
-  --> $DIR/repr-align.rs:18:8
+  --> $DIR/repr-align.rs:18:14
    |
 LL | #[repr(align(16.0))]
-   |        ^^^^^^^^^^^
+   |              ^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0589]: invalid `repr(align)` attribute: not a power of two
-  --> $DIR/repr-align.rs:22:8
+  --> $DIR/repr-align.rs:22:14
    |
 LL | #[repr(align(15))]
-   |        ^^^^^^^^^
+   |              ^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0589]: invalid `repr(align)` attribute: larger than 2^29
-  --> $DIR/repr-align.rs:26:8
+  --> $DIR/repr-align.rs:26:14
    |
 LL | #[repr(align(4294967296))]
-   |        ^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`