Skip to content

Commit c587fd4

Browse files
committed
Auto merge of #114774 - Enselic:less-move-size-noise, r=oli-obk
Avoid duplicate `large_assignments` lints By checking for overlapping spans. This PR does the "reduce noisiness" task in #83518. r? `@oli-obk` who added E-mentor and E-help-wanted and wrote the initial code. (The fix itself is in dc82736. The two commits before that are just small refactorings.)
2 parents 9847c64 + dc82736 commit c587fd4

File tree

4 files changed

+50
-56
lines changed

4 files changed

+50
-56
lines changed

compiler/rustc_monomorphize/src/collector.rs

+46-35
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,8 @@ struct MirUsedCollector<'a, 'tcx> {
590590
body: &'a mir::Body<'tcx>,
591591
output: &'a mut MonoItems<'tcx>,
592592
instance: Instance<'tcx>,
593+
/// Spans for move size lints already emitted. Helps avoid duplicate lints.
594+
move_size_spans: Vec<Span>,
593595
}
594596

595597
impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
@@ -604,6 +606,45 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
604606
ty::EarlyBinder::bind(value),
605607
)
606608
}
609+
610+
fn check_move_size(&mut self, limit: usize, operand: &mir::Operand<'tcx>, location: Location) {
611+
let limit = Size::from_bytes(limit);
612+
let ty = operand.ty(self.body, self.tcx);
613+
let ty = self.monomorphize(ty);
614+
let Ok(layout) = self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) else { return };
615+
if layout.size <= limit {
616+
return;
617+
}
618+
debug!(?layout);
619+
let source_info = self.body.source_info(location);
620+
debug!(?source_info);
621+
for span in &self.move_size_spans {
622+
if span.overlaps(source_info.span) {
623+
return;
624+
}
625+
}
626+
let lint_root = source_info.scope.lint_root(&self.body.source_scopes);
627+
debug!(?lint_root);
628+
let Some(lint_root) = lint_root else {
629+
// This happens when the issue is in a function from a foreign crate that
630+
// we monomorphized in the current crate. We can't get a `HirId` for things
631+
// in other crates.
632+
// FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
633+
// but correct span? This would make the lint at least accept crate-level lint attributes.
634+
return;
635+
};
636+
self.tcx.emit_spanned_lint(
637+
LARGE_ASSIGNMENTS,
638+
lint_root,
639+
source_info.span,
640+
LargeAssignmentsLint {
641+
span: source_info.span,
642+
size: layout.size.bytes(),
643+
limit: limit.bytes(),
644+
},
645+
);
646+
self.move_size_spans.push(source_info.span);
647+
}
607648
}
608649

609650
impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
@@ -803,40 +844,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
803844

804845
fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
805846
self.super_operand(operand, location);
806-
let limit = self.tcx.move_size_limit().0;
807-
if limit == 0 {
808-
return;
809-
}
810-
let limit = Size::from_bytes(limit);
811-
let ty = operand.ty(self.body, self.tcx);
812-
let ty = self.monomorphize(ty);
813-
let layout = self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty));
814-
if let Ok(layout) = layout {
815-
if layout.size > limit {
816-
debug!(?layout);
817-
let source_info = self.body.source_info(location);
818-
debug!(?source_info);
819-
let lint_root = source_info.scope.lint_root(&self.body.source_scopes);
820-
debug!(?lint_root);
821-
let Some(lint_root) = lint_root else {
822-
// This happens when the issue is in a function from a foreign crate that
823-
// we monomorphized in the current crate. We can't get a `HirId` for things
824-
// in other crates.
825-
// FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
826-
// but correct span? This would make the lint at least accept crate-level lint attributes.
827-
return;
828-
};
829-
self.tcx.emit_spanned_lint(
830-
LARGE_ASSIGNMENTS,
831-
lint_root,
832-
source_info.span,
833-
LargeAssignmentsLint {
834-
span: source_info.span,
835-
size: layout.size.bytes(),
836-
limit: limit.bytes(),
837-
},
838-
)
839-
}
847+
let move_size_limit = self.tcx.move_size_limit().0;
848+
if move_size_limit > 0 {
849+
self.check_move_size(move_size_limit, operand, location);
840850
}
841851
}
842852

@@ -1363,7 +1373,8 @@ fn collect_used_items<'tcx>(
13631373
output: &mut MonoItems<'tcx>,
13641374
) {
13651375
let body = tcx.instance_mir(instance.def);
1366-
MirUsedCollector { tcx, body: &body, output, instance }.visit_body(&body);
1376+
MirUsedCollector { tcx, body: &body, output, instance, move_size_spans: vec![] }
1377+
.visit_body(&body);
13671378
}
13681379

13691380
#[instrument(skip(tcx, output), level = "debug")]

tests/ui/async-await/large_moves.attribute.stderr

+2-10
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,12 @@ LL | #![deny(large_assignments)]
1212
| ^^^^^^^^^^^^^^^^^
1313

1414
error: moving 10024 bytes
15-
--> $DIR/large_moves.rs:19:13
16-
|
17-
LL | let z = (x, 42);
18-
| ^^^^^^^ value moved from here
19-
|
20-
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
21-
22-
error: moving 10024 bytes
23-
--> $DIR/large_moves.rs:21:13
15+
--> $DIR/large_moves.rs:20:13
2416
|
2517
LL | let a = z.0;
2618
| ^^^ value moved from here
2719
|
2820
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
2921

30-
error: aborting due to 3 previous errors
22+
error: aborting due to 2 previous errors
3123

tests/ui/async-await/large_moves.option.stderr

+2-10
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,12 @@ LL | #![deny(large_assignments)]
1212
| ^^^^^^^^^^^^^^^^^
1313

1414
error: moving 10024 bytes
15-
--> $DIR/large_moves.rs:19:13
16-
|
17-
LL | let z = (x, 42);
18-
| ^^^^^^^ value moved from here
19-
|
20-
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
21-
22-
error: moving 10024 bytes
23-
--> $DIR/large_moves.rs:21:13
15+
--> $DIR/large_moves.rs:20:13
2416
|
2517
LL | let a = z.0;
2618
| ^^^ value moved from here
2719
|
2820
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
2921

30-
error: aborting due to 3 previous errors
22+
error: aborting due to 2 previous errors
3123

tests/ui/async-await/large_moves.rs

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ fn main() {
1717
dbg!(y);
1818
};
1919
let z = (x, 42); //~ ERROR large_assignments
20-
//~^ ERROR large_assignments
2120
let a = z.0; //~ ERROR large_assignments
2221
let b = z.1;
2322
}

0 commit comments

Comments
 (0)