From fcfc7963891db5c91035ea527ead2ef998d6781b Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sat, 9 Mar 2019 13:30:42 +0530 Subject: [PATCH 1/8] fixes rust-lang#56766 --- src/libsyntax/parse/parser.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fd5038a8614f2..5789d2d09200d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6630,6 +6630,22 @@ impl<'a> Parser<'a> { self.expect(&token::OpenDelim(token::Brace))?; let mut trait_items = vec![]; while !self.eat(&token::CloseDelim(token::Brace)) { + if let token::DocComment(_) = self.token { + if self.look_ahead(1, + |tok| tok == &token::Token::CloseDelim(token::Brace)) { + let mut err = self.diagnostic().struct_span_err_with_code( + self.span, + "found a documentation comment that doesn't document anything", + DiagnosticId::Error("E0584".into()), + ); + err.help("doc comments must come before what they document, maybe a \ + comment was intended with `//`?", + ); + err.emit(); + self.bump(); + continue; + } + } let mut at_end = false; match self.parse_trait_item(&mut at_end) { Ok(item) => trait_items.push(item), From eaff0fe36fa9c6ff25492808750626167c80c3d9 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Wed, 13 Mar 2019 09:58:05 +0530 Subject: [PATCH 2/8] adding test --- src/test/ui/parser/doc-inside-trait-item.rs | 6 ++++++ src/test/ui/parser/doc-inside-trait-item.stderr | 11 +++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/test/ui/parser/doc-inside-trait-item.rs create mode 100644 src/test/ui/parser/doc-inside-trait-item.stderr diff --git a/src/test/ui/parser/doc-inside-trait-item.rs b/src/test/ui/parser/doc-inside-trait-item.rs new file mode 100644 index 0000000000000..897515d65bb8e --- /dev/null +++ b/src/test/ui/parser/doc-inside-trait-item.rs @@ -0,0 +1,6 @@ +trait User{ + fn test(); + /// empty doc + //~^ ERROR found a documentation comment that doesn't document anything +} +fn main() {} \ No newline at end of file diff --git a/src/test/ui/parser/doc-inside-trait-item.stderr b/src/test/ui/parser/doc-inside-trait-item.stderr new file mode 100644 index 0000000000000..261e27b6e0d18 --- /dev/null +++ b/src/test/ui/parser/doc-inside-trait-item.stderr @@ -0,0 +1,11 @@ +error[E0584]: found a documentation comment that doesn't document anything + --> $DIR/doc-inside-trait-item.rs:3:5 + | +LL | /// empty doc + | ^^^^^^^^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0584`. From d2584816254278cd844d4892f0acf563f2e7e207 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Wed, 13 Mar 2019 11:53:06 +0530 Subject: [PATCH 3/8] tidy test --- src/test/ui/parser/doc-inside-trait-item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/parser/doc-inside-trait-item.rs b/src/test/ui/parser/doc-inside-trait-item.rs index 897515d65bb8e..87b501bd2a2df 100644 --- a/src/test/ui/parser/doc-inside-trait-item.rs +++ b/src/test/ui/parser/doc-inside-trait-item.rs @@ -3,4 +3,4 @@ trait User{ /// empty doc //~^ ERROR found a documentation comment that doesn't document anything } -fn main() {} \ No newline at end of file +fn main() {} From ee2a9d93e96e2beb608be7936a5651e454ae706a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 4 Mar 2019 11:52:03 -0800 Subject: [PATCH 4/8] Suggest using anonymous lifetime in `impl Trait` return --- .../nice_region_error/named_anon_conflict.rs | 42 ++++++++++++++++--- .../must_outlive_least_region_or_bound.stderr | 12 ++++-- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 3821484d38e5f..8b44aa5e70601 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -103,13 +103,43 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { error_var ); + let many = if let Ok(snippet) = self.tcx().sess.source_map().span_to_snippet(span) { + if "'static" == &named.to_string() && snippet.starts_with("impl ") { + diag.span_suggestion( + span, + "add explicit unnamed lifetime `'_` to the return type to constrain it", + format!("{} + '_", snippet), + Applicability::Unspecified, + ); + true + } else { + false + } + } else { + false + }; + if many { + diag.span_label( + span, + "`impl Trait` types can only capture lifetimes that they reference" + ); + } else { + diag.span_label(span, format!("lifetime `{}` required", named)); + } diag.span_suggestion( - new_ty_span, - &format!("add explicit lifetime `{}` to {}", named, span_label_var), - new_ty.to_string(), - Applicability::Unspecified, - ) - .span_label(span, format!("lifetime `{}` required", named)); + new_ty_span, + &format!("{}add explicit lifetime `{}` to {}", + if many { + "otherwise, " + } else { + "" + }, + named, + span_label_var, + ), + new_ty.to_string(), + Applicability::Unspecified, + ); Some(diag) } diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 8a477e42a66ef..8a155d1c1b215 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -2,9 +2,15 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/must_outlive_least_region_or_bound.rs:3:23 | LL | fn elided(x: &i32) -> impl Copy { x } - | ---- ^^^^^^^^^ lifetime `'static` required - | | - | help: add explicit lifetime `'static` to the type of `x`: `&'static i32` + | ^^^^^^^^^ `impl Trait` types can only capture lifetimes that they reference +help: add explicit unnamed lifetime `'_` to the return type to constrain it + | +LL | fn elided(x: &i32) -> impl Copy + '_ { x } + | ^^^^^^^^^^^^^^ +help: otherwise, add explicit lifetime `'static` to the type of `x` + | +LL | fn elided(x: &'static i32) -> impl Copy { x } + | ^^^^^^^^^^^^ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:6:44 From 14f4e27df3b69de8ce208be7aa174ce6884bf019 Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Sun, 31 Mar 2019 16:56:30 +0200 Subject: [PATCH 5/8] Fixed URL in cargotest::TEST_REPOS --- src/tools/cargotest/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 7f3c159075b97..3126b44f0d618 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -30,7 +30,7 @@ const TEST_REPOS: &'static [Test] = &[ }, Test { name: "tokei", - repo: "https://github.com/Aaronepower/tokei", + repo: "https://github.com/XAMPPRocky/tokei", sha: "5e11c4852fe4aa086b0e4fe5885822fbe57ba928", lock: None, packages: &[], From 30c247f881a87e40aed30983d4c923efb6148f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 31 Mar 2019 09:07:56 -0700 Subject: [PATCH 6/8] Suggest using anonymous lifetime in `impl Trait` return without hacks Fallback to `static_impl_trait` for nice error message by peeking at the return type and the lifetime type. Point at the return type instead of the return expr/stmt in NLL mode. --- .../nice_region_error/named_anon_conflict.rs | 47 +++++-------------- .../nll/region_infer/error_reporting/mod.rs | 10 ++++ .../must_outlive_least_region_or_bound.rs | 2 +- .../must_outlive_least_region_or_bound.stderr | 22 +++++---- .../ui/nll/ty-outlives/impl-trait-captures.rs | 2 +- .../ty-outlives/impl-trait-captures.stderr | 6 +-- 6 files changed, 41 insertions(+), 48 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 8b44aa5e70601..7403a5d7dbb09 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -1,6 +1,7 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where one region is named and the other is anonymous. use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::hir::{FunctionRetTy, TyKind}; use crate::ty; use errors::{Applicability, DiagnosticBuilder}; @@ -11,9 +12,10 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { let (span, sub, sup) = self.get_regions(); debug!( - "try_report_named_anon_conflict(sub={:?}, sup={:?})", + "try_report_named_anon_conflict(sub={:?}, sup={:?}, error={:?})", sub, - sup + sup, + self.error, ); // Determine whether the sub and sup consist of one named region ('a) @@ -84,6 +86,13 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { { return None; } + if let FunctionRetTy::Return(ty) = &fndecl.output { + if let (TyKind::Def(_, _), ty::ReStatic) = (&ty.node, sub) { + // This is an impl Trait return that evaluates de need of 'static. + // We handle this case better in `static_impl_trait`. + return None; + } + } } let (error_var, span_label_var) = if let Some(simple_ident) = arg.pat.simple_ident() { @@ -103,40 +112,10 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { error_var ); - let many = if let Ok(snippet) = self.tcx().sess.source_map().span_to_snippet(span) { - if "'static" == &named.to_string() && snippet.starts_with("impl ") { - diag.span_suggestion( - span, - "add explicit unnamed lifetime `'_` to the return type to constrain it", - format!("{} + '_", snippet), - Applicability::Unspecified, - ); - true - } else { - false - } - } else { - false - }; - if many { - diag.span_label( - span, - "`impl Trait` types can only capture lifetimes that they reference" - ); - } else { - diag.span_label(span, format!("lifetime `{}` required", named)); - } + diag.span_label(span, format!("lifetime `{}` required", named)); diag.span_suggestion( new_ty_span, - &format!("{}add explicit lifetime `{}` to {}", - if many { - "otherwise, " - } else { - "" - }, - named, - span_label_var, - ), + &format!("add explicit lifetime `{}` to {}", named, span_label_var), new_ty.to_string(), Applicability::Unspecified, ); diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 081c458bfc17a..3773f1a40c792 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -132,6 +132,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { } }); if let Some(i) = best_choice { + if let Some(next) = categorized_path.get(i + 1) { + if categorized_path[i].0 == ConstraintCategory::Return + && next.0 == ConstraintCategory::OpaqueType + { + // The return expression is being influenced by the return type being + // impl Trait, point at the return type and not the return expr. + return *next; + } + } return categorized_path[i]; } @@ -240,6 +249,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.provides_universal_region(r, fr, outlived_fr) }); + debug!("report_error: category={:?} {:?}", category, span); // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { let tables = infcx.tcx.typeck_tables_of(mir_def_id); diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index ef1b976ae333f..1c3b5ac76138f 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; fn elided(x: &i32) -> impl Copy { x } -//~^ ERROR explicit lifetime required in the type of `x` [E0621] +//~^ ERROR cannot infer an appropriate lifetime fn explicit<'a>(x: &'a i32) -> impl Copy { x } //~^ ERROR cannot infer an appropriate lifetime diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 8a155d1c1b215..9339a83b09a9d 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -1,16 +1,20 @@ -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/must_outlive_least_region_or_bound.rs:3:23 +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } - | ^^^^^^^^^ `impl Trait` types can only capture lifetimes that they reference -help: add explicit unnamed lifetime `'_` to the return type to constrain it + | --------- ^ ...but this borrow... + | | + | this return type evaluates to the `'static` lifetime... + | +note: ...can't outlive the anonymous lifetime #1 defined on the function body at 3:1 + --> $DIR/must_outlive_least_region_or_bound.rs:3:1 + | +LL | fn elided(x: &i32) -> impl Copy { x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1 | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^^^^^^^^^^^ -help: otherwise, add explicit lifetime `'static` to the type of `x` - | -LL | fn elided(x: &'static i32) -> impl Copy { x } - | ^^^^^^^^^^^^ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:6:44 @@ -73,5 +77,5 @@ LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { error: aborting due to 5 previous errors -Some errors occurred: E0310, E0621, E0623. +Some errors occurred: E0310, E0623. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs index 7405505d5d6f8..bcdf643c0b9d1 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs @@ -8,8 +8,8 @@ trait Foo<'a> { impl<'a, T> Foo<'a> for T { } fn foo<'a, T>(x: &T) -> impl Foo<'a> { +//~^ ERROR explicit lifetime required in the type of `x` [E0621] x - //~^ ERROR explicit lifetime required in the type of `x` [E0621] } fn main() {} diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr index d9481b6156ca0..3a1e3ce3ad1a0 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -1,8 +1,8 @@ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/impl-trait-captures.rs:11:5 + --> $DIR/impl-trait-captures.rs:10:25 | -LL | x - | ^ lifetime `ReEarlyBound(0, 'a)` required +LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { + | ^^^^^^^^^^^^ lifetime `ReEarlyBound(0, 'a)` required help: add explicit lifetime `ReEarlyBound(0, 'a)` to the type of `x` | LL | fn foo<'a, T>(x: &ReEarlyBound(0, 'a) T) -> impl Foo<'a> { From 3c26f65c0986ad8888f4ce5b65f75cadf37bbef0 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sun, 31 Mar 2019 23:56:09 +0200 Subject: [PATCH 7/8] ci: print the appveyor agent version at the start of the build --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index ab0a29d2752b5..6aac5f0717252 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -126,6 +126,8 @@ clone_depth: 2 build: false install: + # Print which AppVeyor agent version we're running on. + - appveyor version # If we need to download a custom MinGW, do so here and set the path # appropriately. # From 656d4c30e9686568b86e737cef7d2b27bb6041cd Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Mon, 1 Apr 2019 19:51:12 +0900 Subject: [PATCH 8/8] typo fix --- src/librustc_mir/interpret/snapshot.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 0168e1301fa7a..8bb663f846b73 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -431,7 +431,7 @@ impl<'a, 'mir, 'tcx> Eq for EvalSnapshot<'a, 'mir, 'tcx> impl<'a, 'mir, 'tcx> PartialEq for EvalSnapshot<'a, 'mir, 'tcx> { fn eq(&self, other: &Self) -> bool { - // FIXME: This looks to be a *ridicolously expensive* comparison operation. + // FIXME: This looks to be a *ridiculously expensive* comparison operation. // Doesn't this make tons of copies? Either `snapshot` is very badly named, // or it does! self.snapshot() == other.snapshot()