Skip to content

ICE when pattern matching on &dyn PartialEq. #72565

Closed
@lcnr

Description

@lcnr
const F: &'static dyn PartialEq<u32> = &7u32;

fn main() {
    let a: &dyn PartialEq<u32> = &7u32;
    match a {
        F => panic!(),
        _ => {}
    }
}

causes an ICE on the current nightly

error: internal compiler error: src/librustc_mir_build/hair/pattern/_match.rs:363: cannot deref ByRef {
    alloc: Allocation {
        bytes: [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
        ],
        relocations: Relocations(
            SortedMap {
                data: [
                    (
                        Size {
                            raw: 0,
                        },
                        (
                            (),
                            a2,
                        ),
                    ),
                    (
                        Size {
                            raw: 8,
                        },
                        (
                            (),
                            a4,
                        ),
                    ),
                ],
            },
        ),
        init_mask: InitMask {
            blocks: [
                65535,
            ],
            len: Size {
                raw: 16,
            },
        },
        size: Size {
            raw: 16,
        },
        align: Align {
            pow2: 3,
        },
        mutability: Not,
        extra: (),
    },
    offset: Size {
        raw: 0,
    },
}, dyn std::cmp::PartialEq<u32> -> dyn std::cmp::PartialEq<u32>

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:907:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Afaik this is caused by ty_is_partial_eq being slightly too permissive

let ty_is_partial_eq: bool = {
let partial_eq_trait_id =
self.tcx().require_lang_item(EqTraitLangItem, Some(self.span));
let obligation: PredicateObligation<'_> = predicate_for_trait_def(
self.tcx(),
self.param_env,
ObligationCause::misc(self.span, self.id),
partial_eq_trait_id,
0,
cv.ty,
&[],
);
// FIXME: should this call a `predicate_must_hold` variant instead?
self.infcx.predicate_may_hold(&obligation)
};

See #71038 (comment) for more details.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-patternsRelating to patterns and pattern matchingC-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions