about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBryanskiy <ivakin.kir@gmail.com>2024-03-22 21:54:17 +0300
committerBryanskiy <ivakin.kir@gmail.com>2024-03-26 14:00:51 +0300
commit17c6101864a3d7f5d655d69f18c7bd1cf8bfa92c (patch)
tree4db71d5a9d709bdf113cf9611f854a9b276edf72
parenteff958c59e8c07ba0515e164b825c9001b242294 (diff)
downloadrust-17c6101864a3d7f5d655d69f18c7bd1cf8bfa92c.tar.gz
rust-17c6101864a3d7f5d655d69f18c7bd1cf8bfa92c.zip
Delegation: fix ICE on wrong `self` resolution
-rw-r--r--compiler/rustc_resolve/src/late.rs53
-rw-r--r--tests/ui/delegation/target-expr.rs38
-rw-r--r--tests/ui/delegation/target-expr.stderr65
3 files changed, 145 insertions, 11 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index b2b339d2521..49b4a6efd3c 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 00000000000..b9c6fe92810
--- /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: 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
+}
diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr
new file mode 100644
index 00000000000..da0fac2f5e4
--- /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: 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`.