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

ICE: BoundRegion { var: 0, kind: BrNamed(DefId(0:9 ~ rust_bug[3fc9]::or::'a), 'a) } is a region but value is Type(_) #91801

Closed
cfcosta opened this issue Dec 11, 2021 · 5 comments · Fixed by #95603
Labels
C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@cfcosta
Copy link

cfcosta commented Dec 11, 2021

I don't have much context on this, was doing some thinkering on what would be the best way to do something not really interesting, and got this ICE. This bug happens on both Nightly and Stable.

Code

This is the original code I managed to replicate the issue:

pub struct Something;

type Validator<'a> = dyn 'a + Send + Sync + Fn(&'a Something) -> Result<(), ()>;

pub static ALL_VALIDATORS: &[(&'static str, &'static Validator)] = &[(
    "validate that credits and debits balance",
    &validate_something,
)];

fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> {
    return Box::new(move |something: &'_ Something| -> Result<(), ()> {
        first(something).or_else(|_| second(something))
    })
}

fn validate_something(_: &Something) -> Result<(), ()> {
    Ok(())
}

fn main() {}

This code fails with the ICE error. Removing the return on the Box of the or function turns it from an ICE to a normal compiler error.

A member on the Rust discord (@5225225) also reported that this, more minimal test case also returns the same error:

fn or<'a>(first: &'static (dyn Fn(&'a i32))) -> dyn 'a + Fn(&'a i32) {
   return Box::new(panic!());
}

fn main() {}

Meta

rustc +nightly --version --verbose:

rustc 1.59.0-nightly (48a5999fc 2021-12-01)
binary: rustc
commit-hash: 48a5999fceeea84a8971634355287faa349909d4
commit-date: 2021-12-01
host: x86_64-unknown-linux-gnu
release: 1.59.0-nightly
LLVM version: 13.0.0

rustc +stable --version --verbose:

rustc 1.57.0 (f1edd0429 2021-11-29)
binary: rustc
commit-hash: f1edd0429582dd29cccacaf50fd134b05593bd9c
commit-date: 2021-11-29
host: x86_64-unknown-linux-gnu
release: 1.57.0
LLVM version: 13.0.0

Error output

error: internal compiler error: /rustc/48a5999fceeea84a8971634355287faa349909d4/compiler/rustc_infer/src/infer/canonical/substitute.rs:76:18: BoundRegion { var: 0, kind: BrNamed(DefId(0:9 ~ rust_bug[3fc9]::or::'a), 'a) } is a region but value is Type(_)

thread 'rustc' panicked at 'Box<dyn Any>', compiler/rustc_errors/src/lib.rs:1171:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.59.0-nightly (48a5999fc 2021-12-01) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental -C target-cpu=native --crate-type bin

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [evaluate_obligation] evaluating trait selection obligation `for<'a> alloc::boxed::Box<[closure@src/main.rs:11:21: 13:6]>: core::ops::function::Fn<(&'a Something,)>`
#1 [typeck] type-checking `or`
end of query stack
error: could not compile `rust-bug`
Backtrace

error: internal compiler error: /rustc/48a5999fceeea84a8971634355287faa349909d4/compiler/rustc_infer/src/infer/canonical/substitute.rs:76:18: BoundRegion { var: 0, kind: BrNamed(DefId(0:9 ~ rust_bug[3fc9]::or::'a), 'a) } is a region but value is Type(_)

thread 'rustc' panicked at 'Box<dyn Any>', compiler/rustc_errors/src/lib.rs:1171:9
stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
   1: std::panic::panic_any::<rustc_errors::ExplicitBug>
   2: <rustc_errors::HandlerInner>::bug
   3: <rustc_errors::Handler>::bug
   4: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, ()>
   5: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
   6: rustc_middle::util::bug::bug_fmt
   7: rustc_infer::infer::canonical::substitute::substitute_value::<rustc_middle::ty::ParamEnvAnd<rustc_middle::traits::query::type_op::Normalize<rustc_middle::ty::Predicate>>>::{closure#0}
   8: <&rustc_middle::ty::TyS as rustc_middle::ty::fold::TypeFoldable>::super_fold_with::<rustc_middle::ty::fold::BoundVarReplacer>
   9: <&rustc_middle::ty::list::List<rustc_middle::ty::subst::GenericArg> as rustc_middle::ty::fold::TypeFoldable>::fold_with::<rustc_middle::ty::fold::BoundVarReplacer>
  10: <&rustc_middle::ty::TyS as rustc_middle::ty::fold::TypeFoldable>::super_fold_with::<rustc_middle::ty::fold::BoundVarReplacer>
  11: <rustc_middle::ty::fold::BoundVarReplacer as rustc_middle::ty::fold::TypeFolder>::fold_predicate
  12: <rustc_infer::infer::InferCtxtBuilder>::enter_with_canonical::<rustc_middle::ty::ParamEnvAnd<rustc_middle::ty::Predicate>, core::result::Result<rustc_middle::traits::select::EvaluationResult, rustc_middle::traits::select::OverflowError>, rustc_traits::evaluate_obligation::evaluate_obligation::{closure#0}>
  13: rustc_traits::evaluate_obligation::evaluate_obligation
  14: <rustc_query_system::dep_graph::graph::DepGraph<rustc_middle::dep_graph::dep_node::DepKind>>::with_task::<rustc_middle::ty::context::TyCtxt, rustc_middle::infer::canonical::Canonical<rustc_middle::ty::ParamEnvAnd<rustc_middle::ty::Predicate>>, core::result::Result<rustc_middle::traits::select::EvaluationResult, rustc_middle::traits::select::OverflowError>>
  15: rustc_data_structures::stack::ensure_sufficient_stack::<(core::result::Result<rustc_middle::traits::select::EvaluationResult, rustc_middle::traits::select::OverflowError>, rustc_query_system::dep_graph::graph::DepNodeIndex), rustc_query_system::query::plumbing::execute_job<rustc_query_impl::plumbing::QueryCtxt, rustc_middle::infer::canonical::Canonical<rustc_middle::ty::ParamEnvAnd<rustc_middle::ty::Predicate>>, core::result::Result<rustc_middle::traits::select::EvaluationResult, rustc_middle::traits::select::OverflowError>>::{closure#3}>
  16: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::evaluate_obligation, rustc_query_impl::plumbing::QueryCtxt>
  17: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::evaluate_obligation
  18: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt>::predicate_may_hold
  19: <core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::sty::Binder<rustc_middle::ty::sty::ExistentialPredicate>>> as core::iter::traits::iterator::Iterator>::try_fold::<(), core::iter::traits::iterator::Iterator::all::check<rustc_middle::ty::sty::Binder<rustc_middle::ty::sty::ExistentialPredicate>, <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt>::suggest_impl_trait::{closure#5}::{closure#0}>::{closure#0}, core::ops::control_flow::ControlFlow<()>>
  20: <core::iter::adapters::map::Map<core::iter::adapters::filter_map::FilterMap<core::slice::iter::Iter<&rustc_hir::hir::Expr>, <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt>::suggest_impl_trait::{closure#2}>, <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt>::suggest_impl_trait::{closure#3}> as core::iter::traits::iterator::Iterator>::try_fold::<(), core::iter::traits::iterator::Iterator::all::check<&rustc_middle::ty::TyS, <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt>::suggest_impl_trait::{closure#5}>::{closure#0}, core::ops::control_flow::ControlFlow<()>>
  21: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt>::suggest_impl_trait
  22: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::InferCtxtExt>::report_selection_error
  23: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::InferCtxtPrivExt>::report_fulfillment_error
  24: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::InferCtxtExt>::report_fulfillment_errors
  25: <rustc_typeck::check::fn_ctxt::FnCtxt>::type_inference_fallback
  26: <rustc_infer::infer::InferCtxtBuilder>::enter::<&rustc_middle::ty::context::TypeckResults, <rustc_typeck::check::inherited::InheritedBuilder>::enter<rustc_typeck::check::typeck_with_fallback<rustc_typeck::check::typeck::{closure#0}>::{closure#1}, &rustc_middle::ty::context::TypeckResults>::{closure#0}>
  27: rustc_typeck::check::typeck
  28: <rustc_query_system::dep_graph::graph::DepGraph<rustc_middle::dep_graph::dep_node::DepKind>>::with_task::<rustc_middle::ty::context::TyCtxt, rustc_span::def_id::LocalDefId, &rustc_middle::ty::context::TypeckResults>
  29: rustc_data_structures::stack::ensure_sufficient_stack::<(&rustc_middle::ty::context::TypeckResults, rustc_query_system::dep_graph::graph::DepNodeIndex), rustc_query_system::query::plumbing::execute_job<rustc_query_impl::plumbing::QueryCtxt, rustc_span::def_id::LocalDefId, &rustc_middle::ty::context::TypeckResults>::{closure#3}>
  30: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::LocalDefId, &rustc_middle::ty::context::TypeckResults>>
  31: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::typeck
  32: rustc_typeck::check::typeck
  33: <rustc_query_system::dep_graph::graph::DepGraph<rustc_middle::dep_graph::dep_node::DepKind>>::with_task::<rustc_middle::ty::context::TyCtxt, rustc_span::def_id::LocalDefId, &rustc_middle::ty::context::TypeckResults>
  34: rustc_data_structures::stack::ensure_sufficient_stack::<(&rustc_middle::ty::context::TypeckResults, rustc_query_system::dep_graph::graph::DepNodeIndex), rustc_query_system::query::plumbing::execute_job<rustc_query_impl::plumbing::QueryCtxt, rustc_span::def_id::LocalDefId, &rustc_middle::ty::context::TypeckResults>::{closure#3}>
  35: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::LocalDefId, &rustc_middle::ty::context::TypeckResults>>
  36: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::typeck
  37: <rustc_middle::hir::map::Map>::par_body_owners::<rustc_typeck::check::typeck_item_bodies::{closure#0}>
  38: rustc_typeck::check::typeck_item_bodies
  39: <rustc_query_system::dep_graph::graph::DepGraph<rustc_middle::dep_graph::dep_node::DepKind>>::with_task::<rustc_middle::ty::context::TyCtxt, (), ()>
  40: rustc_data_structures::stack::ensure_sufficient_stack::<((), rustc_query_system::dep_graph::graph::DepNodeIndex), rustc_query_system::query::plumbing::execute_job<rustc_query_impl::plumbing::QueryCtxt, (), ()>::{closure#3}>
  41: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<(), ()>>
  42: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::typeck_item_bodies, rustc_query_impl::plumbing::QueryCtxt>
  43: <rustc_session::session::Session>::time::<(), rustc_typeck::check_crate::{closure#7}>
  44: rustc_typeck::check_crate
  45: rustc_interface::passes::analysis
  46: <rustc_query_system::dep_graph::graph::DepGraph<rustc_middle::dep_graph::dep_node::DepKind>>::with_task::<rustc_middle::ty::context::TyCtxt, (), core::result::Result<(), rustc_errors::ErrorReported>>
  47: rustc_data_structures::stack::ensure_sufficient_stack::<(core::result::Result<(), rustc_errors::ErrorReported>, rustc_query_system::dep_graph::graph::DepNodeIndex), rustc_query_system::query::plumbing::execute_job<rustc_query_impl::plumbing::QueryCtxt, (), core::result::Result<(), rustc_errors::ErrorReported>>::{closure#3}>
  48: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<(), core::result::Result<(), rustc_errors::ErrorReported>>>
  49: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::analysis, rustc_query_impl::plumbing::QueryCtxt>
  50: <rustc_interface::passes::QueryContext>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}::{closure#3}, core::result::Result<(), rustc_errors::ErrorReported>>
  51: <rustc_interface::interface::Compiler>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorReported>>
  52: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorReported>, rustc_interface::interface::create_compiler_and_run<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#1}>
  53: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>
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/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.59.0-nightly (48a5999fc 2021-12-01) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental -C target-cpu=native --crate-type bin

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [evaluate_obligation] evaluating trait selection obligation `for<'a> alloc::boxed::Box<[closure@src/main.rs:11:21: 13:6]>: core::ops::function::Fn<(&'a Something,)>`
#1 [typeck] type-checking `or`
#2 [typeck] type-checking `or::{closure#0}::{closure#0}`
#3 [typeck_item_bodies] type-checking all item bodies
#4 [analysis] running analysis passes on this crate
end of query stack

@cfcosta cfcosta added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 11, 2021
@5225225
Copy link
Contributor

5225225 commented Dec 11, 2021

fn or<'a>(first: &'static (dyn Fn(&'a i32))) -> dyn Fn(&'a i32) {
   return Box::new(panic!());
}

This ICEs in the playground, but interestingly, this does not

fn or<'a>(first: &'static (dyn Fn(&'a i32))) -> dyn Fn(&'a i32) {
    Box::new(panic!())
}

Also, the <'a> is needed, you can't use &'static for all of the lifetimes. Same with just dropping the &'a i32 and taking an i32 directly, that fails to ICE.

@5225225
Copy link
Contributor

5225225 commented Dec 11, 2021

also...

trait Foo<'a> {}

fn or<'a>(first: &'static dyn Foo<'a>) -> dyn Foo<'a> {
    return Box::new(panic!());
}

also ICEs but it's a different ICE. Fun! I'll go report that.

@5225225
Copy link
Contributor

5225225 commented Dec 11, 2021

Reported that ICE as #91803, the root cause might be similar.

@cfcosta
Copy link
Author

cfcosta commented Dec 11, 2021

Thanks for all the help @5225225!

@5225225
Copy link
Contributor

5225225 commented Dec 11, 2021

Bisected this

Looks like --regress=ice is acting weirdly. I'm re-running the bisect with a script that greps for "BoundRegion" and it's finding different nightlies. Maybe the behaviour in that commit that confuses bisect-rustc.

********************************************************************************
Regression in nightly-2021-04-01
********************************************************************************

fetching https://static.rust-lang.org/dist/2021-03-31/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2021-03-31: 40 B / 40 B [===========================================] 100.00 % 638.13 KB/s converted 2021-03-31 to 74874a690bc95443292496ff5df5cc5c8cb56e0b
fetching https://static.rust-lang.org/dist/2021-04-01/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2021-04-01: 40 B / 40 B [===========================================] 100.00 % 575.33 KB/s converted 2021-04-01 to 4fdac23f3171e2f8864d359a21da600dd3faafc9
looking for regression commit between 2021-03-31 and 2021-04-01
refreshing repository at "/home/jess/src/rust"
From https://github.com/rust-lang/rust
 * branch                    HEAD       -> FETCH_HEAD
opening existing repository at "/home/jess/src/rust"
fetching (via local git) commits from 74874a690bc95443292496ff5df5cc5c8cb56e0b to 4fdac23f3171e2f8864d359a21da600dd3faafc9
refreshing repository at "/home/jess/src/rust"
From https://github.com/rust-lang/rust
 * branch                    HEAD       -> FETCH_HEAD
opening existing repository at "/home/jess/src/rust"
looking up first commit
looking up second commit
checking that commits are by bors and thus have ci artifacts...
finding bors merge commits
found 6 bors merge commits in the specified range
  commit[0] 2021-03-30UTC: Auto merge of #83652 - xu-cheng:ipv4-octal, r=sfackler
  commit[1] 2021-03-30UTC: Auto merge of #83692 - Dylan-DPC:rollup-2a2m3jy, r=Dylan-DPC
  commit[2] 2021-03-31UTC: Auto merge of #83666 - Amanieu:instrprof-order, r=tmandry
  commit[3] 2021-03-31UTC: Auto merge of #83681 - jyn514:blanket-impls-tweaks, r=Aaron1011
  commit[4] 2021-03-31UTC: Auto merge of #83684 - cjgillot:csp, r=petrochenkov
  commit[5] 2021-03-31UTC: Auto merge of #76814 - jackh726:binder-refactor, r=nikomatsakis
ERROR: no CI builds available between 74874a690bc95443292496ff5df5cc5c8cb56e0b and 4fdac23f3171e2f8864d359a21da600dd3faafc9 within last 167 days

is the new error.

@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Dec 13, 2021
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 4, 2022
Fix late-bound ICE in `dyn` return type suggestion

This fixes the root-cause of the attached issues -- the root problem is that we're using the return type from a signature with late-bound instead of early-bound regions. The change on line 1087 (`let Some(liberated_sig) = typeck_results.liberated_fn_sigs().get(fn_hir_id) else { return false; };`) makes sure we're grabbing the _right_ return type for this suggestion to check the `dyn` predicates with.

Fixes rust-lang#91801
Fixes rust-lang#91803

This fix also includes some drive-by changes, specifically:

1. Don't suggest boxing when we have `-> dyn Trait` and are already returning `Box<T>` where `T: Trait` (before we always boxed the value).
2. Suggestion applies even when the return type is a type alias (e.g. `type Foo = dyn Trait`). This does cause the suggestion to expand to the aliased type, but I think it's still beneficial.
3. Split up the multipart suggestion because there's a 6-line max in the printed output...

I am open to splitting out the above changes, if we just want to fix the ICE first.

cc: `@terrarier2111` and rust-lang#92289
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 4, 2022
Fix late-bound ICE in `dyn` return type suggestion

This fixes the root-cause of the attached issues -- the root problem is that we're using the return type from a signature with late-bound instead of early-bound regions. The change on line 1087 (`let Some(liberated_sig) = typeck_results.liberated_fn_sigs().get(fn_hir_id) else { return false; };`) makes sure we're grabbing the _right_ return type for this suggestion to check the `dyn` predicates with.

Fixes rust-lang#91801
Fixes rust-lang#91803

This fix also includes some drive-by changes, specifically:

1. Don't suggest boxing when we have `-> dyn Trait` and are already returning `Box<T>` where `T: Trait` (before we always boxed the value).
2. Suggestion applies even when the return type is a type alias (e.g. `type Foo = dyn Trait`). This does cause the suggestion to expand to the aliased type, but I think it's still beneficial.
3. Split up the multipart suggestion because there's a 6-line max in the printed output...

I am open to splitting out the above changes, if we just want to fix the ICE first.

cc: ``@terrarier2111`` and rust-lang#92289
@bors bors closed this as completed in 92e53f5 Apr 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants