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

Existential types for traits without generic type parameters make rustc panic #59342

Closed
ghost opened this issue Mar 21, 2019 · 4 comments · Fixed by #66178
Closed

Existential types for traits without generic type parameters make rustc panic #59342

ghost opened this issue Mar 21, 2019 · 4 comments · Fixed by #66178
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` 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

@ghost
Copy link

ghost commented Mar 21, 2019

I tried this code:

#![feature(existential_type)]

trait Meow {
    type MeowType;
    fn meow(self) -> Self::MeowType;
}

impl<T, I> Meow for I
    where I: Iterator<Item = T>
{
    existential type MeowType: Iterator<Item = T>;
    fn meow(self) -> Self::MeowType {
        self
    }
}

fn main() {
}

I expected to be able to compile this code and to use it like this:

let result: Vec<i32> = vec![1, 2, 3].into_iter().meow().collect();

Instead, rustc crashes (see backtrace in the end of the issue).

However, the code compiles fine when I add generic type parameter to Meow trait definition:

#![feature(existential_type)]

trait Meow<T> {
    type MeowType;
    fn meow(self) -> Self::MeowType;
}

impl<T, I> Meow<T> for I
    where I: Iterator<Item = T>
{
    existential type MeowType: Iterator<Item = T>;
    fn meow(self) -> Self::MeowType {
        self
    }
}


fn main() {
}

Meta

rustc --version --verbose:

rustc 1.35.0-nightly (82e2f3ec2 2019-03-20)
binary: rustc
commit-hash: 82e2f3ec25a316c7536c33a6b6704366b14cbf2a
commit-date: 2019-03-20
host: x86_64-apple-darwin
release: 1.35.0-nightly
LLVM version: 8.0

Backtrace:

thread 'rustc' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:345:21
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
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::continue_panic_fmt
   7: rust_begin_unwind
   8: core::panicking::panic_fmt
   9: core::panicking::panic
  10: rustc_typeck::check::writeback::WritebackCx::visit_opaque_types
  11: rustc_typeck::check::writeback::<impl rustc_typeck::check::FnCtxt>::resolve_type_vars_in_body
  12: rustc::ty::context::GlobalCtxt::enter_local
  13: rustc_typeck::check::typeck_tables_of
  14: rustc::ty::query::__query_compute::typeck_tables_of
  15: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::typeck_tables_of>::compute
  16: rustc::dep_graph::graph::DepGraph::with_task_impl
  17: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  18: rustc_typeck::collect::find_existential_constraints::ConstraintLocator::check
  19: rustc::hir::intravisit::Visitor::visit_nested_impl_item
  20: rustc::hir::intravisit::walk_item
  21: rustc_typeck::collect::find_existential_constraints
  22: rustc_typeck::collect::type_of
  23: rustc::ty::query::__query_compute::type_of
  24: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::type_of>::compute
  25: rustc::dep_graph::graph::DepGraph::with_task_impl
  26: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  27: <rustc_typeck::collect::CollectItemTypesVisitor as rustc::hir::intravisit::Visitor>::visit_impl_item
  28: rustc::hir::map::Map::visit_item_likes_in_module
  29: rustc_typeck::collect::collect_mod_item_types
  30: rustc::ty::query::__query_compute::collect_mod_item_types
  31: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::collect_mod_item_types>::compute
  32: rustc::dep_graph::graph::DepGraph::with_task_impl
  33: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  34: rustc_typeck::check_crate::{{closure}}::{{closure}}
  35: rustc::util::common::time
  36: rustc_typeck::check_crate
  37: rustc_interface::passes::analysis
  38: rustc::ty::query::__query_compute::analysis
  39: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::analysis>::compute
  40: rustc::dep_graph::graph::DepGraph::with_task_impl
  41: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  42: rustc::ty::context::tls::enter_global
  43: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  44: rustc_interface::passes::create_global_ctxt::{{closure}}
  45: rustc_interface::passes::BoxedGlobalCtxt::enter
  46: rustc_interface::interface::run_compiler_in_existing_thread_pool
  47: std::thread::local::LocalKey<T>::with
  48: scoped_tls::ScopedKey<T>::set
  49: syntax::with_globals
query stack during panic:
#0 [typeck_tables_of] processing `<I as Meow>::meow`
#1 [type_of] processing `<I as Meow>::MeowType`
#2 [collect_mod_item_types] collecting item types in top-level module
#3 [analysis] running analysis passes on this crate
end of query stack

error: internal compiler error: unexpected panic

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.35.0-nightly (82e2f3ec2 2019-03-20) running on x86_64-apple-darwin
@jonas-schievink jonas-schievink added 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. A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. labels Mar 21, 2019
@Arnavion
Copy link

@a-rodin Note that it's better to not lift the assoc type I::Item into a type parameter in the first place:

impl<I> Meow for I
    where I: Iterator
{
    existential type MeowType: Iterator<Item = I::Item>;
    fn meow(self) -> Self::MeowType {
        self
    }
}

@ghost
Copy link
Author

ghost commented Apr 16, 2019

@Arnavion
But what if I want to have separate implementations for T = f32 and T = i32?

@Centril Centril added F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` requires-nightly This issue requires a nightly compiler in some way. labels Jul 28, 2019
@Aaron1011
Copy link
Member

This now compiles on the latest nightly.

@ghost
Copy link
Author

ghost commented Jul 31, 2019

bors added a commit that referenced this issue Nov 25, 2019
Fix opaque types resulting from projections in function signature

When we normalize the types in a function signature, we may end up
resolving a projection to an opaque type (e.g. `Self::MyType` when
we have `type MyType = impl SomeTrait`). When the projection is
resolved, we will instantiate the generic parameters into fresh
inference variables.

While we do want to normalize projections to opaque types, we don't want
to replace the explicit generic parameters (e.g. `T` in `impl
MyTrait<T>`) with inference variables. We want the opaque type in the
function signature to be eligible to be a defining use of that opaque
type - adding inference variables prevents this, since the opaque type
substs now appears to refer to some specific type, rather than a generic
type.

To resolve this issue, we inspect the opaque types in the function
signature after normalization. Any inference variables in the substs are
replaced with the corresponding generic parameter in the identity substs
(e.g. `T` in `impl MyTrait<T>`). Note that normalization is the only way
that we can end up with inference variables in opaque substs in a
function signature - users have no way of getting inference variables
into a function signature.

Note that all of this refers to the opaque type (ty::Opaque) and its
subst - *not* to the underlying type.

Fixes #59342
@bors bors closed this as completed in 4b57d22 Nov 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` 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.
Development

Successfully merging a pull request may close this issue.

4 participants