From 17c6101864a3d7f5d655d69f18c7bd1cf8bfa92c Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Fri, 22 Mar 2024 21:54:17 +0300 Subject: [PATCH] Delegation: fix ICE on wrong `self` resolution --- compiler/rustc_resolve/src/late.rs | 53 ++++++++++++++++----- tests/ui/delegation/target-expr.rs | 38 +++++++++++++++ tests/ui/delegation/target-expr.stderr | 65 ++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 tests/ui/delegation/target-expr.rs create mode 100644 tests/ui/delegation/target-expr.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b2b339d25217f..49b4a6efd3c3e 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2531,7 +2531,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } 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(..) => {} @@ -2819,7 +2829,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { walk_assoc_item(self, generics, LifetimeBinderKind::Function, item); } 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 .with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { @@ -3069,16 +3088,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } AssocItemKind::Delegation(box delegation) => { debug!("resolve_implementation AssocItemKind::Delegation"); - self.check_trait_item( - item.id, - item.ident, - &item.kind, - ValueNS, - item.span, - seen_trait_items, - |i, s, c| MethodNotMemberOfTrait(i, s, c), + 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.ident, + &item.kind, + ValueNS, + item.span, + seen_trait_items, + |i, s, c| MethodNotMemberOfTrait(i, s, c), + ); + + this.resolve_delegation(delegation) + }, ); - self.resolve_delegation(delegation); } AssocItemKind::MacCall(_) => { panic!("unexpanded macro in resolve!") diff --git a/tests/ui/delegation/target-expr.rs b/tests/ui/delegation/target-expr.rs new file mode 100644 index 0000000000000..b9c6fe92810b1 --- /dev/null +++ b/tests/ui/delegation/target-expr.rs @@ -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) { + 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 ::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 +} diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr new file mode 100644 index 0000000000000..da0fac2f5e46b --- /dev/null +++ b/tests/ui/delegation/target-expr.stderr @@ -0,0 +1,65 @@ +error[E0401]: can't use generic parameters from outer item + --> $DIR/target-expr.rs:19:17 + | +LL | fn bar(_: 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`.