mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #130631 - GuillaumeGomez:rollup-jpgy1iv, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - #128209 (Remove macOS 10.10 dynamic linker bug workaround) - #130526 (Begin experimental support for pin reborrowing) - #130611 (Address diagnostics regression for `const_char_encode_utf8`.) - #130614 (Add arm64e-apple-tvos target) - #130617 (bail if there are too many non-region infer vars in the query response) - #130619 (Fix scraped examples height) - #130624 (Add `Vec::as_non_null`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
da889684c8
@ -207,7 +207,7 @@ borrowck_simd_intrinsic_arg_const =
|
|||||||
*[other] {$arg}th
|
*[other] {$arg}th
|
||||||
} argument of `{$intrinsic}` is required to be a `const` item
|
} 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
|
consider reborrowing the `Pin` instead of moving it
|
||||||
|
|
||||||
borrowck_suggest_iterate_over_slice =
|
borrowck_suggest_iterate_over_slice =
|
||||||
|
@ -415,7 +415,7 @@ pub(crate) enum CaptureReasonSuggest<'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
#[suggestion(
|
#[suggestion(
|
||||||
borrowck_suggest_create_freash_reborrow,
|
borrowck_suggest_create_fresh_reborrow,
|
||||||
applicability = "maybe-incorrect",
|
applicability = "maybe-incorrect",
|
||||||
code = ".as_mut()",
|
code = ".as_mut()",
|
||||||
style = "verbose"
|
style = "verbose"
|
||||||
|
@ -443,58 +443,6 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||||||
|
|
||||||
if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
|
if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
|
||||||
llvm::set_thread_local_mode(g, self.tls_model);
|
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
|
// Wasm statics with custom link sections get special treatment as they
|
||||||
|
@ -558,6 +558,8 @@ declare_features! (
|
|||||||
(unstable, optimize_attribute, "1.34.0", Some(54882)),
|
(unstable, optimize_attribute, "1.34.0", Some(54882)),
|
||||||
/// Allows specifying nop padding on functions for dynamic patching.
|
/// Allows specifying nop padding on functions for dynamic patching.
|
||||||
(unstable, patchable_function_entry, "1.81.0", Some(123115)),
|
(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 { ... }`
|
/// Allows postfix match `expr.match { ... }`
|
||||||
(unstable, postfix_match, "1.79.0", Some(121618)),
|
(unstable, postfix_match, "1.79.0", Some(121618)),
|
||||||
/// Allows macro attributes on expressions, statements and non-inline modules.
|
/// Allows macro attributes on expressions, statements and non-inline modules.
|
||||||
|
@ -214,6 +214,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
ty::Dynamic(predicates, region, ty::DynStar) if self.tcx.features().dyn_star => {
|
ty::Dynamic(predicates, region, ty::DynStar) if self.tcx.features().dyn_star => {
|
||||||
return self.coerce_dyn_star(a, b, predicates, region);
|
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);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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>(
|
fn coerce_from_safe_fn<F, G>(
|
||||||
&self,
|
&self,
|
||||||
a: Ty<'tcx>,
|
a: Ty<'tcx>,
|
||||||
|
@ -780,6 +780,16 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
|||||||
adjustment::Adjust::Borrow(ref autoref) => {
|
adjustment::Adjust::Borrow(ref autoref) => {
|
||||||
self.walk_autoref(expr, &place_with_id, 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)?;
|
place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?;
|
||||||
}
|
}
|
||||||
@ -1284,6 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
|||||||
adjustment::Adjust::NeverToAny
|
adjustment::Adjust::NeverToAny
|
||||||
| adjustment::Adjust::Pointer(_)
|
| adjustment::Adjust::Pointer(_)
|
||||||
| adjustment::Adjust::Borrow(_)
|
| adjustment::Adjust::Borrow(_)
|
||||||
|
| adjustment::Adjust::ReborrowPin(..)
|
||||||
| adjustment::Adjust::DynStar => {
|
| adjustment::Adjust::DynStar => {
|
||||||
// Result is an rvalue.
|
// Result is an rvalue.
|
||||||
Ok(self.cat_rvalue(expr.hir_id, target))
|
Ok(self.cat_rvalue(expr.hir_id, target))
|
||||||
|
@ -104,6 +104,9 @@ pub enum Adjust<'tcx> {
|
|||||||
|
|
||||||
/// Cast into a dyn* object.
|
/// Cast into a dyn* object.
|
||||||
DynStar,
|
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)`
|
/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
|
||||||
|
@ -74,6 +74,7 @@ impl<'tcx> Cx<'tcx> {
|
|||||||
self.thir.exprs.push(expr)
|
self.thir.exprs.push(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "trace", skip(self, expr, span))]
|
||||||
fn apply_adjustment(
|
fn apply_adjustment(
|
||||||
&mut self,
|
&mut self,
|
||||||
hir_expr: &'tcx hir::Expr<'tcx>,
|
hir_expr: &'tcx hir::Expr<'tcx>,
|
||||||
@ -146,6 +147,67 @@ impl<'tcx> Cx<'tcx> {
|
|||||||
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
|
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
|
||||||
}
|
}
|
||||||
Adjust::DynStar => ExprKind::Cast { source: 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 }
|
Expr { temp_lifetime, ty: adjustment.target, span, kind }
|
||||||
@ -1014,7 +1076,7 @@ impl<'tcx> Cx<'tcx> {
|
|||||||
|
|
||||||
// Reconstruct the output assuming it's a reference with the
|
// Reconstruct the output assuming it's a reference with the
|
||||||
// same region and mutability as the receiver. This holds for
|
// 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 {
|
let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
|
||||||
span_bug!(span, "overloaded_place: receiver is not a reference");
|
span_bug!(span, "overloaded_place: receiver is not a reference");
|
||||||
};
|
};
|
||||||
|
@ -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)
|
Ok(canonical)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1453,6 +1453,7 @@ symbols! {
|
|||||||
pic,
|
pic,
|
||||||
pie,
|
pie,
|
||||||
pin,
|
pin,
|
||||||
|
pin_ergonomics,
|
||||||
platform_intrinsics,
|
platform_intrinsics,
|
||||||
plugin,
|
plugin,
|
||||||
plugin_registrar,
|
plugin_registrar,
|
||||||
|
@ -1714,8 +1714,10 @@ supported_targets! {
|
|||||||
("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi),
|
("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi),
|
||||||
("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
|
("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
|
||||||
("aarch64-apple-ios-sim", aarch64_apple_ios_sim),
|
("aarch64-apple-ios-sim", aarch64_apple_ios_sim),
|
||||||
|
|
||||||
("aarch64-apple-tvos", aarch64_apple_tvos),
|
("aarch64-apple-tvos", aarch64_apple_tvos),
|
||||||
("aarch64-apple-tvos-sim", aarch64_apple_tvos_sim),
|
("aarch64-apple-tvos-sim", aarch64_apple_tvos_sim),
|
||||||
|
("arm64e-apple-tvos", arm64e_apple_tvos),
|
||||||
("x86_64-apple-tvos", x86_64_apple_tvos),
|
("x86_64-apple-tvos", x86_64_apple_tvos),
|
||||||
|
|
||||||
("armv7k-apple-watchos", armv7k_apple_watchos),
|
("armv7k-apple-watchos", armv7k_apple_watchos),
|
||||||
|
24
compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs
Normal file
24
compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs
Normal file
@ -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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -1584,7 +1584,8 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
///
|
///
|
||||||
/// This method guarantees that for the purpose of the aliasing model, this method
|
/// This method guarantees that for the purpose of the aliasing model, this method
|
||||||
/// does not materialize a reference to the underlying slice, and thus the returned pointer
|
/// does not materialize a reference to the underlying slice, and thus the returned pointer
|
||||||
/// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
|
/// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
|
||||||
|
/// and [`as_non_null`].
|
||||||
/// Note that calling other methods that materialize mutable references to the slice,
|
/// Note that calling other methods that materialize mutable references to the slice,
|
||||||
/// or mutable references to specific elements you are planning on accessing through this pointer,
|
/// or mutable references to specific elements you are planning on accessing through this pointer,
|
||||||
/// as well as writing to those elements, may still invalidate this pointer.
|
/// as well as writing to those elements, may still invalidate this pointer.
|
||||||
@ -1621,6 +1622,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
///
|
///
|
||||||
/// [`as_mut_ptr`]: Vec::as_mut_ptr
|
/// [`as_mut_ptr`]: Vec::as_mut_ptr
|
||||||
/// [`as_ptr`]: Vec::as_ptr
|
/// [`as_ptr`]: Vec::as_ptr
|
||||||
|
/// [`as_non_null`]: Vec::as_non_null
|
||||||
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
|
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -1640,7 +1642,8 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
///
|
///
|
||||||
/// This method guarantees that for the purpose of the aliasing model, this method
|
/// This method guarantees that for the purpose of the aliasing model, this method
|
||||||
/// does not materialize a reference to the underlying slice, and thus the returned pointer
|
/// does not materialize a reference to the underlying slice, and thus the returned pointer
|
||||||
/// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
|
/// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
|
||||||
|
/// and [`as_non_null`].
|
||||||
/// Note that calling other methods that materialize references to the slice,
|
/// Note that calling other methods that materialize references to the slice,
|
||||||
/// or references to specific elements you are planning on accessing through this pointer,
|
/// or references to specific elements you are planning on accessing through this pointer,
|
||||||
/// may still invalidate this pointer.
|
/// may still invalidate this pointer.
|
||||||
@ -1680,6 +1683,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
///
|
///
|
||||||
/// [`as_mut_ptr`]: Vec::as_mut_ptr
|
/// [`as_mut_ptr`]: Vec::as_mut_ptr
|
||||||
/// [`as_ptr`]: Vec::as_ptr
|
/// [`as_ptr`]: Vec::as_ptr
|
||||||
|
/// [`as_non_null`]: Vec::as_non_null
|
||||||
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
|
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -1689,6 +1693,69 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
self.buf.ptr()
|
self.buf.ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a `NonNull` pointer to the vector's buffer, or a dangling
|
||||||
|
/// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
|
||||||
|
///
|
||||||
|
/// The caller must ensure that the vector outlives the pointer this
|
||||||
|
/// function returns, or else it will end up dangling.
|
||||||
|
/// Modifying the vector may cause its buffer to be reallocated,
|
||||||
|
/// which would also make any pointers to it invalid.
|
||||||
|
///
|
||||||
|
/// This method guarantees that for the purpose of the aliasing model, this method
|
||||||
|
/// does not materialize a reference to the underlying slice, and thus the returned pointer
|
||||||
|
/// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
|
||||||
|
/// and [`as_non_null`].
|
||||||
|
/// Note that calling other methods that materialize references to the slice,
|
||||||
|
/// or references to specific elements you are planning on accessing through this pointer,
|
||||||
|
/// may still invalidate this pointer.
|
||||||
|
/// See the second example below for how this guarantee can be used.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(box_vec_non_null)]
|
||||||
|
///
|
||||||
|
/// // Allocate vector big enough for 4 elements.
|
||||||
|
/// let size = 4;
|
||||||
|
/// let mut x: Vec<i32> = Vec::with_capacity(size);
|
||||||
|
/// let x_ptr = x.as_non_null();
|
||||||
|
///
|
||||||
|
/// // Initialize elements via raw pointer writes, then set length.
|
||||||
|
/// unsafe {
|
||||||
|
/// for i in 0..size {
|
||||||
|
/// x_ptr.add(i).write(i as i32);
|
||||||
|
/// }
|
||||||
|
/// x.set_len(size);
|
||||||
|
/// }
|
||||||
|
/// assert_eq!(&*x, &[0, 1, 2, 3]);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Due to the aliasing guarantee, the following code is legal:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #![feature(box_vec_non_null)]
|
||||||
|
///
|
||||||
|
/// unsafe {
|
||||||
|
/// let mut v = vec![0];
|
||||||
|
/// let ptr1 = v.as_non_null();
|
||||||
|
/// ptr1.write(1);
|
||||||
|
/// let ptr2 = v.as_non_null();
|
||||||
|
/// ptr2.write(2);
|
||||||
|
/// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
|
||||||
|
/// ptr1.write(3);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`as_mut_ptr`]: Vec::as_mut_ptr
|
||||||
|
/// [`as_ptr`]: Vec::as_ptr
|
||||||
|
/// [`as_non_null`]: Vec::as_non_null
|
||||||
|
#[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
|
||||||
|
#[inline]
|
||||||
|
pub fn as_non_null(&mut self) -> NonNull<T> {
|
||||||
|
// SAFETY: A `Vec` always has a non-null pointer.
|
||||||
|
unsafe { NonNull::new_unchecked(self.as_mut_ptr()) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a reference to the underlying allocator.
|
/// Returns a reference to the underlying allocator.
|
||||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! impl char {}
|
//! impl char {}
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::intrinsics::const_eval_select;
|
||||||
use crate::slice;
|
use crate::slice;
|
||||||
use crate::str::from_utf8_unchecked_mut;
|
use crate::str::from_utf8_unchecked_mut;
|
||||||
use crate::unicode::printable::is_printable;
|
use crate::unicode::printable::is_printable;
|
||||||
@ -1762,6 +1763,15 @@ const fn len_utf8(code: u32) -> usize {
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
|
pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
|
||||||
|
const fn panic_at_const(_code: u32, _len: usize, _dst_len: usize) {
|
||||||
|
// Note that we cannot format in constant expressions.
|
||||||
|
panic!("encode_utf8: buffer does not have enough bytes to encode code point");
|
||||||
|
}
|
||||||
|
fn panic_at_rt(code: u32, len: usize, dst_len: usize) {
|
||||||
|
panic!(
|
||||||
|
"encode_utf8: need {len} bytes to encode U+{code:04X} but buffer has just {dst_len}",
|
||||||
|
);
|
||||||
|
}
|
||||||
let len = len_utf8(code);
|
let len = len_utf8(code);
|
||||||
match (len, &mut *dst) {
|
match (len, &mut *dst) {
|
||||||
(1, [a, ..]) => {
|
(1, [a, ..]) => {
|
||||||
@ -1782,8 +1792,8 @@ pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
|
|||||||
*c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
|
*c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
|
||||||
*d = (code & 0x3F) as u8 | TAG_CONT;
|
*d = (code & 0x3F) as u8 | TAG_CONT;
|
||||||
}
|
}
|
||||||
// Note that we cannot format in constant expressions.
|
// FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly.
|
||||||
_ => panic!("encode_utf8: buffer does not have enough bytes to encode code point"),
|
_ => const_eval_select((code, len, dst.len()), panic_at_const, panic_at_rt),
|
||||||
};
|
};
|
||||||
// SAFETY: `<&mut [u8]>::as_mut_ptr` is guaranteed to return a valid pointer and `len` has been tested to be within bounds.
|
// SAFETY: `<&mut [u8]>::as_mut_ptr` is guaranteed to return a valid pointer and `len` has been tested to be within bounds.
|
||||||
unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
|
unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
|
||||||
|
@ -2473,16 +2473,15 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
|||||||
/// # Platform-specific behavior
|
/// # Platform-specific behavior
|
||||||
///
|
///
|
||||||
/// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions
|
/// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions
|
||||||
/// on Unix (except for macOS before version 10.10 and REDOX) and the `CreateFileW`,
|
/// on Unix (except for REDOX) and the `CreateFileW`, `GetFileInformationByHandleEx`,
|
||||||
/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile` functions on
|
/// `SetFileInformationByHandle`, and `NtCreateFile` functions on Windows. Note that, this
|
||||||
/// Windows. Note that, this [may change in the future][changes].
|
/// [may change in the future][changes].
|
||||||
///
|
///
|
||||||
/// [changes]: io#platform-specific-behavior
|
/// [changes]: io#platform-specific-behavior
|
||||||
///
|
///
|
||||||
/// On macOS before version 10.10 and REDOX, as well as when running in Miri for any target, this
|
/// On REDOX, as well as when running in Miri for any target, this function is not protected against
|
||||||
/// function is not protected against time-of-check to time-of-use (TOCTOU) race conditions, and
|
/// time-of-check to time-of-use (TOCTOU) race conditions, and should not be used in
|
||||||
/// should not be used in security-sensitive code on those platforms. All other platforms are
|
/// security-sensitive code on those platforms. All other platforms are protected.
|
||||||
/// protected.
|
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
- [\*-apple-ios-macabi](platform-support/apple-ios-macabi.md)
|
- [\*-apple-ios-macabi](platform-support/apple-ios-macabi.md)
|
||||||
- [arm64e-apple-ios](platform-support/arm64e-apple-ios.md)
|
- [arm64e-apple-ios](platform-support/arm64e-apple-ios.md)
|
||||||
- [\*-apple-tvos](platform-support/apple-tvos.md)
|
- [\*-apple-tvos](platform-support/apple-tvos.md)
|
||||||
|
- [arm64e-apple-tvos](platform-support/arm64e-apple-tvos.md)
|
||||||
- [\*-apple-watchos](platform-support/apple-watchos.md)
|
- [\*-apple-watchos](platform-support/apple-watchos.md)
|
||||||
- [\*-apple-visionos](platform-support/apple-visionos.md)
|
- [\*-apple-visionos](platform-support/apple-visionos.md)
|
||||||
- [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
|
- [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
|
||||||
|
@ -245,8 +245,9 @@ host tools.
|
|||||||
|
|
||||||
target | std | host | notes
|
target | std | host | notes
|
||||||
-------|:---:|:----:|-------
|
-------|:---:|:----:|-------
|
||||||
[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS
|
|
||||||
[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin
|
[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin
|
||||||
|
[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS
|
||||||
|
[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS
|
||||||
[`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS
|
[`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS
|
||||||
[`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS Simulator
|
[`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS Simulator
|
||||||
[`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS
|
[`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS
|
||||||
|
37
src/doc/rustc/src/platform-support/arm64e-apple-tvos.md
Normal file
37
src/doc/rustc/src/platform-support/arm64e-apple-tvos.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# `arm64e-apple-tvos`
|
||||||
|
|
||||||
|
**Tier: 3**
|
||||||
|
|
||||||
|
ARM64e tvOS (10.0+)
|
||||||
|
|
||||||
|
## Target maintainers
|
||||||
|
|
||||||
|
- Artyom Tetyukhin ([@arttet](https://github.com/https://github.com/arttet))
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
This target is cross-compiled and supports `std`.
|
||||||
|
To build this target Xcode 12 or higher on macOS is required.
|
||||||
|
|
||||||
|
## Building the target
|
||||||
|
|
||||||
|
You can build Rust with support for the targets by adding it to the `target` list in `config.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[build]
|
||||||
|
target = [ "arm64e-apple-tvos" ]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building Rust programs
|
||||||
|
|
||||||
|
Rust does not yet ship pre-compiled artifacts for this target.
|
||||||
|
To compile for this target, you will need to build Rust with the target enabled (see [Building the target](#building-the-target) above).
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
The target does support running binaries on tvOS platforms with `arm64e` architecture.
|
||||||
|
|
||||||
|
## Cross-compilation toolchains and C code
|
||||||
|
|
||||||
|
The targets do support `C` code.
|
||||||
|
To build compatible `C` code, you have to use XCode with the same compiler and flags.
|
@ -801,6 +801,9 @@ both the code example and the line numbers, so we need to remove the radius in t
|
|||||||
* and we include additional 10px for padding. */
|
* and we include additional 10px for padding. */
|
||||||
max-height: calc(1.5em * 5 + 10px);
|
max-height: calc(1.5em * 5 + 10px);
|
||||||
}
|
}
|
||||||
|
.more-scraped-examples .scraped-example:not(.expanded) .example-wrap {
|
||||||
|
max-height: calc(1.5em * 10 + 10px);
|
||||||
|
}
|
||||||
|
|
||||||
.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers,
|
.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers,
|
||||||
.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers > pre,
|
.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers > pre,
|
||||||
@ -828,10 +831,14 @@ both the code example and the line numbers, so we need to remove the radius in t
|
|||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
padding: 14px 8px;
|
padding: 14px 8px;
|
||||||
|
padding-right: 2px;
|
||||||
color: var(--src-line-numbers-span-color);
|
color: var(--src-line-numbers-span-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.rustdoc .scraped-example .src-line-numbers {
|
.rustdoc .scraped-example .example-wrap .src-line-numbers {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.rustdoc .src-line-numbers pre {
|
||||||
padding: 14px 0;
|
padding: 14px 0;
|
||||||
}
|
}
|
||||||
.src-line-numbers a, .src-line-numbers span {
|
.src-line-numbers a, .src-line-numbers span {
|
||||||
@ -890,7 +897,7 @@ both the code example and the line numbers, so we need to remove the radius in t
|
|||||||
}
|
}
|
||||||
|
|
||||||
.docblock code, .docblock-short code,
|
.docblock code, .docblock-short code,
|
||||||
pre, .rustdoc.src .example-wrap {
|
pre, .rustdoc.src .example-wrap, .example-wrap .src-line-numbers {
|
||||||
background-color: var(--code-block-background-color);
|
background-color: var(--code-block-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,9 +51,7 @@ static HOSTS: &[&str] = &[
|
|||||||
|
|
||||||
static TARGETS: &[&str] = &[
|
static TARGETS: &[&str] = &[
|
||||||
"aarch64-apple-darwin",
|
"aarch64-apple-darwin",
|
||||||
"arm64e-apple-darwin",
|
|
||||||
"aarch64-apple-ios",
|
"aarch64-apple-ios",
|
||||||
"arm64e-apple-ios",
|
|
||||||
"aarch64-apple-ios-macabi",
|
"aarch64-apple-ios-macabi",
|
||||||
"aarch64-apple-ios-sim",
|
"aarch64-apple-ios-sim",
|
||||||
"aarch64-unknown-fuchsia",
|
"aarch64-unknown-fuchsia",
|
||||||
@ -68,6 +66,9 @@ static TARGETS: &[&str] = &[
|
|||||||
"aarch64-unknown-none-softfloat",
|
"aarch64-unknown-none-softfloat",
|
||||||
"aarch64-unknown-redox",
|
"aarch64-unknown-redox",
|
||||||
"aarch64-unknown-uefi",
|
"aarch64-unknown-uefi",
|
||||||
|
"arm64e-apple-darwin",
|
||||||
|
"arm64e-apple-ios",
|
||||||
|
"arm64e-apple-tvos",
|
||||||
"arm-linux-androideabi",
|
"arm-linux-androideabi",
|
||||||
"arm-unknown-linux-gnueabi",
|
"arm-unknown-linux-gnueabi",
|
||||||
"arm-unknown-linux-gnueabihf",
|
"arm-unknown-linux-gnueabihf",
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
//@ revisions: aarch64_apple_tvos_sim
|
//@ revisions: aarch64_apple_tvos_sim
|
||||||
//@ [aarch64_apple_tvos_sim] compile-flags: --target aarch64-apple-tvos-sim
|
//@ [aarch64_apple_tvos_sim] compile-flags: --target aarch64-apple-tvos-sim
|
||||||
//@ [aarch64_apple_tvos_sim] needs-llvm-components: aarch64
|
//@ [aarch64_apple_tvos_sim] needs-llvm-components: aarch64
|
||||||
|
//@ revisions: arm64e_apple_tvos
|
||||||
|
//@ [arm64e_apple_tvos] compile-flags: --target arm64e-apple-tvos
|
||||||
|
//@ [arm64e_apple_tvos] needs-llvm-components: aarch64
|
||||||
//@ revisions: aarch64_apple_watchos
|
//@ revisions: aarch64_apple_watchos
|
||||||
//@ [aarch64_apple_watchos] compile-flags: --target aarch64-apple-watchos
|
//@ [aarch64_apple_watchos] compile-flags: --target aarch64-apple-watchos
|
||||||
//@ [aarch64_apple_watchos] needs-llvm-components: aarch64
|
//@ [aarch64_apple_watchos] needs-llvm-components: aarch64
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
//
|
|
||||||
//@ only-apple
|
|
||||||
//@ compile-flags: -O
|
|
||||||
|
|
||||||
#![crate_type = "rlib"]
|
|
||||||
#![feature(thread_local)]
|
|
||||||
|
|
||||||
// local_unnamed_addr does not appear when std is built with debug assertions.
|
|
||||||
// CHECK: @STATIC_VAR_1 = thread_local {{(local_unnamed_addr )?}}global <{ [32 x i8] }> zeroinitializer, section "__DATA,__thread_bss", align 4
|
|
||||||
#[no_mangle]
|
|
||||||
#[thread_local]
|
|
||||||
static mut STATIC_VAR_1: [u32; 8] = [0; 8];
|
|
||||||
|
|
||||||
// CHECK: @STATIC_VAR_2 = thread_local {{(local_unnamed_addr )?}}global <{ [32 x i8] }> <{{[^>]*}}>, section "__DATA,__thread_data", align 4
|
|
||||||
#[no_mangle]
|
|
||||||
#[thread_local]
|
|
||||||
static mut STATIC_VAR_2: [u32; 8] = [4; 8];
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe fn f(x: &mut [u32; 8]) {
|
|
||||||
std::mem::swap(x, &mut STATIC_VAR_1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe fn g(x: &mut [u32; 8]) {
|
|
||||||
std::mem::swap(x, &mut STATIC_VAR_2)
|
|
||||||
}
|
|
@ -39,7 +39,10 @@ define-function: (
|
|||||||
{
|
{
|
||||||
"color": |color|,
|
"color": |color|,
|
||||||
"margin": "0px",
|
"margin": "0px",
|
||||||
"padding": "14px 8px",
|
"padding-top": "14px",
|
||||||
|
"padding-bottom": "14px",
|
||||||
|
"padding-left": "8px",
|
||||||
|
"padding-right": "2px",
|
||||||
"text-align": "right",
|
"text-align": "right",
|
||||||
// There should not be a radius on the right of the line numbers.
|
// There should not be a radius on the right of the line numbers.
|
||||||
"border-top-left-radius": "6px",
|
"border-top-left-radius": "6px",
|
||||||
@ -141,3 +144,61 @@ assert-css: (
|
|||||||
},
|
},
|
||||||
ALL,
|
ALL,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Checking line numbers on scraped code examples.
|
||||||
|
go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
|
||||||
|
|
||||||
|
define-function: (
|
||||||
|
"check-padding",
|
||||||
|
[path, padding_bottom],
|
||||||
|
block {
|
||||||
|
assert-css: (|path| + " .src-line-numbers", {
|
||||||
|
"padding-top": "0px",
|
||||||
|
"padding-bottom": "0px",
|
||||||
|
"padding-left": "0px",
|
||||||
|
"padding-right": "0px",
|
||||||
|
})
|
||||||
|
assert-css: (|path| + " .src-line-numbers > pre", {
|
||||||
|
"padding-top": "14px",
|
||||||
|
"padding-bottom": |padding_bottom|,
|
||||||
|
"padding-left": "0px",
|
||||||
|
"padding-right": "0px",
|
||||||
|
})
|
||||||
|
assert-css: (|path| + " .src-line-numbers > pre > span", {
|
||||||
|
"padding-top": "0px",
|
||||||
|
"padding-bottom": "0px",
|
||||||
|
"padding-left": "8px",
|
||||||
|
"padding-right": "8px",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
call-function: ("check-padding", {
|
||||||
|
"path": ".scraped-example .example-wrap",
|
||||||
|
"padding_bottom": "0px",
|
||||||
|
})
|
||||||
|
|
||||||
|
move-cursor-to: ".scraped-example .example-wrap .rust"
|
||||||
|
wait-for: ".scraped-example .example-wrap .button-holder .expand"
|
||||||
|
click: ".scraped-example .example-wrap .button-holder .expand"
|
||||||
|
wait-for: ".scraped-example.expanded"
|
||||||
|
|
||||||
|
call-function: ("check-padding", {
|
||||||
|
"path": ".scraped-example.expanded .example-wrap",
|
||||||
|
"padding_bottom": "14px",
|
||||||
|
})
|
||||||
|
|
||||||
|
// Now checking the line numbers in the source code page.
|
||||||
|
click: ".src"
|
||||||
|
assert-css: (".src-line-numbers", {
|
||||||
|
"padding-top": "20px",
|
||||||
|
"padding-bottom": "20px",
|
||||||
|
"padding-left": "4px",
|
||||||
|
"padding-right": "0px",
|
||||||
|
})
|
||||||
|
assert-css: (".src-line-numbers > a", {
|
||||||
|
"padding-top": "0px",
|
||||||
|
"padding-bottom": "0px",
|
||||||
|
"padding-left": "8px",
|
||||||
|
"padding-right": "8px",
|
||||||
|
})
|
||||||
|
@ -37,6 +37,7 @@ assert-property: (
|
|||||||
|
|
||||||
// The "title" should be located at the right bottom corner of the code example.
|
// The "title" should be located at the right bottom corner of the code example.
|
||||||
store-position: (".scraped-example .example-wrap", {"x": x, "y": y})
|
store-position: (".scraped-example .example-wrap", {"x": x, "y": y})
|
||||||
|
assert-size: (".scraped-example .example-wrap", {"height": 130})
|
||||||
store-size: (".scraped-example .example-wrap", {"width": width, "height": height})
|
store-size: (".scraped-example .example-wrap", {"width": width, "height": height})
|
||||||
store-size: (".scraped-example .scraped-example-title", {
|
store-size: (".scraped-example .scraped-example-title", {
|
||||||
"width": title_width,
|
"width": title_width,
|
||||||
@ -47,6 +48,13 @@ assert-position: (".scraped-example .scraped-example-title", {
|
|||||||
"y": |y| + |height| - |title_height| - 8,
|
"y": |y| + |height| - |title_height| - 8,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
store-size: (".more-scraped-examples .scraped-example .example-wrap", {"height": more_height})
|
||||||
|
assert: |more_height| > |height|
|
||||||
|
assert-size: (".more-scraped-examples .scraped-example .example-wrap", {
|
||||||
|
"height": 250,
|
||||||
|
"width": |width|,
|
||||||
|
})
|
||||||
|
|
||||||
// Check that the expand button works and also that line number aligns with code.
|
// Check that the expand button works and also that line number aligns with code.
|
||||||
move-cursor-to: ".scraped-example .rust"
|
move-cursor-to: ".scraped-example .rust"
|
||||||
click: ".scraped-example .button-holder .expand"
|
click: ".scraped-example .button-holder .expand"
|
||||||
|
36
tests/ui/async-await/pin-reborrow-arg.rs
Normal file
36
tests/ui/async-await/pin-reborrow-arg.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(dead_code, incomplete_features)]
|
||||||
|
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn baz(self: Pin<&mut Self>) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(_: Pin<&mut Foo>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo_const(_: Pin<&Foo>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(x: Pin<&mut Foo>) {
|
||||||
|
foo(x);
|
||||||
|
foo(x); // for this to work we need to automatically reborrow,
|
||||||
|
// as if the user had written `foo(x.as_mut())`.
|
||||||
|
|
||||||
|
Foo::baz(x);
|
||||||
|
Foo::baz(x);
|
||||||
|
|
||||||
|
foo_const(x); // make sure we can reborrow &mut as &.
|
||||||
|
|
||||||
|
let x: Pin<&Foo> = Pin::new(&Foo);
|
||||||
|
|
||||||
|
foo_const(x); // make sure reborrowing from & to & works.
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
18
tests/ui/async-await/pin-reborrow-const-as-mut.rs
Normal file
18
tests/ui/async-await/pin-reborrow-const-as-mut.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(dead_code, incomplete_features)]
|
||||||
|
|
||||||
|
// make sure we can't accidentally reborrow Pin<&T> as Pin<&mut T>
|
||||||
|
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
fn foo(_: Pin<&mut Foo>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(x: Pin<&Foo>) {
|
||||||
|
foo(x); //~ ERROR mismatched types
|
||||||
|
//| ERROR types differ in mutability
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
19
tests/ui/async-await/pin-reborrow-const-as-mut.stderr
Normal file
19
tests/ui/async-await/pin-reborrow-const-as-mut.stderr
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/pin-reborrow-const-as-mut.rs:14:9
|
||||||
|
|
|
||||||
|
LL | foo(x);
|
||||||
|
| --- ^ types differ in mutability
|
||||||
|
| |
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
= note: expected struct `Pin<&mut Foo>`
|
||||||
|
found struct `Pin<&Foo>`
|
||||||
|
note: function defined here
|
||||||
|
--> $DIR/pin-reborrow-const-as-mut.rs:10:4
|
||||||
|
|
|
||||||
|
LL | fn foo(_: Pin<&mut Foo>) {
|
||||||
|
| ^^^ ----------------
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
13
tests/ui/async-await/pin-reborrow-once.rs
Normal file
13
tests/ui/async-await/pin-reborrow-once.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(dead_code, incomplete_features)]
|
||||||
|
|
||||||
|
// Make sure with pin reborrowing that we can only get one mutable reborrow of a pinned reference.
|
||||||
|
|
||||||
|
use std::pin::{pin, Pin};
|
||||||
|
|
||||||
|
fn twice(_: Pin<&mut i32>, _: Pin<&mut i32>) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = pin!(42);
|
||||||
|
twice(x, x); //~ ERROR cannot borrow
|
||||||
|
}
|
12
tests/ui/async-await/pin-reborrow-once.stderr
Normal file
12
tests/ui/async-await/pin-reborrow-once.stderr
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
error[E0499]: cannot borrow `*x.__pointer` as mutable more than once at a time
|
||||||
|
--> $DIR/pin-reborrow-once.rs:12:14
|
||||||
|
|
|
||||||
|
LL | twice(x, x);
|
||||||
|
| ----- - ^ second mutable borrow occurs here
|
||||||
|
| | |
|
||||||
|
| | first mutable borrow occurs here
|
||||||
|
| first borrow later used by call
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0499`.
|
24
tests/ui/async-await/pin-reborrow-self.rs
Normal file
24
tests/ui/async-await/pin-reborrow-self.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//@ check-pass
|
||||||
|
//@ignore-test
|
||||||
|
|
||||||
|
// Currently ignored due to self reborrowing not being implemented for Pin
|
||||||
|
|
||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn foo(self: Pin<&mut Self>) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(x: Pin<&mut Foo>) {
|
||||||
|
x.foo();
|
||||||
|
x.foo(); // for this to work we need to automatically reborrow,
|
||||||
|
// as if the user had written `x.as_mut().foo()`.
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
tests/ui/async-await/pin-reborrow-shorter.rs
Normal file
14
tests/ui/async-await/pin-reborrow-shorter.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//@check-pass
|
||||||
|
|
||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(dead_code, incomplete_features)]
|
||||||
|
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
fn shorter<'b, T: 'b>(_: Pin<&'b mut T>) {}
|
||||||
|
|
||||||
|
fn test<'a: 'b, 'b, T: 'a>(x: Pin<&'a mut T>) {
|
||||||
|
shorter::<'b>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
tests/ui/feature-gates/feature-gate-pin_ergonomics.rs
Normal file
15
tests/ui/feature-gates/feature-gate-pin_ergonomics.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#![allow(dead_code, incomplete_features)]
|
||||||
|
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
fn foo(_: Pin<&mut Foo>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(mut x: Pin<&mut Foo>) {
|
||||||
|
foo(x);
|
||||||
|
foo(x); //~ ERROR use of moved value: `x`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
21
tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr
Normal file
21
tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
error[E0382]: use of moved value: `x`
|
||||||
|
--> $DIR/feature-gate-pin_ergonomics.rs:12:9
|
||||||
|
|
|
||||||
|
LL | fn bar(mut x: Pin<&mut Foo>) {
|
||||||
|
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
||||||
|
LL | foo(x);
|
||||||
|
| - value moved here
|
||||||
|
LL | foo(x);
|
||||||
|
| ^ value used here after move
|
||||||
|
|
|
||||||
|
note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
|
||||||
|
--> $DIR/feature-gate-pin_ergonomics.rs:7:11
|
||||||
|
|
|
||||||
|
LL | fn foo(_: Pin<&mut Foo>) {
|
||||||
|
| --- ^^^^^^^^^^^^^ this parameter takes ownership of the value
|
||||||
|
| |
|
||||||
|
| in this function
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0382`.
|
@ -1,4 +1,6 @@
|
|||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
//@ revisions: current next
|
||||||
|
//[next]@ compile-flags: -Znext-solver
|
||||||
|
|
||||||
// Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
|
// Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
|
|||||||
LL | impls::<W<_>>();
|
LL | impls::<W<_>>();
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
|
||||||
note: required by a bound in `impls`
|
note: required by a bound in `impls`
|
||||||
--> $DIR/fixpoint-exponential-growth.rs:30:13
|
--> $DIR/fixpoint-exponential-growth.rs:30:13
|
||||||
|
|
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
//~ ERROR overflow evaluating the requirement `Self: Trait`
|
||||||
|
//~^ ERROR overflow evaluating the requirement `Self well-formed`
|
||||||
// This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
|
// This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
|
||||||
//@ compile-flags: -Znext-solver --crate-type=lib
|
//@ compile-flags: -Znext-solver --crate-type=lib
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
#![recursion_limit = "0"]
|
#![recursion_limit = "0"]
|
||||||
trait Trait {}
|
trait Trait {}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
error[E0275]: overflow evaluating the requirement `Self: Trait`
|
||||||
|
|
|
||||||
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `Self well-formed`
|
||||||
|
|
|
||||||
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0275`.
|
Loading…
Reference in New Issue
Block a user