Skip to content

Commit 8239a37

Browse files
committed
Auto merge of rust-lang#136389 - matthiaskrgr:rollup-x453dy9, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#130514 (Implement MIR lowering for unsafe binders) - rust-lang#135684 (docs: Documented Send and Sync requirements for Mutex + MutexGuard) - rust-lang#136307 (Implement all mix/max functions in a (hopefully) more optimization amendable way) - rust-lang#136360 (Stabilize `once_wait`) - rust-lang#136364 (document that ptr cmp is unsigned) - rust-lang#136374 (Add link attribute for Enzyme's LLVMRust FFI) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e08cd3c + 2a82ebd commit 8239a37

File tree

63 files changed

+774
-149
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+774
-149
lines changed

compiler/rustc_ast/src/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,7 @@ impl GenBlockKind {
16571657
}
16581658

16591659
/// Whether we're unwrapping or wrapping an unsafe binder
1660-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1660+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
16611661
#[derive(Encodable, Decodable, HashStable_Generic)]
16621662
pub enum UnsafeBinderCastKind {
16631663
// e.g. `&i32` -> `unsafe<'a> &'a i32`

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3915,7 +3915,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
39153915
ProjectionElem::ConstantIndex { .. }
39163916
| ProjectionElem::Subslice { .. }
39173917
| ProjectionElem::Subtype(_)
3918-
| ProjectionElem::Index(_) => kind,
3918+
| ProjectionElem::Index(_)
3919+
| ProjectionElem::UnwrapUnsafeBinder(_) => kind,
39193920
},
39203921
place_ty.projection_ty(tcx, elem),
39213922
)

compiler/rustc_borrowck/src/diagnostics/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
370370
ProjectionElem::Downcast(..) => (),
371371
ProjectionElem::OpaqueCast(..) => (),
372372
ProjectionElem::Subtype(..) => (),
373+
ProjectionElem::UnwrapUnsafeBinder(_) => (),
373374
ProjectionElem::Field(field, _ty) => {
374375
// FIXME(project-rfc_2229#36): print capture precisely here.
375376
if let Some(field) = self.is_upvar_field_projection(PlaceRef {
@@ -450,9 +451,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
450451
PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
451452
}
452453
ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
453-
ProjectionElem::Subtype(ty) | ProjectionElem::OpaqueCast(ty) => {
454-
PlaceTy::from_ty(*ty)
455-
}
454+
ProjectionElem::Subtype(ty)
455+
| ProjectionElem::OpaqueCast(ty)
456+
| ProjectionElem::UnwrapUnsafeBinder(ty) => PlaceTy::from_ty(*ty),
456457
ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
457458
},
458459
};

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
167167
| ProjectionElem::ConstantIndex { .. }
168168
| ProjectionElem::OpaqueCast { .. }
169169
| ProjectionElem::Subslice { .. }
170-
| ProjectionElem::Downcast(..),
170+
| ProjectionElem::Downcast(..)
171+
| ProjectionElem::UnwrapUnsafeBinder(_),
171172
],
172173
} => bug!("Unexpected immutable place."),
173174
}

compiler/rustc_borrowck/src/lib.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
13981398
self.consume_operand(location, (operand, span), state);
13991399
}
14001400
}
1401+
1402+
Rvalue::WrapUnsafeBinder(op, _) => {
1403+
self.consume_operand(location, (op, span), state);
1404+
}
14011405
}
14021406
}
14031407

@@ -1770,7 +1774,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
17701774
// So it's safe to skip these.
17711775
ProjectionElem::OpaqueCast(_)
17721776
| ProjectionElem::Subtype(_)
1773-
| ProjectionElem::Downcast(_, _) => (),
1777+
| ProjectionElem::Downcast(_, _)
1778+
| ProjectionElem::UnwrapUnsafeBinder(_) => (),
17741779
}
17751780

17761781
place_ty = place_ty.projection_ty(tcx, elem);
@@ -2004,6 +2009,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
20042009
// FIXME: is this true even if P is an adt with a dtor?
20052010
{ }
20062011

2012+
ProjectionElem::UnwrapUnsafeBinder(_) => {
2013+
check_parent_of_field(self, location, place_base, span, state);
2014+
}
2015+
20072016
// assigning to (*P) requires P to be initialized
20082017
ProjectionElem::Deref => {
20092018
self.check_if_full_path_is_moved(
@@ -2384,7 +2393,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
23842393
| ProjectionElem::Subslice { .. }
23852394
| ProjectionElem::Subtype(..)
23862395
| ProjectionElem::OpaqueCast { .. }
2387-
| ProjectionElem::Downcast(..) => {
2396+
| ProjectionElem::Downcast(..)
2397+
| ProjectionElem::UnwrapUnsafeBinder(_) => {
23882398
let upvar_field_projection = self.is_upvar_field_projection(place);
23892399
if let Some(field) = upvar_field_projection {
23902400
let upvar = &self.upvars[field.index()];

compiler/rustc_borrowck/src/places_conflict.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,8 @@ fn place_components_conflict<'tcx>(
250250
| (ProjectionElem::Subslice { .. }, _, _)
251251
| (ProjectionElem::OpaqueCast { .. }, _, _)
252252
| (ProjectionElem::Subtype(_), _, _)
253-
| (ProjectionElem::Downcast { .. }, _, _) => {
253+
| (ProjectionElem::Downcast { .. }, _, _)
254+
| (ProjectionElem::UnwrapUnsafeBinder(_), _, _) => {
254255
// Recursive case. This can still be disjoint on a
255256
// further iteration if this a shallow access and
256257
// there's a deref later on, e.g., a borrow
@@ -519,5 +520,9 @@ fn place_projection_conflict<'tcx>(
519520
pi1_elem,
520521
pi2_elem
521522
),
523+
524+
(ProjectionElem::UnwrapUnsafeBinder(_), _) => {
525+
todo!()
526+
}
522527
}
523528
}

compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs

+4
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
325325
self.consume_operand(location, operand);
326326
}
327327
}
328+
329+
Rvalue::WrapUnsafeBinder(op, _) => {
330+
self.consume_operand(location, op);
331+
}
328332
}
329333
}
330334

compiler/rustc_borrowck/src/prefixes.rs

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ impl<'tcx> Iterator for Prefixes<'tcx> {
6666
self.next = Some(cursor_base);
6767
return Some(cursor);
6868
}
69+
ProjectionElem::UnwrapUnsafeBinder(_) => {
70+
self.next = Some(cursor_base);
71+
return Some(cursor);
72+
}
6973
ProjectionElem::Downcast(..)
7074
| ProjectionElem::Subslice { .. }
7175
| ProjectionElem::OpaqueCast { .. }

compiler/rustc_borrowck/src/type_check/mod.rs

+44-2
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,25 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
302302
)
303303
.unwrap();
304304
}
305+
ProjectionElem::UnwrapUnsafeBinder(ty) => {
306+
let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else {
307+
unreachable!();
308+
};
309+
let found_ty = self.typeck.infcx.instantiate_binder_with_fresh_vars(
310+
self.body().source_info(location).span,
311+
BoundRegionConversionTime::HigherRankedType,
312+
binder_ty.into(),
313+
);
314+
self.typeck
315+
.relate_types(
316+
ty,
317+
context.ambient_variance(),
318+
found_ty,
319+
location.to_locations(),
320+
ConstraintCategory::Boring,
321+
)
322+
.unwrap();
323+
}
305324
ProjectionElem::Subtype(_) => {
306325
bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
307326
}
@@ -2233,6 +2252,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22332252
self.check_operand(right, location);
22342253
}
22352254

2255+
Rvalue::WrapUnsafeBinder(op, ty) => {
2256+
self.check_operand(op, location);
2257+
let operand_ty = op.ty(self.body, self.tcx());
2258+
2259+
let ty::UnsafeBinder(binder_ty) = *ty.kind() else {
2260+
unreachable!();
2261+
};
2262+
let expected_ty = self.infcx.instantiate_binder_with_fresh_vars(
2263+
self.body().source_info(location).span,
2264+
BoundRegionConversionTime::HigherRankedType,
2265+
binder_ty.into(),
2266+
);
2267+
self.sub_types(
2268+
operand_ty,
2269+
expected_ty,
2270+
location.to_locations(),
2271+
ConstraintCategory::Boring,
2272+
)
2273+
.unwrap();
2274+
}
2275+
22362276
Rvalue::RawPtr(..)
22372277
| Rvalue::ThreadLocalRef(..)
22382278
| Rvalue::Len(..)
@@ -2258,7 +2298,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22582298
| Rvalue::NullaryOp(..)
22592299
| Rvalue::CopyForDeref(..)
22602300
| Rvalue::UnaryOp(..)
2261-
| Rvalue::Discriminant(..) => None,
2301+
| Rvalue::Discriminant(..)
2302+
| Rvalue::WrapUnsafeBinder(..) => None,
22622303

22632304
Rvalue::Aggregate(aggregate, _) => match **aggregate {
22642305
AggregateKind::Adt(_, _, _, user_ty, _) => user_ty,
@@ -2450,7 +2491,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24502491
| ProjectionElem::OpaqueCast(..)
24512492
| ProjectionElem::Index(..)
24522493
| ProjectionElem::ConstantIndex { .. }
2453-
| ProjectionElem::Subslice { .. } => {
2494+
| ProjectionElem::Subslice { .. }
2495+
| ProjectionElem::UnwrapUnsafeBinder(_) => {
24542496
// other field access
24552497
}
24562498
ProjectionElem::Subtype(_) => {

compiler/rustc_codegen_cranelift/src/base.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,10 @@ fn codegen_stmt<'tcx>(
925925
}
926926
crate::discriminant::codegen_set_discriminant(fx, lval, variant_index);
927927
}
928+
Rvalue::WrapUnsafeBinder(ref operand, _to_ty) => {
929+
let operand = codegen_operand(fx, operand);
930+
lval.write_cvalue_transmute(fx, operand);
931+
}
928932
}
929933
}
930934
StatementKind::StorageLive(_)
@@ -993,7 +997,9 @@ pub(crate) fn codegen_place<'tcx>(
993997
cplace = cplace.place_deref(fx);
994998
}
995999
PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
996-
PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty)),
1000+
PlaceElem::Subtype(ty) | PlaceElem::UnwrapUnsafeBinder(ty) => {
1001+
cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty));
1002+
}
9971003
PlaceElem::Field(field, _ty) => {
9981004
cplace = cplace.place_field(fx, field);
9991005
}

compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use libc::{c_char, c_uint};
44

55
use super::ffi::{BasicBlock, Metadata, Module, Type, Value};
66
use crate::llvm::Bool;
7+
8+
#[link(name = "llvm-wrapper", kind = "static")]
79
extern "C" {
810
// Enzyme
911
pub fn LLVMRustHasMetadata(I: &Value, KindID: c_uint) -> bool;
@@ -12,10 +14,13 @@ extern "C" {
1214
pub fn LLVMRustDIGetInstMetadata(I: &Value) -> Option<&Metadata>;
1315
pub fn LLVMRustEraseInstFromParent(V: &Value);
1416
pub fn LLVMRustGetTerminator<'a>(B: &BasicBlock) -> &'a Value;
15-
pub fn LLVMDumpModule(M: &Module);
16-
pub fn LLVMDumpValue(V: &Value);
1717
pub fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool;
18+
}
1819

20+
extern "C" {
21+
// Enzyme
22+
pub fn LLVMDumpModule(M: &Module);
23+
pub fn LLVMDumpValue(V: &Value);
1924
pub fn LLVMGetFunctionCallConv(F: &Value) -> c_uint;
2025
pub fn LLVMGetReturnType(T: &Type) -> &Type;
2126
pub fn LLVMGetParams(Fnc: &Value, parms: *mut &Value);

compiler/rustc_codegen_ssa/src/mir/place.rs

+3
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
502502
bug!("encountered OpaqueCast({ty}) in codegen")
503503
}
504504
mir::ProjectionElem::Subtype(ty) => cg_base.project_type(bx, self.monomorphize(ty)),
505+
mir::ProjectionElem::UnwrapUnsafeBinder(ty) => {
506+
cg_base.project_type(bx, self.monomorphize(ty))
507+
}
505508
mir::ProjectionElem::Index(index) => {
506509
let index = &mir::Operand::Copy(mir::Place::from(index));
507510
let index = self.codegen_operand(bx, index);

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
823823

824824
OperandRef { val: OperandValue::Immediate(val), layout: box_layout }
825825
}
826+
mir::Rvalue::WrapUnsafeBinder(ref operand, binder_ty) => {
827+
let operand = self.codegen_operand(bx, operand);
828+
let binder_ty = self.monomorphize(binder_ty);
829+
let layout = bx.cx().layout_of(binder_ty);
830+
OperandRef { val: operand.val, layout }
831+
}
826832
}
827833
}
828834

@@ -1123,7 +1129,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11231129
mir::Rvalue::Discriminant(..) |
11241130
mir::Rvalue::NullaryOp(..) |
11251131
mir::Rvalue::ThreadLocalRef(_) |
1126-
mir::Rvalue::Use(..) => // (*)
1132+
mir::Rvalue::Use(..) |
1133+
mir::Rvalue::WrapUnsafeBinder(..) => // (*)
11271134
true,
11281135
// Arrays are always aggregates, so it's not worth checking anything here.
11291136
// (If it's really `[(); N]` or `[T; 0]` and we use the place path, fine.)

compiler/rustc_const_eval/src/check_consts/check.rs

+4
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
728728
);
729729
}
730730
}
731+
732+
Rvalue::WrapUnsafeBinder(..) => {
733+
// Unsafe binders are always trivial to create.
734+
}
731735
}
732736
}
733737

compiler/rustc_const_eval/src/check_consts/qualifs.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ where
258258
in_place::<Q, _>(cx, in_local, place.as_ref())
259259
}
260260

261+
Rvalue::WrapUnsafeBinder(op, _) => in_operand::<Q, _>(cx, in_local, op),
262+
261263
Rvalue::Aggregate(kind, operands) => {
262264
// Return early if we know that the struct or enum being constructed is always
263265
// qualified.
@@ -297,7 +299,8 @@ where
297299
| ProjectionElem::ConstantIndex { .. }
298300
| ProjectionElem::Subslice { .. }
299301
| ProjectionElem::Downcast(_, _)
300-
| ProjectionElem::Index(_) => {}
302+
| ProjectionElem::Index(_)
303+
| ProjectionElem::UnwrapUnsafeBinder(_) => {}
301304
}
302305

303306
let base_ty = place_base.ty(cx.body, cx.tcx);

compiler/rustc_const_eval/src/check_consts/resolver.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ where
202202
| mir::Rvalue::NullaryOp(..)
203203
| mir::Rvalue::UnaryOp(..)
204204
| mir::Rvalue::Discriminant(..)
205-
| mir::Rvalue::Aggregate(..) => {}
205+
| mir::Rvalue::Aggregate(..)
206+
| mir::Rvalue::WrapUnsafeBinder(..) => {}
206207
}
207208
}
208209

compiler/rustc_const_eval/src/interpret/projection.rs

+1
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ where
381381
OpaqueCast(ty) => {
382382
span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck")
383383
}
384+
UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?,
384385
// We don't want anything happening here, this is here as a dummy.
385386
Subtype(_) => base.transmute(base.layout(), self)?,
386387
Field(field, _) => self.project_field(base, field.index())?,

compiler/rustc_const_eval/src/interpret/step.rs

+7
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
277277
let discr = self.discriminant_for_variant(op.layout.ty, variant)?;
278278
self.write_immediate(*discr, &dest)?;
279279
}
280+
281+
WrapUnsafeBinder(ref op, _ty) => {
282+
// Constructing an unsafe binder acts like a transmute
283+
// since the operand's layout does not change.
284+
let op = self.eval_operand(op, None)?;
285+
self.copy_op_allow_transmute(&op, &dest)?;
286+
}
280287
}
281288

282289
trace!("{:?}", self.dump_place(&dest));

compiler/rustc_hir_typeck/src/expr.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1658,8 +1658,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16581658
hir_ty: Option<&'tcx hir::Ty<'tcx>>,
16591659
expected: Expectation<'tcx>,
16601660
) -> Ty<'tcx> {
1661-
self.dcx().span_err(inner_expr.span, "unsafe binder casts are not fully implemented");
1662-
16631661
match kind {
16641662
hir::UnsafeBinderCastKind::Wrap => {
16651663
let ascribed_ty =

compiler/rustc_middle/src/mir/pretty.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
12481248
ShallowInitBox(ref place, ref ty) => {
12491249
with_no_trimmed_paths!(write!(fmt, "ShallowInitBox({place:?}, {ty})"))
12501250
}
1251+
1252+
WrapUnsafeBinder(ref op, ty) => {
1253+
with_no_trimmed_paths!(write!(fmt, "wrap_binder!({op:?}; {ty})"))
1254+
}
12511255
}
12521256
}
12531257
}
@@ -1308,6 +1312,9 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
13081312
ProjectionElem::Index(_)
13091313
| ProjectionElem::ConstantIndex { .. }
13101314
| ProjectionElem::Subslice { .. } => {}
1315+
ProjectionElem::UnwrapUnsafeBinder(_) => {
1316+
write!(fmt, "unwrap_binder!(")?;
1317+
}
13111318
}
13121319
}
13131320

@@ -1356,6 +1363,9 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
13561363
ProjectionElem::Subslice { from, to, from_end: false } => {
13571364
write!(fmt, "[{from:?}..{to:?}]")?;
13581365
}
1366+
ProjectionElem::UnwrapUnsafeBinder(ty) => {
1367+
write!(fmt, "; {ty})")?;
1368+
}
13591369
}
13601370
}
13611371

0 commit comments

Comments
 (0)