From f980f813e189b8568eab93311fcc4effa2cffec3 Mon Sep 17 00:00:00 2001 From: Lucas Kent Date: Sun, 14 Nov 2021 22:04:25 +1100 Subject: [PATCH 1/2] Improve ManuallyDrop suggestion --- compiler/rustc_typeck/src/check/check.rs | 15 ++++++++++--- .../feature-gate-untagged_unions.stderr | 14 ++++++------- src/test/ui/union/issue-41073.stderr | 7 +++---- src/test/ui/union/union-custom-drop.stderr | 7 +++---- .../union-with-drop-fields.mirunsafeck.stderr | 21 ++++++++----------- ...union-with-drop-fields.thirunsafeck.stderr | 21 ++++++++----------- 6 files changed, 42 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index f0a77cb39a622..335814f8627b3 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -371,8 +371,13 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b let param_env = tcx.param_env(item_def_id); for field in fields { let field_ty = field.ty(tcx, substs); - // We are currently checking the type this field came from, so it must be local. - let field_span = tcx.hir().span_if_local(field.did).unwrap(); + let (field_span, ty_span) = + // We are currently checking the type this field came from, so it must be local. + if let Node::Field(field) = tcx.hir().get_if_local(field.did).unwrap() { + (field.span, field.ty.span) + } else { + unreachable!("mir field has to correspond to hir field"); + }; if field_ty.needs_drop(tcx, param_env) { struct_span_err!( tcx.sess, @@ -380,7 +385,11 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b E0740, "unions may not contain fields that need dropping" ) - .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type") + .multipart_suggestion_verbose( + "wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped", + vec![(ty_span, format!("std::mem::ManuallyDrop<{}>", field_ty))], + Applicability::MaybeIncorrect, + ) .emit(); return false; } diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr index ed973871b3f06..a9ccb83558773 100644 --- a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr +++ b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr @@ -13,11 +13,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: String, | ^^^^^^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/feature-gate-untagged_unions.rs:16:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: String, - | ^^^^^^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0740]: unions may not contain fields that need dropping --> $DIR/feature-gate-untagged_unions.rs:24:5 @@ -25,11 +24,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: T, | ^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/feature-gate-untagged_unions.rs:24:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: T, - | ^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors diff --git a/src/test/ui/union/issue-41073.stderr b/src/test/ui/union/issue-41073.stderr index 2e9598b227124..04b4286cc4b63 100644 --- a/src/test/ui/union/issue-41073.stderr +++ b/src/test/ui/union/issue-41073.stderr @@ -4,11 +4,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: A, | ^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/issue-41073.rs:4:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: A, - | ^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/union/union-custom-drop.stderr b/src/test/ui/union/union-custom-drop.stderr index ee2333f905fb4..0c59048f7fedb 100644 --- a/src/test/ui/union/union-custom-drop.stderr +++ b/src/test/ui/union/union-custom-drop.stderr @@ -4,11 +4,10 @@ error[E0740]: unions may not contain fields that need dropping LL | bar: Bar, | ^^^^^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/union-custom-drop.rs:7:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | bar: Bar, - | ^^^^^^^^ +LL | bar: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr b/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr index 2062fb7473faa..8f3d30cd7ee46 100644 --- a/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr +++ b/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr @@ -4,11 +4,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: String, | ^^^^^^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/union-with-drop-fields.rs:11:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: String, - | ^^^^^^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0740]: unions may not contain fields that need dropping --> $DIR/union-with-drop-fields.rs:19:5 @@ -16,11 +15,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: S, | ^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/union-with-drop-fields.rs:19:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: S, - | ^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0740]: unions may not contain fields that need dropping --> $DIR/union-with-drop-fields.rs:24:5 @@ -28,11 +26,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: T, | ^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/union-with-drop-fields.rs:24:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: T, - | ^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors diff --git a/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr b/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr index 2062fb7473faa..8f3d30cd7ee46 100644 --- a/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr +++ b/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr @@ -4,11 +4,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: String, | ^^^^^^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/union-with-drop-fields.rs:11:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: String, - | ^^^^^^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0740]: unions may not contain fields that need dropping --> $DIR/union-with-drop-fields.rs:19:5 @@ -16,11 +15,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: S, | ^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/union-with-drop-fields.rs:19:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: S, - | ^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0740]: unions may not contain fields that need dropping --> $DIR/union-with-drop-fields.rs:24:5 @@ -28,11 +26,10 @@ error[E0740]: unions may not contain fields that need dropping LL | a: T, | ^^^^ | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/union-with-drop-fields.rs:24:5 +help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | -LL | a: T, - | ^^^^ +LL | a: std::mem::ManuallyDrop, + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors From 62acf7f96def600de3239cb93b62d07e9b514276 Mon Sep 17 00:00:00 2001 From: Lucas Kent Date: Mon, 15 Nov 2021 14:47:36 +1100 Subject: [PATCH 2/2] feedback --- compiler/rustc_typeck/src/check/check.rs | 17 +++++++++-------- .../feature-gate-untagged_unions.stderr | 4 ++-- src/test/ui/union/issue-41073.stderr | 2 +- src/test/ui/union/union-custom-drop.stderr | 2 +- .../union-with-drop-fields.mirunsafeck.stderr | 6 +++--- .../union-with-drop-fields.thirunsafeck.stderr | 6 +++--- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 335814f8627b3..bb1d9744e66fe 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -371,14 +371,12 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b let param_env = tcx.param_env(item_def_id); for field in fields { let field_ty = field.ty(tcx, substs); - let (field_span, ty_span) = - // We are currently checking the type this field came from, so it must be local. - if let Node::Field(field) = tcx.hir().get_if_local(field.did).unwrap() { - (field.span, field.ty.span) - } else { - unreachable!("mir field has to correspond to hir field"); - }; if field_ty.needs_drop(tcx, param_env) { + let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) { + // We are currently checking the type this field came from, so it must be local. + Some(Node::Field(field)) => (field.span, field.ty.span), + _ => unreachable!("mir field has to correspond to hir field"), + }; struct_span_err!( tcx.sess, field_span, @@ -387,7 +385,10 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b ) .multipart_suggestion_verbose( "wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped", - vec![(ty_span, format!("std::mem::ManuallyDrop<{}>", field_ty))], + vec![ + (ty_span.shrink_to_lo(), format!("std::mem::ManuallyDrop<")), + (ty_span.shrink_to_hi(), ">".into()), + ], Applicability::MaybeIncorrect, ) .emit(); diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr index a9ccb83558773..0967cb7ba8bd2 100644 --- a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr +++ b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr @@ -16,7 +16,7 @@ LL | a: String, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error[E0740]: unions may not contain fields that need dropping --> $DIR/feature-gate-untagged_unions.rs:24:5 @@ -27,7 +27,7 @@ LL | a: T, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error: aborting due to 3 previous errors diff --git a/src/test/ui/union/issue-41073.stderr b/src/test/ui/union/issue-41073.stderr index 04b4286cc4b63..8edf4db441b9c 100644 --- a/src/test/ui/union/issue-41073.stderr +++ b/src/test/ui/union/issue-41073.stderr @@ -7,7 +7,7 @@ LL | a: A, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error: aborting due to previous error diff --git a/src/test/ui/union/union-custom-drop.stderr b/src/test/ui/union/union-custom-drop.stderr index 0c59048f7fedb..65ca5fd931d67 100644 --- a/src/test/ui/union/union-custom-drop.stderr +++ b/src/test/ui/union/union-custom-drop.stderr @@ -7,7 +7,7 @@ LL | bar: Bar, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | bar: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error: aborting due to previous error diff --git a/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr b/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr index 8f3d30cd7ee46..f5e9681735c6f 100644 --- a/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr +++ b/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr @@ -7,7 +7,7 @@ LL | a: String, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error[E0740]: unions may not contain fields that need dropping --> $DIR/union-with-drop-fields.rs:19:5 @@ -18,7 +18,7 @@ LL | a: S, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error[E0740]: unions may not contain fields that need dropping --> $DIR/union-with-drop-fields.rs:24:5 @@ -29,7 +29,7 @@ LL | a: T, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error: aborting due to 3 previous errors diff --git a/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr b/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr index 8f3d30cd7ee46..f5e9681735c6f 100644 --- a/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr +++ b/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr @@ -7,7 +7,7 @@ LL | a: String, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error[E0740]: unions may not contain fields that need dropping --> $DIR/union-with-drop-fields.rs:19:5 @@ -18,7 +18,7 @@ LL | a: S, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error[E0740]: unions may not contain fields that need dropping --> $DIR/union-with-drop-fields.rs:24:5 @@ -29,7 +29,7 @@ LL | a: T, help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped | LL | a: std::mem::ManuallyDrop, - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++ + error: aborting due to 3 previous errors