Skip to content

Where clause Binder(<...>) was applicable to Obligation(predicate=Binder(TraitPredicate(<...>)),depth=1) but now is not #52893

Closed
@akiselev

Description

@akiselev

EDITED: MCVE is here: #52893 (comment)

error: internal compiler error: librustc\traits\select.rs:2469: Where clause `Binder(<Class<P, T> as At<Name>>)` was applicable to `Obligation(predicate=Binder(TraitPredicate(<Class<_, _> as At<_>>)),depth=1)` but now is not

thread 'main' panicked at 'Box<Any>', librustc_errors\lib.rs:554:9
stack backtrace:
   0: <u128 as compiler_builtins::int::Int>::min_value
   1: <std::sync::mpsc::RecvTimeoutError as std::error::Error>::cause
   2: std::panicking::take_hook
   3: std::panicking::take_hook
   4: rustc::ty::structural_impls::<impl rustc::ty::context::Lift<'tcx> for rustc::middle::const_val::ErrKind<'a>>::lift_to_tcx
   5: std::panicking::rust_panic_with_hook
   6: <rustc_errors::diagnostic::SubDiagnostic as core::fmt::Debug>::fmt
   7: rustc_errors::Handler::bug
   8: rustc::mir::interpret::UndefMask::grow
   9: rustc::ty::context::tls::track_diagnostic
  10: rustc::ty::context::tls::track_diagnostic
  11: rustc::ty::context::tls::track_diagnostic
  12: rustc::session::bug_fmt
  13: rustc::session::bug_fmt
  14: rustc::traits::select::SelectionContext::coinductive_predicate
  15: rustc::traits::select::SelectionContext::select
  16: rustc::infer::InferCtxt::commit_from
  17: rustc::traits::project::normalize_projection_type
  18: rustc::traits::project::normalize_projection_type
  19: <rustc::traits::project::AssociatedTypeNormalizer<'a, 'b, 'gcx, 'tcx> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
  20: <rustc::hir::intravisit::IdRange as core::fmt::Debug>::fmt
  21: rustc::ty::fast_reject::simplify_type
  22: rustc::ty::fast_reject::simplify_type
  23: rustc::traits::project::poly_project_and_unify_type
  24: rustc::ty::context::TyCtxt::_intern_canonical_var_infos
  25: <unknown>
  26: <unknown>
  27: rustc::traits::select::SelectionContext::coinductive_predicate
  28: rustc::traits::select::SelectionContext::coinductive_predicate
  29: rustc::traits::select::SelectionContext::select
  30: rustc::infer::InferCtxt::commit_from
  31: rustc::traits::project::normalize_projection_type
  32: rustc::traits::project::normalize_projection_type
  33: <rustc::traits::project::AssociatedTypeNormalizer<'a, 'b, 'gcx, 'tcx> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
  34: <rustc_typeck::coherence::inherent_impls_overlap::InherentOverlapChecker<'a, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'v>>::visit_trait_item
  35: <rustc_typeck::check::method::probe::ProbeContext<'a, 'gcx, 'tcx> as core::ops::deref::Deref>::deref
  36: <rustc_typeck::check::method::probe::ProbeContext<'a, 'gcx, 'tcx> as core::ops::deref::Deref>::deref
  37: <rustc_typeck::check::method::probe::ProbeContext<'a, 'gcx, 'tcx> as core::ops::deref::Deref>::deref
  38: rustc_typeck::hir_trait_to_predicates
  39: <unknown>
  40: <unknown>
  41: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  42: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  43: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  44: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  45: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  46: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  47: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  48: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  49: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  50: <rustc_typeck::check::GatherLocalsVisitor<'a, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_pat
  51: <rustc_typeck::coherence::inherent_impls_overlap::InherentOverlapChecker<'a, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'v>>::visit_trait_item
  52: <rustc_typeck::check::CheckItemTypesVisitor<'a, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'tcx>>::visit_item
  53: rustc::ty::maps::<impl rustc::ty::maps::config::QueryConfig<'tcx> for rustc::ty::maps::queries::typeck_tables_of<'tcx>>::compute
  54: rustc::ty::context::tls::track_diagnostic
  55: rustc::dep_graph::graph::DepGraph::assert_ignored
  56: rustc::ty::context::tls::track_diagnostic
  57: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_mark_green_and_read
  58: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_mark_green_and_read
  59: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_mark_green_and_read
  60: <rustc_typeck::check::Diverges as core::fmt::Debug>::fmt
  61: <rustc_typeck::check::CheckItemTypesVisitor<'a, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'tcx>>::visit_item
  62: rustc::ty::context::tls::track_diagnostic
  63: rustc::dep_graph::graph::DepGraph::assert_ignored
  64: rustc::ty::context::tls::track_diagnostic
  65: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_mark_green_and_read
  66: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_mark_green_and_read
  67: rustc_typeck::check_crate
  68: <env_logger::Logger as log::Log>::flush
  69: <rustc_driver::pretty::UserIdentifiedItem as core::fmt::Debug>::fmt
  70: <unknown>
  71: rustc_driver::driver::compile_input
  72: rustc_driver::run_compiler
  73: rustc_driver::driver::build_output_filenames
  74: <unknown>
  75: rustc_driver::driver::build_output_filenames
  76: _rust_maybe_catch_panic
  77: rustc_driver::profile::trace::write_style
  78: rustc_driver::main
  79: <unknown>
  80: std::panicking::update_panic_count
  81: _rust_maybe_catch_panic
  82: std::rt::lang_start_internal
  83: <unknown>
  84: <unknown>
  85: BaseThreadInitThunk
  86: RtlUserThreadStart
query stack during panic:
#0 [typeck_tables_of] processing `<Class<P, T> as AddClass<Name, F>>::init`
#1 [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.2 (58cc626de 2018-07-18) running on x86_64-pc-windows-msvc

note: compiler flags: -C debuginfo=2 -C incremental --crate-type lib

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

with

rustc 1.27.2 (58cc626de 2018-07-18)
binary: rustc
commit-hash: 58cc626de3301192d5d8c6dcbde43b5b44211ae2
commit-date: 2018-07-18
host: x86_64-pc-windows-msvc
release: 1.27.2
LLVM version: 6.0

From the code (Offending implementation at the top, specifically <X as Entry>::Data: Fn(Y) -> Class<P, OLIST>:

extern crate frunk;
extern crate frunk_core;

use std::marker::PhantomData;
use frunk::*;
use frunk::prelude::*;

impl<P, T, Name, F, OLIST: HList, X, Y, FINAL> AddClass<Name, F> for Class<P, T> 
where
    Self: At<Name>,
    Self::AtRes: Entry<Data=T>,
    X: Entry,
    F: Fn(Y) ->OLIST,
    T: Push<(PhantomData<HCons<Name, HCons<P, HNil>>>, F)>,
    <X as Entry>::Data: Fn(Y) -> Class<P, OLIST>,
    <Class<P, T> as At<Name>>::AtRes: Push<(Path<Hlist![Name, P]>, F)>,
    <<Class<P, T> as At<Name>>::AtRes as Push<(Path<Hlist![Name, P]>, F)>>::PushRes: for<'this> ToRef<'this, Output=HCons<X, Y>> + Push<OLIST>,
    <<<Class<P, T> as At<Name>>::AtRes as Push<(Path<HCons<Name, HCons<P, HNil>>>, F)>>::PushRes as Push<OLIST>>::PushRes: Entry<Data=FINAL>
{
    type Output = Class<P, FINAL>;

    fn init(self, func: F) -> Self::Output {
        let builder = self.at();
        let builder = builder.push((Path::new(), func));
        let output = {
            let refs = builder.to_ref();
            let func = refs.head.borrow_data();
            func(refs.tail)
        };
        let final_data = builder.push(output);
        Class {
            path: Path::new(),
            data: final_data.get_data()
        }
    }
}

struct Class<P, T> {
    path: Path<P>,
    data: T
}

trait At<Name> {
    type AtRes;

    fn at(self) -> Self::AtRes;
}

trait Push<T> {
    type PushRes;

    fn push(self, other: T) -> Self::PushRes;
}

impl<T> Push<T> for HNil {
    type PushRes = HCons<T, HNil>;

    fn push(self, other: T) -> HCons<T, HNil> {
        HCons {
            head: other,
            tail: HNil
        }
    }
}

impl<T, HEAD, TAIL> Push<T> for HCons<HEAD, TAIL> {
    type PushRes = HCons<T, HCons<HEAD, TAIL>>;

    fn push(self, other: T) -> HCons<T, HCons<HEAD, TAIL>> {
        HCons {
            head: other,
            tail: self
        }
    }
}

impl<Name, P, T> At<Name> for Class<P, T> {
    type AtRes = Class<HCons<Name, P>, T>;

    fn at(self) -> Class<HCons<Name, P>, T> {
        Class {
            path: Path::new(),
            data: self.data
        }
    }
}

trait AddClass<Name, F>: At<Name> {
    type Output;

    fn init(self, func: F) -> Self::Output;
}

trait Entry {
    type Path;
    type Data;

    fn get_data(self) -> Self::Data;
    fn borrow_data(&self) -> &Self::Data;
}

impl<N, T> Entry for (N, T) {
    type Path = N;
    type Data = T;

    fn get_data(self) -> Self::Data {
        self.1
    }

    fn borrow_data(&self) -> &Self::Data {
        &self.1
    }
}

impl<N, T> Entry for Class<N, T> {
    type Path = N;
    type Data = T;

    fn get_data(self) -> Self::Data {
        self.data
    }

    fn borrow_data(&self) -> &Self::Data {
        &self.data
    }
}

impl<'this, P, T: 'this> ToRef<'this> for Class<P, T>
where
    <Class<P, T> as Entry>::Data: ToRef<'this>,
    <T as frunk_core::traits::ToRef<'this>>::Output: 'this,
    T: frunk_core::traits::ToRef<'this>,
{
    type Output = <<Self as Entry>::Data as ToRef<'this>>::Output;

    fn to_ref(&'this self) -> <T as ToRef<'this>>::Output {
        self.borrow_data().to_ref()
    }
}

impl<P: HList, T> Class<P, T> {
    fn at<Name>(self) -> Class<HCons<Name, P>, T> {
        Class {
            path: Path::new(),
            data: self.data
        }
    }

    fn with<Name, F>(self, constructor: F) -> <Self as AddClass<Name, F>>::Output
    where 
        Self: AddClass<Name, F>
    {
        self.init(constructor)
    }

    fn from<F>(self, constructor: F) -> <Self as AddClass<P, F>>::Output
    where 
        Self: AddClass<P, F>
    {
        self.init(constructor)
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Path<T> {
    path: PhantomData<T>
}

impl<P> Path<P> {
    pub fn new() -> Path<P> {
        Path {
            path: PhantomData
        }
    }
}

pub struct VEntry<P, T> {
    path: Path<P>,
    data: PhantomData<T>
}

Changing F: Fn(Y) -> OLIST to F: Fn(Y) -> Class<P, OLIST> does not fix the crash. Changing <X as Entry>::Data: Fn(Y) -> Class<P, OLIST> to <X as Entry>::Data: Fn(Y) -> OLIST compiles. The latter is the correct implementation and I discovered this crash in the middle of some refactoring so I did not expect anything specific to happen except a type checking error.

The crash also happens in nightly 2018-7-23 and 2018-7-30.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-trait-systemArea: Trait systemC-bugCategory: This is a bug.E-needs-testCall 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) ❄️ICEBreaker-Cleanup-CrewHelping to "clean up" bugs with minimal examples and bisectionsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions