mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Enforce that PointerLike requires a pointer-like ABI
This commit is contained in:
parent
dd2b19539e
commit
920c51c526
@ -1522,6 +1522,16 @@ impl<'a> Layout<'a> {
|
|||||||
pub fn size(self) -> Size {
|
pub fn size(self) -> Size {
|
||||||
self.0.0.size
|
self.0.0.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether the layout is from a type that implements [`std::marker::PointerLike`].
|
||||||
|
///
|
||||||
|
/// Currently, that means that the type is pointer-sized, pointer-aligned,
|
||||||
|
/// and has a scalar ABI.
|
||||||
|
pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool {
|
||||||
|
self.size() == data_layout.pointer_size
|
||||||
|
&& self.align().abi == data_layout.pointer_align.abi
|
||||||
|
&& matches!(self.abi(), Abi::Scalar(..))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
@ -221,8 +221,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||||||
let self_ty = tcx.erase_regions(goal.predicate.self_ty());
|
let self_ty = tcx.erase_regions(goal.predicate.self_ty());
|
||||||
|
|
||||||
if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
|
if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
|
||||||
&& layout.layout.size() == tcx.data_layout.pointer_size
|
&& layout.layout.is_pointer_like(&tcx.data_layout)
|
||||||
&& layout.layout.align().abi == tcx.data_layout.pointer_align.abi
|
|
||||||
{
|
{
|
||||||
// FIXME: We could make this faster by making a no-constraints response
|
// FIXME: We could make this faster by making a no-constraints response
|
||||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
|
@ -97,7 +97,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
} else if lang_items.tuple_trait() == Some(def_id) {
|
} else if lang_items.tuple_trait() == Some(def_id) {
|
||||||
self.assemble_candidate_for_tuple(obligation, &mut candidates);
|
self.assemble_candidate_for_tuple(obligation, &mut candidates);
|
||||||
} else if lang_items.pointer_like() == Some(def_id) {
|
} else if lang_items.pointer_like() == Some(def_id) {
|
||||||
self.assemble_candidate_for_ptr_sized(obligation, &mut candidates);
|
self.assemble_candidate_for_pointer_like(obligation, &mut candidates);
|
||||||
} else if lang_items.fn_ptr_trait() == Some(def_id) {
|
} else if lang_items.fn_ptr_trait() == Some(def_id) {
|
||||||
self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
|
self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
|
||||||
} else {
|
} else {
|
||||||
@ -942,15 +942,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assemble_candidate_for_ptr_sized(
|
fn assemble_candidate_for_pointer_like(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) {
|
) {
|
||||||
// The regions of a type don't affect the size of the type
|
// The regions of a type don't affect the size of the type
|
||||||
let self_ty = self
|
let tcx = self.tcx();
|
||||||
.tcx()
|
let self_ty =
|
||||||
.erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate.self_ty()));
|
tcx.erase_regions(tcx.erase_late_bound_regions(obligation.predicate.self_ty()));
|
||||||
|
|
||||||
// But if there are inference variables, we have to wait until it's resolved.
|
// But if there are inference variables, we have to wait until it's resolved.
|
||||||
if self_ty.has_non_region_infer() {
|
if self_ty.has_non_region_infer() {
|
||||||
@ -958,9 +958,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(layout) = self.tcx().layout_of(obligation.param_env.and(self_ty))
|
if let Ok(layout) = tcx.layout_of(obligation.param_env.and(self_ty))
|
||||||
&& layout.layout.size() == self.tcx().data_layout.pointer_size
|
&& layout.layout.is_pointer_like(&tcx.data_layout)
|
||||||
&& layout.layout.align().abi == self.tcx().data_layout.pointer_align.abi
|
|
||||||
{
|
{
|
||||||
candidates.vec.push(BuiltinCandidate { has_nested: false });
|
candidates.vec.push(BuiltinCandidate { has_nested: false });
|
||||||
}
|
}
|
||||||
|
@ -879,7 +879,7 @@ pub trait Tuple {}
|
|||||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||||
#[lang = "pointer_like"]
|
#[lang = "pointer_like"]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
message = "`{Self}` needs to have the same alignment and size as a pointer",
|
message = "`{Self}` needs to have the same ABI as a pointer",
|
||||||
label = "`{Self}` needs to be a pointer-like type"
|
label = "`{Self}` needs to be a pointer-like type"
|
||||||
)]
|
)]
|
||||||
pub trait PointerLike {}
|
pub trait PointerLike {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
--> $DIR/align.rs:4:12
|
--> $DIR/align.rs:3:12
|
||||||
|
|
|
|
||||||
LL | #![feature(dyn_star)]
|
LL | #![feature(dyn_star)]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
@ -7,5 +7,14 @@ LL | #![feature(dyn_star)]
|
|||||||
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
|
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
warning: 1 warning emitted
|
error[E0277]: `AlignedUsize` needs to have the same ABI as a pointer
|
||||||
|
--> $DIR/align.rs:14:13
|
||||||
|
|
|
||||||
|
LL | let x = AlignedUsize(12) as dyn* Debug;
|
||||||
|
| ^^^^^^^^^^^^^^^^ `AlignedUsize` needs to be a pointer-like type
|
||||||
|
|
|
||||||
|
= help: the trait `PointerLike` is not implemented for `AlignedUsize`
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
--> $DIR/align.rs:4:12
|
--> $DIR/align.rs:3:12
|
||||||
|
|
|
|
||||||
LL | #![feature(dyn_star)]
|
LL | #![feature(dyn_star)]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
@ -7,8 +7,8 @@ LL | #![feature(dyn_star)]
|
|||||||
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
|
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error[E0277]: `AlignedUsize` needs to have the same alignment and size as a pointer
|
error[E0277]: `AlignedUsize` needs to have the same ABI as a pointer
|
||||||
--> $DIR/align.rs:15:13
|
--> $DIR/align.rs:14:13
|
||||||
|
|
|
|
||||||
LL | let x = AlignedUsize(12) as dyn* Debug;
|
LL | let x = AlignedUsize(12) as dyn* Debug;
|
||||||
| ^^^^^^^^^^^^^^^^ `AlignedUsize` needs to be a pointer-like type
|
| ^^^^^^^^^^^^^^^^ `AlignedUsize` needs to be a pointer-like type
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
// revisions: normal over_aligned
|
// revisions: normal over_aligned
|
||||||
//[normal] check-pass
|
|
||||||
|
|
||||||
#![feature(dyn_star)]
|
#![feature(dyn_star)]
|
||||||
//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
//~^ 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);
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = AlignedUsize(12) as dyn* Debug;
|
let x = AlignedUsize(12) as dyn* Debug;
|
||||||
//[over_aligned]~^ ERROR `AlignedUsize` needs to have the same alignment and size as a pointer
|
//~^ ERROR `AlignedUsize` needs to have the same ABI as a pointer
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ fn dyn_debug(_: (dyn* Debug + '_)) {
|
|||||||
|
|
||||||
fn polymorphic<T: Debug + ?Sized>(t: &T) {
|
fn polymorphic<T: Debug + ?Sized>(t: &T) {
|
||||||
dyn_debug(t);
|
dyn_debug(t);
|
||||||
//~^ ERROR `&T` needs to have the same alignment and size as a pointer
|
//~^ ERROR `&T` needs to have the same ABI as a pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error[E0277]: `&T` needs to have the same alignment and size as a pointer
|
error[E0277]: `&T` needs to have the same ABI as a pointer
|
||||||
--> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15
|
--> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15
|
||||||
|
|
|
|
||||||
LL | dyn_debug(t);
|
LL | dyn_debug(t);
|
||||||
|
@ -5,6 +5,6 @@ use std::fmt::Debug;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let i = [1, 2, 3, 4] as dyn* Debug;
|
let i = [1, 2, 3, 4] as dyn* Debug;
|
||||||
//~^ ERROR `[i32; 4]` needs to have the same alignment and size as a pointer
|
//~^ ERROR `[i32; 4]` needs to have the same ABI as a pointer
|
||||||
dbg!(i);
|
dbg!(i);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error[E0277]: `[i32; 4]` needs to have the same alignment and size as a pointer
|
error[E0277]: `[i32; 4]` needs to have the same ABI as a pointer
|
||||||
--> $DIR/check-size-at-cast.rs:7:13
|
--> $DIR/check-size-at-cast.rs:7:13
|
||||||
|
|
|
|
||||||
LL | let i = [1, 2, 3, 4] as dyn* Debug;
|
LL | let i = [1, 2, 3, 4] as dyn* Debug;
|
||||||
|
@ -7,7 +7,7 @@ LL | #![feature(dyn_star, trait_upcasting)]
|
|||||||
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
|
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error[E0277]: `dyn* Foo` needs to have the same alignment and size as a pointer
|
error[E0277]: `dyn* Foo` needs to have the same ABI as a pointer
|
||||||
--> $DIR/upcast.rs:30:23
|
--> $DIR/upcast.rs:30:23
|
||||||
|
|
|
|
||||||
LL | let w: dyn* Bar = w;
|
LL | let w: dyn* Bar = w;
|
||||||
|
@ -9,6 +9,6 @@ fn require_(_: impl PointerLike) {}
|
|||||||
fn main() {
|
fn main() {
|
||||||
require_(1usize);
|
require_(1usize);
|
||||||
require_(1u16);
|
require_(1u16);
|
||||||
//~^ ERROR `u16` needs to have the same alignment and size as a pointer
|
//~^ ERROR `u16` needs to have the same ABI as a pointer
|
||||||
require_(&1i16);
|
require_(&1i16);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error[E0277]: `u16` needs to have the same alignment and size as a pointer
|
error[E0277]: `u16` needs to have the same ABI as a pointer
|
||||||
--> $DIR/pointer-like.rs:11:14
|
--> $DIR/pointer-like.rs:11:14
|
||||||
|
|
|
|
||||||
LL | require_(1u16);
|
LL | require_(1u16);
|
||||||
|
Loading…
Reference in New Issue
Block a user