From 8da27078d3b102a1d96dd0a4270baa1bb5f392e2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 12 May 2022 21:18:26 +0200 Subject: [PATCH 01/19] Stop pretty-printing anonymous lifetimes. --- compiler/rustc_middle/src/ty/print/pretty.rs | 71 ++++++++------------ 1 file changed, 28 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 4c0bc2e4337c7..64c63e3d567d0 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2177,61 +2177,47 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { define_scoped_cx!(self); let mut region_index = self.region_index; + let mut next_name = |this: &Self| loop { + let name = name_by_region_index(region_index); + region_index += 1; + if !this.used_region_names.contains(&name) { + break name; + } + }; + // If we want to print verbosely, then print *all* binders, even if they // aren't named. Eventually, we might just want this as the default, but // this is not *quite* right and changes the ordering of some output // anyways. let (new_value, map) = if self.tcx().sess.verbose() { // anon index + 1 (BrEnv takes 0) -> name - let mut region_map: BTreeMap = BTreeMap::default(); + let mut region_map: FxHashMap<_, _> = Default::default(); let bound_vars = value.bound_vars(); for var in bound_vars { + let ty::BoundVariableKind::Region(var) = var else { continue }; match var { - ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => { + ty::BrAnon(_) | ty::BrEnv => { start_or_continue(&mut self, "for<", ", "); + let name = next_name(&self); do_continue(&mut self, name); + region_map.insert(var, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)); } - ty::BoundVariableKind::Region(ty::BrAnon(i)) => { + ty::BrNamed(def_id, kw::UnderscoreLifetime) => { start_or_continue(&mut self, "for<", ", "); - let name = loop { - let name = name_by_region_index(region_index); - region_index += 1; - if !self.used_region_names.contains(&name) { - break name; - } - }; + let name = next_name(&self); do_continue(&mut self, name); - region_map.insert(i + 1, name); + region_map.insert(var, ty::BrNamed(def_id, name)); } - ty::BoundVariableKind::Region(ty::BrEnv) => { + ty::BrNamed(_, name) => { start_or_continue(&mut self, "for<", ", "); - let name = loop { - let name = name_by_region_index(region_index); - region_index += 1; - if !self.used_region_names.contains(&name) { - break name; - } - }; do_continue(&mut self, name); - region_map.insert(0, name); } - _ => continue, } } start_or_continue(&mut self, "", "> "); self.tcx.replace_late_bound_regions(value.clone(), |br| { - let kind = match br.kind { - ty::BrNamed(_, _) => br.kind, - ty::BrAnon(i) => { - let name = region_map[&(i + 1)]; - ty::BrNamed(CRATE_DEF_ID.to_def_id(), name) - } - ty::BrEnv => { - let name = region_map[&0]; - ty::BrNamed(CRATE_DEF_ID.to_def_id(), name) - } - }; + let kind = region_map[&br.kind]; self.tcx.mk_region(ty::ReLateBound( ty::INNERMOST, ty::BoundRegion { var: br.var, kind }, @@ -2242,21 +2228,20 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { let mut name = |br: ty::BoundRegion| { start_or_continue(&mut self, "for<", ", "); let kind = match br.kind { - ty::BrNamed(_, name) => { - do_continue(&mut self, name); - br.kind - } ty::BrAnon(_) | ty::BrEnv => { - let name = loop { - let name = name_by_region_index(region_index); - region_index += 1; - if !self.used_region_names.contains(&name) { - break name; - } - }; + let name = next_name(&self); do_continue(&mut self, name); ty::BrNamed(CRATE_DEF_ID.to_def_id(), name) } + ty::BrNamed(def_id, kw::UnderscoreLifetime) => { + let name = next_name(&self); + do_continue(&mut self, name); + ty::BrNamed(def_id, name) + } + ty::BrNamed(_, name) => { + do_continue(&mut self, name); + br.kind + } }; tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind })) }; From da175c743c3dbf7fc371534acbbd6a1bf0b17d50 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 12 May 2022 21:25:38 +0200 Subject: [PATCH 02/19] Make lifetime errors more precise in the presence of `Fresh` lifetimes. --- compiler/rustc_hir/src/hir.rs | 11 ++++ .../src/infer/error_reporting/mod.rs | 16 ++++-- .../nice_region_error/different_lifetimes.rs | 50 +++++++++++-------- .../nice_region_error/named_anon_conflict.rs | 3 +- .../ui/async-await/issue-76547.base.stderr | 12 +++++ .../ui/async-await/issue-76547.nll.stderr | 10 ++++ .../issues/issue-63388-1.base.stderr | 10 ++-- .../issues/issue-63388-1.nll.stderr | 9 ++-- .../ui/async-await/issues/issue-63388-1.rs | 4 +- src/test/ui/error-codes/E0308-2.stderr | 2 +- src/test/ui/issues/issue-17905-2.stderr | 4 +- src/test/ui/issues/issue-65230.stderr | 2 +- src/test/ui/nll/issue-52742.base.stderr | 2 +- src/test/ui/nll/issue-55394.base.stderr | 2 +- ...types_pin_lifetime_impl_trait-async.stderr | 2 +- ...es_pin_lifetime_mismatch-async.base.stderr | 12 +++++ ...pes_pin_lifetime_mismatch-async.nll.stderr | 10 ++++ .../elision/lt-ref-self-async.base.stderr | 36 +++++++++++++ .../self/elision/lt-ref-self-async.nll.stderr | 30 +++++++++++ .../elision/ref-mut-self-async.base.stderr | 36 +++++++++++++ .../elision/ref-mut-self-async.nll.stderr | 30 +++++++++++ .../elision/ref-mut-struct-async.base.stderr | 30 +++++++++++ .../elision/ref-mut-struct-async.nll.stderr | 25 ++++++++++ .../self/elision/ref-self-async.base.stderr | 42 ++++++++++++++++ .../ui/self/elision/ref-self-async.nll.stderr | 35 +++++++++++++ .../self/elision/ref-struct-async.base.stderr | 30 +++++++++++ .../self/elision/ref-struct-async.nll.stderr | 25 ++++++++++ 27 files changed, 434 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index bda7affe52983..dbe6fe6ea8402 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -131,6 +131,17 @@ impl LifetimeName { } } + pub fn is_anonymous(&self) -> bool { + match *self { + LifetimeName::ImplicitObjectLifetimeDefault + | LifetimeName::Implicit + | LifetimeName::Underscore + | LifetimeName::Param(ParamName::Fresh(_)) + | LifetimeName::Error => true, + LifetimeName::Static | LifetimeName::Param(_) => false, + } + } + pub fn is_elided(&self) -> bool { match self { LifetimeName::ImplicitObjectLifetimeDefault diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 11c893a7cb6d9..a2bd11f8b8e3e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -72,7 +72,7 @@ use rustc_middle::ty::{ subst::{GenericArgKind, Subst, SubstsRef}, Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable, }; -use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span}; +use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::ops::ControlFlow; use std::{cmp, fmt, iter}; @@ -161,7 +161,12 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>( { sp = param.span; } - (format!("the lifetime `{}` as defined here", br.name), sp) + let text = if br.name == kw::UnderscoreLifetime { + format!("the anonymous lifetime as defined here") + } else { + format!("the lifetime `{}` as defined here", br.name) + }; + (text, sp) } ty::ReFree(ty::FreeRegion { bound_region: ty::BoundRegionKind::BrNamed(_, name), .. @@ -172,7 +177,12 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>( { sp = param.span; } - (format!("the lifetime `{}` as defined here", name), sp) + let text = if name == kw::UnderscoreLifetime { + format!("the anonymous lifetime as defined here") + } else { + format!("the lifetime `{}` as defined here", name) + }; + (text, sp) } ty::ReFree(ref fr) => match fr.bound_region { ty::BrAnon(idx) => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index cb72cb41a7c00..b744594ddb7e6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -12,6 +12,7 @@ use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::{GenericParamKind, Ty}; use rustc_middle::ty::Region; +use rustc_span::symbol::kw; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when both the concerned regions are anonymous. @@ -169,7 +170,7 @@ pub fn suggest_adding_lifetime_params<'tcx>( return false; }; - if !lifetime_sub.name.is_elided() || !lifetime_sup.name.is_elided() { + if !lifetime_sub.name.is_anonymous() || !lifetime_sup.name.is_anonymous() { return false; }; @@ -188,32 +189,37 @@ pub fn suggest_adding_lifetime_params<'tcx>( _ => return false, }; - let (suggestion_param_name, introduce_new) = generics + let suggestion_param_name = generics .params .iter() - .find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) - .and_then(|p| tcx.sess.source_map().span_to_snippet(p.span).ok()) - .map(|name| (name, false)) - .unwrap_or_else(|| ("'a".to_string(), true)); - - let mut suggestions = vec![ - if let hir::LifetimeName::Underscore = lifetime_sub.name { - (lifetime_sub.span, suggestion_param_name.clone()) + .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) + .map(|p| p.name.ident().name) + .find(|i| *i != kw::UnderscoreLifetime); + let introduce_new = suggestion_param_name.is_none(); + let suggestion_param_name = + suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned()); + + debug!(?lifetime_sup.span); + debug!(?lifetime_sub.span); + let make_suggestion = |span: rustc_span::Span| { + if span.is_empty() { + (span, format!("{}, ", suggestion_param_name)) + } else if let Ok("&") = tcx.sess.source_map().span_to_snippet(span).as_deref() { + (span.shrink_to_hi(), format!("{} ", suggestion_param_name)) } else { - (lifetime_sub.span.shrink_to_hi(), suggestion_param_name.clone() + " ") - }, - if let hir::LifetimeName::Underscore = lifetime_sup.name { - (lifetime_sup.span, suggestion_param_name.clone()) - } else { - (lifetime_sup.span.shrink_to_hi(), suggestion_param_name.clone() + " ") - }, - ]; + (span, suggestion_param_name.clone()) + } + }; + let mut suggestions = + vec![make_suggestion(lifetime_sub.span), make_suggestion(lifetime_sup.span)]; if introduce_new { - let new_param_suggestion = match &generics.params { - [] => (generics.span, format!("<{}>", suggestion_param_name)), - [first, ..] => (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name)), - }; + let new_param_suggestion = + if let Some(first) = generics.params.iter().find(|p| !p.name.ident().span.is_empty()) { + (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name)) + } else { + (generics.span, format!("<{}>", suggestion_param_name)) + }; suggestions.push(new_param_suggestion); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 3de5273d8c78c..375ad8d3736dc 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -4,6 +4,7 @@ use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_middle::ty; +use rustc_span::symbol::kw; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// When given a `ConcreteFailure` for a function with parameters containing a named region and @@ -67,7 +68,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let is_impl_item = region_info.is_impl_item; match br { - ty::BrAnon(_) => {} + ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(_) => {} _ => { /* not an anonymous region */ debug!("try_report_named_anon_conflict: not an anonymous region"); diff --git a/src/test/ui/async-await/issue-76547.base.stderr b/src/test/ui/async-await/issue-76547.base.stderr index 34705d4838e76..109883fbeb7cb 100644 --- a/src/test/ui/async-await/issue-76547.base.stderr +++ b/src/test/ui/async-await/issue-76547.base.stderr @@ -5,6 +5,12 @@ LL | async fn fut(bufs: &mut [&mut [u8]]) { | ---------------- these two types are declared with different lifetimes... LL | ListFut(bufs).await | ^^^^ ...but data from `bufs` flows into `bufs` here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter + | +LL | async fn fut<'a>(bufs: &'a mut [&'a mut [u8]]) { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/issue-76547.rs:39:14 @@ -13,6 +19,12 @@ LL | async fn fut2(bufs: &mut [&mut [u8]]) -> i32 { | ---------------- these two types are declared with different lifetimes... LL | ListFut2(bufs).await | ^^^^ ...but data from `bufs` flows into `bufs` here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter + | +LL | async fn fut2<'a>(bufs: &'a mut [&'a mut [u8]]) -> i32 { + | ++++ ++ ++ error: aborting due to 2 previous errors diff --git a/src/test/ui/async-await/issue-76547.nll.stderr b/src/test/ui/async-await/issue-76547.nll.stderr index bc30da1e389b3..0a5a52cb79e4c 100644 --- a/src/test/ui/async-await/issue-76547.nll.stderr +++ b/src/test/ui/async-await/issue-76547.nll.stderr @@ -7,6 +7,11 @@ LL | async fn fut(bufs: &mut [&mut [u8]]) { | let's call the lifetime of this reference `'1` LL | ListFut(bufs).await | ^^^^ this usage requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | async fn fut<'a>(bufs: &'a mut [&'a mut [u8]]) { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/issue-76547.rs:39:14 @@ -17,6 +22,11 @@ LL | async fn fut2(bufs: &mut [&mut [u8]]) -> i32 { | let's call the lifetime of this reference `'1` LL | ListFut2(bufs).await | ^^^^ this usage requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | async fn fut2<'a>(bufs: &'a mut [&'a mut [u8]]) -> i32 { + | ++++ ++ ++ error: aborting due to 2 previous errors diff --git a/src/test/ui/async-await/issues/issue-63388-1.base.stderr b/src/test/ui/async-await/issues/issue-63388-1.base.stderr index 2ff85a27a4645..f5409a7ca5d29 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.base.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.base.stderr @@ -1,14 +1,12 @@ -error[E0623]: lifetime mismatch +error[E0621]: explicit lifetime required in the type of `foo` --> $DIR/issue-63388-1.rs:19:9 | LL | &'a self, foo: &dyn Foo - | -------- this parameter and the return type are declared with different lifetimes... -LL | ) -> &dyn Foo - | -------- + | -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)` ... LL | foo - | ^^^ ...but data from `foo` is returned here + | ^^^ lifetime `'a` required error: aborting due to previous error -For more information about this error, try `rustc --explain E0623`. +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr index eee0cee278b9c..9263a81bb6af4 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr @@ -1,17 +1,16 @@ -error: lifetime may not live long enough +error[E0621]: explicit lifetime required in the type of `foo` --> $DIR/issue-63388-1.rs:17:5 | -LL | async fn do_sth<'a>( - | -- lifetime `'a` defined here LL | &'a self, foo: &dyn Foo - | - let's call the lifetime of this reference `'1` + | -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)` LL | ) -> &dyn Foo LL | / { LL | | LL | | foo LL | | LL | | } - | |_____^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + | |_____^ lifetime `'a` required error: aborting due to previous error +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/async-await/issues/issue-63388-1.rs b/src/test/ui/async-await/issues/issue-63388-1.rs index c45d2a42177ce..f00f929540640 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.rs +++ b/src/test/ui/async-await/issues/issue-63388-1.rs @@ -15,9 +15,9 @@ impl Xyz { &'a self, foo: &dyn Foo ) -> &dyn Foo { - //[nll]~^ ERROR lifetime may not live long enough + //[nll]~^ ERROR explicit lifetime required in the type of `foo` [E0621] foo - //[base]~^ ERROR lifetime mismatch + //[base]~^ ERROR explicit lifetime required in the type of `foo` [E0621] } } diff --git a/src/test/ui/error-codes/E0308-2.stderr b/src/test/ui/error-codes/E0308-2.stderr index 5c1dcb4d4f9b3..de54a417253d4 100644 --- a/src/test/ui/error-codes/E0308-2.stderr +++ b/src/test/ui/error-codes/E0308-2.stderr @@ -6,7 +6,7 @@ LL | impl Eq for &dyn DynEq {} | = note: expected trait `<&dyn DynEq as PartialEq>` found trait `<&(dyn DynEq + 'static) as PartialEq>` -note: the lifetime `'_` as defined here... +note: the anonymous lifetime as defined here... --> $DIR/E0308-2.rs:9:13 | LL | impl Eq for &dyn DynEq {} diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr index c68265f71f259..88b5fbec6cf03 100644 --- a/src/test/ui/issues/issue-17905-2.stderr +++ b/src/test/ui/issues/issue-17905-2.stderr @@ -11,7 +11,7 @@ note: the anonymous lifetime defined here... | LL | fn say(self: &Pair<&str, isize>) { | ^^^^ -note: ...does not necessarily outlive the lifetime `'_` as defined here +note: ...does not necessarily outlive the anonymous lifetime as defined here --> $DIR/issue-17905-2.rs:5:5 | LL | &str, @@ -25,7 +25,7 @@ LL | fn say(self: &Pair<&str, isize>) { | = note: expected struct `Pair<&str, _>` found struct `Pair<&str, _>` -note: the lifetime `'_` as defined here... +note: the anonymous lifetime as defined here... --> $DIR/issue-17905-2.rs:5:5 | LL | &str, diff --git a/src/test/ui/issues/issue-65230.stderr b/src/test/ui/issues/issue-65230.stderr index bfeb38d6471e4..fcabcdea74fc2 100644 --- a/src/test/ui/issues/issue-65230.stderr +++ b/src/test/ui/issues/issue-65230.stderr @@ -6,7 +6,7 @@ LL | impl T1 for &dyn T2 {} | = note: expected trait `<&dyn T2 as T0>` found trait `<&(dyn T2 + 'static) as T0>` -note: the lifetime `'_` as defined here... +note: the anonymous lifetime as defined here... --> $DIR/issue-65230.rs:8:13 | LL | impl T1 for &dyn T2 {} diff --git a/src/test/ui/nll/issue-52742.base.stderr b/src/test/ui/nll/issue-52742.base.stderr index 259f378f70b5c..7b1fac082e42f 100644 --- a/src/test/ui/nll/issue-52742.base.stderr +++ b/src/test/ui/nll/issue-52742.base.stderr @@ -4,7 +4,7 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... LL | self.y = b.z | ^^^ | -note: ...the reference is valid for the lifetime `'_` as defined here... +note: ...the reference is valid for the anonymous lifetime as defined here... --> $DIR/issue-52742.rs:15:10 | LL | impl Foo<'_, '_> { diff --git a/src/test/ui/nll/issue-55394.base.stderr b/src/test/ui/nll/issue-55394.base.stderr index cc87954732c4e..2ec6a7af3f257 100644 --- a/src/test/ui/nll/issue-55394.base.stderr +++ b/src/test/ui/nll/issue-55394.base.stderr @@ -14,7 +14,7 @@ note: ...so that reference does not outlive borrowed content | LL | Foo { bar } | ^^^ -note: but, the lifetime must be valid for the lifetime `'_` as defined here... +note: but, the lifetime must be valid for the anonymous lifetime as defined here... --> $DIR/issue-55394.rs:11:10 | LL | impl Foo<'_> { diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 570a08cb58768..a0a42e3adbf81 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | async fn f(self: Pin<&Self>) -> impl Clone { self } | - ^^^^^^^^ | | - | hidden type `Pin<&Foo>` captures the lifetime `'_` as defined here + | hidden type `Pin<&Foo>` captures the anonymous lifetime as defined here | help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound | diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.base.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.base.stderr index 7985bf266d8e8..d2106630dfed7 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.base.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.base.stderr @@ -5,6 +5,12 @@ LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | ---- ---- ^ ...but data from `f` is returned here | | | this parameter and the return type are declared with different lifetimes... + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &Foo { f } + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:82 @@ -13,6 +19,12 @@ LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { ( | ---- ----------------- ^ ...but data from `f` is returned here | | | this parameter and the return type are declared with different lifetimes... + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:22:64 diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr index 8a55a7c34d77b..3fd58725d02b7 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr @@ -6,6 +6,11 @@ LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &Foo { f } + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:75 @@ -15,6 +20,11 @@ LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { ( | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:22:64 diff --git a/src/test/ui/self/elision/lt-ref-self-async.base.stderr b/src/test/ui/self/elision/lt-ref-self-async.base.stderr index b43854906149a..0e2bbcc3c04db 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.base.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.base.stderr @@ -7,6 +7,12 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:24:9 @@ -17,6 +23,12 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:30:9 @@ -27,6 +39,12 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:36:9 @@ -37,6 +55,12 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:42:9 @@ -47,6 +71,12 @@ LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:48:9 @@ -57,6 +87,12 @@ LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr index 2ba9a6596f62d..1c889838e7082 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr @@ -7,6 +7,11 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:24:9 @@ -17,6 +22,11 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:30:9 @@ -27,6 +37,11 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:36:9 @@ -37,6 +52,11 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:42:9 @@ -47,6 +67,11 @@ LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:48:9 @@ -57,6 +82,11 @@ LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self-async.base.stderr b/src/test/ui/self/elision/ref-mut-self-async.base.stderr index 851337552c9ad..8ffc0d6224212 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.base.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.base.stderr @@ -7,6 +7,12 @@ LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:24:9 @@ -17,6 +23,12 @@ LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:30:9 @@ -27,6 +39,12 @@ LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:36:9 @@ -37,6 +55,12 @@ LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:42:9 @@ -47,6 +71,12 @@ LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:48:9 @@ -57,6 +87,12 @@ LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr index cdd464039cda0..9beafcd4ff994 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr @@ -7,6 +7,11 @@ LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:24:9 @@ -17,6 +22,11 @@ LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:30:9 @@ -27,6 +37,11 @@ LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:36:9 @@ -37,6 +52,11 @@ LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:42:9 @@ -47,6 +67,11 @@ LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:48:9 @@ -57,6 +82,11 @@ LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct-async.base.stderr b/src/test/ui/self/elision/ref-mut-struct-async.base.stderr index 0de11c248758f..fefb3fc194439 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.base.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.base.stderr @@ -7,6 +7,12 @@ LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:22:9 @@ -17,6 +23,12 @@ LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:28:9 @@ -27,6 +39,12 @@ LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:34:9 @@ -37,6 +55,12 @@ LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:40:9 @@ -47,6 +71,12 @@ LL | async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr index 0ef410c8df1eb..7fbecbe76a548 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr @@ -7,6 +7,11 @@ LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:22:9 @@ -17,6 +22,11 @@ LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:28:9 @@ -27,6 +37,11 @@ LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:34:9 @@ -37,6 +52,11 @@ LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:40:9 @@ -47,6 +67,11 @@ LL | async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-self-async.base.stderr b/src/test/ui/self/elision/ref-self-async.base.stderr index fa13b69bb21a3..2b142b089d51b 100644 --- a/src/test/ui/self/elision/ref-self-async.base.stderr +++ b/src/test/ui/self/elision/ref-self-async.base.stderr @@ -7,6 +7,12 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:34:9 @@ -17,6 +23,12 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:40:9 @@ -27,6 +39,12 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:46:9 @@ -37,6 +55,12 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:52:9 @@ -47,6 +71,12 @@ LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:58:9 @@ -57,6 +87,12 @@ LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:64:9 @@ -67,6 +103,12 @@ LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 { + | ++++ ++ ++ error: aborting due to 7 previous errors diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr index 77faaa866505f..f4e531a817c3d 100644 --- a/src/test/ui/self/elision/ref-self-async.nll.stderr +++ b/src/test/ui/self/elision/ref-self-async.nll.stderr @@ -7,6 +7,11 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self-async.rs:34:9 @@ -17,6 +22,11 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self-async.rs:40:9 @@ -27,6 +37,11 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self-async.rs:46:9 @@ -37,6 +52,11 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self-async.rs:52:9 @@ -47,6 +67,11 @@ LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self-async.rs:58:9 @@ -57,6 +82,11 @@ LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self-async.rs:64:9 @@ -67,6 +97,11 @@ LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 { + | ++++ ++ ++ error: aborting due to 7 previous errors diff --git a/src/test/ui/self/elision/ref-struct-async.base.stderr b/src/test/ui/self/elision/ref-struct-async.base.stderr index 8da673d44354e..88ddca89804f6 100644 --- a/src/test/ui/self/elision/ref-struct-async.base.stderr +++ b/src/test/ui/self/elision/ref-struct-async.base.stderr @@ -7,6 +7,12 @@ LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:22:9 @@ -17,6 +23,12 @@ LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:28:9 @@ -27,6 +39,12 @@ LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:34:9 @@ -37,6 +55,12 @@ LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:40:9 @@ -47,6 +71,12 @@ LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... LL | f | ^ ...but data from `f` is returned here + | + = note: each elided lifetime in input position becomes a distinct lifetime +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr index ad07c70df8778..83c20329c3dad 100644 --- a/src/test/ui/self/elision/ref-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr @@ -7,6 +7,11 @@ LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:22:9 @@ -17,6 +22,11 @@ LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:28:9 @@ -27,6 +37,11 @@ LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:34:9 @@ -37,6 +52,11 @@ LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:40:9 @@ -47,6 +67,11 @@ LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | async fn box_pin_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors From 7b86c6f21e407e5da617a55aa172e85327b473db Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 12 May 2022 22:29:04 +0200 Subject: [PATCH 03/19] Fortify check for number of generic parameters. --- compiler/rustc_typeck/src/check/check.rs | 177 +++++++++++------- .../rustc_typeck/src/check/compare_method.rs | 20 +- .../parameter_number_and_kind_impl.stderr | 6 +- 3 files changed, 127 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index a6d7fecb2e83b..c513f7d49a1c1 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -8,10 +8,11 @@ use super::*; use rustc_attr as attr; use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; -use rustc_hir::{def::Res, ItemKind, Node, PathSegment}; +use rustc_hir::{ItemKind, Node, PathSegment}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::Obligation; @@ -29,7 +30,6 @@ use rustc_trait_selection::traits; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_ty_utils::representability::{self, Representability}; -use rustc_hir::def::DefKind; use std::iter; use std::ops::ControlFlow; @@ -93,7 +93,6 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.return_type_pre_known = return_type_pre_known; let tcx = fcx.tcx; - let sess = tcx.sess; let hir = tcx.hir(); let declared_ret_ty = fn_sig.output(); @@ -260,85 +259,123 @@ pub(super) fn check_fn<'a, 'tcx>( if let Some(panic_impl_did) = tcx.lang_items().panic_impl() && panic_impl_did == hir.local_def_id(fn_id).to_def_id() { - if let Some(panic_info_did) = tcx.lang_items().panic_info() { - if *declared_ret_ty.kind() != ty::Never { - sess.span_err(decl.output.span(), "return type should be `!`"); - } - - let inputs = fn_sig.inputs(); - let span = hir.span(fn_id); - if inputs.len() == 1 { - let arg_is_panic_info = match *inputs[0].kind() { - ty::Ref(region, ty, mutbl) => match *ty.kind() { - ty::Adt(ref adt, _) => { - adt.did() == panic_info_did - && mutbl == hir::Mutability::Not - && !region.is_static() - } - _ => false, - }, - _ => false, - }; - - if !arg_is_panic_info { - sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`"); - } - - if let Node::Item(item) = hir.get(fn_id) - && let ItemKind::Fn(_, ref generics, _) = item.kind - && !generics.params.is_empty() - { - sess.span_err(span, "should have no type parameters"); - } - } else { - let span = sess.source_map().guess_head_span(span); - sess.span_err(span, "function should have one argument"); - } - } else { - sess.err("language item required, but not found: `panic_info`"); - } + check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig, decl, declared_ret_ty); } // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !` if let Some(alloc_error_handler_did) = tcx.lang_items().oom() && alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() { - if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() { - if *declared_ret_ty.kind() != ty::Never { - sess.span_err(decl.output.span(), "return type should be `!`"); - } + check_alloc_error_fn(tcx, alloc_error_handler_did.expect_local(), fn_sig, decl, declared_ret_ty); + } - let inputs = fn_sig.inputs(); - let span = hir.span(fn_id); - if inputs.len() == 1 { - let arg_is_alloc_layout = match inputs[0].kind() { - ty::Adt(ref adt, _) => adt.did() == alloc_layout_did, - _ => false, - }; + (fcx, gen_ty) +} - if !arg_is_alloc_layout { - sess.span_err(decl.inputs[0].span, "argument should be `Layout`"); - } +fn check_panic_info_fn( + tcx: TyCtxt<'_>, + fn_id: LocalDefId, + fn_sig: ty::FnSig<'_>, + decl: &hir::FnDecl<'_>, + declared_ret_ty: Ty<'_>, +) { + let Some(panic_info_did) = tcx.lang_items().panic_info() else { + tcx.sess.err("language item required, but not found: `panic_info`"); + return; + }; - if let Node::Item(item) = hir.get(fn_id) - && let ItemKind::Fn(_, ref generics, _) = item.kind - && !generics.params.is_empty() - { - sess.span_err( - span, - "`#[alloc_error_handler]` function should have no type parameters", - ); - } - } else { - let span = sess.source_map().guess_head_span(span); - sess.span_err(span, "function should have one argument"); + if *declared_ret_ty.kind() != ty::Never { + tcx.sess.span_err(decl.output.span(), "return type should be `!`"); + } + + let span = tcx.def_span(fn_id); + let inputs = fn_sig.inputs(); + if inputs.len() != 1 { + let span = tcx.sess.source_map().guess_head_span(span); + tcx.sess.span_err(span, "function should have one argument"); + return; + } + + let arg_is_panic_info = match *inputs[0].kind() { + ty::Ref(region, ty, mutbl) => match *ty.kind() { + ty::Adt(ref adt, _) => { + adt.did() == panic_info_did && mutbl == hir::Mutability::Not && !region.is_static() } - } else { - sess.err("language item required, but not found: `alloc_layout`"); - } + _ => false, + }, + _ => false, + }; + + if !arg_is_panic_info { + tcx.sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`"); } - (fcx, gen_ty) + let DefKind::Fn = tcx.def_kind(fn_id) else { + let span = tcx.def_span(fn_id); + tcx.sess.span_err(span, "should be a function"); + return; + }; + + let generic_counts = tcx.generics_of(fn_id).own_counts(); + if generic_counts.types != 0 { + let span = tcx.def_span(fn_id); + tcx.sess.span_err(span, "should have no type parameters"); + } + if generic_counts.consts != 0 { + let span = tcx.def_span(fn_id); + tcx.sess.span_err(span, "should have no const parameters"); + } +} + +fn check_alloc_error_fn( + tcx: TyCtxt<'_>, + fn_id: LocalDefId, + fn_sig: ty::FnSig<'_>, + decl: &hir::FnDecl<'_>, + declared_ret_ty: Ty<'_>, +) { + let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() else { + tcx.sess.err("language item required, but not found: `alloc_layout`"); + return; + }; + + if *declared_ret_ty.kind() != ty::Never { + tcx.sess.span_err(decl.output.span(), "return type should be `!`"); + } + + let inputs = fn_sig.inputs(); + if inputs.len() != 1 { + let span = tcx.def_span(fn_id); + let span = tcx.sess.source_map().guess_head_span(span); + tcx.sess.span_err(span, "function should have one argument"); + return; + } + + let arg_is_alloc_layout = match inputs[0].kind() { + ty::Adt(ref adt, _) => adt.did() == alloc_layout_did, + _ => false, + }; + + if !arg_is_alloc_layout { + tcx.sess.span_err(decl.inputs[0].span, "argument should be `Layout`"); + } + + let DefKind::Fn = tcx.def_kind(fn_id) else { + let span = tcx.def_span(fn_id); + tcx.sess.span_err(span, "`#[alloc_error_handler]` should be a function"); + return; + }; + + let generic_counts = tcx.generics_of(fn_id).own_counts(); + if generic_counts.types != 0 { + let span = tcx.def_span(fn_id); + tcx.sess.span_err(span, "`#[alloc_error_handler]` function should have no type parameters"); + } + if generic_counts.consts != 0 { + let span = tcx.def_span(fn_id); + tcx.sess + .span_err(span, "`#[alloc_error_handler]` function should have no const parameters"); + } } fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 277bc1cf0f065..4d17307ddb968 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -660,8 +660,24 @@ fn compare_number_of_generics<'tcx>( _ => None, }) .collect(); - let spans = impl_item.generics.spans(); - let span = spans.primary_span(); + let spans = if impl_item.generics.params.is_empty() { + vec![impl_item.generics.span] + } else { + impl_item + .generics + .params + .iter() + .filter(|p| { + matches!( + p.kind, + hir::GenericParamKind::Type { .. } + | hir::GenericParamKind::Const { .. } + ) + }) + .map(|p| p.span) + .collect::>() + }; + let span = spans.first().copied(); let mut err = tcx.sess.struct_span_err_with_code( spans, diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr index 1458bf0c4a493..76d39c88b61c3 100644 --- a/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr +++ b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr @@ -8,7 +8,7 @@ LL | type A = u32; | ^ lifetimes do not match type in trait error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters - --> $DIR/parameter_number_and_kind_impl.rs:17:12 + --> $DIR/parameter_number_and_kind_impl.rs:17:16 | LL | type B<'a, 'b>; | -- -- @@ -16,9 +16,7 @@ LL | type B<'a, 'b>; | expected 0 type parameters ... LL | type B<'a, T> = Vec; - | ^^ ^ - | | - | found 1 type parameter + | ^ found 1 type parameter error[E0195]: lifetime parameters or bounds on type `C` do not match the trait declaration --> $DIR/parameter_number_and_kind_impl.rs:19:11 From 3162b33ce57578b958d26c6f1bb600719c93d309 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 13 May 2022 19:08:57 +0200 Subject: [PATCH 04/19] Handle anonymous lifetimes properly in diagnostics. --- .../src/diagnostics/region_name.rs | 10 +-- .../src/infer/error_reporting/mod.rs | 62 +++++++++---------- ...types_pin_lifetime_impl_trait-async.stderr | 4 +- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 4d2a16aa60984..cb4b154d271a5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -567,15 +567,17 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let lifetime = self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?; match lifetime.name { - hir::LifetimeName::Param(_) + hir::LifetimeName::Param(hir::ParamName::Plain(_) | hir::ParamName::Error) | hir::LifetimeName::Error - | hir::LifetimeName::Static - | hir::LifetimeName::Underscore => { + | hir::LifetimeName::Static => { let lifetime_span = lifetime.span; Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span)) } - hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit => { + hir::LifetimeName::Param(hir::ParamName::Fresh(_)) + | hir::LifetimeName::ImplicitObjectLifetimeDefault + | hir::LifetimeName::Implicit + | hir::LifetimeName::Underscore => { // In this case, the user left off the lifetime; so // they wrote something like: // diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index a2bd11f8b8e3e..3a4a7d018231d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -161,45 +161,45 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>( { sp = param.span; } - let text = if br.name == kw::UnderscoreLifetime { - format!("the anonymous lifetime as defined here") - } else { + let text = if br.has_name() { format!("the lifetime `{}` as defined here", br.name) + } else { + format!("the anonymous lifetime as defined here") }; (text, sp) } - ty::ReFree(ty::FreeRegion { - bound_region: ty::BoundRegionKind::BrNamed(_, name), .. - }) => { - let mut sp = sm.guess_head_span(tcx.def_span(scope)); - if let Some(param) = - tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name)) + ty::ReFree(ref fr) => { + if !fr.bound_region.is_named() + && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) { - sp = param.span; - } - let text = if name == kw::UnderscoreLifetime { - format!("the anonymous lifetime as defined here") + ("the anonymous lifetime defined here".to_string(), ty.span) } else { - format!("the lifetime `{}` as defined here", name) - }; - (text, sp) - } - ty::ReFree(ref fr) => match fr.bound_region { - ty::BrAnon(idx) => { - if let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) { - ("the anonymous lifetime defined here".to_string(), ty.span) - } else { - ( + match fr.bound_region { + ty::BoundRegionKind::BrNamed(_, name) => { + let mut sp = sm.guess_head_span(tcx.def_span(scope)); + if let Some(param) = + tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name)) + { + sp = param.span; + } + let text = if name == kw::UnderscoreLifetime { + format!("the anonymous lifetime as defined here") + } else { + format!("the lifetime `{}` as defined here", name) + }; + (text, sp) + } + ty::BrAnon(idx) => ( format!("the anonymous lifetime #{} defined here", idx + 1), - tcx.def_span(scope), - ) + tcx.def_span(scope) + ), + _ => ( + format!("the lifetime `{}` as defined here", region), + sm.guess_head_span(tcx.def_span(scope)), + ), } } - _ => ( - format!("the lifetime `{}` as defined here", region), - sm.guess_head_span(tcx.def_span(scope)), - ), - }, + } _ => bug!(), } } @@ -2555,7 +2555,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::ReEarlyBound(ty::EarlyBoundRegion { name, .. }) | ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(_, name), .. }), _, - ) => { + ) if name != kw::UnderscoreLifetime => { // Does the required lifetime have a nice name we can print? let mut err = struct_span_err!( self.tcx.sess, diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index a0a42e3adbf81..5b8b9bb68ad1e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -2,9 +2,9 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | - ^^^^^^^^ + | ----- ^^^^^^^^ | | - | hidden type `Pin<&Foo>` captures the anonymous lifetime as defined here + | hidden type `Pin<&Foo>` captures the anonymous lifetime defined here | help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound | From 0cf79d7d680bf8ef6f5c9939e7d2d730b504f5e0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 May 2022 12:24:18 +0200 Subject: [PATCH 05/19] Rebase fallout. --- src/test/ui/nll/issue-52742.nll.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/nll/issue-52742.nll.stderr b/src/test/ui/nll/issue-52742.nll.stderr index 6828418a78ec1..1a2165e0a9dac 100644 --- a/src/test/ui/nll/issue-52742.nll.stderr +++ b/src/test/ui/nll/issue-52742.nll.stderr @@ -2,7 +2,7 @@ error: lifetime may not live long enough --> $DIR/issue-52742.rs:17:9 | LL | fn take_bar(&mut self, b: Bar<'_>) { - | --------- -- let's call this `'1` + | --------- - has type `Bar<'1>` | | | has type `&mut Foo<'_, '2>` LL | self.y = b.z From c7db4b08fff9591adb2c7a66d5f81ce685655622 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 10 May 2022 20:17:38 +0900 Subject: [PATCH 06/19] Apply track_caller to closure on `expect_non_local()` --- compiler/rustc_hir/src/def.rs | 5 ++++- compiler/rustc_hir/src/lib.rs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 68876e89c4b1f..414f627259196 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -671,7 +671,10 @@ impl Res { #[track_caller] pub fn expect_non_local(self) -> Res { - self.map_id(|_| panic!("unexpected `Res::Local`")) + self.map_id( + #[track_caller] + |_| panic!("unexpected `Res::Local`"), + ) } pub fn macro_kind(self) -> Option { diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 7833571f88d43..d845c433d8c5f 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -3,6 +3,7 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html #![feature(associated_type_defaults)] +#![feature(closure_track_caller)] #![feature(const_btree_new)] #![feature(let_else)] #![feature(once_cell)] From bd4d1cd7a2edd98a92b85997812e70aee5e740c7 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 31 May 2022 11:22:26 -0500 Subject: [PATCH 07/19] migrate `maybe_recover_from_bad_qpath_stage_2` diagnostic --- .../locales/en-US/parser.ftl | 4 ++++ .../rustc_parse/src/parser/diagnostics.rs | 22 +++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index c98989b23c1a5..985173277e170 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -14,3 +14,7 @@ parser-add-paren = try adding parentheses parser-forgot-paren = perhaps you forgot parentheses? parser-expect-path = expected a path + +parser-maybe-recover-from-bad-qpath-stage-2 = + missing angle brackets in associated item path + .suggestion = try: `{$ty}` diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 12302315e9044..f57338ae4dd6e 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -286,6 +286,15 @@ pub enum BadTypePlusSub { }, } +#[derive(SessionDiagnostic)] +#[error(slug = "parser-maybe-recover-from-bad-qpath-stage-2")] +struct BadQPathStage2 { + #[primary_span] + #[suggestion(applicability = "maybe-incorrect")] + span: Span, + ty: String, +} + // SnapshotParser is used to create a snapshot of the parser // without causing duplicate errors being emitted when the `Parser` // is dropped. @@ -1469,15 +1478,10 @@ impl<'a> Parser<'a> { path.span = ty_span.to(self.prev_token.span); let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty)); - self.struct_span_err(path.span, "missing angle brackets in associated item path") - .span_suggestion( - // This is a best-effort recovery. - path.span, - "try", - format!("<{}>::{}", ty_str, pprust::path_to_string(&path)), - Applicability::MaybeIncorrect, - ) - .emit(); + self.sess.emit_err(BadQPathStage2 { + span: path.span, + ty: format!("<{}>::{}", ty_str, pprust::path_to_string(&path)), + }); let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`. Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path))) From 29ed9a56e3b5538f52f45723933fd769e9411d58 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 31 May 2022 11:45:44 -0500 Subject: [PATCH 08/19] migrate `maybe_consume_incorrect_semicolon` diagnostic --- .../locales/en-US/parser.ftl | 5 ++++ .../rustc_parse/src/parser/diagnostics.rs | 27 ++++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 985173277e170..90124b64f3cb3 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -18,3 +18,8 @@ parser-expect-path = expected a path parser-maybe-recover-from-bad-qpath-stage-2 = missing angle brackets in associated item path .suggestion = try: `{$ty}` + +parser-incorrect-semicolon = + expected item, found `;` + .suggestion = remove this semicolon + .help = {$name} declarations are not followed by a semicolon diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f57338ae4dd6e..9bfd4098968d3 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -295,6 +295,17 @@ struct BadQPathStage2 { ty: String, } +#[derive(SessionDiagnostic)] +#[error(slug = "parser-incorrect-semicolon")] +struct IncorrectSemicolon<'a> { + #[primary_span] + #[suggestion(applicability = "machine-applicable")] + span: Span, + #[help] + opt_help: Option<()>, + name: &'a str, +} + // SnapshotParser is used to create a snapshot of the parser // without causing duplicate errors being emitted when the `Parser` // is dropped. @@ -1490,13 +1501,10 @@ impl<'a> Parser<'a> { pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P]) -> bool { if self.token.kind == TokenKind::Semi { self.bump(); - let mut err = self.struct_span_err(self.prev_token.span, "expected item, found `;`"); - err.span_suggestion_short( - self.prev_token.span, - "remove this semicolon", - String::new(), - Applicability::MachineApplicable, - ); + + let mut err = + IncorrectSemicolon { span: self.prev_token.span, opt_help: None, name: "" }; + if !items.is_empty() { let previous_item = &items[items.len() - 1]; let previous_item_kind_name = match previous_item.kind { @@ -1509,10 +1517,11 @@ impl<'a> Parser<'a> { _ => None, }; if let Some(name) = previous_item_kind_name { - err.help(&format!("{name} declarations are not followed by a semicolon")); + err.opt_help = Some(()); + err.name = name; } } - err.emit(); + self.sess.emit_err(err); true } else { false From 93a427e3ca48bdb7f107e0dd0cf48dd53fb8aea8 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 31 May 2022 12:33:35 -0500 Subject: [PATCH 09/19] migrate `recover_from_await_method_call` diagnostic --- .../locales/en-US/parser.ftl | 4 ++++ compiler/rustc_parse/src/parser/diagnostics.rs | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 90124b64f3cb3..740ebcab0f86b 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -23,3 +23,7 @@ parser-incorrect-semicolon = expected item, found `;` .suggestion = remove this semicolon .help = {$name} declarations are not followed by a semicolon + +parser-incorrect-use-of-await = + incorrect use of `await` + .suggestion = `await` is not a method call, remove the parentheses diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 9bfd4098968d3..466b69ec33998 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -306,6 +306,14 @@ struct IncorrectSemicolon<'a> { name: &'a str, } +#[derive(SessionDiagnostic)] +#[error(slug = "parser-incorrect-use-of-await")] +struct IncorrectUseOfAwait { + #[primary_span] + #[suggestion(applicability = "machine-applicable")] + span: Span, +} + // SnapshotParser is used to create a snapshot of the parser // without causing duplicate errors being emitted when the `Parser` // is dropped. @@ -1659,14 +1667,8 @@ impl<'a> Parser<'a> { self.bump(); // ( let sp = lo.to(self.token.span); self.bump(); // ) - self.struct_span_err(sp, "incorrect use of `await`") - .span_suggestion( - sp, - "`await` is not a method call, remove the parentheses", - String::new(), - Applicability::MachineApplicable, - ) - .emit(); + + self.sess.emit_err(IncorrectUseOfAwait { span: sp }); } } From 2a0496cbc822b8e5488f6c4ba4cf9588595daf2a Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 31 May 2022 12:56:26 -0500 Subject: [PATCH 10/19] use `suggestion_short` for incorrect semicolon diagnostic --- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 466b69ec33998..6252182d09acb 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -299,7 +299,7 @@ struct BadQPathStage2 { #[error(slug = "parser-incorrect-semicolon")] struct IncorrectSemicolon<'a> { #[primary_span] - #[suggestion(applicability = "machine-applicable")] + #[suggestion_short(applicability = "machine-applicable")] span: Span, #[help] opt_help: Option<()>, From a06ba4548777cd4f4ac5379fbad6f2ab56ef85b1 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 31 May 2022 14:32:07 -0500 Subject: [PATCH 11/19] migrate `error_on_incorrect_await` diagnostic --- .../locales/en-US/parser.ftl | 5 +++ .../rustc_parse/src/parser/diagnostics.rs | 31 +++++++++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 740ebcab0f86b..98836bbc485b9 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -27,3 +27,8 @@ parser-incorrect-semicolon = parser-incorrect-use-of-await = incorrect use of `await` .suggestion = `await` is not a method call, remove the parentheses + + +parser-incorrect-await = + incorrect use of `await` + .suggestion = `await` is a postfix operation diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 6252182d09acb..1c09f56e4e604 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -314,6 +314,17 @@ struct IncorrectUseOfAwait { span: Span, } +#[derive(SessionDiagnostic)] +#[error(slug = "parser-incorrect-await")] +struct IncorrectAwait { + #[primary_span] + span: Span, + #[suggestion(code = "{expr}.await{question_mark}")] + sugg_span: (Span, Applicability), + expr: String, + question_mark: &'static str, +} + // SnapshotParser is used to create a snapshot of the parser // without causing duplicate errors being emitted when the `Parser` // is dropped. @@ -1643,18 +1654,20 @@ impl<'a> Parser<'a> { } fn error_on_incorrect_await(&self, lo: Span, hi: Span, expr: &Expr, is_question: bool) -> Span { - let expr_str = - self.span_to_snippet(expr.span).unwrap_or_else(|_| pprust::expr_to_string(&expr)); - let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" }); - let sp = lo.to(hi); - let app = match expr.kind { + let span = lo.to(hi); + let applicability = match expr.kind { ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await ?` _ => Applicability::MachineApplicable, }; - self.struct_span_err(sp, "incorrect use of `await`") - .span_suggestion(sp, "`await` is a postfix operation", suggestion, app) - .emit(); - sp + + self.sess.emit_err(IncorrectAwait { + span, + sugg_span: (span, applicability), + expr: self.span_to_snippet(expr.span).unwrap_or_else(|_| pprust::expr_to_string(&expr)), + question_mark: if is_question { "?" } else { "" }, + }); + + span } /// If encountering `future.await()`, consumes and emits an error. From 9ce04e378338b35d51a18c298f9f82fb4dbf920d Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 31 May 2022 15:07:44 -0500 Subject: [PATCH 12/19] merge diagnostics about incorrect uses of `.await` --- compiler/rustc_error_messages/locales/en-US/parser.ftl | 8 ++------ compiler/rustc_parse/src/parser/diagnostics.rs | 6 +++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 98836bbc485b9..f9feba8012be6 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -26,9 +26,5 @@ parser-incorrect-semicolon = parser-incorrect-use-of-await = incorrect use of `await` - .suggestion = `await` is not a method call, remove the parentheses - - -parser-incorrect-await = - incorrect use of `await` - .suggestion = `await` is a postfix operation + .parentheses-suggestion = `await` is not a method call, remove the parentheses + .postfix-suggestion = `await` is a postfix operation diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 1c09f56e4e604..dea9681a9af78 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -310,16 +310,16 @@ struct IncorrectSemicolon<'a> { #[error(slug = "parser-incorrect-use-of-await")] struct IncorrectUseOfAwait { #[primary_span] - #[suggestion(applicability = "machine-applicable")] + #[suggestion(message = "parentheses-suggestion", applicability = "machine-applicable")] span: Span, } #[derive(SessionDiagnostic)] -#[error(slug = "parser-incorrect-await")] +#[error(slug = "parser-incorrect-use-of-await")] struct IncorrectAwait { #[primary_span] span: Span, - #[suggestion(code = "{expr}.await{question_mark}")] + #[suggestion(message = "postfix-suggestion", code = "{expr}.await{question_mark}")] sugg_span: (Span, Applicability), expr: String, question_mark: &'static str, From e1d63d1d7c19c6d341b9baed971493eb3354117c Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 31 May 2022 16:28:05 -0500 Subject: [PATCH 13/19] migrate `check_for_for_in_in_typo` diagnostic --- .../locales/en-US/parser.ftl | 4 ++++ .../rustc_parse/src/parser/diagnostics.rs | 21 ++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index f9feba8012be6..076b1b1caed72 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -28,3 +28,7 @@ parser-incorrect-use-of-await = incorrect use of `await` .parentheses-suggestion = `await` is not a method call, remove the parentheses .postfix-suggestion = `await` is a postfix operation + +parser-in-in-typo = + expected iterable, found keyword `in` + .suggestion = remove the duplicated `in` diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index dea9681a9af78..d6b981bdeefc5 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -325,6 +325,15 @@ struct IncorrectAwait { question_mark: &'static str, } +#[derive(SessionDiagnostic)] +#[error(slug = "parser-in-in-typo")] +struct InInTypo { + #[primary_span] + span: Span, + #[suggestion(applicability = "machine-applicable")] + sugg_span: Span, +} + // SnapshotParser is used to create a snapshot of the parser // without causing duplicate errors being emitted when the `Parser` // is dropped. @@ -1953,14 +1962,10 @@ impl<'a> Parser<'a> { pub(super) fn check_for_for_in_in_typo(&mut self, in_span: Span) { if self.eat_keyword(kw::In) { // a common typo: `for _ in in bar {}` - self.struct_span_err(self.prev_token.span, "expected iterable, found keyword `in`") - .span_suggestion_short( - in_span.until(self.prev_token.span), - "remove the duplicated `in`", - String::new(), - Applicability::MachineApplicable, - ) - .emit(); + self.sess.emit_err(InInTypo { + span: self.prev_token.span, + sugg_span: in_span.until(self.prev_token.span), + }); } } From 0b54b91496f3812de5fa21a09c8d8db3fc96108a Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 1 Jun 2022 00:23:23 +0200 Subject: [PATCH 14/19] Spelling correction. --- library/alloc/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index d5ed3fd18c3b8..4a965cb12db48 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1397,7 +1397,7 @@ impl Arc { /// be cloned. /// /// See also [`get_mut`], which will fail rather than cloning the inner value - /// or diassociating [`Weak`] pointers. + /// or disassociating [`Weak`] pointers. /// /// [`clone`]: Clone::clone /// [`get_mut`]: Arc::get_mut From 31ece0c850ca3642efa13fcd3dfb0ce007c2e0cc Mon Sep 17 00:00:00 2001 From: Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> Date: Wed, 1 Jun 2022 13:47:39 +0200 Subject: [PATCH 15/19] Update sync.rs --- library/alloc/src/sync.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4a965cb12db48..1fb036743bff8 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1393,11 +1393,11 @@ impl Arc { /// referred to as clone-on-write. /// /// However, if there are no other `Arc` pointers to this allocation, but some [`Weak`] - /// pointers, then the [`Weak`] pointers will be disassociated and the inner value will not + /// pointers, then the [`Weak`] pointers will be disociated and the inner value will not /// be cloned. /// /// See also [`get_mut`], which will fail rather than cloning the inner value - /// or disassociating [`Weak`] pointers. + /// or dissociating [`Weak`] pointers. /// /// [`clone`]: Clone::clone /// [`get_mut`]: Arc::get_mut @@ -1420,7 +1420,7 @@ impl Arc { /// assert_eq!(*other_data, 12); /// ``` /// - /// [`Weak`] pointers will be disassociated: + /// [`Weak`] pointers will be dissociated: /// /// ``` /// use std::sync::Arc; From f81269f508f41ccc8d4398cb36a218b19cbd2901 Mon Sep 17 00:00:00 2001 From: Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> Date: Wed, 1 Jun 2022 14:12:36 +0200 Subject: [PATCH 16/19] Update sync.rs --- library/alloc/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 1fb036743bff8..55d51e0a3c4cf 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1393,7 +1393,7 @@ impl Arc { /// referred to as clone-on-write. /// /// However, if there are no other `Arc` pointers to this allocation, but some [`Weak`] - /// pointers, then the [`Weak`] pointers will be disociated and the inner value will not + /// pointers, then the [`Weak`] pointers will be dissociated and the inner value will not /// be cloned. /// /// See also [`get_mut`], which will fail rather than cloning the inner value From 0fa70a8e2a95f0e33c4598ced446cfe3e7df1ae6 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Wed, 1 Jun 2022 07:14:33 -0500 Subject: [PATCH 17/19] rename `sp` to `span` --- compiler/rustc_parse/src/parser/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d6b981bdeefc5..8198938da646e 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1687,10 +1687,10 @@ impl<'a> Parser<'a> { // future.await() let lo = self.token.span; self.bump(); // ( - let sp = lo.to(self.token.span); + let span = lo.to(self.token.span); self.bump(); // ) - self.sess.emit_err(IncorrectUseOfAwait { span: sp }); + self.sess.emit_err(IncorrectUseOfAwait { span }); } } From 572c39000ba24a254637f8e53bb5933fbd5ebef7 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 25 May 2022 21:45:35 +0900 Subject: [PATCH 18/19] Stabilize `box_into_pin` --- library/alloc/src/boxed.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 41f3b1fa3dddb..e2c692b5299f4 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1175,14 +1175,33 @@ impl Box { /// This conversion does not allocate on the heap and happens in place. /// /// This is also available via [`From`]. - #[unstable(feature = "box_into_pin", issue = "62370")] + /// + /// # Notes + /// + /// It's not recommended that crates add an impl like `From> for Pin`, + /// as it'll introduce an ambiguity when calling `Pin::from`. + /// A demonstration of such a poor impl is shown below. + /// + /// ```compile_fail + /// # use std::pin::Pin; + /// struct Foo; // A type defined in this crate. + /// impl From> for Pin { + /// fn from(_: Box<()>) -> Pin { + /// Pin::new(Foo) + /// } + /// } + /// + /// let foo = Box::new(()); + /// let bar = Pin::from(foo); + /// ``` + #[stable(feature = "box_into_pin", since = "1.63.0")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] pub const fn into_pin(boxed: Self) -> Pin where A: 'static, { // It's not possible to move or replace the insides of a `Pin>` - // when `T: !Unpin`, so it's safe to pin it directly without any + // when `T: !Unpin`, so it's safe to pin it directly without any // additional requirements. unsafe { Pin::new_unchecked(boxed) } } From 0835dfe5795ef7f7214a9fa6dc8facb8ed166a1c Mon Sep 17 00:00:00 2001 From: Reilly Wood <26268125+rgwood@users.noreply.github.com> Date: Wed, 1 Jun 2022 20:32:33 -0400 Subject: [PATCH 19/19] Fix Windows file metadata docs Retrieving file metadata on Windows now uses GetFileInformationByHandle not GetFileAttributesEx --- library/std/src/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 431a1efc8d1f6..55bd2c59406df 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1620,7 +1620,7 @@ pub fn remove_file>(path: P) -> io::Result<()> { /// # Platform-specific behavior /// /// This function currently corresponds to the `stat` function on Unix -/// and the `GetFileAttributesEx` function on Windows. +/// and the `GetFileInformationByHandle` function on Windows. /// Note that, this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior @@ -1654,7 +1654,7 @@ pub fn metadata>(path: P) -> io::Result { /// # Platform-specific behavior /// /// This function currently corresponds to the `lstat` function on Unix -/// and the `GetFileAttributesEx` function on Windows. +/// and the `GetFileInformationByHandle` function on Windows. /// Note that, this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior