From 0a8d98a270da057975d3cc552a4bb5f0bda5a3af Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 5 Feb 2019 16:49:38 +0100 Subject: Parse const generics Co-Authored-By: Gabriel Smith --- src/libsyntax/parse/parser.rs | 276 +++++++++++++++--------------------------- src/libsyntax/parse/token.rs | 14 +++ 2 files changed, 112 insertions(+), 178 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cacdab980fa..2ff450af423 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -397,6 +397,7 @@ crate enum TokenType { Ident, Path, Type, + Const, } impl TokenType { @@ -409,6 +410,7 @@ impl TokenType { TokenType::Ident => "identifier".to_string(), TokenType::Path => "path".to_string(), TokenType::Type => "type".to_string(), + TokenType::Const => "const".to_string(), } } } @@ -946,6 +948,19 @@ impl<'a> Parser<'a> { } } + fn check_const_param(&mut self) -> bool { + self.check_keyword(keywords::Const) + } + + fn check_const_arg(&mut self) -> bool { + if self.token.can_begin_const_arg() { + true + } else { + self.expected_tokens.push(TokenType::Const); + false + } + } + /// Expect and consume a `+`. if `+=` is seen, replace it with a `=` /// and continue. If a `+` is not seen, return false. /// @@ -5482,15 +5497,28 @@ impl<'a> Parser<'a> { Ok((ident, TraitItemKind::Type(bounds, default), generics)) } + fn parse_const_param(&mut self, preceding_attrs: Vec) -> PResult<'a, GenericParam> { + self.expect_keyword(keywords::Const)?; + let ident = self.parse_ident()?; + self.expect(&token::Colon)?; + let ty = self.parse_ty()?; + + Ok(GenericParam { + ident, + id: ast::DUMMY_NODE_ID, + attrs: preceding_attrs.into(), + bounds: Vec::new(), + kind: GenericParamKind::Const { + ty, + } + }) + } + /// Parses (possibly empty) list of lifetime and type parameters, possibly including /// trailing comma and erroneous trailing attributes. crate fn parse_generic_params(&mut self) -> PResult<'a, Vec> { - let mut lifetimes = Vec::new(); let mut params = Vec::new(); - let mut seen_ty_param: Option = None; - let mut last_comma_span = None; - let mut bad_lifetime_pos = vec![]; - let mut suggestions = vec![]; + let mut prev_param: Option = None; loop { let attrs = self.parse_outer_attributes()?; if self.check_lifetime() { @@ -5501,39 +5529,36 @@ impl<'a> Parser<'a> { } else { Vec::new() }; - lifetimes.push(ast::GenericParam { + params.push(ast::GenericParam { ident: lifetime.ident, id: lifetime.id, attrs: attrs.into(), bounds, kind: ast::GenericParamKind::Lifetime, }); - if let Some(sp) = seen_ty_param { - let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); - bad_lifetime_pos.push(self.prev_span); - if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { - suggestions.push((remove_sp, String::new())); - suggestions.push(( - sp.shrink_to_lo(), - format!("{}, ", snippet))); - } - } + prev_param = Some(ParamKindOrd::Lifetime); + } else if self.check_const_param() { + // Parse const parameter. + params.push(self.parse_const_param(attrs)?); + prev_param = Some(ParamKindOrd::Const); } else if self.check_ident() { // Parse type parameter. params.push(self.parse_ty_param(attrs)?); - if seen_ty_param.is_none() { - seen_ty_param = Some(self.prev_span); - } + prev_param = Some(ParamKindOrd::Type); } else { // Check for trailing attributes and stop parsing. if !attrs.is_empty() { - let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" }; - self.struct_span_err( - attrs[0].span, - &format!("trailing attribute after {} parameters", param_kind), - ) - .span_label(attrs[0].span, "attributes must go before parameters") - .emit(); + if let Some(prev_param) = prev_param { + self.struct_span_err( + attrs[0].span, + &format!( + "trailing attribute after {} parameter", + prev_param, + ), + ) + .span_label(attrs[0].span, "attributes must go before parameters") + .emit(); + } } break } @@ -5541,24 +5566,8 @@ impl<'a> Parser<'a> { if !self.eat(&token::Comma) { break } - last_comma_span = Some(self.prev_span); - } - if !bad_lifetime_pos.is_empty() { - let mut err = self.struct_span_err( - bad_lifetime_pos, - "lifetime parameters must be declared prior to type parameters", - ); - if !suggestions.is_empty() { - err.multipart_suggestion( - "move the lifetime parameter prior to the first type parameter", - suggestions, - Applicability::MachineApplicable, - ); - } - err.emit(); } - lifetimes.extend(params); // ensure the correct order of lifetimes and type params - Ok(lifetimes) + Ok(params) } /// Parse a set of optional generic type parameter declarations. Where @@ -5740,35 +5749,16 @@ impl<'a> Parser<'a> { fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { let mut args = Vec::new(); let mut bindings = Vec::new(); + let mut misplaced_assoc_ty_bindings: Vec = Vec::new(); + let mut assoc_ty_bindings: Vec = Vec::new(); - let mut seen_type = false; - let mut seen_binding = false; + let args_lo = self.span; - let mut last_comma_span = None; - let mut first_type_or_binding_span: Option = None; - let mut first_binding_span: Option = None; - - let mut bad_lifetime_pos = vec![]; - let mut bad_type_pos = vec![]; - - let mut lifetime_suggestions = vec![]; - let mut type_suggestions = vec![]; loop { if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. args.push(GenericArg::Lifetime(self.expect_lifetime())); - - if seen_type || seen_binding { - let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); - bad_lifetime_pos.push(self.prev_span); - - if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { - lifetime_suggestions.push((remove_sp, String::new())); - lifetime_suggestions.push(( - first_type_or_binding_span.unwrap().shrink_to_lo(), - format!("{}, ", snippet))); - } - } + misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); } else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) { // Parse associated type binding. let lo = self.span; @@ -5782,131 +5772,59 @@ impl<'a> Parser<'a> { ty, span, }); - - seen_binding = true; - if first_type_or_binding_span.is_none() { - first_type_or_binding_span = Some(span); - } - if first_binding_span.is_none() { - first_binding_span = Some(span); - } + assoc_ty_bindings.push(span); + } else if self.check_const_arg() { + // Parse const argument. + let expr = if let token::OpenDelim(token::Brace) = self.token { + self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())? + } else if self.token.can_begin_literal_or_bool() { + let lit = self.parse_lit()?; + self.mk_expr(lit.span, ExprKind::Lit(lit), ThinVec::new()) + } else { + // FIXME(const_generics): to distinguish between idents for types and consts, + // we should introduce a GenericArg::Ident in the AST and distinguish when + // lowering to the HIR. For now, idents for const args are not permitted. + return Err( + self.fatal("identifiers may currently not be used for const generics") + ); + }; + let value = AnonConst { + id: ast::DUMMY_NODE_ID, + value: expr, + }; + args.push(GenericArg::Const(value)); + misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); } else if self.check_type() { // Parse type argument. - let ty_param = self.parse_ty()?; - if seen_binding { - let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); - bad_type_pos.push(self.prev_span); - - if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { - type_suggestions.push((remove_sp, String::new())); - type_suggestions.push(( - first_binding_span.unwrap().shrink_to_lo(), - format!("{}, ", snippet))); - } - } - - if first_type_or_binding_span.is_none() { - first_type_or_binding_span = Some(ty_param.span); - } - args.push(GenericArg::Type(ty_param)); - seen_type = true; + args.push(GenericArg::Type(self.parse_ty()?)); + misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); } else { break } if !self.eat(&token::Comma) { break - } else { - last_comma_span = Some(self.prev_span); - } - } - - self.maybe_report_incorrect_generic_argument_order( - bad_lifetime_pos, bad_type_pos, lifetime_suggestions, type_suggestions - ); - - Ok((args, bindings)) - } - - /// Maybe report an error about incorrect generic argument order - "lifetime parameters - /// must be declared before type parameters", "type parameters must be declared before - /// associated type bindings" or both. - fn maybe_report_incorrect_generic_argument_order( - &self, - bad_lifetime_pos: Vec, - bad_type_pos: Vec, - lifetime_suggestions: Vec<(Span, String)>, - type_suggestions: Vec<(Span, String)>, - ) { - let mut err = if !bad_lifetime_pos.is_empty() && !bad_type_pos.is_empty() { - let mut positions = bad_lifetime_pos.clone(); - positions.extend_from_slice(&bad_type_pos); - - self.struct_span_err( - positions, - "generic arguments must declare lifetimes, types and associated type bindings in \ - that order", - ) - } else if !bad_lifetime_pos.is_empty() { - self.struct_span_err( - bad_lifetime_pos.clone(), - "lifetime parameters must be declared prior to type parameters" - ) - } else if !bad_type_pos.is_empty() { - self.struct_span_err( - bad_type_pos.clone(), - "type parameters must be declared prior to associated type bindings" - ) - } else { - return; - }; - - if !bad_lifetime_pos.is_empty() { - for sp in &bad_lifetime_pos { - err.span_label(*sp, "must be declared prior to type parameters"); - } - } - - if !bad_type_pos.is_empty() { - for sp in &bad_type_pos { - err.span_label(*sp, "must be declared prior to associated type bindings"); } } - if !lifetime_suggestions.is_empty() && !type_suggestions.is_empty() { - let mut suggestions = lifetime_suggestions; - suggestions.extend_from_slice(&type_suggestions); - - let plural = bad_lifetime_pos.len() + bad_type_pos.len() > 1; - err.multipart_suggestion( - &format!( - "move the parameter{}", - if plural { "s" } else { "" }, - ), - suggestions, - Applicability::MachineApplicable, - ); - } else if !lifetime_suggestions.is_empty() { - err.multipart_suggestion( - &format!( - "move the lifetime parameter{} prior to the first type parameter", - if bad_lifetime_pos.len() > 1 { "s" } else { "" }, - ), - lifetime_suggestions, - Applicability::MachineApplicable, - ); - } else if !type_suggestions.is_empty() { - err.multipart_suggestion( - &format!( - "move the type parameter{} prior to the first associated type binding", - if bad_type_pos.len() > 1 { "s" } else { "" }, - ), - type_suggestions, - Applicability::MachineApplicable, + // FIXME: we would like to report this in ast_validation instead, but we currently do not + // preserve ordering of generic parameters with respect to associated type binding, so we + // lose that information after parsing. + if misplaced_assoc_ty_bindings.len() > 0 { + let mut err = self.struct_span_err( + args_lo.to(self.prev_span), + "associated type bindings must be declared after generic parameters", ); + for span in misplaced_assoc_ty_bindings { + err.span_label( + span, + "this associated type binding should be moved after the generic parameters", + ); + } + err.emit(); } - err.emit(); + Ok((args, bindings)) } /// Parses an optional `where` clause and places it in `generics`. @@ -6526,6 +6444,7 @@ impl<'a> Parser<'a> { // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds // `<` (LIFETIME|IDENT) `=` - generic parameter with a default + // `<` const IDENT - generic const parameter // The only truly ambiguous case is // `<` IDENT `>` `::` IDENT ... // we disambiguate it in favor of generics (`impl ::absolute::Path { ... }`) @@ -6535,7 +6454,8 @@ impl<'a> Parser<'a> { (self.look_ahead(1, |t| t == &token::Pound || t == &token::Gt) || self.look_ahead(1, |t| t.is_lifetime() || t.is_ident()) && self.look_ahead(2, |t| t == &token::Gt || t == &token::Comma || - t == &token::Colon || t == &token::Eq)) + t == &token::Colon || t == &token::Eq) || + self.look_ahead(1, |t| t.is_keyword(keywords::Const))) } fn parse_impl_body(&mut self) -> PResult<'a, (Vec, Vec)> { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 3b1fa5ea01f..dad32072739 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -279,6 +279,20 @@ impl Token { } } + /// Returns `true` if the token can appear at the start of a const param. + pub fn can_begin_const_arg(&self) -> bool { + match self { + OpenDelim(Brace) => true, + Interpolated(ref nt) => match nt.0 { + NtExpr(..) => true, + NtBlock(..) => true, + NtLiteral(..) => true, + _ => false, + } + _ => self.can_begin_literal_or_bool(), + } + } + /// Returns `true` if the token can appear at the start of a generic bound. crate fn can_begin_bound(&self) -> bool { self.is_path_start() || self.is_lifetime() || self.is_keyword(keywords::For) || -- cgit 1.4.1-3-g733a5 From bbdcc4e7ce697bbd6ad398987c5e4ec4928f5da4 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 7 Feb 2019 10:10:11 +0100 Subject: Adjust parser generic parameter errors --- src/libsyntax/parse/parser.rs | 53 +++++++++++----------- src/libsyntax/parse/token.rs | 1 - .../attrs-with-no-formal-in-generics-1.rs | 2 +- .../attrs-with-no-formal-in-generics-1.stderr | 2 +- .../attrs-with-no-formal-in-generics-2.rs | 2 +- .../attrs-with-no-formal-in-generics-2.stderr | 2 +- .../attrs-with-no-formal-in-generics-3.rs | 2 +- .../attrs-with-no-formal-in-generics-3.stderr | 2 +- .../const-generics/const-expression-parameter.rs | 19 ++++++++ .../const-expression-parameter.stderr | 26 +++++++++++ src/test/ui/issues/issue-20616-3.rs | 5 +- src/test/ui/issues/issue-20616-3.stderr | 4 +- src/test/ui/issues/issue-20616-7.rs | 5 +- src/test/ui/issues/issue-20616-7.stderr | 4 +- src/test/ui/issues/issue-20616-8.rs | 5 +- src/test/ui/issues/issue-20616-8.stderr | 4 +- src/test/ui/issues/issue-20616-9.rs | 5 +- src/test/ui/issues/issue-20616-9.stderr | 4 +- 18 files changed, 93 insertions(+), 54 deletions(-) create mode 100644 src/test/ui/const-generics/const-expression-parameter.rs create mode 100644 src/test/ui/const-generics/const-expression-parameter.stderr (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2ff450af423..7640f0bdf06 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -948,10 +948,6 @@ impl<'a> Parser<'a> { } } - fn check_const_param(&mut self) -> bool { - self.check_keyword(keywords::Const) - } - fn check_const_arg(&mut self) -> bool { if self.token.can_begin_const_arg() { true @@ -1046,7 +1042,8 @@ impl<'a> Parser<'a> { } /// Attempt to consume a `<`. If `<<` is seen, replace it with a single - /// `<` and continue. If a `<` is not seen, return false. + /// `<` and continue. If `<-` is seen, replace it with a single `<` + /// and continue. If a `<` is not seen, return false. /// /// This is meant to be used when parsing generics on a path to get the /// starting token. @@ -1062,6 +1059,11 @@ impl<'a> Parser<'a> { self.bump_with(token::Lt, span); true } + token::LArrow => { + let span = self.span.with_lo(self.span.lo() + BytePos(1)); + self.bump_with(token::BinOp(token::Minus), span); + true + } _ => false, }; @@ -5518,7 +5520,6 @@ impl<'a> Parser<'a> { /// trailing comma and erroneous trailing attributes. crate fn parse_generic_params(&mut self) -> PResult<'a, Vec> { let mut params = Vec::new(); - let mut prev_param: Option = None; loop { let attrs = self.parse_outer_attributes()?; if self.check_lifetime() { @@ -5536,29 +5537,21 @@ impl<'a> Parser<'a> { bounds, kind: ast::GenericParamKind::Lifetime, }); - prev_param = Some(ParamKindOrd::Lifetime); - } else if self.check_const_param() { + } else if self.check_keyword(keywords::Const) { // Parse const parameter. params.push(self.parse_const_param(attrs)?); - prev_param = Some(ParamKindOrd::Const); } else if self.check_ident() { // Parse type parameter. params.push(self.parse_ty_param(attrs)?); - prev_param = Some(ParamKindOrd::Type); } else { // Check for trailing attributes and stop parsing. - if !attrs.is_empty() { - if let Some(prev_param) = prev_param { - self.struct_span_err( - attrs[0].span, - &format!( - "trailing attribute after {} parameter", - prev_param, - ), - ) - .span_label(attrs[0].span, "attributes must go before parameters") - .emit(); - } + if !attrs.is_empty() && !params.is_empty() { + self.struct_span_err( + attrs[0].span, + &format!("trailing attribute after generic parameter"), + ) + .span_label(attrs[0].span, "attributes must go before parameters") + .emit(); } break } @@ -5774,19 +5767,25 @@ impl<'a> Parser<'a> { }); assoc_ty_bindings.push(span); } else if self.check_const_arg() { + // FIXME(const_generics): to distinguish between idents for types and consts, + // we should introduce a GenericArg::Ident in the AST and distinguish when + // lowering to the HIR. For now, idents for const args are not permitted. + // Parse const argument. let expr = if let token::OpenDelim(token::Brace) = self.token { self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())? - } else if self.token.can_begin_literal_or_bool() { - let lit = self.parse_lit()?; - self.mk_expr(lit.span, ExprKind::Lit(lit), ThinVec::new()) - } else { + } else if self.token.is_ident() { // FIXME(const_generics): to distinguish between idents for types and consts, // we should introduce a GenericArg::Ident in the AST and distinguish when // lowering to the HIR. For now, idents for const args are not permitted. return Err( self.fatal("identifiers may currently not be used for const generics") ); + } else { + // FIXME(const_generics): this currently conflicts with emplacement syntax + // with negative integer literals. + let lit = self.parse_lit()?; + self.mk_expr(lit.span, ExprKind::Lit(lit), ThinVec::new()) }; let value = AnonConst { id: ast::DUMMY_NODE_ID, @@ -6444,7 +6443,7 @@ impl<'a> Parser<'a> { // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds // `<` (LIFETIME|IDENT) `=` - generic parameter with a default - // `<` const IDENT - generic const parameter + // `<` const - generic const parameter // The only truly ambiguous case is // `<` IDENT `>` `::` IDENT ... // we disambiguate it in favor of generics (`impl ::absolute::Path { ... }`) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index dad32072739..c3885f0d04d 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -284,7 +284,6 @@ impl Token { match self { OpenDelim(Brace) => true, Interpolated(ref nt) => match nt.0 { - NtExpr(..) => true, NtBlock(..) => true, NtLiteral(..) => true, _ => false, diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.rs b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.rs index 2ef5f13f3d4..ca5fdd9da85 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.rs +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.rs @@ -7,7 +7,7 @@ struct RefIntPair<'a, 'b>(&'a u32, &'b u32); impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { - //~^ ERROR trailing attribute after lifetime parameter + //~^ ERROR trailing attribute after generic parameter } fn main() { diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr index 97c0a19a3da..55e7a987784 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr @@ -1,4 +1,4 @@ -error: trailing attribute after lifetime parameter +error: trailing attribute after generic parameter --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25 | LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.rs b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.rs index f58ddd5fbda..c795612acf0 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.rs +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.rs @@ -7,6 +7,6 @@ struct RefAny<'a, T>(&'a T); impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} -//~^ ERROR trailing attribute after type parameter +//~^ ERROR trailing attribute after generic parameter fn main() {} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr index ff7ced77f25..acd0ae3678a 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr @@ -1,4 +1,4 @@ -error: trailing attribute after type parameter +error: trailing attribute after generic parameter --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35 | LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs index 44a7c9d7c8b..3cfc70b4185 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs @@ -6,7 +6,7 @@ struct RefIntPair<'a, 'b>(&'a u32, &'b u32); fn hof_lt(_: Q) where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 - //~^ ERROR trailing attribute after lifetime parameter + //~^ ERROR trailing attribute after generic parameter {} fn main() {} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr index b383e21e161..b9ca0097467 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr @@ -1,4 +1,4 @@ -error: trailing attribute after lifetime parameter +error: trailing attribute after generic parameter --> $DIR/attrs-with-no-formal-in-generics-3.rs:8:44 | LL | where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 diff --git a/src/test/ui/const-generics/const-expression-parameter.rs b/src/test/ui/const-generics/const-expression-parameter.rs new file mode 100644 index 00000000000..c582c596bfc --- /dev/null +++ b/src/test/ui/const-generics/const-expression-parameter.rs @@ -0,0 +1,19 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn u32_identity() -> u32 { + //~^ ERROR const generics in any position are currently unsupported + 5 +} + +fn foo_a() { + u32_identity::<-1>(); //~ ERROR expected identifier, found `<-` +} + +fn foo_b() { + u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+` +} + +fn main() { + u32_identity::<5>(); // ok +} diff --git a/src/test/ui/const-generics/const-expression-parameter.stderr b/src/test/ui/const-generics/const-expression-parameter.stderr new file mode 100644 index 00000000000..1dd3a960316 --- /dev/null +++ b/src/test/ui/const-generics/const-expression-parameter.stderr @@ -0,0 +1,26 @@ +error: expected identifier, found `<-` + --> $DIR/const-expression-parameter.rs:10:19 + | +LL | u32_identity::<-1>(); //~ ERROR expected identifier, found `<-` + | ^^ expected identifier + +error: expected one of `,` or `>`, found `+` + --> $DIR/const-expression-parameter.rs:14:22 + | +LL | u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+` + | ^ expected one of `,` or `>` here + +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-expression-parameter.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error: const generics in any position are currently unsupported + --> $DIR/const-expression-parameter.rs:4:23 + | +LL | fn u32_identity() -> u32 { + | ^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/issues/issue-20616-3.rs b/src/test/ui/issues/issue-20616-3.rs index 9f983f74f5b..9bfd5bf2313 100644 --- a/src/test/ui/issues/issue-20616-3.rs +++ b/src/test/ui/issues/issue-20616-3.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time @@ -12,7 +10,8 @@ type Type_1_<'a, T> = &'a T; //type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` -type Type_3 = Box; //~ error: expected one of `>`, const, identifier, lifetime, or type, found `,` +type Type_3 = Box; +//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,` //type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` diff --git a/src/test/ui/issues/issue-20616-3.stderr b/src/test/ui/issues/issue-20616-3.stderr index e8edb5ba70f..f51fb949c74 100644 --- a/src/test/ui/issues/issue-20616-3.stderr +++ b/src/test/ui/issues/issue-20616-3.stderr @@ -1,7 +1,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,` - --> $DIR/issue-20616-3.rs:15:24 + --> $DIR/issue-20616-3.rs:13:24 | -LL | type Type_3 = Box; //~ error: expected one of `>`, const, identifier, lifetime, or type, found `,` +LL | type Type_3 = Box; | ^ expected one of `>`, const, identifier, lifetime, or type here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-7.rs b/src/test/ui/issues/issue-20616-7.rs index 277b4524506..ffd1620c1d3 100644 --- a/src/test/ui/issues/issue-20616-7.rs +++ b/src/test/ui/issues/issue-20616-7.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time @@ -27,7 +25,8 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` -type Type_7 = Box<(),,>; //~ error: expected one of `>`, const, identifier, lifetime, or type, found `,` +type Type_7 = Box<(),,>; +//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,` //type Type_8<'a,,> = &'a (); // error: expected ident, found `,` diff --git a/src/test/ui/issues/issue-20616-7.stderr b/src/test/ui/issues/issue-20616-7.stderr index c1422d849fc..c0e108375be 100644 --- a/src/test/ui/issues/issue-20616-7.stderr +++ b/src/test/ui/issues/issue-20616-7.stderr @@ -1,7 +1,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,` - --> $DIR/issue-20616-7.rs:30:22 + --> $DIR/issue-20616-7.rs:28:22 | -LL | type Type_7 = Box<(),,>; //~ error: expected one of `>`, const, identifier, lifetime, or type, found `,` +LL | type Type_7 = Box<(),,>; | ^ expected one of `>`, const, identifier, lifetime, or type here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-8.rs b/src/test/ui/issues/issue-20616-8.rs index 756119e0127..c9e8b61e50b 100644 --- a/src/test/ui/issues/issue-20616-8.rs +++ b/src/test/ui/issues/issue-20616-8.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time @@ -30,7 +28,8 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_7 = Box<(),,>; // error: expected type, found `,` -type Type_8<'a,,> = &'a (); //~ error: expected one of `>`, `const`, identifier, or lifetime, found `,` +type Type_8<'a,,> = &'a (); +//~^ error: expected one of `>`, `const`, identifier, or lifetime, found `,` //type Type_9 = Box; // error: expected identifier, found `,` diff --git a/src/test/ui/issues/issue-20616-8.stderr b/src/test/ui/issues/issue-20616-8.stderr index cfe3ec57712..0ef9192f1e7 100644 --- a/src/test/ui/issues/issue-20616-8.stderr +++ b/src/test/ui/issues/issue-20616-8.stderr @@ -1,7 +1,7 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,` - --> $DIR/issue-20616-8.rs:33:16 + --> $DIR/issue-20616-8.rs:31:16 | -LL | type Type_8<'a,,> = &'a (); //~ error: expected one of `>`, `const`, identifier, or lifetime, found `,` +LL | type Type_8<'a,,> = &'a (); | ^ expected one of `>`, `const`, identifier, or lifetime here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-9.rs b/src/test/ui/issues/issue-20616-9.rs index 6074fbb2204..1c509f26fd6 100644 --- a/src/test/ui/issues/issue-20616-9.rs +++ b/src/test/ui/issues/issue-20616-9.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time @@ -33,4 +31,5 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_8<'a,,> = &'a (); // error: expected identifier, found `,` -type Type_9 = Box; //~ error: expected one of `>`, `const`, identifier, or lifetime, found `,` +type Type_9 = Box; +//~^ error: expected one of `>`, `const`, identifier, or lifetime, found `,` diff --git a/src/test/ui/issues/issue-20616-9.stderr b/src/test/ui/issues/issue-20616-9.stderr index 960e8c8c086..5fd1400a2e8 100644 --- a/src/test/ui/issues/issue-20616-9.stderr +++ b/src/test/ui/issues/issue-20616-9.stderr @@ -1,7 +1,7 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,` - --> $DIR/issue-20616-9.rs:36:15 + --> $DIR/issue-20616-9.rs:34:15 | -LL | type Type_9 = Box; //~ error: expected one of `>`, `const`, identifier, or lifetime, found `,` +LL | type Type_9 = Box; | ^ expected one of `>`, `const`, identifier, or lifetime here error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 9ad04b9960ed125d450fbf49f3c4c21702ab36ae Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 7 Feb 2019 14:58:31 +0100 Subject: Add warning for a parameter list with an attribute but no parameters --- src/libsyntax/parse/parser.rs | 26 ++++++++++++++++------ ...attribute-with-no-generics-in-parameter-list.rs | 4 +--- ...ibute-with-no-generics-in-parameter-list.stderr | 8 +++++++ 3 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/attribute-with-no-generics-in-parameter-list.stderr (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7640f0bdf06..d9195ebe312 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5545,13 +5545,25 @@ impl<'a> Parser<'a> { params.push(self.parse_ty_param(attrs)?); } else { // Check for trailing attributes and stop parsing. - if !attrs.is_empty() && !params.is_empty() { - self.struct_span_err( - attrs[0].span, - &format!("trailing attribute after generic parameter"), - ) - .span_label(attrs[0].span, "attributes must go before parameters") - .emit(); + if !attrs.is_empty() { + if !params.is_empty() { + self.struct_span_err( + attrs[0].span, + &format!("trailing attribute after generic parameter"), + ) + .span_label(attrs[0].span, "attributes must go before parameters") + .emit(); + } else { + self.struct_span_err( + attrs[0].span, + &format!("attribute without generic parameters"), + ) + .span_label( + attrs[0].span, + "attributes are only permitted when preceding parameters", + ) + .emit(); + } } break } diff --git a/src/test/ui/attribute-with-no-generics-in-parameter-list.rs b/src/test/ui/attribute-with-no-generics-in-parameter-list.rs index 3342f749dee..c2cc91d8f77 100644 --- a/src/test/ui/attribute-with-no-generics-in-parameter-list.rs +++ b/src/test/ui/attribute-with-no-generics-in-parameter-list.rs @@ -1,5 +1,3 @@ -// run-pass - -fn foo<#[attr]>() {} // ok +fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters fn main() {} diff --git a/src/test/ui/attribute-with-no-generics-in-parameter-list.stderr b/src/test/ui/attribute-with-no-generics-in-parameter-list.stderr new file mode 100644 index 00000000000..f08f107a62f --- /dev/null +++ b/src/test/ui/attribute-with-no-generics-in-parameter-list.stderr @@ -0,0 +1,8 @@ +error: attribute without generic parameters + --> $DIR/attribute-with-no-generics-in-parameter-list.rs:1:8 + | +LL | fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters + | ^^^^^^^ attributes are only permitted when preceding parameters + +error: aborting due to previous error + -- cgit 1.4.1-3-g733a5 From 451f1287839451fc097a406fad1a9160c22c280a Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 7 Feb 2019 14:58:47 +0100 Subject: Parse negative literals in const generic arguments --- src/libsyntax/parse/parser.rs | 3 +-- src/test/ui/const-generics/const-expression-parameter.rs | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d9195ebe312..d71145893c3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5796,8 +5796,7 @@ impl<'a> Parser<'a> { } else { // FIXME(const_generics): this currently conflicts with emplacement syntax // with negative integer literals. - let lit = self.parse_lit()?; - self.mk_expr(lit.span, ExprKind::Lit(lit), ThinVec::new()) + self.parse_literal_maybe_minus()? }; let value = AnonConst { id: ast::DUMMY_NODE_ID, diff --git a/src/test/ui/const-generics/const-expression-parameter.rs b/src/test/ui/const-generics/const-expression-parameter.rs index c582c596bfc..f4e9008dbd0 100644 --- a/src/test/ui/const-generics/const-expression-parameter.rs +++ b/src/test/ui/const-generics/const-expression-parameter.rs @@ -14,6 +14,10 @@ fn foo_b() { u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+` } +fn foo_c() { + u32_identity::< -1 >(); // ok +} + fn main() { u32_identity::<5>(); // ok } -- cgit 1.4.1-3-g733a5 From 4e0e1889990bdf1d6f10c9071144c44eebc80e97 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 7 Feb 2019 14:59:59 +0100 Subject: Make name resolution handle consts in GenericParamsFromOuterFunction properly --- src/librustc_resolve/lib.rs | 49 ++++++++++++++++------ src/librustc_typeck/diagnostics.rs | 5 ++- src/libsyntax/parse/token.rs | 3 +- src/test/ui/bad/bad-type-env-capture.rs | 2 +- src/test/ui/bad/bad-type-env-capture.stderr | 8 ++-- src/test/ui/error-codes/E0401.stderr | 16 +++---- src/test/ui/inner-static-type-parameter.rs | 2 +- src/test/ui/inner-static-type-parameter.stderr | 6 +-- src/test/ui/issues/issue-12796.rs | 2 +- src/test/ui/issues/issue-12796.stderr | 4 +- src/test/ui/issues/issue-3021-c.rs | 4 +- src/test/ui/issues/issue-3021-c.stderr | 16 +++---- src/test/ui/issues/issue-3214.rs | 2 +- src/test/ui/issues/issue-3214.stderr | 8 ++-- src/test/ui/issues/issue-5997-enum.rs | 2 +- src/test/ui/issues/issue-5997-enum.stderr | 6 +-- src/test/ui/issues/issue-5997-struct.rs | 2 +- src/test/ui/issues/issue-5997-struct.stderr | 8 ++-- src/test/ui/nested-ty-params.rs | 2 +- src/test/ui/nested-ty-params.stderr | 12 +++--- .../resolve/resolve-type-param-in-item-in-trait.rs | 8 ++-- .../resolve-type-param-in-item-in-trait.stderr | 24 +++++------ src/test/ui/type/type-arg-out-of-scope.rs | 2 +- src/test/ui/type/type-arg-out-of-scope.stderr | 12 +++--- src/test/ui/use-self-in-inner-fn.rs | 4 +- src/test/ui/use-self-in-inner-fn.stderr | 4 +- 26 files changed, 120 insertions(+), 93 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ebd6b0eb5da..365ba974d5a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -142,8 +142,8 @@ impl Ord for BindingError { } enum ResolutionError<'a> { - /// error E0401: can't use type parameters from outer function - TypeParametersFromOuterFunction(Def), + /// error E0401: can't use type or const parameters from outer function + GenericParamsFromOuterFunction(Def), /// error E0403: the name is already used for a type/const parameter in this list of /// generic parameters NameAlreadyUsedInParameterList(Name, &'a Span), @@ -196,13 +196,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>, resolution_error: ResolutionError<'a>) -> DiagnosticBuilder<'sess> { match resolution_error { - ResolutionError::TypeParametersFromOuterFunction(outer_def) => { + ResolutionError::GenericParamsFromOuterFunction(outer_def) => { let mut err = struct_span_err!(resolver.session, span, E0401, - "can't use type parameters from outer function", + "can't use generic parameters from outer function", ); - err.span_label(span, format!("use of type variable from outer function")); + err.span_label(span, format!("use of generic parameter from outer function")); let cm = resolver.session.source_map(); match outer_def { @@ -231,15 +231,20 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>, err.span_label(span, "type variable from outer function"); } } + Def::ConstParam(def_id) => { + if let Some(span) = resolver.definitions.opt_span(def_id) { + err.span_label(span, "const variable from outer function"); + } + } _ => { - bug!("TypeParametersFromOuterFunction should only be used with Def::SelfTy, \ + bug!("GenericParamsFromOuterFunction should only be used with Def::SelfTy, \ Def::TyParam"); } } // Try to retrieve the span of the function signature and generate a new message with // a local type or const parameter. - let sugg_msg = &format!("try using a local type parameter instead"); + let sugg_msg = &format!("try using a local generic parameter instead"); if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) { // Suggest the modification to the user err.span_suggestion( @@ -250,9 +255,9 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>, ); } else if let Some(sp) = cm.generate_fn_name_span(span) { err.span_label(sp, - format!("try adding a local type parameter in this method instead")); + format!("try adding a local generic parameter in this method instead")); } else { - err.help(&format!("try using a local type parameter instead")); + err.help(&format!("try using a local generic parameter instead")); } err @@ -549,8 +554,7 @@ impl<'a> PathSource<'a> { Def::Struct(..) | Def::Union(..) | Def::Enum(..) | Def::Trait(..) | Def::TraitAlias(..) | Def::TyAlias(..) | Def::AssociatedTy(..) | Def::PrimTy(..) | Def::TyParam(..) | - Def::SelfTy(..) | Def::Existential(..) | Def::ConstParam(..) | - Def::ForeignTy(..) => true, + Def::SelfTy(..) | Def::Existential(..) | Def::ForeignTy(..) => true, _ => false, }, PathSource::Trait(AliasPossibility::No) => match def { @@ -803,6 +807,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { _: Span, node_id: NodeId) { + debug!("(resolving function) entering function"); let (rib_kind, asyncness) = match function_kind { FnKind::ItemFn(_, ref header, ..) => (ItemRibKind, header.asyncness), @@ -2053,6 +2058,7 @@ impl<'a> Resolver<'a> { let record_used = record_used_id.is_some(); let mut module = self.graph_root; for i in (0 .. self.ribs[ns].len()).rev() { + debug!("walk rib\n{:?}", self.ribs[ns][i].bindings); if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() { // The ident resolves to a type parameter or local variable. return Some(LexicalScopeBinding::Def( @@ -4223,7 +4229,7 @@ impl<'a> Resolver<'a> { resolve_error( self, span, - ResolutionError::TypeParametersFromOuterFunction(def), + ResolutionError::GenericParamsFromOuterFunction(def), ); } return Def::Err; @@ -4231,6 +4237,25 @@ impl<'a> Resolver<'a> { } } } + Def::ConstParam(..) => { + // A const param is always declared in a signature, which is always followed by + // some kind of function rib kind (specifically, ItemRibKind in the case of a + // normal function), so we can skip the first rib as it will be guaranteed to + // (spuriously) conflict with the const param. + for rib in &ribs[1..] { + if let ItemRibKind = rib.kind { + // This was an attempt to use a const parameter outside its scope. + if record_used { + resolve_error( + self, + span, + ResolutionError::GenericParamsFromOuterFunction(def), + ); + } + return Def::Err; + } + } + } _ => {} } def diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 3ed09dfe992..e6533ac4b75 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -348,13 +348,14 @@ fn main() { "##, E0044: r##" -You can't use type parameters on foreign items. Example of erroneous code: +You can't use type or const parameters on foreign items. +Example of erroneous code: ```compile_fail,E0044 extern { fn some_func(x: T); } ``` -To fix this, replace the type parameter with the specializations that you +To fix this, replace the generic parameter with the specializations that you need: ``` diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index c3885f0d04d..d5856c67156 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -284,6 +284,7 @@ impl Token { match self { OpenDelim(Brace) => true, Interpolated(ref nt) => match nt.0 { + NtExpr(..) => true, NtBlock(..) => true, NtLiteral(..) => true, _ => false, @@ -306,7 +307,7 @@ impl Token { } } - /// Returns `true` if the token is any literal, a minus (which can follow a literal, + /// Returns `true` if the token is any literal, a minus (which can prefix a literal, /// for example a '-42', or one of the boolean idents). crate fn can_begin_literal_or_bool(&self) -> bool { match *self { diff --git a/src/test/ui/bad/bad-type-env-capture.rs b/src/test/ui/bad/bad-type-env-capture.rs index d2e6dff1252..53dfb13139a 100644 --- a/src/test/ui/bad/bad-type-env-capture.rs +++ b/src/test/ui/bad/bad-type-env-capture.rs @@ -1,4 +1,4 @@ fn foo() { - fn bar(b: T) { } //~ ERROR can't use type parameters from outer + fn bar(b: T) { } //~ ERROR can't use generic parameters from outer } fn main() { } diff --git a/src/test/ui/bad/bad-type-env-capture.stderr b/src/test/ui/bad/bad-type-env-capture.stderr index 5558a440061..ce803e96801 100644 --- a/src/test/ui/bad/bad-type-env-capture.stderr +++ b/src/test/ui/bad/bad-type-env-capture.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/bad-type-env-capture.rs:2:15 | LL | fn foo() { | - type variable from outer function -LL | fn bar(b: T) { } //~ ERROR can't use type parameters from outer - | --- ^ use of type variable from outer function +LL | fn bar(b: T) { } //~ ERROR can't use generic parameters from outer + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bar` + | help: try using a local generic parameter instead: `bar` error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index c94fa497678..27f281ee437 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -1,26 +1,26 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/E0401.rs:4:39 | LL | fn foo(x: T) { | - type variable from outer function LL | fn bfnr, W: Fn()>(y: T) { //~ ERROR E0401 - | --------------------------- ^ use of type variable from outer function + | --------------------------- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bfnr, W: Fn(), T>` + | help: try using a local generic parameter instead: `bfnr, W: Fn(), T>` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/E0401.rs:9:16 | LL | fn foo(x: T) { | - type variable from outer function ... LL | fn baz $DIR/E0401.rs:22:25 | LL | impl Iterator for A { @@ -29,7 +29,7 @@ LL | impl Iterator for A { LL | fn helper(sel: &Self) -> u8 { //~ ERROR E0401 | ^^^^ | | - | use of type variable from outer function + | use of generic parameter from outer function | use a type here instead error: aborting due to 3 previous errors diff --git a/src/test/ui/inner-static-type-parameter.rs b/src/test/ui/inner-static-type-parameter.rs index 60b4c5b8131..c08ccd29d80 100644 --- a/src/test/ui/inner-static-type-parameter.rs +++ b/src/test/ui/inner-static-type-parameter.rs @@ -4,7 +4,7 @@ enum Bar { What } //~ ERROR parameter `T` is never used fn foo() { static a: Bar = Bar::What; -//~^ ERROR can't use type parameters from outer function +//~^ ERROR can't use generic parameters from outer function } fn main() { diff --git a/src/test/ui/inner-static-type-parameter.stderr b/src/test/ui/inner-static-type-parameter.stderr index 2f2856edb0c..87fb364954d 100644 --- a/src/test/ui/inner-static-type-parameter.stderr +++ b/src/test/ui/inner-static-type-parameter.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/inner-static-type-parameter.rs:6:19 | LL | fn foo() { | --- - type variable from outer function | | - | try adding a local type parameter in this method instead + | try adding a local generic parameter in this method instead LL | static a: Bar = Bar::What; - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function error[E0392]: parameter `T` is never used --> $DIR/inner-static-type-parameter.rs:3:10 diff --git a/src/test/ui/issues/issue-12796.rs b/src/test/ui/issues/issue-12796.rs index acd4584c737..942d6b9a568 100644 --- a/src/test/ui/issues/issue-12796.rs +++ b/src/test/ui/issues/issue-12796.rs @@ -1,7 +1,7 @@ trait Trait { fn outer(&self) { fn inner(_: &Self) { - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } } diff --git a/src/test/ui/issues/issue-12796.stderr b/src/test/ui/issues/issue-12796.stderr index 4bc29fd37dc..a01fd2d6542 100644 --- a/src/test/ui/issues/issue-12796.stderr +++ b/src/test/ui/issues/issue-12796.stderr @@ -1,10 +1,10 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-12796.rs:3:22 | LL | fn inner(_: &Self) { | ^^^^ | | - | use of type variable from outer function + | use of generic parameter from outer function | can't use `Self` here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3021-c.rs b/src/test/ui/issues/issue-3021-c.rs index 491336206ca..94ed1fdf781 100644 --- a/src/test/ui/issues/issue-3021-c.rs +++ b/src/test/ui/issues/issue-3021-c.rs @@ -1,8 +1,8 @@ fn siphash() { trait U { - fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function - //~^ ERROR can't use type parameters from outer function + fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } diff --git a/src/test/ui/issues/issue-3021-c.stderr b/src/test/ui/issues/issue-3021-c.stderr index 323ce4fa306..5eadf7837c7 100644 --- a/src/test/ui/issues/issue-3021-c.stderr +++ b/src/test/ui/issues/issue-3021-c.stderr @@ -1,24 +1,24 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-3021-c.rs:4:24 | LL | fn siphash() { | - type variable from outer function ... -LL | fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function - | - ^ use of type variable from outer function +LL | fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function + | - ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `g` + | help: try using a local generic parameter instead: `g` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-3021-c.rs:4:30 | LL | fn siphash() { | - type variable from outer function ... -LL | fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function - | - ^ use of type variable from outer function +LL | fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function + | - ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `g` + | help: try using a local generic parameter instead: `g` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-3214.rs b/src/test/ui/issues/issue-3214.rs index 85eae2686e6..9a727aa3057 100644 --- a/src/test/ui/issues/issue-3214.rs +++ b/src/test/ui/issues/issue-3214.rs @@ -1,6 +1,6 @@ fn foo() { struct Foo { - x: T, //~ ERROR can't use type parameters from outer function + x: T, //~ ERROR can't use generic parameters from outer function } impl Drop for Foo { diff --git a/src/test/ui/issues/issue-3214.stderr b/src/test/ui/issues/issue-3214.stderr index 4ecea4f9800..e6526bad3e0 100644 --- a/src/test/ui/issues/issue-3214.stderr +++ b/src/test/ui/issues/issue-3214.stderr @@ -1,13 +1,13 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-3214.rs:3:12 | LL | fn foo() { | --- - type variable from outer function | | - | try adding a local type parameter in this method instead + | try adding a local generic parameter in this method instead LL | struct Foo { -LL | x: T, //~ ERROR can't use type parameters from outer function - | ^ use of type variable from outer function +LL | x: T, //~ ERROR can't use generic parameters from outer function + | ^ use of generic parameter from outer function error[E0107]: wrong number of type arguments: expected 0, found 1 --> $DIR/issue-3214.rs:6:26 diff --git a/src/test/ui/issues/issue-5997-enum.rs b/src/test/ui/issues/issue-5997-enum.rs index 0987117ecd4..3ff4e036c60 100644 --- a/src/test/ui/issues/issue-5997-enum.rs +++ b/src/test/ui/issues/issue-5997-enum.rs @@ -1,6 +1,6 @@ fn f() -> bool { enum E { V(Z) } - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function true } diff --git a/src/test/ui/issues/issue-5997-enum.stderr b/src/test/ui/issues/issue-5997-enum.stderr index 5c26dc92c85..5c778143e13 100644 --- a/src/test/ui/issues/issue-5997-enum.stderr +++ b/src/test/ui/issues/issue-5997-enum.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-5997-enum.rs:2:16 | LL | fn f() -> bool { | - - type variable from outer function | | - | try adding a local type parameter in this method instead + | try adding a local generic parameter in this method instead LL | enum E { V(Z) } - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function error: aborting due to previous error diff --git a/src/test/ui/issues/issue-5997-struct.rs b/src/test/ui/issues/issue-5997-struct.rs index 04ac489a55c..6cf510b0a9d 100644 --- a/src/test/ui/issues/issue-5997-struct.rs +++ b/src/test/ui/issues/issue-5997-struct.rs @@ -1,5 +1,5 @@ fn f() -> bool { - struct S(T); //~ ERROR can't use type parameters from outer function + struct S(T); //~ ERROR can't use generic parameters from outer function true } diff --git a/src/test/ui/issues/issue-5997-struct.stderr b/src/test/ui/issues/issue-5997-struct.stderr index 1d05d13242e..a60987b3f98 100644 --- a/src/test/ui/issues/issue-5997-struct.stderr +++ b/src/test/ui/issues/issue-5997-struct.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-5997-struct.rs:2:14 | LL | fn f() -> bool { | - - type variable from outer function | | - | try adding a local type parameter in this method instead -LL | struct S(T); //~ ERROR can't use type parameters from outer function - | ^ use of type variable from outer function + | try adding a local generic parameter in this method instead +LL | struct S(T); //~ ERROR can't use generic parameters from outer function + | ^ use of generic parameter from outer function error: aborting due to previous error diff --git a/src/test/ui/nested-ty-params.rs b/src/test/ui/nested-ty-params.rs index 102f8d02ee4..85413acdb14 100644 --- a/src/test/ui/nested-ty-params.rs +++ b/src/test/ui/nested-ty-params.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use type parameters from outer function +// error-pattern:can't use generic parameters from outer function fn hd(v: Vec ) -> U { fn hd1(w: [U]) -> U { return w[0]; } diff --git a/src/test/ui/nested-ty-params.stderr b/src/test/ui/nested-ty-params.stderr index 617eddf6525..37adeffb9b0 100644 --- a/src/test/ui/nested-ty-params.stderr +++ b/src/test/ui/nested-ty-params.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/nested-ty-params.rs:3:16 | LL | fn hd(v: Vec ) -> U { | - type variable from outer function LL | fn hd1(w: [U]) -> U { return w[0]; } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `hd1` + | help: try using a local generic parameter instead: `hd1` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/nested-ty-params.rs:3:23 | LL | fn hd(v: Vec ) -> U { | - type variable from outer function LL | fn hd1(w: [U]) -> U { return w[0]; } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `hd1` + | help: try using a local generic parameter instead: `hd1` error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.rs b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.rs index 112427a3fce..c77a66524f7 100644 --- a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.rs +++ b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.rs @@ -6,7 +6,7 @@ trait TraitA { fn outer(&self) { enum Foo { Variance(A) - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } } @@ -14,21 +14,21 @@ trait TraitA { trait TraitB { fn outer(&self) { struct Foo(A); - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } trait TraitC { fn outer(&self) { struct Foo { a: A } - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } trait TraitD { fn outer(&self) { fn foo(a: A) { } - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } diff --git a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 8eca720d88e..f6b8abf4057 100644 --- a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -1,44 +1,44 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:8:22 | LL | trait TraitA { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | enum Foo { LL | Variance(A) - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:16:23 | LL | trait TraitB { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | struct Foo(A); - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28 | LL | trait TraitC { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | struct Foo { a: A } - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22 | LL | trait TraitD { | - type variable from outer function LL | fn outer(&self) { LL | fn foo(a: A) { } - | ------ ^ use of type variable from outer function + | ------ ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `foo` + | help: try using a local generic parameter instead: `foo` error: aborting due to 4 previous errors diff --git a/src/test/ui/type/type-arg-out-of-scope.rs b/src/test/ui/type/type-arg-out-of-scope.rs index b96c9bf6a0e..d5b815f6a95 100644 --- a/src/test/ui/type/type-arg-out-of-scope.rs +++ b/src/test/ui/type/type-arg-out-of-scope.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use type parameters from outer function +// error-pattern:can't use generic parameters from outer function fn foo(x: T) { fn bar(f: Box T>) { } } diff --git a/src/test/ui/type/type-arg-out-of-scope.stderr b/src/test/ui/type/type-arg-out-of-scope.stderr index 62b6a86662d..645cbb33abe 100644 --- a/src/test/ui/type/type-arg-out-of-scope.stderr +++ b/src/test/ui/type/type-arg-out-of-scope.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/type-arg-out-of-scope.rs:3:25 | LL | fn foo(x: T) { | - type variable from outer function LL | fn bar(f: Box T>) { } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bar` + | help: try using a local generic parameter instead: `bar` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/type-arg-out-of-scope.rs:3:31 | LL | fn foo(x: T) { | - type variable from outer function LL | fn bar(f: Box T>) { } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bar` + | help: try using a local generic parameter instead: `bar` error: aborting due to 2 previous errors diff --git a/src/test/ui/use-self-in-inner-fn.rs b/src/test/ui/use-self-in-inner-fn.rs index cde96dc778b..eccb315feb1 100644 --- a/src/test/ui/use-self-in-inner-fn.rs +++ b/src/test/ui/use-self-in-inner-fn.rs @@ -4,8 +4,8 @@ impl A { //~^ NOTE `Self` type implicitly declared here, by this `impl` fn banana(&mut self) { fn peach(this: &Self) { - //~^ ERROR can't use type parameters from outer function - //~| NOTE use of type variable from outer function + //~^ ERROR can't use generic parameters from outer function + //~| NOTE use of generic parameter from outer function //~| NOTE use a type here instead } } diff --git a/src/test/ui/use-self-in-inner-fn.stderr b/src/test/ui/use-self-in-inner-fn.stderr index a613804b803..96609349924 100644 --- a/src/test/ui/use-self-in-inner-fn.stderr +++ b/src/test/ui/use-self-in-inner-fn.stderr @@ -1,4 +1,4 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/use-self-in-inner-fn.rs:6:25 | LL | impl A { @@ -7,7 +7,7 @@ LL | impl A { LL | fn peach(this: &Self) { | ^^^^ | | - | use of type variable from outer function + | use of generic parameter from outer function | use a type here instead error: aborting due to previous error -- cgit 1.4.1-3-g733a5