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 when equating TAIT and RPIT in canonical queries #108498

Closed
aliemjay opened this issue Feb 26, 2023 · 3 comments · Fixed by #114586 or #122077
Closed

ICE when equating TAIT and RPIT in canonical queries #108498

aliemjay opened this issue Feb 26, 2023 · 3 comments · Fixed by #114586 or #122077
Assignees
Labels
C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. 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. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@aliemjay
Copy link
Member

aliemjay commented Feb 26, 2023

Code

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=ec86c1b56e1fe08951cf0dbb67ea7d7b

#![feature(type_alias_impl_trait)]

type Opaque = impl Sized;

fn get_rpit() -> impl Clone {}

fn query(_: impl FnOnce() -> Opaque) {}

fn test() -> Opaque {
    query(get_rpit);
    get_rpit()
}

While trying to prove the predicate <get_rpit as FnOnce>::Output == Opaque, we end up equating get_rpit::opaque#0 == Opaque::opaque#0. Because inside canonical queries we know nothing about the defining scope (DefiningAnchor::Bubble), we register the hidden type as get_rpit::opaque := Opaque::opaque instead of Opaque::opaque := get_rpit::opaque.

Cc @oli-obk.

Meta

Nightly version: 1.69.0-nightly (2023-02-25 34e6673)

Error output

Backtrace

warning: type alias `Opaque` is never used
 --> src/lib.rs:3:6
  |
3 | type Opaque = impl Sized;
  |      ^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

warning: function `get_rpit` is never used
 --> src/lib.rs:5:4
  |
5 | fn get_rpit() -> impl Clone {}
  |    ^^^^^^^^

warning: function `query` is never used
 --> src/lib.rs:7:4
  |
7 | fn query(_: impl FnOnce() -> Opaque) {}
  |    ^^^^^

warning: function `test` is never used
 --> src/lib.rs:9:4
  |
9 | fn test() -> Opaque {
  |    ^^^^

error: internal compiler error: no errors encountered even though `delay_span_bug` issued

error: internal compiler error: VecMap([(OpaqueTypeKey { def_id: DefId(0:8 ~ playground[4e8e]::get_rpit::{opaque#0}), substs: [] }, OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Opaque }, origin: FnReturn(DefId(0:4 ~ playground[4e8e]::get_rpit)) })])
  |
  = note: delayed at    0: <rustc_errors::HandlerInner>::emit_diagnostic
             1: <rustc_errors::Handler>::delay_span_bug::<rustc_span::span_encoding::Span, &alloc::string::String>
             2: core::ptr::drop_in_place::<rustc_infer::infer::InferCtxt>
             3: <rustc_infer::infer::InferCtxtBuilder as rustc_trait_selection::infer::InferCtxtBuilderExt>::enter_canonical_trait_query::<rustc_middle::ty::ParamEnvAnd<rustc_middle::traits::query::type_op::ProvePredicate>, (), rustc_traits::type_op::type_op_prove_predicate::{closure#0}>
             4: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::type_op_prove_predicate, rustc_query_impl::plumbing::QueryCtxt, rustc_middle::dep_graph::dep_node::DepKind>
             5: <rustc_middle::ty::ParamEnvAnd<rustc_middle::traits::query::type_op::ProvePredicate> as rustc_trait_selection::traits::query::type_op::TypeOp>::fully_perform
             6: <rustc_borrowck::type_check::TypeChecker>::normalize_and_prove_instantiated_predicates
             7: <rustc_borrowck::type_check::TypeVerifier as rustc_middle::mir::visit::Visitor>::visit_constant
             8: <rustc_borrowck::type_check::TypeVerifier as rustc_middle::mir::visit::Visitor>::visit_body
             9: rustc_borrowck::type_check::type_check
            10: rustc_borrowck::nll::compute_regions
            11: rustc_borrowck::do_mir_borrowck
            12: rustc_borrowck::mir_borrowck
            13: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::queries::mir_borrowck, rustc_query_impl::plumbing::QueryCtxt>
            14: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::mir_borrowck
            15: <rustc_hir_analysis::collect::type_of::find_opaque_ty_constraints_for_tait::ConstraintLocator>::check
            16: <rustc_hir_analysis::collect::type_of::find_opaque_ty_constraints_for_tait::ConstraintLocator as rustc_hir::intravisit::Visitor>::visit_nested_item
            17: rustc_hir::intravisit::walk_mod::<rustc_hir_analysis::collect::type_of::find_opaque_ty_constraints_for_tait::ConstraintLocator>
            18: rustc_hir_analysis::collect::type_of::find_opaque_ty_constraints_for_tait
            19: rustc_hir_analysis::collect::type_of::type_of
            20: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::type_of, rustc_query_impl::plumbing::QueryCtxt, rustc_middle::dep_graph::dep_node::DepKind>
            21: rustc_hir_analysis::check::check::check_mod_item_types
            22: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::queries::check_mod_item_types, rustc_query_impl::plumbing::QueryCtxt>
            23: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::check_mod_item_types
            24: <rustc_middle::hir::map::Map>::for_each_module::<rustc_hir_analysis::check_crate::{closure#6}::{closure#0}>
            25: rustc_hir_analysis::check_crate
            26: rustc_interface::passes::analysis
            27: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::queries::analysis, rustc_query_impl::plumbing::QueryCtxt>
            28: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::analysis
            29: <rustc_middle::ty::context::GlobalCtxt>::enter::<rustc_driver_impl::run_compiler::{closure#1}::{closure#2}::{closure#4}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
            30: <rustc_interface::interface::Compiler>::enter::<rustc_driver_impl::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorGuaranteed>>
            31: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}::{closure#0}>
            32: std::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
            33: <<std::thread::Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
            34: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
                       at /rustc/34e6673a0473e90ef01a18eb575392c9e3859747/library/alloc/src/boxed.rs:1988:9
            35: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
                       at /rustc/34e6673a0473e90ef01a18eb575392c9e3859747/library/alloc/src/boxed.rs:1988:9
            36: std::sys::unix::thread::Thread::new::thread_start
                       at /rustc/34e6673a0473e90ef01a18eb575392c9e3859747/library/std/src/sys/unix/thread.rs:108:17
            37: start_thread
            38: clone
          

error: internal compiler error: broken MIR in DefId(0:6 ~ playground[4e8e]::test) (NoSolution): could not prove Binder(ProjectionPredicate(AliasTy { substs: [fn() -> impl std::clone::Clone {get_rpit}, ()], def_id: DefId(2:2923 ~ core[df15]::ops::function::FnOnce::Output) }, Term::Ty(Opaque)), [])
  |
  = note: delayed at    0: <rustc_errors::HandlerInner>::emit_diagnostic
             1: <rustc_errors::Handler>::delay_span_bug::<rustc_span::span_encoding::Span, &str>
             2: <rustc_borrowck::type_check::TypeChecker>::normalize_and_prove_instantiated_predicates
             3: <rustc_borrowck::type_check::TypeVerifier as rustc_middle::mir::visit::Visitor>::visit_constant
             4: <rustc_borrowck::type_check::TypeVerifier as rustc_middle::mir::visit::Visitor>::visit_body
             5: rustc_borrowck::type_check::type_check
             6: rustc_borrowck::nll::compute_regions
             7: rustc_borrowck::do_mir_borrowck
             8: rustc_borrowck::mir_borrowck
             9: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::queries::mir_borrowck, rustc_query_impl::plumbing::QueryCtxt>
            10: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::mir_borrowck
            11: <rustc_hir_analysis::collect::type_of::find_opaque_ty_constraints_for_tait::ConstraintLocator>::check
            12: <rustc_hir_analysis::collect::type_of::find_opaque_ty_constraints_for_tait::ConstraintLocator as rustc_hir::intravisit::Visitor>::visit_nested_item
            13: rustc_hir::intravisit::walk_mod::<rustc_hir_analysis::collect::type_of::find_opaque_ty_constraints_for_tait::ConstraintLocator>
            14: rustc_hir_analysis::collect::type_of::find_opaque_ty_constraints_for_tait
            15: rustc_hir_analysis::collect::type_of::type_of
            16: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::type_of, rustc_query_impl::plumbing::QueryCtxt, rustc_middle::dep_graph::dep_node::DepKind>
            17: rustc_hir_analysis::check::check::check_mod_item_types
            18: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::queries::check_mod_item_types, rustc_query_impl::plumbing::QueryCtxt>
            19: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::check_mod_item_types
            20: <rustc_middle::hir::map::Map>::for_each_module::<rustc_hir_analysis::check_crate::{closure#6}::{closure#0}>
            21: rustc_hir_analysis::check_crate
            22: rustc_interface::passes::analysis
            23: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::queries::analysis, rustc_query_impl::plumbing::QueryCtxt>
            24: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::analysis
            25: <rustc_middle::ty::context::GlobalCtxt>::enter::<rustc_driver_impl::run_compiler::{closure#1}::{closure#2}::{closure#4}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
            26: <rustc_interface::interface::Compiler>::enter::<rustc_driver_impl::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorGuaranteed>>
            27: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}::{closure#0}>
            28: std::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
            29: <<std::thread::Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
            30: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
                       at /rustc/34e6673a0473e90ef01a18eb575392c9e3859747/library/alloc/src/boxed.rs:1988:9
            31: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
                       at /rustc/34e6673a0473e90ef01a18eb575392c9e3859747/library/alloc/src/boxed.rs:1988:9
            32: std::sys::unix::thread::Thread::new::thread_start
                       at /rustc/34e6673a0473e90ef01a18eb575392c9e3859747/library/std/src/sys/unix/thread.rs:108:17
            33: start_thread
            34: clone
          

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.69.0-nightly (34e6673a0 2023-02-25) running on x86_64-unknown-linux-gnu

note: compiler flags: --crate-type lib -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2

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

query stack during panic:
end of query stack
warning: `playground` (lib) generated 4 warnings
error: could not compile `playground`; 4 warnings emitted

@rustbot label F-type_alias_impl_trait T-types

@aliemjay aliemjay 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 Feb 26, 2023
@rustbot rustbot added F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-types Relevant to the types team, which will review and decide on the PR/issue. labels Feb 26, 2023
@compiler-errors
Copy link
Member

This would require some more design and stuff -- but I wonder if, when we relate an opaque with another opaque in a DefiningAnchor::Bubble scope, we should emit some other sort of opaque type constraint, like OpaqueEq(LHS, RHS), that isn't just LHS := RHS. Then when we instantiate it in some other infcx, we'll choose whether LHS := RHS or RHS := LHS depending on what the defining anchor of that one is.

@oli-obk
Copy link
Contributor

oli-obk commented Feb 28, 2023

yea, that was always the plan, but it seemed too niche to put the effort in for now

@oli-obk oli-obk self-assigned this Feb 28, 2023
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Mar 12, 2023
@oli-obk oli-obk added the fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. label Aug 7, 2023
@bors bors closed this as completed in e2b3676 Sep 11, 2023
github-actions bot pushed a commit to rust-lang/miri that referenced this issue Sep 12, 2023
…ompiler-errors

Bubble up opaque <eq> opaque operations instead of picking an order

In case we are in `Bubble` mode (meaning every opaque type that is defined in the current crate is treated as if it were in its defining scope), we don't try to register an opaque type as the hidden type of another opaque type, but instead bubble up an obligation to equate them at the query caller site. Usually that means we have a `DefiningAnchor::Bind` and thus can reliably figure out whether an opaque type is in its defining scope. Where we can't, we'll error out, so the default is sound.

With this change we start using `AliasTyEq` predicates in the old solver, too.

fixes rust-lang/rust#108498

But also regresses `tests/ui/impl-trait/anon_scope_creep.rs`. Our use of `Bubble` for `check_opaque_type_well_formed` is going to keep biting us.

r? `@lcnr` `@compiler-errors`
@aliemjay
Copy link
Member Author

aliemjay commented Oct 8, 2023

Reopened because the fix was incomplete. See #116530

@aliemjay aliemjay reopened this Oct 8, 2023
bors added a commit to rust-lang-ci/rust that referenced this issue Mar 11, 2024
Pass list of defineable opaque types into canonical queries

based on rust-lang#121796

This eliminates `DefiningAnchor::Bubble` for good and brings the old solver closer to the new one wrt cycles and nested obligations. At that point the difference between `DefiningAnchor::Bind([])` and `DefiningAnchor::Error` was academic. We only used the difference for some sanity checks, which actually had to be worked around in places, so I just removed `DefiningAnchor` entirely and just stored the list of opaques that may be defined.

fixes rust-lang#108498

* [ ] run crater
bors added a commit to rust-lang-ci/rust that referenced this issue Mar 13, 2024
Pass list of defineable opaque types into canonical queries

This eliminates `DefiningAnchor::Bubble` for good and brings the old solver closer to the new one wrt cycles and nested obligations. At that point the difference between `DefiningAnchor::Bind([])` and `DefiningAnchor::Error` was academic. We only used the difference for some sanity checks, which actually had to be worked around in places, so I just removed `DefiningAnchor` entirely and just stored the list of opaques that may be defined.

fixes rust-lang#108498

* [ ] run crater
lnicola pushed a commit to lnicola/rust-analyzer that referenced this issue Apr 7, 2024
…ompiler-errors

Bubble up opaque <eq> opaque operations instead of picking an order

In case we are in `Bubble` mode (meaning every opaque type that is defined in the current crate is treated as if it were in its defining scope), we don't try to register an opaque type as the hidden type of another opaque type, but instead bubble up an obligation to equate them at the query caller site. Usually that means we have a `DefiningAnchor::Bind` and thus can reliably figure out whether an opaque type is in its defining scope. Where we can't, we'll error out, so the default is sound.

With this change we start using `AliasTyEq` predicates in the old solver, too.

fixes rust-lang/rust#108498

But also regresses `tests/ui/impl-trait/anon_scope_creep.rs`. Our use of `Bubble` for `check_opaque_type_well_formed` is going to keep biting us.

r? `@lcnr` `@compiler-errors`
@bors bors closed this as completed in b234e44 Apr 9, 2024
RalfJung pushed a commit to RalfJung/rust-analyzer that referenced this issue Apr 27, 2024
…ompiler-errors

Bubble up opaque <eq> opaque operations instead of picking an order

In case we are in `Bubble` mode (meaning every opaque type that is defined in the current crate is treated as if it were in its defining scope), we don't try to register an opaque type as the hidden type of another opaque type, but instead bubble up an obligation to equate them at the query caller site. Usually that means we have a `DefiningAnchor::Bind` and thus can reliably figure out whether an opaque type is in its defining scope. Where we can't, we'll error out, so the default is sound.

With this change we start using `AliasTyEq` predicates in the old solver, too.

fixes rust-lang/rust#108498

But also regresses `tests/ui/impl-trait/anon_scope_creep.rs`. Our use of `Bubble` for `check_opaque_type_well_formed` is going to keep biting us.

r? `@lcnr` `@compiler-errors`
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. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. 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. T-types Relevant to the types team, which will review and decide on the PR/issue.
5 participants