Repository navigation
Assertion failed in erroneous recursive types with methods returning a impl Trait type #72554
Copy link
Copy link
Closed
Labels
A-codegenArea: Code generationArea: Code generationA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.Category: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.ICE tracked in rust-lang/glacier.
Description
Summary
- erroneous recursive types (without being wrapped with
Box<_>) having methods whose return type isimpl Traitcauses the assertion failure.
I tried this code:
use std::collections::BTreeSet;
#[derive(Hash)]
pub enum ElemDerived {
A(ElemDerived)
}
pub enum Elem {
Derived(ElemDerived)
}
pub struct Set(BTreeSet<Elem>);
impl Set {
pub fn into_iter(self) -> impl Iterator<Item = Elem> {
self.0.into_iter()
}
}
fn main() {}I expected to see this happen:
- I expected the error message "recursive type
ElemDerivedhas infinite size." - Indeed, if there is no method with return type
impl Trait, we got the following normal error messages:error[E0072]: recursive type `ElemDerived` has infinite size --> ./bug.rs:4:1 | 4 | pub enum ElemDerived { | ^^^^^^^^^^^^^^^^^^^^ recursive type has infinite size 5 | A(ElemDerived) | ----------- recursive without indirection | = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ElemDerived` representable error: aborting due to previous error
Instead, this happened:
rustcaborted with the following assertion failure.% RUST_BACKTRACE=1 rustc ./bug.rs error: internal compiler error: src/librustc_infer/traits/codegen/mod.rs:108: Encountered errors `[FulfillmentError(Obligation(predicate=Binder(TraitPredicate(<[type error] as std::marker::Sized>)), depth=2),Ambiguity)]` resolving bounds after type-checking thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:875:9 stack backtrace: 0: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt 1: core::fmt::write 2: std::io::Write::write_fmt 3: std::panicking::default_hook::{{closure}} 4: std::panicking::default_hook 5: rustc_driver::report_ice 6: std::panicking::rust_panic_with_hook 7: std::panicking::begin_panic 8: rustc_errors::HandlerInner::bug 9: rustc_errors::Handler::bug 10: rustc::util::bug::opt_span_bug_fmt::{{closure}} 11: rustc::ty::context::tls::with_opt::{{closure}} 12: rustc::ty::context::tls::with_opt 13: rustc::util::bug::opt_span_bug_fmt 14: rustc::util::bug::bug_fmt 15: rustc_infer::traits::codegen::<impl rustc_infer::infer::InferCtxt>::drain_fulfillment_cx_or_panic 16: rustc::ty::context::GlobalCtxt::enter_local 17: rustc_infer::traits::codegen::codegen_fulfill_obligation 18: rustc::ty::query::__query_compute::codegen_fulfill_obligation 19: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::codegen_fulfill_obligation>::compute 20: rustc::dep_graph::graph::DepGraph::with_task_impl 21: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 22: rustc_ty::instance::resolve_instance 23: rustc::ty::instance::Instance::resolve 24: rustc_mir_build::lints::check 25: rustc::ty::context::GlobalCtxt::enter_local 26: rustc_mir_build::build::mir_built 27: rustc::ty::query::__query_compute::mir_built 28: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_built>::compute 29: rustc::dep_graph::graph::DepGraph::with_task_impl 30: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 31: rustc_mir::transform::check_unsafety::unsafety_check_result 32: rustc::ty::query::__query_compute::unsafety_check_result 33: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::unsafety_check_result>::compute 34: rustc::dep_graph::graph::DepGraph::with_task_impl 35: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 36: rustc_mir::transform::mir_const 37: rustc::ty::query::__query_compute::mir_const 38: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_const>::compute 39: rustc::dep_graph::graph::DepGraph::with_task_impl 40: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 41: rustc_mir::transform::mir_validated 42: rustc::ty::query::__query_compute::mir_validated 43: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_validated>::compute 44: rustc::dep_graph::graph::DepGraph::with_task_impl 45: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 46: rustc_mir::borrow_check::mir_borrowck 47: rustc::ty::query::__query_compute::mir_borrowck 48: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_borrowck>::compute 49: rustc::dep_graph::graph::DepGraph::with_task_impl 50: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 51: rustc_typeck::collect::type_of::type_of 52: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::type_of>::compute 53: rustc::dep_graph::graph::DepGraph::with_task_impl 54: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 55: rustc::ty::util::<impl rustc::ty::context::TyCtxt>::try_expand_impl_trait_type::OpaqueTypeExpander::expand_opaque_ty 56: rustc::ty::util::<impl rustc::ty::context::TyCtxt>::try_expand_impl_trait_type 57: rustc_typeck::check::check_item_type 58: rustc::hir::map::Map::visit_item_likes_in_module 59: rustc_typeck::check::check_mod_item_types 60: rustc::ty::query::__query_compute::check_mod_item_types 61: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::check_mod_item_types>::compute 62: rustc::dep_graph::graph::DepGraph::with_task_impl 63: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 64: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::ensure_query 65: rustc_session::utils::<impl rustc_session::session::Session>::time 66: rustc_typeck::check_crate 67: rustc_interface::passes::analysis 68: rustc::ty::query::__query_compute::analysis 69: rustc::dep_graph::graph::DepGraph::with_task_impl 70: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query 71: rustc::ty::context::tls::enter_global 72: rustc_interface::interface::run_compiler_in_existing_thread_pool note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports note: rustc 1.43.1 (8d69840ab 2020-05-04) running on x86_64-apple-darwin query stack during panic: #0 [codegen_fulfill_obligation] checking if `std::iter::IntoIterator` fulfills its obligations #1 [mir_built] building MIR for #2 [unsafety_check_result] unsafety-checking `Set::into_iter` #3 [mir_const] processing `Set::into_iter` #4 [mir_validated] processing `Set::into_iter` #5 [mir_borrowck] borrow-checking `Set::into_iter` #6 [type_of] processing `Set::into_iter::{{opaque}}#0` #7 [check_mod_item_types] checking item types in top-level module #8 [analysis] running analysis passes on this crate end of query stack error: aborting due to previous error
Meta
rustc --version --verbose:% rustc --version --verbose rustc 1.43.1 (8d69840ab 2020-05-04) binary: rustc commit-hash: 8d69840ab92ea7f4d323420088dd8c9775f180cd commit-date: 2020-05-04 host: x86_64-apple-darwin release: 1.43.1 LLVM version: 9.0
Metadata
Metadata
Assignees
Labels
A-codegenArea: Code generationArea: Code generationA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.Category: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.ICE tracked in rust-lang/glacier.
Activity
JohnTitor commentedon May 25, 2020
rustbot commentedon May 25, 2020
JohnTitor commentedon May 25, 2020
rustbot commentedon May 25, 2020
JohnTitor commentedon May 25, 2020
rustbot commentedon May 25, 2020
Error: The feature
glacieris not enabled in this repository.To enable it add its section in the
triagebot.tomlin the root of the repository.Please let
@rust-lang/releaseknow if you're having trouble with this bot.JohnTitor commentedon May 25, 2020
Oh, we must have enabled this... Sorry for the noise!
Rollup merge of rust-lang#72560 - JohnTitor:glacier, r=Mark-Simulacrum
JohnTitor commentedon May 26, 2020
I think now we could...
@rustbot glacier "https://gist.github.com/rust-play/e9a2a667c7f9015fdf681a7e6a542d63"
estebank commentedon May 29, 2020
Making the following change:
fn drain_fulfillment_cx_or_panic<T>( infcx: &InferCtxt<'_, 'tcx>, fulfill_cx: &mut FulfillmentContext<'tcx>, result: &T, ) -> T where T: TypeFoldable<'tcx>, { debug!("drain_fulfillment_cx_or_panic()"); // In principle, we only need to do this so long as `result` // contains unbound type parameters. It could be a slight // optimization to stop iterating early. if let Err(errors) = fulfill_cx.select_all_or_error(infcx) { + // `select_all_or_error` can return an empty `Vec<FulfillmentError>` when you have a bad + // interation of `impl Trait` in return position and a recursive ADT without indirection + // (#72554). + if !errors.is_empty() { + infcx.tcx.sess.delay_span_bug( + rustc_span::DUMMY_SP, + "`select_all_or_error` failed but no errors where present", + ); + } else { bug!("encountered errors `{:?}` resolving bounds after type-checking", errors); + } } let result = infcx.resolve_vars_if_possible(result); infcx.tcx.erase_regions(&result) }makes the output look correct, but I am not sure of whether that should be the fix, making it always a
delay_span_bugand continue returning theOk<VTable>or make the caller returnErr(ErrorReported)instead (which seems to me to be the correct behavior). I do not understand why this has to panic in the first place.JohnTitor commentedon May 31, 2020
Triage: Seems the ICE is fixed with the latest nightly, now
recursive_type_with_infinite_size_errorcatches this correctly (not bisected yet). Marking as E-needs-test, cc @estebank for awareness.Rollup merge of rust-lang#72718 - estebank:impl-trait-obligation-fail…
Rollup merge of rust-lang#72718 - estebank:impl-trait-obligation-fail…
Auto merge of rust-lang#72975 - Dylan-DPC:rollup-6zvco5x, r=Dylan-DPC
Remove noisy suggestion of hash_map rust-lang#72642