Skip to content

Commit da88968

Browse files
committed
Auto merge of rust-lang#130631 - GuillaumeGomez:rollup-jpgy1iv, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - rust-lang#128209 (Remove macOS 10.10 dynamic linker bug workaround) - rust-lang#130526 (Begin experimental support for pin reborrowing) - rust-lang#130611 (Address diagnostics regression for `const_char_encode_utf8`.) - rust-lang#130614 (Add arm64e-apple-tvos target) - rust-lang#130617 (bail if there are too many non-region infer vars in the query response) - rust-lang#130619 (Fix scraped examples height) - rust-lang#130624 (Add `Vec::as_non_null`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5ba6db1 + 81b818e commit da88968

File tree

37 files changed

+581
-100
lines changed

37 files changed

+581
-100
lines changed

Diff for: compiler/rustc_borrowck/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ borrowck_simd_intrinsic_arg_const =
207207
*[other] {$arg}th
208208
} argument of `{$intrinsic}` is required to be a `const` item
209209
210-
borrowck_suggest_create_freash_reborrow =
210+
borrowck_suggest_create_fresh_reborrow =
211211
consider reborrowing the `Pin` instead of moving it
212212
213213
borrowck_suggest_iterate_over_slice =

Diff for: compiler/rustc_borrowck/src/session_diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ pub(crate) enum CaptureReasonSuggest<'tcx> {
415415
span: Span,
416416
},
417417
#[suggestion(
418-
borrowck_suggest_create_freash_reborrow,
418+
borrowck_suggest_create_fresh_reborrow,
419419
applicability = "maybe-incorrect",
420420
code = ".as_mut()",
421421
style = "verbose"

Diff for: compiler/rustc_codegen_llvm/src/consts.rs

-52
Original file line numberDiff line numberDiff line change
@@ -443,58 +443,6 @@ impl<'ll> CodegenCx<'ll, '_> {
443443

444444
if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
445445
llvm::set_thread_local_mode(g, self.tls_model);
446-
447-
// Do not allow LLVM to change the alignment of a TLS on macOS.
448-
//
449-
// By default a global's alignment can be freely increased.
450-
// This allows LLVM to generate more performant instructions
451-
// e.g., using load-aligned into a SIMD register.
452-
//
453-
// However, on macOS 10.10 or below, the dynamic linker does not
454-
// respect any alignment given on the TLS (radar 24221680).
455-
// This will violate the alignment assumption, and causing segfault at runtime.
456-
//
457-
// This bug is very easy to trigger. In `println!` and `panic!`,
458-
// the `LOCAL_STDOUT`/`LOCAL_STDERR` handles are stored in a TLS,
459-
// which the values would be `mem::replace`d on initialization.
460-
// The implementation of `mem::replace` will use SIMD
461-
// whenever the size is 32 bytes or higher. LLVM notices SIMD is used
462-
// and tries to align `LOCAL_STDOUT`/`LOCAL_STDERR` to a 32-byte boundary,
463-
// which macOS's dyld disregarded and causing crashes
464-
// (see issues #51794, #51758, #50867, #48866 and #44056).
465-
//
466-
// To workaround the bug, we trick LLVM into not increasing
467-
// the global's alignment by explicitly assigning a section to it
468-
// (equivalent to automatically generating a `#[link_section]` attribute).
469-
// See the comment in the `GlobalValue::canIncreaseAlignment()` function
470-
// of `lib/IR/Globals.cpp` for why this works.
471-
//
472-
// When the alignment is not increased, the optimized `mem::replace`
473-
// will use load-unaligned instructions instead, and thus avoiding the crash.
474-
//
475-
// We could remove this hack whenever we decide to drop macOS 10.10 support.
476-
if self.tcx.sess.target.is_like_osx {
477-
// The `inspect` method is okay here because we checked for provenance, and
478-
// because we are doing this access to inspect the final interpreter state
479-
// (not as part of the interpreter execution).
480-
//
481-
// FIXME: This check requires that the (arbitrary) value of undefined bytes
482-
// happens to be zero. Instead, we should only check the value of defined bytes
483-
// and set all undefined bytes to zero if this allocation is headed for the
484-
// BSS.
485-
let all_bytes_are_zero = alloc.provenance().ptrs().is_empty()
486-
&& alloc
487-
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
488-
.iter()
489-
.all(|&byte| byte == 0);
490-
491-
let sect_name = if all_bytes_are_zero {
492-
c"__DATA,__thread_bss"
493-
} else {
494-
c"__DATA,__thread_data"
495-
};
496-
llvm::LLVMSetSection(g, sect_name.as_ptr());
497-
}
498446
}
499447

500448
// Wasm statics with custom link sections get special treatment as they

Diff for: compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ declare_features! (
558558
(unstable, optimize_attribute, "1.34.0", Some(54882)),
559559
/// Allows specifying nop padding on functions for dynamic patching.
560560
(unstable, patchable_function_entry, "1.81.0", Some(123115)),
561+
/// Experimental features that make `Pin` more ergonomic.
562+
(incomplete, pin_ergonomics, "CURRENT_RUSTC_VERSION", Some(130494)),
561563
/// Allows postfix match `expr.match { ... }`
562564
(unstable, postfix_match, "1.79.0", Some(121618)),
563565
/// Allows macro attributes on expressions, statements and non-inline modules.

Diff for: compiler/rustc_hir_typeck/src/coercion.rs

+62
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
214214
ty::Dynamic(predicates, region, ty::DynStar) if self.tcx.features().dyn_star => {
215215
return self.coerce_dyn_star(a, b, predicates, region);
216216
}
217+
ty::Adt(pin, _)
218+
if self.tcx.features().pin_ergonomics
219+
&& self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) =>
220+
{
221+
return self.coerce_pin(a, b);
222+
}
217223
_ => {}
218224
}
219225

@@ -774,6 +780,62 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
774780
})
775781
}
776782

783+
/// Applies reborrowing for `Pin`
784+
///
785+
/// We currently only support reborrowing `Pin<&mut T>` as `Pin<&mut T>`. This is accomplished
786+
/// by inserting a call to `Pin::as_mut` during MIR building.
787+
///
788+
/// In the future we might want to support other reborrowing coercions, such as:
789+
/// - `Pin<&mut T>` as `Pin<&T>`
790+
/// - `Pin<&T>` as `Pin<&T>`
791+
/// - `Pin<Box<T>>` as `Pin<&T>`
792+
/// - `Pin<Box<T>>` as `Pin<&mut T>`
793+
#[instrument(skip(self), level = "trace")]
794+
fn coerce_pin(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
795+
// We need to make sure the two types are compatible for coercion.
796+
// Then we will build a ReborrowPin adjustment and return that as an InferOk.
797+
798+
// Right now we can only reborrow if this is a `Pin<&mut T>`.
799+
let extract_pin_mut = |ty: Ty<'tcx>| {
800+
// Get the T out of Pin<T>
801+
let (pin, ty) = match ty.kind() {
802+
ty::Adt(pin, args) if self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => {
803+
(*pin, args[0].expect_ty())
804+
}
805+
_ => {
806+
debug!("can't reborrow {:?} as pinned", ty);
807+
return Err(TypeError::Mismatch);
808+
}
809+
};
810+
// Make sure the T is something we understand (just `&mut U` for now)
811+
match ty.kind() {
812+
ty::Ref(region, ty, mutbl) => Ok((pin, *region, *ty, *mutbl)),
813+
_ => {
814+
debug!("can't reborrow pin of inner type {:?}", ty);
815+
Err(TypeError::Mismatch)
816+
}
817+
}
818+
};
819+
820+
let (pin, a_region, a_ty, mut_a) = extract_pin_mut(a)?;
821+
let (_, b_region, _b_ty, mut_b) = extract_pin_mut(b)?;
822+
823+
coerce_mutbls(mut_a, mut_b)?;
824+
825+
// update a with b's mutability since we'll be coercing mutability
826+
let a = Ty::new_adt(
827+
self.tcx,
828+
pin,
829+
self.tcx.mk_args(&[Ty::new_ref(self.tcx, a_region, a_ty, mut_b).into()]),
830+
);
831+
832+
// To complete the reborrow, we need to make sure we can unify the inner types, and if so we
833+
// add the adjustments.
834+
self.unify_and(a, b, |_inner_ty| {
835+
vec![Adjustment { kind: Adjust::ReborrowPin(b_region, mut_b), target: b }]
836+
})
837+
}
838+
777839
fn coerce_from_safe_fn<F, G>(
778840
&self,
779841
a: Ty<'tcx>,

Diff for: compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+11
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,16 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
780780
adjustment::Adjust::Borrow(ref autoref) => {
781781
self.walk_autoref(expr, &place_with_id, autoref);
782782
}
783+
784+
adjustment::Adjust::ReborrowPin(_, mutbl) => {
785+
// Reborrowing a Pin is like a combinations of a deref and a borrow, so we do
786+
// both.
787+
let bk = match mutbl {
788+
ty::Mutability::Not => ty::BorrowKind::ImmBorrow,
789+
ty::Mutability::Mut => ty::BorrowKind::MutBorrow,
790+
};
791+
self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
792+
}
783793
}
784794
place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?;
785795
}
@@ -1284,6 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
12841294
adjustment::Adjust::NeverToAny
12851295
| adjustment::Adjust::Pointer(_)
12861296
| adjustment::Adjust::Borrow(_)
1297+
| adjustment::Adjust::ReborrowPin(..)
12871298
| adjustment::Adjust::DynStar => {
12881299
// Result is an rvalue.
12891300
Ok(self.cat_rvalue(expr.hir_id, target))

Diff for: compiler/rustc_middle/src/ty/adjustment.rs

+3
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ pub enum Adjust<'tcx> {
104104

105105
/// Cast into a dyn* object.
106106
DynStar,
107+
108+
/// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
109+
ReborrowPin(ty::Region<'tcx>, hir::Mutability),
107110
}
108111

109112
/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`

Diff for: compiler/rustc_mir_build/src/thir/cx/expr.rs

+63-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl<'tcx> Cx<'tcx> {
7474
self.thir.exprs.push(expr)
7575
}
7676

77+
#[instrument(level = "trace", skip(self, expr, span))]
7778
fn apply_adjustment(
7879
&mut self,
7980
hir_expr: &'tcx hir::Expr<'tcx>,
@@ -146,6 +147,67 @@ impl<'tcx> Cx<'tcx> {
146147
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
147148
}
148149
Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) },
150+
Adjust::ReborrowPin(region, mutbl) => {
151+
debug!("apply ReborrowPin adjustment");
152+
// Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`
153+
154+
// We'll need these types later on
155+
let pin_ty_args = match expr.ty.kind() {
156+
ty::Adt(_, args) => args,
157+
_ => bug!("ReborrowPin with non-Pin type"),
158+
};
159+
let pin_ty = pin_ty_args.iter().next().unwrap().expect_ty();
160+
let ptr_target_ty = match pin_ty.kind() {
161+
ty::Ref(_, ty, _) => *ty,
162+
_ => bug!("ReborrowPin with non-Ref type"),
163+
};
164+
165+
// pointer = ($expr).__pointer
166+
let pointer_target = ExprKind::Field {
167+
lhs: self.thir.exprs.push(expr),
168+
variant_index: FIRST_VARIANT,
169+
name: FieldIdx::from(0u32),
170+
};
171+
let arg = Expr { temp_lifetime, ty: pin_ty, span, kind: pointer_target };
172+
let arg = self.thir.exprs.push(arg);
173+
174+
// arg = *pointer
175+
let expr = ExprKind::Deref { arg };
176+
let arg = self.thir.exprs.push(Expr {
177+
temp_lifetime,
178+
ty: ptr_target_ty,
179+
span,
180+
kind: expr,
181+
});
182+
183+
// expr = &mut target
184+
let borrow_kind = match mutbl {
185+
hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
186+
hir::Mutability::Not => BorrowKind::Shared,
187+
};
188+
let new_pin_target = Ty::new_ref(self.tcx, region, ptr_target_ty, mutbl);
189+
let expr = self.thir.exprs.push(Expr {
190+
temp_lifetime,
191+
ty: new_pin_target,
192+
span,
193+
kind: ExprKind::Borrow { borrow_kind, arg },
194+
});
195+
196+
// kind = Pin { __pointer: pointer }
197+
let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, Some(span));
198+
let args = self.tcx.mk_args(&[new_pin_target.into()]);
199+
let kind = ExprKind::Adt(Box::new(AdtExpr {
200+
adt_def: self.tcx.adt_def(pin_did),
201+
variant_index: FIRST_VARIANT,
202+
args,
203+
fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
204+
user_ty: None,
205+
base: None,
206+
}));
207+
208+
debug!(?kind);
209+
kind
210+
}
149211
};
150212

151213
Expr { temp_lifetime, ty: adjustment.target, span, kind }
@@ -1014,7 +1076,7 @@ impl<'tcx> Cx<'tcx> {
10141076

10151077
// Reconstruct the output assuming it's a reference with the
10161078
// same region and mutability as the receiver. This holds for
1017-
// `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
1079+
// `Deref(Mut)::deref(_mut)` and `Index(Mut)::index(_mut)`.
10181080
let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
10191081
span_bug!(span, "overloaded_place: receiver is not a reference");
10201082
};

Diff for: compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs

+11
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,17 @@ where
157157
},
158158
);
159159

160+
// HACK: We bail with overflow if the response would have too many non-region
161+
// inference variables. This tends to only happen if we encounter a lot of
162+
// ambiguous alias types which get replaced with fresh inference variables
163+
// during generalization. This prevents a hang in nalgebra.
164+
let num_non_region_vars = canonical.variables.iter().filter(|c| !c.is_region()).count();
165+
if num_non_region_vars > self.cx().recursion_limit() {
166+
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
167+
suggest_increasing_limit: true,
168+
}));
169+
}
170+
160171
Ok(canonical)
161172
}
162173

Diff for: compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,7 @@ symbols! {
14531453
pic,
14541454
pie,
14551455
pin,
1456+
pin_ergonomics,
14561457
platform_intrinsics,
14571458
plugin,
14581459
plugin_registrar,

Diff for: compiler/rustc_target/src/spec/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1714,8 +1714,10 @@ supported_targets! {
17141714
("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi),
17151715
("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
17161716
("aarch64-apple-ios-sim", aarch64_apple_ios_sim),
1717+
17171718
("aarch64-apple-tvos", aarch64_apple_tvos),
17181719
("aarch64-apple-tvos-sim", aarch64_apple_tvos_sim),
1720+
("arm64e-apple-tvos", arm64e_apple_tvos),
17191721
("x86_64-apple-tvos", x86_64_apple_tvos),
17201722

17211723
("armv7k-apple-watchos", armv7k_apple_watchos),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use crate::spec::base::apple::{base, Arch, TargetAbi};
2+
use crate::spec::{FramePointer, Target, TargetOptions};
3+
4+
pub(crate) fn target() -> Target {
5+
let (opts, llvm_target, arch) = base("tvos", Arch::Arm64e, TargetAbi::Normal);
6+
Target {
7+
llvm_target,
8+
metadata: crate::spec::TargetMetadata {
9+
description: Some("ARM64e Apple tvOS".into()),
10+
tier: Some(3),
11+
host_tools: Some(false),
12+
std: Some(true),
13+
},
14+
pointer_width: 64,
15+
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
16+
arch,
17+
options: TargetOptions {
18+
features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
19+
max_atomic_width: Some(128),
20+
frame_pointer: FramePointer::NonLeaf,
21+
..opts
22+
},
23+
}
24+
}

0 commit comments

Comments
 (0)