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 combining specialization with associated constants as array lengths #50439

Closed
pythonesque opened this issue May 4, 2018 · 3 comments · Fixed by #98701
Closed

ICE combining specialization with associated constants as array lengths #50439

pythonesque opened this issue May 4, 2018 · 3 comments · Fixed by #98701
Assignees
Labels
A-associated-items Area: Associated items such as associated types and consts. A-specialization Area: Trait impl specialization C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-specialization `#![feature(specialization)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@pythonesque
Copy link
Contributor

pythonesque commented May 4, 2018

Testcase:

#![feature(specialization)]

pub trait ReflectDrop {
    const REFLECT_DROP : bool = false;
}

impl<T> ReflectDrop for T where T : Clone {}

pub trait PinDropInternal {
    fn is_valid() where Self: ReflectDrop;
}

struct Bears<T>(T);

default impl <T> ReflectDrop for Bears<T> { }

impl <T: Sized> PinDropInternal for Bears<T> {
    fn is_valid() where Self: ReflectDrop {
        let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize];
    }
}

fn main() {
}

I was mostly fooling around trying to see if there was any way I could get rustc to believe that it would always know whether Bears was Drop regardless of T; for the test case, I changed it to Clone and got rid of actually setting the constant to true in the default case, as well as some unsafe keywords, to avoid muddying the waters with Drop's semantics. Note that the array trick for turning a constant into a compile time error comes from https://github.com/nvzqz/static-assertions-rs, so it's not as contrived as it initially appears.

Stacktrace:

$ RUST_BACKTRACE=1 rustc min.rs 
error: internal compiler error: librustc/traits/structural_impls.rs:180: impossible case reached

thread 'main' panicked at 'Box<Any>', librustc_errors/lib.rs:554:9
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
   6: std::panicking::begin_panic
   7: rustc_errors::Handler::bug
   8: rustc::session::opt_span_bug_fmt::{{closure}}
   9: rustc::ty::context::tls::with_opt::{{closure}}
  10: rustc::ty::context::tls::with_context_opt
  11: rustc::ty::context::tls::with_opt
  12: rustc::session::opt_span_bug_fmt
  13: rustc::session::bug_fmt
  14: rustc::traits::structural_impls::<impl rustc::ty::context::Lift<'tcx> for rustc::traits::SelectionError<'a>>::lift_to_tcx
  15: rustc::traits::select::SelectionContext::candidate_from_obligation
  16: rustc::traits::select::SelectionContext::evaluate_stack
  17: rustc::dep_graph::graph::DepGraph::with_anon_task
  18: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  19: rustc::traits::select::SelectionContext::evaluate_candidate
  20: <&'a mut I as core::iter::iterator::Iterator>::next
  21: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  22: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  23: rustc::dep_graph::graph::DepGraph::with_anon_task
  24: rustc::traits::select::SelectionContext::candidate_from_obligation
  25: rustc::traits::select::SelectionContext::evaluate_stack
  26: rustc::dep_graph::graph::DepGraph::with_anon_task
  27: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  28: rustc::traits::select::SelectionContext::evaluate_candidate
  29: <&'a mut I as core::iter::iterator::Iterator>::next
  30: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  31: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  32: rustc::dep_graph::graph::DepGraph::with_anon_task
  33: rustc::traits::select::SelectionContext::candidate_from_obligation
  34: rustc::traits::select::SelectionContext::evaluate_stack
  35: rustc::dep_graph::graph::DepGraph::with_anon_task
  36: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  37: rustc::traits::select::SelectionContext::evaluate_candidate
  38: <&'a mut I as core::iter::iterator::Iterator>::next
  39: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  40: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  41: rustc::dep_graph::graph::DepGraph::with_anon_task
  42: rustc::traits::select::SelectionContext::candidate_from_obligation
  43: rustc::traits::select::SelectionContext::evaluate_stack
  44: rustc::dep_graph::graph::DepGraph::with_anon_task
  45: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  46: rustc::traits::select::SelectionContext::evaluate_candidate
  47: <&'a mut I as core::iter::iterator::Iterator>::next
  48: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  49: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  50: rustc::dep_graph::graph::DepGraph::with_anon_task
  51: rustc::traits::select::SelectionContext::candidate_from_obligation
  52: rustc::traits::select::SelectionContext::evaluate_stack
  53: rustc::dep_graph::graph::DepGraph::with_anon_task
  54: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  55: rustc::traits::select::SelectionContext::evaluate_candidate
  56: <&'a mut I as core::iter::iterator::Iterator>::next
  57: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  58: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  59: rustc::dep_graph::graph::DepGraph::with_anon_task
  60: rustc::traits::select::SelectionContext::candidate_from_obligation
  61: rustc::traits::select::SelectionContext::evaluate_stack
  62: rustc::dep_graph::graph::DepGraph::with_anon_task
  63: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  64: rustc::traits::select::SelectionContext::evaluate_candidate
  65: <&'a mut I as core::iter::iterator::Iterator>::next
  66: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  67: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  68: rustc::dep_graph::graph::DepGraph::with_anon_task
  69: rustc::traits::select::SelectionContext::candidate_from_obligation
  70: rustc::traits::select::SelectionContext::evaluate_stack
  71: rustc::dep_graph::graph::DepGraph::with_anon_task
  72: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  73: rustc::traits::select::SelectionContext::evaluate_candidate
  74: <&'a mut I as core::iter::iterator::Iterator>::next
  75: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  76: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  77: rustc::dep_graph::graph::DepGraph::with_anon_task
  78: rustc::traits::select::SelectionContext::candidate_from_obligation
  79: rustc::traits::select::SelectionContext::evaluate_stack
  80: rustc::dep_graph::graph::DepGraph::with_anon_task
  81: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  82: rustc::traits::select::SelectionContext::evaluate_candidate
  83: <&'a mut I as core::iter::iterator::Iterator>::next
  84: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  85: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  86: rustc::dep_graph::graph::DepGraph::with_anon_task
  87: rustc::traits::select::SelectionContext::candidate_from_obligation
  88: rustc::traits::select::SelectionContext::evaluate_stack
  89: rustc::dep_graph::graph::DepGraph::with_anon_task
  90: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
  91: rustc::traits::select::SelectionContext::evaluate_candidate
  92: <&'a mut I as core::iter::iterator::Iterator>::next
  93: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T, I>>::from_iter
  94: rustc::traits::select::SelectionContext::candidate_from_obligation_no_cache
  95: rustc::dep_graph::graph::DepGraph::with_anon_task
  96: rustc::traits::select::SelectionContext::candidate_from_obligation
  97: rustc::traits::select::SelectionContext::evaluate_stack
  98: rustc::dep_graph::graph::DepGraph::with_anon_task
  99: rustc::traits::select::SelectionContext::evaluate_predicate_recursively
query stack during panic:
#0 [evaluate_obligation] evaluating trait selection obligation `Bears<_>: ReflectDrop`
#1 [typeck_tables_of] processing `<Bears<T> as PinDropInternal>::is_valid::{{initializer}}`
#2 [const_eval] const-evaluating `<Bears<T> as PinDropInternal>::is_valid::{{initializer}}`
#3 [typeck_tables_of] processing `<Bears<T> as PinDropInternal>::is_valid`
#4 [typeck_item_bodies] type-checking all item bodies
end of query stack
error: aborting due to previous error


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.27.0-nightly (8a37c75a3 2018-05-02) running on x86_64-apple-darwin

$ rustc --version --verbose
rustc 1.27.0-nightly (8a37c75a3 2018-05-02)
binary: rustc
commit-hash: 8a37c75a3a661385cc607d934c70e86a9eaf5fd7
commit-date: 2018-05-02
host: x86_64-apple-darwin
release: 1.27.0-nightly
LLVM version: 6.0
@pietroalbini pietroalbini added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ A-specialization Area: Trait impl specialization C-bug Category: This is a bug. labels May 4, 2018
@cuviper cuviper added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 4, 2018
@memoryruins
Copy link
Contributor

The test case overflows on rustc 1.31.0-nightly (f99911a4a 2018-10-23)

   Compiling playground v0.0.1 (/playground)
error[E0275]: overflow evaluating the requirement `Bears<_>: std::marker::Sized`
  |
  = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`
  = note: required because of the requirements on the impl of `ReflectDrop` for `Bears<_>`

error: aborting due to previous error

@jonas-schievink jonas-schievink added A-associated-items Area: Associated items such as associated types and consts. F-specialization `#![feature(specialization)]` labels Sep 15, 2019
@Centril Centril added the requires-nightly This issue requires a nightly compiler in some way. label Oct 25, 2019
@WaffleLapkin
Copy link
Member

The code doesn't produce ICE anymore (tested on 1.47.0-nightly (2020-07-25 d6953df14657f5932270)), instead, the following error is produced:

error: constant expression depends on a generic parameter
  --> src/main.rs:20:22
   |
20 |         let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize];
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this may fail depending on what value the parameter takes

(playground)

@matthiaskrgr
Copy link
Member

this no longer crashes rustc 1.57.0-nightly (497ee321a 2021-09-09), marking as needs-test
@rustbot modify labels: E-needs-test

@rustbot rustbot added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Sep 10, 2021
@TaKO8Ki TaKO8Ki self-assigned this Jun 30, 2022
TaKO8Ki added a commit to TaKO8Ki/rust that referenced this issue Jun 30, 2022
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 2, 2022
Rollup of 6 pull requests

Successful merges:

 - rust-lang#98701 (Add regression test for rust-lang#50439)
 - rust-lang#98715 (add ice test for rust-lang#97047)
 - rust-lang#98753 (Fix `x dist rust-dev` on a fresh checkout)
 - rust-lang#98805 (Add rust-lang#95469 to the release notes)
 - rust-lang#98812 (feat: Add a documentation problem issue template)
 - rust-lang#98819 (update Miri)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors closed this as completed in 27983d3 Jul 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items such as associated types and consts. A-specialization Area: Trait impl specialization C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-specialization `#![feature(specialization)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. 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.

10 participants