Skip to content

negative_impls and auto_traits experimental features allow trait impls to overlap #74629

Closed
@WaffleLapkin

Description

@WaffleLapkin

I tried this code (this is the most minimal example that I could create, though I think that there may exist a simpler one. my original code: playground):

#![feature(negative_impls, auto_traits)]
struct Nil;
struct Cons<H>(H);
struct Test;

trait Fold<F> {}

impl<T, F> Fold<F> for Cons<T> // 0
where
    T: Fold<Nil>,
{}

impl<T, F> Fold<F> for Cons<T> // 1
where
    T: Fold<F>,
    private::Is<T>: private::NotNil,
{}

impl<F> Fold<F> for Test {} // 2

mod private {
    use crate::Nil;

    pub struct Is<T>(T);
    pub auto trait NotNil {}
    impl !NotNil for Is<Nil> {}
}

(playground)

I expected to see a compilation error because 0 and 1 implementations are clearly overlapping each other. E.g.: with T = Test, F = () all bounds are true, making both implementations appliable (Test: Fold<Nil>, Test: Fold<()> are true because of 2, Is<Test>: NotNil is true because of auto trait & lack of negative implementation).

However, this code compiles with the latest nightly (1.47.0-nightly (2020-07-20 f9a3086363f214f2b56b))

To make things even weirder, this does not compile:

fn assert<T>()
where
    Cons<T>: Fold<()>
{}

assert::<Test>(); // error[E0283]: type annotations needed

(playground)

Error

error[E0283]: type annotations needed
  --> src/main.rs:11:5
   |
6  |     fn assert<T>()
   |        ------ required by a bound in this
7  |     where
8  |         Cons<T>: Fold<()>
   |                  -------- required by this bound in `main::assert`
...
11 |     assert::<Test>();
   |     ^^^^^^^^^^^^^^ cannot infer type for struct `Cons<Test>`
   |
   = note: cannot satisfy `Cons<Test>: Fold<()>`

But this does compile:

fn indirect_assert0<T>()
where
    T: Fold<Nil>,
{
    assert::<T>();
}

fn indirect_assert1<T>()
where
    T: Fold<Nil>,
    private::Is<T>: private::NotNil,
{
    assert::<T>();
}

indirect_assert0::<Test>();
indirect_assert1::<Test>();

(playground)

And lastly, if you'll try to add a constant to the trait & print it, the compiler will ICE.

Backtrace

   Compiling playground v0.0.1 (/playground)
error: internal compiler error: /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/librustc_middle/macros.rs:16:9: encountered bad ConstKind after monomorphizing: Error(DelaySpanBugEmitted(()))
  --> src/main.rs:10:14
   |
10 |         dbg!(Cons::<T>::IMPL);
   |              ^^^^^^^^^^^^^^^

thread 'rustc' panicked at 'Box<Any>', /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/macros.rs:13:23
stack backtrace:
   0: std::backtrace_rs::backtrace::libunwind::trace
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/../backtrace/src/backtrace/libunwind.rs:96
   1: std::backtrace_rs::backtrace::trace_unsynchronized
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/../backtrace/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/sys_common/backtrace.rs:58
   4: core::fmt::write
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libcore/fmt/mod.rs:1117
   5: std::io::Write::write_fmt
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/io/mod.rs:1508
   6: std::sys_common::backtrace::_print
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/sys_common/backtrace.rs:61
   7: std::sys_common::backtrace::print
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/sys_common/backtrace.rs:48
   8: std::panicking::default_hook::{{closure}}
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/panicking.rs:217
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at /rustc/f9a3086363f214f2b56bef30f0ac572e1a9127f1/src/libstd/panicking.rs:530
  12: std::panicking::begin_panic
  13: rustc_errors::HandlerInner::span_bug
  14: rustc_errors::Handler::span_bug
  15: rustc_middle::util::bug::opt_span_bug_fmt::{{closure}}
  16: rustc_middle::ty::context::tls::with_opt::{{closure}}
  17: rustc_middle::ty::context::tls::with_opt
  18: rustc_middle::util::bug::opt_span_bug_fmt
  19: rustc_middle::util::bug::span_bug_fmt
  20: rustc_codegen_ssa::mir::constant::<impl rustc_codegen_ssa::mir::FunctionCx<Bx>>::eval_mir_constant
  21: rustc_codegen_ssa::mir::codegen_mir
  22: <rustc_middle::mir::mono::MonoItem as rustc_codegen_ssa::mono_item::MonoItemExt>::define
  23: rustc_codegen_llvm::base::compile_codegen_unit::module_codegen
  24: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
  25: rustc_codegen_llvm::base::compile_codegen_unit
  26: rustc_codegen_ssa::base::codegen_crate
  27: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  28: rustc_interface::passes::start_codegen
  29: rustc_middle::ty::context::tls::enter_global
  30: rustc_interface::queries::Queries::ongoing_codegen
  31: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
  32: rustc_span::with_source_map
  33: rustc_interface::interface::create_compiler_and_run
  34: scoped_tls::ScopedKey<T>::set
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.47.0-nightly (f9a308636 2020-07-20) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --crate-type bin

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

query stack during panic:
end of query stack
error: aborting due to previous error

error: could not compile `playground`.

To learn more, run the command again with --verbose.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-auto-traitsArea: auto traits (e.g., `auto trait Send {}`)C-bugCategory: This is a bug.F-auto_traits`#![feature(auto_traits)]`F-negative_impls#![feature(negative_impls)]I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessS-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.T-typesRelevant to the types team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions