Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fully move dropck to mir #98641

Merged
merged 1 commit into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 24 additions & 27 deletions compiler/rustc_borrowck/src/type_check/liveness/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use itertools::{Either, Itertools};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::mir::{Body, Local};
use rustc_middle::ty::{RegionVid, TyCtxt};
use std::rc::Rc;

use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
use rustc_mir_dataflow::move_paths::MoveData;
use rustc_mir_dataflow::ResultsCursor;
use std::rc::Rc;

use crate::{
constraints::OutlivesConstraintSet,
Expand Down Expand Up @@ -46,7 +46,8 @@ pub(super) fn generate<'mir, 'tcx>(
&typeck.borrowck_context.universal_regions,
&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 polonius_drop_used = if facts_enabled {
Expand All @@ -57,48 +58,44 @@ pub(super) fn generate<'mir, 'tcx>(
None
};

if !live_locals.is_empty() || facts_enabled {
trace::trace(
typeck,
body,
elements,
flow_inits,
move_data,
live_locals,
polonius_drop_used,
);
}
trace::trace(
typeck,
body,
elements,
flow_inits,
move_data,
relevant_live_locals,
boring_locals,
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
// 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
// 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>,
free_regions: &FxHashSet<RegionVid>,
body: &Body<'tcx>,
) -> Vec<Local> {
let live_locals: Vec<Local> = body
.local_decls
.iter_enumerated()
.filter_map(|(local, local_decl)| {
) -> (Vec<Local>, Vec<Local>) {
let (boring_locals, relevant_live_locals): (Vec<_>, Vec<_>) =
body.local_decls.iter_enumerated().partition_map(|(local, local_decl)| {
if tcx.all_free_regions_meet(&local_decl.ty, |r| {
free_regions.contains(&r.to_region_vid())
}) {
None
Either::Left(local)
} else {
Some(local)
Either::Right(local)
}
})
.collect();
});

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());

live_locals
(relevant_live_locals, boring_locals)
}

/// Computes all regions that are (currently) known to outlive free
Expand Down
37 changes: 29 additions & 8 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ pub(super) fn trace<'mir, 'tcx>(
elements: &Rc<RegionValueElements>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, '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)>>,
) {
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 {
typeck,
Expand All @@ -61,10 +62,12 @@ pub(super) fn trace<'mir, 'tcx>(
let mut results = LivenessResults::new(cx);

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.
Expand Down Expand Up @@ -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>) {
for local in live_locals {
fn compute_for_all_locals(&mut self, relevant_live_locals: Vec<Local>) {
for local in relevant_live_locals {
self.reset_local_state();
self.add_defs_for(local);
self.compute_use_live_points_for(local);
Expand All @@ -157,19 +160,37 @@ 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 facts for all locals with free regions, since regions may outlive
/// the function body only at certain nodes in the CFG.
fn add_extra_drop_facts(
&mut self,
drop_used: Vec<(Local, Location)>,
live_locals: FxHashSet<Local>,
relevant_live_locals: FxHashSet<Local>,
) {
let locations = IntervalSet::new(self.cx.elements.num_points());

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;
if local_ty.has_free_regions() {
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1825,7 +1825,8 @@ rustc_queries! {
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(
goal: CanonicalTyGoal<'tcx>
) -> Result<
Expand Down
18 changes: 6 additions & 12 deletions compiler/rustc_typeck/src/check/dropck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::util::IgnoreRegions;
use rustc_middle::ty::{self, Predicate, Ty, TyCtxt};
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
/// `drop_impl_did` is not any more specialized than the type it is
Expand Down Expand Up @@ -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
/// the given type, but it's also currently preventing non-regular recursion in
/// 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>(
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
rcx: &mut RegionCtxt<'a, 'tcx>,
ty: Ty<'tcx>,
span: Span,
body_id: hir::HirId,
_rcx: &mut RegionCtxt<'a, 'tcx>,
_ty: Ty<'tcx>,
_span: Span,
_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
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ enum FingerTree<T:'static> {
fn main() {
let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
FingerTree::Single(1);
//~^ ERROR overflow while adding drop-check rules for FingerTree
}
10 changes: 1 addition & 9 deletions src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

error[E0320]: overflow while adding drop-check rules for FingerTree<i32>
--> $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
error: aborting due to previous error

1 change: 0 additions & 1 deletion src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ enum FingerTree<T:'static> {
fn main() {
let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
FingerTree::Single(1);
//~^ ERROR overflow while adding drop-check rules for FingerTree
}
10 changes: 1 addition & 9 deletions src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

error[E0320]: overflow while adding drop-check rules for FingerTree<i32>
--> $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
error: aborting due to previous error

3 changes: 1 addition & 2 deletions src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,5 @@ enum Wrapper<T:'static> {
fn main() {
let w = //~ ERROR overflow while adding drop-check rules for Option
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
}
10 changes: 1 addition & 9 deletions src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

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>
--> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:14
|
Expand All @@ -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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

1 change: 0 additions & 1 deletion src/test/ui/infinite/infinite-struct.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
struct Take(Take);
//~^ ERROR has infinite size
//~| ERROR cycle detected

// check that we don't hang trying to find the tail of a recursive struct (#79437)
fn foo() -> Take {
Expand Down
14 changes: 2 additions & 12 deletions src/test/ui/infinite/infinite-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,6 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Take` repre
LL | struct Take(Box<Take>);
| ++++ +

error[E0391]: cycle detected when computing drop-check constraints for `Take`
--> $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
error: aborting due to previous error

Some errors have detailed explanations: E0072, E0391.
For more information about an error, try `rustc --explain E0072`.
For more information about this error, try `rustc --explain E0072`.
1 change: 0 additions & 1 deletion src/test/ui/infinite/infinite-tag-type-recursion.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
enum MList { Cons(isize, MList), Nil }
//~^ 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)); }
14 changes: 2 additions & 12 deletions src/test/ui/infinite/infinite-tag-type-recursion.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
| ++++ +

error[E0391]: cycle detected when computing drop-check constraints for `MList`
--> $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
error: aborting due to previous error

Some errors have detailed explanations: E0072, E0391.
For more information about an error, try `rustc --explain E0072`.
For more information about this error, try `rustc --explain E0072`.
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
// Dropck shouldn't hit a recursion limit from checking `S<u32>` since it has
// no free regions or type parameters.
// Codegen however, has to error for the infinitely many `drop_in_place`
// functions it has been asked to create.

// build-fail
// normalize-stderr-test: ".nll/" -> "/"
// compile-flags: -Zmir-opt-level=0
// `S` is infinitely recursing so it's not possible to generate a finite
// drop impl (ignoring polymorphization).
//
// Dropck should therefore detect that this is the case and eagerly error.

struct S<T> {
t: 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() {
// Force instantiation.
Expand Down
Loading