Auto merge of #91902 - matthiaskrgr:rollup-hjjyhow, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #91529 (add BinaryHeap::try_reserve and BinaryHeap::try_reserve_exact)
 - #91820 (Suggest to specify a target triple when lang item is missing)
 - #91851 (Make `MaybeUninit::zeroed` `const`)
 - #91875 (Use try_normalize_erasing_regions in RevealAllVisitor)
 - #91887 (Remove `in_band_lifetimes` from `rustc_const_eval`)
 - #91892 (Fix HashStable implementation on InferTy)
 - #91893 (Remove `in_band_lifetimes` from `rustc_hir`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-12-14 11:30:17 +00:00
commit 404c8471ab
31 changed files with 271 additions and 98 deletions

View File

@ -423,14 +423,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
}
#[inline(always)]
fn stack(
fn stack<'a>(
ecx: &'a InterpCx<'mir, 'tcx, Self>,
) -> &'a [Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>] {
&ecx.machine.stack
}
#[inline(always)]
fn stack_mut(
fn stack_mut<'a>(
ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>> {
&mut ecx.machine.stack

View File

@ -25,9 +25,9 @@ pub use fn_queries::*;
pub use machine::*;
pub(crate) fn const_caller_location(
tcx: TyCtxt<'tcx>,
tcx: TyCtxt<'_>,
(file, line, col): (Symbol, u32, u32),
) -> ConstValue<'tcx> {
) -> ConstValue<'_> {
trace!("const_caller_location: {}:{}:{}", file, line, col);
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), false);

View File

@ -935,7 +935,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
#[must_use]
pub fn dump_place(&'a self, place: Place<M::PointerTag>) -> PlacePrinter<'a, 'mir, 'tcx, M> {
pub fn dump_place(&self, place: Place<M::PointerTag>) -> PlacePrinter<'_, 'mir, 'tcx, M> {
PlacePrinter { ecx: self, place }
}

View File

@ -292,14 +292,15 @@ pub enum InternKind {
/// Any errors here would anyway be turned into `const_err` lints, whereas validation failures
/// are hard errors.
#[tracing::instrument(level = "debug", skip(ecx))]
pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx, const_eval::MemoryKind>>(
pub fn intern_const_alloc_recursive<
'mir,
'tcx: 'mir,
M: CompileTimeMachine<'mir, 'tcx, const_eval::MemoryKind>,
>(
ecx: &mut InterpCx<'mir, 'tcx, M>,
intern_kind: InternKind,
ret: &MPlaceTy<'tcx>,
) -> Result<(), ErrorReported>
where
'tcx: 'mir,
{
) -> Result<(), ErrorReported> {
let tcx = ecx.tcx;
let base_intern_mode = match intern_kind {
InternKind::Static(mutbl) => InternMode::Static(mutbl),

View File

@ -148,7 +148,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
}
}
impl PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> {
impl<'tcx> PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> {
fn region_should_not_be_omitted(&self, _region: ty::Region<'_>) -> bool {
false
}

View File

@ -374,12 +374,12 @@ pub trait Machine<'mir, 'tcx>: Sized {
) -> InterpResult<'tcx, Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>>;
/// Borrow the current thread's stack.
fn stack(
fn stack<'a>(
ecx: &'a InterpCx<'mir, 'tcx, Self>,
) -> &'a [Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>];
/// Mutably borrow the current thread's stack.
fn stack_mut(
fn stack_mut<'a>(
ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>>;

View File

@ -106,7 +106,7 @@ pub struct ImmTy<'tcx, Tag: Provenance = AllocId> {
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ImmTy<'_>, 72);
impl<Tag: Provenance> std::fmt::Display for ImmTy<'tcx, Tag> {
impl<Tag: Provenance> std::fmt::Display for ImmTy<'_, Tag> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// Helper function for printing a scalar to a FmtPrinter
fn p<'a, 'tcx, F: std::fmt::Write, Tag: Provenance>(

View File

@ -150,7 +150,7 @@ impl<Tag: Provenance> MemPlace<Tag> {
}
#[inline]
pub fn offset(
pub fn offset<'tcx>(
self,
offset: Size,
meta: MemPlaceMeta<Tag>,
@ -420,7 +420,7 @@ where
// Iterates over all fields of an array. Much more efficient than doing the
// same by repeatedly calling `mplace_array`.
pub(super) fn mplace_array_fields(
pub(super) fn mplace_array_fields<'a>(
&self,
base: &'a MPlaceTy<'tcx, Tag>,
) -> InterpResult<'tcx, impl Iterator<Item = InterpResult<'tcx, MPlaceTy<'tcx, Tag>>> + 'a>

View File

@ -11,7 +11,6 @@ Rust MIR: a lowered representation of Rust.
#![feature(crate_visibility_modifier)]
#![feature(decl_macro)]
#![feature(exact_size_is_empty)]
#![feature(in_band_lifetimes)]
#![feature(iter_zip)]
#![feature(let_else)]
#![feature(map_try_insert)]

View File

@ -35,7 +35,7 @@ pub struct Qualifs<'mir, 'tcx> {
needs_non_const_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
}
impl Qualifs<'mir, 'tcx> {
impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
/// Returns `true` if `local` is `NeedsDrop` at the given `Location`.
///
/// Only updates the cursor if absolutely necessary
@ -185,7 +185,7 @@ pub struct Checker<'mir, 'tcx> {
secondary_errors: Vec<Diagnostic>,
}
impl Deref for Checker<'mir, 'tcx> {
impl<'mir, 'tcx> Deref for Checker<'mir, 'tcx> {
type Target = ConstCx<'mir, 'tcx>;
fn deref(&self) -> &Self::Target {
@ -193,7 +193,7 @@ impl Deref for Checker<'mir, 'tcx> {
}
}
impl Checker<'mir, 'tcx> {
impl<'mir, 'tcx> Checker<'mir, 'tcx> {
pub fn new(ccx: &'mir ConstCx<'mir, 'tcx>) -> Self {
Checker {
span: ccx.body.span,
@ -273,7 +273,7 @@ impl Checker<'mir, 'tcx> {
struct StorageDeads {
locals: BitSet<Local>,
}
impl Visitor<'tcx> for StorageDeads {
impl<'tcx> Visitor<'tcx> for StorageDeads {
fn visit_statement(&mut self, stmt: &Statement<'tcx>, _: Location) {
if let StatementKind::StorageDead(l) = stmt.kind {
self.locals.insert(l);
@ -460,7 +460,7 @@ impl Checker<'mir, 'tcx> {
}
}
impl Visitor<'tcx> for Checker<'mir, 'tcx> {
impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
fn visit_basic_block_data(&mut self, bb: BasicBlock, block: &BasicBlockData<'tcx>) {
trace!("visit_basic_block_data: bb={:?} is_cleanup={:?}", bb, block.is_cleanup);
@ -1042,7 +1042,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
}
}
fn place_as_reborrow(
fn place_as_reborrow<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
place: Place<'tcx>,

View File

@ -28,7 +28,7 @@ pub struct ConstCx<'mir, 'tcx> {
pub const_kind: Option<hir::ConstContext>,
}
impl ConstCx<'mir, 'tcx> {
impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self {
let def_id = body.source.def_id().expect_local();
let param_env = tcx.param_env(def_id);
@ -72,11 +72,7 @@ impl ConstCx<'mir, 'tcx> {
}
}
pub fn rustc_allow_const_fn_unstable(
tcx: TyCtxt<'tcx>,
def_id: DefId,
feature_gate: Symbol,
) -> bool {
pub fn rustc_allow_const_fn_unstable(tcx: TyCtxt<'_>, def_id: DefId, feature_gate: Symbol) -> bool {
let attrs = tcx.get_attrs(def_id);
attr::rustc_allow_const_fn_unstable(&tcx.sess, attrs).any(|name| name == feature_gate)
}
@ -89,7 +85,7 @@ pub fn rustc_allow_const_fn_unstable(
// functions can be called in a const-context by users of the stable compiler. "const-stable"
// functions are subject to more stringent restrictions than "const-unstable" functions: They
// cannot use unstable features and can only call other "const-stable" functions.
pub fn is_const_stable_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
use attr::{ConstStability, Stability, StabilityLevel};
// A default body marked const is not const-stable because const

View File

@ -39,7 +39,7 @@ pub trait NonConstOp: std::fmt::Debug {
DiagnosticImportance::Primary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>;
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>;
}
#[derive(Debug)]
@ -53,7 +53,7 @@ impl NonConstOp for FloatingPointOp {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_floating_point_arithmetic,
@ -67,7 +67,7 @@ impl NonConstOp for FloatingPointOp {
#[derive(Debug)]
pub struct FnCallIndirect;
impl NonConstOp for FnCallIndirect {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn")
}
}
@ -76,7 +76,7 @@ impl NonConstOp for FnCallIndirect {
#[derive(Debug)]
pub struct FnCallNonConst<'tcx>(pub Option<(DefId, SubstsRef<'tcx>)>);
impl<'a> NonConstOp for FnCallNonConst<'a> {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -149,7 +149,7 @@ impl<'a> NonConstOp for FnCallNonConst<'a> {
pub struct FnCallUnstable(pub DefId, pub Option<Symbol>);
impl NonConstOp for FnCallUnstable {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let FnCallUnstable(def_id, feature) = *self;
let mut err = ccx.tcx.sess.struct_span_err(
@ -183,7 +183,7 @@ impl NonConstOp for FnPtrCast {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_fn_ptr_basics,
@ -204,7 +204,7 @@ impl NonConstOp for Generator {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind());
if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 {
feature_err(&ccx.tcx.sess.parse_sess, sym::const_async_blocks, span, &msg)
@ -217,7 +217,7 @@ impl NonConstOp for Generator {
#[derive(Debug)]
pub struct HeapAllocation;
impl NonConstOp for HeapAllocation {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -241,7 +241,7 @@ impl NonConstOp for HeapAllocation {
#[derive(Debug)]
pub struct InlineAsm;
impl NonConstOp for InlineAsm {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
struct_span_err!(
ccx.tcx.sess,
span,
@ -257,7 +257,7 @@ pub struct LiveDrop {
pub dropped_at: Option<Span>,
}
impl NonConstOp for LiveDrop {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -285,7 +285,7 @@ impl NonConstOp for TransientCellBorrow {
// not additionally emit a feature gate error if activating the feature gate won't work.
DiagnosticImportance::Secondary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_refs_to_cell,
@ -301,7 +301,7 @@ impl NonConstOp for TransientCellBorrow {
/// it in the future for static items.
pub struct CellBorrow;
impl NonConstOp for CellBorrow {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -348,7 +348,7 @@ impl NonConstOp for MutBorrow {
DiagnosticImportance::Secondary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let raw = match self.0 {
hir::BorrowKind::Raw => "raw ",
hir::BorrowKind::Ref => "",
@ -387,7 +387,7 @@ impl NonConstOp for TransientMutBorrow {
Status::Unstable(sym::const_mut_refs)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let raw = match self.0 {
hir::BorrowKind::Raw => "raw ",
hir::BorrowKind::Ref => "",
@ -414,7 +414,7 @@ impl NonConstOp for MutDeref {
DiagnosticImportance::Secondary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
@ -428,7 +428,7 @@ impl NonConstOp for MutDeref {
#[derive(Debug)]
pub struct PanicNonStr;
impl NonConstOp for PanicNonStr {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
ccx.tcx.sess.struct_span_err(
span,
"argument to `panic!()` in a const context must have type `&str`",
@ -442,7 +442,7 @@ impl NonConstOp for PanicNonStr {
#[derive(Debug)]
pub struct RawPtrComparison;
impl NonConstOp for RawPtrComparison {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let mut err = ccx
.tcx
.sess
@ -462,7 +462,7 @@ impl NonConstOp for RawMutPtrDeref {
Status::Unstable(sym::const_mut_refs)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
@ -478,7 +478,7 @@ impl NonConstOp for RawMutPtrDeref {
#[derive(Debug)]
pub struct RawPtrToIntCast;
impl NonConstOp for RawPtrToIntCast {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let mut err = ccx
.tcx
.sess
@ -503,7 +503,7 @@ impl NonConstOp for StaticAccess {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -529,7 +529,7 @@ impl NonConstOp for StaticAccess {
#[derive(Debug)]
pub struct ThreadLocalAccess;
impl NonConstOp for ThreadLocalAccess {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
struct_span_err!(
ccx.tcx.sess,
span,
@ -560,7 +560,11 @@ pub mod ty {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
@ -590,7 +594,11 @@ pub mod ty {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_fn_ptr_basics,
@ -607,7 +615,11 @@ pub mod ty {
Status::Unstable(sym::const_impl_trait)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_impl_trait,
@ -637,7 +649,11 @@ pub mod ty {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx> {
let mut err = feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_trait_bound,
@ -676,7 +692,11 @@ pub mod ty {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx> {
let mut err = feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_trait_bound,
@ -703,7 +723,11 @@ pub mod ty {
Status::Unstable(sym::const_trait_bound_opt_out)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error<'tcx>(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_trait_bound_opt_out,

View File

@ -23,7 +23,7 @@ pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool {
///
/// This is separate from the rest of the const checking logic because it must run after drop
/// elaboration.
pub fn check_live_drops(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
let def_id = body.source.def_id().expect_local();
let const_kind = tcx.hir().body_const_context(def_id);
if const_kind.is_none() {
@ -50,7 +50,7 @@ struct CheckLiveDrops<'mir, 'tcx> {
}
// So we can access `body` and `tcx`.
impl std::ops::Deref for CheckLiveDrops<'mir, 'tcx> {
impl<'mir, 'tcx> std::ops::Deref for CheckLiveDrops<'mir, 'tcx> {
type Target = ConstCx<'mir, 'tcx>;
fn deref(&self) -> &Self::Target {
@ -58,13 +58,13 @@ impl std::ops::Deref for CheckLiveDrops<'mir, 'tcx> {
}
}
impl CheckLiveDrops<'mir, 'tcx> {
impl CheckLiveDrops<'_, '_> {
fn check_live_drop(&self, span: Span) {
ops::LiveDrop { dropped_at: None }.build_error(self.ccx, span).emit();
}
}
impl Visitor<'tcx> for CheckLiveDrops<'mir, 'tcx> {
impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
fn visit_basic_block_data(&mut self, bb: BasicBlock, block: &mir::BasicBlockData<'tcx>) {
trace!("visit_basic_block_data: bb={:?} is_cleanup={:?}", bb, block.is_cleanup);

View File

@ -13,7 +13,7 @@ use rustc_trait_selection::traits::{
use super::ConstCx;
pub fn in_any_value_of_ty(
pub fn in_any_value_of_ty<'tcx>(
cx: &ConstCx<'_, 'tcx>,
ty: Ty<'tcx>,
error_occured: Option<ErrorReported>,
@ -58,7 +58,7 @@ pub trait Qualif {
/// from a call to another function.
///
/// It also determines the `Qualif`s for primitive types.
fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool;
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool;
/// Returns `true` if this `Qualif` is inherent to the given struct or enum.
///
@ -68,7 +68,7 @@ pub trait Qualif {
/// with a custom `Drop` impl is inherently `NeedsDrop`.
///
/// Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound.
fn in_adt_inherently(
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef,
substs: SubstsRef<'tcx>,
@ -89,11 +89,15 @@ impl Qualif for HasMutInterior {
qualifs.has_mut_interior
}
fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
!ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env)
}
fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tcx>) -> bool {
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef,
_: SubstsRef<'tcx>,
) -> bool {
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
// It arises structurally for all other types.
Some(adt.did) == cx.tcx.lang_items().unsafe_cell_type()
@ -115,11 +119,15 @@ impl Qualif for NeedsDrop {
qualifs.needs_drop
}
fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
ty.needs_drop(cx.tcx, cx.param_env)
}
fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tcx>) -> bool {
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef,
_: SubstsRef<'tcx>,
) -> bool {
adt.has_dtor(cx.tcx)
}
}
@ -137,7 +145,7 @@ impl Qualif for NeedsNonConstDrop {
qualifs.needs_non_const_drop
}
fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, mut ty: Ty<'tcx>) -> bool {
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, mut ty: Ty<'tcx>) -> bool {
// Avoid selecting for simple cases.
match ty::util::needs_drop_components(ty, &cx.tcx.data_layout).as_deref() {
Ok([]) => return false,
@ -177,7 +185,11 @@ impl Qualif for NeedsNonConstDrop {
)
}
fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tcx>) -> bool {
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef,
_: SubstsRef<'tcx>,
) -> bool {
adt.has_non_const_dtor(cx.tcx)
}
}
@ -192,7 +204,7 @@ impl Qualif for CustomEq {
qualifs.custom_eq
}
fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
// If *any* component of a composite data type does not implement `Structural{Partial,}Eq`,
// we know that at least some values of that type are not structural-match. I say "some"
// because that component may be part of an enum variant (e.g.,
@ -202,7 +214,7 @@ impl Qualif for CustomEq {
traits::search_for_structural_match_violation(id, cx.body.span, cx.tcx, ty).is_some()
}
fn in_adt_inherently(
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef,
substs: SubstsRef<'tcx>,
@ -215,7 +227,11 @@ impl Qualif for CustomEq {
// FIXME: Use `mir::visit::Visitor` for the `in_*` functions if/when it supports early return.
/// Returns `true` if this `Rvalue` contains qualif `Q`.
pub fn in_rvalue<Q, F>(cx: &ConstCx<'_, 'tcx>, in_local: &mut F, rvalue: &Rvalue<'tcx>) -> bool
pub fn in_rvalue<'tcx, Q, F>(
cx: &ConstCx<'_, 'tcx>,
in_local: &mut F,
rvalue: &Rvalue<'tcx>,
) -> bool
where
Q: Qualif,
F: FnMut(Local) -> bool,
@ -270,7 +286,7 @@ where
}
/// Returns `true` if this `Place` contains qualif `Q`.
pub fn in_place<Q, F>(cx: &ConstCx<'_, 'tcx>, in_local: &mut F, place: PlaceRef<'tcx>) -> bool
pub fn in_place<'tcx, Q, F>(cx: &ConstCx<'_, 'tcx>, in_local: &mut F, place: PlaceRef<'tcx>) -> bool
where
Q: Qualif,
F: FnMut(Local) -> bool,
@ -302,7 +318,11 @@ where
}
/// Returns `true` if this `Operand` contains qualif `Q`.
pub fn in_operand<Q, F>(cx: &ConstCx<'_, 'tcx>, in_local: &mut F, operand: &Operand<'tcx>) -> bool
pub fn in_operand<'tcx, Q, F>(
cx: &ConstCx<'_, 'tcx>,
in_local: &mut F,
operand: &Operand<'tcx>,
) -> bool
where
Q: Qualif,
F: FnMut(Local) -> bool,

View File

@ -28,7 +28,7 @@ struct TransferFunction<'a, 'mir, 'tcx, Q> {
_qualif: PhantomData<Q>,
}
impl<Q> TransferFunction<'a, 'mir, 'tcx, Q>
impl<'a, 'mir, 'tcx, Q> TransferFunction<'a, 'mir, 'tcx, Q>
where
Q: Qualif,
{
@ -127,7 +127,7 @@ where
}
}
impl<Q> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx, Q>
impl<'tcx, Q> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx, Q>
where
Q: Qualif,
{
@ -330,7 +330,7 @@ impl JoinSemiLattice for State {
}
}
impl<Q> AnalysisDomain<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q>
impl<'tcx, Q> AnalysisDomain<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q>
where
Q: Qualif,
{
@ -350,7 +350,7 @@ where
}
}
impl<Q> Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q>
impl<'tcx, Q> Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q>
where
Q: Qualif,
{

View File

@ -168,8 +168,8 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
}
}
pub fn collect_temps_and_candidates(
ccx: &ConstCx<'mir, 'tcx>,
pub fn collect_temps_and_candidates<'tcx>(
ccx: &ConstCx<'_, 'tcx>,
rpo: &mut ReversePostorder<'_, 'tcx>,
) -> (IndexVec<Local, TempState>, Vec<Candidate>) {
let mut collector = Collector {
@ -191,7 +191,7 @@ struct Validator<'a, 'tcx> {
temps: &'a IndexVec<Local, TempState>,
}
impl std::ops::Deref for Validator<'a, 'tcx> {
impl<'a, 'tcx> std::ops::Deref for Validator<'a, 'tcx> {
type Target = ConstCx<'a, 'tcx>;
fn deref(&self) -> &Self::Target {

View File

@ -66,7 +66,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
///
/// The point of this function is to approximate "equal up to subtyping". However,
/// the approximation is incorrect as variance is ignored.
pub fn equal_up_to_regions(
pub fn equal_up_to_regions<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
src: Ty<'tcx>,

View File

@ -522,7 +522,7 @@ pub struct GenericParam<'hir> {
pub kind: GenericParamKind<'hir>,
}
impl GenericParam<'hir> {
impl<'hir> GenericParam<'hir> {
pub fn bounds_span_for_suggestions(&self) -> Option<Span> {
self.bounds
.iter()
@ -557,7 +557,7 @@ pub struct Generics<'hir> {
pub span: Span,
}
impl Generics<'hir> {
impl<'hir> Generics<'hir> {
pub const fn empty() -> Generics<'hir> {
Generics {
params: &[],
@ -622,7 +622,7 @@ pub enum WherePredicate<'hir> {
EqPredicate(WhereEqPredicate<'hir>),
}
impl WherePredicate<'_> {
impl<'hir> WherePredicate<'hir> {
pub fn span(&self) -> Span {
match self {
WherePredicate::BoundPredicate(p) => p.span,
@ -644,7 +644,7 @@ pub struct WhereBoundPredicate<'hir> {
pub bounds: GenericBounds<'hir>,
}
impl WhereBoundPredicate<'hir> {
impl<'hir> WhereBoundPredicate<'hir> {
/// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
let path = match self.bounded_ty.kind {
@ -1236,7 +1236,7 @@ pub struct Body<'hir> {
pub generator_kind: Option<GeneratorKind>,
}
impl Body<'hir> {
impl<'hir> Body<'hir> {
pub fn id(&self) -> BodyId {
BodyId { hir_id: self.value.hir_id }
}
@ -2623,7 +2623,7 @@ pub enum VariantData<'hir> {
Unit(HirId),
}
impl VariantData<'hir> {
impl<'hir> VariantData<'hir> {
/// Return the fields of this variant.
pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
match *self {

View File

@ -139,7 +139,7 @@ pub trait Map<'hir> {
}
// Used when no map is actually available, forcing manual implementation of nested visitors.
impl Map<'hir> for ! {
impl<'hir> Map<'hir> for ! {
fn find(&self, _: HirId) -> Option<Node<'hir>> {
unreachable!()
}

View File

@ -4,7 +4,6 @@
#![feature(const_btree_new)]
#![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)]
#![feature(once_cell)]
#![feature(min_specialization)]
#![feature(never_type)]

View File

@ -211,7 +211,7 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Item<'_> {
}
}
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> {
impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
// We ignore the `nodes` and `bodies` fields since these refer to information included in
// `hash` which is hashed in the collector and used for the crate hash.
@ -221,7 +221,7 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> {
}
}
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap<'tcx> {
impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap<'tcx> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
// We ignore the `map` since it refers to information included in `hash` which is hashed in
// the collector and used for the crate hash.

View File

@ -36,6 +36,9 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
#[inline]
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
*ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
// We have to use `try_normalize_erasing_regions` here, since it's
// possible that we visit impossible-to-satisfy where clauses here,
// see #91745
*ty = self.tcx.try_normalize_erasing_regions(self.param_env, *ty).unwrap_or(ty);
}
}

View File

@ -67,10 +67,16 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
} else if item == LangItem::Oom {
if !tcx.features().default_alloc_error_handler {
tcx.sess.err("`#[alloc_error_handler]` function required, but not found");
tcx.sess.note_without_error("Use `#![feature(default_alloc_error_handler)]` for a default error handler");
tcx.sess.note_without_error("use `#![feature(default_alloc_error_handler)]` for a default error handler");
}
} else {
tcx.sess.err(&format!("language item required, but not found: `{}`", name));
tcx
.sess
.diagnostic()
.struct_err(&format!("language item required, but not found: `{}`", name))
.note(&format!("this can occur when a binary crate with `#![no_std]` is compiled for a target where `{}` is defined in the standard library", name))
.help(&format!("you may be able to compile for a target that doesn't need `{}`, specify a target with `--target` or in `.cargo/config`", name))
.emit();
}
}
}

View File

@ -559,6 +559,7 @@ impl<CTX> HashStable<CTX> for FloatTy {
impl<CTX> HashStable<CTX> for InferTy {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
use InferTy::*;
discriminant(self).hash_stable(ctx, hasher);
match self {
TyVar(v) => v.as_u32().hash_stable(ctx, hasher),
IntVar(v) => v.index.hash_stable(ctx, hasher),

View File

@ -149,6 +149,7 @@ use core::mem::{self, swap, ManuallyDrop};
use core::ops::{Deref, DerefMut};
use core::ptr;
use crate::collections::TryReserveError;
use crate::slice;
use crate::vec::{self, AsIntoIter, Vec};
@ -953,6 +954,84 @@ impl<T> BinaryHeap<T> {
self.data.reserve(additional);
}
/// Tries to reserve the minimum capacity for exactly `additional`
/// elements to be inserted in the given `BinaryHeap<T>`. After calling
/// `try_reserve_exact`, capacity will be greater than or equal to
/// `self.len() + additional` if it returns `Ok(())`.
/// Does nothing if the capacity is already sufficient.
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore, capacity can not be relied upon to be precisely
/// minimal. Prefer [`try_reserve`] if future insertions are expected.
///
/// [`try_reserve`]: BinaryHeap::try_reserve
///
/// # Errors
///
/// If the capacity overflows, or the allocator reports a failure, then an error
/// is returned.
///
/// # Examples
///
/// ```
/// #![feature(try_reserve_2)]
/// use std::collections::BinaryHeap;
/// use std::collections::TryReserveError;
///
/// fn find_max_slow(data: &[u32]) -> Result<Option<u32>, TryReserveError> {
/// let mut heap = BinaryHeap::new();
///
/// // Pre-reserve the memory, exiting if we can't
/// heap.try_reserve_exact(data.len())?;
///
/// // Now we know this can't OOM in the middle of our complex work
/// heap.extend(data.iter());
///
/// Ok(heap.pop())
/// }
/// # find_max_slow(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
/// ```
#[unstable(feature = "try_reserve_2", issue = "91789")]
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.data.try_reserve_exact(additional)
}
/// Tries to reserve capacity for at least `additional` more elements to be inserted
/// in the given `BinaryHeap<T>`. The collection may reserve more space to avoid
/// frequent reallocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional`. Does nothing if
/// capacity is already sufficient.
///
/// # Errors
///
/// If the capacity overflows, or the allocator reports a failure, then an error
/// is returned.
///
/// # Examples
///
/// ```
/// #![feature(try_reserve_2)]
/// use std::collections::BinaryHeap;
/// use std::collections::TryReserveError;
///
/// fn find_max_slow(data: &[u32]) -> Result<Option<u32>, TryReserveError> {
/// let mut heap = BinaryHeap::new();
///
/// // Pre-reserve the memory, exiting if we can't
/// heap.try_reserve(data.len())?;
///
/// // Now we know this can't OOM in the middle of our complex work
/// heap.extend(data.iter());
///
/// Ok(heap.pop())
/// }
/// # find_max_slow(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
/// ```
#[unstable(feature = "try_reserve_2", issue = "91789")]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.data.try_reserve(additional)
}
/// Discards as much additional capacity as possible.
///
/// # Examples

View File

@ -394,10 +394,11 @@ impl<T> MaybeUninit<T> {
/// // This is undefined behavior. ⚠️
/// ```
#[stable(feature = "maybe_uninit", since = "1.36.0")]
#[rustc_const_unstable(feature = "const_maybe_uninit_zeroed", issue = "91850")]
#[must_use]
#[inline]
#[rustc_diagnostic_item = "maybe_uninit_zeroed"]
pub fn zeroed() -> MaybeUninit<T> {
pub const fn zeroed() -> MaybeUninit<T> {
let mut u = MaybeUninit::<T>::uninit();
// SAFETY: `u.as_mut_ptr()` points to allocated memory.
unsafe {

View File

@ -1,6 +1,9 @@
error: extern location for std does not exist:
error: language item required, but not found: `eh_personality`
|
= note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
= help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`
error: `#[panic_handler]` function required, but not found

View File

@ -0,0 +1,21 @@
// check-pass
pub trait Foo {
type Bar;
}
pub trait Broken {
type Assoc;
fn broken(&self) where Self::Assoc: Foo;
}
impl<T> Broken for T {
type Assoc = ();
fn broken(&self) where Self::Assoc: Foo {
let _x: <Self::Assoc as Foo>::Bar;
}
}
fn main() {
let _m: &dyn Broken<Assoc=()> = &();
}

View File

@ -1,6 +1,6 @@
error: `#[alloc_error_handler]` function required, but not found
note: Use `#![feature(default_alloc_error_handler)]` for a default error handler
note: use `#![feature(default_alloc_error_handler)]` for a default error handler
error: aborting due to previous error

View File

@ -11,6 +11,9 @@ LL | extern crate core as other_core;
|
error: language item required, but not found: `eh_personality`
|
= note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
= help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`
error: `#[panic_handler]` function required, but not found

View File

@ -0,0 +1,17 @@
// check-pass
// incremental
struct Struct<T>(T);
impl<T> std::ops::Deref for Struct<T> {
type Target = dyn Fn(T);
fn deref(&self) -> &Self::Target {
unimplemented!()
}
}
fn main() {
let f = Struct(Default::default());
f(0);
f(0);
}