From 558cbfb19b8e43e447f1cae6ecdb06c0b961067e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 24 May 2018 17:34:23 -0400 Subject: [PATCH] prohibit turbofish in `impl Trait` methods --- src/librustc_typeck/check/method/confirm.rs | 52 +++++++++++-------- src/librustc_typeck/check/method/mod.rs | 14 ++--- src/librustc_typeck/check/mod.rs | 4 +- ...iversal-turbofish-in-method-issue-50950.rs | 27 ++++++++++ ...sal-turbofish-in-method-issue-50950.stderr | 9 ++++ 5 files changed, 75 insertions(+), 31 deletions(-) create mode 100644 src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.rs create mode 100644 src/test/ui/impl-trait/universal-turbofish-in-method-issue-50950.stderr diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 7d9f2e094e1af..f3a3c30fe5ad9 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 8ffb6e99fc04e..49f9ae0e971a9 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 46dbccaa137ea..70d299437a6e9 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 0000000000000..ac53612d2daac --- /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 or the MIT license +// , 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(&mut self, _efunc: impl FnMut(T)) {} +} + +struct TestEvent(i32); + +fn main() { + let mut evt = EventHandler {}; + evt.handle_event::(|_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 0000000000000..fec3f78535ddd --- /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::(|_evt| { + | ^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0632`.