Auto merge of #134201 - matthiaskrgr:rollup-22b721y, r=matthiaskrgr
Rollup of 11 pull requests Successful merges: - #122003 (link libunwind dynamically and allow controlling it via `crt-static` on gnullvm targets) - #133859 (Move some alloc tests to the alloctests crate) - #134070 (Some asm! diagnostic adjustments and a papercut fix) - #134144 (Properly consider APITs for never type fallback ascription fix) - #134152 (Simplify `rustc_mir_dataflow::abs_domain`.) - #134154 (suppress field expr with generics error message if it's a method) - #134155 (Forbid `unsafe_op_in_unsafe_fn` for Hurd) - #134173 (allow `symbol_intern_string_literal` lint in test modules) - #134178 (Stabilize the Rust 2024 prelude) - #134179 (Remove outdated consteval note from `<*mut T>::align_offset` docs.) - #134187 (Remove `PErr`.) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4606a4d6fa
49 changed files with 475 additions and 190 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
|
|
||||||
use rustc_span::create_default_session_globals_then;
|
use rustc_span::create_default_session_globals_then;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -94,8 +94,7 @@ mod styled_buffer;
|
||||||
mod tests;
|
mod tests;
|
||||||
pub mod translation;
|
pub mod translation;
|
||||||
|
|
||||||
pub type PErr<'a> = Diag<'a>;
|
pub type PResult<'a, T> = Result<T, Diag<'a>>;
|
||||||
pub type PResult<'a, T> = Result<T, PErr<'a>>;
|
|
||||||
|
|
||||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||||
|
|
||||||
|
@ -576,6 +575,10 @@ pub enum StashKey {
|
||||||
UndeterminedMacroResolution,
|
UndeterminedMacroResolution,
|
||||||
/// Used by `Parser::maybe_recover_trailing_expr`
|
/// Used by `Parser::maybe_recover_trailing_expr`
|
||||||
ExprInPat,
|
ExprInPat,
|
||||||
|
/// If in the parser we detect a field expr with turbofish generic params it's possible that
|
||||||
|
/// it's a method call without parens. If later on in `hir_typeck` we find out that this is
|
||||||
|
/// the case we suppress this message and we give a better suggestion.
|
||||||
|
GenericInFieldExpr,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
|
fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
|
|
||||||
use rustc_data_structures::stable_hasher::Hash64;
|
use rustc_data_structures::stable_hasher::Hash64;
|
||||||
use rustc_span::def_id::{DefPathHash, StableCrateId};
|
use rustc_span::def_id::{DefPathHash, StableCrateId};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::assert_matches::debug_assert_matches;
|
||||||
use rustc_abi::FieldIdx;
|
use rustc_abi::FieldIdx;
|
||||||
use rustc_ast::InlineAsmTemplatePiece;
|
use rustc_ast::InlineAsmTemplatePiece;
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{self as hir, LangItem};
|
use rustc_hir::{self as hir, LangItem};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
|
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
|
||||||
|
@ -21,6 +22,12 @@ pub struct InlineAsmCtxt<'a, 'tcx> {
|
||||||
get_operand_ty: Box<dyn Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
|
get_operand_ty: Box<dyn Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum NonAsmTypeReason<'tcx> {
|
||||||
|
UnevaluatedSIMDArrayLength(DefId, ty::Const<'tcx>),
|
||||||
|
Invalid(Ty<'tcx>),
|
||||||
|
InvalidElement(DefId, Ty<'tcx>),
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||||
pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
|
pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
|
||||||
InlineAsmCtxt {
|
InlineAsmCtxt {
|
||||||
|
@ -56,7 +63,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_asm_ty(&self, ty: Ty<'tcx>) -> Option<InlineAsmType> {
|
fn get_asm_ty(&self, ty: Ty<'tcx>) -> Result<InlineAsmType, NonAsmTypeReason<'tcx>> {
|
||||||
let asm_ty_isize = match self.tcx.sess.target.pointer_width {
|
let asm_ty_isize = match self.tcx.sess.target.pointer_width {
|
||||||
16 => InlineAsmType::I16,
|
16 => InlineAsmType::I16,
|
||||||
32 => InlineAsmType::I32,
|
32 => InlineAsmType::I32,
|
||||||
|
@ -65,64 +72,62 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
|
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Ok(InlineAsmType::I8),
|
||||||
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16),
|
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Ok(InlineAsmType::I16),
|
||||||
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
|
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Ok(InlineAsmType::I32),
|
||||||
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Some(InlineAsmType::I64),
|
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Ok(InlineAsmType::I64),
|
||||||
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Some(InlineAsmType::I128),
|
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Ok(InlineAsmType::I128),
|
||||||
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(asm_ty_isize),
|
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Ok(asm_ty_isize),
|
||||||
ty::Float(FloatTy::F16) => Some(InlineAsmType::F16),
|
ty::Float(FloatTy::F16) => Ok(InlineAsmType::F16),
|
||||||
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
|
ty::Float(FloatTy::F32) => Ok(InlineAsmType::F32),
|
||||||
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
|
ty::Float(FloatTy::F64) => Ok(InlineAsmType::F64),
|
||||||
ty::Float(FloatTy::F128) => Some(InlineAsmType::F128),
|
ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128),
|
||||||
ty::FnPtr(..) => Some(asm_ty_isize),
|
ty::FnPtr(..) => Ok(asm_ty_isize),
|
||||||
ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Some(asm_ty_isize),
|
ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Ok(asm_ty_isize),
|
||||||
ty::Adt(adt, args) if adt.repr().simd() => {
|
ty::Adt(adt, args) if adt.repr().simd() => {
|
||||||
let fields = &adt.non_enum_variant().fields;
|
let fields = &adt.non_enum_variant().fields;
|
||||||
let elem_ty = fields[FieldIdx::ZERO].ty(self.tcx, args);
|
let field = &fields[FieldIdx::ZERO];
|
||||||
|
let elem_ty = field.ty(self.tcx, args);
|
||||||
|
|
||||||
let (size, ty) = match elem_ty.kind() {
|
let (size, ty) = match elem_ty.kind() {
|
||||||
ty::Array(ty, len) => {
|
ty::Array(ty, len) => {
|
||||||
|
let len = self.tcx.normalize_erasing_regions(self.typing_env, *len);
|
||||||
if let Some(len) = len.try_to_target_usize(self.tcx) {
|
if let Some(len) = len.try_to_target_usize(self.tcx) {
|
||||||
(len, *ty)
|
(len, *ty)
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return Err(NonAsmTypeReason::UnevaluatedSIMDArrayLength(
|
||||||
|
field.did, len,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (fields.len() as u64, elem_ty),
|
_ => (fields.len() as u64, elem_ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::VecI8(size)),
|
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Ok(InlineAsmType::VecI8(size)),
|
||||||
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => {
|
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Ok(InlineAsmType::VecI16(size)),
|
||||||
Some(InlineAsmType::VecI16(size))
|
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Ok(InlineAsmType::VecI32(size)),
|
||||||
}
|
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Ok(InlineAsmType::VecI64(size)),
|
||||||
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => {
|
|
||||||
Some(InlineAsmType::VecI32(size))
|
|
||||||
}
|
|
||||||
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => {
|
|
||||||
Some(InlineAsmType::VecI64(size))
|
|
||||||
}
|
|
||||||
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => {
|
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => {
|
||||||
Some(InlineAsmType::VecI128(size))
|
Ok(InlineAsmType::VecI128(size))
|
||||||
}
|
}
|
||||||
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => {
|
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => {
|
||||||
Some(match self.tcx.sess.target.pointer_width {
|
Ok(match self.tcx.sess.target.pointer_width {
|
||||||
16 => InlineAsmType::VecI16(size),
|
16 => InlineAsmType::VecI16(size),
|
||||||
32 => InlineAsmType::VecI32(size),
|
32 => InlineAsmType::VecI32(size),
|
||||||
64 => InlineAsmType::VecI64(size),
|
64 => InlineAsmType::VecI64(size),
|
||||||
width => bug!("unsupported pointer width: {width}"),
|
width => bug!("unsupported pointer width: {width}"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ty::Float(FloatTy::F16) => Some(InlineAsmType::VecF16(size)),
|
ty::Float(FloatTy::F16) => Ok(InlineAsmType::VecF16(size)),
|
||||||
ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)),
|
ty::Float(FloatTy::F32) => Ok(InlineAsmType::VecF32(size)),
|
||||||
ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(size)),
|
ty::Float(FloatTy::F64) => Ok(InlineAsmType::VecF64(size)),
|
||||||
ty::Float(FloatTy::F128) => Some(InlineAsmType::VecF128(size)),
|
ty::Float(FloatTy::F128) => Ok(InlineAsmType::VecF128(size)),
|
||||||
_ => None,
|
_ => Err(NonAsmTypeReason::InvalidElement(field.did, ty)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Infer(_) => bug!("unexpected infer ty in asm operand"),
|
ty::Infer(_) => bug!("unexpected infer ty in asm operand"),
|
||||||
_ => None,
|
_ => Err(NonAsmTypeReason::Invalid(ty)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,17 +168,42 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => self.get_asm_ty(ty),
|
_ => self.get_asm_ty(ty),
|
||||||
};
|
};
|
||||||
let Some(asm_ty) = asm_ty else {
|
let asm_ty = match asm_ty {
|
||||||
let msg = format!("cannot use value of type `{ty}` for inline assembly");
|
Ok(asm_ty) => asm_ty,
|
||||||
self.tcx
|
Err(reason) => {
|
||||||
.dcx()
|
match reason {
|
||||||
.struct_span_err(expr.span, msg)
|
NonAsmTypeReason::UnevaluatedSIMDArrayLength(did, len) => {
|
||||||
.with_note(
|
let msg = format!("cannot evaluate SIMD vector length `{len}`");
|
||||||
"only integers, floats, SIMD vectors, pointers and function pointers \
|
self.tcx
|
||||||
can be used as arguments for inline assembly",
|
.dcx()
|
||||||
)
|
.struct_span_err(self.tcx.def_span(did), msg)
|
||||||
.emit();
|
.with_span_note(
|
||||||
return None;
|
expr.span,
|
||||||
|
"SIMD vector length needs to be known statically for use in `asm!`",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
NonAsmTypeReason::Invalid(ty) => {
|
||||||
|
let msg = format!("cannot use value of type `{ty}` for inline assembly");
|
||||||
|
self.tcx.dcx().struct_span_err(expr.span, msg).with_note(
|
||||||
|
"only integers, floats, SIMD vectors, pointers and function pointers \
|
||||||
|
can be used as arguments for inline assembly",
|
||||||
|
).emit();
|
||||||
|
}
|
||||||
|
NonAsmTypeReason::InvalidElement(did, ty) => {
|
||||||
|
let msg = format!(
|
||||||
|
"cannot use SIMD vector with element type `{ty}` for inline assembly"
|
||||||
|
);
|
||||||
|
self.tcx.dcx()
|
||||||
|
.struct_span_err(self.tcx.def_span(did), msg).with_span_note(
|
||||||
|
expr.span,
|
||||||
|
"only integers, floats, SIMD vectors, pointers and function pointers \
|
||||||
|
can be used as arguments for inline assembly",
|
||||||
|
).emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check that the type implements Copy. The only case where this can
|
// Check that the type implements Copy. The only case where this can
|
||||||
|
|
|
@ -3076,7 +3076,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
err.help("methods are immutable and cannot be assigned to");
|
err.help("methods are immutable and cannot be assigned to");
|
||||||
}
|
}
|
||||||
|
|
||||||
err.emit()
|
// See `StashKey::GenericInFieldExpr` for more info
|
||||||
|
self.dcx().try_steal_replace_and_emit_err(field.span, StashKey::GenericInFieldExpr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn point_at_param_definition(&self, err: &mut Diag<'_>, param: ty::ParamTy) {
|
fn point_at_param_definition(&self, err: &mut Diag<'_>, param: ty::ParamTy) {
|
||||||
|
|
|
@ -613,19 +613,16 @@ impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
|
||||||
if arg_segment.args.is_none()
|
if arg_segment.args.is_none()
|
||||||
&& let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id)
|
&& let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id)
|
||||||
&& let generics = self.fcx.tcx.generics_of(def_id)
|
&& let generics = self.fcx.tcx.generics_of(def_id)
|
||||||
&& let args = &all_args[generics.parent_count..]
|
&& let args = all_args[generics.parent_count..].iter().zip(&generics.own_params)
|
||||||
// We can't turbofish consts :(
|
// We can't turbofish consts :(
|
||||||
&& args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_)))
|
&& args.clone().all(|(_, param)| matches!(param.kind, ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Lifetime))
|
||||||
{
|
{
|
||||||
let n_tys = args
|
// We filter out APITs, which are not turbofished.
|
||||||
.iter()
|
let non_apit_type_args = args.filter(|(_, param)| {
|
||||||
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
|
matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: false, .. })
|
||||||
.count();
|
});
|
||||||
for (idx, arg) in args
|
let n_tys = non_apit_type_args.clone().count();
|
||||||
.iter()
|
for (idx, (arg, _)) in non_apit_type_args.enumerate() {
|
||||||
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
|
|
||||||
.enumerate()
|
|
||||||
{
|
|
||||||
if let Some(ty) = arg.as_type()
|
if let Some(ty) = arg.as_type()
|
||||||
&& let Some(vid) = self.fcx.root_vid(ty)
|
&& let Some(vid) = self.fcx.root_vid(ty)
|
||||||
&& self.reachable_vids.contains(&vid)
|
&& self.reachable_vids.contains(&vid)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
|
|
||||||
use rustc_span::{Symbol, create_default_session_globals_then};
|
use rustc_span::{Symbol, create_default_session_globals_then};
|
||||||
|
|
||||||
use crate::levels::parse_lint_and_tool_name;
|
use crate::levels::parse_lint_and_tool_name;
|
||||||
|
|
|
@ -4,52 +4,26 @@
|
||||||
//! field-deref on a local variable, `x.field`, has the same meaning
|
//! field-deref on a local variable, `x.field`, has the same meaning
|
||||||
//! in both domains). Indexed projections are the exception: `a[x]`
|
//! in both domains). Indexed projections are the exception: `a[x]`
|
||||||
//! needs to be treated as mapping to the same move path as `a[y]` as
|
//! needs to be treated as mapping to the same move path as `a[y]` as
|
||||||
//! well as `a[13]`, etc.
|
//! well as `a[13]`, etc. So we map these `x`/`y` values to `()`.
|
||||||
//!
|
//!
|
||||||
//! (In theory, the analysis could be extended to work with sets of
|
//! (In theory, the analysis could be extended to work with sets of
|
||||||
//! paths, so that `a[0]` and `a[13]` could be kept distinct, while
|
//! paths, so that `a[0]` and `a[13]` could be kept distinct, while
|
||||||
//! `a[x]` would still overlap them both. But that is not this
|
//! `a[x]` would still overlap them both. But that is not this
|
||||||
//! representation does today.)
|
//! representation does today.)
|
||||||
|
|
||||||
use rustc_middle::mir::{Local, Operand, PlaceElem, ProjectionElem};
|
use rustc_middle::mir::{PlaceElem, ProjectionElem, ProjectionKind};
|
||||||
use rustc_middle::ty::Ty;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
|
||||||
pub(crate) struct AbstractOperand;
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
|
||||||
pub(crate) struct AbstractType;
|
|
||||||
pub(crate) type AbstractElem = ProjectionElem<AbstractOperand, AbstractType>;
|
|
||||||
|
|
||||||
pub(crate) trait Lift {
|
pub(crate) trait Lift {
|
||||||
type Abstract;
|
fn lift(&self) -> ProjectionKind;
|
||||||
fn lift(&self) -> Self::Abstract;
|
|
||||||
}
|
|
||||||
impl<'tcx> Lift for Operand<'tcx> {
|
|
||||||
type Abstract = AbstractOperand;
|
|
||||||
fn lift(&self) -> Self::Abstract {
|
|
||||||
AbstractOperand
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Lift for Local {
|
|
||||||
type Abstract = AbstractOperand;
|
|
||||||
fn lift(&self) -> Self::Abstract {
|
|
||||||
AbstractOperand
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'tcx> Lift for Ty<'tcx> {
|
|
||||||
type Abstract = AbstractType;
|
|
||||||
fn lift(&self) -> Self::Abstract {
|
|
||||||
AbstractType
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Lift for PlaceElem<'tcx> {
|
impl<'tcx> Lift for PlaceElem<'tcx> {
|
||||||
type Abstract = AbstractElem;
|
fn lift(&self) -> ProjectionKind {
|
||||||
fn lift(&self) -> Self::Abstract {
|
|
||||||
match *self {
|
match *self {
|
||||||
ProjectionElem::Deref => ProjectionElem::Deref,
|
ProjectionElem::Deref => ProjectionElem::Deref,
|
||||||
ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty.lift()),
|
ProjectionElem::Field(f, _ty) => ProjectionElem::Field(f, ()),
|
||||||
ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty.lift()),
|
ProjectionElem::OpaqueCast(_ty) => ProjectionElem::OpaqueCast(()),
|
||||||
ProjectionElem::Index(ref i) => ProjectionElem::Index(i.lift()),
|
ProjectionElem::Index(_i) => ProjectionElem::Index(()),
|
||||||
ProjectionElem::Subslice { from, to, from_end } => {
|
ProjectionElem::Subslice { from, to, from_end } => {
|
||||||
ProjectionElem::Subslice { from, to, from_end }
|
ProjectionElem::Subslice { from, to, from_end }
|
||||||
}
|
}
|
||||||
|
@ -57,7 +31,7 @@ impl<'tcx> Lift for PlaceElem<'tcx> {
|
||||||
ProjectionElem::ConstantIndex { offset, min_length, from_end }
|
ProjectionElem::ConstantIndex { offset, min_length, from_end }
|
||||||
}
|
}
|
||||||
ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u),
|
ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u),
|
||||||
ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty.lift()),
|
ProjectionElem::Subtype(_ty) => ProjectionElem::Subtype(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use rustc_middle::ty::{Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use self::abs_domain::{AbstractElem, Lift};
|
use self::abs_domain::Lift;
|
||||||
use crate::un_derefer::UnDerefer;
|
use crate::un_derefer::UnDerefer;
|
||||||
|
|
||||||
mod abs_domain;
|
mod abs_domain;
|
||||||
|
@ -300,7 +300,7 @@ pub struct MovePathLookup<'tcx> {
|
||||||
/// subsequent search so that it is solely relative to that
|
/// subsequent search so that it is solely relative to that
|
||||||
/// base-place). For the remaining lookup, we map the projection
|
/// base-place). For the remaining lookup, we map the projection
|
||||||
/// elem to the associated MovePathIndex.
|
/// elem to the associated MovePathIndex.
|
||||||
projections: FxHashMap<(MovePathIndex, AbstractElem), MovePathIndex>,
|
projections: FxHashMap<(MovePathIndex, ProjectionKind), MovePathIndex>,
|
||||||
|
|
||||||
un_derefer: UnDerefer<'tcx>,
|
un_derefer: UnDerefer<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rustc_ast::token::{self, Delimiter, Token};
|
use rustc_ast::token::{self, Delimiter, Token};
|
||||||
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
|
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
|
||||||
use rustc_ast_pretty::pprust::token_to_string;
|
use rustc_ast_pretty::pprust::token_to_string;
|
||||||
use rustc_errors::{Applicability, PErr};
|
use rustc_errors::{Applicability, Diag};
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
|
|
||||||
use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level};
|
use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level};
|
||||||
|
@ -14,7 +14,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
||||||
pub(super) fn lex_token_trees(
|
pub(super) fn lex_token_trees(
|
||||||
&mut self,
|
&mut self,
|
||||||
is_delimited: bool,
|
is_delimited: bool,
|
||||||
) -> (Spacing, TokenStream, Result<(), Vec<PErr<'psess>>>) {
|
) -> (Spacing, TokenStream, Result<(), Vec<Diag<'psess>>>) {
|
||||||
// Move past the opening delimiter.
|
// Move past the opening delimiter.
|
||||||
let open_spacing = self.bump_minimal();
|
let open_spacing = self.bump_minimal();
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eof_err(&mut self) -> PErr<'psess> {
|
fn eof_err(&mut self) -> Diag<'psess> {
|
||||||
let msg = "this file contains an unclosed delimiter";
|
let msg = "this file contains an unclosed delimiter";
|
||||||
let mut err = self.dcx().struct_span_err(self.token.span, msg);
|
let mut err = self.dcx().struct_span_err(self.token.span, msg);
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
||||||
fn lex_token_tree_open_delim(
|
fn lex_token_tree_open_delim(
|
||||||
&mut self,
|
&mut self,
|
||||||
open_delim: Delimiter,
|
open_delim: Delimiter,
|
||||||
) -> Result<TokenTree, Vec<PErr<'psess>>> {
|
) -> Result<TokenTree, Vec<Diag<'psess>>> {
|
||||||
// The span for beginning of the delimited section.
|
// The span for beginning of the delimited section.
|
||||||
let pre_span = self.token.span;
|
let pre_span = self.token.span;
|
||||||
|
|
||||||
|
@ -250,8 +250,8 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
||||||
fn unclosed_delim_err(
|
fn unclosed_delim_err(
|
||||||
&mut self,
|
&mut self,
|
||||||
tts: TokenStream,
|
tts: TokenStream,
|
||||||
mut errs: Vec<PErr<'psess>>,
|
mut errs: Vec<Diag<'psess>>,
|
||||||
) -> Vec<PErr<'psess>> {
|
) -> Vec<Diag<'psess>> {
|
||||||
// If there are unclosed delims, see if there are diff markers and if so, point them
|
// If there are unclosed delims, see if there are diff markers and if so, point them
|
||||||
// out instead of complaining about the unclosed delims.
|
// out instead of complaining about the unclosed delims.
|
||||||
let mut parser = Parser::new(self.psess, tts, None);
|
let mut parser = Parser::new(self.psess, tts, None);
|
||||||
|
@ -308,7 +308,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
||||||
errs
|
errs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'psess> {
|
fn close_delim_err(&mut self, delim: Delimiter) -> Diag<'psess> {
|
||||||
// An unexpected closing delimiter (i.e., there is no matching opening delimiter).
|
// An unexpected closing delimiter (i.e., there is no matching opening delimiter).
|
||||||
let token_str = token_to_string(&self.token);
|
let token_str = token_to_string(&self.token);
|
||||||
let msg = format!("unexpected closing delimiter: `{token_str}`");
|
let msg = format!("unexpected closing delimiter: `{token_str}`");
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PErr, PResult, Subdiagnostic,
|
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PResult, Subdiagnostic,
|
||||||
Suggestions, pluralize,
|
Suggestions, pluralize,
|
||||||
};
|
};
|
||||||
use rustc_session::errors::ExprParenthesesNeeded;
|
use rustc_session::errors::ExprParenthesesNeeded;
|
||||||
|
@ -2132,7 +2132,7 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
delim: Delimiter,
|
delim: Delimiter,
|
||||||
lo: Span,
|
lo: Span,
|
||||||
err: PErr<'a>,
|
err: Diag<'a>,
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
let guar = err.emit();
|
let guar = err.emit();
|
||||||
// Recover from parse error, callers expect the closing delim to be consumed.
|
// Recover from parse error, callers expect the closing delim to be consumed.
|
||||||
|
@ -3014,7 +3014,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check for exclusive ranges written as `..<`
|
/// Check for exclusive ranges written as `..<`
|
||||||
pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: PErr<'a>) -> PErr<'a> {
|
pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: Diag<'a>) -> Diag<'a> {
|
||||||
if maybe_lt == token::Lt
|
if maybe_lt == token::Lt
|
||||||
&& (self.expected_tokens.contains(&TokenType::Token(token::Gt))
|
&& (self.expected_tokens.contains(&TokenType::Token(token::Gt))
|
||||||
|| matches!(self.token.kind, token::Literal(..)))
|
|| matches!(self.token.kind, token::Literal(..)))
|
||||||
|
|
|
@ -1369,11 +1369,14 @@ impl<'a> Parser<'a> {
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
// Field access `expr.f`
|
// Field access `expr.f`
|
||||||
|
let span = lo.to(self.prev_token.span);
|
||||||
if let Some(args) = seg.args {
|
if let Some(args) = seg.args {
|
||||||
self.dcx().emit_err(errors::FieldExpressionWithGeneric(args.span()));
|
// See `StashKey::GenericInFieldExpr` for more info on why we stash this.
|
||||||
|
self.dcx()
|
||||||
|
.create_err(errors::FieldExpressionWithGeneric(args.span()))
|
||||||
|
.stash(seg.ident.span, StashKey::GenericInFieldExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = lo.to(self.prev_token.span);
|
|
||||||
Ok(self.mk_expr(span, ExprKind::Field(self_arg, seg.ident)))
|
Ok(self.mk_expr(span, ExprKind::Field(self_arg, seg.ident)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
|
|
||||||
use std::assert_matches::assert_matches;
|
use std::assert_matches::assert_matches;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
|
|
||||||
use rustc_ast::token::{self, IdentIsRaw};
|
use rustc_ast::token::{self, IdentIsRaw};
|
||||||
use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
||||||
use rustc_span::{BytePos, Span, Symbol, create_default_session_globals_then};
|
use rustc_span::{BytePos, Span, Symbol, create_default_session_globals_then};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -42,6 +42,8 @@ pub(crate) fn opts() -> TargetOptions {
|
||||||
eh_frame_header: false,
|
eh_frame_header: false,
|
||||||
no_default_libraries: false,
|
no_default_libraries: false,
|
||||||
has_thread_local: true,
|
has_thread_local: true,
|
||||||
|
crt_static_allows_dylibs: true,
|
||||||
|
crt_static_respected: true,
|
||||||
// FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
|
// FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
|
||||||
// output DWO, despite using DWARF, doesn't use ELF..
|
// output DWO, despite using DWARF, doesn't use ELF..
|
||||||
debuginfo_kind: DebuginfoKind::Pdb,
|
debuginfo_kind: DebuginfoKind::Pdb,
|
||||||
|
|
|
@ -10,9 +10,6 @@ use core::hint;
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use core::ptr::{self, NonNull};
|
use core::ptr::{self, NonNull};
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
// These are the magic symbols to call the global allocator. rustc generates
|
// These are the magic symbols to call the global allocator. rustc generates
|
||||||
// them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute
|
// them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute
|
||||||
|
|
|
@ -155,9 +155,6 @@ use crate::collections::TryReserveError;
|
||||||
use crate::slice;
|
use crate::slice;
|
||||||
use crate::vec::{self, AsVecIntoIter, Vec};
|
use crate::vec::{self, AsVecIntoIter, Vec};
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
/// A priority queue implemented with a binary heap.
|
/// A priority queue implemented with a binary heap.
|
||||||
///
|
///
|
||||||
/// This will be a max-heap.
|
/// This will be a max-heap.
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
//! [`CString`] and its related types.
|
//! [`CString`] and its related types.
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use core::ffi::{CStr, c_char};
|
use core::ffi::{CStr, c_char};
|
||||||
use core::num::NonZero;
|
use core::num::NonZero;
|
||||||
|
|
|
@ -239,8 +239,6 @@ pub mod string;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
#[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync)))]
|
#[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync)))]
|
||||||
pub mod task;
|
pub mod task;
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
pub mod vec;
|
pub mod vec;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
|
@ -39,9 +39,6 @@ use crate::string::String;
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use crate::vec::Vec;
|
use crate::vec::Vec;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
/// A soft limit on the amount of references that may be made to an `Arc`.
|
/// A soft limit on the amount of references that may be made to an `Arc`.
|
||||||
///
|
///
|
||||||
/// Going above this limit will abort your program (although not
|
/// Going above this limit will abort your program (although not
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use super::*;
|
use alloc::alloc::*;
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
use crate::boxed::Box;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn allocate_zeroed() {
|
fn allocate_zeroed() {
|
||||||
unsafe {
|
unsafe {
|
|
@ -1,11 +1,12 @@
|
||||||
|
use alloc::ffi::CString;
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
use alloc::sync::Arc;
|
||||||
use core::assert_matches::assert_matches;
|
use core::assert_matches::assert_matches;
|
||||||
use core::ffi::FromBytesUntilNulError;
|
use core::ffi::{CStr, FromBytesUntilNulError, c_char};
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
use core::hash::SipHasher13 as DefaultHasher;
|
use core::hash::SipHasher13 as DefaultHasher;
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn c_to_rust() {
|
fn c_to_rust() {
|
||||||
let data = b"123\0";
|
let data = b"123\0";
|
|
@ -1,7 +1,9 @@
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::collections::binary_heap::*;
|
||||||
|
use std::iter::TrustedLen;
|
||||||
|
use std::mem;
|
||||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||||
|
|
||||||
use super::*;
|
|
||||||
use crate::boxed::Box;
|
|
||||||
use crate::testing::crash_test::{CrashTestDummy, Panic};
|
use crate::testing::crash_test::{CrashTestDummy, Panic};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -531,7 +533,7 @@ fn panic_safe() {
|
||||||
self.0.partial_cmp(&other.0)
|
self.0.partial_cmp(&other.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut rng = crate::test_helpers::test_rng();
|
let mut rng = crate::test_rng();
|
||||||
const DATASZ: usize = 32;
|
const DATASZ: usize = 32;
|
||||||
// Miri is too slow
|
// Miri is too slow
|
||||||
let ntest = if cfg!(miri) { 1 } else { 10 };
|
let ntest = if cfg!(miri) { 1 } else { 10 };
|
1
library/alloc/tests/collections/mod.rs
Normal file
1
library/alloc/tests/collections/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
mod binary_heap;
|
|
@ -5,8 +5,10 @@
|
||||||
#![feature(btree_extract_if)]
|
#![feature(btree_extract_if)]
|
||||||
#![feature(cow_is_borrowed)]
|
#![feature(cow_is_borrowed)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(downcast_unchecked)]
|
||||||
#![feature(extract_if)]
|
#![feature(extract_if)]
|
||||||
#![feature(exact_size_is_empty)]
|
#![feature(exact_size_is_empty)]
|
||||||
|
#![feature(hashmap_internals)]
|
||||||
#![feature(linked_list_cursors)]
|
#![feature(linked_list_cursors)]
|
||||||
#![feature(map_try_insert)]
|
#![feature(map_try_insert)]
|
||||||
#![feature(pattern)]
|
#![feature(pattern)]
|
||||||
|
@ -29,9 +31,11 @@
|
||||||
#![feature(const_str_from_utf8)]
|
#![feature(const_str_from_utf8)]
|
||||||
#![feature(panic_update_hook)]
|
#![feature(panic_update_hook)]
|
||||||
#![feature(pointer_is_aligned_to)]
|
#![feature(pointer_is_aligned_to)]
|
||||||
|
#![feature(test)]
|
||||||
#![feature(thin_box)]
|
#![feature(thin_box)]
|
||||||
#![feature(drain_keep_rest)]
|
#![feature(drain_keep_rest)]
|
||||||
#![feature(local_waker)]
|
#![feature(local_waker)]
|
||||||
|
#![feature(str_as_str)]
|
||||||
#![feature(strict_provenance_lints)]
|
#![feature(strict_provenance_lints)]
|
||||||
#![feature(vec_pop_if)]
|
#![feature(vec_pop_if)]
|
||||||
#![feature(unique_rc_arc)]
|
#![feature(unique_rc_arc)]
|
||||||
|
@ -40,25 +44,33 @@
|
||||||
#![deny(fuzzy_provenance_casts)]
|
#![deny(fuzzy_provenance_casts)]
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
use std::hash::{DefaultHasher, Hash, Hasher};
|
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
|
|
||||||
|
mod alloc;
|
||||||
mod arc;
|
mod arc;
|
||||||
mod autotraits;
|
mod autotraits;
|
||||||
mod borrow;
|
mod borrow;
|
||||||
mod boxed;
|
mod boxed;
|
||||||
mod btree_set_hash;
|
mod btree_set_hash;
|
||||||
mod c_str;
|
mod c_str;
|
||||||
|
mod c_str2;
|
||||||
|
mod collections;
|
||||||
mod const_fns;
|
mod const_fns;
|
||||||
mod cow_str;
|
mod cow_str;
|
||||||
mod fmt;
|
mod fmt;
|
||||||
mod heap;
|
mod heap;
|
||||||
mod linked_list;
|
mod linked_list;
|
||||||
|
mod misc_tests;
|
||||||
mod rc;
|
mod rc;
|
||||||
mod slice;
|
mod slice;
|
||||||
mod sort;
|
mod sort;
|
||||||
mod str;
|
mod str;
|
||||||
mod string;
|
mod string;
|
||||||
|
mod sync;
|
||||||
mod task;
|
mod task;
|
||||||
|
mod testing;
|
||||||
mod thin_box;
|
mod thin_box;
|
||||||
mod vec;
|
mod vec;
|
||||||
mod vec_deque;
|
mod vec_deque;
|
||||||
|
@ -69,6 +81,18 @@ fn hash<T: Hash>(t: &T) -> u64 {
|
||||||
s.finish()
|
s.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
|
||||||
|
/// seed not being the same for every RNG invocation too.
|
||||||
|
fn test_rng() -> rand_xorshift::XorShiftRng {
|
||||||
|
use std::hash::{BuildHasher, Hash, Hasher};
|
||||||
|
let mut hasher = std::hash::RandomState::new().build_hasher();
|
||||||
|
std::panic::Location::caller().hash(&mut hasher);
|
||||||
|
let hc64 = hasher.finish();
|
||||||
|
let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
|
||||||
|
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
|
||||||
|
rand::SeedableRng::from_seed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten.
|
// FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten.
|
||||||
// See https://github.com/kripken/emscripten-fastcomp/issues/169
|
// See https://github.com/kripken/emscripten-fastcomp/issues/169
|
||||||
#[cfg(not(target_os = "emscripten"))]
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
|
use alloc::sync::*;
|
||||||
|
use std::alloc::{AllocError, Allocator, Layout};
|
||||||
|
use std::any::Any;
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::option::Option::None;
|
use std::option::Option::None;
|
||||||
|
use std::ptr::NonNull;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::Ordering::*;
|
||||||
use std::sync::atomic::Ordering::SeqCst;
|
use std::sync::atomic::{self, AtomicUsize};
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
struct Canary(*mut AtomicUsize);
|
struct Canary(*mut AtomicUsize);
|
||||||
|
|
||||||
impl Drop for Canary {
|
impl Drop for Canary {
|
80
library/alloc/tests/testing/crash_test.rs
Normal file
80
library/alloc/tests/testing/crash_test.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
use std::sync::atomic::Ordering::SeqCst;
|
||||||
|
|
||||||
|
/// A blueprint for crash test dummy instances that monitor drops.
|
||||||
|
/// Some instances may be configured to panic at some point.
|
||||||
|
///
|
||||||
|
/// Crash test dummies are identified and ordered by an id, so they can be used
|
||||||
|
/// as keys in a BTreeMap.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CrashTestDummy {
|
||||||
|
pub id: usize,
|
||||||
|
dropped: AtomicUsize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CrashTestDummy {
|
||||||
|
/// Creates a crash test dummy design. The `id` determines order and equality of instances.
|
||||||
|
pub fn new(id: usize) -> CrashTestDummy {
|
||||||
|
CrashTestDummy { id, dropped: AtomicUsize::new(0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates an instance of a crash test dummy that records what events it experiences
|
||||||
|
/// and optionally panics.
|
||||||
|
pub fn spawn(&self, panic: Panic) -> Instance<'_> {
|
||||||
|
Instance { origin: self, panic }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns how many times instances of the dummy have been dropped.
|
||||||
|
pub fn dropped(&self) -> usize {
|
||||||
|
self.dropped.load(SeqCst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Instance<'a> {
|
||||||
|
origin: &'a CrashTestDummy,
|
||||||
|
panic: Panic,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum Panic {
|
||||||
|
Never,
|
||||||
|
InDrop,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Instance<'_> {
|
||||||
|
pub fn id(&self) -> usize {
|
||||||
|
self.origin.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Instance<'_> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.origin.dropped.fetch_add(1, SeqCst);
|
||||||
|
if self.panic == Panic::InDrop {
|
||||||
|
panic!("panic in `drop`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Instance<'_> {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
self.id().partial_cmp(&other.id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Instance<'_> {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.id().cmp(&other.id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Instance<'_> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.id().eq(&other.id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for Instance<'_> {}
|
1
library/alloc/tests/testing/mod.rs
Normal file
1
library/alloc/tests/testing/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod crash_test;
|
|
@ -71,7 +71,7 @@ pub mod rust_2021 {
|
||||||
/// The 2024 version of the core prelude.
|
/// The 2024 version of the core prelude.
|
||||||
///
|
///
|
||||||
/// See the [module-level documentation](self) for more.
|
/// See the [module-level documentation](self) for more.
|
||||||
#[unstable(feature = "prelude_2024", issue = "121042")]
|
#[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub mod rust_2024 {
|
pub mod rust_2024 {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use super::common::*;
|
pub use super::common::*;
|
||||||
|
@ -84,7 +84,7 @@ pub mod rust_2024 {
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use crate::convert::{TryFrom, TryInto};
|
pub use crate::convert::{TryFrom, TryInto};
|
||||||
|
|
||||||
#[unstable(feature = "prelude_2024", issue = "121042")]
|
#[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use crate::future::{Future, IntoFuture};
|
pub use crate::future::{Future, IntoFuture};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1587,15 +1587,6 @@ impl<T: ?Sized> *mut T {
|
||||||
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
|
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
|
||||||
/// the returned offset is correct in all terms other than alignment.
|
/// the returned offset is correct in all terms other than alignment.
|
||||||
///
|
///
|
||||||
/// When this is called during compile-time evaluation (which is unstable), the implementation
|
|
||||||
/// may return `usize::MAX` in cases where that can never happen at runtime. This is because the
|
|
||||||
/// actual alignment of pointers is not known yet during compile-time, so an offset with
|
|
||||||
/// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8;
|
|
||||||
/// N]` might be allocated at an odd or an even address, but at compile-time this is not yet
|
|
||||||
/// known, so the execution has to be correct for either choice. It is therefore impossible to
|
|
||||||
/// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual
|
|
||||||
/// for unstable APIs.)
|
|
||||||
///
|
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// The function panics if `align` is not a power-of-two.
|
/// The function panics if `align` is not a power-of-two.
|
||||||
|
|
|
@ -348,7 +348,6 @@
|
||||||
#![feature(pin_coerce_unsized_trait)]
|
#![feature(pin_coerce_unsized_trait)]
|
||||||
#![feature(pointer_is_aligned_to)]
|
#![feature(pointer_is_aligned_to)]
|
||||||
#![feature(portable_simd)]
|
#![feature(portable_simd)]
|
||||||
#![feature(prelude_2024)]
|
|
||||||
#![feature(ptr_as_uninit)]
|
#![feature(ptr_as_uninit)]
|
||||||
#![feature(ptr_mask)]
|
#![feature(ptr_mask)]
|
||||||
#![feature(random)]
|
#![feature(random)]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Hurd-specific definitions
|
//! Hurd-specific definitions
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")]
|
#![stable(feature = "raw_ext", since = "1.1.0")]
|
||||||
|
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod raw;
|
pub mod raw;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
//!
|
//!
|
||||||
//! # Prelude contents
|
//! # Prelude contents
|
||||||
//!
|
//!
|
||||||
|
//! The items included in the prelude depend on the edition of the crate.
|
||||||
//! The first version of the prelude is used in Rust 2015 and Rust 2018,
|
//! The first version of the prelude is used in Rust 2015 and Rust 2018,
|
||||||
//! and lives in [`std::prelude::v1`].
|
//! and lives in [`std::prelude::v1`].
|
||||||
//! [`std::prelude::rust_2015`] and [`std::prelude::rust_2018`] re-export this prelude.
|
//! [`std::prelude::rust_2015`] and [`std::prelude::rust_2018`] re-export this prelude.
|
||||||
|
@ -67,15 +68,21 @@
|
||||||
//! The prelude used in Rust 2021, [`std::prelude::rust_2021`], includes all of the above,
|
//! The prelude used in Rust 2021, [`std::prelude::rust_2021`], includes all of the above,
|
||||||
//! and in addition re-exports:
|
//! and in addition re-exports:
|
||||||
//!
|
//!
|
||||||
//! * <code>[std::convert]::{[TryFrom], [TryInto]}</code>,
|
//! * <code>[std::convert]::{[TryFrom], [TryInto]}</code>.
|
||||||
//! * <code>[std::iter]::[FromIterator]</code>.
|
//! * <code>[std::iter]::[FromIterator]</code>.
|
||||||
//!
|
//!
|
||||||
|
//! The prelude used in Rust 2024, [`std::prelude::rust_2024`], includes all of the above,
|
||||||
|
//! and in addition re-exports:
|
||||||
|
//!
|
||||||
|
//! * <code>[std::future]::{[Future], [IntoFuture]}</code>.
|
||||||
|
//!
|
||||||
//! [std::borrow]: crate::borrow
|
//! [std::borrow]: crate::borrow
|
||||||
//! [std::boxed]: crate::boxed
|
//! [std::boxed]: crate::boxed
|
||||||
//! [std::clone]: crate::clone
|
//! [std::clone]: crate::clone
|
||||||
//! [std::cmp]: crate::cmp
|
//! [std::cmp]: crate::cmp
|
||||||
//! [std::convert]: crate::convert
|
//! [std::convert]: crate::convert
|
||||||
//! [std::default]: crate::default
|
//! [std::default]: crate::default
|
||||||
|
//! [std::future]: crate::future
|
||||||
//! [std::iter]: crate::iter
|
//! [std::iter]: crate::iter
|
||||||
//! [std::marker]: crate::marker
|
//! [std::marker]: crate::marker
|
||||||
//! [std::mem]: crate::mem
|
//! [std::mem]: crate::mem
|
||||||
|
@ -85,6 +92,7 @@
|
||||||
//! [`std::prelude::rust_2015`]: rust_2015
|
//! [`std::prelude::rust_2015`]: rust_2015
|
||||||
//! [`std::prelude::rust_2018`]: rust_2018
|
//! [`std::prelude::rust_2018`]: rust_2018
|
||||||
//! [`std::prelude::rust_2021`]: rust_2021
|
//! [`std::prelude::rust_2021`]: rust_2021
|
||||||
|
//! [`std::prelude::rust_2024`]: rust_2024
|
||||||
//! [std::result]: crate::result
|
//! [std::result]: crate::result
|
||||||
//! [std::slice]: crate::slice
|
//! [std::slice]: crate::slice
|
||||||
//! [std::string]: crate::string
|
//! [std::string]: crate::string
|
||||||
|
@ -94,6 +102,8 @@
|
||||||
//! [book-dtor]: ../../book/ch15-03-drop.html
|
//! [book-dtor]: ../../book/ch15-03-drop.html
|
||||||
//! [book-enums]: ../../book/ch06-01-defining-an-enum.html
|
//! [book-enums]: ../../book/ch06-01-defining-an-enum.html
|
||||||
//! [book-iter]: ../../book/ch13-02-iterators.html
|
//! [book-iter]: ../../book/ch13-02-iterators.html
|
||||||
|
//! [Future]: crate::future::Future
|
||||||
|
//! [IntoFuture]: crate::future::IntoFuture
|
||||||
|
|
||||||
// No formatting: this file is nothing but re-exports, and their order is worth preserving.
|
// No formatting: this file is nothing but re-exports, and their order is worth preserving.
|
||||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
#![cfg_attr(rustfmt, rustfmt::skip)]
|
||||||
|
@ -158,12 +168,12 @@ pub mod rust_2021 {
|
||||||
/// The 2024 version of the prelude of The Rust Standard Library.
|
/// The 2024 version of the prelude of The Rust Standard Library.
|
||||||
///
|
///
|
||||||
/// See the [module-level documentation](self) for more.
|
/// See the [module-level documentation](self) for more.
|
||||||
#[unstable(feature = "prelude_2024", issue = "121042")]
|
#[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub mod rust_2024 {
|
pub mod rust_2024 {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use super::common::*;
|
pub use super::common::*;
|
||||||
|
|
||||||
#[unstable(feature = "prelude_2024", issue = "121042")]
|
#[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use core::prelude::rust_2024::*;
|
pub use core::prelude::rust_2024::*;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,3 +178,8 @@ cfg_if::cfg_if! {
|
||||||
#[cfg(target_os = "hurd")]
|
#[cfg(target_os = "hurd")]
|
||||||
#[link(name = "gcc_s")]
|
#[link(name = "gcc_s")]
|
||||||
extern "C" {}
|
extern "C" {}
|
||||||
|
|
||||||
|
#[cfg(all(target_os = "windows", target_env = "gnu", target_abi = "llvm"))]
|
||||||
|
#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
|
||||||
|
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
|
||||||
|
extern "C" {}
|
||||||
|
|
|
@ -102,12 +102,9 @@ pub type _Unwind_Exception_Cleanup_Fn =
|
||||||
// rustc_codegen_ssa::src::back::symbol_export, rustc_middle::middle::exported_symbols
|
// rustc_codegen_ssa::src::back::symbol_export, rustc_middle::middle::exported_symbols
|
||||||
// and RFC 2841
|
// and RFC 2841
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
any(
|
all(
|
||||||
all(
|
feature = "llvm-libunwind",
|
||||||
feature = "llvm-libunwind",
|
any(target_os = "fuchsia", target_os = "linux", target_os = "xous")
|
||||||
any(target_os = "fuchsia", target_os = "linux", target_os = "xous")
|
|
||||||
),
|
|
||||||
all(target_os = "windows", target_env = "gnu", target_abi = "llvm")
|
|
||||||
),
|
),
|
||||||
link(name = "unwind", kind = "static", modifiers = "-bundle")
|
link(name = "unwind", kind = "static", modifiers = "-bundle")
|
||||||
)]
|
)]
|
||||||
|
|
|
@ -1035,12 +1035,7 @@ impl Builder<'_> {
|
||||||
rustflags.arg("-Wrustc::internal");
|
rustflags.arg("-Wrustc::internal");
|
||||||
// cfg(bootstrap) - remove this check when lint is in bootstrap compiler
|
// cfg(bootstrap) - remove this check when lint is in bootstrap compiler
|
||||||
if stage != 0 {
|
if stage != 0 {
|
||||||
// Lint is allow by default so downstream tools don't get a lit
|
rustflags.arg("-Drustc::symbol_intern_string_literal");
|
||||||
// they can do nothing about
|
|
||||||
// We shouldn't be preinterning symbols used by tests
|
|
||||||
if cmd_kind != Kind::Test {
|
|
||||||
rustflags.arg("-Drustc::symbol_intern_string_literal");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
|
// FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
|
||||||
// of the individual lints are satisfied.
|
// of the individual lints are satisfied.
|
||||||
|
|
21
tests/ui/asm/generic_const_simd_vec_len.rs
Normal file
21
tests/ui/asm/generic_const_simd_vec_len.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//! This is a regression test to ensure that we emit a diagnostic pointing to the
|
||||||
|
//! reason the type was rejected in inline assembly.
|
||||||
|
|
||||||
|
//@ only-x86_64
|
||||||
|
|
||||||
|
#![feature(repr_simd)]
|
||||||
|
|
||||||
|
#[repr(simd)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Foo<const C: usize>([u8; C]);
|
||||||
|
//~^ ERROR: cannot evaluate SIMD vector length
|
||||||
|
|
||||||
|
pub unsafe fn foo<const C: usize>(a: Foo<C>) {
|
||||||
|
std::arch::asm!(
|
||||||
|
"movaps {src}, {src}",
|
||||||
|
src = in(xmm_reg) a,
|
||||||
|
//~^ NOTE: SIMD vector length needs to be known statically
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
tests/ui/asm/generic_const_simd_vec_len.stderr
Normal file
14
tests/ui/asm/generic_const_simd_vec_len.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error: cannot evaluate SIMD vector length `C`
|
||||||
|
--> $DIR/generic_const_simd_vec_len.rs:10:32
|
||||||
|
|
|
||||||
|
LL | pub struct Foo<const C: usize>([u8; C]);
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
note: SIMD vector length needs to be known statically for use in `asm!`
|
||||||
|
--> $DIR/generic_const_simd_vec_len.rs:16:27
|
||||||
|
|
|
||||||
|
LL | src = in(xmm_reg) a,
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
22
tests/ui/asm/named_const_simd_vec_len.rs
Normal file
22
tests/ui/asm/named_const_simd_vec_len.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
//! This is a regression test to ensure that we evaluate
|
||||||
|
//! SIMD vector length constants instead of assuming they are literals.
|
||||||
|
|
||||||
|
//@ only-x86_64
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(repr_simd)]
|
||||||
|
|
||||||
|
const C: usize = 16;
|
||||||
|
|
||||||
|
#[repr(simd)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Foo([u8; C]);
|
||||||
|
|
||||||
|
pub unsafe fn foo(a: Foo) {
|
||||||
|
std::arch::asm!(
|
||||||
|
"movaps {src}, {src}",
|
||||||
|
src = in(xmm_reg) a,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -11,6 +11,8 @@ fn main() {
|
||||||
m();
|
m();
|
||||||
q();
|
q();
|
||||||
let _ = meow();
|
let _ = meow();
|
||||||
|
let _ = fallback_return();
|
||||||
|
let _ = fully_apit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn m() {
|
fn m() {
|
||||||
|
@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
|
||||||
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
|
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fallback_return() -> Result<(), ()> {
|
||||||
|
//[e2021]~^ this function depends on never type fallback being `()`
|
||||||
|
//[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
|
||||||
|
takes_apit::<()>(|| Default::default())?;
|
||||||
|
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mk<T>() -> Result<T, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn takes_apit2(_x: impl Default) {}
|
||||||
|
|
||||||
|
fn fully_apit() -> Result<(), ()> {
|
||||||
|
//[e2021]~^ this function depends on never type fallback being `()`
|
||||||
|
//[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
|
||||||
|
takes_apit2(mk::<()>()?);
|
||||||
|
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: this function depends on never type fallback being `()`
|
warning: this function depends on never type fallback being `()`
|
||||||
--> $DIR/never-type-fallback-breaking.rs:16:1
|
--> $DIR/never-type-fallback-breaking.rs:18:1
|
||||||
|
|
|
|
||||||
LL | fn m() {
|
LL | fn m() {
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -8,7 +8,7 @@ LL | fn m() {
|
||||||
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
||||||
= help: specify the types explicitly
|
= help: specify the types explicitly
|
||||||
note: in edition 2024, the requirement `!: Default` will fail
|
note: in edition 2024, the requirement `!: Default` will fail
|
||||||
--> $DIR/never-type-fallback-breaking.rs:20:17
|
--> $DIR/never-type-fallback-breaking.rs:22:17
|
||||||
|
|
|
|
||||||
LL | true => Default::default(),
|
LL | true => Default::default(),
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -19,7 +19,7 @@ LL | let x: () = match true {
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
warning: this function depends on never type fallback being `()`
|
warning: this function depends on never type fallback being `()`
|
||||||
--> $DIR/never-type-fallback-breaking.rs:28:1
|
--> $DIR/never-type-fallback-breaking.rs:30:1
|
||||||
|
|
|
|
||||||
LL | fn q() -> Option<()> {
|
LL | fn q() -> Option<()> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -28,7 +28,7 @@ LL | fn q() -> Option<()> {
|
||||||
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
||||||
= help: specify the types explicitly
|
= help: specify the types explicitly
|
||||||
note: in edition 2024, the requirement `!: Default` will fail
|
note: in edition 2024, the requirement `!: Default` will fail
|
||||||
--> $DIR/never-type-fallback-breaking.rs:35:5
|
--> $DIR/never-type-fallback-breaking.rs:37:5
|
||||||
|
|
|
|
||||||
LL | deserialize()?;
|
LL | deserialize()?;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -38,7 +38,7 @@ LL | deserialize::<()>()?;
|
||||||
| ++++++
|
| ++++++
|
||||||
|
|
||||||
warning: this function depends on never type fallback being `()`
|
warning: this function depends on never type fallback being `()`
|
||||||
--> $DIR/never-type-fallback-breaking.rs:45:1
|
--> $DIR/never-type-fallback-breaking.rs:47:1
|
||||||
|
|
|
|
||||||
LL | fn meow() -> Result<(), ()> {
|
LL | fn meow() -> Result<(), ()> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -47,7 +47,7 @@ LL | fn meow() -> Result<(), ()> {
|
||||||
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
||||||
= help: specify the types explicitly
|
= help: specify the types explicitly
|
||||||
note: in edition 2024, the requirement `(): From<!>` will fail
|
note: in edition 2024, the requirement `(): From<!>` will fail
|
||||||
--> $DIR/never-type-fallback-breaking.rs:48:5
|
--> $DIR/never-type-fallback-breaking.rs:50:5
|
||||||
|
|
|
|
||||||
LL | help(1)?;
|
LL | help(1)?;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -56,5 +56,43 @@ help: use `()` annotations to avoid fallback changes
|
||||||
LL | help::<(), _>(1)?;
|
LL | help::<(), _>(1)?;
|
||||||
| +++++++++
|
| +++++++++
|
||||||
|
|
||||||
warning: 3 warnings emitted
|
warning: this function depends on never type fallback being `()`
|
||||||
|
--> $DIR/never-type-fallback-breaking.rs:59:1
|
||||||
|
|
|
||||||
|
LL | pub fn fallback_return() -> Result<(), ()> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
|
||||||
|
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
||||||
|
= help: specify the types explicitly
|
||||||
|
note: in edition 2024, the requirement `!: Default` will fail
|
||||||
|
--> $DIR/never-type-fallback-breaking.rs:62:19
|
||||||
|
|
|
||||||
|
LL | takes_apit(|| Default::default())?;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
help: use `()` annotations to avoid fallback changes
|
||||||
|
|
|
||||||
|
LL | takes_apit::<()>(|| Default::default())?;
|
||||||
|
| ++++++
|
||||||
|
|
||||||
|
warning: this function depends on never type fallback being `()`
|
||||||
|
--> $DIR/never-type-fallback-breaking.rs:73:1
|
||||||
|
|
|
||||||
|
LL | fn fully_apit() -> Result<(), ()> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
|
||||||
|
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
||||||
|
= help: specify the types explicitly
|
||||||
|
note: in edition 2024, the requirement `!: Default` will fail
|
||||||
|
--> $DIR/never-type-fallback-breaking.rs:76:17
|
||||||
|
|
|
||||||
|
LL | takes_apit2(mk()?);
|
||||||
|
| ^^^^^
|
||||||
|
help: use `()` annotations to avoid fallback changes
|
||||||
|
|
|
||||||
|
LL | takes_apit2(mk::<()>()?);
|
||||||
|
| ++++++
|
||||||
|
|
||||||
|
warning: 5 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0277]: the trait bound `!: Default` is not satisfied
|
error[E0277]: the trait bound `!: Default` is not satisfied
|
||||||
--> $DIR/never-type-fallback-breaking.rs:20:17
|
--> $DIR/never-type-fallback-breaking.rs:22:17
|
||||||
|
|
|
|
||||||
LL | true => Default::default(),
|
LL | true => Default::default(),
|
||||||
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
||||||
|
@ -8,7 +8,7 @@ LL | true => Default::default(),
|
||||||
= help: did you intend to use the type `()` here instead?
|
= help: did you intend to use the type `()` here instead?
|
||||||
|
|
||||||
error[E0277]: the trait bound `!: Default` is not satisfied
|
error[E0277]: the trait bound `!: Default` is not satisfied
|
||||||
--> $DIR/never-type-fallback-breaking.rs:35:5
|
--> $DIR/never-type-fallback-breaking.rs:37:5
|
||||||
|
|
|
|
||||||
LL | deserialize()?;
|
LL | deserialize()?;
|
||||||
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
||||||
|
@ -16,13 +16,13 @@ LL | deserialize()?;
|
||||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||||
= help: did you intend to use the type `()` here instead?
|
= help: did you intend to use the type `()` here instead?
|
||||||
note: required by a bound in `deserialize`
|
note: required by a bound in `deserialize`
|
||||||
--> $DIR/never-type-fallback-breaking.rs:31:23
|
--> $DIR/never-type-fallback-breaking.rs:33:23
|
||||||
|
|
|
|
||||||
LL | fn deserialize<T: Default>() -> Option<T> {
|
LL | fn deserialize<T: Default>() -> Option<T> {
|
||||||
| ^^^^^^^ required by this bound in `deserialize`
|
| ^^^^^^^ required by this bound in `deserialize`
|
||||||
|
|
||||||
error[E0277]: the trait bound `(): From<!>` is not satisfied
|
error[E0277]: the trait bound `(): From<!>` is not satisfied
|
||||||
--> $DIR/never-type-fallback-breaking.rs:48:5
|
--> $DIR/never-type-fallback-breaking.rs:50:5
|
||||||
|
|
|
|
||||||
LL | help(1)?;
|
LL | help(1)?;
|
||||||
| ^^^^^^^ the trait `From<!>` is not implemented for `()`
|
| ^^^^^^^ the trait `From<!>` is not implemented for `()`
|
||||||
|
@ -39,11 +39,36 @@ LL | help(1)?;
|
||||||
and 4 others
|
and 4 others
|
||||||
= note: required for `!` to implement `Into<()>`
|
= note: required for `!` to implement `Into<()>`
|
||||||
note: required by a bound in `help`
|
note: required by a bound in `help`
|
||||||
--> $DIR/never-type-fallback-breaking.rs:42:20
|
--> $DIR/never-type-fallback-breaking.rs:44:20
|
||||||
|
|
|
|
||||||
LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
|
LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
|
||||||
| ^^^^^^^^ required by this bound in `help`
|
| ^^^^^^^^ required by this bound in `help`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0277]: the trait bound `!: Default` is not satisfied
|
||||||
|
--> $DIR/never-type-fallback-breaking.rs:62:19
|
||||||
|
|
|
||||||
|
LL | takes_apit(|| Default::default())?;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
||||||
|
|
|
||||||
|
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||||
|
= help: did you intend to use the type `()` here instead?
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `!: Default` is not satisfied
|
||||||
|
--> $DIR/never-type-fallback-breaking.rs:76:17
|
||||||
|
|
|
||||||
|
LL | takes_apit2(mk()?);
|
||||||
|
| ----------- ^^^^^ the trait `Default` is not implemented for `!`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||||
|
= help: did you intend to use the type `()` here instead?
|
||||||
|
note: required by a bound in `takes_apit2`
|
||||||
|
--> $DIR/never-type-fallback-breaking.rs:71:25
|
||||||
|
|
|
||||||
|
LL | fn takes_apit2(_x: impl Default) {}
|
||||||
|
| ^^^^^^^ required by this bound in `takes_apit2`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -11,6 +11,8 @@ fn main() {
|
||||||
m();
|
m();
|
||||||
q();
|
q();
|
||||||
let _ = meow();
|
let _ = meow();
|
||||||
|
let _ = fallback_return();
|
||||||
|
let _ = fully_apit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn m() {
|
fn m() {
|
||||||
|
@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
|
||||||
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
|
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fallback_return() -> Result<(), ()> {
|
||||||
|
//[e2021]~^ this function depends on never type fallback being `()`
|
||||||
|
//[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
|
||||||
|
takes_apit(|| Default::default())?;
|
||||||
|
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mk<T>() -> Result<T, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn takes_apit2(_x: impl Default) {}
|
||||||
|
|
||||||
|
fn fully_apit() -> Result<(), ()> {
|
||||||
|
//[e2021]~^ this function depends on never type fallback being `()`
|
||||||
|
//[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
|
||||||
|
takes_apit2(mk()?);
|
||||||
|
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@ LL | foo(|| panic!());
|
||||||
= note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
|
= note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
|
||||||
help: use `()` annotations to avoid fallback changes
|
help: use `()` annotations to avoid fallback changes
|
||||||
|
|
|
|
||||||
LL | foo::<(), _>(|| panic!());
|
LL | foo::<()>(|| panic!());
|
||||||
| +++++++++
|
| ++++++
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
error: field expressions cannot have generic arguments
|
|
||||||
--> $DIR/bad-name.rs:2:12
|
|
||||||
|
|
|
||||||
LL | let x.y::<isize>.z foo;
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
error: expected a pattern, found an expression
|
error: expected a pattern, found an expression
|
||||||
--> $DIR/bad-name.rs:2:7
|
--> $DIR/bad-name.rs:2:7
|
||||||
|
|
|
|
||||||
|
@ -18,5 +12,11 @@ error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator,
|
||||||
LL | let x.y::<isize>.z foo;
|
LL | let x.y::<isize>.z foo;
|
||||||
| ^^^ expected one of 9 possible tokens
|
| ^^^ expected one of 9 possible tokens
|
||||||
|
|
||||||
|
error: field expressions cannot have generic arguments
|
||||||
|
--> $DIR/bad-name.rs:2:12
|
||||||
|
|
|
||||||
|
LL | let x.y::<isize>.z foo;
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = vec![].into_iter().collect::<usize>;
|
let _ = vec![].into_iter().collect::<usize>;
|
||||||
//~^ ERROR attempted to take value of method `collect` on type `std::vec::IntoIter<_>`
|
//~^ ERROR attempted to take value of method `collect` on type `std::vec::IntoIter<_>`
|
||||||
//~| ERROR field expressions cannot have generic arguments
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
error: field expressions cannot have generic arguments
|
|
||||||
--> $DIR/method-missing-parentheses.rs:2:41
|
|
||||||
|
|
|
||||||
LL | let _ = vec![].into_iter().collect::<usize>;
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
error[E0615]: attempted to take value of method `collect` on type `std::vec::IntoIter<_>`
|
error[E0615]: attempted to take value of method `collect` on type `std::vec::IntoIter<_>`
|
||||||
--> $DIR/method-missing-parentheses.rs:2:32
|
--> $DIR/method-missing-parentheses.rs:2:32
|
||||||
|
|
|
|
||||||
|
@ -15,6 +9,6 @@ help: use parentheses to call the method
|
||||||
LL | let _ = vec![].into_iter().collect::<usize>();
|
LL | let _ = vec![].into_iter().collect::<usize>();
|
||||||
| ++
|
| ++
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0615`.
|
For more information about this error, try `rustc --explain E0615`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue