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

Compiler panics when comparing functions #91636

Closed
CeleritasCelery opened this issue Dec 7, 2021 · 6 comments
Closed

Compiler panics when comparing functions #91636

CeleritasCelery opened this issue Dec 7, 2021 · 6 comments
Labels
C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@CeleritasCelery
Copy link
Contributor

CeleritasCelery commented Dec 7, 2021

Edit: see example in the first comment below for a reproduction without Miri.

I have created a minimal reproduction based on some more verbose code that was causing Miri to panic. Note this code does not panic when compiled to native code with rustc (though that doesn't mean there is no undefined behavior here).

Code

type BuiltIn = for<'a> fn(&str);

struct Function {
    inner: BuiltIn,
}

impl Function {
    fn new(subr: BuiltIn) -> Self {
        Self { inner: subr }
    }
}

fn dummy(_: &str) {}

fn main() {
    let func1 = Function::new(dummy);
    let func2 = Function::new(dummy);
    let inner: fn(&'static _) -> _ = func1.inner;
    if inner == func2.inner {
        println!("equal");
    } else {
        println!("not equal");
    }
}

Meta

rustc --version --verbose:

rustc 1.59.0-nightly (acbe4443c 2021-12-02)
binary: rustc
commit-hash: acbe4443cc4c9695c0b74a7b64b60333c990a400
commit-date: 2021-12-02
host: x86_64-unknown-linux-gnu
release: 1.59.0-nightly
LLVM version: 13.0.0

Error output

thread 'rustc' panicked at 'Unexpected types for BinOp: fn(&str) Eq for<'r> fn(&'r str)', /rustc/acbe4443cc4c9695c0b74a7b64b60333c990a400/compiler/rustc_const_eval/src/interpret/operator.rs:332:17

error: internal compiler error: unexpected panic

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

stack backtrace:
   0: rust_begin_unwind
             at /rustc/acbe4443cc4c9695c0b74a7b64b60333c990a400/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/acbe4443cc4c9695c0b74a7b64b60333c990a400/library/core/src/panicking.rs:107:14
   2: <rustc_const_eval::interpret::eval_context::InterpCx<miri::machine::Evaluator>>::overflowing_binary_op
   3: <rustc_const_eval::interpret::eval_context::InterpCx<miri::machine::Evaluator>>::binop_ignore_overflow
   4: <rustc_const_eval::interpret::eval_context::InterpCx<miri::machine::Evaluator>>::statement
   5: miri::eval::eval_entry
   6: <rustc_interface::passes::QueryContext>::enter::<<miri::MiriCompilerCalls as rustc_driver::Callbacks>::after_analysis::{closure#0}, ()>
   7: <miri::MiriCompilerCalls as rustc_driver::Callbacks>::after_analysis
   8: <rustc_interface::interface::Compiler>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorReported>>
   9: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorReported>, rustc_interface::interface::create_compiler_and_run<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#1}>
  10: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>

@CeleritasCelery CeleritasCelery added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 7, 2021
@SNCPlay42
Copy link
Contributor

SNCPlay42 commented Dec 7, 2021

While trying to reduce a bit, I got a version that causes an ICE in a regular build without Miri: (playground)

fn foo(_a: &str) {}

fn main() {
    let x = foo as fn(&'static str);
    
    let _ = x == foo;
}

@RalfJung
Copy link
Member

RalfJung commented Dec 9, 2021

Good catch! The panic is triggered here:

assert!(
right.layout.ty == left.layout.ty || right.layout.ty.is_integral(),
"Unexpected types for BinOp: {:?} {:?} {:?}",

Looks like we actually allow == on operands of different type if one is a subtype of the other. The more you know...

@ouz-a
Copy link
Contributor

ouz-a commented Dec 9, 2021

Good catch! The panic is triggered here:

assert!(
right.layout.ty == left.layout.ty || right.layout.ty.is_integral(),
"Unexpected types for BinOp: {:?} {:?} {:?}",

Looks like we actually allow == on operands of different type if one is a subtype of the other. The more you know...

I am trying to fix this and I found that this compiled fine back in 1.44.0 https://godbolt.org/z/Wznsz7PeM something happened in 1.45.0 and it doesn't compile anymore

@RalfJung
Copy link
Member

RalfJung commented Dec 9, 2021

Oh, interesting. What did the MIR look like back then?
Maybe there was some explicit subtyping happening.

@ouz-a
Copy link
Contributor

ouz-a commented Dec 9, 2021

Unfortunately, I can't locally test 1.44.0 on my machine since M1 builds don't exist for those versions.

fn foo(_a: &str) {}
fn type_of<T>(_: T){
    println!("type -> {:#?}",std::any::type_name::<T>())
}
fn main() {
    let x = foo as fn(&'static str);
    type_of(foo);
    let _ = x == foo;
}

weirdly or not weirdly (IDK) this compiles in stable and nightly version I think it's because of coercion but I don't know also code doesn't even enter
assert!( right.layout.ty == left.layout.ty || right.layout.ty.is_integral(), "Unexpected types for BinOp: {:?} {:?} {:?}", here when coercion happens.

I opened zulip discussion about this

@CeleritasCelery CeleritasCelery changed the title Miri panics when comparing functions Compiler panics when comparing functions Dec 10, 2021
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 14, 2021
Looser check for overflowing_binary_op

Fix for issue rust-lang#91636 tight check resulted in ICE, this makes the check a little looser. It seems `eq` allows comparing of `supertype` and `subtype` if `lhs = supertype` and `rhs = subtype` but not vice versa, is this intended behavior ?
@RalfJung
Copy link
Member

Fixed by #91856

bors added a commit to rust-lang/miri that referenced this issue Dec 15, 2021
add regression test

Adds a regression test for rust-lang/rust#91636 (which was fixed by rust-lang/rust#91856)
bors added a commit to rust-lang/miri that referenced this issue Dec 15, 2021
add regression test

Adds a regression test for rust-lang/rust#91636 (which was fixed by rust-lang/rust#91856)
bors added a commit to rust-lang/miri that referenced this issue Dec 15, 2021
add regression test

Adds a regression test for rust-lang/rust#91636 (which was fixed by rust-lang/rust#91856)
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Dec 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants