about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/move_check.rs20
-rw-r--r--tests/ui/lint/large_assignments/inline_mir.rs24
-rw-r--r--tests/ui/lint/large_assignments/inline_mir.stderr15
3 files changed, 56 insertions, 3 deletions
diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
index 838bfdab1ea..946714e3e48 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
@@ -162,13 +162,27 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
             // but correct span? This would make the lint at least accept crate-level lint attributes.
             return;
         };
+
+        // If the source scope is inlined by the MIR inliner, report the lint on the call site.
+        let reported_span = self
+            .body
+            .source_scopes
+            .get(source_info.scope)
+            .and_then(|source_scope_data| source_scope_data.inlined)
+            .map(|(_, call_site)| call_site)
+            .unwrap_or(span);
+
         self.tcx.emit_node_span_lint(
             LARGE_ASSIGNMENTS,
             lint_root,
-            span,
-            LargeAssignmentsLint { span, size: too_large_size.bytes(), limit: limit as u64 },
+            reported_span,
+            LargeAssignmentsLint {
+                span: reported_span,
+                size: too_large_size.bytes(),
+                limit: limit as u64,
+            },
         );
-        self.move_size_spans.push(span);
+        self.move_size_spans.push(reported_span);
     }
 }
 
diff --git a/tests/ui/lint/large_assignments/inline_mir.rs b/tests/ui/lint/large_assignments/inline_mir.rs
new file mode 100644
index 00000000000..fc27b8ff244
--- /dev/null
+++ b/tests/ui/lint/large_assignments/inline_mir.rs
@@ -0,0 +1,24 @@
+#![feature(large_assignments)]
+#![deny(large_assignments)]
+#![move_size_limit = "1000"]
+
+//! Tests that with `-Zinline-mir`, we do NOT get an error that points to the
+//! implementation of `UnsafeCell` since that is not actionable by the user:
+//!
+//! ```text
+//! error: moving 9999 bytes
+//!   --> /rustc/FAKE_PREFIX/library/core/src/cell.rs:2054:9
+//!    |
+//!    = note: value moved from here
+//! ```
+//!
+//! We want the diagnostics to point to the relevant user code.
+
+//@ build-fail
+//@ compile-flags: -Zmir-opt-level=1 -Zinline-mir
+
+pub fn main() {
+    let data = [10u8; 9999];
+    let cell = std::cell::UnsafeCell::new(data); //~ ERROR large_assignments
+    std::hint::black_box(cell);
+}
diff --git a/tests/ui/lint/large_assignments/inline_mir.stderr b/tests/ui/lint/large_assignments/inline_mir.stderr
new file mode 100644
index 00000000000..d9010e24d03
--- /dev/null
+++ b/tests/ui/lint/large_assignments/inline_mir.stderr
@@ -0,0 +1,15 @@
+error: moving 9999 bytes
+  --> $DIR/inline_mir.rs:22:16
+   |
+LL |     let cell = std::cell::UnsafeCell::new(data);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here
+   |
+   = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
+note: the lint level is defined here
+  --> $DIR/inline_mir.rs:2:9
+   |
+LL | #![deny(large_assignments)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+