From d2b9a77bdfd3451f5e55f96d383f97aefb76e97e Mon Sep 17 00:00:00 2001 From: tinaun Date: Sat, 3 Mar 2018 17:07:48 -0500 Subject: [PATCH 1/2] check impl trait first --- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/mod.rs | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index b777ac30920cd..c7cebda95a1c5 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -309,7 +309,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // 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); + self.fcx.check_path_parameter_count(self.span, &mut fn_segment, true, false); // Create subst for early-bound lifetime parameters, combining // parameters from the type and those from the method. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index db5a458bb8ce4..36ed6864f3af0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4764,9 +4764,9 @@ 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. - self.check_path_parameter_count(span, &mut type_segment, false); - self.check_path_parameter_count(span, &mut fn_segment, false); - self.check_impl_trait(span, &mut fn_segment); + let supress_mismatch = self.check_impl_trait(span, &mut 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); let (fn_start, has_self) = match (type_segment, fn_segment) { (_, Some((_, generics))) => { @@ -4919,7 +4919,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn check_path_parameter_count(&self, span: Span, segment: &mut Option<(&hir::PathSegment, &ty::Generics)>, - is_method_call: bool) { + is_method_call: bool, + supress_mismatch_error: bool) { let (lifetimes, types, infer_types, bindings) = segment.map_or( (&[][..], &[][..], true, &[][..]), |(s, _)| s.parameters.as_ref().map_or( @@ -4959,7 +4960,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // type parameters, we force instantiate_value_path to // use inference variables instead of the provided types. *segment = None; - } else if types.len() < required_len && !infer_types { + } else if types.len() < required_len && !infer_types && !supress_mismatch_error { let expected_text = count_type_params(required_len); let actual_text = count_type_params(types.len()); struct_span_err!(self.tcx.sess, span, E0089, @@ -5026,10 +5027,11 @@ 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: &mut Option<(&hir::PathSegment, &ty::Generics)>) + -> bool { use hir::SyntheticTyParamKind::*; - segment.map(|(path_segment, generics)| { + let segment = segment.map(|(path_segment, generics)| { let explicit = !path_segment.infer_types; let impl_trait = generics.types.iter() .any(|ty_param| { @@ -5050,7 +5052,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { err.emit(); } + + impl_trait }); + + segment.unwrap_or(false) } // Resolves `typ` by a single level if `typ` is a type variable. From 97e0dc330fb4dfc3fc5161fbba1f0b4193d80bc9 Mon Sep 17 00:00:00 2001 From: tinaun Date: Sat, 3 Mar 2018 17:32:47 -0500 Subject: [PATCH 2/2] added test --- .../ui/impl-trait/universal-issue-48703.rs | 19 +++++++++++++++++++ .../impl-trait/universal-issue-48703.stderr | 9 +++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/ui/impl-trait/universal-issue-48703.rs create mode 100644 src/test/ui/impl-trait/universal-issue-48703.stderr diff --git a/src/test/ui/impl-trait/universal-issue-48703.rs b/src/test/ui/impl-trait/universal-issue-48703.rs new file mode 100644 index 0000000000000..e017b37b7b733 --- /dev/null +++ b/src/test/ui/impl-trait/universal-issue-48703.rs @@ -0,0 +1,19 @@ +// Copyright 2017 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. + +#![feature(universal_impl_trait)] + +use std::fmt::Debug; + +fn foo(x: impl Debug) { } + +fn main() { + foo::('a'); //~ ERROR cannot provide explicit type parameters +} diff --git a/src/test/ui/impl-trait/universal-issue-48703.stderr b/src/test/ui/impl-trait/universal-issue-48703.stderr new file mode 100644 index 0000000000000..ea509684f9efc --- /dev/null +++ b/src/test/ui/impl-trait/universal-issue-48703.stderr @@ -0,0 +1,9 @@ +error[E0632]: cannot provide explicit type parameters when `impl Trait` is used in argument position. + --> $DIR/universal-issue-48703.rs:18:5 + | +LL | foo::('a'); //~ ERROR cannot provide explicit type parameters + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0632`.