Auto merge of #98641 - lcnr:mir-dropck, r=oli-obk
fully move dropck to mir r? `@oli-obk`
This commit is contained in:
commit
a3beeaa84d
16 changed files with 79 additions and 124 deletions
|
@ -1,11 +1,11 @@
|
||||||
|
use itertools::{Either, Itertools};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_middle::mir::{Body, Local};
|
use rustc_middle::mir::{Body, Local};
|
||||||
use rustc_middle::ty::{RegionVid, TyCtxt};
|
use rustc_middle::ty::{RegionVid, TyCtxt};
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
|
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
|
||||||
use rustc_mir_dataflow::move_paths::MoveData;
|
use rustc_mir_dataflow::move_paths::MoveData;
|
||||||
use rustc_mir_dataflow::ResultsCursor;
|
use rustc_mir_dataflow::ResultsCursor;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
constraints::OutlivesConstraintSet,
|
constraints::OutlivesConstraintSet,
|
||||||
|
@ -46,7 +46,8 @@ pub(super) fn generate<'mir, 'tcx>(
|
||||||
&typeck.borrowck_context.universal_regions,
|
&typeck.borrowck_context.universal_regions,
|
||||||
&typeck.borrowck_context.constraints.outlives_constraints,
|
&typeck.borrowck_context.constraints.outlives_constraints,
|
||||||
);
|
);
|
||||||
let live_locals = compute_live_locals(typeck.tcx(), &free_regions, &body);
|
let (relevant_live_locals, boring_locals) =
|
||||||
|
compute_relevant_live_locals(typeck.tcx(), &free_regions, &body);
|
||||||
let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx());
|
let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx());
|
||||||
|
|
||||||
let polonius_drop_used = if facts_enabled {
|
let polonius_drop_used = if facts_enabled {
|
||||||
|
@ -57,48 +58,44 @@ pub(super) fn generate<'mir, 'tcx>(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if !live_locals.is_empty() || facts_enabled {
|
|
||||||
trace::trace(
|
trace::trace(
|
||||||
typeck,
|
typeck,
|
||||||
body,
|
body,
|
||||||
elements,
|
elements,
|
||||||
flow_inits,
|
flow_inits,
|
||||||
move_data,
|
move_data,
|
||||||
live_locals,
|
relevant_live_locals,
|
||||||
|
boring_locals,
|
||||||
polonius_drop_used,
|
polonius_drop_used,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The purpose of `compute_live_locals` is to define the subset of `Local`
|
// The purpose of `compute_relevant_live_locals` is to define the subset of `Local`
|
||||||
// variables for which we need to do a liveness computation. We only need
|
// variables for which we need to do a liveness computation. We only need
|
||||||
// to compute whether a variable `X` is live if that variable contains
|
// to compute whether a variable `X` is live if that variable contains
|
||||||
// some region `R` in its type where `R` is not known to outlive a free
|
// some region `R` in its type where `R` is not known to outlive a free
|
||||||
// region (i.e., where `R` may be valid for just a subset of the fn body).
|
// region (i.e., where `R` may be valid for just a subset of the fn body).
|
||||||
fn compute_live_locals<'tcx>(
|
fn compute_relevant_live_locals<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
free_regions: &FxHashSet<RegionVid>,
|
free_regions: &FxHashSet<RegionVid>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
) -> Vec<Local> {
|
) -> (Vec<Local>, Vec<Local>) {
|
||||||
let live_locals: Vec<Local> = body
|
let (boring_locals, relevant_live_locals): (Vec<_>, Vec<_>) =
|
||||||
.local_decls
|
body.local_decls.iter_enumerated().partition_map(|(local, local_decl)| {
|
||||||
.iter_enumerated()
|
|
||||||
.filter_map(|(local, local_decl)| {
|
|
||||||
if tcx.all_free_regions_meet(&local_decl.ty, |r| {
|
if tcx.all_free_regions_meet(&local_decl.ty, |r| {
|
||||||
free_regions.contains(&r.to_region_vid())
|
free_regions.contains(&r.to_region_vid())
|
||||||
}) {
|
}) {
|
||||||
None
|
Either::Left(local)
|
||||||
} else {
|
} else {
|
||||||
Some(local)
|
Either::Right(local)
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect();
|
|
||||||
|
|
||||||
debug!("{} total variables", body.local_decls.len());
|
debug!("{} total variables", body.local_decls.len());
|
||||||
debug!("{} variables need liveness", live_locals.len());
|
debug!("{} variables need liveness", relevant_live_locals.len());
|
||||||
debug!("{} regions outlive free regions", free_regions.len());
|
debug!("{} regions outlive free regions", free_regions.len());
|
||||||
|
|
||||||
live_locals
|
(relevant_live_locals, boring_locals)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes all regions that are (currently) known to outlive free
|
/// Computes all regions that are (currently) known to outlive free
|
||||||
|
|
|
@ -41,12 +41,13 @@ pub(super) fn trace<'mir, 'tcx>(
|
||||||
elements: &Rc<RegionValueElements>,
|
elements: &Rc<RegionValueElements>,
|
||||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
live_locals: Vec<Local>,
|
relevant_live_locals: Vec<Local>,
|
||||||
|
boring_locals: Vec<Local>,
|
||||||
polonius_drop_used: Option<Vec<(Local, Location)>>,
|
polonius_drop_used: Option<Vec<(Local, Location)>>,
|
||||||
) {
|
) {
|
||||||
debug!("trace()");
|
debug!("trace()");
|
||||||
|
|
||||||
let local_use_map = &LocalUseMap::build(&live_locals, elements, body);
|
let local_use_map = &LocalUseMap::build(&relevant_live_locals, elements, body);
|
||||||
|
|
||||||
let cx = LivenessContext {
|
let cx = LivenessContext {
|
||||||
typeck,
|
typeck,
|
||||||
|
@ -61,10 +62,12 @@ pub(super) fn trace<'mir, 'tcx>(
|
||||||
let mut results = LivenessResults::new(cx);
|
let mut results = LivenessResults::new(cx);
|
||||||
|
|
||||||
if let Some(drop_used) = polonius_drop_used {
|
if let Some(drop_used) = polonius_drop_used {
|
||||||
results.add_extra_drop_facts(drop_used, live_locals.iter().copied().collect())
|
results.add_extra_drop_facts(drop_used, relevant_live_locals.iter().copied().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
results.compute_for_all_locals(live_locals);
|
results.compute_for_all_locals(relevant_live_locals);
|
||||||
|
|
||||||
|
results.dropck_boring_locals(boring_locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contextual state for the type-liveness generator.
|
/// Contextual state for the type-liveness generator.
|
||||||
|
@ -133,8 +136,8 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_for_all_locals(&mut self, live_locals: Vec<Local>) {
|
fn compute_for_all_locals(&mut self, relevant_live_locals: Vec<Local>) {
|
||||||
for local in live_locals {
|
for local in relevant_live_locals {
|
||||||
self.reset_local_state();
|
self.reset_local_state();
|
||||||
self.add_defs_for(local);
|
self.add_defs_for(local);
|
||||||
self.compute_use_live_points_for(local);
|
self.compute_use_live_points_for(local);
|
||||||
|
@ -157,6 +160,24 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Runs dropck for locals whose liveness isn't relevant. This is
|
||||||
|
// necessary to eagerly detect unbound recursion during drop glue computation.
|
||||||
|
fn dropck_boring_locals(&mut self, boring_locals: Vec<Local>) {
|
||||||
|
for local in boring_locals {
|
||||||
|
let local_ty = self.cx.body.local_decls[local].ty;
|
||||||
|
let drop_data = self.cx.drop_data.entry(local_ty).or_insert_with({
|
||||||
|
let typeck = &mut self.cx.typeck;
|
||||||
|
move || LivenessContext::compute_drop_data(typeck, local_ty)
|
||||||
|
});
|
||||||
|
|
||||||
|
drop_data.dropck_result.report_overflows(
|
||||||
|
self.cx.typeck.infcx.tcx,
|
||||||
|
self.cx.body.local_decls[local].source_info.span,
|
||||||
|
local_ty,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Add extra drop facts needed for Polonius.
|
/// Add extra drop facts needed for Polonius.
|
||||||
///
|
///
|
||||||
/// Add facts for all locals with free regions, since regions may outlive
|
/// Add facts for all locals with free regions, since regions may outlive
|
||||||
|
@ -164,12 +185,12 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||||
fn add_extra_drop_facts(
|
fn add_extra_drop_facts(
|
||||||
&mut self,
|
&mut self,
|
||||||
drop_used: Vec<(Local, Location)>,
|
drop_used: Vec<(Local, Location)>,
|
||||||
live_locals: FxHashSet<Local>,
|
relevant_live_locals: FxHashSet<Local>,
|
||||||
) {
|
) {
|
||||||
let locations = IntervalSet::new(self.cx.elements.num_points());
|
let locations = IntervalSet::new(self.cx.elements.num_points());
|
||||||
|
|
||||||
for (local, location) in drop_used {
|
for (local, location) in drop_used {
|
||||||
if !live_locals.contains(&local) {
|
if !relevant_live_locals.contains(&local) {
|
||||||
let local_ty = self.cx.body.local_decls[local].ty;
|
let local_ty = self.cx.body.local_decls[local].ty;
|
||||||
if local_ty.has_free_regions() {
|
if local_ty.has_free_regions() {
|
||||||
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
|
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
|
||||||
|
|
|
@ -1825,7 +1825,8 @@ rustc_queries! {
|
||||||
remap_env_constness
|
remap_env_constness
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Do not call this query directly: invoke `infcx.at().dropck_outlives()` instead.
|
/// Do not call this query directly:
|
||||||
|
/// invoke `DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx)` instead.
|
||||||
query dropck_outlives(
|
query dropck_outlives(
|
||||||
goal: CanonicalTyGoal<'tcx>
|
goal: CanonicalTyGoal<'tcx>
|
||||||
) -> Result<
|
) -> Result<
|
||||||
|
|
|
@ -8,8 +8,6 @@ use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::util::IgnoreRegions;
|
use rustc_middle::ty::util::IgnoreRegions;
|
||||||
use rustc_middle::ty::{self, Predicate, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Predicate, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::query::dropck_outlives::AtExt;
|
|
||||||
use rustc_trait_selection::traits::ObligationCause;
|
|
||||||
|
|
||||||
/// This function confirms that the `Drop` implementation identified by
|
/// This function confirms that the `Drop` implementation identified by
|
||||||
/// `drop_impl_did` is not any more specialized than the type it is
|
/// `drop_impl_did` is not any more specialized than the type it is
|
||||||
|
@ -234,18 +232,14 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||||
/// This function is not only checking that the dropck obligations are met for
|
/// This function is not only checking that the dropck obligations are met for
|
||||||
/// the given type, but it's also currently preventing non-regular recursion in
|
/// the given type, but it's also currently preventing non-regular recursion in
|
||||||
/// types from causing stack overflows (dropck_no_diverge_on_nonregular_*.rs).
|
/// types from causing stack overflows (dropck_no_diverge_on_nonregular_*.rs).
|
||||||
|
///
|
||||||
|
/// FIXME: Completely rip out dropck and regionck.
|
||||||
pub(crate) fn check_drop_obligations<'a, 'tcx>(
|
pub(crate) fn check_drop_obligations<'a, 'tcx>(
|
||||||
rcx: &mut RegionCtxt<'a, 'tcx>,
|
_rcx: &mut RegionCtxt<'a, 'tcx>,
|
||||||
ty: Ty<'tcx>,
|
_ty: Ty<'tcx>,
|
||||||
span: Span,
|
_span: Span,
|
||||||
body_id: hir::HirId,
|
_body_id: hir::HirId,
|
||||||
) {
|
) {
|
||||||
debug!("check_drop_obligations typ: {:?}", ty);
|
|
||||||
|
|
||||||
let cause = &ObligationCause::misc(span, body_id);
|
|
||||||
let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty);
|
|
||||||
debug!("dropck_outlives = {:#?}", infer_ok);
|
|
||||||
rcx.fcx.register_infer_ok_obligations(infer_ok);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an implementation of the TypeRelation trait with the
|
// This is an implementation of the TypeRelation trait with the
|
||||||
|
|
|
@ -23,5 +23,4 @@ enum FingerTree<T:'static> {
|
||||||
fn main() {
|
fn main() {
|
||||||
let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
|
let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
|
||||||
FingerTree::Single(1);
|
FingerTree::Single(1);
|
||||||
//~^ ERROR overflow while adding drop-check rules for FingerTree
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,5 @@ LL | let ft =
|
||||||
|
|
|
|
||||||
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
|
||||||
error[E0320]: overflow while adding drop-check rules for FingerTree<i32>
|
error: aborting due to previous error
|
||||||
--> $DIR/dropck_no_diverge_on_nonregular_1.rs:25:9
|
|
||||||
|
|
|
||||||
LL | FingerTree::Single(1);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,4 @@ enum FingerTree<T:'static> {
|
||||||
fn main() {
|
fn main() {
|
||||||
let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
|
let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
|
||||||
FingerTree::Single(1);
|
FingerTree::Single(1);
|
||||||
//~^ ERROR overflow while adding drop-check rules for FingerTree
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,5 @@ LL | let ft =
|
||||||
|
|
|
|
||||||
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
|
||||||
error[E0320]: overflow while adding drop-check rules for FingerTree<i32>
|
error: aborting due to previous error
|
||||||
--> $DIR/dropck_no_diverge_on_nonregular_2.rs:24:9
|
|
||||||
|
|
|
||||||
LL | FingerTree::Single(1);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,5 @@ enum Wrapper<T:'static> {
|
||||||
fn main() {
|
fn main() {
|
||||||
let w = //~ ERROR overflow while adding drop-check rules for Option
|
let w = //~ ERROR overflow while adding drop-check rules for Option
|
||||||
Some(Wrapper::Simple::<u32>);
|
Some(Wrapper::Simple::<u32>);
|
||||||
//~^ ERROR overflow while adding drop-check rules for Option
|
//~^ ERROR overflow while adding drop-check rules for Wrapper
|
||||||
//~| ERROR overflow while adding drop-check rules for Wrapper
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,6 @@ LL | let w =
|
||||||
|
|
|
|
||||||
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<u32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<u32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
|
||||||
error[E0320]: overflow while adding drop-check rules for Option<Wrapper<u32>>
|
|
||||||
--> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:9
|
|
||||||
|
|
|
||||||
LL | Some(Wrapper::Simple::<u32>);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<u32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
|
|
||||||
error[E0320]: overflow while adding drop-check rules for Wrapper<u32>
|
error[E0320]: overflow while adding drop-check rules for Wrapper<u32>
|
||||||
--> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:14
|
--> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:14
|
||||||
|
|
|
|
||||||
|
@ -22,5 +14,5 @@ LL | Some(Wrapper::Simple::<u32>);
|
||||||
|
|
|
|
||||||
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<u32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
= note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<u32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
struct Take(Take);
|
struct Take(Take);
|
||||||
//~^ ERROR has infinite size
|
//~^ ERROR has infinite size
|
||||||
//~| ERROR cycle detected
|
|
||||||
|
|
||||||
// check that we don't hang trying to find the tail of a recursive struct (#79437)
|
// check that we don't hang trying to find the tail of a recursive struct (#79437)
|
||||||
fn foo() -> Take {
|
fn foo() -> Take {
|
||||||
|
|
|
@ -11,16 +11,6 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Take` repre
|
||||||
LL | struct Take(Box<Take>);
|
LL | struct Take(Box<Take>);
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing drop-check constraints for `Take`
|
error: aborting due to previous error
|
||||||
--> $DIR/infinite-struct.rs:1:1
|
|
||||||
|
|
|
||||||
LL | struct Take(Take);
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: ...which immediately requires computing drop-check constraints for `Take` again
|
|
||||||
= note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, constness: NotConst }, value: Take } }`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0072`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0072, E0391.
|
|
||||||
For more information about an error, try `rustc --explain E0072`.
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
enum MList { Cons(isize, MList), Nil }
|
enum MList { Cons(isize, MList), Nil }
|
||||||
//~^ ERROR recursive type `MList` has infinite size
|
//~^ ERROR recursive type `MList` has infinite size
|
||||||
//~| ERROR cycle detected when computing drop-check constraints for `MList`
|
|
||||||
|
|
||||||
fn main() { let a = MList::Cons(10, MList::Cons(11, MList::Nil)); }
|
fn main() { let a = MList::Cons(10, MList::Cons(11, MList::Nil)); }
|
||||||
|
|
|
@ -11,16 +11,6 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `MList` repr
|
||||||
LL | enum MList { Cons(isize, Box<MList>), Nil }
|
LL | enum MList { Cons(isize, Box<MList>), Nil }
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing drop-check constraints for `MList`
|
error: aborting due to previous error
|
||||||
--> $DIR/infinite-tag-type-recursion.rs:1:1
|
|
||||||
|
|
|
||||||
LL | enum MList { Cons(isize, MList), Nil }
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: ...which immediately requires computing drop-check constraints for `MList` again
|
|
||||||
= note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, constness: NotConst }, value: MList } }`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0072`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0072, E0391.
|
|
||||||
For more information about an error, try `rustc --explain E0072`.
|
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
// Dropck shouldn't hit a recursion limit from checking `S<u32>` since it has
|
// `S` is infinitely recursing so it's not possible to generate a finite
|
||||||
// no free regions or type parameters.
|
// drop impl (ignoring polymorphization).
|
||||||
// Codegen however, has to error for the infinitely many `drop_in_place`
|
//
|
||||||
// functions it has been asked to create.
|
// Dropck should therefore detect that this is the case and eagerly error.
|
||||||
|
|
||||||
// build-fail
|
|
||||||
// normalize-stderr-test: ".nll/" -> "/"
|
|
||||||
// compile-flags: -Zmir-opt-level=0
|
|
||||||
|
|
||||||
struct S<T> {
|
struct S<T> {
|
||||||
t: T,
|
t: T,
|
||||||
s: Box<S<fn(u: T)>>,
|
s: Box<S<fn(u: T)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn f(x: S<u32>) {}
|
fn f(x: S<u32>) {} //~ ERROR overflow while adding drop-check rules for S<u32>
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Force instantiation.
|
// Force instantiation.
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
error: reached the recursion limit while instantiating `std::ptr::drop_in_place::<S<fn(f...)))))))))))))))))))))))))))))>))`
|
error[E0320]: overflow while adding drop-check rules for S<u32>
|
||||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
--> $DIR/issue-38591-non-regular-dropck-recursion.rs:11:6
|
||||||
|
|
|
|
||||||
LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
LL | fn f(x: S<u32>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^
|
||||||
|
|
|
|
||||||
note: `std::ptr::drop_in_place` defined here
|
= note: overflowed on S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>
|
||||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
|
||||||
|
|
|
||||||
LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-38591-non-regular-dropck-recursion/issue-38591-non-regular-dropck-recursion.long-type.txt'
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue