Skip to content

deref_patterns is unsound due to dyn of subtrait of DerefPure #154619

@theemathas

Description

@theemathas

By defining a trait that's a subtrait of DerefPure, the trait object of that user-defined trait automatically implements DerefPure, without inheriting the Deref impl of the concrete type inside. This allows users to implement a non-pure Deref on the trait object type, violating the invariant of DerefPure.

For example, the following code causes a SIGILL at run time, due to none of the arms in the match being matched.

#![feature(deref_pure_trait, deref_patterns)]

use std::ops::{Deref, DerefPure};
use std::sync::atomic::{AtomicBool, Ordering::SeqCst};

trait Trait: DerefPure {}
impl Trait for Box<i32> {}

static STATE: AtomicBool = AtomicBool::new(false);

impl Deref for dyn Trait + '_ {
    type Target = bool;
    fn deref(&self) -> &bool {
        if STATE.swap(true, SeqCst) {
            &true
        } else {
            &false
        }
    }
}

fn main() {
    let a: Box<i32> = Box::new(1);
    let b: &dyn Trait = &a;
    match b {
        deref!(true) => {}
        deref!(false) => {}
    }
}

Note that making Deref a supertrait of DerefPure doesn't fix this problem, since there's still a similar unsoundness with DerefMut instead.

A possible solution is applying #[rustc_dyn_incompatible_trait] to DerefPure.

Meta

Reproducible on the playground with version 1.96.0-nightly (2026-03-29 a25435bcf7cfc9b953d3)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-dyn-compatibilityArea: Dyn compatibility (formerly: object safety)A-dyn-traitArea: trait objects, vtable layoutA-patternsRelating to patterns and pattern matchingC-bugCategory: This is a bug.F-deref_patterns`#![feature(deref_patterns)]`I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-langRelevant to the language teamT-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions