rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.52k stars 12.61k forks source link

alias bound candidates for opaques allow cyclic reasoning #109387

Open lcnr opened 1 year ago

lcnr commented 1 year ago
#![feature(type_alias_impl_trait)]

trait Trait<T> {
    type Assoc: Default;
}

type Ty<T> = impl Trait<T>;

impl<T> Trait<T> for T {
    type Assoc = <Ty<T> as Trait<T>>::Assoc;
}

#[allow(unused)]
fn define<T>(x: T) -> Ty<T> { x }

fn main() {
    let _ = <() as Trait<()>>::Assoc::default();
}
passes cargo check and results in an ICE ``` error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize fn() -> as Trait<()>>::Assoc {< as Trait<()>>::Assoc as std::default::Default>::default}, maybe try to call `try_normalize_erasing_regions` instead thread 'rustc' panicked at 'Box', /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/compiler/rustc_errors/src/lib.rs:1644:9 stack backtrace: 0: 0x7fccbf4e4c2a - std::backtrace_rs::backtrace::libunwind::trace::h2515acc71f4b7930 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5 1: 0x7fccbf4e4c2a - std::backtrace_rs::backtrace::trace_unsynchronized::he6766fb71a792b8f at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5 2: 0x7fccbf4e4c2a - std::sys_common::backtrace::_print_fmt::h66095118e41b05ee at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/sys_common/backtrace.rs:65:5 3: 0x7fccbf4e4c2a - ::fmt::h7b02ddcbc50194ff at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/sys_common/backtrace.rs:44:22 4: 0x7fccbf54824e - core::fmt::write::h0189aceee7302cd0 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/core/src/fmt/mod.rs:1254:17 5: 0x7fccbf4d79b5 - std::io::Write::write_fmt::h918fabbbac2260c4 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/io/mod.rs:1698:15 6: 0x7fccbf4e49f5 - std::sys_common::backtrace::_print::h41f5e13e972dc45f at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/sys_common/backtrace.rs:47:5 7: 0x7fccbf4e49f5 - std::sys_common::backtrace::print::h1c3c6b0fe82cc982 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/sys_common/backtrace.rs:34:9 8: 0x7fccbf4e776f - std::panicking::default_hook::{{closure}}::hce27f1b648cb1527 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/panicking.rs:271:22 9: 0x7fccbf4e74ab - std::panicking::default_hook::hadee4be0a52a9df6 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/panicking.rs:290:9 10: 0x7fccc273d565 - >::call_once::{shim:vtable#0} 11: 0x7fccbf4e7fad - as core::ops::function::Fn>::call::h0c02084a5fe3170c at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/alloc/src/boxed.rs:2002:9 12: 0x7fccbf4e7fad - std::panicking::rust_panic_with_hook::h0498acdcd60e6d9e at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/panicking.rs:696:13 13: 0x7fccc2c775b1 - std[d2fc22aa23273b84]::panicking::begin_panic::::{closure#0} 14: 0x7fccc2c75096 - std[d2fc22aa23273b84]::sys_common::backtrace::__rust_end_short_backtrace::::{closure#0}, !> 15: 0x7fccc2c8a476 - std[d2fc22aa23273b84]::panicking::begin_panic:: 16: 0x7fccc2cec4d6 - std[d2fc22aa23273b84]::panic::panic_any:: 17: 0x7fccc2ceaf76 - ::bug::<&alloc[146302d0966b713d]::string::String> 18: 0x7fccc2ceac40 - ::bug::<&alloc[146302d0966b713d]::string::String> 19: 0x7fccc2ce2fab - rustc_middle[44f4fa3c07a5b96d]::util::bug::opt_span_bug_fmt::::{closure#0} 20: 0x7fccc2ce19fa - rustc_middle[44f4fa3c07a5b96d]::ty::context::tls::with_opt::::{closure#0}, !>::{closure#0} 21: 0x7fccc2ce19c6 - rustc_middle[44f4fa3c07a5b96d]::ty::context::tls::with_context_opt::::{closure#0}, !>::{closure#0}, !> 22: 0x7fccc2ce2ef6 - rustc_middle[44f4fa3c07a5b96d]::util::bug::opt_span_bug_fmt:: 23: 0x7fccc0dc86d3 - rustc_middle[44f4fa3c07a5b96d]::util::bug::bug_fmt 24: 0x7fccc08b296a - >::fold_ty 25: 0x7fccc122e51a - >::eval_mir_constant 26: 0x7fccc12250f1 - ::visit_basic_block_data 27: 0x7fccc1220c89 - ::run_lint 28: 0x7fccc11f78b9 - rustc_mir_transform[40d85b965ee1f86e]::run_analysis_to_runtime_passes 29: 0x7fccc11f67d1 - rustc_mir_transform[40d85b965ee1f86e]::mir_drops_elaborated_and_const_checked 30: 0x7fccc11f4c50 - rustc_query_system[fba465ff5df52802]::query::plumbing::try_execute_query:: 31: 0x7fccc1aa2ac2 - rustc_mir_transform[40d85b965ee1f86e]::optimized_mir 32: 0x7fccc1aa0ccf - rustc_query_system[fba465ff5df52802]::query::plumbing::try_execute_query:: 33: 0x7fccc15e4eba - rustc_monomorphize[882ebeeb6d5d3a1d]::collector::collect_neighbours 34: 0x7fccc15e13aa - rustc_monomorphize[882ebeeb6d5d3a1d]::collector::collect_items_rec 35: 0x7fccc1bdca5a - rustc_data_structures[a666149ac6da9659]::sync::par_for_each_in::, rustc_monomorphize[882ebeeb6d5d3a1d]::collector::collect_crate_mono_items::{closure#1}::{closure#0}> 36: 0x7fccc1bdc6f1 - ::time::<(), rustc_monomorphize[882ebeeb6d5d3a1d]::collector::collect_crate_mono_items::{closure#1}> 37: 0x7fccc1bdc464 - rustc_monomorphize[882ebeeb6d5d3a1d]::collector::collect_crate_mono_items 38: 0x7fccc1bda7b0 - rustc_monomorphize[882ebeeb6d5d3a1d]::partitioning::collect_and_partition_mono_items 39: 0x7fccc1932c82 - rustc_query_system[fba465ff5df52802]::query::plumbing::try_execute_query:: 40: 0x7fccc193293d - ::collect_and_partition_mono_items 41: 0x7fccc1c6c013 - rustc_codegen_ssa[9a4b9ef85533b414]::base::codegen_crate:: 42: 0x7fccc1c6bdde - ::codegen_crate 43: 0x7fccc19567b1 - ::time::, rustc_interface[9d302fd946af7c88]::passes::start_codegen::{closure#0}> 44: 0x7fccc19562d9 - rustc_interface[9d302fd946af7c88]::passes::start_codegen 45: 0x7fccc1953018 - ::enter::<::ongoing_codegen::{closure#0}::{closure#0}, core[ef02eb5763a621f4]::result::Result, rustc_span[fc3e3761b6371eb]::ErrorGuaranteed>> 46: 0x7fccc1951574 - ::ongoing_codegen 47: 0x7fccc1950b41 - ::enter::, rustc_span[fc3e3761b6371eb]::ErrorGuaranteed>> 48: 0x7fccc194ec10 - rustc_span[fc3e3761b6371eb]::with_source_map::, rustc_interface[9d302fd946af7c88]::interface::run_compiler, rustc_driver_impl[f5bb7a311e11caf0]::run_compiler::{closure#1}>::{closure#0}::{closure#0}> 49: 0x7fccc194e1b9 - std[d2fc22aa23273b84]::sys_common::backtrace::__rust_begin_short_backtrace::, rustc_driver_impl[f5bb7a311e11caf0]::run_compiler::{closure#1}>::{closure#0}, core[ef02eb5763a621f4]::result::Result<(), rustc_span[fc3e3761b6371eb]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[ef02eb5763a621f4]::result::Result<(), rustc_span[fc3e3761b6371eb]::ErrorGuaranteed>> 50: 0x7fccc20267ba - <::spawn_unchecked_, rustc_driver_impl[f5bb7a311e11caf0]::run_compiler::{closure#1}>::{closure#0}, core[ef02eb5763a621f4]::result::Result<(), rustc_span[fc3e3761b6371eb]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[ef02eb5763a621f4]::result::Result<(), rustc_span[fc3e3761b6371eb]::ErrorGuaranteed>>::{closure#1} as core[ef02eb5763a621f4]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0} 51: 0x7fccbf4f1e83 - as core::ops::function::FnOnce>::call_once::hc115614f1f0f79d3 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/alloc/src/boxed.rs:1988:9 52: 0x7fccbf4f1e83 - as core::ops::function::FnOnce>::call_once::h123e851e4d4b5225 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/alloc/src/boxed.rs:1988:9 53: 0x7fccbf4f1e83 - std::sys::unix::thread::Thread::new::thread_start::h823b35624605ef69 at /rustc/da7c50c089d5db2d3ebaf227fe075bb1346bfaec/library/std/src/sys/unix/thread.rs:108:17 54: 0x7fccbf3b9609 - start_thread 55: 0x7fccbf2dc133 - clone 56: 0x0 - 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.70.0-nightly (da7c50c08 2023-03-19) running on x86_64-unknown-linux-gnu note: compiler flags: --crate-type bin -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 note: some of the compiler flags provided by cargo are hidden query stack during panic: #0 [mir_drops_elaborated_and_const_checked] elaborating drops for `main` #1 [optimized_mir] optimizing MIR for `main` #2 [collect_and_partition_mono_items] collect_and_partition_mono_items end of query stack error: could not compile `playground` (bin "playground") ```

This has the same underlying reason as the unsoundness for super traits with coinduction and alias bound for projections. To my knowledge none of these issues are exploitable on stable right now though.

This relies on the following unsound circular reasoning:

lcnr commented 1 year ago

it's probably possible to get a segfault at runtime from this instead, but thinking about circular reasoning like this is hard so I am satisfied with an ICE for now.

lcnr commented 1 year ago

A proposed solution was to recheck the opaque for well-formedness with Reveal::All. This check probably still needs to handle region obligations as we can otherwise end up with unproven outlives bounds.

lcnr commented 1 year ago

it's probably possible to get a segfault at runtime from this instead, but thinking about circular reasoning like this is hard so I am satisfied with an ICE for now.

This is surprisingly hard: taking the known issue for projections in the new solver https://github.com/lcnr/solver-woes/issues/9#issuecomment-1483510789, we instead overflow because instantiating Tait with String requires a nested String: Copy bound which we again prove using the alias bound on Tait, resulting in a cycle https://rust.godbolt.org/z/41cM1snx5

// compile-flags: -Ztrait-solver=next
#![feature(type_alias_impl_trait)]

mod define {
    pub type Tait where Tait: Copy = impl Copy;
    fn define() -> Tait
    where
        Tait: Copy
    {
        String::new()
    }
}
fn copy(x: &define::Tait) -> define::Tait {
    *x
}

using a coinductive trait currently also doesn't compile though I am unsure why https://rust.godbolt.org/z/xncdcecWY

// compile-flags: -Ztrait-solver=next
#![feature(rustc_attrs, type_alias_impl_trait)]

#[rustc_coinductive]
trait Trait {
    fn mk() -> Self;
}

mod define {
    use super::*;
    pub type Tait where Tait: Trait = impl Trait;
    fn define() -> Tait
    where
        Tait: Trait
    {}
}
fn make() -> define::Tait {
    Trait::mk()
}