Skip to content

Commit

Permalink
Rollup merge of rust-lang#105491 - sulami:master, r=compiler-errors
Browse files Browse the repository at this point in the history
Illegal sized bounds: only suggest mutability change if needed

In a scenario like

```rust
struct Type;

pub trait Trait {
    fn function(&mut self)
    where
        Self: Sized;
}

impl Trait for Type {
    fn function(&mut self) {}
}

fn main() {
    (&mut Type as &mut dyn Trait).function();
}
```

the problem is Sized, not the mutability of self. Thus don't emit the "you need &T instead of &mut T" note, or the other way around, as all it does is just invert the mutability of whatever was supplied.

Fixes rust-lang#103622.
  • Loading branch information
Dylan-DPC authored Dec 13, 2022
2 parents d5a8be4 + 40ba1c9 commit 2dd2b73
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ProbeScope::TraitsInScope,
) {
Ok(ref new_pick) if pick.differs_from(new_pick) => {
needs_mut = true;
needs_mut = new_pick.self_ty.ref_mutability() != self_ty.ref_mutability();
}
_ => {}
}
Expand Down
34 changes: 34 additions & 0 deletions src/test/ui/illegal-sized-bound/mutability-mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
struct MutType;

pub trait MutTrait {
fn function(&mut self)
where
Self: Sized;
//~^ this has a `Sized` requirement
}

impl MutTrait for MutType {
fn function(&mut self) {}
}

struct Type;

pub trait Trait {
fn function(&self)
where
Self: Sized;
//~^ this has a `Sized` requirement
}

impl Trait for Type {
fn function(&self) {}
}

fn main() {
(&MutType as &dyn MutTrait).function();
//~^ ERROR the `function` method cannot be invoked on a trait object
//~| NOTE you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
(&mut Type as &mut dyn Trait).function();
//~^ ERROR the `function` method cannot be invoked on a trait object
//~| NOTE you need `&dyn Trait` instead of `&mut dyn Trait`
}
24 changes: 24 additions & 0 deletions src/test/ui/illegal-sized-bound/mutability-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error: the `function` method cannot be invoked on a trait object
--> $DIR/mutability-mismatch.rs:28:33
|
LL | Self: Sized;
| ----- this has a `Sized` requirement
...
LL | (&MutType as &dyn MutTrait).function();
| ^^^^^^^^
|
= note: you need `&mut dyn MutTrait` instead of `&dyn MutTrait`

error: the `function` method cannot be invoked on a trait object
--> $DIR/mutability-mismatch.rs:31:35
|
LL | Self: Sized;
| ----- this has a `Sized` requirement
...
LL | (&mut Type as &mut dyn Trait).function();
| ^^^^^^^^
|
= note: you need `&dyn Trait` instead of `&mut dyn Trait`

error: aborting due to 2 previous errors

32 changes: 32 additions & 0 deletions src/test/ui/illegal-sized-bound/regular.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
struct MutType;

pub trait MutTrait {
fn function(&mut self)
where
Self: Sized;
//~^ this has a `Sized` requirement
}

impl MutTrait for MutType {
fn function(&mut self) {}
}

struct Type;

pub trait Trait {
fn function(&self)
where
Self: Sized;
//~^ this has a `Sized` requirement
}

impl Trait for Type {
fn function(&self) {}
}

fn main() {
(&mut MutType as &mut dyn MutTrait).function();
//~^ ERROR the `function` method cannot be invoked on a trait object
(&Type as &dyn Trait).function();
//~^ ERROR the `function` method cannot be invoked on a trait object
}
20 changes: 20 additions & 0 deletions src/test/ui/illegal-sized-bound/regular.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: the `function` method cannot be invoked on a trait object
--> $DIR/regular.rs:28:41
|
LL | Self: Sized;
| ----- this has a `Sized` requirement
...
LL | (&mut MutType as &mut dyn MutTrait).function();
| ^^^^^^^^

error: the `function` method cannot be invoked on a trait object
--> $DIR/regular.rs:30:27
|
LL | Self: Sized;
| ----- this has a `Sized` requirement
...
LL | (&Type as &dyn Trait).function();
| ^^^^^^^^

error: aborting due to 2 previous errors

0 comments on commit 2dd2b73

Please sign in to comment.