From c9b7b1f73b8d256a0885506d8e7e76cd35067318 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 22 Jan 2020 01:43:24 +0000 Subject: [PATCH] Refactor `create_substs_for_generic_args` a little --- src/librustc/ty/mod.rs | 10 ++++ src/librustc/ty/structural_impls.rs | 7 +-- src/librustc_error_codes/error_codes/E0747.md | 7 +-- src/librustc_hir/hir.rs | 8 +++ src/librustc_typeck/astconv.rs | 52 ++++++++----------- 5 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a195c944ff2..54c0a267fe7 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -931,6 +931,16 @@ pub enum GenericParamDefKind { Const, } +impl GenericParamDefKind { + pub fn descr(&self) -> &'static str { + match self { + GenericParamDefKind::Lifetime => "lifetime", + GenericParamDefKind::Type { .. } => "type", + GenericParamDefKind::Const => "constant", + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub struct GenericParamDef { pub name: Symbol, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 59dd41e9d56..388afc15c85 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -19,12 +19,7 @@ impl fmt::Debug for ty::GenericParamDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let type_name = match self.kind { - ty::GenericParamDefKind::Lifetime => "Lifetime", - ty::GenericParamDefKind::Type { .. } => "Type", - ty::GenericParamDefKind::Const => "Const", - }; - write!(f, "{}({}, {:?}, {})", type_name, self.name, self.def_id, self.index) + write!(f, "{}({}, {:?}, {})", self.kind.descr(), self.name, self.def_id, self.index) } } diff --git a/src/librustc_error_codes/error_codes/E0747.md b/src/librustc_error_codes/error_codes/E0747.md index 45b2dfd9e2b..9bdfb5ef0bc 100644 --- a/src/librustc_error_codes/error_codes/E0747.md +++ b/src/librustc_error_codes/error_codes/E0747.md @@ -1,10 +1,11 @@ -Generic arguments must be provided in the same order as the corresponding generic -parameters are declared. +Generic arguments must be provided in the same order as the corresponding +generic parameters are declared. Erroneous code example: ```compile_fail,E0747 struct S<'a, T>(&'a T); -type X = S<(), 'static>; // error: the type argument is provided before the lifetime argument +type X = S<(), 'static>; // error: the type argument is provided before the + // lifetime argument ``` diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 8496a6ed23b..4a6871e0232 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -298,6 +298,14 @@ pub fn is_const(&self) -> bool { _ => false, } } + + pub fn descr(&self) -> &'static str { + match self { + GenericArg::Lifetime(_) => "lifetime", + GenericArg::Type(_) => "type", + GenericArg::Const(_) => "constant", + } + } } #[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4ef732a7662..a590a942e42 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -12,7 +12,7 @@ use crate::require_c_abi_if_c_variadic; use crate::util::common::ErrorReported; use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; -use rustc::session::parse::feature_err; +use rustc::session::{parse::feature_err, Session}; use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef}; use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; @@ -446,6 +446,20 @@ fn check_generic_arg_count( (arg_count_mismatch, unexpected_spans) } + /// Report an error that a generic argument did not match the generic parameter that was + /// expected. + fn generic_arg_mismatch_err(sess: &Session, arg: &GenericArg<'_>, kind: &'static str) { + struct_span_err!( + sess, + arg.span(), + E0747, + "{} provided when a {} was expected", + arg.descr(), + kind, + ) + .emit(); + } + /// Creates the relevant generic argument substitutions /// corresponding to a set of generic parameters. This is a /// rather complex function. Let us try to explain the role @@ -541,12 +555,6 @@ pub fn create_substs_for_generic_args<'b>( let mut args = generic_args.iter().flat_map(|generic_args| generic_args.args.iter()).peekable(); - let arg_kind = |arg| match arg { - &GenericArg::Lifetime(_) => "lifetime", - &GenericArg::Type(_) => "type", - &GenericArg::Const(_) => "constant", - }; - // If we encounter a type or const when we expect a lifetime, we infer the lifetimes. // If we later encounter a lifetime, we know that the arguments were provided in the // wrong order. `force_infer_lt` records the type or const that forced lifetimes to be @@ -582,20 +590,7 @@ pub fn create_substs_for_generic_args<'b>( // the arguments don't match up with the parameters, we won't issue // an additional error, as the user already knows what's wrong. if !arg_count_mismatch { - let param_kind = match kind { - GenericParamDefKind::Lifetime => "lifetime", - GenericParamDefKind::Type { .. } => "type", - GenericParamDefKind::Const => "constant", - }; - struct_span_err!( - tcx.sess, - arg.span(), - E0747, - "{} provided when a {} was expected", - arg_kind(arg), - param_kind, - ) - .emit(); + Self::generic_arg_mismatch_err(tcx.sess, arg, kind.descr()); } // We've reported the error, but we want to make sure that this @@ -607,6 +602,7 @@ pub fn create_substs_for_generic_args<'b>( } } } + (Some(&arg), None) => { // We should never be able to reach this point with well-formed input. // There are two situations in which we can encounter this issue. @@ -620,29 +616,23 @@ pub fn create_substs_for_generic_args<'b>( // after a type or const). We want to throw an error in this case. if !arg_count_mismatch { - let kind = arg_kind(arg); + let kind = arg.descr(); assert_eq!(kind, "lifetime"); let provided = force_infer_lt.expect("lifetimes ought to have been inferred"); - struct_span_err!( - tcx.sess, - provided.span(), - E0747, - "{} provided when a {} was expected", - arg_kind(provided), - kind, - ) - .emit(); + Self::generic_arg_mismatch_err(tcx.sess, provided, kind); } break; } + (None, Some(¶m)) => { // If there are fewer arguments than parameters, it means // we're inferring the remaining arguments. substs.push(inferred_kind(Some(&substs), param, infer_args)); params.next(); } + (None, None) => break, } } -- 2.44.0