Skip to content

Commit 0030465

Browse files
committed
Auto merge of #109413 - compiler-errors:pointer-like-abi, r=cjgillot
Enforce that `PointerLike` requires a pointer-like ABI At least temporarily, let's ban coercing things that are pointer-sized and pointer-aligned but *not* `Abi::Scalar(..)` into `dyn*`. See: #104694 (comment) This can be lifted in the future if we decie that we *want* to be able to coerce something `repr(C)` into a `dyn*`, but we'll have to figure out what to do with Miri and codegen... r? compiler
2 parents f8ed97e + 920c51c commit 0030465

14 files changed

+41
-25
lines changed

compiler/rustc_abi/src/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,16 @@ impl<'a> Layout<'a> {
15221522
pub fn size(self) -> Size {
15231523
self.0.0.size
15241524
}
1525+
1526+
/// Whether the layout is from a type that implements [`std::marker::PointerLike`].
1527+
///
1528+
/// Currently, that means that the type is pointer-sized, pointer-aligned,
1529+
/// and has a scalar ABI.
1530+
pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool {
1531+
self.size() == data_layout.pointer_size
1532+
&& self.align().abi == data_layout.pointer_align.abi
1533+
&& matches!(self.abi(), Abi::Scalar(..))
1534+
}
15251535
}
15261536

15271537
#[derive(Copy, Clone, PartialEq, Eq, Debug)]

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
221221
let self_ty = tcx.erase_regions(goal.predicate.self_ty());
222222

223223
if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
224-
&& layout.layout.size() == tcx.data_layout.pointer_size
225-
&& layout.layout.align().abi == tcx.data_layout.pointer_align.abi
224+
&& layout.layout.is_pointer_like(&tcx.data_layout)
226225
{
227226
// FIXME: We could make this faster by making a no-constraints response
228227
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
9797
} else if lang_items.tuple_trait() == Some(def_id) {
9898
self.assemble_candidate_for_tuple(obligation, &mut candidates);
9999
} else if lang_items.pointer_like() == Some(def_id) {
100-
self.assemble_candidate_for_ptr_sized(obligation, &mut candidates);
100+
self.assemble_candidate_for_pointer_like(obligation, &mut candidates);
101101
} else if lang_items.fn_ptr_trait() == Some(def_id) {
102102
self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
103103
} else {
@@ -942,25 +942,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
942942
}
943943
}
944944

945-
fn assemble_candidate_for_ptr_sized(
945+
fn assemble_candidate_for_pointer_like(
946946
&mut self,
947947
obligation: &TraitObligation<'tcx>,
948948
candidates: &mut SelectionCandidateSet<'tcx>,
949949
) {
950950
// The regions of a type don't affect the size of the type
951-
let self_ty = self
952-
.tcx()
953-
.erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate.self_ty()));
951+
let tcx = self.tcx();
952+
let self_ty =
953+
tcx.erase_regions(tcx.erase_late_bound_regions(obligation.predicate.self_ty()));
954954

955955
// But if there are inference variables, we have to wait until it's resolved.
956956
if self_ty.has_non_region_infer() {
957957
candidates.ambiguous = true;
958958
return;
959959
}
960960

961-
if let Ok(layout) = self.tcx().layout_of(obligation.param_env.and(self_ty))
962-
&& layout.layout.size() == self.tcx().data_layout.pointer_size
963-
&& layout.layout.align().abi == self.tcx().data_layout.pointer_align.abi
961+
if let Ok(layout) = tcx.layout_of(obligation.param_env.and(self_ty))
962+
&& layout.layout.is_pointer_like(&tcx.data_layout)
964963
{
965964
candidates.vec.push(BuiltinCandidate { has_nested: false });
966965
}

library/core/src/marker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ pub trait Tuple {}
879879
#[unstable(feature = "pointer_like_trait", issue = "none")]
880880
#[lang = "pointer_like"]
881881
#[rustc_on_unimplemented(
882-
message = "`{Self}` needs to have the same alignment and size as a pointer",
882+
message = "`{Self}` needs to have the same ABI as a pointer",
883883
label = "`{Self}` needs to be a pointer-like type"
884884
)]
885885
pub trait PointerLike {}

tests/ui/dyn-star/align.normal.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/align.rs:4:12
2+
--> $DIR/align.rs:3:12
33
|
44
LL | #![feature(dyn_star)]
55
| ^^^^^^^^
66
|
77
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
warning: 1 warning emitted
10+
error[E0277]: `AlignedUsize` needs to have the same ABI as a pointer
11+
--> $DIR/align.rs:14:13
12+
|
13+
LL | let x = AlignedUsize(12) as dyn* Debug;
14+
| ^^^^^^^^^^^^^^^^ `AlignedUsize` needs to be a pointer-like type
15+
|
16+
= help: the trait `PointerLike` is not implemented for `AlignedUsize`
17+
18+
error: aborting due to previous error; 1 warning emitted
1119

20+
For more information about this error, try `rustc --explain E0277`.

tests/ui/dyn-star/align.over_aligned.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/align.rs:4:12
2+
--> $DIR/align.rs:3:12
33
|
44
LL | #![feature(dyn_star)]
55
| ^^^^^^^^
66
|
77
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
error[E0277]: `AlignedUsize` needs to have the same alignment and size as a pointer
11-
--> $DIR/align.rs:15:13
10+
error[E0277]: `AlignedUsize` needs to have the same ABI as a pointer
11+
--> $DIR/align.rs:14:13
1212
|
1313
LL | let x = AlignedUsize(12) as dyn* Debug;
1414
| ^^^^^^^^^^^^^^^^ `AlignedUsize` needs to be a pointer-like type

tests/ui/dyn-star/align.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// revisions: normal over_aligned
2-
//[normal] check-pass
32

43
#![feature(dyn_star)]
54
//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
@@ -13,5 +12,5 @@ struct AlignedUsize(usize);
1312

1413
fn main() {
1514
let x = AlignedUsize(12) as dyn* Debug;
16-
//[over_aligned]~^ ERROR `AlignedUsize` needs to have the same alignment and size as a pointer
15+
//~^ ERROR `AlignedUsize` needs to have the same ABI as a pointer
1716
}

tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fn dyn_debug(_: (dyn* Debug + '_)) {
99

1010
fn polymorphic<T: Debug + ?Sized>(t: &T) {
1111
dyn_debug(t);
12-
//~^ ERROR `&T` needs to have the same alignment and size as a pointer
12+
//~^ ERROR `&T` needs to have the same ABI as a pointer
1313
}
1414

1515
fn main() {}

tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: `&T` needs to have the same alignment and size as a pointer
1+
error[E0277]: `&T` needs to have the same ABI as a pointer
22
--> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15
33
|
44
LL | dyn_debug(t);

tests/ui/dyn-star/check-size-at-cast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ use std::fmt::Debug;
55

66
fn main() {
77
let i = [1, 2, 3, 4] as dyn* Debug;
8-
//~^ ERROR `[i32; 4]` needs to have the same alignment and size as a pointer
8+
//~^ ERROR `[i32; 4]` needs to have the same ABI as a pointer
99
dbg!(i);
1010
}

tests/ui/dyn-star/check-size-at-cast.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: `[i32; 4]` needs to have the same alignment and size as a pointer
1+
error[E0277]: `[i32; 4]` needs to have the same ABI as a pointer
22
--> $DIR/check-size-at-cast.rs:7:13
33
|
44
LL | let i = [1, 2, 3, 4] as dyn* Debug;

tests/ui/dyn-star/upcast.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | #![feature(dyn_star, trait_upcasting)]
77
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
error[E0277]: `dyn* Foo` needs to have the same alignment and size as a pointer
10+
error[E0277]: `dyn* Foo` needs to have the same ABI as a pointer
1111
--> $DIR/upcast.rs:30:23
1212
|
1313
LL | let w: dyn* Bar = w;

tests/ui/traits/new-solver/pointer-like.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ fn require_(_: impl PointerLike) {}
99
fn main() {
1010
require_(1usize);
1111
require_(1u16);
12-
//~^ ERROR `u16` needs to have the same alignment and size as a pointer
12+
//~^ ERROR `u16` needs to have the same ABI as a pointer
1313
require_(&1i16);
1414
}

tests/ui/traits/new-solver/pointer-like.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: `u16` needs to have the same alignment and size as a pointer
1+
error[E0277]: `u16` needs to have the same ABI as a pointer
22
--> $DIR/pointer-like.rs:11:14
33
|
44
LL | require_(1u16);

0 commit comments

Comments
 (0)