mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 14:07:04 +00:00
Auto merge of #137651 - fmease:rollup-s3s7m6f, r=fmease
Rollup of 14 pull requests Successful merges: - #136576 (pass optimization level to llvm-bitcode-linker) - #137154 (Add UTF-8 validation fast paths in `Wtf8Buf`) - #137311 (Enable `f16` for MIPS) - #137320 (fix(rustdoc): Fixed stability version in rustdoc) - #137529 (remove few unused args) - #137544 (tests: Add regression test for derive token invalidation (#81099)) - #137559 (run some tests on emscripten again) - #137601 (ssa/mono: deduplicate `type_has_metadata`) - #137603 (codegen_llvm: avoid `Deref` impls w/ extern type) - #137604 (trait_sel: resolve vars in host effects) - #137609 (Complete the list of resources used in rustdoc output) - #137613 (hir_analysis: skip self type of host effect preds in variances_of) - #137614 (fix doc in library/core/src/pin.rs) - #137622 (fix attribute-related ICE when parsing macro on the rhs of a name-value attribute) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2b3cef882a
@ -333,7 +333,10 @@ impl<'sess> AttributeParser<'sess> {
|
||||
{
|
||||
lit
|
||||
} else {
|
||||
let guar = self.dcx().has_errors().unwrap();
|
||||
let guar = self.dcx().span_delayed_bug(
|
||||
args.span().unwrap_or(DUMMY_SP),
|
||||
"expr in place where literal is expected (builtin attr parsing)",
|
||||
);
|
||||
ast::MetaItemLit {
|
||||
symbol: kw::Empty,
|
||||
suffix: None,
|
||||
|
@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_hir::{self as hir, AttrPath};
|
||||
use rustc_span::symbol::{Ident, kw};
|
||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol};
|
||||
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
||||
|
||||
pub struct SegmentIterator<'a> {
|
||||
offset: usize,
|
||||
@ -127,7 +127,7 @@ impl<'a> ArgParser<'a> {
|
||||
}
|
||||
AttrArgs::Eq { eq_span, expr } => Self::NameValue(NameValueParser {
|
||||
eq_span: *eq_span,
|
||||
value: expr_to_lit(dcx, &expr),
|
||||
value: expr_to_lit(dcx, &expr, *eq_span),
|
||||
value_span: expr.span,
|
||||
}),
|
||||
}
|
||||
@ -348,7 +348,7 @@ impl NameValueParser {
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr) -> MetaItemLit {
|
||||
fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr, span: Span) -> MetaItemLit {
|
||||
// In valid code the value always ends up as a single literal. Otherwise, a dummy
|
||||
// literal suffices because the error is handled elsewhere.
|
||||
if let ExprKind::Lit(token_lit) = expr.kind
|
||||
@ -356,8 +356,11 @@ fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr) -> MetaItemLit {
|
||||
{
|
||||
lit
|
||||
} else {
|
||||
let guar = dcx.has_errors().unwrap();
|
||||
MetaItemLit { symbol: kw::Empty, suffix: None, kind: LitKind::Err(guar), span: DUMMY_SP }
|
||||
let guar = dcx.span_delayed_bug(
|
||||
span,
|
||||
"expr in place where literal is expected (builtin attr parsing)",
|
||||
);
|
||||
MetaItemLit { symbol: kw::Empty, suffix: None, kind: LitKind::Err(guar), span }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,7 +648,7 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
|
||||
| StatementKind::StorageLive(..) => {}
|
||||
// This does not affect borrowck
|
||||
StatementKind::BackwardIncompatibleDropHint { place, reason: BackwardIncompatibleDropReason::Edition2024 } => {
|
||||
self.check_backward_incompatible_drop(location, (**place, span), state);
|
||||
self.check_backward_incompatible_drop(location, **place, state);
|
||||
}
|
||||
StatementKind::StorageDead(local) => {
|
||||
self.access_place(
|
||||
@ -1174,7 +1174,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||
fn check_backward_incompatible_drop(
|
||||
&mut self,
|
||||
location: Location,
|
||||
(place, place_span): (Place<'tcx>, Span),
|
||||
place: Place<'tcx>,
|
||||
state: &BorrowckDomain,
|
||||
) {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
@ -793,7 +793,9 @@ pub(crate) unsafe fn optimize_thin_module(
|
||||
{
|
||||
let _timer =
|
||||
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
|
||||
unsafe { llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) };
|
||||
unsafe {
|
||||
llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target.raw())
|
||||
};
|
||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
|
||||
}
|
||||
|
||||
@ -823,7 +825,7 @@ pub(crate) unsafe fn optimize_thin_module(
|
||||
let _timer =
|
||||
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
|
||||
if unsafe {
|
||||
!llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target)
|
||||
!llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target.raw())
|
||||
} {
|
||||
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use std::ffi::{CStr, c_char};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
@ -80,12 +79,12 @@ impl OwnedTargetMachine {
|
||||
.map(|tm_unique| Self { tm_unique, phantom: PhantomData })
|
||||
.ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for OwnedTargetMachine {
|
||||
type Target = llvm::TargetMachine;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
/// Returns inner `llvm::TargetMachine` type.
|
||||
///
|
||||
/// This could be a `Deref` implementation, but `llvm::TargetMachine` is an extern type and
|
||||
/// `Deref::Target: ?Sized`.
|
||||
pub fn raw(&self) -> &llvm::TargetMachine {
|
||||
// SAFETY: constructing ensures we have a valid pointer created by
|
||||
// llvm::LLVMRustCreateTargetMachine.
|
||||
unsafe { self.tm_unique.as_ref() }
|
||||
|
@ -637,7 +637,7 @@ pub(crate) unsafe fn llvm_optimize(
|
||||
let result = unsafe {
|
||||
llvm::LLVMRustOptimize(
|
||||
module.module_llvm.llmod(),
|
||||
&*module.module_llvm.tm,
|
||||
&*module.module_llvm.tm.raw(),
|
||||
to_pass_builder_opt_level(opt_level),
|
||||
opt_stage,
|
||||
cgcx.opts.cg.linker_plugin_lto.enabled(),
|
||||
@ -875,7 +875,7 @@ pub(crate) unsafe fn codegen(
|
||||
};
|
||||
write_output_file(
|
||||
dcx,
|
||||
tm,
|
||||
tm.raw(),
|
||||
config.no_builtins,
|
||||
llmod,
|
||||
&path,
|
||||
@ -909,7 +909,7 @@ pub(crate) unsafe fn codegen(
|
||||
|
||||
write_output_file(
|
||||
dcx,
|
||||
tm,
|
||||
tm.raw(),
|
||||
config.no_builtins,
|
||||
llmod,
|
||||
&obj_out,
|
||||
|
@ -405,7 +405,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
|
||||
// Emit KCFI operand bundle
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
|
||||
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
|
||||
bundles.push(kcfi_bundle);
|
||||
}
|
||||
|
||||
@ -1433,7 +1433,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
|
||||
// Emit KCFI operand bundle
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
|
||||
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
|
||||
bundles.push(kcfi_bundle);
|
||||
}
|
||||
|
||||
@ -1782,7 +1782,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
|
||||
// Emit KCFI operand bundle
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
|
||||
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
|
||||
bundles.push(kcfi_bundle);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ impl<'ll> Funclet<'ll> {
|
||||
}
|
||||
|
||||
pub(crate) fn bundle(&self) -> &llvm::OperandBundle<'ll> {
|
||||
&self.operand
|
||||
self.operand.raw()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ pub(crate) unsafe fn create_module<'ll>(
|
||||
{
|
||||
let tm = crate::back::write::create_informational_target_machine(tcx.sess, false);
|
||||
unsafe {
|
||||
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
|
||||
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm.raw());
|
||||
}
|
||||
|
||||
let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) };
|
||||
|
@ -1,7 +1,6 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ops::Deref;
|
||||
use std::ptr;
|
||||
use std::str::FromStr;
|
||||
use std::string::FromUtf8Error;
|
||||
@ -355,6 +354,16 @@ impl<'a> OperandBundleOwned<'a> {
|
||||
};
|
||||
OperandBundleOwned { raw: ptr::NonNull::new(raw).unwrap() }
|
||||
}
|
||||
|
||||
/// Returns inner `OperandBundle` type.
|
||||
///
|
||||
/// This could be a `Deref` implementation, but `OperandBundle` contains an extern type and
|
||||
/// `Deref::Target: ?Sized`.
|
||||
pub(crate) fn raw(&self) -> &OperandBundle<'a> {
|
||||
// SAFETY: The returned reference is opaque and can only used for FFI.
|
||||
// It is valid for as long as `&self` is.
|
||||
unsafe { self.raw.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OperandBundleOwned<'_> {
|
||||
@ -365,16 +374,6 @@ impl Drop for OperandBundleOwned<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for OperandBundleOwned<'a> {
|
||||
type Target = OperandBundle<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY: The returned reference is opaque and can only used for FFI.
|
||||
// It is valid for as long as `&self` is.
|
||||
unsafe { self.raw.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add_module_flag_u32(
|
||||
module: &Module,
|
||||
merge_behavior: ModuleFlagMergeBehavior,
|
||||
|
@ -331,7 +331,8 @@ pub(crate) fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec<S
|
||||
if let Some(feat) = to_llvm_features(sess, feature) {
|
||||
for llvm_feature in feat {
|
||||
let cstr = SmallCStr::new(llvm_feature);
|
||||
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
|
||||
if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) }
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -453,8 +454,8 @@ pub(crate) fn print(req: &PrintRequest, out: &mut String, sess: &Session) {
|
||||
require_inited();
|
||||
let tm = create_informational_target_machine(sess, false);
|
||||
match req.kind {
|
||||
PrintKind::TargetCPUs => print_target_cpus(sess, &tm, out),
|
||||
PrintKind::TargetFeatures => print_target_features(sess, &tm, out),
|
||||
PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out),
|
||||
PrintKind::TargetFeatures => print_target_features(sess, tm.raw(), out),
|
||||
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
|
||||
}
|
||||
}
|
||||
|
@ -1939,14 +1939,14 @@ impl<'a> Linker for LlbcLinker<'a> {
|
||||
}
|
||||
|
||||
fn optimize(&mut self) {
|
||||
match self.sess.opts.optimize {
|
||||
self.link_arg(match self.sess.opts.optimize {
|
||||
OptLevel::No => "-O0",
|
||||
OptLevel::Less => "-O1",
|
||||
OptLevel::More => "-O2",
|
||||
OptLevel::Aggressive => "-O3",
|
||||
OptLevel::Size => "-Os",
|
||||
OptLevel::SizeMin => "-Oz",
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
fn full_relro(&mut self) {}
|
||||
|
@ -2,7 +2,7 @@ use rustc_abi::Primitive::{Int, Pointer};
|
||||
use rustc_abi::{Align, BackendRepr, FieldsShape, Size, TagEncoding, VariantIdx, Variants};
|
||||
use rustc_middle::mir::PlaceTy;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::{bug, mir};
|
||||
use tracing::{debug, instrument};
|
||||
@ -168,7 +168,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
||||
};
|
||||
let val = PlaceValue {
|
||||
llval,
|
||||
llextra: if bx.cx().type_has_metadata(field.ty) { self.val.llextra } else { None },
|
||||
llextra: if bx.cx().tcx().type_has_metadata(field.ty, bx.cx().typing_env()) {
|
||||
self.val.llextra
|
||||
} else {
|
||||
None
|
||||
},
|
||||
align: effective_field_align,
|
||||
};
|
||||
val.with_type(field)
|
||||
|
@ -3,7 +3,7 @@ use std::assert_matches::assert_matches;
|
||||
use arrayvec::ArrayVec;
|
||||
use rustc_abi::{self as abi, FIRST_VARIANT, FieldIdx};
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, mir, span_bug};
|
||||
use rustc_session::config::OptLevel;
|
||||
@ -878,7 +878,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
|
||||
let ty = cg_place.layout.ty;
|
||||
assert!(
|
||||
if bx.cx().type_has_metadata(ty) {
|
||||
if bx.cx().tcx().type_has_metadata(ty, bx.cx().typing_env()) {
|
||||
matches!(val, OperandValue::Pair(..))
|
||||
} else {
|
||||
matches!(val, OperandValue::Immediate(..))
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rustc_abi::{AddressSpace, Float, Integer, Reg};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi};
|
||||
|
||||
use super::BackendTypes;
|
||||
@ -84,19 +84,6 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
|
||||
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
||||
ty.is_freeze(self.tcx(), self.typing_env())
|
||||
}
|
||||
|
||||
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
|
||||
if ty.is_sized(self.tcx(), self.typing_env()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let tail = self.tcx().struct_tail_for_codegen(ty, self.typing_env());
|
||||
match tail.kind() {
|
||||
ty::Foreign(..) => false,
|
||||
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
||||
_ => bug!("unexpected unsized tail: {:?}", tail),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where
|
||||
|
@ -1074,7 +1074,6 @@ fn lower_variant<'tcx>(
|
||||
def.ctor().map(|(kind, _, def_id)| (kind, def_id.to_def_id())),
|
||||
discr,
|
||||
fields,
|
||||
adt_kind,
|
||||
parent_did.to_def_id(),
|
||||
recovered,
|
||||
adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive)
|
||||
|
@ -198,6 +198,10 @@ fn variance_of_opaque(
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef { def_id: _, args, .. },
|
||||
polarity: _,
|
||||
})
|
||||
| ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
|
||||
trait_ref: ty::TraitRef { def_id: _, args, .. },
|
||||
constness: _,
|
||||
}) => {
|
||||
for arg in &args[1..] {
|
||||
arg.visit_with(&mut collector);
|
||||
|
@ -1116,7 +1116,6 @@ impl<'a> CrateMetadataRef<'a> {
|
||||
value: self.get_default_field(did.index),
|
||||
})
|
||||
.collect(),
|
||||
adt_kind,
|
||||
parent_did,
|
||||
None,
|
||||
data.is_non_exhaustive,
|
||||
|
@ -1184,23 +1184,17 @@ impl VariantDef {
|
||||
///
|
||||
/// If someone speeds up attribute loading to not be a performance concern, they can
|
||||
/// remove this hack and use the constructor `DefId` everywhere.
|
||||
#[instrument(level = "debug")]
|
||||
pub fn new(
|
||||
name: Symbol,
|
||||
variant_did: Option<DefId>,
|
||||
ctor: Option<(CtorKind, DefId)>,
|
||||
discr: VariantDiscr,
|
||||
fields: IndexVec<FieldIdx, FieldDef>,
|
||||
adt_kind: AdtKind,
|
||||
parent_did: DefId,
|
||||
recover_tainted: Option<ErrorGuaranteed>,
|
||||
is_field_list_non_exhaustive: bool,
|
||||
) -> Self {
|
||||
debug!(
|
||||
"VariantDef::new(name = {:?}, variant_did = {:?}, ctor = {:?}, discr = {:?},
|
||||
fields = {:?}, adt_kind = {:?}, parent_did = {:?})",
|
||||
name, variant_did, ctor, discr, fields, adt_kind, parent_did,
|
||||
);
|
||||
|
||||
let mut flags = VariantFlags::NO_VARIANT_FLAGS;
|
||||
if is_field_list_non_exhaustive {
|
||||
flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
|
||||
|
@ -208,6 +208,20 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(typing_env, ty), || {})
|
||||
}
|
||||
|
||||
/// Returns true if a type has metadata.
|
||||
pub fn type_has_metadata(self, ty: Ty<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool {
|
||||
if ty.is_sized(self, typing_env) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let tail = self.struct_tail_for_codegen(ty, typing_env);
|
||||
match tail.kind() {
|
||||
ty::Foreign(..) => false,
|
||||
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
||||
_ => bug!("unexpected unsized tail: {:?}", tail),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the deeply last field of nested structures, or the same type if
|
||||
/// not a structure at all. Corresponds to the only possible unsized field,
|
||||
/// and its type can be used to determine unsizing strategy.
|
||||
|
@ -751,7 +751,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
||||
/// This does not walk the MIR of the constant as that is not needed for codegen, all we need is
|
||||
/// to ensure that the constant evaluates successfully and walk the result.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn visit_const_operand(&mut self, constant: &mir::ConstOperand<'tcx>, location: Location) {
|
||||
fn visit_const_operand(&mut self, constant: &mir::ConstOperand<'tcx>, _location: Location) {
|
||||
// No `super_constant` as we don't care about `visit_ty`/`visit_ty_const`.
|
||||
let Some(val) = self.eval_constant(constant) else { return };
|
||||
collect_const_value(self.tcx, val, self.used_items);
|
||||
@ -1043,18 +1043,7 @@ fn find_vtable_types_for_unsizing<'tcx>(
|
||||
) -> (Ty<'tcx>, Ty<'tcx>) {
|
||||
let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
let type_has_metadata = |ty: Ty<'tcx>| -> bool {
|
||||
if ty.is_sized(tcx.tcx, typing_env) {
|
||||
return false;
|
||||
}
|
||||
let tail = tcx.struct_tail_for_codegen(ty, typing_env);
|
||||
match tail.kind() {
|
||||
ty::Foreign(..) => false,
|
||||
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
||||
_ => bug!("unexpected unsized tail: {:?}", tail),
|
||||
}
|
||||
};
|
||||
if type_has_metadata(inner_source) {
|
||||
if tcx.type_has_metadata(inner_source, typing_env) {
|
||||
(inner_source, inner_target)
|
||||
} else {
|
||||
tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, typing_env)
|
||||
|
@ -2252,7 +2252,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
#[instrument(level = "debug", skip(self, parent_scope))]
|
||||
pub(crate) fn make_path_suggestion(
|
||||
&mut self,
|
||||
span: Span,
|
||||
mut path: Vec<Segment>,
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
) -> Option<(Vec<Segment>, Option<String>)> {
|
||||
@ -2480,7 +2479,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
// or `use a::{b, c, d}};`
|
||||
// ^^^^^^^^^^^
|
||||
let (has_nested, after_crate_name) =
|
||||
find_span_immediately_after_crate_name(self.tcx.sess, module_name, import.use_span);
|
||||
find_span_immediately_after_crate_name(self.tcx.sess, import.use_span);
|
||||
debug!(has_nested, ?after_crate_name);
|
||||
|
||||
let source_map = self.tcx.sess.source_map();
|
||||
@ -2687,11 +2686,7 @@ fn extend_span_to_previous_binding(sess: &Session, binding_span: Span) -> Option
|
||||
/// // ^^^^^^^^^^^^^^^ -- true
|
||||
/// ```
|
||||
#[instrument(level = "debug", skip(sess))]
|
||||
fn find_span_immediately_after_crate_name(
|
||||
sess: &Session,
|
||||
module_name: Symbol,
|
||||
use_span: Span,
|
||||
) -> (bool, Span) {
|
||||
fn find_span_immediately_after_crate_name(sess: &Session, use_span: Span) -> (bool, Span) {
|
||||
let source_map = sess.source_map();
|
||||
|
||||
// Using `use issue_59764::foo::{baz, makro};` as an example throughout..
|
||||
|
@ -955,11 +955,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let err = match self.make_path_suggestion(
|
||||
span,
|
||||
import.module_path.clone(),
|
||||
&import.parent_scope,
|
||||
) {
|
||||
let err = match self
|
||||
.make_path_suggestion(import.module_path.clone(), &import.parent_scope)
|
||||
{
|
||||
Some((suggestion, note)) => UnresolvedImportError {
|
||||
span,
|
||||
label: None,
|
||||
|
@ -31,6 +31,8 @@ pub fn evaluate_host_effect_obligation<'tcx>(
|
||||
);
|
||||
}
|
||||
|
||||
let ref obligation = selcx.infcx.resolve_vars_if_possible(obligation.clone());
|
||||
|
||||
// Force ambiguity for infer self ty.
|
||||
if obligation.predicate.self_ty().is_ty_var() {
|
||||
return Err(EvaluationFailure::Ambiguous);
|
||||
|
@ -1240,8 +1240,8 @@ impl<Ptr: Deref> Pin<Ptr> {
|
||||
/// points to is pinned, that is a violation of the API contract and may lead to undefined
|
||||
/// behavior in later (even safe) operations.
|
||||
///
|
||||
/// By using this method, you are also making a promise about the [`Deref`] and
|
||||
/// [`DerefMut`] implementations of `Ptr`, if they exist. Most importantly, they
|
||||
/// By using this method, you are also making a promise about the [`Deref`],
|
||||
/// [`DerefMut`], and [`Drop`] implementations of `Ptr`, if they exist. Most importantly, they
|
||||
/// must not move out of their `self` arguments: `Pin::as_mut` and `Pin::as_ref`
|
||||
/// will call `DerefMut::deref_mut` and `Deref::deref` *on the pointer type `Ptr`*
|
||||
/// and expect these methods to uphold the pinning invariants.
|
||||
|
@ -107,7 +107,6 @@ fn main() {
|
||||
("csky", _) => false,
|
||||
("hexagon", _) => false,
|
||||
("loongarch64", _) => false,
|
||||
("mips" | "mips64" | "mips32r6" | "mips64r6", _) => false,
|
||||
("powerpc" | "powerpc64", _) => false,
|
||||
("sparc" | "sparc64", _) => false,
|
||||
("wasm32" | "wasm64", _) => false,
|
||||
|
@ -41,13 +41,13 @@ impl AsInner<Wtf8> for Buf {
|
||||
|
||||
impl fmt::Debug for Buf {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(self.as_slice(), f)
|
||||
fmt::Debug::fmt(&self.inner, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Buf {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(self.as_slice(), f)
|
||||
fmt::Display::fmt(&self.inner, f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,18 @@ impl fmt::Debug for Wtf8Buf {
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats the string with unpaired surrogates substituted with the replacement
|
||||
/// character, U+FFFD.
|
||||
impl fmt::Display for Wtf8Buf {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if let Some(s) = self.as_known_utf8() {
|
||||
fmt::Display::fmt(s, formatter)
|
||||
} else {
|
||||
fmt::Display::fmt(&**self, formatter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Wtf8Buf {
|
||||
/// Creates a new, empty WTF-8 string.
|
||||
#[inline]
|
||||
@ -262,6 +274,18 @@ impl Wtf8Buf {
|
||||
unsafe { Wtf8::from_mut_bytes_unchecked(&mut self.bytes) }
|
||||
}
|
||||
|
||||
/// Converts the string to UTF-8 without validation, if it was created from
|
||||
/// valid UTF-8.
|
||||
#[inline]
|
||||
fn as_known_utf8(&self) -> Option<&str> {
|
||||
if self.is_known_utf8 {
|
||||
// SAFETY: The buffer is known to be valid UTF-8.
|
||||
Some(unsafe { str::from_utf8_unchecked(self.as_bytes()) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Reserves capacity for at least `additional` more bytes to be inserted
|
||||
/// in the given `Wtf8Buf`.
|
||||
/// The collection may reserve more space to avoid frequent reallocations.
|
||||
@ -364,7 +388,7 @@ impl Wtf8Buf {
|
||||
_ => {
|
||||
// If we'll be pushing a string containing a surrogate, we may
|
||||
// no longer have UTF-8.
|
||||
if other.next_surrogate(0).is_some() {
|
||||
if self.is_known_utf8 && other.next_surrogate(0).is_some() {
|
||||
self.is_known_utf8 = false;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,27 @@ included, and carry their own copyright notices and license terms:
|
||||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See SourceSerif4-LICENSE.md.
|
||||
|
||||
* Nanum Barun Gothic Font (NanumBarunGothic.woff2)
|
||||
|
||||
Copyright 2010, NAVER Corporation (http://www.nhncorp.com)
|
||||
with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic,
|
||||
NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen,
|
||||
Naver NanumPen, Naver NanumGothicEco, NanumGothicEco,
|
||||
Naver NanumMyeongjoEco, NanumMyeongjoEco, Naver NanumGothicLight,
|
||||
NanumGothicLight, NanumBarunGothic, Naver NanumBarunGothic.
|
||||
|
||||
https://hangeul.naver.com/2017/nanum
|
||||
https://github.com/hiun/NanumBarunGothic
|
||||
|
||||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See NanumBarunGothic-LICENSE.txt.
|
||||
|
||||
* Rust logos (rust-logo.svg, favicon.svg, favicon-32x32.png)
|
||||
|
||||
Copyright 2025 Rust Foundation.
|
||||
Licensed under the Creative Commons Attribution license (CC-BY).
|
||||
https://rustfoundation.org/policy/rust-trademark-policy/
|
||||
|
||||
This copyright file is intended to be distributed with rustdoc output.
|
||||
|
||||
# REUSE-IgnoreEnd
|
||||
|
@ -39,6 +39,16 @@ impl DocFolder for StabilityPropagator<'_, '_> {
|
||||
let item_stability = self.cx.tcx.lookup_stability(def_id);
|
||||
let inline_stability =
|
||||
item.inline_stmt_id.and_then(|did| self.cx.tcx.lookup_stability(did));
|
||||
let is_glob_export = item.inline_stmt_id.and_then(|id| {
|
||||
let hir_id = self.cx.tcx.local_def_id_to_hir_id(id);
|
||||
Some(matches!(
|
||||
self.cx.tcx.hir_node(hir_id),
|
||||
rustc_hir::Node::Item(rustc_hir::Item {
|
||||
kind: rustc_hir::ItemKind::Use(_, rustc_hir::UseKind::Glob),
|
||||
..
|
||||
})
|
||||
))
|
||||
});
|
||||
let own_stability = if let Some(item_stab) = item_stability
|
||||
&& let StabilityLevel::Stable { since: _, allowed_through_unstable_modules } =
|
||||
item_stab.level
|
||||
@ -47,6 +57,8 @@ impl DocFolder for StabilityPropagator<'_, '_> {
|
||||
since: inline_since,
|
||||
allowed_through_unstable_modules: _,
|
||||
} = inline_stab.level
|
||||
&& let Some(is_global_export) = is_glob_export
|
||||
&& !is_global_export
|
||||
{
|
||||
inline_stab.level = StabilityLevel::Stable {
|
||||
since: inline_since,
|
||||
|
@ -16,3 +16,31 @@ pub mod ffi {
|
||||
//@ has "foo/struct.CStr.html" "//span[@class='sub-heading']/span[@class='since']" "1.0.0"
|
||||
//@ !has - "//span[@class='sub-heading']/span[@class='since']" "1.99.0"
|
||||
pub use ffi::CStr;
|
||||
|
||||
// https://github.com/rust-lang/rust/issues/137141
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
//@ has "foo/task/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.36.0"
|
||||
//@ !has - "//span[@class='sub-heading']/span[@class='since']" "1.0.0"
|
||||
pub mod task {
|
||||
|
||||
#[doc(inline)]
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
//@ has "foo/task/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.36.0"
|
||||
//@ has "foo/task/ready/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.64.0"
|
||||
pub use core::task::*;
|
||||
}
|
||||
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
//@ has "foo/core/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.36.0"
|
||||
//@ !has - "//span[@class='sub-heading']/span[@class='since']" "1.0.0"
|
||||
pub mod core {
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
//@ has "foo/core/task/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.36.0"
|
||||
pub mod task {
|
||||
|
||||
#[stable(feature = "ready_macro", since = "1.64.0")]
|
||||
//@ has "foo/core/task/ready/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.64.0"
|
||||
pub mod ready {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
tests/ui/attributes/crate-type-macro-empty.rs
Normal file
7
tests/ui/attributes/crate-type-macro-empty.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// Tests for the issue in #137589
|
||||
#[crate_type = foo!()]
|
||||
//~^ ERROR cannot find macro `foo` in this scope
|
||||
|
||||
macro_rules! foo {} //~ ERROR unexpected end of macro invocation
|
||||
|
||||
fn main() {}
|
20
tests/ui/attributes/crate-type-macro-empty.stderr
Normal file
20
tests/ui/attributes/crate-type-macro-empty.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/crate-type-macro-empty.rs:5:1
|
||||
|
|
||||
LL | macro_rules! foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
||||
error: cannot find macro `foo` in this scope
|
||||
--> $DIR/crate-type-macro-empty.rs:2:16
|
||||
|
|
||||
LL | #[crate_type = foo!()]
|
||||
| ^^^ consider moving the definition of `foo` before this call
|
||||
|
|
||||
note: a macro with the same name exists, but it appears later
|
||||
--> $DIR/crate-type-macro-empty.rs:5:14
|
||||
|
|
||||
LL | macro_rules! foo {}
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
9
tests/ui/attributes/crate-type-macro-not-crate.rs
Normal file
9
tests/ui/attributes/crate-type-macro-not-crate.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// Tests for the issue in #137589
|
||||
|
||||
|
||||
macro_rules! foo {
|
||||
($x:expr) => {"rlib"}
|
||||
}
|
||||
|
||||
#[crate_type = foo!()] //~ ERROR unexpected end of macro invocation
|
||||
fn main() {}
|
17
tests/ui/attributes/crate-type-macro-not-crate.stderr
Normal file
17
tests/ui/attributes/crate-type-macro-not-crate.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
error: unexpected end of macro invocation
|
||||
--> $DIR/crate-type-macro-not-crate.rs:8:16
|
||||
|
|
||||
LL | macro_rules! foo {
|
||||
| ---------------- when calling this macro
|
||||
...
|
||||
LL | #[crate_type = foo!()]
|
||||
| ^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match meta-variable `$x:expr`
|
||||
--> $DIR/crate-type-macro-not-crate.rs:5:6
|
||||
|
|
||||
LL | ($x:expr) => {"rlib"}
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
8
tests/ui/attributes/crate-type-macro-not-found.rs
Normal file
8
tests/ui/attributes/crate-type-macro-not-found.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// Tests for the issue in #137589
|
||||
#[crate_type = foo!()] //~ ERROR cannot find macro `foo` in this scope
|
||||
|
||||
macro_rules! foo {
|
||||
($x:expr) => {"rlib"}
|
||||
}
|
||||
|
||||
fn main() {}
|
14
tests/ui/attributes/crate-type-macro-not-found.stderr
Normal file
14
tests/ui/attributes/crate-type-macro-not-found.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: cannot find macro `foo` in this scope
|
||||
--> $DIR/crate-type-macro-not-found.rs:2:16
|
||||
|
|
||||
LL | #[crate_type = foo!()]
|
||||
| ^^^ consider moving the definition of `foo` before this call
|
||||
|
|
||||
note: a macro with the same name exists, but it appears later
|
||||
--> $DIR/crate-type-macro-not-found.rs:4:14
|
||||
|
|
||||
LL | macro_rules! foo {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
23
tests/ui/proc-macro/derive-cfg-nested-tokens.rs
Normal file
23
tests/ui/proc-macro/derive-cfg-nested-tokens.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// A regression test for issue #81099.
|
||||
|
||||
//@ check-pass
|
||||
//@ proc-macro:test-macros.rs
|
||||
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(proc_macro_hygiene)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate test_macros;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct S {
|
||||
// `print_args` runs twice
|
||||
// - on eagerly configured `S` (from `impl Copy`), only 11 should be printed
|
||||
// - on non-configured `S` (from `struct S`), both 10 and 11 should be printed
|
||||
field: [u8; #[print_attr] {
|
||||
#[cfg(FALSE)] { 10 }
|
||||
#[cfg(not(FALSE))] { 11 }
|
||||
}],
|
||||
}
|
||||
|
||||
fn main() {}
|
149
tests/ui/proc-macro/derive-cfg-nested-tokens.stdout
Normal file
149
tests/ui/proc-macro/derive-cfg-nested-tokens.stdout
Normal file
@ -0,0 +1,149 @@
|
||||
PRINT-ATTR INPUT (DISPLAY): { #[cfg(not(FALSE))] { 11 } }
|
||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [
|
||||
Punct {
|
||||
ch: '#',
|
||||
spacing: Alone,
|
||||
span: #0 bytes(491..492),
|
||||
},
|
||||
Group {
|
||||
delimiter: Bracket,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "cfg",
|
||||
span: #0 bytes(493..496),
|
||||
},
|
||||
Group {
|
||||
delimiter: Parenthesis,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "not",
|
||||
span: #0 bytes(497..500),
|
||||
},
|
||||
Group {
|
||||
delimiter: Parenthesis,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "FALSE",
|
||||
span: #0 bytes(501..506),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(500..507),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(496..508),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(492..509),
|
||||
},
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [
|
||||
Literal {
|
||||
kind: Integer,
|
||||
symbol: "11",
|
||||
suffix: None,
|
||||
span: #0 bytes(513..515),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(511..517),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(452..523),
|
||||
},
|
||||
]
|
||||
PRINT-ATTR INPUT (DISPLAY): { #[cfg(FALSE)] { 10 } #[cfg(not(FALSE))] { 11 } }
|
||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [
|
||||
Punct {
|
||||
ch: '#',
|
||||
spacing: Alone,
|
||||
span: #0 bytes(462..463),
|
||||
},
|
||||
Group {
|
||||
delimiter: Bracket,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "cfg",
|
||||
span: #0 bytes(464..467),
|
||||
},
|
||||
Group {
|
||||
delimiter: Parenthesis,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "FALSE",
|
||||
span: #0 bytes(468..473),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(467..474),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(463..475),
|
||||
},
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [
|
||||
Literal {
|
||||
kind: Integer,
|
||||
symbol: "10",
|
||||
suffix: None,
|
||||
span: #0 bytes(478..480),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(476..482),
|
||||
},
|
||||
Punct {
|
||||
ch: '#',
|
||||
spacing: Alone,
|
||||
span: #0 bytes(491..492),
|
||||
},
|
||||
Group {
|
||||
delimiter: Bracket,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "cfg",
|
||||
span: #0 bytes(493..496),
|
||||
},
|
||||
Group {
|
||||
delimiter: Parenthesis,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "not",
|
||||
span: #0 bytes(497..500),
|
||||
},
|
||||
Group {
|
||||
delimiter: Parenthesis,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "FALSE",
|
||||
span: #0 bytes(501..506),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(500..507),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(496..508),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(492..509),
|
||||
},
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [
|
||||
Literal {
|
||||
kind: Integer,
|
||||
symbol: "11",
|
||||
suffix: None,
|
||||
span: #0 bytes(513..515),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(511..517),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(452..523),
|
||||
},
|
||||
]
|
@ -1,6 +1,5 @@
|
||||
//@ run-pass
|
||||
#![allow(non_camel_case_types)]
|
||||
//@ ignore-emscripten FIXME(#45351) hits an LLVM assert
|
||||
#![feature(repr_simd, intrinsics)]
|
||||
|
||||
#[repr(simd)]
|
||||
@ -53,7 +52,6 @@ unsafe fn simd_or<T>(x: T, y: T) -> T;
|
||||
#[rustc_intrinsic]
|
||||
unsafe fn simd_xor<T>(x: T, y: T) -> T;
|
||||
|
||||
|
||||
#[rustc_intrinsic]
|
||||
unsafe fn simd_neg<T>(x: T) -> T;
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
//@ run-pass
|
||||
//@ ignore-emscripten FIXME(#45351) hits an LLVM assert
|
||||
|
||||
#![feature(repr_simd, intrinsics)]
|
||||
|
||||
|
||||
#[rustc_intrinsic]
|
||||
unsafe fn simd_cast<T, U>(x: T) -> U;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
//@ run-pass
|
||||
//@ ignore-emscripten FIXME(#45351) hits an LLVM assert
|
||||
|
||||
#![feature(repr_simd, intrinsics, concat_idents)]
|
||||
#![allow(non_camel_case_types)]
|
||||
@ -14,7 +13,6 @@ struct u32x4(pub [u32; 4]);
|
||||
#[derive(Copy, Clone)]
|
||||
struct f32x4(pub [f32; 4]);
|
||||
|
||||
|
||||
#[rustc_intrinsic]
|
||||
unsafe fn simd_eq<T, U>(x: T, y: T) -> U;
|
||||
|
||||
@ -39,11 +37,11 @@ macro_rules! cmp {
|
||||
let rhs = $rhs;
|
||||
let e: u32x4 = concat_idents!(simd_, $method)($lhs, $rhs);
|
||||
// assume the scalar version is correct/the behaviour we want.
|
||||
assert!((e.0[0] != 0) == lhs.0[0] .$method(&rhs.0[0]));
|
||||
assert!((e.0[1] != 0) == lhs.0[1] .$method(&rhs.0[1]));
|
||||
assert!((e.0[2] != 0) == lhs.0[2] .$method(&rhs.0[2]));
|
||||
assert!((e.0[3] != 0) == lhs.0[3] .$method(&rhs.0[3]));
|
||||
}}
|
||||
assert!((e.0[0] != 0) == lhs.0[0].$method(&rhs.0[0]));
|
||||
assert!((e.0[1] != 0) == lhs.0[1].$method(&rhs.0[1]));
|
||||
assert!((e.0[2] != 0) == lhs.0[2].$method(&rhs.0[2]));
|
||||
assert!((e.0[3] != 0) == lhs.0[3].$method(&rhs.0[3]));
|
||||
}};
|
||||
}
|
||||
macro_rules! tests {
|
||||
($($lhs: ident, $rhs: ident;)*) => {{
|
||||
@ -75,9 +73,9 @@ fn main() {
|
||||
let i2 = i32x4([5, -5, 20, -100]);
|
||||
let i3 = i32x4([10, -11, 20, -100]);
|
||||
|
||||
let u1 = u32x4([10, !11+1, 12, 13]);
|
||||
let u2 = u32x4([5, !5+1, 20, !100+1]);
|
||||
let u3 = u32x4([10, !11+1, 20, !100+1]);
|
||||
let u1 = u32x4([10, !11 + 1, 12, 13]);
|
||||
let u2 = u32x4([5, !5 + 1, 20, !100 + 1]);
|
||||
let u3 = u32x4([10, !11 + 1, 20, !100 + 1]);
|
||||
|
||||
let f1 = f32x4([10.0, -11.0, 12.0, 13.0]);
|
||||
let f2 = f32x4([5.0, -5.0, 20.0, -100.0]);
|
||||
|
@ -1,5 +1,4 @@
|
||||
//@ run-pass
|
||||
//@ ignore-emscripten FIXME(#45351) hits an LLVM assert
|
||||
|
||||
#![feature(repr_simd, intrinsics)]
|
||||
|
||||
@ -22,7 +21,6 @@ unsafe fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
|
||||
#[rustc_intrinsic]
|
||||
unsafe fn simd_extract<T, E>(x: T, idx: u32) -> E;
|
||||
|
||||
|
||||
#[rustc_intrinsic]
|
||||
unsafe fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
//@ run-pass
|
||||
//@ ignore-emscripten FIXME(#45351)
|
||||
|
||||
#![feature(repr_simd, test)]
|
||||
|
||||
@ -15,9 +14,7 @@ fn main() {
|
||||
// non-optimized builds
|
||||
unsafe {
|
||||
let memory = &mut [0u64; 8] as *mut _ as *mut u8;
|
||||
let misaligned_ptr: &mut [u8; 32] = {
|
||||
std::mem::transmute(memory.offset(1))
|
||||
};
|
||||
let misaligned_ptr: &mut [u8; 32] = { std::mem::transmute(memory.offset(1)) };
|
||||
*misaligned_ptr = std::mem::transmute(Mu64([1, 1, 1, 1]));
|
||||
test::black_box(memory);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
//@ run-pass
|
||||
//@ ignore-emscripten FIXME(#45351)
|
||||
|
||||
#![feature(repr_simd, intrinsics)]
|
||||
|
||||
|
@ -0,0 +1,36 @@
|
||||
//@ check-pass
|
||||
//@ compile-flags: --crate-type=lib
|
||||
#![no_std]
|
||||
#![allow(internal_features)]
|
||||
#![feature(rustc_attrs, min_specialization, const_trait_impl)]
|
||||
|
||||
// In the default impl below, `A` is constrained by the projection predicate, and if the host effect
|
||||
// predicate for `const Foo` doesn't resolve vars, then specialization will fail.
|
||||
|
||||
#[const_trait]
|
||||
trait Foo {}
|
||||
|
||||
pub trait Iterator {
|
||||
type Item;
|
||||
}
|
||||
|
||||
#[rustc_unsafe_specialization_marker]
|
||||
pub trait MoreSpecificThanIterator: Iterator {}
|
||||
|
||||
pub trait Tr {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
impl<A: const Foo, Iter> Tr for Iter
|
||||
where
|
||||
Iter: Iterator<Item = A>,
|
||||
{
|
||||
default fn foo() {}
|
||||
}
|
||||
|
||||
impl<A: const Foo, Iter> Tr for Iter
|
||||
where
|
||||
Iter: MoreSpecificThanIterator<Item = A>,
|
||||
{
|
||||
fn foo() {}
|
||||
}
|
13
tests/ui/traits/const-traits/variance.rs
Normal file
13
tests/ui/traits/const-traits/variance.rs
Normal file
@ -0,0 +1,13 @@
|
||||
#![feature(rustc_attrs, const_trait_impl)]
|
||||
#![allow(internal_features)]
|
||||
#![rustc_variance_of_opaques]
|
||||
|
||||
#[const_trait]
|
||||
trait Foo {}
|
||||
|
||||
impl const Foo for () {}
|
||||
|
||||
fn foo<'a: 'a>() -> impl const Foo {}
|
||||
//~^ ERROR ['a: *]
|
||||
|
||||
fn main() {}
|
8
tests/ui/traits/const-traits/variance.stderr
Normal file
8
tests/ui/traits/const-traits/variance.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: ['a: *]
|
||||
--> $DIR/variance.rs:10:21
|
||||
|
|
||||
LL | fn foo<'a: 'a>() -> impl const Foo {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
Loading…
Reference in New Issue
Block a user