Skip to content

Commit 0cd9708

Browse files
committed
Delegation: fix ICE on wrong instantiation
1 parent 10a7aa1 commit 0cd9708

21 files changed

+236
-177
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2212,6 +2212,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22122212
try_emit("delegation with early bound generics");
22132213
}
22142214

2215+
// There is no way to instantiate `Self` param for caller if
2216+
// 1. callee is a trait method
2217+
// 2. delegation item isn't an associative item
2218+
if let DefKind::AssocFn = self.tcx().def_kind(sig_id)
2219+
&& let DefKind::Fn = self.tcx().def_kind(self.item_def_id())
2220+
&& self.tcx().associated_item(sig_id).container
2221+
== ty::AssocItemContainer::TraitContainer
2222+
{
2223+
try_emit("delegation to a trait method from a free function");
2224+
}
2225+
22152226
if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes {
22162227
try_emit("delegation to async functions");
22172228
}

tests/ui/delegation/bad-resolve.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![feature(fn_delegation)]
2-
//~^ WARN the feature `fn_delegation` is incomplete
2+
#![allow(incomplete_features)]
33

44
trait Trait {
55
const C: u32 = 0;
@@ -34,14 +34,6 @@ impl Trait for S {
3434

3535
reuse foo { &self.0 }
3636
//~^ ERROR cannot find function `foo` in this scope
37-
reuse F::foo { &self.0 }
38-
//~^ ERROR cannot find function `foo` in `F`
39-
//~| ERROR duplicate definitions with name `foo`
40-
}
41-
42-
impl S {
43-
reuse F::foo { &self.0 }
44-
//~^ ERROR cannot find function `foo` in `F`
4537
}
4638

4739
fn main() {}

tests/ui/delegation/bad-resolve.stderr

+2-35
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,6 @@ LL | reuse <F as Trait>::baz;
2525
| | help: there is an associated function with a similar name: `bar`
2626
| not a member of trait `Trait`
2727

28-
error[E0201]: duplicate definitions with name `foo`:
29-
--> $DIR/bad-resolve.rs:37:5
30-
|
31-
LL | fn foo(&self, x: i32) -> i32 { x }
32-
| ---------------------------------- item in trait
33-
...
34-
LL | reuse foo { &self.0 }
35-
| --------------------- previous definition here
36-
LL |
37-
LL | reuse F::foo { &self.0 }
38-
| ^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
39-
4028
error[E0423]: expected function, found associated constant `Trait::C`
4129
--> $DIR/bad-resolve.rs:24:11
4230
|
@@ -66,27 +54,6 @@ error[E0425]: cannot find function `foo` in this scope
6654
LL | reuse foo { &self.0 }
6755
| ^^^ not found in this scope
6856

69-
error[E0425]: cannot find function `foo` in `F`
70-
--> $DIR/bad-resolve.rs:37:14
71-
|
72-
LL | reuse F::foo { &self.0 }
73-
| ^^^ not found in `F`
74-
75-
error[E0425]: cannot find function `foo` in `F`
76-
--> $DIR/bad-resolve.rs:43:14
77-
|
78-
LL | reuse F::foo { &self.0 }
79-
| ^^^ not found in `F`
80-
81-
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
82-
--> $DIR/bad-resolve.rs:1:12
83-
|
84-
LL | #![feature(fn_delegation)]
85-
| ^^^^^^^^^^^^^
86-
|
87-
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
88-
= note: `#[warn(incomplete_features)]` on by default
89-
9057
error[E0046]: not all trait items implemented, missing: `Type`
9158
--> $DIR/bad-resolve.rs:22:1
9259
|
@@ -96,7 +63,7 @@ LL | type Type;
9663
LL | impl Trait for S {
9764
| ^^^^^^^^^^^^^^^^ missing `Type` in implementation
9865

99-
error: aborting due to 11 previous errors; 1 warning emitted
66+
error: aborting due to 8 previous errors
10067

101-
Some errors have detailed explanations: E0046, E0201, E0324, E0407, E0423, E0425, E0575, E0576.
68+
Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0575, E0576.
10269
For more information about an error, try `rustc --explain E0046`.

tests/ui/delegation/duplicate-definition-inside-trait-impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![feature(fn_delegation)]
2-
//~^ WARN the feature `fn_delegation` is incomplete
2+
#![allow(incomplete_features)]
33

44
trait Trait {
55
fn foo(&self) -> u32 { 0 }

tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr

+1-10
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@ LL | reuse to_reuse::foo { self }
99
LL | reuse Trait::foo;
1010
| ^^^^^^^^^^^^^^^^^ duplicate definition
1111

12-
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
13-
--> $DIR/duplicate-definition-inside-trait-impl.rs:1:12
14-
|
15-
LL | #![feature(fn_delegation)]
16-
| ^^^^^^^^^^^^^
17-
|
18-
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
19-
= note: `#[warn(incomplete_features)]` on by default
20-
21-
error: aborting due to 1 previous error; 1 warning emitted
12+
error: aborting due to 1 previous error
2213

2314
For more information about this error, try `rustc --explain E0201`.

tests/ui/delegation/explicit-paths-in-traits-pass.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@ run-pass
22

33
#![feature(fn_delegation)]
4-
//~^ WARN the feature `fn_delegation` is incomplete
4+
#![allow(incomplete_features)]
55

66
trait ToReuse {
77
fn foo(&self, x: i32) -> i32 { x }

tests/ui/delegation/explicit-paths-in-traits-pass.stderr

-11
This file was deleted.

tests/ui/delegation/explicit-paths-pass.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@ run-pass
22

33
#![feature(fn_delegation)]
4-
//~^ WARN the feature `fn_delegation` is incomplete
4+
#![allow(incomplete_features)]
55

66
trait Trait {
77
fn bar(&self, x: i32) -> i32 { x }
@@ -10,7 +10,6 @@ trait Trait {
1010
}
1111
fn static_method(x: i32) -> i32 { x }
1212
fn static_method2(x: i32, y: i32) -> i32 { x + y }
13-
fn baz<'a>(&self, x: &'a i32) -> &'a i32 { x }
1413
}
1514

1615
struct F;
@@ -29,11 +28,9 @@ impl Trait for S {
2928
reuse Trait::description { &self.0 }
3029
reuse <F as Trait>::static_method;
3130
reuse <F as Trait>::static_method2 { S::static_method(self) }
32-
reuse Trait::baz { &self.0 }
3331
}
3432

3533
impl S {
36-
reuse Trait::baz { &self.0 }
3734
reuse <F as Trait>::static_method { to_reuse::foo(self) }
3835
}
3936

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

52-
reuse <S as Trait>::static_method;
53-
reuse <S as Trait>::static_method2 { static_method(self) }
5449
#[inline]
5550
reuse to_reuse::foo;
56-
assert_eq!(42, static_method(42));
57-
assert_eq!(21, static_method2(10, 10));
5851
assert_eq!(43, foo(42));
5952
assert_eq!(15, zero_args());
60-
61-
let x: i32 = 15;
62-
assert_eq!(&x, <S as Trait>::baz(&s, &x));
63-
assert_eq!(&x, S::baz(&s, &x));
6453
}

tests/ui/delegation/explicit-paths-pass.stderr

-11
This file was deleted.

tests/ui/delegation/explicit-paths-signature-pass.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@ run-pass
22

33
#![feature(fn_delegation)]
4-
//~^ WARN the feature `fn_delegation` is incomplete
4+
#![allow(incomplete_features)]
55

66
mod to_reuse {
77
use crate::S;

tests/ui/delegation/explicit-paths-signature-pass.stderr

-11
This file was deleted.

tests/ui/delegation/explicit-paths.rs

+69-10
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,84 @@
11
#![feature(fn_delegation)]
2-
//~^ WARN the feature `fn_delegation` is incomplete
2+
#![allow(incomplete_features)]
33

44
trait Trait {
5-
fn bar(&self) -> i32 { 42 }
5+
fn foo1(&self, x: i32) -> i32 { x }
6+
fn foo2(x: i32) -> i32 { x }
67
}
78

89
struct F;
910
impl Trait for F {}
10-
1111
struct S(F);
1212

13-
impl Trait for S {
14-
reuse <F as Trait>::bar;
15-
//~^ ERROR mismatched types
13+
pub mod to_reuse {
14+
pub fn foo3() {}
15+
}
16+
17+
impl F {
18+
fn foo4(&self) {}
19+
}
20+
21+
mod fn_to_other {
22+
use super::*;
23+
24+
reuse Trait::foo1;
25+
//~^ ERROR delegation to a trait method from a free function is not supported yet
26+
reuse <S as Trait>::foo2;
27+
//~^ ERROR delegation to a trait method from a free function is not supported yet
28+
reuse to_reuse::foo3;
29+
reuse S::foo4;
30+
//~^ ERROR cannot find function `foo4` in `S`
31+
}
32+
33+
mod inherent_impl_assoc_fn_to_other {
34+
use crate::*;
35+
36+
impl S {
37+
reuse Trait::foo1 { &self.0 }
38+
reuse <S as Trait>::foo2;
39+
reuse to_reuse::foo3;
40+
reuse F::foo4 { &self.0 }
41+
//~^ ERROR cannot find function `foo4` in `F`
42+
}
43+
}
44+
45+
mod trait_impl_assoc_fn_to_other {
46+
use crate::*;
47+
48+
impl Trait for S {
49+
reuse Trait::foo1 { &self.0 }
50+
reuse <F as Trait>::foo2;
51+
reuse to_reuse::foo3;
52+
//~^ ERROR method `foo3` is not a member of trait `Trait`
53+
reuse F::foo4 { &self.0 }
54+
//~^ ERROR method `foo4` is not a member of trait `Trait`
55+
//~| ERROR cannot find function `foo4` in `F`
56+
}
57+
}
58+
59+
mod trait_assoc_fn_to_other {
60+
use crate::*;
61+
62+
trait Trait2 : Trait {
63+
reuse <F as Trait>::foo1 { self }
64+
//~^ ERROR mismatched types
65+
reuse <F as Trait>::foo2;
66+
reuse to_reuse::foo3;
67+
reuse F::foo4 { &F }
68+
//~^ ERROR cannot find function `foo4` in `F`
69+
}
1670
}
1771

18-
struct S2(F);
72+
mod type_mismatch {
73+
use crate::*;
1974

20-
impl Trait for S2 {
21-
reuse <S2 as Trait>::bar { &self.0 }
22-
//~^ ERROR mismatched types
75+
struct S2;
76+
impl Trait for S {
77+
//~^ ERROR conflicting implementations of trait `Trait` for type `S`
78+
reuse <S2 as Trait>::foo1;
79+
//~^ ERROR mismatched types
80+
//~| ERROR the trait bound `S2: Trait` is not satisfied
81+
}
2382
}
2483

2584
fn main() {}

0 commit comments

Comments
 (0)