Skip to content

With min_specialization enabled, an incomplete impl for a non-static type will delegate method calls to a less-specific impl with a 'static bound #79457

Closed
@fleabitdev

Description

@fleabitdev

Rustc version: 1.50.0-nightly (2020-11-25 b48cafd9eb658b5d7401), tested on the playground.

#![feature(min_specialization)]

use std::any::Any;

pub trait Tr {
    fn method(self) -> Box<dyn Any + 'static>;
}

impl<T: Any + 'static> Tr for T {
    fn method(self) -> Box<dyn Any + 'static> {
        Box::new(self)
    }
}

impl<'a> Tr for &'a i32 {
}

fn promote_to_static<'a>(i: &'a i32) -> &'static i32 {
    *i.method().downcast().unwrap()
}

struct Wrapper<'a>(&'a i32);

impl<'a> Tr for Wrapper<'a> {
}

fn promote_to_static_2<'a>(w: Wrapper<'a>) -> Wrapper<'static> {
    *w.method().downcast().unwrap()
}

fn main() {
    let i = Box::new(100_i32);
    let static_i: &'static i32 = promote_to_static(&*i);
    drop(i);
    println!("{}", *static_i);
    
    let j = Box::new(200_i32);
    let static_w: Wrapper<'static> = promote_to_static_2(Wrapper(&*j));
    drop(j);
    println!("{}", *static_w.0);
}

This bug also occurs when:

  • The trait contains two methods, method_0 and method_1
  • Both of those methods are implemented in the blanket impl
  • Only method_0 is overridden for &i32
  • We invoke method_1 on an &i32

I included the promote_to_static_2 function to demonstrate that this seems to be unrelated to autoderef; Wrapper does not implement Deref.

Metadata

Metadata

Assignees

Labels

A-specializationArea: Trait impl specializationA-trait-systemArea: Trait systemC-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.F-min_specialization`#![feature(min_specialization)]`I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-compilerRelevant to the compiler 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