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

Trait bounds not checked on specializable associated types #33017

Closed
apasel422 opened this issue Apr 15, 2016 · 11 comments · Fixed by #84496
Closed

Trait bounds not checked on specializable associated types #33017

apasel422 opened this issue Apr 15, 2016 · 11 comments · Fixed by #84496
Labels
A-associated-items Area: Associated items (types, constants & functions) 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-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-medium Medium priority 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

@apasel422
Copy link
Contributor

foo.rs:

#![feature(specialization)]

trait Foo: Sized {
    type Bar: From<Self>;
}

impl Foo for i32 {
    default type Bar = ();
}

fn xyz<T: Foo>(t: T) -> T::Bar {
    t.into()
}

fn main() {
    xyz(5i32);
}
> rustc --version
rustc 1.10.0-nightly (2174bd97c 2016-04-14)
> RUST_BACKTRACE=1 rustc foo.rs 
error: internal compiler error: ../src/librustc/infer/mod.rs:544: Encountered errors `[FulfillmentError(Obligation(predicate=Binder(TraitPredicate(<() as std::convert::From<i32>>)),depth=1),Unimplemented)]` fulfilling during trans
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: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'Box<Any>', ../src/libsyntax/errors/mod.rs:536
stack backtrace:
   1:     0x7f075adfc600 - std::sys::backtrace::tracing::imp::write::h9fb600083204ae7f
   2:     0x7f075ae09d4b - std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::hca543c34f11229ac
   3:     0x7f075ae098ec - std::panicking::default_hook::hc2c969e7453d080c
   4:     0x7f075adce8bf - std::sys_common::unwind::begin_unwind_inner::h30e12d15ce2b2e25
   5:     0x7f0759d28008 - std::sys_common::unwind::begin_unwind::h24c4c0fa2cfe995a
   6:     0x7f0759d27fab - syntax::errors::Handler::span_bug::h1c6b996df38ae8d7
   7:     0x7f0759d5c152 - rustc::session::opt_span_bug_fmt::_$u7b$$u7b$closure$u7d$$u7d$::hf0fb5697f8f25f40
   8:     0x7f0759d5c042 - rustc::session::span_bug_fmt::h4591bcbadfc38558
   9:     0x7f0759d6ffb3 - rustc_trans::common::fulfill_obligation::hb97500cd4d49823c
  10:     0x7f0759e6dc39 - _<collector..MirNeighborCollector<'a, 'tcx> as rustc..mir..visit..Visitor<'tcx>>::visit_operand::hc9aaa9442e0c17d2
  11:     0x7f0759e695f6 - rustc_trans::collector::collect_items_rec::hd5e212e77fc53d1a
  12:     0x7f0759e697ad - rustc_trans::collector::collect_items_rec::hd5e212e77fc53d1a
  13:     0x7f0759dabc86 - rustc_trans::base::collect_translation_items::_$u7b$$u7b$closure$u7d$$u7d$::h33d9d5954414c1ad
  14:     0x7f0759d99510 - rustc_trans::base::trans_crate::h6ed1dbd6e572a8c2
  15:     0x7f075b36215f - rustc_driver::driver::phase_4_translate_to_llvm::hd7579aae98641824
  16:     0x7f075b36081f - rustc_driver::driver::compile_input::_$u7b$$u7b$closure$u7d$$u7d$::h5534474dbe9371c4
  17:     0x7f075b35d190 - rustc_driver::driver::phase_3_run_analysis_passes::_$u7b$$u7b$closure$u7d$$u7d$::h5a042a091cd7658c
  18:     0x7f075b356c6b - rustc::ty::context::TyCtxt::create_and_enter::h3f9051bcccbd93e4
  19:     0x7f075b35371e - rustc_driver::driver::phase_3_run_analysis_passes::h9c723484c588a35b
  20:     0x7f075b325f7f - rustc_driver::driver::compile_input::h0629572e6f316b31
  21:     0x7f075b30c4e4 - rustc_driver::run_compiler::h8902aebf8b1849a8
  22:     0x7f075b309941 - std::sys_common::unwind::try::try_fn::h4c74456035d0fcc7
  23:     0x7f075adf9d9b - __rust_try
  24:     0x7f075adf9d2d - std::sys_common::unwind::inner_try::h47a4d9cd4a369dcd
  25:     0x7f075b30a18a - _<F as std..boxed..FnBox<A>>::call_box::h27f542a39f1d61ef
  26:     0x7f075ae07ee4 - std::sys::thread::Thread::new::thread_start::h6f266e069bf4ec2b
  27:     0x7f0752c606a9 - start_thread
  28:     0x7f075aa5ce9c - clone
  29:                0x0 - <unknown>
@apasel422 apasel422 added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ A-specialization Area: Trait impl specialization labels Apr 15, 2016
@arielb1 arielb1 added I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness and removed I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ labels Apr 16, 2016
@apasel422 apasel422 changed the title Trait bounds not checked on specializable assocated types Trait bounds not checked on specializable associated types Jun 23, 2016
@apasel422
Copy link
Contributor Author

Triage: still an issue.

@dtolnay
Copy link
Member

dtolnay commented Nov 28, 2016

I just hit this, though the error is a bit different now: "resolving bounds after type-checking" rather than "fulfilling during trans".

error: internal compiler error: ../src/librustc/infer/mod.rs:624: Encountered errors `[FulfillmentError(Obligation(predicate=Binder(TraitPredicate(<() as std::convert::From<i32>>)),depth=1),Unimplemented)]` resolving bounds after type-checking

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: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'Box<Any>', ../src/librustc_errors/lib.rs:383
stack backtrace:
   1:     0x7f91a71b237a - std::sys::imp::backtrace::tracing::imp::write::h944c02ac40aee2d7
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
   2:     0x7f91a71c122f - std::panicking::default_hook::{{closure}}::h6875a2976258b020
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:247
   3:     0x7f91a71c0dcd - std::panicking::default_hook::h88ffbc5922643264
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:257
   4:     0x7f91a71c16d7 - std::panicking::rust_panic_with_hook::ha5aed1dfc0e220e3
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:451
   5:     0x7f91a67fae4b - std::panicking::begin_panic::h264cdc75d51b518b
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:413
   6:     0x7f91a6817d93 - rustc::session::opt_span_bug_fmt::{{closure}}::h4a9b70c3df8b4b3a
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/<panic macros>:3
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/session/mod.rs:778
   7:     0x7f91a6817bb6 - rustc::session::span_bug_fmt::h0c5d2225aa96fe42
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1046
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1035
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/thread/local.rs:245
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1031
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1046
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/session/mod.rs:775
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/session/mod.rs:768
   8:     0x7f91a688fc77 - rustc_trans::common::fulfill_obligation::{{closure}}::{{closure}}::hf13a4d09f7cbb18e
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/macros.rs:59
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/common.rs:989
   9:     0x7f91a688c0dc - rustc_trans::common::fulfill_obligation::h6bfd7b7f15728b60
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/infer/mod.rs:440
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1019
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/thread/local.rs:245
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1016
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:853
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/infer/mod.rs:440
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/common.rs:949
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/dep_graph/dep_tracking_map.rs:145
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/common.rs:943
  10:     0x7f91a6887278 - rustc_trans::collector::do_static_dispatch::h9456c98c4201c352
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:864
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:829
  11:     0x7f91a68868aa - <rustc_trans::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_operand::h7428e8287ff72240
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:575
  12:     0x7f91a6886fe6 - <rustc_trans::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_terminator_kind::h8233aed64e4688ea
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/mir/visit.rs:424
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:658
  13:     0x7f91a6813387 - rustc::mir::visit::Visitor::visit_mir::hc23b408d887d8c09
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/mir/visit.rs:354
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/mir/visit.rs:123
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/mir/visit.rs:290
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/mir/visit.rs:96
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/mir/visit.rs:256
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/mir/visit.rs:90
  14:     0x7f91a688524c - rustc_trans::collector::collect_items_rec::h9535e33b3068eb29
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:1223
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:376
  15:     0x7f91a68858ff - rustc_trans::collector::collect_items_rec::h9535e33b3068eb29
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:383
  16:     0x7f91a686f200 - rustc_trans::base::collect_and_partition_translation_items::{{closure}}::h9f2b052ae16b5f0b
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:285
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/dep_graph/graph.rs:70
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/collector.rs:276
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/base.rs:2023
  17:     0x7f91a686b59f - rustc_trans::base::collect_and_partition_translation_items::h6a325f48a6efa8c7
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/util/common.rs:34
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/base.rs:2022
  18:     0x7f91a685ddca - rustc_trans::base::trans_crate::h6e0b0bf1b66798ce
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_trans/base.rs:1572
  19:     0x7f91a7571401 - rustc_driver::driver::phase_4_translate_to_llvm::h48ed91c172294403
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/driver.rs:1041
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/util/common.rs:34
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/driver.rs:1039
  20:     0x7f91a7541c36 - rustc_driver::driver::compile_input::{{closure}}::hf13172fc4e5a2f4d
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/driver.rs:207
  21:     0x7f91a755f503 - rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}::h97a3a12d948df547
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/driver.rs:995
  22:     0x7f91a7558833 - rustc_driver::driver::phase_3_run_analysis_passes::hb0ad9de18d423e67
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1019
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/thread/local.rs:245
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1016
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1003
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/thread/local.rs:245
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:1000
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc/ty/context.rs:789
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/driver.rs:870
  23:     0x7f91a753fb77 - rustc_driver::driver::compile_input::h8e119234b60571d5
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/driver.rs:174
  24:     0x7f91a7585cd8 - rustc_driver::run_compiler::hbdfc4f84e2e0f4b9
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/lib.rs:221
  25:     0x7f91a74a1158 - std::panicking::try::do_call::hf679f17bf3b43b0b
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/lib.rs:1116
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/lib.rs:137
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/librustc_driver/lib.rs:1050
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panic.rs:295
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:356
  26:     0x7f91a71cbc1a - __rust_maybe_catch_panic
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libpanic_unwind/lib.rs:97
  27:     0x7f91a74c31b8 - <F as alloc::boxed::FnBox<A>>::call_box::h506fb5d7b8891cd4
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:332
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panic.rs:351
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/thread/mod.rs:287
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/liballoc/boxed.rs:595
  28:     0x7f91a71c0094 - std::sys::imp::thread::Thread::new::thread_start::h8084b1107992ae5b
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/liballoc/boxed.rs:605
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys_common/thread.rs:21
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys/unix/thread.rs:84
  29:     0x7f919f3f5709 - start_thread
  30:     0x7f91a6e7a82c - clone
  31:                0x0 - <unknown>

@strega-nil
Copy link
Contributor

ping @arielb1 how is this unsound?

@bstrie bstrie added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 20, 2017
@bstrie
Copy link
Contributor

bstrie commented Jun 20, 2017

Given that @arielb1 has seen fit to tag this as a soundness bug I'm nominating it so that it can receive a priority assessment, though I'll second ubsan in asking for a demonstration of the unsoundness here.

@nikomatsakis
Copy link
Contributor

In general, having trait bounds that are not checked can lead to unsoundness, since some part of the code will assume that they hold when in fact they do not (consider, e.g., what might happen if the bound were Send).

@nikomatsakis
Copy link
Contributor

I'm going to mark this as P-medium and tag it from the specialization issue (it is specific to specialization, right?)

@nikomatsakis
Copy link
Contributor

triage: P-medium

@rust-highfive rust-highfive added P-medium Medium priority and removed I-nominated labels Jul 6, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 25, 2017
@bstrie bstrie added the B-unstable Blocker: Implemented in the nightly compiler and unstable. label Sep 20, 2017
@mjbshaw
Copy link
Contributor

mjbshaw commented Aug 3, 2018

The code in the OP compiles for me with the latest nightly Rust (1.29.0-nightly (97085f9 2018-08-01)). However, the following still fails (and I assume it's the same issue; if not I can file a new issue):

#![feature(specialization)]

trait PreProcess<T> {
  type Type: PostProcess<T> + std::default::Default;
  fn pre_process() -> Self::Type;
}

trait PostProcess<T> {
  fn post_process(self);
}

impl<T> PreProcess<T> for T {
  default type Type = std::marker::PhantomData<T>;
  default fn pre_process() -> Self::Type {
    return <Self::Type as std::default::Default>::default();
  }
}

pub struct Foo;

pub fn do_foo() {
  PostProcess::post_process(<Foo as PreProcess<Foo>>::pre_process());
}

Backtrace:

error: internal compiler error: librustc/traits/codegen/mod.rs:68: Encountered error `Unimplemented` selecting `Binder(<std::marker::PhantomData<Foo> as PostProcess<Foo>>)` during codegen

thread 'main' panicked at 'Box<Any>', librustc_errors/lib.rs:578: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::ty::context::tls::with_related_context
  15: rustc::infer::InferCtxtBuilder::enter
  16: rustc::traits::codegen::codegen_fulfill_obligation
  17: rustc::ty::query::__query_compute::codegen_fulfill_obligation
  18: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::codegen_fulfill_obligation<'tcx>>::compute
  19: rustc::dep_graph::graph::DepGraph::with_task_impl
  20: rustc::ty::context::tls::with_related_context
  21: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  22: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  23: rustc::ty::instance::Instance::resolve
  24: rustc_mir::monomorphize::collector::visit_fn_use
  25: <rustc_mir::monomorphize::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_terminator_kind
  26: rustc_mir::monomorphize::collector::collect_items_rec
  27: rustc_mir::monomorphize::collector::collect_crate_mono_items::{{closure}}
  28: rustc::util::common::time
  29: rustc_mir::monomorphize::collector::collect_crate_mono_items
  30: rustc::util::common::time
  31: rustc_codegen_llvm::base::collect_and_partition_mono_items
  32: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::collect_and_partition_mono_items<'tcx>>::compute
  33: rustc::dep_graph::graph::DepGraph::with_task_impl
  34: rustc::ty::context::tls::with_related_context
  35: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  36: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  37: rustc_codegen_llvm::back::symbol_export::exported_symbols_provider_local
  38: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::exported_symbols<'tcx>>::compute
  39: rustc::dep_graph::graph::DepGraph::with_task_impl
  40: rustc::ty::context::tls::with_related_context
  41: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  42: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  43: rustc_metadata::encoder::encode_metadata
  44: rustc_metadata::cstore_impl::<impl rustc::middle::cstore::CrateStore for rustc_metadata::cstore::CStore>::encode_metadata
  45: rustc::ty::context::TyCtxt::encode_metadata
  46: rustc_codegen_llvm::base::write_metadata
  47: rustc::util::common::time
  48: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_utils::codegen_backend::CodegenBackend>::codegen_crate
  49: rustc::util::common::time
  50: rustc_driver::driver::phase_4_codegen
  51: rustc_driver::driver::compile_input::{{closure}}
  52: rustc::ty::context::tls::enter_context
  53: <std::thread::local::LocalKey<T>>::with
  54: rustc::ty::context::TyCtxt::create_and_enter
  55: rustc_driver::driver::compile_input
  56: rustc_driver::run_compiler_with_pool
  57: <scoped_tls::ScopedKey<T>>::set
  58: <scoped_tls::ScopedKey<T>>::set
  59: syntax::with_globals
  60: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  61: __rust_maybe_catch_panic
  62: rustc_driver::run
  63: rustc_driver::main
  64: std::rt::lang_start::{{closure}}
  65: std::panicking::try::do_call
  66: __rust_maybe_catch_panic
  67: std::rt::lang_start_internal
  68: main
query stack during panic:
#0 [codegen_fulfill_obligation] checking if `PostProcess` fulfills its obligations
#1 [collect_and_partition_mono_items] collect_and_partition_mono_items
#2 [exported_symbols] exported_symbols
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.29.0-nightly (97085f9fb 2018-08-01) running on x86_64-apple-darwin

note: compiler flags: --crate-type rlib

@arielb1
Copy link
Contributor

arielb1 commented Jul 6, 2019

So I think this is "fixed-by-chalk", but this is fixed-by-chalk in a way that breaks specialization (cc @rust-lang/wg-traits).

Let's have a more easy-to-understand version of the problem:

#![feature(specialization)]

trait Foo: Sized {
    type Assoc: Copy + From<Self> + Into<Self>;
}

impl<T> Foo for T {
    default type Assoc = Self;
}

fn xyz<T: Foo>(t: T) -> T::Bar {
    t.into()
}

fn main() {
    xyz(5i32);
}

The problem is the following:

  1. wfchecking our impl needs to prove the where-clause, which in the environment is Γ, T: Sized ⊢ <T as Foo>::Bar: From<Self>.
  2. i32: From<Self> holds by VtableImpl (by the impl we are checking), so we can prove that obligation by ProjectionCandidate (which will be a VtableParam) that depends on the VtableImpl. Therefore, wfchecking is OK. Therefore, fun.
  3. So why isn't this a problem every time we have a projection? Normally, rustc normalizes <i32 as Foo>::Bar to the real associated type, and then it can't find the ProjectionCandidate, so no problem. With specialization, rustc can't normalize the associated type, so it sees the bug. I can't have a proof for this working, but this seems reasonably likely to work.
  4. One way that might solve this in the rustc model would be to basically say that for any given trait ref, only the most specialized impl is supposed to be checking the wf requirement (for every trait-ref, there is always a most-specialized impl, so this is OK), and when checking wf, add the associated types for our own impl explicitly to our parameter environment (e.g., add <T as Foo>::Bar = T - note no quantification over T - to the param env in our example). That will make things normalize and work, and I'm not even sure is particularly ugly. I don't think it is less sound than 3., but then I don't quite know when 3. is sound.
  5. So what's going on with Chalk? Last time I saw it, the way we made implied bounds work was to move ProjectionPredicate to the environment - in rustc terms, basically only allow it if we have proven the impl using VtableParam. This solves the problem, because our impl was proven in a well-formed way, so a VtableParam will ensure we make progress and there will be no cycles.
    The reason this does not work in specialization, is that we do want users to be able to prove things like <X as Foo>::Bar: Copy, even while they might not know what <X as Foo>::Bar is. For that, they need to have a ProjectionCandidate keyed off a VtableImpl. I have no idea how to do this in the Chalk model.

Was Chalk changed to do something else by now? Does this have a different interaction with specialization?

@DutchGhost
Copy link
Contributor

DutchGhost commented Jul 7, 2019

A PoC to show the unsoundness of this. It's a use-after free by 'copying' a String:

#![feature(specialization)]

trait UncheckedCopy: Sized {
    type Output: From<Self> + Copy + Into<Self>;
}

impl <T> UncheckedCopy for T {
    default type Output = Self;
}

fn unchecked_copy<T: UncheckedCopy>(other: &T::Output) -> T {
    (*other).into()
}

fn bug(origin: String) {
    // Turn the String into it's Output type...
    // Which we can just do by `.into()`, the assoc type states `From<Self>`.
    let origin_output = origin.into();
    
    // Make a copy of String::Output, which is a String...
    let mut copy: String = unchecked_copy::<String>(&origin_output);
    
    // Turn the Output type into a String again,
    // Which we can just do by `.into()`, the assoc type states `Into<Self>`.
    let mut origin: String = origin_output.into();
    
    // assert both Strings use the same buffer.
    assert_eq!(copy.as_ptr(), origin.as_ptr());
    
    // Any use of the copy we made becomes invalid,
    drop(origin);
    
    // OH NO! UB UB UB UB!
    copy.push_str(" world!");
    println!("{}", copy);
}

fn main() {
    bug(String::from("hello"));
}

Link to the playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018

@Centril Centril added requires-nightly This issue requires a nightly compiler in some way. F-specialization `#![feature(specialization)]` labels Jul 28, 2019
@jonas-schievink jonas-schievink removed the B-unstable Blocker: Implemented in the nightly compiler and unstable. label Aug 29, 2019
@jonas-schievink jonas-schievink added the A-associated-items Area: Associated items (types, constants & functions) label Nov 24, 2019
@Elinvynia Elinvynia added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Jun 9, 2020
@LeSeulArtichaut LeSeulArtichaut removed the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Jun 9, 2020
@Dylan-DPC-zz
Copy link

This is fixed now: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018 and needs a test

@Dylan-DPC-zz Dylan-DPC-zz 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 7, 2020
marmeladema added a commit to marmeladema/rust that referenced this issue Apr 23, 2021
@bors bors closed this as completed in ec61abf Apr 24, 2021
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 (types, constants & functions) 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-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-medium Medium priority 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.