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

Poor error message for attempt to make doubly-fat pointers #46375

Open
jimblandy opened this issue Nov 29, 2017 · 3 comments
Open

Poor error message for attempt to make doubly-fat pointers #46375

jimblandy opened this issue Nov 29, 2017 · 3 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jimblandy
Copy link
Contributor

Compiling the following code yields the given error:

#![allow(unused_variables)]

trait T1 { fn f(&self); }
trait T2 { fn g(&self); }

struct S;

impl T1 for S {
    fn f(&self) {
        println!("<S as T1>::f");
    }
}

impl T2 for T1 {
    fn g(&self) {
        println!("<T1 as T2>::g");
        self.f();
    }
}

fn main() {
    let s: S = S;
    let bs: Box<S> = Box::new(s);

    let t1_object: Box<T1> = bs;
    let t2_object: Box<T2> = t1_object;
}
error[E0308]: mismatched types
  --> src/main.rs:26:30
   |
26 |     let t2_object: Box<T2> = t1_object;
   |                              ^^^^^^^^^ expected trait `T2`, found trait `T1`
   |
   = note: expected type `std::boxed::Box<T2>`
              found type `std::boxed::Box<T1>`

This is confusing when the intent is to create a trait object. I think it's common to internalize the rule that one can coerce Box<T> to Box<Trait> if T: Trait, without noticing the side requirement that Box<T> must not be a fat pointer, lest we create a doubly-fat pointer.

I would speculate that what's going on in the compiler is that the coercion code declines to perform any coercion, leaving Rust to report the mismatch. It would be helpful to issue a note to the effect that trait object creation was considered, but rejected because the incoming pointer was already fat.

@sfackler sfackler added the A-diagnostics Area: Messages for errors, warnings, and lints label Nov 29, 2017
@XAMPPRocky XAMPPRocky added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 26, 2018
@estebank
Copy link
Contributor

Triage: no change.

@estebank
Copy link
Contributor

estebank commented Feb 1, 2020

Current output, little change:

error[E0308]: mismatched types
  --> file.rs:26:30
   |
26 |     let t2_object: Box<T2> = t1_object;
   |                    -------   ^^^^^^^^^ expected trait `T2`, found trait `T1`
   |                    |
   |                    expected due to this
   |
   = note: expected struct `std::boxed::Box<dyn T2>`
              found struct `std::boxed::Box<dyn T1>`

@RodBurman
Copy link

Using:

% caro -v -V
zsh: command not found: caro
rod@Mac fatptr % cargo -v -V
cargo 1.85.1 (d73d2caf9 2024-12-31)
release: 1.85.1
commit-hash: d73d2caf9e41a39daf2a8d6ce60ec80bf354d2a7
commit-date: 2024-12-31
host: aarch64-apple-darwin
libgit2: 1.8.1 (sys:0.19.0 vendored)
libcurl: 8.7.1 (sys:0.4.74+curl-8.9.0 system ssl:(SecureTransport) LibreSSL/3.3.6)
ssl: OpenSSL 1.1.1w  11 Sep 2023
os: Mac OS 15.3.2 [64-bit]

yields:

 % cargo build
   Compiling fatptr v0.1.0 (/Users/rod/code/rust/triage/fatptr)
error[E0782]: expected a type, found a trait
  --> src/main.rs:14:13
   |
14 | impl T2 for T1 {
   |             ^^
   |
help: you can add the `dyn` keyword if you want a trait object
   |
14 | impl T2 for dyn T1 {
   |             +++
help: alternatively use a blanket implementation to implement `T2` for all types that also implement `T1`
   |
14 | impl<T: T1> T2 for T {
   |     +++++++        ~

error[E0782]: expected a type, found a trait
  --> src/main.rs:25:24
   |
25 |     let t1_object: Box<T1> = bs;
   |                        ^^
   |
help: you can add the `dyn` keyword if you want a trait object
   |
25 |     let t1_object: Box<dyn T1> = bs;
   |                        +++

error[E0782]: expected a type, found a trait
  --> src/main.rs:26:24
   |
26 |     let t2_object: Box<T2> = t1_object;
   |                        ^^
   |
help: you can add the `dyn` keyword if you want a trait object
   |
26 |     let t2_object: Box<dyn T2> = t1_object;
   |                        +++

For more information about this error, try `rustc --explain E0782`.
error: could not compile `fatptr` (bin "fatptr") due to 3 previous errors

which is a totally different set of error messages. However after following the recommended fixes to give:

#![allow(unused_variables)]

trait T1 { fn f(&self); }
trait T2 { fn g(&self); }

struct S;

impl T1 for S { 
    fn f(&self) {
        println!("<S as T1>::f");
    }   
}

// impl T2 for dyn T1    -- gives same error
impl<T: T1> T2 for T { 
    fn g(&self) {
        println!("<T1 as T2>::g");
        self.f();
    }   
}

fn main() {
    let s: S = S;
    let bs: Box<S> = Box::new(s);

    let t1_object: Box<dyn T1> = bs; 
    let t2_object: Box<dyn T2> = t1_object;
}

Produces:

cargo build   
   Compiling fatptr v0.1.0 (/Users/rod/code/rust/triage/fatptr)
error[E0308]: mismatched types
  --> src/main.rs:26:34
   |
26 |     let t2_object: Box<dyn T2> = t1_object;
   |                    -----------   ^^^^^^^^^ expected trait `T2`, found trait `T1`
   |                    |
   |                    expected due to this
   |
   = note: expected struct `Box<dyn T2>`
              found struct `Box<dyn T1>`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `fatptr` (bin "fatptr") due to 1 previous error

which is essentially the same as in the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. 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