Skip to content

ICE: Type parameter W/#1 out of range when substituting #55872

Closed
@DutchGhost

Description

@DutchGhost

Playing with async/await, using

  • Futures: futures-preview = "0.3.0-alpha.9"
  • Tokio: tokio = { version = "0.1.0", features = ["async-await-preview"] }

and some nightly features, I stumbled upon this ICE.
(possibly related to #55265)

#![feature(await_macro, async_await, futures_api, pin, existential_type)]

macro_rules! async_for {
    ($item:ident in $stream:ident $todo:block) => (
        while let Some($item) = await!($stream.next()) $todo
    )
}

use futures::{Stream, Future};
use std::marker::Unpin;

use futures::StreamExt as StreamExt;

use tokio::prelude::{AsyncWriteExt};

pub trait Sip
where
    Self: Stream
{
    type Future: Future;

    fn start_sip<W, F>(self, writer: W, convert: F) -> Self::Future
    where
        W: AsyncWriteExt + Unpin,
        F: Fn(&Self::Item) -> &[u8] + Unpin
    ;
}

impl <S> Sip for S
where
    S: Stream + Unpin,
{
    existential type Future: Future<Output = ()>;

    fn start_sip<W, F>(mut self, mut writer: W, mut convert: F) -> Self::Future
    where
        W: AsyncWriteExt + Unpin,
        F: Fn(&Self::Item) -> &[u8] + Unpin
    {
        async move {
            async_for!(item in self {
                let bytes = convert(&item);
                await!(writer.write_async(bytes));
            });

            await!(tokio::io::shutdown(writer).into_awaitable());
        }
    }
}
Backtrace:
error: internal compiler error: librustc\ty\subst.rs:462: Type parameter `W/#1` (W/1) out of range when substituting (root type=Some(impl futures::Future)) substs=[S]

thread 'main' panicked at 'Box<Any>', librustc_errors\lib.rs:538:9
stack backtrace:
   0: <std::future::SetOnDrop as core::ops::drop::Drop>::drop
   1: std::panicking::take_hook
   2: std::panicking::take_hook
   3: <rustc::ty::sty::Binder<rustc::ty::ProjectionPredicate<'tcx>> as rustc::ty::ToPredicate<'tcx>>::to_predicate
   4: std::panicking::rust_panic_with_hook
   5: <usize as rustc::session::config::dep_tracking::DepTrackingHash>::hash
   6: <rustc::traits::query::type_op::outlives::DropckOutlives<'a> as rustc::ty::context::Lift<'tcx>>::lift_to_tcx
   7: rustc::ty::context::tls::track_diagnostic
   8: rustc::ty::context::tls::track_diagnostic
   9: rustc::ty::context::tls::track_diagnostic
  10: rustc::ty::context::tls::track_diagnostic
  11: rustc::util::bug::bug_fmt
  12: rustc::util::bug::bug_fmt
  13: <rustc::ty::subst::SubstFolder<'a, 'gcx, 'tcx> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
  14: rustc::ty::context::TyCtxt::generate_borrow_of_any_match_input
  15: rustc::ty::error::<impl rustc::ty::TyS<'tcx>>::sort_string
  16: <rustc::ty::subst::SubstFolder<'a, 'gcx, 'tcx> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
  17: rustc::ty::context::TyCtxt::generate_borrow_of_any_match_input
  18: rustc::ty::error::<impl rustc::ty::TyS<'tcx>>::sort_string
  19: <rustc::ty::subst::SubstFolder<'a, 'gcx, 'tcx> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
  20: <rustc_mir::hair::pattern::check_match::MutationChecker<'a, 'tcx> as rustc::middle::expr_use_visitor::Delegate<'tcx>>::decl_without_init
  21: rustc_mir::borrow_check::nll::facts::<impl core::convert::From<usize> for rustc_mir::dataflow::move_paths::indexes::BorrowIndex>::from
  22: <rustc_mir::borrow_check::nll::type_check::TypeVerifier<'a, 'b, 'gcx, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_mir
  23: <rustc_mir::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMapBuild<'_, '_> as rustc::mir::visit::Visitor<'tcx>>::visit_local
  24: <rustc_mir::borrow_check::nll::renumber::NLLVisitor<'a, 'gcx, 'tcx> as rustc::mir::visit::MutVisitor<'tcx>>::visit_statement
  25: <rustc_mir::util::borrowck_errors::Origin as core::fmt::Debug>::fmt
  26: <rustc_mir::hair::pattern::check_match::MutationChecker<'a, 'tcx> as rustc::middle::expr_use_visitor::Delegate<'tcx>>::decl_without_init
  27: <rustc_mir::borrow_check::nll::renumber::NLLVisitor<'a, 'gcx, 'tcx> as rustc::mir::visit::MutVisitor<'tcx>>::visit_statement
  28: rustc::ty::query::on_disk_cache::__ty_decoder_impl::<impl serialize::serialize::Decoder for rustc::ty::query::on_disk_cache::CacheDecoder<'a, 'tcx, 'x>>::read_str
  29: rustc::ty::context::tls::track_diagnostic
  30: rustc::ty::context::tls::track_diagnostic
  31: rustc::dep_graph::graph::DepGraph::assert_ignored
  32: rustc::ty::context::tls::track_diagnostic
  33: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  34: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  35: rustc::ty::query::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::mir_borrowck
  36: rustc_driver::set_sigpipe_handler
  37: rustc_driver::set_sigpipe_handler
  38: <rustc_driver::pretty::IdentifiedAnnotation<'hir> as rustc_driver::pretty::HirPrinterSupport<'hir>>::sess
  39: rustc_driver::set_sigpipe_handler
  40: rustc_driver::driver::compile_input
  41: rustc_driver::run_compiler
  42: <rustc_driver::profile::trace::Query as core::fmt::Debug>::fmt
  43: rustc_driver::run_compiler
  44: <humantime::date::Error as std::error::Error>::cause
  45: _rust_maybe_catch_panic
  46: <env_logger::filter::inner::Filter as core::fmt::Display>::fmt
  47: rustc_driver::main
  48: <unknown>
  49: std::panicking::update_panic_count
  50: _rust_maybe_catch_panic
  51: std::rt::lang_start_internal
  52: <unknown>
  53: <unknown>
  54: BaseThreadInitThunk
  55: RtlUserThreadStart
query stack during panic:
#0 [mir_borrowck] processing `<S as sip::Sip>::start_sip`
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.31.0-nightly (de9666f12 2018-10-31) running on x86_64-pc-windows-msvc

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

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

error: Could not compile `webscraper_better`.

No ICE happens when writing the trait and implementation like this (notice the Generic parameters are now on the trait definition rather than on the function):

use futures::{Stream, Future};
use std::marker::Unpin;

use futures::StreamExt as StreamExt;

use tokio::prelude::{AsyncWriteExt};

pub trait Sip<W, F>
where
    Self: Stream
{
    type Future: Future;

    fn start_sip(self, writer: W, convert: F) -> Self::Future
    where
        W: AsyncWriteExt + Unpin,
        F: FnMut(&Self::Item) -> &[u8] + Unpin
    ;
}

impl <W, F, S> Sip<W, F> for S
where
    S: Stream + Unpin,
{
    existential type Future: Future<Output = ()>;

    fn start_sip(mut self, mut writer: W, mut convert: F) -> Self::Future
    where
        W: AsyncWriteExt + Unpin,
        F: FnMut(&Self::Item) -> &[u8] + Unpin
    {
        async move {
            async_for!(item in self {
                let bytes = convert(&item);
                await!(writer.write_async(bytes));
            });

            await!(tokio::io::shutdown(writer).into_awaitable());
        }
    }
}

Metadata

Metadata

Assignees

Labels

A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions