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

Delegation: fix ICE on wrong Self instantiation #123101

Merged
merged 1 commit into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2212,6 +2212,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
try_emit("delegation with early bound generics");
}

// There is no way to instantiate `Self` param for caller if
// 1. callee is a trait method
// 2. delegation item isn't an associative item
if let DefKind::AssocFn = self.tcx().def_kind(sig_id)
&& let DefKind::Fn = self.tcx().def_kind(self.item_def_id())
&& self.tcx().associated_item(sig_id).container
== ty::AssocItemContainer::TraitContainer
{
try_emit("delegation to a trait method from a free function");
}

if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes {
try_emit("delegation to async functions");
}
Expand Down
10 changes: 1 addition & 9 deletions tests/ui/delegation/bad-resolve.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]

trait Trait {
const C: u32 = 0;
Expand Down Expand Up @@ -34,14 +34,6 @@ impl Trait for S {

reuse foo { &self.0 }
//~^ ERROR cannot find function `foo` in this scope
reuse F::foo { &self.0 }
//~^ ERROR cannot find function `foo` in `F`
//~| ERROR duplicate definitions with name `foo`
}

impl S {
reuse F::foo { &self.0 }
//~^ ERROR cannot find function `foo` in `F`
}

fn main() {}
37 changes: 2 additions & 35 deletions tests/ui/delegation/bad-resolve.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,6 @@ LL | reuse <F as Trait>::baz;
| | help: there is an associated function with a similar name: `bar`
| not a member of trait `Trait`

error[E0201]: duplicate definitions with name `foo`:
--> $DIR/bad-resolve.rs:37:5
|
LL | fn foo(&self, x: i32) -> i32 { x }
| ---------------------------------- item in trait
...
LL | reuse foo { &self.0 }
| --------------------- previous definition here
LL |
LL | reuse F::foo { &self.0 }
| ^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition

error[E0423]: expected function, found associated constant `Trait::C`
--> $DIR/bad-resolve.rs:24:11
|
Expand Down Expand Up @@ -66,27 +54,6 @@ error[E0425]: cannot find function `foo` in this scope
LL | reuse foo { &self.0 }
| ^^^ not found in this scope

error[E0425]: cannot find function `foo` in `F`
--> $DIR/bad-resolve.rs:37:14
|
LL | reuse F::foo { &self.0 }
| ^^^ not found in `F`

error[E0425]: cannot find function `foo` in `F`
--> $DIR/bad-resolve.rs:43:14
|
LL | reuse F::foo { &self.0 }
| ^^^ not found in `F`

warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/bad-resolve.rs:1:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default

error[E0046]: not all trait items implemented, missing: `Type`
--> $DIR/bad-resolve.rs:22:1
|
Expand All @@ -96,7 +63,7 @@ LL | type Type;
LL | impl Trait for S {
| ^^^^^^^^^^^^^^^^ missing `Type` in implementation

error: aborting due to 11 previous errors; 1 warning emitted
error: aborting due to 8 previous errors

Some errors have detailed explanations: E0046, E0201, E0324, E0407, E0423, E0425, E0575, E0576.
Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0575, E0576.
For more information about an error, try `rustc --explain E0046`.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]

trait Trait {
fn foo(&self) -> u32 { 0 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@ LL | reuse to_reuse::foo { self }
LL | reuse Trait::foo;
| ^^^^^^^^^^^^^^^^^ duplicate definition

warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/duplicate-definition-inside-trait-impl.rs:1:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default

error: aborting due to 1 previous error; 1 warning emitted
error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0201`.
2 changes: 1 addition & 1 deletion tests/ui/delegation/explicit-paths-in-traits-pass.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ run-pass

#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]

trait ToReuse {
fn foo(&self, x: i32) -> i32 { x }
Expand Down
11 changes: 0 additions & 11 deletions tests/ui/delegation/explicit-paths-in-traits-pass.stderr

This file was deleted.

13 changes: 1 addition & 12 deletions tests/ui/delegation/explicit-paths-pass.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ run-pass

#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]

trait Trait {
fn bar(&self, x: i32) -> i32 { x }
Expand All @@ -10,7 +10,6 @@ trait Trait {
}
fn static_method(x: i32) -> i32 { x }
fn static_method2(x: i32, y: i32) -> i32 { x + y }
fn baz<'a>(&self, x: &'a i32) -> &'a i32 { x }
}

struct F;
Expand All @@ -29,11 +28,9 @@ impl Trait for S {
reuse Trait::description { &self.0 }
reuse <F as Trait>::static_method;
reuse <F as Trait>::static_method2 { S::static_method(self) }
reuse Trait::baz { &self.0 }
}

impl S {
reuse Trait::baz { &self.0 }
reuse <F as Trait>::static_method { to_reuse::foo(self) }
}

Expand All @@ -49,16 +46,8 @@ fn main() {
assert_eq!(42, <S as Trait>::static_method(42));
assert_eq!(21, S::static_method2(10, 10));

reuse <S as Trait>::static_method;
reuse <S as Trait>::static_method2 { static_method(self) }
#[inline]
reuse to_reuse::foo;
assert_eq!(42, static_method(42));
assert_eq!(21, static_method2(10, 10));
assert_eq!(43, foo(42));
assert_eq!(15, zero_args());

let x: i32 = 15;
assert_eq!(&x, <S as Trait>::baz(&s, &x));
assert_eq!(&x, S::baz(&s, &x));
}
11 changes: 0 additions & 11 deletions tests/ui/delegation/explicit-paths-pass.stderr

This file was deleted.

2 changes: 1 addition & 1 deletion tests/ui/delegation/explicit-paths-signature-pass.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ run-pass

#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]

mod to_reuse {
use crate::S;
Expand Down
11 changes: 0 additions & 11 deletions tests/ui/delegation/explicit-paths-signature-pass.stderr

This file was deleted.

79 changes: 69 additions & 10 deletions tests/ui/delegation/explicit-paths.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,84 @@
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]

trait Trait {
fn bar(&self) -> i32 { 42 }
fn foo1(&self, x: i32) -> i32 { x }
fn foo2(x: i32) -> i32 { x }
}

struct F;
impl Trait for F {}

struct S(F);

impl Trait for S {
reuse <F as Trait>::bar;
//~^ ERROR mismatched types
pub mod to_reuse {
pub fn foo3() {}
}

impl F {
fn foo4(&self) {}
}

mod fn_to_other {
use super::*;

reuse Trait::foo1;
//~^ ERROR delegation to a trait method from a free function is not supported yet
reuse <S as Trait>::foo2;
//~^ ERROR delegation to a trait method from a free function is not supported yet
reuse to_reuse::foo3;
reuse S::foo4;
//~^ ERROR cannot find function `foo4` in `S`
}

mod inherent_impl_assoc_fn_to_other {
use crate::*;

impl S {
reuse Trait::foo1 { &self.0 }
reuse <S as Trait>::foo2;
reuse to_reuse::foo3;
reuse F::foo4 { &self.0 }
//~^ ERROR cannot find function `foo4` in `F`
}
}

mod trait_impl_assoc_fn_to_other {
use crate::*;

impl Trait for S {
reuse Trait::foo1 { &self.0 }
reuse <F as Trait>::foo2;
reuse to_reuse::foo3;
//~^ ERROR method `foo3` is not a member of trait `Trait`
reuse F::foo4 { &self.0 }
//~^ ERROR method `foo4` is not a member of trait `Trait`
//~| ERROR cannot find function `foo4` in `F`
}
}

mod trait_assoc_fn_to_other {
use crate::*;

trait Trait2 : Trait {
reuse <F as Trait>::foo1 { self }
//~^ ERROR mismatched types
reuse <F as Trait>::foo2;
reuse to_reuse::foo3;
reuse F::foo4 { &F }
//~^ ERROR cannot find function `foo4` in `F`
}
}

struct S2(F);
mod type_mismatch {
use crate::*;

impl Trait for S2 {
reuse <S2 as Trait>::bar { &self.0 }
//~^ ERROR mismatched types
struct S2;
impl Trait for S {
//~^ ERROR conflicting implementations of trait `Trait` for type `S`
reuse <S2 as Trait>::foo1;
//~^ ERROR mismatched types
//~| ERROR the trait bound `S2: Trait` is not satisfied
}
}

fn main() {}