From 5cbe6aa6ca1612344b1ac19ec473b585e00ad022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 30 Sep 2019 13:35:26 -0700 Subject: [PATCH 01/13] Reword E0392 slightly Make it clearer that a type or lifetime argument not being used can be fixed by referencing it in a struct's fields, not just using `PhathomData`. --- src/librustc_typeck/check/wfcheck.rs | 15 ++++++++++----- .../const-param-type-depends-on-type-param.stderr | 2 +- src/test/ui/error-codes/E0392.stderr | 2 +- src/test/ui/inner-static-type-parameter.stderr | 2 +- src/test/ui/issues/issue-17904-2.stderr | 2 +- src/test/ui/issues/issue-20413.stderr | 2 +- src/test/ui/issues/issue-36299.stderr | 4 ++-- src/test/ui/issues/issue-36638.stderr | 2 +- src/test/ui/issues/issue-37534.stderr | 2 +- ...n-bounds-on-objects-and-type-parameters.stderr | 2 +- src/test/ui/self/self_type_keyword.stderr | 2 +- .../variance-regions-unused-direct.stderr | 4 ++-- .../variance-regions-unused-indirect.stderr | 4 ++-- .../variance/variance-unused-region-param.stderr | 4 ++-- .../ui/variance/variance-unused-type-param.stderr | 6 +++--- 15 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 20c517d779b42..4dc5c6ca3074d 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -999,11 +999,16 @@ fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) { let suggested_marker_id = tcx.lang_items().phantom_data(); // Help is available only in presence of lang items. - if let Some(def_id) = suggested_marker_id { - err.help(&format!("consider removing `{}` or using a marker such as `{}`", - param_name, - tcx.def_path_str(def_id))); - } + let msg = if let Some(def_id) = suggested_marker_id { + format!( + "consider removing `{}`, refering to it in a field or using a marker such as `{}`", + param_name, + tcx.def_path_str(def_id), + ) + } else { + format!( "consider removing `{}` or refering to it in a field", param_name) + }; + err.help(&msg); err.emit(); } diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index 142efe45ac2d7..b72c68036d701 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -18,7 +18,7 @@ error[E0392]: parameter `T` is never used LL | pub struct Dependent([(); X]); | ^ unused parameter | - = help: consider removing `T` or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0392.stderr b/src/test/ui/error-codes/E0392.stderr index d0b808df184c4..d036cb5a07f3d 100644 --- a/src/test/ui/error-codes/E0392.stderr +++ b/src/test/ui/error-codes/E0392.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `T` is never used LL | enum Foo { Bar } | ^ unused parameter | - = help: consider removing `T` or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to previous error diff --git a/src/test/ui/inner-static-type-parameter.stderr b/src/test/ui/inner-static-type-parameter.stderr index 083b4b67eb459..f945dbda7d78a 100644 --- a/src/test/ui/inner-static-type-parameter.stderr +++ b/src/test/ui/inner-static-type-parameter.stderr @@ -14,7 +14,7 @@ error[E0392]: parameter `T` is never used LL | enum Bar { What } | ^ unused parameter | - = help: consider removing `T` or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-17904-2.stderr b/src/test/ui/issues/issue-17904-2.stderr index 930409cc63727..b84922a4d8f6a 100644 --- a/src/test/ui/issues/issue-17904-2.stderr +++ b/src/test/ui/issues/issue-17904-2.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `T` is never used LL | struct Foo where T: Copy; | ^ unused parameter | - = help: consider removing `T` or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 72a8fe4283b56..1c3ff16a2071a 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `T` is never used LL | struct NoData; | ^ unused parameter | - = help: consider removing `T` or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` --> $DIR/issue-20413.rs:8:1 diff --git a/src/test/ui/issues/issue-36299.stderr b/src/test/ui/issues/issue-36299.stderr index edbe790a0c9f6..2a9e01421c06d 100644 --- a/src/test/ui/issues/issue-36299.stderr +++ b/src/test/ui/issues/issue-36299.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `'a` is never used LL | struct Foo<'a, A> {} | ^^ unused parameter | - = help: consider removing `'a` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `A` is never used --> $DIR/issue-36299.rs:1:16 @@ -12,7 +12,7 @@ error[E0392]: parameter `A` is never used LL | struct Foo<'a, A> {} | ^ unused parameter | - = help: consider removing `A` or using a marker such as `std::marker::PhantomData` + = help: consider removing `A`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-36638.stderr b/src/test/ui/issues/issue-36638.stderr index f3f94198465d8..68354b569ff51 100644 --- a/src/test/ui/issues/issue-36638.stderr +++ b/src/test/ui/issues/issue-36638.stderr @@ -16,7 +16,7 @@ error[E0392]: parameter `Self` is never used LL | struct Foo(Self); | ^^^^ unused parameter | - = help: consider removing `Self` or using a marker such as `std::marker::PhantomData` + = help: consider removing `Self`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-37534.stderr b/src/test/ui/issues/issue-37534.stderr index 3a0ab32dcc66b..baf75771b1367 100644 --- a/src/test/ui/issues/issue-37534.stderr +++ b/src/test/ui/issues/issue-37534.stderr @@ -20,7 +20,7 @@ error[E0392]: parameter `T` is never used LL | struct Foo { } | ^ unused parameter | - = help: consider removing `T` or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr index 003dd0699d381..5c0df850cba0b 100644 --- a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr +++ b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr @@ -27,7 +27,7 @@ error[E0392]: parameter `'c` is never used LL | struct Foo<'a,'b,'c> { | ^^ unused parameter | - = help: consider removing `'c` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'c`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 3 previous errors diff --git a/src/test/ui/self/self_type_keyword.stderr b/src/test/ui/self/self_type_keyword.stderr index 6534d8c36e343..ee82d9da6229c 100644 --- a/src/test/ui/self/self_type_keyword.stderr +++ b/src/test/ui/self/self_type_keyword.stderr @@ -76,7 +76,7 @@ error[E0392]: parameter `'Self` is never used LL | struct Bar<'Self>; | ^^^^^ unused parameter | - = help: consider removing `'Self` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'Self`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 12 previous errors diff --git a/src/test/ui/variance/variance-regions-unused-direct.stderr b/src/test/ui/variance/variance-regions-unused-direct.stderr index 21ff475663c6c..3d1158d4f799f 100644 --- a/src/test/ui/variance/variance-regions-unused-direct.stderr +++ b/src/test/ui/variance/variance-regions-unused-direct.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `'a` is never used LL | struct Bivariant<'a>; | ^^ unused parameter | - = help: consider removing `'a` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `'d` is never used --> $DIR/variance-regions-unused-direct.rs:7:19 @@ -12,7 +12,7 @@ error[E0392]: parameter `'d` is never used LL | struct Struct<'a, 'd> { | ^^ unused parameter | - = help: consider removing `'d` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'d`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/variance/variance-regions-unused-indirect.stderr b/src/test/ui/variance/variance-regions-unused-indirect.stderr index fd66217f692f1..ccb2213f80b77 100644 --- a/src/test/ui/variance/variance-regions-unused-indirect.stderr +++ b/src/test/ui/variance/variance-regions-unused-indirect.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `'a` is never used LL | enum Foo<'a> { | ^^ unused parameter | - = help: consider removing `'a` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `'a` is never used --> $DIR/variance-regions-unused-indirect.rs:7:10 @@ -12,7 +12,7 @@ error[E0392]: parameter `'a` is never used LL | enum Bar<'a> { | ^^ unused parameter | - = help: consider removing `'a` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/variance/variance-unused-region-param.stderr b/src/test/ui/variance/variance-unused-region-param.stderr index a96b2338bf428..228fe7483f6ff 100644 --- a/src/test/ui/variance/variance-unused-region-param.stderr +++ b/src/test/ui/variance/variance-unused-region-param.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `'a` is never used LL | struct SomeStruct<'a> { x: u32 } | ^^ unused parameter | - = help: consider removing `'a` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `'a` is never used --> $DIR/variance-unused-region-param.rs:4:15 @@ -12,7 +12,7 @@ error[E0392]: parameter `'a` is never used LL | enum SomeEnum<'a> { Nothing } | ^^ unused parameter | - = help: consider removing `'a` or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/variance/variance-unused-type-param.stderr b/src/test/ui/variance/variance-unused-type-param.stderr index 883db46298624..5acf8adfe8791 100644 --- a/src/test/ui/variance/variance-unused-type-param.stderr +++ b/src/test/ui/variance/variance-unused-type-param.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `A` is never used LL | struct SomeStruct { x: u32 } | ^ unused parameter | - = help: consider removing `A` or using a marker such as `std::marker::PhantomData` + = help: consider removing `A`, refering to it in a field or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `A` is never used --> $DIR/variance-unused-type-param.rs:9:15 @@ -12,7 +12,7 @@ error[E0392]: parameter `A` is never used LL | enum SomeEnum { Nothing } | ^ unused parameter | - = help: consider removing `A` or using a marker such as `std::marker::PhantomData` + = help: consider removing `A`, refering to it in a field or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `T` is never used --> $DIR/variance-unused-type-param.rs:13:15 @@ -20,7 +20,7 @@ error[E0392]: parameter `T` is never used LL | enum ListCell { | ^ unused parameter | - = help: consider removing `T` or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` error: aborting due to 3 previous errors From 7b480cdec6d6c046dc3cd86020f3762e37558cd4 Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Tue, 1 Oct 2019 18:20:46 -0400 Subject: [PATCH 02/13] Implement Clone::clone_from for LinkedList --- src/liballoc/collections/linked_list.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 816a71f255798..998bcb87393b1 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1197,6 +1197,19 @@ impl Clone for LinkedList { fn clone(&self) -> Self { self.iter().cloned().collect() } + + fn clone_from(&mut self, other: &Self) { + let mut iter_other = other.iter(); + if self.len() > other.len() { + self.split_off(other.len()); + } + for elem in self.iter_mut() { + elem.clone_from(iter_other.next().unwrap()); + } + if !iter_other.is_empty() { + self.extend(iter_other.cloned()); + } + } } #[stable(feature = "rust1", since = "1.0.0")] From 1245467322dd8a93f375fc8965a6102d84a8303b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 18 Aug 2019 01:20:24 -0400 Subject: [PATCH 03/13] Improve HRTB error span when -Zno-leak-check is used As described in #57374, NLL currently produces unhelpful higher-ranked trait bound (HRTB) errors when '-Zno-leak-check' is enabled. This PR tackles one half of this issue - making the error message point at the proper span. The error message itself is still the very generic "higher-ranked subtype error", but this can be improved in a follow-up PR. The root cause of the bad spans lies in how NLL attempts to compute the 'blamed' region, for which it will retrieve a span for. Consider the following code, which (correctly) does not compile: ```rust let my_val: u8 = 25; let a: &u8 = &my_val; let b = a; let c = b; let d: &'static u8 = c; ``` This will cause NLL to generate the following subtype constraints: d :< c c :< b b <: a Since normal Rust lifetimes are covariant, this results in the following region constraints (I'm using 'd to denote the lifetime of 'd', 'c to denote the lifetime of 'c, etc.): 'c: 'd 'b: 'c 'a: 'b From this, we can derive that 'a: 'd holds, which implies that 'a: 'static must hold. However, this is not the case, since 'a refers to 'my_val', which does not outlive the current function. When NLL attempts to infer regions for this code, it will see that the region 'a has grown 'too large' - it will be inferred to outlive 'static, despite the fact that is not declared as outliving 'static We can find the region responsible, 'd, by starting at the *end* of the 'constraint chain' we generated above. This works because for normal (non-higher-ranked) lifetimes, we generally build up a 'chain' of lifetime constraints *away* from the original variable/lifetime. That is, our original lifetime 'a is required to outlive progressively more regions. If it ends up living for too long, we can look at the 'end' of this chain to determine the 'most recent' usage that caused the lifetime to grow too large. However, this logic does not work correctly when higher-ranked trait bounds (HRTBs) come into play. This is because HRTBs have *contravariance* with respect to their bound regions. For example, this code snippet compiles: ```rust let a: for<'a> fn(&'a ()) = |_| {}; let b: fn(&'static ()) = a; ``` Here, we require that 'a' is a subtype of 'b'. Because of contravariance, we end up with the region constraint 'static: 'a, *not* 'a: 'static This means that our 'constraint chains' grow in the opposite direction of 'normal lifetime' constraint chains. As we introduce subtypes, our lifetime ends up being outlived by other lifetimes, rather than outliving other lifetimes. Therefore, starting at the end of the 'constraint chain' will cause us to 'blame' a lifetime close to the original definition of a variable, instead of close to where the bad lifetime constraint is introduced. This PR improves how we select the region to blame for 'too large' universal lifetimes, when bound lifetimes are involved. If the region we're checking is a 'placeholder' region (e.g. the region 'a' in for<'a>, or the implicit region in fn(&())), we start traversing the constraint chain from the beginning, rather than the end. There are two (maybe more) different ways we generate region constraints for NLL: requirements generated from trait queries, and requirements generated from MIR subtype constraints. While the former always use explicit placeholder regions, the latter is more tricky. In order to implement contravariance for HRTBs, TypeRelating replaces placeholder regions with existential regions. This requires us to keep track of whether or not an existential region was originally a placeholder region. When we look for a region to blame, we check if our starting region is either a placeholder region or is an existential region created from a placeholder region. If so, we start iterating from the beginning of the constraint chain, rather than the end. --- src/librustc/infer/mod.rs | 6 +- src/librustc/infer/nll_relate/mod.rs | 4 +- .../nll/region_infer/error_reporting/mod.rs | 63 +++++++++++++++---- .../borrow_check/nll/region_infer/mod.rs | 14 +++-- src/librustc_mir/borrow_check/nll/renumber.rs | 2 +- .../borrow_check/nll/type_check/relate_tys.rs | 8 ++- src/librustc_traits/chalk_context/unify.rs | 2 +- src/test/ui/hrtb/issue-30786.rs | 1 + src/test/ui/nll/relate_tys/fn-subtype.rs | 10 +++ src/test/ui/nll/relate_tys/fn-subtype.stderr | 8 +++ src/test/ui/nll/relate_tys/trait-hrtb.rs | 16 +++++ src/test/ui/nll/relate_tys/trait-hrtb.stderr | 8 +++ 12 files changed, 116 insertions(+), 26 deletions(-) create mode 100644 src/test/ui/nll/relate_tys/fn-subtype.rs create mode 100644 src/test/ui/nll/relate_tys/fn-subtype.stderr create mode 100644 src/test/ui/nll/relate_tys/trait-hrtb.rs create mode 100644 src/test/ui/nll/relate_tys/trait-hrtb.stderr diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index b06b63455ba4b..99297d7222b07 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -418,7 +418,9 @@ pub enum NLLRegionVariableOrigin { /// from a `for<'a> T` binder). Meant to represent "any region". Placeholder(ty::PlaceholderRegion), - Existential, + Existential { + was_placeholder: bool + }, } impl NLLRegionVariableOrigin { @@ -426,7 +428,7 @@ impl NLLRegionVariableOrigin { match self { NLLRegionVariableOrigin::FreeRegion => true, NLLRegionVariableOrigin::Placeholder(..) => true, - NLLRegionVariableOrigin::Existential => false, + NLLRegionVariableOrigin::Existential{ .. } => false, } } diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index 47e5c2b59ef36..4649f3f9567e7 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -93,7 +93,7 @@ pub trait TypeRelatingDelegate<'tcx> { /// we will invoke this method to instantiate `'a` with an /// inference variable (though `'b` would be instantiated first, /// as a placeholder). - fn next_existential_region_var(&mut self) -> ty::Region<'tcx>; + fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx>; /// Creates a new region variable representing a /// higher-ranked region that is instantiated universally. @@ -193,7 +193,7 @@ where let placeholder = ty::PlaceholderRegion { universe, name: br }; delegate.next_placeholder_region(placeholder) } else { - delegate.next_existential_region_var() + delegate.next_existential_region_var(true) } } }; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 6d3f2e566382f..826be88e36572 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -98,9 +98,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, body: &Body<'tcx>, from_region: RegionVid, + from_region_origin: NLLRegionVariableOrigin, target_test: impl Fn(RegionVid) -> bool, ) -> (ConstraintCategory, bool, Span) { - debug!("best_blame_constraint(from_region={:?})", from_region); + debug!("best_blame_constraint(from_region={:?}, from_region_origin={:?})", + from_region, from_region_origin); // Find all paths let (path, target_region) = @@ -153,19 +155,50 @@ impl<'tcx> RegionInferenceContext<'tcx> { // we still want to screen for an "interesting" point to // highlight (e.g., a call site or something). let target_scc = self.constraint_sccs.scc(target_region); - let best_choice = (0..path.len()).rev().find(|&i| { - let constraint = path[i]; + let mut range = 0..path.len(); + + let should_reverse = match from_region_origin { + NLLRegionVariableOrigin::FreeRegion + | NLLRegionVariableOrigin::Existential { was_placeholder: false } => { + true + } + NLLRegionVariableOrigin::Placeholder(_) + | NLLRegionVariableOrigin::Existential { was_placeholder: true } => { + false + } + }; + + let find_region = |i: &usize| { + let constraint = path[*i]; let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup); - match categorized_path[i].0 { - ConstraintCategory::OpaqueType | ConstraintCategory::Boring | - ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false, - ConstraintCategory::TypeAnnotation | ConstraintCategory::Return | - ConstraintCategory::Yield => true, - _ => constraint_sup_scc != target_scc, + if should_reverse { + match categorized_path[*i].0 { + ConstraintCategory::OpaqueType | ConstraintCategory::Boring | + ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false, + ConstraintCategory::TypeAnnotation | ConstraintCategory::Return | + ConstraintCategory::Yield => true, + _ => constraint_sup_scc != target_scc, + } + } else { + match categorized_path[*i].0 { + ConstraintCategory::OpaqueType | ConstraintCategory::Boring | + ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false, + _ => true + } } - }); + }; + + let best_choice = if should_reverse { + range.rev().find(find_region) + } else { + range.find(find_region) + }; + + debug!("best_blame_constraint: best_choice={:?} should_reverse={}", + best_choice, should_reverse); + if let Some(i) = best_choice { if let Some(next) = categorized_path.get(i + 1) { if categorized_path[i].0 == ConstraintCategory::Return @@ -297,12 +330,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, mir_def_id: DefId, fr: RegionVid, + fr_origin: NLLRegionVariableOrigin, outlived_fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> DiagnosticBuilder<'a> { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); - let (category, _, span) = self.best_blame_constraint(body, fr, |r| { + let (category, _, span) = self.best_blame_constraint(body, fr, fr_origin, |r| { self.provides_universal_region(r, fr, outlived_fr) }); @@ -709,6 +743,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let (category, from_closure, span) = self.best_blame_constraint( body, borrow_region, + NLLRegionVariableOrigin::FreeRegion, |r| self.provides_universal_region(r, borrow_region, outlived_region) ); @@ -768,11 +803,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, body: &Body<'tcx>, fr1: RegionVid, + fr1_origin: NLLRegionVariableOrigin, fr2: RegionVid, ) -> (ConstraintCategory, Span) { let (category, _, span) = self.best_blame_constraint( body, fr1, + fr1_origin, |r| self.provides_universal_region(r, fr1, fr2), ); (category, span) @@ -825,7 +862,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { universe1.cannot_name(placeholder.universe) } - NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential => false, + NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => { + false + } } } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 38df803539712..164f7b0627c2d 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -406,7 +406,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - NLLRegionVariableOrigin::Existential => { + NLLRegionVariableOrigin::Existential { .. } => { // For existential, regions, nothing to do. } } @@ -1348,7 +1348,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.check_bound_universal_region(infcx, body, mir_def_id, fr, placeholder); } - NLLRegionVariableOrigin::Existential => { + NLLRegionVariableOrigin::Existential { .. } => { // nothing to check here } } @@ -1461,7 +1461,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("check_universal_region: fr_minus={:?}", fr_minus); let blame_span_category = - self.find_outlives_blame_span(body, longer_fr, shorter_fr); + self.find_outlives_blame_span(body, longer_fr, + NLLRegionVariableOrigin::FreeRegion,shorter_fr); // Grow `shorter_fr` until we find some non-local regions. (We // always will.) We'll call them `shorter_fr+` -- they're ever @@ -1494,6 +1495,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { infcx, mir_def_id, longer_fr, + NLLRegionVariableOrigin::FreeRegion, shorter_fr, region_naming, ); @@ -1547,7 +1549,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { }; // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. - let (_, span) = self.find_outlives_blame_span(body, longer_fr, error_region); + let (_, span) = self.find_outlives_blame_span( + body, longer_fr, NLLRegionVariableOrigin::Placeholder(placeholder), error_region + ); // Obviously, this error message is far from satisfactory. // At present, though, it only appears in unit tests -- @@ -1608,7 +1612,7 @@ impl<'tcx> RegionDefinition<'tcx> { let origin = match rv_origin { RegionVariableOrigin::NLL(origin) => origin, - _ => NLLRegionVariableOrigin::Existential, + _ => NLLRegionVariableOrigin::Existential { was_placeholder: false }, }; Self { origin, universe, external_name: None } diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index cd13803875b5d..6e4db36bdce03 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -35,7 +35,7 @@ where infcx .tcx .fold_regions(value, &mut false, |_region, _depth| { - let origin = NLLRegionVariableOrigin::Existential; + let origin = NLLRegionVariableOrigin::Existential { was_placeholder: false }; infcx.next_nll_region_var(origin) }) } diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index 2549aa4fbff93..919fcdbd39ba0 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -66,9 +66,9 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { self.infcx.create_next_universe() } - fn next_existential_region_var(&mut self) -> ty::Region<'tcx> { + fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx> { if let Some(_) = &mut self.borrowck_context { - let origin = NLLRegionVariableOrigin::Existential; + let origin = NLLRegionVariableOrigin::Existential { was_placeholder }; self.infcx.next_nll_region_var(origin) } else { self.infcx.tcx.lifetimes.re_erased @@ -88,7 +88,9 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { self.infcx - .next_nll_region_var_in_universe(NLLRegionVariableOrigin::Existential, universe) + .next_nll_region_var_in_universe(NLLRegionVariableOrigin::Existential { + was_placeholder: false + }, universe) } fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) { diff --git a/src/librustc_traits/chalk_context/unify.rs b/src/librustc_traits/chalk_context/unify.rs index 1f9090324414b..5959c2ea5ca14 100644 --- a/src/librustc_traits/chalk_context/unify.rs +++ b/src/librustc_traits/chalk_context/unify.rs @@ -65,7 +65,7 @@ impl TypeRelatingDelegate<'tcx> for &mut ChalkTypeRelatingDelegate<'_, 'tcx> { self.infcx.create_next_universe() } - fn next_existential_region_var(&mut self) -> ty::Region<'tcx> { + fn next_existential_region_var(&mut self, _was_placeholder: bool) -> ty::Region<'tcx> { self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP)) } diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs index c42297ca68346..1bbef995fe885 100644 --- a/src/test/ui/hrtb/issue-30786.rs +++ b/src/test/ui/hrtb/issue-30786.rs @@ -114,4 +114,5 @@ fn main() { //[nll]~^ ERROR higher-ranked subtype error let count = filter.count(); // Assert that we still have a valid stream. //[nll]~^ ERROR higher-ranked subtype error + } diff --git a/src/test/ui/nll/relate_tys/fn-subtype.rs b/src/test/ui/nll/relate_tys/fn-subtype.rs new file mode 100644 index 0000000000000..ac00627ad00eb --- /dev/null +++ b/src/test/ui/nll/relate_tys/fn-subtype.rs @@ -0,0 +1,10 @@ +// Test that NLL produces correct spans for higher-ranked subtyping errors. +// +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +fn main() { + let x: fn(&'static ()) = |_| {}; + let y: for<'a> fn(&'a ()) = x; //~ ERROR higher-ranked subtype error +} diff --git a/src/test/ui/nll/relate_tys/fn-subtype.stderr b/src/test/ui/nll/relate_tys/fn-subtype.stderr new file mode 100644 index 0000000000000..b089b5aaa2535 --- /dev/null +++ b/src/test/ui/nll/relate_tys/fn-subtype.stderr @@ -0,0 +1,8 @@ +error: higher-ranked subtype error + --> $DIR/fn-subtype.rs:9:33 + | +LL | let y: for<'a> fn(&'a ()) = x; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/nll/relate_tys/trait-hrtb.rs b/src/test/ui/nll/relate_tys/trait-hrtb.rs new file mode 100644 index 0000000000000..80f31ca6b4782 --- /dev/null +++ b/src/test/ui/nll/relate_tys/trait-hrtb.rs @@ -0,0 +1,16 @@ +// Test that NLL generates proper error spans for trait HRTB errors +// +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +trait Foo<'a> {} + +fn make_foo<'a>() -> Box> { + panic!() +} + +fn main() { + let x: Box> = make_foo(); + let y: Box Foo<'a>> = x; //~ ERROR higher-ranked subtype error +} diff --git a/src/test/ui/nll/relate_tys/trait-hrtb.stderr b/src/test/ui/nll/relate_tys/trait-hrtb.stderr new file mode 100644 index 0000000000000..4df2f352522a3 --- /dev/null +++ b/src/test/ui/nll/relate_tys/trait-hrtb.stderr @@ -0,0 +1,8 @@ +error: higher-ranked subtype error + --> $DIR/trait-hrtb.rs:15:39 + | +LL | let y: Box Foo<'a>> = x; + | ^ + +error: aborting due to previous error + From 1caa6dc5461292611fcad75c8114c9fd35d7e923 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 1 Oct 2019 21:22:46 -0400 Subject: [PATCH 04/13] Fixup tests --- src/test/ui/hrtb/issue-30786.nll.stderr | 12 +++++++++--- src/test/ui/hrtb/issue-30786.rs | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr index 1cfd93e59d935..cd1272da2a66e 100644 --- a/src/test/ui/hrtb/issue-30786.nll.stderr +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -1,14 +1,20 @@ error: higher-ranked subtype error - --> $DIR/issue-30786.rs:113:18 + --> $DIR/issue-30786.rs:108:15 + | +LL | let map = source.map(|x: &_| x); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:114:18 | LL | let filter = map.filter(|x: &_| true); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/issue-30786.rs:115:17 + --> $DIR/issue-30786.rs:116:17 | LL | let count = filter.count(); // Assert that we still have a valid stream. | ^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs index 1bbef995fe885..34d6b19f602f7 100644 --- a/src/test/ui/hrtb/issue-30786.rs +++ b/src/test/ui/hrtb/issue-30786.rs @@ -106,7 +106,8 @@ impl StreamExt for T where for<'a> &'a mut T: Stream { } fn main() { let source = Repeat(10); let map = source.map(|x: &_| x); - //[migrate]~^ ERROR implementation of `Stream` is not general enough + //[nll]~^ ERROR higher-ranked subtype error + //[migrate]~^^ ERROR implementation of `Stream` is not general enough //[migrate]~| NOTE `Stream` would have to be implemented for the type `&'0 mut Map //[migrate]~| NOTE but `Stream` is actually implemented for the type `&'1 //[migrate]~| NOTE implementation of `Stream` is not general enough From 9c5a5c471aa9229b82bafa8ec18e55722d9ba8c3 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 1 Oct 2019 21:39:19 -0400 Subject: [PATCH 05/13] Rename to `was_placeholder` to `from_forall` --- src/librustc/infer/mod.rs | 12 +++++++++++- .../nll/region_infer/error_reporting/mod.rs | 4 ++-- .../borrow_check/nll/region_infer/mod.rs | 2 +- src/librustc_mir/borrow_check/nll/renumber.rs | 2 +- .../borrow_check/nll/type_check/relate_tys.rs | 6 +++--- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 99297d7222b07..35db82406ab46 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -419,7 +419,17 @@ pub enum NLLRegionVariableOrigin { Placeholder(ty::PlaceholderRegion), Existential { - was_placeholder: bool + /// If this is true, then this variable was created to represent a lifetime + /// bound in a `for` binder. For example, it might have been created to + /// represent the lifetime `'a` in a type like `for<'a> fn(&'a u32)`. + /// Such variables are created when we are trying to figure out if there + /// is any valid instantiation of `'a` that could fit into some scenario. + /// + /// This is used to inform error reporting: in the case that we are trying to + /// determine whether there is any valid instantiation of a `'a` variable that meets + /// some constraint C, we want to blame the "source" of that `for` type, + /// rather than blaming the source of the constraint C. + from_forall: bool }, } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 826be88e36572..fa02e2dd234ef 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -159,11 +159,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { let should_reverse = match from_region_origin { NLLRegionVariableOrigin::FreeRegion - | NLLRegionVariableOrigin::Existential { was_placeholder: false } => { + | NLLRegionVariableOrigin::Existential { from_forall: false } => { true } NLLRegionVariableOrigin::Placeholder(_) - | NLLRegionVariableOrigin::Existential { was_placeholder: true } => { + | NLLRegionVariableOrigin::Existential { from_forall: true } => { false } }; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 164f7b0627c2d..dbb810db555b4 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -1612,7 +1612,7 @@ impl<'tcx> RegionDefinition<'tcx> { let origin = match rv_origin { RegionVariableOrigin::NLL(origin) => origin, - _ => NLLRegionVariableOrigin::Existential { was_placeholder: false }, + _ => NLLRegionVariableOrigin::Existential { from_forall: false }, }; Self { origin, universe, external_name: None } diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index 6e4db36bdce03..315c369716e38 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -35,7 +35,7 @@ where infcx .tcx .fold_regions(value, &mut false, |_region, _depth| { - let origin = NLLRegionVariableOrigin::Existential { was_placeholder: false }; + let origin = NLLRegionVariableOrigin::Existential { from_forall: false }; infcx.next_nll_region_var(origin) }) } diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index 919fcdbd39ba0..80bf0478128c7 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -66,9 +66,9 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { self.infcx.create_next_universe() } - fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx> { + fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> { if let Some(_) = &mut self.borrowck_context { - let origin = NLLRegionVariableOrigin::Existential { was_placeholder }; + let origin = NLLRegionVariableOrigin::Existential { from_forall }; self.infcx.next_nll_region_var(origin) } else { self.infcx.tcx.lifetimes.re_erased @@ -89,7 +89,7 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { self.infcx .next_nll_region_var_in_universe(NLLRegionVariableOrigin::Existential { - was_placeholder: false + from_forall: false }, universe) } From ba54ef8110db16475b19ff9a1eaa46c696fa9584 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 1 Oct 2019 21:44:13 -0400 Subject: [PATCH 06/13] Add comments, rename variable --- .../nll/region_infer/error_reporting/mod.rs | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index fa02e2dd234ef..984da4432861e 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -157,7 +157,42 @@ impl<'tcx> RegionInferenceContext<'tcx> { let target_scc = self.constraint_sccs.scc(target_region); let mut range = 0..path.len(); - let should_reverse = match from_region_origin { + // As noted above, when reporting an error, there is typically a chain of constraints + // leading from some "source" region which must outlive some "target" region. + // In most cases, we prefer to "blame" the constraints closer to the target -- + // but there is one exception. When constraints arise from higher-ranked subtyping, + // we generally prefer to blame the source value, + // as the "target" in this case tends to be some type annotation that the user gave. + // Therefore, if we find that the region origin is some instantiation + // of a higher-ranked region, we start our search from the "source" point + // rather than the "target", and we also tweak a few other things. + // + // An example might be this bit of Rust code: + // + // ```rust + // let x: fn(&'static ()) = |_| {}; + // let y: for<'a> fn(&'a ()) = x; + // ``` + // + // In MIR, this will be converted into a combination of assignments and type ascriptions. + // In particular, the 'static is imposed through a type ascription: + // + // ```rust + // x = ...; + // AscribeUserType(x, fn(&'static ()) + // y = x; + // ``` + // + // We wind up ultimately with constraints like + // + // ```rust + // !a: 'temp1 // from the `y = x` statement + // 'temp1: 'temp2 + // 'temp2: 'static // from the AscribeUserType + // ``` + // + // and here we prefer to blame the source (the y = x statement). + let blame_source = match from_region_origin { NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { from_forall: false } => { true @@ -173,7 +208,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup); - if should_reverse { + if blame_source { match categorized_path[*i].0 { ConstraintCategory::OpaqueType | ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false, @@ -190,14 +225,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { } }; - let best_choice = if should_reverse { + let best_choice = if blame_source { range.rev().find(find_region) } else { range.find(find_region) }; - debug!("best_blame_constraint: best_choice={:?} should_reverse={}", - best_choice, should_reverse); + debug!("best_blame_constraint: best_choice={:?} blame_source={}", + best_choice, blame_source); if let Some(i) = best_choice { if let Some(next) = categorized_path.get(i + 1) { From 2537a8aa7a44d76b3345b98f394f6d2744f3a9cc Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 1 Oct 2019 15:17:50 +0100 Subject: [PATCH 07/13] syntax: improve parameter without type suggestions This commit improves the suggestions provided when function parameters do not have types: - A new suggestion is added for arbitrary self types, which suggests adding `self: ` before the type. - Existing suggestions are now provided when a `<` is found where a `:` was expected (previously only `,` and `)` or trait items), this gives suggestions in the case where the unnamed parameter type is generic in a free function. - The suggestion that a type name be provided (e.g. `fn foo(HashMap)` -> `fn foo(HashMap: TypeName)`) will no longer occur when a `<` was found instead of `:`. - The ident will not be used for recovery when a `<` was found instead of `:`. Signed-off-by: David Wood --- src/libsyntax/parse/diagnostics.rs | 32 ++++++++++++++----- src/libsyntax/parse/parser.rs | 1 + src/test/ui/anon-params-denied-2018.stderr | 8 +++++ src/test/ui/parser/pat-lt-bracket-2.stderr | 6 ++++ .../param-attrs-2018.stderr | 4 +++ src/test/ui/span/issue-34264.stderr | 6 ++++ .../ui/suggestions/issue-64252-self-type.rs | 14 ++++++++ .../suggestions/issue-64252-self-type.stderr | 30 +++++++++++++++++ 8 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/suggestions/issue-64252-self-type.rs create mode 100644 src/test/ui/suggestions/issue-64252-self-type.stderr diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index e8d7b7663ed52..4ad0bd06d99ae 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -1220,6 +1220,7 @@ impl<'a> Parser<'a> { err: &mut DiagnosticBuilder<'_>, pat: P, require_name: bool, + is_self_allowed: bool, is_trait_item: bool, ) -> Option { // If we find a pattern followed by an identifier, it could be an (incorrect) @@ -1241,14 +1242,27 @@ impl<'a> Parser<'a> { if require_name && ( is_trait_item || self.token == token::Comma || + self.token == token::Lt || self.token == token::CloseDelim(token::Paren) - ) { // `fn foo(a, b) {}` or `fn foo(usize, usize) {}` - err.span_suggestion( - pat.span, - "if this was a parameter name, give it a type", - format!("{}: TypeName", ident), - Applicability::HasPlaceholders, - ); + ) { // `fn foo(a, b) {}`, `fn foo(a, b) {}` or `fn foo(usize, usize) {}` + if is_self_allowed { + err.span_suggestion( + pat.span, + "if this is a `self` type, give it a parameter name", + format!("self: {}", ident), + Applicability::MaybeIncorrect, + ); + } + // Avoid suggesting that `fn foo(HashMap)` is fixed with a change to + // `fn foo(HashMap: TypeName)`. + if self.token != token::Lt { + err.span_suggestion( + pat.span, + "if this was a parameter name, give it a type", + format!("{}: TypeName", ident), + Applicability::HasPlaceholders, + ); + } err.span_suggestion( pat.span, "if this is a type, explicitly ignore the parameter name", @@ -1256,7 +1270,9 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)"); - return Some(ident); + + // Don't attempt to recover by using the `X` in `X` as the parameter name. + return if self.token == token::Lt { None } else { Some(ident) }; } } None diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 95f84d5cb3314..d4a6e9f6c6bc8 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1212,6 +1212,7 @@ impl<'a> Parser<'a> { &mut err, pat, is_name_required, + is_self_allowed, is_trait_item, ) { err.emit(); diff --git a/src/test/ui/anon-params-denied-2018.stderr b/src/test/ui/anon-params-denied-2018.stderr index a58998e4891e0..3fcf41a9a60a2 100644 --- a/src/test/ui/anon-params-denied-2018.stderr +++ b/src/test/ui/anon-params-denied-2018.stderr @@ -5,6 +5,10 @@ LL | fn foo(i32); | ^ expected one of `:`, `@`, or `|` here | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn foo(self: i32); + | ^^^^^^^^^ help: if this was a parameter name, give it a type | LL | fn foo(i32: TypeName); @@ -21,6 +25,10 @@ LL | fn bar_with_default_impl(String, String) {} | ^ expected one of `:`, `@`, or `|` here | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn bar_with_default_impl(self: String, String) {} + | ^^^^^^^^^^^^ help: if this was a parameter name, give it a type | LL | fn bar_with_default_impl(String: TypeName, String) {} diff --git a/src/test/ui/parser/pat-lt-bracket-2.stderr b/src/test/ui/parser/pat-lt-bracket-2.stderr index dbc8d0f5865c6..2191e31ad1ff2 100644 --- a/src/test/ui/parser/pat-lt-bracket-2.stderr +++ b/src/test/ui/parser/pat-lt-bracket-2.stderr @@ -3,6 +3,12 @@ error: expected one of `:`, `@`, or `|`, found `<` | LL | fn a(B<) {} | ^ expected one of `:`, `@`, or `|` here + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a type, explicitly ignore the parameter name + | +LL | fn a(_: B<) {} + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr index 9860e9805b2ed..e4248f3b974b9 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr @@ -5,6 +5,10 @@ LL | trait Trait2015 { fn foo(#[allow(C)] i32); } | ^ expected one of `:`, `@`, or `|` here | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | trait Trait2015 { fn foo(#[allow(C)] self: i32); } + | ^^^^^^^^^ help: if this was a parameter name, give it a type | LL | trait Trait2015 { fn foo(#[allow(C)] i32: TypeName); } diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr index cc0eccd37a26f..8d4a66f142d2c 100644 --- a/src/test/ui/span/issue-34264.stderr +++ b/src/test/ui/span/issue-34264.stderr @@ -3,6 +3,12 @@ error: expected one of `:`, `@`, or `|`, found `<` | LL | fn foo(Option, String) {} | ^ expected one of `:`, `@`, or `|` here + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a type, explicitly ignore the parameter name + | +LL | fn foo(_: Option, String) {} + | ^^^^^^^^^ error: expected one of `:`, `@`, or `|`, found `)` --> $DIR/issue-34264.rs:1:27 diff --git a/src/test/ui/suggestions/issue-64252-self-type.rs b/src/test/ui/suggestions/issue-64252-self-type.rs new file mode 100644 index 0000000000000..128d5e85c22c8 --- /dev/null +++ b/src/test/ui/suggestions/issue-64252-self-type.rs @@ -0,0 +1,14 @@ +// This test checks that a suggestion to add a `self: ` parameter name is provided +// to functions where this is applicable. + +pub fn foo(Box) { } +//~^ ERROR expected one of `:`, `@`, or `|`, found `<` + +struct Bar; + +impl Bar { + fn bar(Box) { } + //~^ ERROR expected one of `:`, `@`, or `|`, found `<` +} + +fn main() { } diff --git a/src/test/ui/suggestions/issue-64252-self-type.stderr b/src/test/ui/suggestions/issue-64252-self-type.stderr new file mode 100644 index 0000000000000..fa28a0d684e5e --- /dev/null +++ b/src/test/ui/suggestions/issue-64252-self-type.stderr @@ -0,0 +1,30 @@ +error: expected one of `:`, `@`, or `|`, found `<` + --> $DIR/issue-64252-self-type.rs:4:15 + | +LL | pub fn foo(Box) { } + | ^ expected one of `:`, `@`, or `|` here + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a type, explicitly ignore the parameter name + | +LL | pub fn foo(_: Box) { } + | ^^^^^^ + +error: expected one of `:`, `@`, or `|`, found `<` + --> $DIR/issue-64252-self-type.rs:10:15 + | +LL | fn bar(Box) { } + | ^ expected one of `:`, `@`, or `|` here + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn bar(self: Box) { } + | ^^^^^^^^^ +help: if this is a type, explicitly ignore the parameter name + | +LL | fn bar(_: Box) { } + | ^^^^^^ + +error: aborting due to 2 previous errors + From fb80e6c62ea5ae3a19b1b4076f636ced3e3b70d8 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 2 Oct 2019 08:17:28 -0400 Subject: [PATCH 08/13] BacktraceStatus: add Eq impl See discussion on #53487. --- src/libstd/backtrace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index 61c42a56071e6..9f400713a86d4 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -113,7 +113,7 @@ pub struct Backtrace { /// The current status of a backtrace, indicating whether it was captured or /// whether it is empty for some other reason. #[non_exhaustive] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub enum BacktraceStatus { /// Capturing a backtrace is not supported, likely because it's not /// implemented for the current platform. From 03455e47d818a1f8f65efb7c5af38276dc78a2a0 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 2 Oct 2019 11:02:14 -0300 Subject: [PATCH 09/13] Filter out RLS output directories on tidy runs --- src/tools/tidy/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index e01184e3658b5..337f9c4d6dbed 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -53,6 +53,9 @@ fn filter_dirs(path: &Path) -> bool { "src/tools/rls", "src/tools/rust-installer", "src/tools/rustfmt", + + // Filter RLS output directories + "target/rls", ]; skip.iter().any(|p| path.ends_with(p)) } From 5055d4b1c6d7dedaec015e4ba9d96c94b1d978fd Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Wed, 2 Oct 2019 11:29:12 -0400 Subject: [PATCH 10/13] Use zipped iterators in clone_from for LinkedList --- src/liballoc/collections/linked_list.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 998bcb87393b1..702df250999fb 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1203,8 +1203,8 @@ impl Clone for LinkedList { if self.len() > other.len() { self.split_off(other.len()); } - for elem in self.iter_mut() { - elem.clone_from(iter_other.next().unwrap()); + for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) { + elem.clone_from(elem_other); } if !iter_other.is_empty() { self.extend(iter_other.cloned()); From df203a297f6b8de283785a1a75bc89465ff168c6 Mon Sep 17 00:00:00 2001 From: AnthonyMikh Date: Wed, 2 Oct 2019 19:48:21 +0300 Subject: [PATCH 11/13] Compare primary with value instead of dropping it --- src/librustc_errors/emitter.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 0c7aa3582ac23..9aea46da68b1a 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1026,7 +1026,8 @@ impl EmitterWriter { children.iter() .map(|sub| self.get_multispan_max_line_num(&sub.span)) .max() - .unwrap_or(primary) + .unwrap_or(0) + .max(primary) } /// Adds a left margin to every line but the first, given a padding length and the label being From 864e6feaf857f4a48ace3eafd2003a32ac46602b Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Wed, 2 Oct 2019 15:18:31 -0400 Subject: [PATCH 12/13] Add test for LinkedList clone_from --- src/liballoc/collections/linked_list/tests.rs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index ecb5948f11b36..1001f6bba3b82 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -110,6 +110,49 @@ fn test_append() { check_links(&n); } +#[test] +fn test_clone_from() { + // Short cloned from long + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![8, 7, 6, 2, 3, 4, 5]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } + // Long cloned from short + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![6, 7, 8]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } + // Two equal length lists + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![9, 8, 1, 2, 3]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } +} + #[test] fn test_insert_prev() { let mut m = list_from(&[0, 2, 4, 6, 8]); From a180294f8bb5653c844c9ca4a457a7e4bc47e162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 2 Oct 2019 12:26:49 -0700 Subject: [PATCH 13/13] review comment --- src/librustc_typeck/check/wfcheck.rs | 2 +- .../const-param-type-depends-on-type-param.stderr | 2 +- src/test/ui/error-codes/E0392.stderr | 2 +- src/test/ui/inner-static-type-parameter.stderr | 2 +- src/test/ui/issues/issue-17904-2.stderr | 2 +- src/test/ui/issues/issue-20413.stderr | 2 +- src/test/ui/issues/issue-36299.stderr | 4 ++-- src/test/ui/issues/issue-36638.stderr | 2 +- src/test/ui/issues/issue-37534.stderr | 2 +- .../region-bounds-on-objects-and-type-parameters.stderr | 2 +- src/test/ui/self/self_type_keyword.stderr | 2 +- src/test/ui/variance/variance-regions-unused-direct.stderr | 4 ++-- .../ui/variance/variance-regions-unused-indirect.stderr | 4 ++-- src/test/ui/variance/variance-unused-region-param.stderr | 4 ++-- src/test/ui/variance/variance-unused-type-param.stderr | 6 +++--- 15 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 4dc5c6ca3074d..de1cc12aea37c 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -1001,7 +1001,7 @@ fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) { // Help is available only in presence of lang items. let msg = if let Some(def_id) = suggested_marker_id { format!( - "consider removing `{}`, refering to it in a field or using a marker such as `{}`", + "consider removing `{}`, refering to it in a field, or using a marker such as `{}`", param_name, tcx.def_path_str(def_id), ) diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index b72c68036d701..b50605ce0fe1a 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -18,7 +18,7 @@ error[E0392]: parameter `T` is never used LL | pub struct Dependent([(); X]); | ^ unused parameter | - = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0392.stderr b/src/test/ui/error-codes/E0392.stderr index d036cb5a07f3d..25cd9984052fa 100644 --- a/src/test/ui/error-codes/E0392.stderr +++ b/src/test/ui/error-codes/E0392.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `T` is never used LL | enum Foo { Bar } | ^ unused parameter | - = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to previous error diff --git a/src/test/ui/inner-static-type-parameter.stderr b/src/test/ui/inner-static-type-parameter.stderr index f945dbda7d78a..e8281b916f6fa 100644 --- a/src/test/ui/inner-static-type-parameter.stderr +++ b/src/test/ui/inner-static-type-parameter.stderr @@ -14,7 +14,7 @@ error[E0392]: parameter `T` is never used LL | enum Bar { What } | ^ unused parameter | - = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-17904-2.stderr b/src/test/ui/issues/issue-17904-2.stderr index b84922a4d8f6a..9d1d769158687 100644 --- a/src/test/ui/issues/issue-17904-2.stderr +++ b/src/test/ui/issues/issue-17904-2.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `T` is never used LL | struct Foo where T: Copy; | ^ unused parameter | - = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 1c3ff16a2071a..675b47a68ad2e 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `T` is never used LL | struct NoData; | ^ unused parameter | - = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` --> $DIR/issue-20413.rs:8:1 diff --git a/src/test/ui/issues/issue-36299.stderr b/src/test/ui/issues/issue-36299.stderr index 2a9e01421c06d..a092bab0e81f8 100644 --- a/src/test/ui/issues/issue-36299.stderr +++ b/src/test/ui/issues/issue-36299.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `'a` is never used LL | struct Foo<'a, A> {} | ^^ unused parameter | - = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `A` is never used --> $DIR/issue-36299.rs:1:16 @@ -12,7 +12,7 @@ error[E0392]: parameter `A` is never used LL | struct Foo<'a, A> {} | ^ unused parameter | - = help: consider removing `A`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `A`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-36638.stderr b/src/test/ui/issues/issue-36638.stderr index 68354b569ff51..699dba0e3f832 100644 --- a/src/test/ui/issues/issue-36638.stderr +++ b/src/test/ui/issues/issue-36638.stderr @@ -16,7 +16,7 @@ error[E0392]: parameter `Self` is never used LL | struct Foo(Self); | ^^^^ unused parameter | - = help: consider removing `Self`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `Self`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-37534.stderr b/src/test/ui/issues/issue-37534.stderr index baf75771b1367..a17fd623c1edd 100644 --- a/src/test/ui/issues/issue-37534.stderr +++ b/src/test/ui/issues/issue-37534.stderr @@ -20,7 +20,7 @@ error[E0392]: parameter `T` is never used LL | struct Foo { } | ^ unused parameter | - = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr index 5c0df850cba0b..57a987f703851 100644 --- a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr +++ b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr @@ -27,7 +27,7 @@ error[E0392]: parameter `'c` is never used LL | struct Foo<'a,'b,'c> { | ^^ unused parameter | - = help: consider removing `'c`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'c`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 3 previous errors diff --git a/src/test/ui/self/self_type_keyword.stderr b/src/test/ui/self/self_type_keyword.stderr index ee82d9da6229c..456077b65b83e 100644 --- a/src/test/ui/self/self_type_keyword.stderr +++ b/src/test/ui/self/self_type_keyword.stderr @@ -76,7 +76,7 @@ error[E0392]: parameter `'Self` is never used LL | struct Bar<'Self>; | ^^^^^ unused parameter | - = help: consider removing `'Self`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'Self`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 12 previous errors diff --git a/src/test/ui/variance/variance-regions-unused-direct.stderr b/src/test/ui/variance/variance-regions-unused-direct.stderr index 3d1158d4f799f..95fa841a75888 100644 --- a/src/test/ui/variance/variance-regions-unused-direct.stderr +++ b/src/test/ui/variance/variance-regions-unused-direct.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `'a` is never used LL | struct Bivariant<'a>; | ^^ unused parameter | - = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `'d` is never used --> $DIR/variance-regions-unused-direct.rs:7:19 @@ -12,7 +12,7 @@ error[E0392]: parameter `'d` is never used LL | struct Struct<'a, 'd> { | ^^ unused parameter | - = help: consider removing `'d`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'d`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/variance/variance-regions-unused-indirect.stderr b/src/test/ui/variance/variance-regions-unused-indirect.stderr index ccb2213f80b77..c90bad8edd478 100644 --- a/src/test/ui/variance/variance-regions-unused-indirect.stderr +++ b/src/test/ui/variance/variance-regions-unused-indirect.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `'a` is never used LL | enum Foo<'a> { | ^^ unused parameter | - = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `'a` is never used --> $DIR/variance-regions-unused-indirect.rs:7:10 @@ -12,7 +12,7 @@ error[E0392]: parameter `'a` is never used LL | enum Bar<'a> { | ^^ unused parameter | - = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/variance/variance-unused-region-param.stderr b/src/test/ui/variance/variance-unused-region-param.stderr index 228fe7483f6ff..bba301cdbfbcd 100644 --- a/src/test/ui/variance/variance-unused-region-param.stderr +++ b/src/test/ui/variance/variance-unused-region-param.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `'a` is never used LL | struct SomeStruct<'a> { x: u32 } | ^^ unused parameter | - = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `'a` is never used --> $DIR/variance-unused-region-param.rs:4:15 @@ -12,7 +12,7 @@ error[E0392]: parameter `'a` is never used LL | enum SomeEnum<'a> { Nothing } | ^^ unused parameter | - = help: consider removing `'a`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `'a`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 2 previous errors diff --git a/src/test/ui/variance/variance-unused-type-param.stderr b/src/test/ui/variance/variance-unused-type-param.stderr index 5acf8adfe8791..d2891015eb7f5 100644 --- a/src/test/ui/variance/variance-unused-type-param.stderr +++ b/src/test/ui/variance/variance-unused-type-param.stderr @@ -4,7 +4,7 @@ error[E0392]: parameter `A` is never used LL | struct SomeStruct { x: u32 } | ^ unused parameter | - = help: consider removing `A`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `A`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `A` is never used --> $DIR/variance-unused-type-param.rs:9:15 @@ -12,7 +12,7 @@ error[E0392]: parameter `A` is never used LL | enum SomeEnum { Nothing } | ^ unused parameter | - = help: consider removing `A`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `A`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error[E0392]: parameter `T` is never used --> $DIR/variance-unused-type-param.rs:13:15 @@ -20,7 +20,7 @@ error[E0392]: parameter `T` is never used LL | enum ListCell { | ^ unused parameter | - = help: consider removing `T`, refering to it in a field or using a marker such as `std::marker::PhantomData` + = help: consider removing `T`, refering to it in a field, or using a marker such as `std::marker::PhantomData` error: aborting due to 3 previous errors