about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-05-24 17:34:23 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-05-24 18:43:48 -0400
commit558cbfb19b8e43e447f1cae6ecdb06c0b961067e (patch)
tree8b5bbc46eecee1ff841b735f46895ec349d128fd /src
parenta76bff86e6f4b56b2c3fd1704ce8535ed207dd78 (diff)
downloadrust-558cbfb19b8e43e447f1cae6ecdb06c0b961067e.tar.gz
rust-558cbfb19b8e43e447f1cae6ecdb06c0b961067e.zip
prohibit turbofish in `impl Trait` methods
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/method/confirm.rs52
-rw-r--r--src/librustc_typeck/check/method/mod.rs14
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.rs27
-rw-r--r--src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.stderr9
5 files changed, 75 insertions, 31 deletions
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 7d9f2e094e1..f3a3c30fe5a 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -46,18 +46,21 @@ pub struct ConfirmResult<'tcx> {
 }
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
-    pub fn confirm_method(&self,
-                          span: Span,
-                          self_expr: &'gcx hir::Expr,
-                          call_expr: &'gcx hir::Expr,
-                          unadjusted_self_ty: Ty<'tcx>,
-                          pick: probe::Pick<'tcx>,
-                          segment: &hir::PathSegment)
-                          -> ConfirmResult<'tcx> {
-        debug!("confirm(unadjusted_self_ty={:?}, pick={:?}, generic_args={:?})",
-               unadjusted_self_ty,
-               pick,
-               segment.parameters);
+    pub fn confirm_method(
+        &self,
+        span: Span,
+        self_expr: &'gcx hir::Expr,
+        call_expr: &'gcx hir::Expr,
+        unadjusted_self_ty: Ty<'tcx>,
+        pick: probe::Pick<'tcx>,
+        segment: &hir::PathSegment,
+    ) -> ConfirmResult<'tcx> {
+        debug!(
+            "confirm(unadjusted_self_ty={:?}, pick={:?}, generic_args={:?})",
+            unadjusted_self_ty,
+            pick,
+            segment.parameters,
+        );
 
         let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
         confirm_cx.confirm(unadjusted_self_ty, pick, segment)
@@ -78,11 +81,12 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
         }
     }
 
-    fn confirm(&mut self,
-               unadjusted_self_ty: Ty<'tcx>,
-               pick: probe::Pick<'tcx>,
-               segment: &hir::PathSegment)
-               -> ConfirmResult<'tcx> {
+    fn confirm(
+        &mut self,
+        unadjusted_self_ty: Ty<'tcx>,
+        pick: probe::Pick<'tcx>,
+        segment: &hir::PathSegment,
+    ) -> ConfirmResult<'tcx> {
         // Adjust the self expression the user provided and obtain the adjusted type.
         let self_ty = self.adjust_self_ty(unadjusted_self_ty, &pick);
 
@@ -300,17 +304,19 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             })
     }
 
-    fn instantiate_method_substs(&mut self,
-                                 pick: &probe::Pick<'tcx>,
-                                 segment: &hir::PathSegment,
-                                 parent_substs: &Substs<'tcx>)
-                                 -> &'tcx Substs<'tcx> {
+    fn instantiate_method_substs(
+        &mut self,
+        pick: &probe::Pick<'tcx>,
+        segment: &hir::PathSegment,
+        parent_substs: &Substs<'tcx>,
+    ) -> &'tcx Substs<'tcx> {
         // Determine the values for the generic parameters of the method.
         // If they were not explicitly supplied, just construct fresh
         // variables.
         let method_generics = self.tcx.generics_of(pick.item.def_id);
         let mut fn_segment = Some((segment, method_generics));
-        self.fcx.check_path_parameter_count(self.span, &mut fn_segment, true, false);
+        let supress_mismatch = self.fcx.check_impl_trait(self.span, fn_segment);
+        self.fcx.check_path_parameter_count(self.span, &mut fn_segment, true, supress_mismatch);
 
         // Create subst for early-bound lifetime parameters, combining
         // parameters from the type and those from the method.
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 8ffb6e99fc0..49f9ae0e971 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -179,12 +179,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         self.tcx.check_stability(pick.item.def_id, Some(call_expr.id), span);
 
-        let result = self.confirm_method(span,
-                                         self_expr,
-                                         call_expr,
-                                         self_ty,
-                                         pick.clone(),
-                                         segment);
+        let result = self.confirm_method(
+            span,
+            self_expr,
+            call_expr,
+            self_ty,
+            pick.clone(),
+            segment,
+        );
 
         if result.illegal_sized_bound {
             // We probe again, taking all traits into account (not only those in scope).
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 46dbccaa137..70d299437a6 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4734,7 +4734,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // variables. If the user provided some types, we may still need
         // to add defaults. If the user provided *too many* types, that's
         // a problem.
-        let supress_mismatch = self.check_impl_trait(span, &mut fn_segment);
+        let supress_mismatch = self.check_impl_trait(span, fn_segment);
         self.check_path_parameter_count(span, &mut type_segment, false, supress_mismatch);
         self.check_path_parameter_count(span, &mut fn_segment, false, supress_mismatch);
 
@@ -5019,7 +5019,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     /// Report error if there is an explicit type parameter when using `impl Trait`.
     fn check_impl_trait(&self,
                         span: Span,
-                        segment: &mut Option<(&hir::PathSegment, &ty::Generics)>)
+                        segment: Option<(&hir::PathSegment, &ty::Generics)>)
                         -> bool {
         let segment = segment.map(|(path_segment, generics)| {
             let explicit = !path_segment.infer_types;
diff --git a/src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.rs b/src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.rs
new file mode 100644
index 00000000000..ac53612d2da
--- /dev/null
+++ b/src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.rs
@@ -0,0 +1,27 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::any::Any;
+pub struct EventHandler {
+}
+
+impl EventHandler
+{
+    pub fn handle_event<T: Any>(&mut self, _efunc: impl FnMut(T)) {}
+}
+
+struct TestEvent(i32);
+
+fn main() {
+    let mut evt = EventHandler {};
+    evt.handle_event::<TestEvent, fn(TestEvent)>(|_evt| {
+        //~^ ERROR cannot provide explicit type parameters
+    });
+}
diff --git a/src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.stderr b/src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.stderr
new file mode 100644
index 00000000000..fec3f78535d
--- /dev/null
+++ b/src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.stderr
@@ -0,0 +1,9 @@
+error[E0632]: cannot provide explicit type parameters when `impl Trait` is used in argument position.
+  --> $DIR/universal-turbofish-in-method-issue-50950.rs:24:9
+   |
+LL |     evt.handle_event::<TestEvent, fn(TestEvent)>(|_evt| {
+   |         ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0632`.