Skip to content

ICE when trying to implement Drop generically #41974

Closed

Description

@raphaelcohn

I've defined a trait CompletionQueue<'a>, which wraps various FFI *mut xxx pointers. All of these pointers can be freed by the same FFI function, so to reduce code duplication, I defined a pointer() method on my CompletionQueue<'a> trait, and tried to define a generic implementation of Drop that is basically unsafe { ff_drop_function(self.pointer()) }. This causes the compiler to panic...

     Running `rustc --crate-name rdma_core src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=7b223b004c70695f -C extra-filename=-7b223b004c70695f --out-dir /Volumes/Source/GitHub/lemonrock/rdma-core/.cargo/target/debug/deps -L dependency=/Volumes/Source/GitHub/lemonrock/rdma-core/.cargo/target/debug/deps --extern rust_extra=/Volumes/Source/GitHub/lemonrock/rdma-core/.cargo/target/debug/deps/librust_extra-c243164c893672bb.rlib --extern errno=/Volumes/Source/GitHub/lemonrock/rdma-core/.cargo/target/debug/deps/liberrno-e26062265f10ba2f.rlib --extern syscall_alt=/Volumes/Source/GitHub/lemonrock/rdma-core/.cargo/target/debug/deps/libsyscall_alt-e072c8ee531427e2.rlib --extern libc=/Volumes/Source/GitHub/lemonrock/rdma-core/.cargo/target/debug/deps/liblibc-b057f0656f58b4ca.rlib --extern rdma_core_sys=/Volumes/Source/GitHub/lemonrock/rdma-core/.cargo/target/debug/deps/librdma_core_sys-9e84b480a6be2488.rlib`
error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `std::boxed::Box<_>`:
  --> src/CompletionQueue.rs:5:1
   |
5  | / impl<'a, T: Sized + CompletionQueue<'a>> Drop for T
6  | | {
7  | | 	#[inline(always)]
8  | | 	fn drop(&mut self)
...  |
11 | | 	}
12 | | }
   | |_^
   |
   = note: conflicting implementation in crate `alloc`

error[E0120]: the Drop trait may only be implemented on structures
 --> src/CompletionQueue.rs:5:51
  |
5 | impl<'a, T: Sized + CompletionQueue<'a>> Drop for T
  |                                                   ^ implementing Drop requires a struct

error: internal compiler error: src/librustc_typeck/check/dropck.rs:64: should have been rejected by coherence check: T
  --> src/CompletionQueue.rs:5:1
   |
5  | / impl<'a, T: Sized + CompletionQueue<'a>> Drop for T
6  | | {
7  | | 	#[inline(always)]
8  | | 	fn drop(&mut self)
...  |
11 | | 	}
12 | | }
   | |_^

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:375
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::panicking::default_hook::{{closure}}
   2: std::panicking::default_hook
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic
   5: rustc_errors::Handler::span_bug
   6: rustc::session::opt_span_bug_fmt::{{closure}}
   7: rustc::session::span_bug_fmt
   8: rustc_typeck::check::dropck::check_drop_impl
   9: core::ops::FnMut::call_mut
  10: rustc::ty::util::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::calculate_dtor::{{closure}}
  11: rustc::ty::util::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::calculate_dtor
  12: rustc_typeck::check::adt_destructor
  13: rustc::ty::maps::<impl rustc::ty::maps::queries::adt_destructor<'tcx>>::try_get
  14: rustc::ty::util::<impl rustc::ty::ParameterEnvironment<'tcx>>::can_type_implement_copy
  15: rustc_typeck::coherence::coherent_trait
  16: rustc::ty::maps::<impl rustc::ty::maps::queries::coherent_trait<'tcx>>::try_get
  17: rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::coherent_trait
  18: rustc_typeck::coherence::check_coherence
  19: rustc_typeck::check_crate
  20: rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}
  21: rustc_driver::driver::phase_3_run_analysis_passes
  22: rustc_driver::driver::compile_input
  23: rustc_driver::run_compiler
  24: std::panicking::try::do_call
  25: __rust_maybe_catch_panic
  26: <F as alloc::boxed::FnBox<A>>::call_box
  27: std::sys::imp::thread::Thread::new::thread_start
  28: _pthread_body
  29: _pthread_start

Activity

  1. raphaelcohn commented on May 13, 2017

    @raphaelcohn
    Author

    Background: rust-nightly, version rustc 1.19.0-nightly (777ee2079 2017-05-01), running on Mac OS X (Darwin Kernel Version 15.6.0) on a x86_64 bit Mac Pro cylinder. Native target.

  2. raphaelcohn commented on May 13, 2017

    @raphaelcohn
    Author

    Also present in rustc 1.19.0-nightly (e17a1227a 2017-05-12)

  3. djzin commented on May 13, 2017

    @djzin
    Contributor

    Implementing Drop (or any trait you do not control) generically in this way is not possible because it violates the coherence rules. (What if someone implemented CompletionQueue and Drop seperately?) You probably want to wrap your types in a newtype with a forwarding implementation of the CompletionQueue trait.

    With that said, the compiler probably shouldn't ICE on this!

  4. added
    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
    on May 13, 2017
  5. raphaelcohn commented on May 15, 2017

    @raphaelcohn
    Author

    Thank you. I was trying to avoid writing and maintaining a lot of tedious, duplicated boilerplate...

  6. Mark-Simulacrum commented on Jun 22, 2017

    @Mark-Simulacrum
    Member

    Can you provide a code example (preferably minimal?)

  7. raphaelcohn commented on Jul 12, 2017

    @raphaelcohn
    Author

    Nope; it was a long time ago.

  8. tmccombs commented on Nov 4, 2017

    @tmccombs
    Contributor

    I encountered this same issue on rustc 1.21 (with a very similar use case).

    Unfortunately, while I can reproduce it in my project, I can't come up with a minimal example that reproduces the ICE.

    The full otuput look like

    error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `std::boxed::Box<_>`:
      --> src/stream.rs:76:1
       |
    76 | / impl<T> Drop for T where T: Stream {
    77 | |     fn drop(&mut self) {
    78 | |         unsafe {
    79 | |             nn_close(self.as_raw_fd());
    80 | |         }
    81 | |     }
    82 | | }
       | |_^
       |
       = note: conflicting implementation in crate `alloc`
    
    error[E0120]: the Drop trait may only be implemented on structures
      --> src/stream.rs:76:18
       |
    76 | impl<T> Drop for T where T: Stream {
       |                  ^ implementing Drop requires a struct
    
    error: internal compiler error: /checkout/src/librustc_typeck/check/dropck.rs:64: should have been rejected by coherence check: T
      --> src/stream.rs:76:1
       |
    76 | / impl<T> Drop for T where T: Stream {
    77 | |     fn drop(&mut self) {
    78 | |         unsafe {
    79 | |             nn_close(self.as_raw_fd());
    80 | |         }
    81 | |     }
    82 | | }
       | |_^
    
    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.21.0 (3b72af97e 2017-10-09) running on x86_64-unknown-linux-gnu
    
    thread 'rustc' panicked at 'Box<Any>', /checkout/src/librustc_errors/lib.rs:437:8
    
  9. tmccombs commented on Nov 4, 2017

    @tmccombs
    Contributor
  10. sinkuu commented on Nov 4, 2017

    @sinkuu
    Contributor

    Further reduced (playground):

    #[derive(Copy, Clone)]
    struct Flags;
    
    trait A {
    }
    
    impl<T> Drop for T where T: A {
        fn drop(&mut self) {
        }
    }
  11. added a commit that references this issue on Jan 3, 2018
    f7932ef
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions