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

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 opened this issue Nov 27, 2020 · 2 comments · Fixed by #111252
Assignees
Labels
A-specialization Area: Trait impl specialization A-trait-system Area: Trait system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-min_specialization `#![feature(min_specialization)]` I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@fleabitdev
Copy link

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.

@fleabitdev fleabitdev added the C-bug Category: This is a bug. label Nov 27, 2020
@camelid camelid added A-specialization Area: Trait impl specialization A-trait-system Area: Trait system labels Nov 27, 2020
@jonas-schievink jonas-schievink added I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 27, 2020
@voidc
Copy link
Contributor

voidc commented Mar 31, 2023

The given example does not compile with Rust 1.70.0-nightly (ec2f40c 2023-03-30). It produces the following error:

error[E0477]: the type `&'a i32` does not fulfill the required lifetime
  |
  = note: type must satisfy the static lifetime

error[E0477]: the type `Wrapper<'a>` does not fulfill the required lifetime
  |
  = note: type must satisfy the static lifetime

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=abcf336e6e3914ed4c9bce7952eaffa6

Therefore, I would propose to no longer label this issue as unsound but as a diagnostics issue.

@matthewjasper matthewjasper added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label May 4, 2023
@matthewjasper
Copy link
Contributor

The error should point to some actual code though.

@oli-obk oli-obk removed the I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness label May 4, 2023
@matthewjasper matthewjasper self-assigned this May 4, 2023
@bors bors closed this as completed in f748bb1 May 9, 2023
@oli-obk oli-obk added the I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness label Jul 16, 2024
@workingjubilee workingjubilee added the F-min_specialization `#![feature(min_specialization)]` label Oct 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-specialization Area: Trait impl specialization A-trait-system Area: Trait system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-min_specialization `#![feature(min_specialization)]` I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants