Delegation: fix ICE on wrong self
resolution
This commit is contained in:
parent
eff958c59e
commit
17c6101864
3 changed files with 145 additions and 11 deletions
|
@ -2531,7 +2531,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKind::Delegation(ref delegation) => {
|
ItemKind::Delegation(ref delegation) => {
|
||||||
self.resolve_delegation(delegation);
|
let span = delegation.path.segments.last().unwrap().ident.span;
|
||||||
|
self.with_generic_param_rib(
|
||||||
|
&[],
|
||||||
|
RibKind::Item(HasGenericParams::Yes(span), def_kind),
|
||||||
|
LifetimeRibKind::Generics {
|
||||||
|
binder: item.id,
|
||||||
|
kind: LifetimeBinderKind::Function,
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
|this| this.resolve_delegation(delegation),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKind::ExternCrate(..) => {}
|
ItemKind::ExternCrate(..) => {}
|
||||||
|
@ -2819,7 +2829,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||||
walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
|
walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
|
||||||
}
|
}
|
||||||
AssocItemKind::Delegation(delegation) => {
|
AssocItemKind::Delegation(delegation) => {
|
||||||
self.resolve_delegation(delegation);
|
self.with_generic_param_rib(
|
||||||
|
&[],
|
||||||
|
RibKind::AssocItem,
|
||||||
|
LifetimeRibKind::Generics {
|
||||||
|
binder: item.id,
|
||||||
|
kind: LifetimeBinderKind::Function,
|
||||||
|
span: delegation.path.segments.last().unwrap().ident.span,
|
||||||
|
},
|
||||||
|
|this| this.resolve_delegation(delegation),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
AssocItemKind::Type(box TyAlias { generics, .. }) => self
|
AssocItemKind::Type(box TyAlias { generics, .. }) => self
|
||||||
.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
|
.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
|
||||||
|
@ -3069,7 +3088,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||||
}
|
}
|
||||||
AssocItemKind::Delegation(box delegation) => {
|
AssocItemKind::Delegation(box delegation) => {
|
||||||
debug!("resolve_implementation AssocItemKind::Delegation");
|
debug!("resolve_implementation AssocItemKind::Delegation");
|
||||||
self.check_trait_item(
|
self.with_generic_param_rib(
|
||||||
|
&[],
|
||||||
|
RibKind::AssocItem,
|
||||||
|
LifetimeRibKind::Generics {
|
||||||
|
binder: item.id,
|
||||||
|
kind: LifetimeBinderKind::Function,
|
||||||
|
span: delegation.path.segments.last().unwrap().ident.span,
|
||||||
|
},
|
||||||
|
|this| {
|
||||||
|
this.check_trait_item(
|
||||||
item.id,
|
item.id,
|
||||||
item.ident,
|
item.ident,
|
||||||
&item.kind,
|
&item.kind,
|
||||||
|
@ -3078,7 +3106,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||||
seen_trait_items,
|
seen_trait_items,
|
||||||
|i, s, c| MethodNotMemberOfTrait(i, s, c),
|
|i, s, c| MethodNotMemberOfTrait(i, s, c),
|
||||||
);
|
);
|
||||||
self.resolve_delegation(delegation);
|
|
||||||
|
this.resolve_delegation(delegation)
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
AssocItemKind::MacCall(_) => {
|
AssocItemKind::MacCall(_) => {
|
||||||
panic!("unexpanded macro in resolve!")
|
panic!("unexpanded macro in resolve!")
|
||||||
|
|
38
tests/ui/delegation/target-expr.rs
Normal file
38
tests/ui/delegation/target-expr.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#![feature(fn_delegation)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
fn static_method(x: i32) -> i32 { x }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct F;
|
||||||
|
|
||||||
|
struct S(F);
|
||||||
|
impl Trait for S {}
|
||||||
|
|
||||||
|
fn foo(x: i32) -> i32 { x }
|
||||||
|
|
||||||
|
fn bar<T: Default>(_: T) {
|
||||||
|
reuse Trait::static_method {
|
||||||
|
//~^ ERROR delegation with early bound generics is not supported yet
|
||||||
|
//~| ERROR mismatched types
|
||||||
|
let _ = T::Default();
|
||||||
|
//~^ ERROR can't use generic parameters from outer item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let y = 0;
|
||||||
|
reuse <S as Trait>::static_method {
|
||||||
|
let x = y;
|
||||||
|
//~^ ERROR can't capture dynamic environment in a fn item
|
||||||
|
foo(self);
|
||||||
|
|
||||||
|
let reuse_ptr: fn(i32) -> i32 = static_method;
|
||||||
|
reuse_ptr(0)
|
||||||
|
}
|
||||||
|
self.0;
|
||||||
|
//~^ ERROR expected value, found module `self`
|
||||||
|
let z = x;
|
||||||
|
//~^ ERROR cannot find value `x` in this scope
|
||||||
|
}
|
65
tests/ui/delegation/target-expr.stderr
Normal file
65
tests/ui/delegation/target-expr.stderr
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
error[E0401]: can't use generic parameters from outer item
|
||||||
|
--> $DIR/target-expr.rs:19:17
|
||||||
|
|
|
||||||
|
LL | fn bar<T: Default>(_: T) {
|
||||||
|
| - type parameter from outer item
|
||||||
|
LL | reuse Trait::static_method {
|
||||||
|
| - help: try introducing a local generic parameter here: `T,`
|
||||||
|
...
|
||||||
|
LL | let _ = T::Default();
|
||||||
|
| ^^^^^^^^^^ use of generic parameter from outer item
|
||||||
|
|
||||||
|
error[E0434]: can't capture dynamic environment in a fn item
|
||||||
|
--> $DIR/target-expr.rs:27:17
|
||||||
|
|
|
||||||
|
LL | let x = y;
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= help: use the `|| { ... }` closure form instead
|
||||||
|
|
||||||
|
error[E0424]: expected value, found module `self`
|
||||||
|
--> $DIR/target-expr.rs:34:5
|
||||||
|
|
|
||||||
|
LL | fn main() {
|
||||||
|
| ---- this function can't have a `self` parameter
|
||||||
|
...
|
||||||
|
LL | self.0;
|
||||||
|
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
|
||||||
|
|
||||||
|
error[E0425]: cannot find value `x` in this scope
|
||||||
|
--> $DIR/target-expr.rs:36:13
|
||||||
|
|
|
||||||
|
LL | let z = x;
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
help: the binding `x` is available in a different scope in the same function
|
||||||
|
--> $DIR/target-expr.rs:27:13
|
||||||
|
|
|
||||||
|
LL | let x = y;
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: delegation with early bound generics is not supported yet
|
||||||
|
--> $DIR/target-expr.rs:16:18
|
||||||
|
|
|
||||||
|
LL | fn static_method(x: i32) -> i32 { x }
|
||||||
|
| ------------------------------- callee defined here
|
||||||
|
...
|
||||||
|
LL | reuse Trait::static_method {
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/target-expr.rs:16:32
|
||||||
|
|
|
||||||
|
LL | reuse Trait::static_method {
|
||||||
|
| ________________________________^
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | let _ = T::Default();
|
||||||
|
LL | |
|
||||||
|
LL | | }
|
||||||
|
| |_____^ expected `i32`, found `()`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434.
|
||||||
|
For more information about an error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue