Auto merge of #136481 - jieyouxu:rollup-w0lnnqb, r=jieyouxu
Rollup of 8 pull requests Successful merges: - #136356 (Docs for f16 and f128: correct a typo and add details) - #136404 (Remove a footgun-y feature / relic of the past from the compiletest DSL) - #136432 (LTA: Actually check where-clauses for well-formedness at the def site) - #136438 (miri: improve error when offset_from preconditions are violated) - #136441 ([`compiletest`-related cleanups 1/7] Cleanup `is_rustdoc` logic and remove a useless path join in rustdoc-json runtest logic) - #136455 (Remove some `Clone` bounds and derives.) - #136464 (Remove hook calling via `TyCtxtAt`.) - #136467 (override default config profile on tarballs) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
534d79adf9
33 changed files with 251 additions and 143 deletions
|
@ -280,7 +280,9 @@ const_eval_nullary_intrinsic_fail =
|
||||||
could not evaluate nullary intrinsic
|
could not evaluate nullary intrinsic
|
||||||
|
|
||||||
const_eval_offset_from_different_allocations =
|
const_eval_offset_from_different_allocations =
|
||||||
`{$name}` called on pointers into different allocations
|
`{$name}` called on two different pointers that are not both derived from the same allocation
|
||||||
|
const_eval_offset_from_out_of_bounds =
|
||||||
|
`{$name}` called on two different pointers where the memory range between them is not in-bounds of an allocation
|
||||||
const_eval_offset_from_overflow =
|
const_eval_offset_from_overflow =
|
||||||
`{$name}` called when first pointer is too far ahead of second
|
`{$name}` called when first pointer is too far ahead of second
|
||||||
const_eval_offset_from_test =
|
const_eval_offset_from_test =
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Not in interpret to make sure we do not use private implementation details
|
// Not in interpret to make sure we do not use private implementation details
|
||||||
|
|
||||||
use rustc_abi::VariantIdx;
|
use rustc_abi::VariantIdx;
|
||||||
use rustc_middle::query::{Key, TyCtxtAt};
|
use rustc_middle::query::Key;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_middle::{bug, mir};
|
use rustc_middle::{bug, mir};
|
||||||
|
@ -35,16 +35,17 @@ pub(crate) type ValTreeCreationResult<'tcx> = Result<ty::ValTree<'tcx>, ValTreeC
|
||||||
|
|
||||||
#[instrument(skip(tcx), level = "debug")]
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
|
pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
|
||||||
tcx: TyCtxtAt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
val: mir::ConstValue<'tcx>,
|
val: mir::ConstValue<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> Option<mir::DestructuredConstant<'tcx>> {
|
) -> Option<mir::DestructuredConstant<'tcx>> {
|
||||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||||
let (ecx, op) = mk_eval_cx_for_const_val(tcx, typing_env, val, ty)?;
|
// FIXME: use a proper span here?
|
||||||
|
let (ecx, op) = mk_eval_cx_for_const_val(tcx.at(rustc_span::DUMMY_SP), typing_env, val, ty)?;
|
||||||
|
|
||||||
// We go to `usize` as we cannot allocate anything bigger anyway.
|
// We go to `usize` as we cannot allocate anything bigger anyway.
|
||||||
let (field_count, variant, down) = match ty.kind() {
|
let (field_count, variant, down) = match ty.kind() {
|
||||||
ty::Array(_, len) => (len.try_to_target_usize(tcx.tcx)? as usize, None, op),
|
ty::Array(_, len) => (len.try_to_target_usize(tcx)? as usize, None, op),
|
||||||
ty::Adt(def, _) if def.variants().is_empty() => {
|
ty::Adt(def, _) if def.variants().is_empty() => {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,7 +319,25 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||||
|
|
||||||
// Check that the memory between them is dereferenceable at all, starting from the
|
// Check that the memory between them is dereferenceable at all, starting from the
|
||||||
// origin pointer: `dist` is `a - b`, so it is based on `b`.
|
// origin pointer: `dist` is `a - b`, so it is based on `b`.
|
||||||
self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest)?;
|
self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest)
|
||||||
|
.map_err_kind(|_| {
|
||||||
|
// This could mean they point to different allocations, or they point to the same allocation
|
||||||
|
// but not the entire range between the pointers is in-bounds.
|
||||||
|
if let Ok((a_alloc_id, ..)) = self.ptr_try_get_alloc_id(a, 0)
|
||||||
|
&& let Ok((b_alloc_id, ..)) = self.ptr_try_get_alloc_id(b, 0)
|
||||||
|
&& a_alloc_id == b_alloc_id
|
||||||
|
{
|
||||||
|
err_ub_custom!(
|
||||||
|
fluent::const_eval_offset_from_out_of_bounds,
|
||||||
|
name = intrinsic_name,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
err_ub_custom!(
|
||||||
|
fluent::const_eval_offset_from_different_allocations,
|
||||||
|
name = intrinsic_name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})?;
|
||||||
// Then check that this is also dereferenceable from `a`. This ensures that they are
|
// Then check that this is also dereferenceable from `a`. This ensures that they are
|
||||||
// derived from the same allocation.
|
// derived from the same allocation.
|
||||||
self.check_ptr_access_signed(
|
self.check_ptr_access_signed(
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use rustc_hir::LangItem;
|
use rustc_hir::LangItem;
|
||||||
use rustc_middle::query::TyCtxtAt;
|
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::{self};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_middle::{bug, mir};
|
use rustc_middle::{bug, mir};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
|
@ -48,15 +47,15 @@ fn alloc_caller_location<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn const_caller_location_provider(
|
pub(crate) fn const_caller_location_provider(
|
||||||
tcx: TyCtxtAt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
file: Symbol,
|
file: Symbol,
|
||||||
line: u32,
|
line: u32,
|
||||||
col: u32,
|
col: u32,
|
||||||
) -> mir::ConstValue<'_> {
|
) -> mir::ConstValue<'_> {
|
||||||
trace!("const_caller_location: {}:{}:{}", file, line, col);
|
trace!("const_caller_location: {}:{}:{}", file, line, col);
|
||||||
let mut ecx = mk_eval_cx_to_read_const_val(
|
let mut ecx = mk_eval_cx_to_read_const_val(
|
||||||
tcx.tcx,
|
tcx,
|
||||||
tcx.span,
|
rustc_span::DUMMY_SP, // FIXME: use a proper span here?
|
||||||
ty::TypingEnv::fully_monomorphized(),
|
ty::TypingEnv::fully_monomorphized(),
|
||||||
CanAccessMutGlobal::No,
|
CanAccessMutGlobal::No,
|
||||||
);
|
);
|
||||||
|
|
|
@ -328,16 +328,20 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
|
||||||
hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
|
hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
|
||||||
// `ForeignItem`s are handled separately.
|
// `ForeignItem`s are handled separately.
|
||||||
hir::ItemKind::ForeignMod { .. } => Ok(()),
|
hir::ItemKind::ForeignMod { .. } => Ok(()),
|
||||||
hir::ItemKind::TyAlias(hir_ty, hir_generics) => {
|
hir::ItemKind::TyAlias(hir_ty, hir_generics) if tcx.type_alias_is_lazy(item.owner_id) => {
|
||||||
if tcx.type_alias_is_lazy(item.owner_id) {
|
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
|
||||||
// Bounds of lazy type aliases and of eager ones that contain opaque types are respected.
|
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||||
// E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`.
|
let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
|
||||||
let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
|
wfcx.register_wf_obligation(
|
||||||
|
hir_ty.span,
|
||||||
|
Some(WellFormedLoc::Ty(def_id)),
|
||||||
|
item_ty.into(),
|
||||||
|
);
|
||||||
|
check_where_clauses(wfcx, item.span, def_id);
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
check_variances_for_type_defn(tcx, item, hir_generics);
|
check_variances_for_type_defn(tcx, item, hir_generics);
|
||||||
res
|
res
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
};
|
};
|
||||||
|
@ -1276,7 +1280,6 @@ fn check_item_fn(
|
||||||
|
|
||||||
enum UnsizedHandling {
|
enum UnsizedHandling {
|
||||||
Forbid,
|
Forbid,
|
||||||
Allow,
|
|
||||||
AllowIfForeignTail,
|
AllowIfForeignTail,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1294,7 +1297,6 @@ fn check_item_type(
|
||||||
|
|
||||||
let forbid_unsized = match unsized_handling {
|
let forbid_unsized = match unsized_handling {
|
||||||
UnsizedHandling::Forbid => true,
|
UnsizedHandling::Forbid => true,
|
||||||
UnsizedHandling::Allow => false,
|
|
||||||
UnsizedHandling::AllowIfForeignTail => {
|
UnsizedHandling::AllowIfForeignTail => {
|
||||||
let tail =
|
let tail =
|
||||||
tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
|
tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
|
||||||
|
|
|
@ -24,7 +24,7 @@ use rustc_middle::util::Providers;
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
providers.hooks.save_dep_graph =
|
providers.hooks.save_dep_graph =
|
||||||
|tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx.tcx));
|
|tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx));
|
||||||
}
|
}
|
||||||
|
|
||||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||||
|
|
|
@ -689,7 +689,7 @@ fn provide_cstore_hooks(providers: &mut Providers) {
|
||||||
providers.hooks.def_path_hash_to_def_id_extern = |tcx, hash, stable_crate_id| {
|
providers.hooks.def_path_hash_to_def_id_extern = |tcx, hash, stable_crate_id| {
|
||||||
// If this is a DefPathHash from an upstream crate, let the CrateStore map
|
// If this is a DefPathHash from an upstream crate, let the CrateStore map
|
||||||
// it to a DefId.
|
// it to a DefId.
|
||||||
let cstore = CStore::from_tcx(tcx.tcx);
|
let cstore = CStore::from_tcx(tcx);
|
||||||
let cnum = *tcx
|
let cnum = *tcx
|
||||||
.untracked()
|
.untracked()
|
||||||
.stable_crate_ids
|
.stable_crate_ids
|
||||||
|
@ -702,11 +702,11 @@ fn provide_cstore_hooks(providers: &mut Providers) {
|
||||||
};
|
};
|
||||||
|
|
||||||
providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| {
|
providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| {
|
||||||
let cstore = CStore::from_tcx(tcx.tcx);
|
let cstore = CStore::from_tcx(tcx);
|
||||||
cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx.sess, index_guess, hash)
|
cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx.sess, index_guess, hash)
|
||||||
};
|
};
|
||||||
providers.hooks.import_source_files = |tcx, cnum| {
|
providers.hooks.import_source_files = |tcx, cnum| {
|
||||||
let cstore = CStore::from_tcx(tcx.tcx);
|
let cstore = CStore::from_tcx(tcx);
|
||||||
let cdata = cstore.get_crate_data(cnum);
|
let cdata = cstore.get_crate_data(cnum);
|
||||||
for file_index in 0..cdata.root.source_map.size() {
|
for file_index in 0..cdata.root.source_map.size() {
|
||||||
cdata.imported_source_file(file_index as u32, tcx.sess);
|
cdata.imported_source_file(file_index as u32, tcx.sess);
|
||||||
|
|
|
@ -6,11 +6,9 @@
|
||||||
use rustc_hir::def_id::{DefId, DefPathHash};
|
use rustc_hir::def_id::{DefId, DefPathHash};
|
||||||
use rustc_session::StableCrateId;
|
use rustc_session::StableCrateId;
|
||||||
use rustc_span::def_id::{CrateNum, LocalDefId};
|
use rustc_span::def_id::{CrateNum, LocalDefId};
|
||||||
use rustc_span::{DUMMY_SP, ExpnHash, ExpnId};
|
use rustc_span::{ExpnHash, ExpnId};
|
||||||
use tracing::instrument;
|
|
||||||
|
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
use crate::query::TyCtxtAt;
|
|
||||||
use crate::ty::{Ty, TyCtxt};
|
use crate::ty::{Ty, TyCtxt};
|
||||||
|
|
||||||
macro_rules! declare_hooks {
|
macro_rules! declare_hooks {
|
||||||
|
@ -22,26 +20,14 @@ macro_rules! declare_hooks {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn $name(self, $($arg: $K,)*) -> $V
|
pub fn $name(self, $($arg: $K,)*) -> $V
|
||||||
{
|
{
|
||||||
self.at(DUMMY_SP).$name($($arg,)*)
|
(self.hooks.$name)(self, $($arg,)*)
|
||||||
}
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TyCtxtAt<'tcx> {
|
|
||||||
$(
|
|
||||||
$(#[$attr])*
|
|
||||||
#[inline(always)]
|
|
||||||
#[instrument(level = "debug", skip(self), ret)]
|
|
||||||
pub fn $name(self, $($arg: $K,)*) -> $V
|
|
||||||
{
|
|
||||||
(self.tcx.hooks.$name)(self, $($arg,)*)
|
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Providers {
|
pub struct Providers {
|
||||||
$(pub $name: for<'tcx> fn(
|
$(pub $name: for<'tcx> fn(
|
||||||
TyCtxtAt<'tcx>,
|
TyCtxt<'tcx>,
|
||||||
$($arg: $K,)*
|
$($arg: $K,)*
|
||||||
) -> $V,)*
|
) -> $V,)*
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
|
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
|
||||||
use rustc_index::{IndexVec, newtype_index};
|
use rustc_index::{IndexVec, newtype_index};
|
||||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
|
use rustc_macros::{HashStable, TypeVisitable};
|
||||||
use rustc_middle::middle::region;
|
use rustc_middle::middle::region;
|
||||||
use rustc_middle::mir::interpret::AllocId;
|
use rustc_middle::mir::interpret::AllocId;
|
||||||
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
|
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
|
||||||
|
@ -53,7 +53,7 @@ macro_rules! thir_with_elements {
|
||||||
/// A container for a THIR body.
|
/// A container for a THIR body.
|
||||||
///
|
///
|
||||||
/// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
|
/// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
|
||||||
#[derive(Debug, HashStable, Clone)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct Thir<'tcx> {
|
pub struct Thir<'tcx> {
|
||||||
$(
|
$(
|
||||||
pub $field_name: $field_ty,
|
pub $field_name: $field_ty,
|
||||||
|
@ -98,14 +98,14 @@ thir_with_elements! {
|
||||||
params: ParamId => Param<'tcx> => "p{}",
|
params: ParamId => Param<'tcx> => "p{}",
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, HashStable, Clone)]
|
#[derive(Debug, HashStable)]
|
||||||
pub enum BodyTy<'tcx> {
|
pub enum BodyTy<'tcx> {
|
||||||
Const(Ty<'tcx>),
|
Const(Ty<'tcx>),
|
||||||
Fn(FnSig<'tcx>),
|
Fn(FnSig<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Description of a type-checked function parameter.
|
/// Description of a type-checked function parameter.
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct Param<'tcx> {
|
pub struct Param<'tcx> {
|
||||||
/// The pattern that appears in the parameter list, or None for implicit parameters.
|
/// The pattern that appears in the parameter list, or None for implicit parameters.
|
||||||
pub pat: Option<Box<Pat<'tcx>>>,
|
pub pat: Option<Box<Pat<'tcx>>>,
|
||||||
|
@ -125,7 +125,7 @@ pub enum LintLevel {
|
||||||
Explicit(HirId),
|
Explicit(HirId),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
/// Whether the block itself has a label. Used by `label: {}`
|
/// Whether the block itself has a label. Used by `label: {}`
|
||||||
/// and `try` blocks.
|
/// and `try` blocks.
|
||||||
|
@ -145,7 +145,7 @@ pub struct Block {
|
||||||
|
|
||||||
type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
|
type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct AdtExpr<'tcx> {
|
pub struct AdtExpr<'tcx> {
|
||||||
/// The ADT we're constructing.
|
/// The ADT we're constructing.
|
||||||
pub adt_def: AdtDef<'tcx>,
|
pub adt_def: AdtDef<'tcx>,
|
||||||
|
@ -162,7 +162,7 @@ pub struct AdtExpr<'tcx> {
|
||||||
pub base: AdtExprBase<'tcx>,
|
pub base: AdtExprBase<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub enum AdtExprBase<'tcx> {
|
pub enum AdtExprBase<'tcx> {
|
||||||
/// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
|
/// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
|
||||||
None,
|
None,
|
||||||
|
@ -175,7 +175,7 @@ pub enum AdtExprBase<'tcx> {
|
||||||
DefaultFields(Box<[Ty<'tcx>]>),
|
DefaultFields(Box<[Ty<'tcx>]>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct ClosureExpr<'tcx> {
|
pub struct ClosureExpr<'tcx> {
|
||||||
pub closure_id: LocalDefId,
|
pub closure_id: LocalDefId,
|
||||||
pub args: UpvarArgs<'tcx>,
|
pub args: UpvarArgs<'tcx>,
|
||||||
|
@ -184,7 +184,7 @@ pub struct ClosureExpr<'tcx> {
|
||||||
pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>,
|
pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct InlineAsmExpr<'tcx> {
|
pub struct InlineAsmExpr<'tcx> {
|
||||||
pub asm_macro: AsmMacro,
|
pub asm_macro: AsmMacro,
|
||||||
pub template: &'tcx [InlineAsmTemplatePiece],
|
pub template: &'tcx [InlineAsmTemplatePiece],
|
||||||
|
@ -202,12 +202,12 @@ pub enum BlockSafety {
|
||||||
ExplicitUnsafe(HirId),
|
ExplicitUnsafe(HirId),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct Stmt<'tcx> {
|
pub struct Stmt<'tcx> {
|
||||||
pub kind: StmtKind<'tcx>,
|
pub kind: StmtKind<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub enum StmtKind<'tcx> {
|
pub enum StmtKind<'tcx> {
|
||||||
/// An expression with a trailing semicolon.
|
/// An expression with a trailing semicolon.
|
||||||
Expr {
|
Expr {
|
||||||
|
@ -247,11 +247,11 @@ pub enum StmtKind<'tcx> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, HashStable)]
|
||||||
pub struct LocalVarId(pub HirId);
|
pub struct LocalVarId(pub HirId);
|
||||||
|
|
||||||
/// A THIR expression.
|
/// A THIR expression.
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct Expr<'tcx> {
|
pub struct Expr<'tcx> {
|
||||||
/// kind of expression
|
/// kind of expression
|
||||||
pub kind: ExprKind<'tcx>,
|
pub kind: ExprKind<'tcx>,
|
||||||
|
@ -278,7 +278,7 @@ pub struct TempLifetime {
|
||||||
pub backwards_incompatible: Option<region::Scope>,
|
pub backwards_incompatible: Option<region::Scope>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub enum ExprKind<'tcx> {
|
pub enum ExprKind<'tcx> {
|
||||||
/// `Scope`s are used to explicitly mark destruction scopes,
|
/// `Scope`s are used to explicitly mark destruction scopes,
|
||||||
/// and to track the `HirId` of the expressions within the scope.
|
/// and to track the `HirId` of the expressions within the scope.
|
||||||
|
@ -556,20 +556,20 @@ pub enum ExprKind<'tcx> {
|
||||||
/// Represents the association of a field identifier and an expression.
|
/// Represents the association of a field identifier and an expression.
|
||||||
///
|
///
|
||||||
/// This is used in struct constructors.
|
/// This is used in struct constructors.
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct FieldExpr {
|
pub struct FieldExpr {
|
||||||
pub name: FieldIdx,
|
pub name: FieldIdx,
|
||||||
pub expr: ExprId,
|
pub expr: ExprId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct FruInfo<'tcx> {
|
pub struct FruInfo<'tcx> {
|
||||||
pub base: ExprId,
|
pub base: ExprId,
|
||||||
pub field_types: Box<[Ty<'tcx>]>,
|
pub field_types: Box<[Ty<'tcx>]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `match` arm.
|
/// A `match` arm.
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct Arm<'tcx> {
|
pub struct Arm<'tcx> {
|
||||||
pub pattern: Box<Pat<'tcx>>,
|
pub pattern: Box<Pat<'tcx>>,
|
||||||
pub guard: Option<ExprId>,
|
pub guard: Option<ExprId>,
|
||||||
|
@ -587,7 +587,7 @@ pub enum LogicalOp {
|
||||||
Or,
|
Or,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable)]
|
#[derive(Debug, HashStable)]
|
||||||
pub enum InlineAsmOperand<'tcx> {
|
pub enum InlineAsmOperand<'tcx> {
|
||||||
In {
|
In {
|
||||||
reg: InlineAsmRegOrRegClass,
|
reg: InlineAsmRegOrRegClass,
|
||||||
|
@ -625,13 +625,13 @@ pub enum InlineAsmOperand<'tcx> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable, TypeVisitable)]
|
#[derive(Debug, HashStable, TypeVisitable)]
|
||||||
pub struct FieldPat<'tcx> {
|
pub struct FieldPat<'tcx> {
|
||||||
pub field: FieldIdx,
|
pub field: FieldIdx,
|
||||||
pub pattern: Box<Pat<'tcx>>,
|
pub pattern: Box<Pat<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable, TypeVisitable)]
|
#[derive(Debug, HashStable, TypeVisitable)]
|
||||||
pub struct Pat<'tcx> {
|
pub struct Pat<'tcx> {
|
||||||
pub ty: Ty<'tcx>,
|
pub ty: Ty<'tcx>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -739,7 +739,7 @@ impl<'tcx> Pat<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable, TypeVisitable)]
|
#[derive(Debug, HashStable, TypeVisitable)]
|
||||||
pub struct Ascription<'tcx> {
|
pub struct Ascription<'tcx> {
|
||||||
pub annotation: CanonicalUserTypeAnnotation<'tcx>,
|
pub annotation: CanonicalUserTypeAnnotation<'tcx>,
|
||||||
/// Variance to use when relating the `user_ty` to the **type of the value being
|
/// Variance to use when relating the `user_ty` to the **type of the value being
|
||||||
|
@ -763,7 +763,7 @@ pub struct Ascription<'tcx> {
|
||||||
pub variance: ty::Variance,
|
pub variance: ty::Variance,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, HashStable, TypeVisitable)]
|
#[derive(Debug, HashStable, TypeVisitable)]
|
||||||
pub enum PatKind<'tcx> {
|
pub enum PatKind<'tcx> {
|
||||||
/// A wildcard pattern: `_`.
|
/// A wildcard pattern: `_`.
|
||||||
Wild,
|
Wild,
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_middle::mir::coverage::{
|
||||||
FunctionCoverageInfo, MappingKind, Op,
|
FunctionCoverageInfo, MappingKind, Op,
|
||||||
};
|
};
|
||||||
use rustc_middle::mir::{Body, Statement, StatementKind};
|
use rustc_middle::mir::{Body, Statement, StatementKind};
|
||||||
use rustc_middle::query::TyCtxtAt;
|
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_middle::util::Providers;
|
use rustc_middle::util::Providers;
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
|
@ -15,8 +14,7 @@ use tracing::trace;
|
||||||
|
|
||||||
/// Registers query/hook implementations related to coverage.
|
/// Registers query/hook implementations related to coverage.
|
||||||
pub(crate) fn provide(providers: &mut Providers) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
providers.hooks.is_eligible_for_coverage =
|
providers.hooks.is_eligible_for_coverage = is_eligible_for_coverage;
|
||||||
|TyCtxtAt { tcx, .. }, def_id| is_eligible_for_coverage(tcx, def_id);
|
|
||||||
providers.queries.coverage_attr_on = coverage_attr_on;
|
providers.queries.coverage_attr_on = coverage_attr_on;
|
||||||
providers.queries.coverage_ids_info = coverage_ids_info;
|
providers.queries.coverage_ids_info = coverage_ids_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -953,7 +953,7 @@ fn visit_instance_use<'tcx>(
|
||||||
|
|
||||||
/// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
|
/// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
|
||||||
/// can just link to the upstream crate and therefore don't need a mono item.
|
/// can just link to the upstream crate and therefore don't need a mono item.
|
||||||
fn should_codegen_locally<'tcx>(tcx: TyCtxtAt<'tcx>, instance: Instance<'tcx>) -> bool {
|
fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
|
||||||
let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
|
let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -976,7 +976,7 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxtAt<'tcx>, instance: Instance<'tcx>) -
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcx.is_reachable_non_generic(def_id) || instance.upstream_monomorphization(*tcx).is_some() {
|
if tcx.is_reachable_non_generic(def_id) || instance.upstream_monomorphization(tcx).is_some() {
|
||||||
// We can link to the item in question, no instance needed in this crate.
|
// We can link to the item in question, no instance needed in this crate.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,6 @@ pub fn query_system<'a>(
|
||||||
rustc_middle::rustc_query_append! { define_queries! }
|
rustc_middle::rustc_query_append! { define_queries! }
|
||||||
|
|
||||||
pub fn provide(providers: &mut rustc_middle::util::Providers) {
|
pub fn provide(providers: &mut rustc_middle::util::Providers) {
|
||||||
providers.hooks.alloc_self_profile_query_strings =
|
providers.hooks.alloc_self_profile_query_strings = alloc_self_profile_query_strings;
|
||||||
|tcx| alloc_self_profile_query_strings(tcx.tcx);
|
providers.hooks.query_key_hash_verify_all = query_key_hash_verify_all;
|
||||||
providers.hooks.query_key_hash_verify_all = |tcx| query_key_hash_verify_all(tcx.tcx);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ type Never = std::convert::Infallible;
|
||||||
/// which means in practice almost every foldable type needs to also be
|
/// which means in practice almost every foldable type needs to also be
|
||||||
/// visitable. (However, there are some types that are visitable without being
|
/// visitable. (However, there are some types that are visitable without being
|
||||||
/// foldable.)
|
/// foldable.)
|
||||||
pub trait TypeFoldable<I: Interner>: TypeVisitable<I> {
|
pub trait TypeFoldable<I: Interner>: TypeVisitable<I> + Clone {
|
||||||
/// The entry point for folding. To fold a value `t` with a folder `f`
|
/// The entry point for folding. To fold a value `t` with a folder `f`
|
||||||
/// call: `t.try_fold_with(f)`.
|
/// call: `t.try_fold_with(f)`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -59,7 +59,7 @@ use crate::{self as ty, Interner, TypeFlags};
|
||||||
///
|
///
|
||||||
/// To implement this conveniently, use the derive macro located in
|
/// To implement this conveniently, use the derive macro located in
|
||||||
/// `rustc_macros`.
|
/// `rustc_macros`.
|
||||||
pub trait TypeVisitable<I: Interner>: fmt::Debug + Clone {
|
pub trait TypeVisitable<I: Interner>: fmt::Debug {
|
||||||
/// The entry point for visiting. To visit a value `t` with a visitor `v`
|
/// The entry point for visiting. To visit a value `t` with a visitor `v`
|
||||||
/// call: `t.visit_with(v)`.
|
/// call: `t.visit_with(v)`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1160,9 +1160,9 @@ impl<T> (T,) {}
|
||||||
///
|
///
|
||||||
/// Note that most common platforms will not support `f16` in hardware without enabling extra target
|
/// Note that most common platforms will not support `f16` in hardware without enabling extra target
|
||||||
/// features, with the notable exception of Apple Silicon (also known as M1, M2, etc.) processors.
|
/// features, with the notable exception of Apple Silicon (also known as M1, M2, etc.) processors.
|
||||||
/// Hardware support on x86-64 requires the avx512fp16 feature, while RISC-V requires Zhf.
|
/// Hardware support on x86/x86-64 requires the avx512fp16 or avx10.1 features, while RISC-V requires
|
||||||
/// Usually the fallback implementation will be to use `f32` hardware if it exists, and convert
|
/// Zfh, and Arm/AArch64 requires FEAT_FP16. Usually the fallback implementation will be to use `f32`
|
||||||
/// between `f16` and `f32` when performing math.
|
/// hardware if it exists, and convert between `f16` and `f32` when performing math.
|
||||||
///
|
///
|
||||||
/// *[See also the `std::f16::consts` module](crate::f16::consts).*
|
/// *[See also the `std::f16::consts` module](crate::f16::consts).*
|
||||||
///
|
///
|
||||||
|
@ -1344,10 +1344,10 @@ mod prim_f64 {}
|
||||||
/// quad-precision values][wikipedia] for more information.
|
/// quad-precision values][wikipedia] for more information.
|
||||||
///
|
///
|
||||||
/// Note that no platforms have hardware support for `f128` without enabling target specific features,
|
/// Note that no platforms have hardware support for `f128` without enabling target specific features,
|
||||||
/// as for all instruction set architectures `f128` is considered an optional feature.
|
/// as for all instruction set architectures `f128` is considered an optional feature. Only Power ISA
|
||||||
/// Only Power ISA ("PowerPC") and RISC-V specify it, and only certain microarchitectures
|
/// ("PowerPC") and RISC-V (via the Q extension) specify it, and only certain microarchitectures
|
||||||
/// actually implement it. For x86-64 and AArch64, ISA support is not even specified,
|
/// actually implement it. For x86-64 and AArch64, ISA support is not even specified, so it will always
|
||||||
/// so it will always be a software implementation significantly slower than `f64`.
|
/// be a software implementation significantly slower than `f64`.
|
||||||
///
|
///
|
||||||
/// _Note: `f128` support is incomplete. Many platforms will not be able to link math functions. On
|
/// _Note: `f128` support is incomplete. Many platforms will not be able to link math functions. On
|
||||||
/// x86 in particular, these functions do link but their results are always incorrect._
|
/// x86 in particular, these functions do link but their results are always incorrect._
|
||||||
|
|
|
@ -700,7 +700,7 @@ trait Merge {
|
||||||
impl Merge for TomlConfig {
|
impl Merge for TomlConfig {
|
||||||
fn merge(
|
fn merge(
|
||||||
&mut self,
|
&mut self,
|
||||||
TomlConfig { build, install, llvm, rust, dist, target, profile: _, change_id }: Self,
|
TomlConfig { build, install, llvm, rust, dist, target, profile, change_id }: Self,
|
||||||
replace: ReplaceOpt,
|
replace: ReplaceOpt,
|
||||||
) {
|
) {
|
||||||
fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
|
fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
|
||||||
|
@ -712,7 +712,10 @@ impl Merge for TomlConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.change_id.inner.merge(change_id.inner, replace);
|
self.change_id.inner.merge(change_id.inner, replace);
|
||||||
|
self.profile.merge(profile, replace);
|
||||||
|
|
||||||
do_merge(&mut self.build, build, replace);
|
do_merge(&mut self.build, build, replace);
|
||||||
do_merge(&mut self.install, install, replace);
|
do_merge(&mut self.install, install, replace);
|
||||||
do_merge(&mut self.llvm, llvm, replace);
|
do_merge(&mut self.llvm, llvm, replace);
|
||||||
|
@ -1505,6 +1508,10 @@ impl Config {
|
||||||
build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into()));
|
build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if GitInfo::new(false, &config.src).is_from_tarball() && toml.profile.is_none() {
|
||||||
|
toml.profile = Some("dist".into());
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(include) = &toml.profile {
|
if let Some(include) = &toml.profile {
|
||||||
// Allows creating alias for profile names, allowing
|
// Allows creating alias for profile names, allowing
|
||||||
// profiles to be renamed while maintaining back compatibility
|
// profiles to be renamed while maintaining back compatibility
|
||||||
|
|
|
@ -882,14 +882,6 @@ fn iter_header(
|
||||||
}
|
}
|
||||||
let ln = ln.trim();
|
let ln = ln.trim();
|
||||||
|
|
||||||
// Assume that any directives will be found before the first module or function. This
|
|
||||||
// doesn't seem to be an optimization with a warm page cache. Maybe with a cold one.
|
|
||||||
// FIXME(jieyouxu): this will cause `//@` directives in the rest of the test file to
|
|
||||||
// not be checked.
|
|
||||||
if ln.starts_with("fn") || ln.starts_with("mod") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let Some(directive_line) = line_directive(line_number, comment, ln) else {
|
let Some(directive_line) = line_directive(line_number, comment, ln) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1417,9 +1417,7 @@ impl<'test> TestCx<'test> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_rustdoc(&self) -> bool {
|
fn is_rustdoc(&self) -> bool {
|
||||||
self.config.src_base.ends_with("rustdoc-ui")
|
matches!(self.config.suite.as_str(), "rustdoc-ui" | "rustdoc-js" | "rustdoc-json")
|
||||||
|| self.config.src_base.ends_with("rustdoc-js")
|
|
||||||
|| self.config.src_base.ends_with("rustdoc-json")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mir_dump_dir(&self) -> PathBuf {
|
fn get_mir_dump_dir(&self) -> PathBuf {
|
||||||
|
|
|
@ -16,13 +16,12 @@ impl TestCx<'_> {
|
||||||
self.fatal_proc_rec("rustdoc failed!", &proc_res);
|
self.fatal_proc_rec("rustdoc failed!", &proc_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
let root = self.config.find_rust_src_root().unwrap();
|
|
||||||
let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
|
let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
|
||||||
json_out.set_extension("json");
|
json_out.set_extension("json");
|
||||||
let res = self.run_command_to_procres(
|
let res = self.run_command_to_procres(
|
||||||
Command::new(self.config.jsondocck_path.as_ref().unwrap())
|
Command::new(self.config.jsondocck_path.as_ref().unwrap())
|
||||||
.arg("--doc-dir")
|
.arg("--doc-dir")
|
||||||
.arg(root.join(&out_dir))
|
.arg(&out_dir)
|
||||||
.arg("--template")
|
.arg("--template")
|
||||||
.arg(&self.testpaths.file),
|
.arg(&self.testpaths.file),
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
(&1_u8 as *const u8).offset_from(&2_u8); //~ERROR: not both derived from the same allocation
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
error: Undefined Behavior: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
|
||||||
|
--> tests/fail/intrinsics/ptr_offset_from_different_allocs.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | (&1_u8 as *const u8).offset_from(&2_u8);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
|
||||||
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
= note: BACKTRACE:
|
||||||
|
= note: inside `main` at tests/fail/intrinsics/ptr_offset_from_different_allocs.rs:LL:CC
|
||||||
|
|
||||||
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -15,6 +15,6 @@ fn main() {
|
||||||
let _ = p1.byte_offset_from(p1);
|
let _ = p1.byte_offset_from(p1);
|
||||||
|
|
||||||
// UB because different pointers.
|
// UB because different pointers.
|
||||||
let _ = p1.byte_offset_from(p2); //~ERROR: no provenance
|
let _ = p1.byte_offset_from(p2); //~ERROR: not both derived from the same allocation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: out-of-bounds `offset_from` origin: expected a pointer to the end of 1 byte of memory, but got 0xb[noalloc] which is a dangling pointer (it has no provenance)
|
error: Undefined Behavior: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
|
||||||
--> tests/fail/intrinsics/ptr_offset_from_different_ints.rs:LL:CC
|
--> tests/fail/intrinsics/ptr_offset_from_different_ints.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let _ = p1.byte_offset_from(p2);
|
LL | let _ = p1.byte_offset_from(p2);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of 1 byte of memory, but got 0xb[noalloc] which is a dangling pointer (it has no provenance)
|
| ^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
|
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
fn main() {
|
||||||
|
let mem = [0u8; 1];
|
||||||
|
let ptr = mem.as_ptr();
|
||||||
|
unsafe {
|
||||||
|
ptr.wrapping_add(4).offset_from(ptr); //~ERROR: the memory range between them is not in-bounds of an allocation
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
error: Undefined Behavior: `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
|
||||||
|
--> tests/fail/intrinsics/ptr_offset_from_oob.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | ptr.wrapping_add(4).offset_from(ptr);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
|
||||||
|
|
|
||||||
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
= note: BACKTRACE:
|
||||||
|
= note: inside `main` at tests/fail/intrinsics/ptr_offset_from_oob.rs:LL:CC
|
||||||
|
|
||||||
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -58,35 +58,35 @@ static mut Z: u64 = 0;
|
||||||
// Currently, only MIPS and RISCV successfully put any objects in the small data
|
// Currently, only MIPS and RISCV successfully put any objects in the small data
|
||||||
// sections so the U/V/W/X tests are skipped on Hexagon and M68K
|
// sections so the U/V/W/X tests are skipped on Hexagon and M68K
|
||||||
|
|
||||||
//@ RISCV: .section .sdata
|
// RISCV: .section .sdata
|
||||||
//@ RISCV-NOT: .section
|
// RISCV-NOT: .section
|
||||||
//@ RISCV: U:
|
// RISCV: U:
|
||||||
//@ RISCV: .section .sbss
|
// RISCV: .section .sbss
|
||||||
//@ RISCV-NOT: .section
|
// RISCV-NOT: .section
|
||||||
//@ RISCV: V:
|
// RISCV: V:
|
||||||
//@ RISCV: .section .sdata
|
// RISCV: .section .sdata
|
||||||
//@ RISCV-NOT: .section
|
// RISCV-NOT: .section
|
||||||
//@ RISCV: W:
|
// RISCV: W:
|
||||||
//@ RISCV: .section .sbss
|
// RISCV: .section .sbss
|
||||||
//@ RISCV-NOT: .section
|
// RISCV-NOT: .section
|
||||||
//@ RISCV: X:
|
// RISCV: X:
|
||||||
|
|
||||||
//@ MIPS: .section .sdata
|
// MIPS: .section .sdata
|
||||||
//@ MIPS-NOT: .section
|
// MIPS-NOT: .section
|
||||||
//@ MIPS: U:
|
// MIPS: U:
|
||||||
//@ MIPS: .section .sbss
|
// MIPS: .section .sbss
|
||||||
//@ MIPS-NOT: .section
|
// MIPS-NOT: .section
|
||||||
//@ MIPS: V:
|
// MIPS: V:
|
||||||
//@ MIPS: .section .sdata
|
// MIPS: .section .sdata
|
||||||
//@ MIPS-NOT: .section
|
// MIPS-NOT: .section
|
||||||
//@ MIPS: W:
|
// MIPS: W:
|
||||||
//@ MIPS: .section .sbss
|
// MIPS: .section .sbss
|
||||||
//@ MIPS-NOT: .section
|
// MIPS-NOT: .section
|
||||||
//@ MIPS: X:
|
// MIPS: X:
|
||||||
|
|
||||||
//@ CHECK: .section .data.Y,
|
// CHECK: .section .data.Y,
|
||||||
//@ CHECK-NOT: .section
|
// CHECK-NOT: .section
|
||||||
//@ CHECK: Y:
|
// CHECK: Y:
|
||||||
//@ CHECK: .section .bss.Z,
|
// CHECK: .section .bss.Z,
|
||||||
//@ CHECK-NOT: .section
|
// CHECK-NOT: .section
|
||||||
//@ CHECK: Z:
|
// CHECK: Z:
|
||||||
|
|
|
@ -190,7 +190,7 @@ LL | from_ptr_range(ptr..ptr.add(1))
|
||||||
error[E0080]: could not evaluate static initializer
|
error[E0080]: could not evaluate static initializer
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
= note: `ptr_offset_from_unsigned` called on pointers into different allocations
|
= note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
|
|
||||||
note: inside `std::ptr::const_ptr::<impl *const u32>::sub_ptr`
|
note: inside `std::ptr::const_ptr::<impl *const u32>::sub_ptr`
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
@ -205,7 +205,7 @@ LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).ad
|
||||||
error[E0080]: could not evaluate static initializer
|
error[E0080]: could not evaluate static initializer
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
= note: `ptr_offset_from_unsigned` called on pointers into different allocations
|
= note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
|
|
||||||
note: inside `std::ptr::const_ptr::<impl *const u32>::sub_ptr`
|
note: inside `std::ptr::const_ptr::<impl *const u32>::sub_ptr`
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub const DIFFERENT_ALLOC: usize = {
|
||||||
let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
|
let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
|
||||||
let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct;
|
let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct;
|
||||||
let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; //~ERROR evaluation of constant value failed
|
let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; //~ERROR evaluation of constant value failed
|
||||||
//~| pointers into different allocations
|
//~| not both derived from the same allocation
|
||||||
offset as usize
|
offset as usize
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ pub const DIFFERENT_INT: isize = { // offset_from with two different integers: l
|
||||||
let ptr1 = 8 as *const u8;
|
let ptr1 = 8 as *const u8;
|
||||||
let ptr2 = 16 as *const u8;
|
let ptr2 = 16 as *const u8;
|
||||||
unsafe { ptr_offset_from(ptr2, ptr1) } //~ERROR evaluation of constant value failed
|
unsafe { ptr_offset_from(ptr2, ptr1) } //~ERROR evaluation of constant value failed
|
||||||
//~| dangling pointer
|
//~| not both derived from the same allocation
|
||||||
};
|
};
|
||||||
|
|
||||||
const OUT_OF_BOUNDS_1: isize = {
|
const OUT_OF_BOUNDS_1: isize = {
|
||||||
|
@ -46,7 +46,7 @@ const OUT_OF_BOUNDS_1: isize = {
|
||||||
let end_ptr = (start_ptr).wrapping_add(length);
|
let end_ptr = (start_ptr).wrapping_add(length);
|
||||||
// First ptr is out of bounds
|
// First ptr is out of bounds
|
||||||
unsafe { ptr_offset_from(end_ptr, start_ptr) } //~ERROR evaluation of constant value failed
|
unsafe { ptr_offset_from(end_ptr, start_ptr) } //~ERROR evaluation of constant value failed
|
||||||
//~| expected a pointer to 10 bytes of memory
|
//~| the memory range between them is not in-bounds of an allocation
|
||||||
};
|
};
|
||||||
|
|
||||||
const OUT_OF_BOUNDS_2: isize = {
|
const OUT_OF_BOUNDS_2: isize = {
|
||||||
|
@ -55,7 +55,7 @@ const OUT_OF_BOUNDS_2: isize = {
|
||||||
let end_ptr = (start_ptr).wrapping_add(length);
|
let end_ptr = (start_ptr).wrapping_add(length);
|
||||||
// Second ptr is out of bounds
|
// Second ptr is out of bounds
|
||||||
unsafe { ptr_offset_from(start_ptr, end_ptr) } //~ERROR evaluation of constant value failed
|
unsafe { ptr_offset_from(start_ptr, end_ptr) } //~ERROR evaluation of constant value failed
|
||||||
//~| expected a pointer to the end of 10 bytes of memory
|
//~| the memory range between them is not in-bounds of an allocation
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DIFFERENT_ALLOC_UNSIGNED: usize = {
|
pub const DIFFERENT_ALLOC_UNSIGNED: usize = {
|
||||||
|
@ -64,7 +64,7 @@ pub const DIFFERENT_ALLOC_UNSIGNED: usize = {
|
||||||
let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
|
let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
|
||||||
let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct;
|
let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct;
|
||||||
unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } //~ERROR evaluation of constant value failed
|
unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } //~ERROR evaluation of constant value failed
|
||||||
//~| pointers into different allocations
|
//~| not both derived from the same allocation
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const TOO_FAR_APART1: isize = {
|
pub const TOO_FAR_APART1: isize = {
|
||||||
|
|
|
@ -2,12 +2,12 @@ error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:19:27
|
--> $DIR/offset_from_ub.rs:19:27
|
||||||
|
|
|
|
||||||
LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) };
|
LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on pointers into different allocations
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
= note: `ptr_offset_from` called on pointers into different allocations
|
= note: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
|
|
||||||
note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
|
note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
@ -27,25 +27,25 @@ error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:39:14
|
--> $DIR/offset_from_ub.rs:39:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(ptr2, ptr1) }
|
LL | unsafe { ptr_offset_from(ptr2, ptr1) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got 0x8[noalloc] which is a dangling pointer (it has no provenance)
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:48:14
|
--> $DIR/offset_from_ub.rs:48:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(end_ptr, start_ptr) }
|
LL | unsafe { ptr_offset_from(end_ptr, start_ptr) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got ALLOC0 which is only $BYTES bytes from the end of the allocation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:57:14
|
--> $DIR/offset_from_ub.rs:57:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(start_ptr, end_ptr) }
|
LL | unsafe { ptr_offset_from(start_ptr, end_ptr) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of $BYTES bytes of memory, but got ALLOC1+0xa which does not have enough space to the beginning of the allocation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:66:14
|
--> $DIR/offset_from_ub.rs:66:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }
|
LL | unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:73:14
|
--> $DIR/offset_from_ub.rs:73:14
|
||||||
|
@ -80,7 +80,7 @@ LL | unsafe { ptr_offset_from_unsigned(ptr2, ptr1) }
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
= note: out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got a null pointer
|
= note: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
|
||||||
|
|
|
|
||||||
note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
|
note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
9
tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs
Normal file
9
tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//! Ensure that we check generic parameter defaults for well-formedness at the definition site.
|
||||||
|
#![feature(lazy_type_alias)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
type Alias<T = Vec<str>, const N: usize = {0 - 1}> = T;
|
||||||
|
//~^ ERROR evaluation of constant value failed
|
||||||
|
//~| ERROR the size for values of type `str` cannot be known at compilation time
|
||||||
|
|
||||||
|
fn main() {}
|
20
tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr
Normal file
20
tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/def-site-param-defaults-wf.rs:5:44
|
||||||
|
|
|
||||||
|
LL | type Alias<T = Vec<str>, const N: usize = {0 - 1}> = T;
|
||||||
|
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
|
--> $DIR/def-site-param-defaults-wf.rs:5:16
|
||||||
|
|
|
||||||
|
LL | type Alias<T = Vec<str>, const N: usize = {0 - 1}> = T;
|
||||||
|
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
note: required by an implicit `Sized` bound in `Vec`
|
||||||
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0080, E0277.
|
||||||
|
For more information about an error, try `rustc --explain E0080`.
|
13
tests/ui/lazy-type-alias/def-site-predicates-wf.rs
Normal file
13
tests/ui/lazy-type-alias/def-site-predicates-wf.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//! Ensure that we check the predicates at the definition site for well-formedness.
|
||||||
|
#![feature(lazy_type_alias)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
type Alias0 = ()
|
||||||
|
where
|
||||||
|
Vec<str>:; //~ ERROR the size for values of type `str` cannot be known at compilation time
|
||||||
|
|
||||||
|
type Alias1 = ()
|
||||||
|
where
|
||||||
|
Vec<str>: Sized; //~ ERROR the size for values of type `str` cannot be known at compilation time
|
||||||
|
|
||||||
|
fn main() {}
|
23
tests/ui/lazy-type-alias/def-site-predicates-wf.stderr
Normal file
23
tests/ui/lazy-type-alias/def-site-predicates-wf.stderr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
|
--> $DIR/def-site-predicates-wf.rs:7:5
|
||||||
|
|
|
||||||
|
LL | Vec<str>:;
|
||||||
|
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
note: required by an implicit `Sized` bound in `Vec`
|
||||||
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
|
--> $DIR/def-site-predicates-wf.rs:11:15
|
||||||
|
|
|
||||||
|
LL | Vec<str>: Sized;
|
||||||
|
| ^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
note: required by an implicit `Sized` bound in `Vec`
|
||||||
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue