Skip to content

Commit

Permalink
Delegation: fix ICE on wrong instantiation
Browse files Browse the repository at this point in the history
  • Loading branch information
Bryanskiy committed Mar 27, 2024
1 parent b13a71a commit eb3617b
Show file tree
Hide file tree
Showing 19 changed files with 207 additions and 169 deletions.
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() {}

0 comments on commit eb3617b

Please sign in to comment.