From c1383e4dc4bd6598f5d73d2d6b1054f61b2b99d4 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Fri, 19 Jan 2018 19:57:10 -0800 Subject: Add filtering options to `rustc_on_unimplemented` - filter error on the evaluated value of `Self` - filter error on the evaluated value of the type arguments - add argument to include custom note in diagnostic - allow the parser to parse `Self` when processing attributes - add custom message to binops --- src/libsyntax/parse/attr.rs | 2 +- src/libsyntax/parse/parser.rs | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 053746b579d..b01f479895b 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -235,7 +235,7 @@ impl<'a> Parser<'a> { } let lo = self.span; - let ident = self.parse_ident()?; + let ident = self.parse_ident_attr()?; let node = self.parse_meta_item_kind()?; Ok(ast::MetaItem { name: ident.name, node: node, span: lo.to(self.prev_span) }) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b3c485a85c0..9e8c4d3de22 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -762,13 +762,19 @@ impl<'a> Parser<'a> { } pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { - self.parse_ident_common(true) + self.parse_ident_common(true, false) } - fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { + pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { + self.parse_ident_common(true, true) + } + + fn parse_ident_common(&mut self, recover: bool, accept_self: bool) -> PResult<'a, ast::Ident> { match self.token { token::Ident(i) => { - if self.token.is_reserved_ident() { + if self.token.is_reserved_ident() + && !(accept_self && i.name == keywords::SelfType.name()) + { let mut err = self.struct_span_err(self.span, &format!("expected identifier, found {}", self.this_token_descr())); @@ -2111,7 +2117,7 @@ impl<'a> Parser<'a> { self.bump(); Ok(Ident::with_empty_ctxt(name)) } else { - self.parse_ident_common(false) + self.parse_ident_common(false, false) } } @@ -2128,7 +2134,7 @@ impl<'a> Parser<'a> { hi = self.prev_span; (fieldname, self.parse_expr()?, false) } else { - let fieldname = self.parse_ident_common(false)?; + let fieldname = self.parse_ident_common(false, false)?; hi = self.prev_span; // Mimic `x: x` for the `x` field shorthand. -- cgit 1.4.1-3-g733a5 From 27a23db66032be9be96e697fdda50e73b0b90cc5 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 22 Jan 2018 19:03:51 -0800 Subject: Rework `parse_ident_attr` --- src/libsyntax/parse/parser.rs | 51 ++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 25 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9e8c4d3de22..5b55f0f2328 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -761,29 +761,37 @@ impl<'a> Parser<'a> { }) } + fn expected_ident_found(&self) -> DiagnosticBuilder<'a> { + let mut err = self.struct_span_err(self.span, + &format!("expected identifier, found {}", + self.this_token_descr())); + if let Some(token_descr) = self.token_descr() { + err.span_label(self.span, format!("expected identifier, found {}", token_descr)); + } else { + err.span_label(self.span, "expected identifier"); + } + err + } + pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { - self.parse_ident_common(true, false) + self.parse_ident_common(true) } pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { - self.parse_ident_common(true, true) + match self.token { + token::Ident(i) if i.name == keywords::SelfType.name() { + self.bump(); + Ok(i) + } + _ => self.parse_ident(), + } } - fn parse_ident_common(&mut self, recover: bool, accept_self: bool) -> PResult<'a, ast::Ident> { + fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { token::Ident(i) => { - if self.token.is_reserved_ident() - && !(accept_self && i.name == keywords::SelfType.name()) - { - let mut err = self.struct_span_err(self.span, - &format!("expected identifier, found {}", - self.this_token_descr())); - if let Some(token_descr) = self.token_descr() { - err.span_label(self.span, format!("expected identifier, found {}", - token_descr)); - } else { - err.span_label(self.span, "expected identifier"); - } + if self.token.is_reserved_ident() { + let mut err = self.expected_ident_found(); if recover { err.emit(); } else { @@ -797,14 +805,7 @@ impl<'a> Parser<'a> { Err(if self.prev_token_kind == PrevTokenKind::DocComment { self.span_fatal_err(self.prev_span, Error::UselessDocComment) } else { - let mut err = self.fatal(&format!("expected identifier, found `{}`", - self.this_token_to_string())); - if let Some(token_descr) = self.token_descr() { - err.span_label(self.span, format!("expected identifier, found {}", - token_descr)); - } else { - err.span_label(self.span, "expected identifier"); - } + let mut err = self.expected_ident_found(); if self.token == token::Underscore { err.note("`_` is a wildcard pattern, not an identifier"); } @@ -2117,7 +2118,7 @@ impl<'a> Parser<'a> { self.bump(); Ok(Ident::with_empty_ctxt(name)) } else { - self.parse_ident_common(false, false) + self.parse_ident_common(false) } } @@ -2134,7 +2135,7 @@ impl<'a> Parser<'a> { hi = self.prev_span; (fieldname, self.parse_expr()?, false) } else { - let fieldname = self.parse_ident_common(false, false)?; + let fieldname = self.parse_ident_common(false)?; hi = self.prev_span; // Mimic `x: x` for the `x` field shorthand. -- cgit 1.4.1-3-g733a5 From f7c61783e4cbc169955c7e633ecf629ed901a54e Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 22 Jan 2018 19:13:06 -0800 Subject: Fix tests --- src/libsyntax/parse/parser.rs | 2 +- src/test/compile-fail/const-eval-overflow-4b.rs | 2 +- src/test/compile-fail/ufcs-qpath-self-mismatch.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5b55f0f2328..38017020730 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -779,7 +779,7 @@ impl<'a> Parser<'a> { pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(i) if i.name == keywords::SelfType.name() { + token::Ident(i) if i.name == keywords::SelfType.name() => { self.bump(); Ok(i) } diff --git a/src/test/compile-fail/const-eval-overflow-4b.rs b/src/test/compile-fail/const-eval-overflow-4b.rs index 02072e9a1a1..6028df18839 100644 --- a/src/test/compile-fail/const-eval-overflow-4b.rs +++ b/src/test/compile-fail/const-eval-overflow-4b.rs @@ -22,7 +22,7 @@ const A_I8_T : [u32; (i8::MAX as i8 + 1u8) as usize] //~^ ERROR mismatched types //~| expected i8, found u8 - //~| ERROR the trait bound `i8: std::ops::Add` is not satisfied + //~| ERROR cannot add `u8` to `i8` = [0; (i8::MAX as usize) + 1]; diff --git a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs index 94a98b1582a..caf510071bd 100644 --- a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs +++ b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs @@ -12,7 +12,7 @@ use std::ops::Add; fn main() { >::add(1, 2); - //~^ ERROR `i32: std::ops::Add` is not satisfied + //~^ ERROR cannot add `u32` to `i32` >::add(1u32, 2); //~^ ERROR mismatched types >::add(1, 2u32); -- cgit 1.4.1-3-g733a5 From 378e73e6db0b4d47586f4e3ec975e43ef530ac99 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 1 Feb 2018 12:12:55 -0800 Subject: Remove support for `Self` in attributes --- src/librustc/traits/error_reporting.rs | 2 -- src/libsyntax/parse/parser.rs | 8 +------- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index be7ecbce8af..d5ac6343144 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -372,9 +372,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let generics = self.tcx.generics_of(def_id); let self_ty = trait_ref.self_ty(); let self_ty_str = self_ty.to_string(); - // FIXME: remove once `Self` is accepted by the compiler flags.push(("_Self".to_string(), Some(self_ty_str.clone()))); - flags.push(("Self".to_string(), Some(self_ty_str.clone()))); for param in generics.types.iter() { let name = param.name.as_str().to_string(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 38017020730..9d573ea0e7c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -778,13 +778,7 @@ impl<'a> Parser<'a> { } pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { - match self.token { - token::Ident(i) if i.name == keywords::SelfType.name() => { - self.bump(); - Ok(i) - } - _ => self.parse_ident(), - } + self.parse_ident() } fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { -- cgit 1.4.1-3-g733a5 From fd3f2312a75bcc4c8121ad324a012c3b8befb61c Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 1 Feb 2018 14:16:53 -0800 Subject: Fix test after rebase --- src/libsyntax/parse/attr.rs | 2 +- src/libsyntax/parse/parser.rs | 4 -- .../ui/mismatched_types/closure-arg-count.stderr | 50 +++++++++++++--------- src/test/ui/suggestions/for-c-in-str.stderr | 2 +- src/test/ui/suggestions/iterate-str.rs | 19 -------- src/test/ui/suggestions/iterate-str.stderr | 13 ------ 6 files changed, 31 insertions(+), 59 deletions(-) delete mode 100644 src/test/ui/suggestions/iterate-str.rs delete mode 100644 src/test/ui/suggestions/iterate-str.stderr (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index b01f479895b..053746b579d 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -235,7 +235,7 @@ impl<'a> Parser<'a> { } let lo = self.span; - let ident = self.parse_ident_attr()?; + let ident = self.parse_ident()?; let node = self.parse_meta_item_kind()?; Ok(ast::MetaItem { name: ident.name, node: node, span: lo.to(self.prev_span) }) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9d573ea0e7c..4c61ab6bd78 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -777,10 +777,6 @@ impl<'a> Parser<'a> { self.parse_ident_common(true) } - pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { - self.parse_ident() - } - fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { token::Ident(i) => { diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 4e1523c79d2..be00ee4d74e 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -14,7 +14,7 @@ error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument | | | expected closure that takes 2 arguments -error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument +error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument --> $DIR/closure-arg-count.rs:19:15 | 19 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); @@ -39,9 +39,9 @@ help: change the closure to take multiple arguments instead of a single tuple | ^^^^^^^^^^^^^^^ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:21:5 + --> $DIR/closure-arg-count.rs:23:5 | -21 | f(|| panic!()); +23 | f(|| panic!()); | ^ -- takes 0 arguments | | | expected closure that takes 1 argument @@ -52,45 +52,53 @@ note: required by `f` 13 | fn f>(_: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:24:53 +error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments + --> $DIR/closure-arg-count.rs:26:53 | -24 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); - | ^^^ ------ help: consider changing the closure to accept a tuple: `|(i, x)|` +26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); + | ^^^ ------ takes 2 distinct arguments | | - | expected closure that takes a single tuple as argument + | expected closure that takes a single 2-tuple as argument +help: change the closure to accept a tuple instead of individual arguments + | +26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); + | ^^^^^^^^ -error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:26:53 +error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments + --> $DIR/closure-arg-count.rs:28:53 | -26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); - | ^^^ ------------- help: consider changing the closure to accept a tuple: `|(i, x): (usize, _)|` +28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); + | ^^^ ------------- takes 2 distinct arguments | | - | expected closure that takes a single tuple as argument + | expected closure that takes a single 2-tuple as argument +help: change the closure to accept a tuple instead of individual arguments + | +28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); + | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:28:53 + --> $DIR/closure-arg-count.rs:30:53 | -28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); +30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments | | | expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:30:53 + --> $DIR/closure-arg-count.rs:32:53 | -30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); +32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument ... -37 | fn foo() {} +41 | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:33:53 + --> $DIR/closure-arg-count.rs:35:53 | -32 | let bar = |i, x, y| i; +34 | let bar = |i, x, y| i; | --------- takes 3 distinct arguments -33 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); +35 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); | ^^^ expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments diff --git a/src/test/ui/suggestions/for-c-in-str.stderr b/src/test/ui/suggestions/for-c-in-str.stderr index 7a6dc9a5040..88a7b1b49d6 100644 --- a/src/test/ui/suggestions/for-c-in-str.stderr +++ b/src/test/ui/suggestions/for-c-in-str.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied --> $DIR/for-c-in-str.rs:14:14 | 14 | for c in "asdf" { - | ^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` | = help: the trait `std::iter::Iterator` is not implemented for `&str` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/suggestions/iterate-str.rs b/src/test/ui/suggestions/iterate-str.rs deleted file mode 100644 index 1022491b84a..00000000000 --- a/src/test/ui/suggestions/iterate-str.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018 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. - -fn main() { - for c in "foobarbaz" { - println!("{}", c); - } - //~^^^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied - //~| NOTE `&str` is not an iterator; try calling `.chars()` or `.bytes()` - //~| HELP the trait `std::iter::Iterator` is not implemented for `&str` - //~| NOTE required by `std::iter::IntoIterator::into_iter` -} diff --git a/src/test/ui/suggestions/iterate-str.stderr b/src/test/ui/suggestions/iterate-str.stderr deleted file mode 100644 index 59da6d70c02..00000000000 --- a/src/test/ui/suggestions/iterate-str.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied - --> $DIR/iterate-str.rs:12:5 - | -12 | / for c in "foobarbaz" { -13 | | println!("{}", c); -14 | | } - | |_____^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` - | - = help: the trait `std::iter::Iterator` is not implemented for `&str` - = note: required by `std::iter::IntoIterator::into_iter` - -error: aborting due to previous error - -- cgit 1.4.1-3-g733a5