Skip to content

Commit 72f7e31

Browse files
committed
Auto merge of #97679 - Dylan-DPC:rollup-nswmgmx, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #97366 (Stabilize `{slice,array}::from_ref`) - #97653 (add cast kind of from_exposed_addr (int-to-ptr casts)) - #97663 (take back half-baked noaliasing check in Assignment) - #97664 (On E0204 suggest missing type param bounds) - #97668 (rustdoc: clean up primitive.slice.html links) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3a90bed + d6f35b3 commit 72f7e31

33 files changed

+370
-87
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,31 +2154,55 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21542154
match (cast_ty_from, cast_ty_to) {
21552155
(Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => (),
21562156
_ => {
2157-
span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty)
2157+
span_mirbug!(
2158+
self,
2159+
rvalue,
2160+
"Invalid PointerExposeAddress cast {:?} -> {:?}",
2161+
ty_from,
2162+
ty
2163+
)
21582164
}
21592165
}
21602166
}
21612167

2162-
CastKind::Misc => {
2168+
CastKind::PointerFromExposedAddress => {
21632169
let ty_from = op.ty(body, tcx);
21642170
let cast_ty_from = CastTy::from_ty(ty_from);
21652171
let cast_ty_to = CastTy::from_ty(*ty);
21662172
match (cast_ty_from, cast_ty_to) {
2167-
(None, _)
2168-
| (_, None | Some(CastTy::FnPtr))
2169-
| (Some(CastTy::Float), Some(CastTy::Ptr(_)))
2170-
| (
2171-
Some(CastTy::Ptr(_) | CastTy::FnPtr),
2172-
Some(CastTy::Float | CastTy::Int(_)),
2173-
) => {
2174-
span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty,)
2173+
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => (),
2174+
_ => {
2175+
span_mirbug!(
2176+
self,
2177+
rvalue,
2178+
"Invalid PointerFromExposedAddress cast {:?} -> {:?}",
2179+
ty_from,
2180+
ty
2181+
)
21752182
}
2183+
}
2184+
}
2185+
2186+
CastKind::Misc => {
2187+
let ty_from = op.ty(body, tcx);
2188+
let cast_ty_from = CastTy::from_ty(ty_from);
2189+
let cast_ty_to = CastTy::from_ty(*ty);
2190+
// Misc casts are either between floats and ints, or one ptr type to another.
2191+
match (cast_ty_from, cast_ty_to) {
21762192
(
2177-
Some(CastTy::Int(_)),
2178-
Some(CastTy::Int(_) | CastTy::Float | CastTy::Ptr(_)),
2193+
Some(CastTy::Int(_) | CastTy::Float),
2194+
Some(CastTy::Int(_) | CastTy::Float),
21792195
)
2180-
| (Some(CastTy::Float), Some(CastTy::Int(_) | CastTy::Float))
21812196
| (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Ptr(_))) => (),
2197+
_ => {
2198+
span_mirbug!(
2199+
self,
2200+
rvalue,
2201+
"Invalid Misc cast {:?} -> {:?}",
2202+
ty_from,
2203+
ty,
2204+
)
2205+
}
21822206
}
21832207
}
21842208
}

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,9 @@ fn codegen_stmt<'tcx>(
608608
lval.write_cvalue(fx, operand.cast_pointer_to(to_layout));
609609
}
610610
Rvalue::Cast(
611-
CastKind::Misc | CastKind::PointerExposeAddress,
611+
CastKind::Misc
612+
| CastKind::PointerExposeAddress
613+
| CastKind::PointerFromExposedAddress,
612614
ref operand,
613615
to_ty,
614616
) => {

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
269269
mir::CastKind::Pointer(
270270
PointerCast::MutToConstPointer | PointerCast::ArrayToPointer,
271271
)
272-
| mir::CastKind::Misc => {
272+
| mir::CastKind::Misc
273+
// Since int2ptr can have arbitrary integer types as input (so we have to do
274+
// sign extension and all that), it is currently best handled in the same code
275+
// path as the other integer-to-X casts.
276+
| mir::CastKind::PointerFromExposedAddress => {
273277
assert!(bx.cx().is_backend_immediate(cast));
274278
let ll_t_out = bx.cx().immediate_backend_type(cast);
275279
if operand.layout.abi.is_uninhabited() {

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
3737
self.write_immediate(res, dest)?;
3838
}
3939

40+
PointerFromExposedAddress => {
41+
let src = self.read_immediate(src)?;
42+
let res = self.pointer_from_exposed_address_cast(&src, cast_ty)?;
43+
self.write_immediate(res, dest)?;
44+
}
45+
4046
Misc => {
4147
let src = self.read_immediate(src)?;
4248
let res = self.misc_cast(&src, cast_ty)?;
@@ -201,6 +207,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
201207
Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
202208
}
203209

210+
pub fn pointer_from_exposed_address_cast(
211+
&mut self,
212+
src: &ImmTy<'tcx, M::PointerTag>,
213+
cast_ty: Ty<'tcx>,
214+
) -> InterpResult<'tcx, Immediate<M::PointerTag>> {
215+
assert!(src.layout.ty.is_integral());
216+
assert_matches!(cast_ty.kind(), ty::RawPtr(_));
217+
218+
// First cast to usize.
219+
let scalar = src.to_scalar()?;
220+
let addr = self.cast_from_int_like(scalar, src.layout, self.tcx.types.usize)?;
221+
let addr = addr.to_machine_usize(self)?;
222+
223+
// Then turn address into pointer.
224+
let ptr = M::ptr_from_addr_cast(&self, addr);
225+
Ok(Scalar::from_maybe_pointer(ptr, self).into())
226+
}
227+
204228
pub fn cast_from_int_like(
205229
&self,
206230
scalar: Scalar<M::PointerTag>, // input value (there is no ScalarTy so we separate data+layout)
@@ -225,16 +249,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
225249
Scalar::from_uint(v, size)
226250
}
227251

228-
RawPtr(_) => {
229-
assert!(src_layout.ty.is_integral());
230-
231-
let size = self.pointer_size();
232-
let addr = u64::try_from(size.truncate(v)).unwrap();
233-
234-
let ptr = M::ptr_from_addr_cast(&self, addr);
235-
Scalar::from_maybe_pointer(ptr, self)
236-
}
237-
238252
Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value),
239253
Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value),
240254
Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value),

compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -869,8 +869,6 @@ where
869869
Ok(src_val) => {
870870
assert!(!src.layout.is_unsized(), "cannot have unsized immediates");
871871
// Yay, we got a value that we can write directly.
872-
// FIXME: Add a check to make sure that if `src` is indirect,
873-
// it does not overlap with `dest`.
874872
return self.write_immediate_no_validate(*src_val, dest);
875873
}
876874
Err(mplace) => mplace,
@@ -890,7 +888,7 @@ where
890888
});
891889
assert_eq!(src.meta, dest.meta, "Can only copy between equally-sized instances");
892890

893-
self.mem_copy(src.ptr, src.align, dest.ptr, dest.align, size, /*nonoverlapping*/ true)
891+
self.mem_copy(src.ptr, src.align, dest.ptr, dest.align, size, /*nonoverlapping*/ false)
894892
}
895893

896894
/// Copies the data from an operand to a place. The layouts may disagree, but they must

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
158158
place: mir::Place<'tcx>,
159159
) -> InterpResult<'tcx> {
160160
let dest = self.eval_place(place)?;
161+
// FIXME: ensure some kind of non-aliasing between LHS and RHS?
162+
// Also see https://github.com/rust-lang/rust/issues/68364.
161163

162164
use rustc_middle::mir::Rvalue::*;
163165
match *rvalue {

compiler/rustc_const_eval/src/transform/check_consts/check.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -519,32 +519,30 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
519519
}
520520
}
521521

522-
Rvalue::Cast(
523-
CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
524-
_,
525-
_,
526-
) => {}
527-
528522
Rvalue::Cast(
529523
CastKind::Pointer(
530-
PointerCast::UnsafeFnPointer
524+
PointerCast::MutToConstPointer
525+
| PointerCast::ArrayToPointer
526+
| PointerCast::UnsafeFnPointer
531527
| PointerCast::ClosureFnPointer(_)
532528
| PointerCast::ReifyFnPointer,
533529
),
534530
_,
535531
_,
536532
) => {
537-
// Nothing to do here. Function pointer casts are allowed now.
533+
// These are all okay; they only change the type, not the data.
538534
}
539535

540536
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
541-
// Nothing to check here (`check_local_or_return_ty` ensures no trait objects occur
542-
// in the type of any local, which also excludes casts).
537+
// Unsizing is implemented for CTFE.
543538
}
544539

545540
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
546541
self.check_op(ops::RawPtrToIntCast);
547542
}
543+
Rvalue::Cast(CastKind::PointerFromExposedAddress, _, _) => {
544+
// Since no pointer can ever get exposed (rejected above), this is easy to support.
545+
}
548546

549547
Rvalue::Cast(CastKind::Misc, _, _) => {}
550548

compiler/rustc_const_eval/src/transform/promote_consts.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,8 @@ impl<'tcx> Validator<'_, 'tcx> {
504504
// ptr-to-int casts are not possible in consts and thus not promotable
505505
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => return Err(Unpromotable),
506506

507-
// int-to-ptr casts are fine, they just use the integer value at pointer type.
507+
// all other casts including int-to-ptr casts are fine, they just use the integer value
508+
// at pointer type.
508509
Rvalue::Cast(_, operand, _) => {
509510
self.validate_operand(operand)?;
510511
}

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2613,12 +2613,18 @@ impl<'tcx> Rvalue<'tcx> {
26132613

26142614
#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
26152615
pub enum CastKind {
2616-
Misc,
26172616
/// An exposing pointer to address cast. A cast between a pointer and an integer type, or
26182617
/// between a function pointer and an integer type.
26192618
/// See the docs on `expose_addr` for more details.
26202619
PointerExposeAddress,
2620+
/// An address-to-pointer cast that picks up an exposed provenance.
2621+
/// See the docs on `from_exposed_addr` for more details.
2622+
PointerFromExposedAddress,
2623+
/// All sorts of pointer-to-pointer casts. Note that reference-to-raw-ptr casts are
2624+
/// translated into `&raw mut/const *r`, i.e., they are not actually casts.
26212625
Pointer(PointerCast),
2626+
/// Remaining unclassified casts.
2627+
Misc,
26222628
}
26232629

26242630
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]

compiler/rustc_middle/src/ty/diagnostics.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,10 @@ pub fn suggest_constraining_type_params<'a>(
272272
continue;
273273
}
274274

275-
let constraint = constraints.iter().map(|&(c, _)| c).collect::<Vec<_>>().join(" + ");
275+
let mut constraint = constraints.iter().map(|&(c, _)| c).collect::<Vec<_>>();
276+
constraint.sort();
277+
constraint.dedup();
278+
let constraint = constraint.join(" + ");
276279
let mut suggest_restrict = |span, bound_list_non_empty| {
277280
suggestions.push((
278281
span,

0 commit comments

Comments
 (0)