Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #130631

Merged
merged 23 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0444056
Remove macOS 10.10 dynamic linker bug workaround
beetrees Jul 25, 2024
7b7992f
Begin experimental support for pin reborrowing
eholk Sep 4, 2024
a73c8b1
Apply code review suggestions
eholk Sep 18, 2024
b2b76fb
Allow shortening reborrows
eholk Sep 19, 2024
92a5d21
Add a test case to make sure we don't reborrow twice
eholk Sep 19, 2024
a18800f
pin_ergonomics: allow reborrowing as Pin<&T>
eholk Sep 19, 2024
bfadadf
Address diagnostics regression for 'const_char_encode_utf8';
bjoernager Sep 20, 2024
9104632
Revert additional scraped examples height
GuillaumeGomez Sep 20, 2024
660210c
Add GUI test to check size of additional scraped examples
GuillaumeGomez Sep 20, 2024
38bf289
Improve paddings for code blocks line numbers
GuillaumeGomez Sep 20, 2024
55058b6
Add GUI tests for line numbers padding
GuillaumeGomez Sep 20, 2024
5a219cb
bail if there are too many non-region infer vars
lcnr Sep 20, 2024
9613f48
add comment
lcnr Sep 20, 2024
340b38e
Add arm64e-apple-tvos target
arttet Sep 20, 2024
a6aeba8
update tests
lcnr Sep 20, 2024
ff86269
Add `Vec::as_non_null`
theemathas Sep 20, 2024
bf6389f
Rollup merge of #128209 - beetrees:no-macos-10.10, r=jieyouxu
GuillaumeGomez Sep 20, 2024
fe5f734
Rollup merge of #130526 - eholk:pin-reborrow, r=compiler-errors
GuillaumeGomez Sep 20, 2024
2a3f353
Rollup merge of #130611 - bjoernager:const-char-encode-utf8, r=dtolnay
GuillaumeGomez Sep 20, 2024
df2b730
Rollup merge of #130614 - arttet:arm64e-apple-tvos, r=bjorn3
GuillaumeGomez Sep 20, 2024
7adf4c2
Rollup merge of #130617 - lcnr:nalgebra-hang-3, r=compiler-errors
GuillaumeGomez Sep 20, 2024
5708062
Rollup merge of #130619 - GuillaumeGomez:scraped-examples-height, r=n…
GuillaumeGomez Sep 20, 2024
81b818e
Rollup merge of #130624 - theemathas:vec_as_non_null, r=Noratrieb
GuillaumeGomez Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ borrowck_simd_intrinsic_arg_const =
*[other] {$arg}th
} argument of `{$intrinsic}` is required to be a `const` item

borrowck_suggest_create_freash_reborrow =
borrowck_suggest_create_fresh_reborrow =
consider reborrowing the `Pin` instead of moving it

borrowck_suggest_iterate_over_slice =
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ pub(crate) enum CaptureReasonSuggest<'tcx> {
span: Span,
},
#[suggestion(
borrowck_suggest_create_freash_reborrow,
borrowck_suggest_create_fresh_reborrow,
applicability = "maybe-incorrect",
code = ".as_mut()",
style = "verbose"
Expand Down
52 changes: 0 additions & 52 deletions compiler/rustc_codegen_llvm/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,58 +443,6 @@ impl<'ll> CodegenCx<'ll, '_> {

if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
llvm::set_thread_local_mode(g, self.tls_model);

// Do not allow LLVM to change the alignment of a TLS on macOS.
//
// By default a global's alignment can be freely increased.
// This allows LLVM to generate more performant instructions
// e.g., using load-aligned into a SIMD register.
//
// However, on macOS 10.10 or below, the dynamic linker does not
// respect any alignment given on the TLS (radar 24221680).
// This will violate the alignment assumption, and causing segfault at runtime.
//
// This bug is very easy to trigger. In `println!` and `panic!`,
// the `LOCAL_STDOUT`/`LOCAL_STDERR` handles are stored in a TLS,
// which the values would be `mem::replace`d on initialization.
// The implementation of `mem::replace` will use SIMD
// whenever the size is 32 bytes or higher. LLVM notices SIMD is used
// and tries to align `LOCAL_STDOUT`/`LOCAL_STDERR` to a 32-byte boundary,
// which macOS's dyld disregarded and causing crashes
// (see issues #51794, #51758, #50867, #48866 and #44056).
//
// To workaround the bug, we trick LLVM into not increasing
// the global's alignment by explicitly assigning a section to it
// (equivalent to automatically generating a `#[link_section]` attribute).
// See the comment in the `GlobalValue::canIncreaseAlignment()` function
// of `lib/IR/Globals.cpp` for why this works.
//
// When the alignment is not increased, the optimized `mem::replace`
// will use load-unaligned instructions instead, and thus avoiding the crash.
//
// We could remove this hack whenever we decide to drop macOS 10.10 support.
if self.tcx.sess.target.is_like_osx {
// The `inspect` method is okay here because we checked for provenance, and
// because we are doing this access to inspect the final interpreter state
// (not as part of the interpreter execution).
//
// FIXME: This check requires that the (arbitrary) value of undefined bytes
// happens to be zero. Instead, we should only check the value of defined bytes
// and set all undefined bytes to zero if this allocation is headed for the
// BSS.
let all_bytes_are_zero = alloc.provenance().ptrs().is_empty()
&& alloc
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
.iter()
.all(|&byte| byte == 0);

let sect_name = if all_bytes_are_zero {
c"__DATA,__thread_bss"
} else {
c"__DATA,__thread_data"
};
llvm::LLVMSetSection(g, sect_name.as_ptr());
}
}

// Wasm statics with custom link sections get special treatment as they
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,8 @@ declare_features! (
(unstable, optimize_attribute, "1.34.0", Some(54882)),
/// Allows specifying nop padding on functions for dynamic patching.
(unstable, patchable_function_entry, "1.81.0", Some(123115)),
/// Experimental features that make `Pin` more ergonomic.
(incomplete, pin_ergonomics, "CURRENT_RUSTC_VERSION", Some(130494)),
/// Allows postfix match `expr.match { ... }`
(unstable, postfix_match, "1.79.0", Some(121618)),
/// Allows macro attributes on expressions, statements and non-inline modules.
Expand Down
62 changes: 62 additions & 0 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
ty::Dynamic(predicates, region, ty::DynStar) if self.tcx.features().dyn_star => {
return self.coerce_dyn_star(a, b, predicates, region);
}
ty::Adt(pin, _)
if self.tcx.features().pin_ergonomics
&& self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) =>
{
return self.coerce_pin(a, b);
}
_ => {}
}

Expand Down Expand Up @@ -774,6 +780,62 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
})
}

/// Applies reborrowing for `Pin`
///
/// We currently only support reborrowing `Pin<&mut T>` as `Pin<&mut T>`. This is accomplished
/// by inserting a call to `Pin::as_mut` during MIR building.
///
/// In the future we might want to support other reborrowing coercions, such as:
/// - `Pin<&mut T>` as `Pin<&T>`
/// - `Pin<&T>` as `Pin<&T>`
/// - `Pin<Box<T>>` as `Pin<&T>`
/// - `Pin<Box<T>>` as `Pin<&mut T>`
#[instrument(skip(self), level = "trace")]
fn coerce_pin(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
// We need to make sure the two types are compatible for coercion.
// Then we will build a ReborrowPin adjustment and return that as an InferOk.

// Right now we can only reborrow if this is a `Pin<&mut T>`.
let extract_pin_mut = |ty: Ty<'tcx>| {
// Get the T out of Pin<T>
let (pin, ty) = match ty.kind() {
ty::Adt(pin, args) if self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => {
(*pin, args[0].expect_ty())
}
_ => {
debug!("can't reborrow {:?} as pinned", ty);
return Err(TypeError::Mismatch);
}
};
// Make sure the T is something we understand (just `&mut U` for now)
match ty.kind() {
ty::Ref(region, ty, mutbl) => Ok((pin, *region, *ty, *mutbl)),
_ => {
debug!("can't reborrow pin of inner type {:?}", ty);
Err(TypeError::Mismatch)
}
}
};

let (pin, a_region, a_ty, mut_a) = extract_pin_mut(a)?;
let (_, b_region, _b_ty, mut_b) = extract_pin_mut(b)?;

coerce_mutbls(mut_a, mut_b)?;

// update a with b's mutability since we'll be coercing mutability
let a = Ty::new_adt(
self.tcx,
pin,
self.tcx.mk_args(&[Ty::new_ref(self.tcx, a_region, a_ty, mut_b).into()]),
);

// To complete the reborrow, we need to make sure we can unify the inner types, and if so we
// add the adjustments.
self.unify_and(a, b, |_inner_ty| {
vec![Adjustment { kind: Adjust::ReborrowPin(b_region, mut_b), target: b }]
})
}

fn coerce_from_safe_fn<F, G>(
&self,
a: Ty<'tcx>,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,16 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
adjustment::Adjust::Borrow(ref autoref) => {
self.walk_autoref(expr, &place_with_id, autoref);
}

adjustment::Adjust::ReborrowPin(_, mutbl) => {
// Reborrowing a Pin is like a combinations of a deref and a borrow, so we do
// both.
let bk = match mutbl {
ty::Mutability::Not => ty::BorrowKind::ImmBorrow,
ty::Mutability::Mut => ty::BorrowKind::MutBorrow,
};
self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
}
}
place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?;
}
Expand Down Expand Up @@ -1284,6 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
adjustment::Adjust::NeverToAny
| adjustment::Adjust::Pointer(_)
| adjustment::Adjust::Borrow(_)
| adjustment::Adjust::ReborrowPin(..)
| adjustment::Adjust::DynStar => {
// Result is an rvalue.
Ok(self.cat_rvalue(expr.hir_id, target))
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/adjustment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ pub enum Adjust<'tcx> {

/// Cast into a dyn* object.
DynStar,

/// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
ReborrowPin(ty::Region<'tcx>, hir::Mutability),
}

/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
Expand Down
64 changes: 63 additions & 1 deletion compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl<'tcx> Cx<'tcx> {
self.thir.exprs.push(expr)
}

#[instrument(level = "trace", skip(self, expr, span))]
fn apply_adjustment(
&mut self,
hir_expr: &'tcx hir::Expr<'tcx>,
Expand Down Expand Up @@ -146,6 +147,67 @@ impl<'tcx> Cx<'tcx> {
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
}
Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) },
Adjust::ReborrowPin(region, mutbl) => {
debug!("apply ReborrowPin adjustment");
// Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`

// We'll need these types later on
let pin_ty_args = match expr.ty.kind() {
ty::Adt(_, args) => args,
_ => bug!("ReborrowPin with non-Pin type"),
};
let pin_ty = pin_ty_args.iter().next().unwrap().expect_ty();
let ptr_target_ty = match pin_ty.kind() {
ty::Ref(_, ty, _) => *ty,
_ => bug!("ReborrowPin with non-Ref type"),
};

// pointer = ($expr).__pointer
let pointer_target = ExprKind::Field {
lhs: self.thir.exprs.push(expr),
variant_index: FIRST_VARIANT,
name: FieldIdx::from(0u32),
};
let arg = Expr { temp_lifetime, ty: pin_ty, span, kind: pointer_target };
let arg = self.thir.exprs.push(arg);

// arg = *pointer
let expr = ExprKind::Deref { arg };
let arg = self.thir.exprs.push(Expr {
temp_lifetime,
ty: ptr_target_ty,
span,
kind: expr,
});

// expr = &mut target
let borrow_kind = match mutbl {
hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
hir::Mutability::Not => BorrowKind::Shared,
};
let new_pin_target = Ty::new_ref(self.tcx, region, ptr_target_ty, mutbl);
let expr = self.thir.exprs.push(Expr {
temp_lifetime,
ty: new_pin_target,
span,
kind: ExprKind::Borrow { borrow_kind, arg },
});

// kind = Pin { __pointer: pointer }
let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, Some(span));
let args = self.tcx.mk_args(&[new_pin_target.into()]);
let kind = ExprKind::Adt(Box::new(AdtExpr {
adt_def: self.tcx.adt_def(pin_did),
variant_index: FIRST_VARIANT,
args,
fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
user_ty: None,
base: None,
}));

debug!(?kind);
kind
}
};

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

// Reconstruct the output assuming it's a reference with the
// same region and mutability as the receiver. This holds for
// `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
// `Deref(Mut)::deref(_mut)` and `Index(Mut)::index(_mut)`.
let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
span_bug!(span, "overloaded_place: receiver is not a reference");
};
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ where
},
);

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

Ok(canonical)
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,7 @@ symbols! {
pic,
pie,
pin,
pin_ergonomics,
platform_intrinsics,
plugin,
plugin_registrar,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1714,8 +1714,10 @@ supported_targets! {
("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi),
("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
("aarch64-apple-ios-sim", aarch64_apple_ios_sim),

("aarch64-apple-tvos", aarch64_apple_tvos),
("aarch64-apple-tvos-sim", aarch64_apple_tvos_sim),
("arm64e-apple-tvos", arm64e_apple_tvos),
("x86_64-apple-tvos", x86_64_apple_tvos),

("armv7k-apple-watchos", armv7k_apple_watchos),
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, Target, TargetOptions};

pub(crate) fn target() -> Target {
let (opts, llvm_target, arch) = base("tvos", Arch::Arm64e, TargetAbi::Normal);
Target {
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64e Apple tvOS".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(true),
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..opts
},
}
}
Loading
Loading