Skip to content

Commit f3b2d7f

Browse files
author
Ariel Ben-Yehuda
committed
improve error messages
1 parent 47d53e8 commit f3b2d7f

File tree

7 files changed

+72
-65
lines changed

7 files changed

+72
-65
lines changed

src/librustc/dep_graph/dep_node.rs

+1
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ define_dep_nodes!( <'tcx>
479479
[] BorrowCheck(DefId),
480480
[] MirBorrowCheck(DefId),
481481
[] UnsafetyCheckResult(DefId),
482+
[] UnsafeDeriveOnReprPacked(DefId),
482483

483484
[] Reachability,
484485
[] MirKeys,

src/librustc/ty/maps/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ define_maps! { <'tcx>
169169
/// The result of unsafety-checking this def-id.
170170
[] fn unsafety_check_result: UnsafetyCheckResult(DefId) -> mir::UnsafetyCheckResult,
171171

172+
/// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error
173+
[] fn unsafe_derive_on_repr_packed: UnsafeDeriveOnReprPacked(DefId) -> (),
174+
172175
/// The signature of functions and closures.
173176
[] fn fn_sig: FnSignature(DefId) -> ty::PolyFnSig<'tcx>,
174177

src/librustc/ty/maps/plumbing.rs

+1
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
768768
DepKind::BorrowCheck => { force!(borrowck, def_id!()); }
769769
DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
770770
DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
771+
DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
771772
DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); }
772773
DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
773774
DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }

src/librustc_mir/transform/check_unsafety.rs

+30-23
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
259259
pub(crate) fn provide(providers: &mut Providers) {
260260
*providers = Providers {
261261
unsafety_check_result,
262+
unsafe_derive_on_repr_packed,
262263
..*providers
263264
};
264265
}
@@ -341,6 +342,27 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
341342
}
342343
}
343344

345+
fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
346+
let lint_node_id = match tcx.hir.as_local_node_id(def_id) {
347+
Some(node_id) => node_id,
348+
None => bug!("checking unsafety for non-local def id {:?}", def_id)
349+
};
350+
351+
// FIXME: when we make this a hard error, this should have its
352+
// own error code.
353+
let message = if !tcx.generics_of(def_id).types.is_empty() {
354+
format!("#[derive] can't be used on a #[repr(packed)] struct with \
355+
type parameters (error E0133)")
356+
} else {
357+
format!("#[derive] can't be used on a non-Copy #[repr(packed)] struct \
358+
(error E0133)")
359+
};
360+
tcx.lint_node(SAFE_PACKED_BORROWS,
361+
lint_node_id,
362+
tcx.def_span(def_id),
363+
&message);
364+
}
365+
344366
/// Return the NodeId for an enclosing scope that is also `unsafe`
345367
fn is_enclosed(tcx: TyCtxt,
346368
used_unsafe: &FxHashSet<ast::NodeId>,
@@ -402,7 +424,6 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
402424
unsafe_blocks
403425
} = tcx.unsafety_check_result(def_id);
404426

405-
let mut emitted_derive_error = false;
406427
for &UnsafetyViolation {
407428
source_info, description, kind
408429
} in violations.iter() {
@@ -423,29 +444,15 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
423444
block (error E0133)", description));
424445
}
425446
UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
426-
if emitted_derive_error {
427-
continue
428-
}
429-
430-
let message = if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
431-
emitted_derive_error = true;
432-
// FIXME: when we make this a hard error, this should have its
433-
// own error code.
434-
if !tcx.generics_of(impl_def_id).types.is_empty() {
435-
format!("#[derive] can't be used on a #[repr(packed)] struct with \
436-
type parameters (error E0133)")
437-
} else {
438-
format!("#[derive] can't be used on a non-Copy #[repr(packed)] struct \
439-
(error E0133)")
440-
}
447+
if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
448+
tcx.unsafe_derive_on_repr_packed(impl_def_id);
441449
} else {
442-
format!("{} requires unsafe function or \
443-
block (error E0133)", description)
444-
};
445-
tcx.lint_node(SAFE_PACKED_BORROWS,
446-
lint_node_id,
447-
source_info.span,
448-
&message);
450+
tcx.lint_node(SAFE_PACKED_BORROWS,
451+
lint_node_id,
452+
source_info.span,
453+
&format!("{} requires unsafe function or \
454+
block (error E0133)", description));
455+
}
449456
}
450457
}
451458
}

src/test/compile-fail/deriving-with-repr-packed-not-copy.rs

-28
This file was deleted.

src/test/ui/deriving-with-repr-packed.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,32 @@
1010

1111
#![deny(safe_packed_borrows)]
1212

13-
// check that deriving a non-Copy packed struct is an error.
13+
// check that derive on a packed struct with non-Copy fields
14+
// correctly. This can't be made to work perfectly because
15+
// we can't just use the field from the struct as it might
16+
// not be aligned.
17+
1418
#[derive(Copy, Clone, PartialEq, Eq)]
15-
#[repr(packed)]
16-
pub struct Foo<T>(T, T, T);
1719
//~^ ERROR #[derive] can't be used
1820
//~| hard error
1921
//~^^^ ERROR #[derive] can't be used
2022
//~| hard error
23+
#[repr(packed)]
24+
pub struct Foo<T>(T, T, T);
25+
2126
#[derive(PartialEq, Eq)]
27+
//~^ ERROR #[derive] can't be used
28+
//~| hard error
2229
#[repr(packed)]
2330
pub struct Bar(u32, u32, u32);
24-
//~^ ERROR #[derive] can't be used
31+
32+
#[derive(PartialEq)]
33+
struct Y(usize);
34+
35+
#[derive(PartialEq)]
36+
//~^ ERROR #[derive] can't be used on a non-Copy #[repr(packed)]
2537
//~| hard error
38+
#[repr(packed)]
39+
struct X(Y);
2640

2741
fn main() {}
+19-10
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: #[derive] can't be used on a #[repr(packed)] struct with type parameters (error E0133)
2-
--> $DIR/deriving-with-repr-packed.rs:16:19
2+
--> $DIR/deriving-with-repr-packed.rs:18:16
33
|
4-
16 | pub struct Foo<T>(T, T, T);
5-
| ^^
4+
18 | #[derive(Copy, Clone, PartialEq, Eq)]
5+
| ^^^^^
66
|
77
note: lint level defined here
88
--> $DIR/deriving-with-repr-packed.rs:11:9
@@ -13,22 +13,31 @@ note: lint level defined here
1313
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
1414

1515
error: #[derive] can't be used on a #[repr(packed)] struct with type parameters (error E0133)
16-
--> $DIR/deriving-with-repr-packed.rs:16:19
16+
--> $DIR/deriving-with-repr-packed.rs:18:23
1717
|
18-
16 | pub struct Foo<T>(T, T, T);
19-
| ^^
18+
18 | #[derive(Copy, Clone, PartialEq, Eq)]
19+
| ^^^^^^^^^
2020
|
2121
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2222
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
2323

2424
error: #[derive] can't be used on a non-Copy #[repr(packed)] struct (error E0133)
25-
--> $DIR/deriving-with-repr-packed.rs:23:16
25+
--> $DIR/deriving-with-repr-packed.rs:26:10
2626
|
27-
23 | pub struct Bar(u32, u32, u32);
28-
| ^^^^
27+
26 | #[derive(PartialEq, Eq)]
28+
| ^^^^^^^^^
2929
|
3030
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3131
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
3232

33-
error: aborting due to 5 previous errors
33+
error: #[derive] can't be used on a non-Copy #[repr(packed)] struct (error E0133)
34+
--> $DIR/deriving-with-repr-packed.rs:35:10
35+
|
36+
35 | #[derive(PartialEq)]
37+
| ^^^^^^^^^
38+
|
39+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
40+
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
41+
42+
error: aborting due to 4 previous errors
3443

0 commit comments

Comments
 (0)