Skip to content

Commit 17c6101

Browse files
committed
Delegation: fix ICE on wrong self resolution
1 parent eff958c commit 17c6101

File tree

3 files changed

+145
-11
lines changed

3 files changed

+145
-11
lines changed

compiler/rustc_resolve/src/late.rs

+42-11
Original file line numberDiff line numberDiff line change
@@ -2531,7 +2531,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
25312531
}
25322532

25332533
ItemKind::Delegation(ref delegation) => {
2534-
self.resolve_delegation(delegation);
2534+
let span = delegation.path.segments.last().unwrap().ident.span;
2535+
self.with_generic_param_rib(
2536+
&[],
2537+
RibKind::Item(HasGenericParams::Yes(span), def_kind),
2538+
LifetimeRibKind::Generics {
2539+
binder: item.id,
2540+
kind: LifetimeBinderKind::Function,
2541+
span,
2542+
},
2543+
|this| this.resolve_delegation(delegation),
2544+
);
25352545
}
25362546

25372547
ItemKind::ExternCrate(..) => {}
@@ -2819,7 +2829,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
28192829
walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
28202830
}
28212831
AssocItemKind::Delegation(delegation) => {
2822-
self.resolve_delegation(delegation);
2832+
self.with_generic_param_rib(
2833+
&[],
2834+
RibKind::AssocItem,
2835+
LifetimeRibKind::Generics {
2836+
binder: item.id,
2837+
kind: LifetimeBinderKind::Function,
2838+
span: delegation.path.segments.last().unwrap().ident.span,
2839+
},
2840+
|this| this.resolve_delegation(delegation),
2841+
);
28232842
}
28242843
AssocItemKind::Type(box TyAlias { generics, .. }) => self
28252844
.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
@@ -3069,16 +3088,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
30693088
}
30703089
AssocItemKind::Delegation(box delegation) => {
30713090
debug!("resolve_implementation AssocItemKind::Delegation");
3072-
self.check_trait_item(
3073-
item.id,
3074-
item.ident,
3075-
&item.kind,
3076-
ValueNS,
3077-
item.span,
3078-
seen_trait_items,
3079-
|i, s, c| MethodNotMemberOfTrait(i, s, c),
3091+
self.with_generic_param_rib(
3092+
&[],
3093+
RibKind::AssocItem,
3094+
LifetimeRibKind::Generics {
3095+
binder: item.id,
3096+
kind: LifetimeBinderKind::Function,
3097+
span: delegation.path.segments.last().unwrap().ident.span,
3098+
},
3099+
|this| {
3100+
this.check_trait_item(
3101+
item.id,
3102+
item.ident,
3103+
&item.kind,
3104+
ValueNS,
3105+
item.span,
3106+
seen_trait_items,
3107+
|i, s, c| MethodNotMemberOfTrait(i, s, c),
3108+
);
3109+
3110+
this.resolve_delegation(delegation)
3111+
},
30803112
);
3081-
self.resolve_delegation(delegation);
30823113
}
30833114
AssocItemKind::MacCall(_) => {
30843115
panic!("unexpanded macro in resolve!")

tests/ui/delegation/target-expr.rs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#![feature(fn_delegation)]
2+
#![allow(incomplete_features)]
3+
4+
trait Trait {
5+
fn static_method(x: i32) -> i32 { x }
6+
}
7+
8+
struct F;
9+
10+
struct S(F);
11+
impl Trait for S {}
12+
13+
fn foo(x: i32) -> i32 { x }
14+
15+
fn bar<T: Default>(_: T) {
16+
reuse Trait::static_method {
17+
//~^ ERROR delegation with early bound generics is not supported yet
18+
//~| ERROR mismatched types
19+
let _ = T::Default();
20+
//~^ ERROR can't use generic parameters from outer item
21+
}
22+
}
23+
24+
fn main() {
25+
let y = 0;
26+
reuse <S as Trait>::static_method {
27+
let x = y;
28+
//~^ ERROR can't capture dynamic environment in a fn item
29+
foo(self);
30+
31+
let reuse_ptr: fn(i32) -> i32 = static_method;
32+
reuse_ptr(0)
33+
}
34+
self.0;
35+
//~^ ERROR expected value, found module `self`
36+
let z = x;
37+
//~^ ERROR cannot find value `x` in this scope
38+
}
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
error[E0401]: can't use generic parameters from outer item
2+
--> $DIR/target-expr.rs:19:17
3+
|
4+
LL | fn bar<T: Default>(_: T) {
5+
| - type parameter from outer item
6+
LL | reuse Trait::static_method {
7+
| - help: try introducing a local generic parameter here: `T,`
8+
...
9+
LL | let _ = T::Default();
10+
| ^^^^^^^^^^ use of generic parameter from outer item
11+
12+
error[E0434]: can't capture dynamic environment in a fn item
13+
--> $DIR/target-expr.rs:27:17
14+
|
15+
LL | let x = y;
16+
| ^
17+
|
18+
= help: use the `|| { ... }` closure form instead
19+
20+
error[E0424]: expected value, found module `self`
21+
--> $DIR/target-expr.rs:34:5
22+
|
23+
LL | fn main() {
24+
| ---- this function can't have a `self` parameter
25+
...
26+
LL | self.0;
27+
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
28+
29+
error[E0425]: cannot find value `x` in this scope
30+
--> $DIR/target-expr.rs:36:13
31+
|
32+
LL | let z = x;
33+
| ^
34+
|
35+
help: the binding `x` is available in a different scope in the same function
36+
--> $DIR/target-expr.rs:27:13
37+
|
38+
LL | let x = y;
39+
| ^
40+
41+
error: delegation with early bound generics is not supported yet
42+
--> $DIR/target-expr.rs:16:18
43+
|
44+
LL | fn static_method(x: i32) -> i32 { x }
45+
| ------------------------------- callee defined here
46+
...
47+
LL | reuse Trait::static_method {
48+
| ^^^^^^^^^^^^^
49+
50+
error[E0308]: mismatched types
51+
--> $DIR/target-expr.rs:16:32
52+
|
53+
LL | reuse Trait::static_method {
54+
| ________________________________^
55+
LL | |
56+
LL | |
57+
LL | | let _ = T::Default();
58+
LL | |
59+
LL | | }
60+
| |_____^ expected `i32`, found `()`
61+
62+
error: aborting due to 6 previous errors
63+
64+
Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434.
65+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)