diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2021-06-07 20:25:19 +0100 |
|---|---|---|
| committer | Rémy Rakic <remy.rakic+github@gmail.com> | 2021-08-15 09:11:01 +0200 |
| commit | d563a63788b143c84c9b40b68e940f436dd58e79 (patch) | |
| tree | a9128644268240f064ca75293aec64ba24e298c9 | |
| parent | 0c388b0261d7ac33089e5b10ab215653154a5293 (diff) | |
| download | rust-d563a63788b143c84c9b40b68e940f436dd58e79.tar.gz rust-d563a63788b143c84c9b40b68e940f436dd58e79.zip | |
Report nicer errors for HRTB NLL errors from queries
29 files changed, 473 insertions, 101 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 8c7a792eaa2..9b9ded5c6ba 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1111,7 +1111,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// etc) this is the root universe U0. For inference variables or /// placeholders, however, it will return the universe which which /// they are associated. - fn universe_of_region(&self, r: ty::Region<'tcx>) -> ty::UniverseIndex { + pub fn universe_of_region(&self, r: ty::Region<'tcx>) -> ty::UniverseIndex { self.inner.borrow_mut().unwrap_region_constraints().universe(r) } @@ -1289,6 +1289,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { op(inner.unwrap_region_constraints().data()) } + pub fn region_var_origin(&self, vid: ty::RegionVid) -> RegionVariableOrigin { + let mut inner = self.inner.borrow_mut(); + let inner = &mut *inner; + inner + .region_constraint_storage + .as_mut() + .expect("regions already resolved") + .with_log(&mut inner.undo_log) + .var_origin(vid) + } + /// Takes ownership of the list of variable regions. This implies /// that all the region constraints have already been taken, and /// hence that `resolve_regions_and_report_errors` can never be diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 7f4c33c5792..5adbfd469a4 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -445,6 +445,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.var_infos[vid].universe } + /// Returns the origin for the given variable. + pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { + self.var_infos[vid].origin + } + fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) { // cannot add constraints once regions are resolved debug!("RegionConstraintCollector: add_constraint({:?})", constraint); diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs index 5db20acf941..8400bcf12d7 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs @@ -1,9 +1,14 @@ +use rustc_errors::DiagnosticBuilder; use rustc_infer::infer::canonical::Canonical; -use rustc_infer::traits::ObligationCause; +use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; +use rustc_infer::infer::region_constraints::Constraint; +use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _}; +use rustc_infer::traits::{Normalized, Obligation, ObligationCause, TraitEngine, TraitEngineExt}; use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::{self, Ty, TypeFoldable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::query::type_op; +use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _}; use std::fmt; use std::rc::Rc; @@ -37,11 +42,10 @@ impl UniverseInfo<'tcx> { crate fn report_error( &self, mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, - _placeholder: ty::PlaceholderRegion, - _error_element: RegionElement, + placeholder: ty::PlaceholderRegion, + error_element: RegionElement, span: Span, ) { - // FIXME: improve this error message match self.0 { UniverseInfoInner::RelateTys { expected, found } => { let body_id = mbcx.infcx.tcx.hir().local_def_id_to_hir_id(mbcx.mir_def_id()); @@ -53,7 +57,13 @@ impl UniverseInfo<'tcx> { ); err.buffer(&mut mbcx.errors_buffer); } - UniverseInfoInner::TypeOp(_) | UniverseInfoInner::Other => { + UniverseInfoInner::TypeOp(ref type_op_info) => { + type_op_info.report_error(mbcx, placeholder, error_element, span); + } + UniverseInfoInner::Other => { + // FIXME: This error message isn't great, but it doesn't show + // up in the existing UI tests. Consider investigating this + // some more. mbcx.infcx .tcx .sess @@ -73,8 +83,8 @@ impl<'tcx> ToUniverseInfo<'tcx> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(PredicateQuery { - _canonical_query: self, - _base_universe: base_universe, + canonical_query: self, + base_universe, }))) } } @@ -84,8 +94,8 @@ impl<'tcx, T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx> ToUniverseInfo<'t { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(NormalizeQuery { - _canonical_query: self, - _base_universe: base_universe, + canonical_query: self, + base_universe, }))) } } @@ -109,23 +119,229 @@ impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::Custo #[allow(unused_lifetimes)] trait TypeOpInfo<'tcx> { - // TODO: Methods for rerunning type op and reporting an error + /// Returns an rrror to be reported if rerunning the type op fails to + /// recover the error's cause. + fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx>; + + fn base_universe(&self) -> ty::UniverseIndex; + + fn nice_error( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + placeholder_region: ty::Region<'tcx>, + error_region: Option<ty::Region<'tcx>>, + ) -> Option<DiagnosticBuilder<'tcx>>; + + fn report_error( + &self, + mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + placeholder: ty::PlaceholderRegion, + error_element: RegionElement, + span: Span, + ) { + let tcx = mbcx.infcx.tcx; + let base_universe = self.base_universe(); + + let adjusted_universe = if let Some(adjusted) = + placeholder.universe.as_u32().checked_sub(base_universe.as_u32()) + { + adjusted + } else { + self.fallback_error(tcx, span).buffer(&mut mbcx.errors_buffer); + return; + }; + + let placeholder_region = tcx.mk_region(ty::RePlaceholder(ty::Placeholder { + name: placeholder.name, + universe: adjusted_universe.into(), + })); + + let error_region = + if let RegionElement::PlaceholderRegion(error_placeholder) = error_element { + let adjusted_universe = + error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32()); + adjusted_universe.map(|adjusted| { + tcx.mk_region(ty::RePlaceholder(ty::Placeholder { + name: error_placeholder.name, + universe: adjusted.into(), + })) + }) + } else { + None + }; + + debug!(?placeholder_region); + + let nice_error = self.nice_error(tcx, span, placeholder_region, error_region); + + if let Some(nice_error) = nice_error { + nice_error.buffer(&mut mbcx.errors_buffer); + } else { + self.fallback_error(tcx, span).buffer(&mut mbcx.errors_buffer); + } + } } struct PredicateQuery<'tcx> { - _canonical_query: + canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>>, - _base_universe: ty::UniverseIndex, + base_universe: ty::UniverseIndex, } -impl TypeOpInfo<'tcx> for PredicateQuery<'tcx> {} +impl TypeOpInfo<'tcx> for PredicateQuery<'tcx> { + fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error"); + err.note(&format!("could not prove {}", self.canonical_query.value.value.predicate)); + err + } + + fn base_universe(&self) -> ty::UniverseIndex { + self.base_universe + } + + fn nice_error( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + placeholder_region: ty::Region<'tcx>, + error_region: Option<ty::Region<'tcx>>, + ) -> Option<DiagnosticBuilder<'tcx>> { + tcx.infer_ctxt().enter_with_canonical(span, &self.canonical_query, |ref infcx, key, _| { + let mut fulfill_cx = TraitEngine::new(tcx); + + let (param_env, prove_predicate) = key.into_parts(); + fulfill_cx.register_predicate_obligation( + infcx, + Obligation::new( + ObligationCause::dummy_with_span(span), + param_env, + prove_predicate.predicate, + ), + ); + + try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) + }) + } +} struct NormalizeQuery<'tcx, T> { - _canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>, - _base_universe: ty::UniverseIndex, + canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>, + base_universe: ty::UniverseIndex, } -impl<T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T> where - T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx +impl<T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T> +where + T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx, { + fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error"); + err.note(&format!("could not normalize `{}`", self.canonical_query.value.value.value)); + err + } + + fn base_universe(&self) -> ty::UniverseIndex { + self.base_universe + } + + fn nice_error( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + placeholder_region: ty::Region<'tcx>, + error_region: Option<ty::Region<'tcx>>, + ) -> Option<DiagnosticBuilder<'tcx>> { + tcx.infer_ctxt().enter_with_canonical(span, &self.canonical_query, |ref infcx, key, _| { + let mut fulfill_cx = TraitEngine::new(tcx); + + let mut selcx = SelectionContext::new(infcx); + let (param_env, value) = key.into_parts(); + + let Normalized { value: _, obligations } = rustc_trait_selection::traits::normalize( + &mut selcx, + param_env, + ObligationCause::dummy_with_span(span), + value.value, + ); + fulfill_cx.register_predicate_obligations(infcx, obligations); + + try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) + }) + } +} + +fn try_extract_error_from_fulfill_cx<'tcx>( + mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>, + infcx: &InferCtxt<'_, 'tcx>, + placeholder_region: ty::Region<'tcx>, + error_region: Option<ty::Region<'tcx>>, +) -> Option<DiagnosticBuilder<'tcx>> { + let tcx = infcx.tcx; + + // We generally shouldn't have here because the query was + // already run, but there's no point using `delay_span_bug` + // when we're going to emit an error here anyway. + let _errors = fulfill_cx.select_all_or_error(infcx).err().unwrap_or_else(Vec::new); + + let region_obligations = infcx.take_registered_region_obligations(); + debug!(?region_obligations); + + let (sub_region, cause) = infcx.with_region_constraints(|region_constraints| { + debug!(?region_constraints); + region_constraints.constraints.iter().find_map(|(constraint, cause)| { + match *constraint { + Constraint::RegSubReg(sub, sup) if sup == placeholder_region && sup != sub => { + Some((sub, cause.clone())) + } + // FIXME: Should this check the universe of the var? + Constraint::VarSubReg(vid, sup) if sup == placeholder_region => { + Some((tcx.mk_region(ty::ReVar(vid)), cause.clone())) + } + _ => None, + } + }) + })?; + + debug!(?sub_region, ?cause); + let nice_error = match (error_region, sub_region) { + (Some(error_region), &ty::ReVar(vid)) => NiceRegionError::new( + infcx, + RegionResolutionError::SubSupConflict( + vid, + infcx.region_var_origin(vid), + cause.clone(), + error_region, + cause.clone(), + placeholder_region, + ), + ), + (Some(error_region), _) => NiceRegionError::new( + infcx, + RegionResolutionError::ConcreteFailure(cause.clone(), error_region, placeholder_region), + ), + // Note universe here is wrong... + (None, &ty::ReVar(vid)) => NiceRegionError::new( + infcx, + RegionResolutionError::UpperBoundUniverseConflict( + vid, + infcx.region_var_origin(vid), + infcx.universe_of_region(sub_region), + cause.clone(), + placeholder_region, + ), + ), + (None, _) => NiceRegionError::new( + infcx, + RegionResolutionError::ConcreteFailure(cause.clone(), sub_region, placeholder_region), + ), + }; + nice_error.try_report_from_nll().or_else(|| { + if let SubregionOrigin::Subtype(trace) = cause { + Some( + infcx.report_and_explain_type_error(*trace, &TypeError::RegionsPlaceholderMismatch), + ) + } else { + None + } + }) } diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.nll.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.nll.stderr index 2e03986a9ed..59e27cd2e7d 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.nll.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.nll.stderr @@ -1,8 +1,12 @@ -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/higher-ranked-projection.rs:25:5 | LL | foo(()); - | ^^^^^^^ + | ^^^^^^^ one type is more general than the other + | + = note: expected type `&'a ()` + found reference `&()` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/generator/auto-trait-regions.nll.stderr b/src/test/ui/generator/auto-trait-regions.nll.stderr index 794369a8dc0..76970fb7872 100644 --- a/src/test/ui/generator/auto-trait-regions.nll.stderr +++ b/src/test/ui/generator/auto-trait-regions.nll.stderr @@ -24,17 +24,23 @@ LL | assert_foo(a); | = note: consider using a `let` binding to create a longer lived value -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:31:5 | LL | assert_foo(gen); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`... + = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef` -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:50:5 | LL | assert_foo(gen); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` error: aborting due to 4 previous errors diff --git a/src/test/ui/generator/resume-arg-late-bound.nll.stderr b/src/test/ui/generator/resume-arg-late-bound.nll.stderr index 7d712191924..25bc6afc550 100644 --- a/src/test/ui/generator/resume-arg-late-bound.nll.stderr +++ b/src/test/ui/generator/resume-arg-late-bound.nll.stderr @@ -1,8 +1,12 @@ -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/resume-arg-late-bound.rs:15:5 | LL | test(gen); - | ^^^^^^^^^ + | ^^^^^^^^^ one type is more general than the other + | + = note: expected type `for<'a> Generator<&'a mut bool>` + found type `Generator<&mut bool>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/higher-rank-trait-bounds/issue-59311.rs b/src/test/ui/higher-rank-trait-bounds/issue-59311.rs index 1e1241c7f83..d617571753c 100644 --- a/src/test/ui/higher-rank-trait-bounds/issue-59311.rs +++ b/src/test/ui/higher-rank-trait-bounds/issue-59311.rs @@ -14,7 +14,7 @@ pub fn crash<V>(v: &V) where for<'a> &'a V: T + 'static, { - v.t(|| {}); //~ ERROR: higher-ranked subtype error + v.t(|| {}); //~ ERROR: higher-ranked lifetime error } fn main() {} diff --git a/src/test/ui/higher-rank-trait-bounds/issue-59311.stderr b/src/test/ui/higher-rank-trait-bounds/issue-59311.stderr index ca632629267..c16c8206153 100644 --- a/src/test/ui/higher-rank-trait-bounds/issue-59311.stderr +++ b/src/test/ui/higher-rank-trait-bounds/issue-59311.stderr @@ -1,8 +1,10 @@ -error: higher-ranked subtype error +error: higher-ranked lifetime error --> $DIR/issue-59311.rs:17:9 | LL | v.t(|| {}); | ^^^^^ + | + = note: could not prove for<'a> &'a V: 'static error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.nll.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.nll.stderr index f290a93326f..46f5308dd87 100644 --- a/src/test/ui/hrtb/hrtb-conflate-regions.nll.stderr +++ b/src/test/ui/hrtb/hrtb-conflate-regions.nll.stderr @@ -1,14 +1,20 @@ -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/hrtb-conflate-regions.rs:27:10 | LL | fn b() { want_foo2::<SomeStruct>(); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/hrtb-conflate-regions.rs:27:10 | LL | fn b() { want_foo2::<SomeStruct>(); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.nll.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.nll.stderr index a4c3ffd1f6c..364b613fc77 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.nll.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.nll.stderr @@ -1,8 +1,11 @@ -error: higher-ranked subtype error +error: implementation of `Trait` is not general enough --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5 | LL | foo::<()>(); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ implementation of `Trait` is not general enough + | + = note: `()` must implement `Trait<for<'b> fn(&'b u32)>` + = note: ...but it actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.nll.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.nll.stderr index e2a399b2faa..cb2ce8a4116 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.nll.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.nll.stderr @@ -1,8 +1,11 @@ -error: higher-ranked subtype error +error: implementation of `Trait` is not general enough --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5 | LL | foo::<()>(); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ implementation of `Trait` is not general enough + | + = note: `()` must implement `Trait<for<'b> fn(Cell<&'b u32>)>` + = note: ...but it actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr b/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr index 8901a1b4681..a812282def9 100644 --- a/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr +++ b/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr @@ -1,8 +1,11 @@ -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/hrtb-just-for-static.rs:24:5 | LL | want_hrtb::<StaticInt>() - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`... + = note: ...but it actually implements `Foo<&'static isize>` error: lifetime may not live long enough --> $DIR/hrtb-just-for-static.rs:30:5 diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr index c3dd7949575..aefe3cdfd64 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr @@ -57,11 +57,14 @@ LL | foo_hrtb_bar_not(&mut t); | = help: consider replacing `'b` with `'static` -error: higher-ranked subtype error +error: implementation of `Bar` is not general enough --> $DIR/hrtb-perfect-forwarding.rs:43:5 | LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough + | + = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`... + = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1` warning: function cannot return without recursing --> $DIR/hrtb-perfect-forwarding.rs:48:1 diff --git a/src/test/ui/hrtb/issue-46989.nll.stderr b/src/test/ui/hrtb/issue-46989.nll.stderr index 6c127b92d97..309e1a676ed 100644 --- a/src/test/ui/hrtb/issue-46989.nll.stderr +++ b/src/test/ui/hrtb/issue-46989.nll.stderr @@ -1,8 +1,11 @@ -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/issue-46989.rs:38:5 | LL | assert_foo::<fn(&i32)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)` + = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-40000.nll.stderr b/src/test/ui/issues/issue-40000.nll.stderr index 4e2bde06a52..e6f0b5fbfba 100644 --- a/src/test/ui/issues/issue-40000.nll.stderr +++ b/src/test/ui/issues/issue-40000.nll.stderr @@ -1,14 +1,21 @@ -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/issue-40000.rs:6:9 | LL | foo(bar); - | ^^^ + | ^^^ one type is more general than the other + | + = note: expected trait object `dyn for<'r> Fn(&'r i32)` + found trait object `dyn Fn(&i32)` -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/issue-40000.rs:6:9 | LL | foo(bar); - | ^^^ + | ^^^ one type is more general than the other + | + = note: expected trait object `dyn for<'r> Fn(&'r i32)` + found trait object `dyn Fn(&i32)` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-54302-cases.nll.stderr b/src/test/ui/issues/issue-54302-cases.nll.stderr index 7463a3f286f..6e8b69c4bee 100644 --- a/src/test/ui/issues/issue-54302-cases.nll.stderr +++ b/src/test/ui/issues/issue-54302-cases.nll.stderr @@ -1,26 +1,38 @@ -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:63:5 | LL | <u32 as RefFoo<u32>>::ref_foo(a) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`... + = note: ...but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:69:5 | LL | <i32 as RefFoo<i32>>::ref_foo(a) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`... + = note: ...but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1` -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:75:5 | LL | <u64 as RefFoo<u64>>::ref_foo(a) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`... + = note: ...but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1` -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:81:5 | LL | <i64 as RefFoo<i64>>::ref_foo(a) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`... + = note: ...but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1` error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-55731.nll.stderr b/src/test/ui/issues/issue-55731.nll.stderr index dd38bb62912..97fd6678c99 100644 --- a/src/test/ui/issues/issue-55731.nll.stderr +++ b/src/test/ui/issues/issue-55731.nll.stderr @@ -1,11 +1,14 @@ -error: higher-ranked subtype error +error: implementation of `DistributedIteratorMulti` is not general enough --> $DIR/issue-55731.rs:48:5 | LL | / multi(Map { LL | | i: Cloned(PhantomData), LL | | f: X, LL | | }); - | |______^ + | |______^ implementation of `DistributedIteratorMulti` is not general enough + | + = note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`... + = note: ...but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57843.nll.stderr b/src/test/ui/issues/issue-57843.nll.stderr index 70d16cc9a1d..2ab49ec61cf 100644 --- a/src/test/ui/issues/issue-57843.nll.stderr +++ b/src/test/ui/issues/issue-57843.nll.stderr @@ -1,8 +1,11 @@ -error: higher-ranked subtype error +error: implementation of `FnOnce` is not general enough --> $DIR/issue-57843.rs:25:9 | LL | Foo(Box::new(|_| ())); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 bool)` must implement `FnOnce<(&'1 bool,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 bool,)>`, for some specific lifetime `'2` error: aborting due to previous error diff --git a/src/test/ui/lifetimes/issue-79187-2.nll.stderr b/src/test/ui/lifetimes/issue-79187-2.nll.stderr index 4970c579e7b..907b43d6762 100644 --- a/src/test/ui/lifetimes/issue-79187-2.nll.stderr +++ b/src/test/ui/lifetimes/issue-79187-2.nll.stderr @@ -16,29 +16,47 @@ LL | take_foo(|a: &i32| -> &i32 { a }); | | let's call the lifetime of this reference `'2` | let's call the lifetime of this reference `'1` -error: higher-ranked subtype error +error: implementation of `FnOnce` is not general enough --> $DIR/issue-79187-2.rs:8:5 | LL | take_foo(|a| a); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 i32) -> &i32` must implement `FnOnce<(&'1 i32,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 i32,)>`, for some specific lifetime `'2` -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/issue-79187-2.rs:8:5 | LL | take_foo(|a| a); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `for<'r> Fn<(&'r i32,)>` + found type `Fn<(&i32,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-79187-2.rs:8:14 + | +LL | take_foo(|a| a); + | ^^^^^ -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/issue-79187-2.rs:9:5 | LL | take_foo(|a: &i32| a); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected reference `&i32` + found reference `&i32` -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/issue-79187-2.rs:10:5 | LL | take_foo(|a: &i32| -> &i32 { a }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected reference `&i32` + found reference `&i32` error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lifetimes/issue-79187.nll.stderr b/src/test/ui/lifetimes/issue-79187.nll.stderr index aa8809dbc95..725b132e83a 100644 --- a/src/test/ui/lifetimes/issue-79187.nll.stderr +++ b/src/test/ui/lifetimes/issue-79187.nll.stderr @@ -1,14 +1,26 @@ -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/issue-79187.rs:5:5 | LL | thing(f); - | ^^^^^^^^ + | ^^^^^^^^ one type is more general than the other + | + = note: expected type `for<'r> FnOnce<(&'r u32,)>` + found type `FnOnce<(&u32,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-79187.rs:4:13 + | +LL | let f = |_| (); + | ^^^^^^ -error: higher-ranked subtype error +error: implementation of `FnOnce` is not general enough --> $DIR/issue-79187.rs:5:5 | LL | thing(f); - | ^^^^^^^^ + | ^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 u32)` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lub-glb/old-lub-glb-object.nll.stderr b/src/test/ui/lub-glb/old-lub-glb-object.nll.stderr index 51bf96f3233..ad14d6b7521 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.nll.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-object.nll.stderr @@ -1,14 +1,21 @@ -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/old-lub-glb-object.rs:10:14 | LL | _ => y, - | ^ + | ^ one type is more general than the other + | + = note: expected trait object `dyn for<'r, 's> Foo<&'r u8, &'s u8>` + found trait object `dyn for<'r> Foo<&'r u8, &'r u8>` -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/old-lub-glb-object.rs:10:14 | LL | _ => y, - | ^ + | ^ one type is more general than the other + | + = note: expected trait object `dyn for<'r, 's> Foo<&'r u8, &'s u8>` + found trait object `dyn for<'r> Foo<&'r u8, &'r u8>` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/closure-mismatch.nll.stderr b/src/test/ui/mismatched_types/closure-mismatch.nll.stderr index 745a61b866e..f29126e6afc 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.nll.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.nll.stderr @@ -1,14 +1,26 @@ -error: higher-ranked subtype error +error: implementation of `FnOnce` is not general enough --> $DIR/closure-mismatch.rs:8:5 | LL | baz(|_| ()); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/closure-mismatch.rs:8:5 | LL | baz(|_| ()); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `for<'r> Fn<(&'r (),)>` + found type `Fn<(&(),)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/closure-mismatch.rs:8:9 + | +LL | baz(|_| ()); + | ^^^^^^ error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs index 44dcd191d1b..37a01f28946 100644 --- a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs +++ b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs @@ -30,6 +30,6 @@ impl<T> Y for fn(T) { fn main() { let _x = <fn(&())>::make_f(); - //~^ higher-ranked subtype error - //~| higher-ranked subtype error + //~^ ERROR implementation of `Y` is not general enough + //~| ERROR implementation of `Y` is not general enough } diff --git a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr index 190b520c678..ed79c7df25e 100644 --- a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr +++ b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr @@ -1,14 +1,20 @@ -error: higher-ranked subtype error +error: implementation of `Y` is not general enough --> $DIR/impl-fn-ignore-binder-via-bottom.rs:32:14 | LL | let _x = <fn(&())>::make_f(); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ implementation of `Y` is not general enough + | + = note: `Y` would have to be implemented for the type `for<'r> fn(&'r ())` + = note: ...but `Y` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0` -error: higher-ranked subtype error +error: implementation of `Y` is not general enough --> $DIR/impl-fn-ignore-binder-via-bottom.rs:32:14 | LL | let _x = <fn(&())>::make_f(); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ implementation of `Y` is not general enough + | + = note: `Y` would have to be implemented for the type `for<'r> fn(&'r ())` + = note: ...but `Y` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/relate_tys/trait-hrtb.rs b/src/test/ui/nll/relate_tys/trait-hrtb.rs index 80f31ca6b47..2e94fc5c12d 100644 --- a/src/test/ui/nll/relate_tys/trait-hrtb.rs +++ b/src/test/ui/nll/relate_tys/trait-hrtb.rs @@ -12,5 +12,5 @@ fn make_foo<'a>() -> Box<dyn Foo<'a>> { fn main() { let x: Box<dyn Foo<'static>> = make_foo(); - let y: Box<dyn for<'a> Foo<'a>> = x; //~ ERROR higher-ranked subtype error + let y: Box<dyn for<'a> Foo<'a>> = x; //~ ERROR mismatched types [E0308] } diff --git a/src/test/ui/nll/relate_tys/trait-hrtb.stderr b/src/test/ui/nll/relate_tys/trait-hrtb.stderr index 4df2f352522..60a7f204446 100644 --- a/src/test/ui/nll/relate_tys/trait-hrtb.stderr +++ b/src/test/ui/nll/relate_tys/trait-hrtb.stderr @@ -1,8 +1,12 @@ -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/trait-hrtb.rs:15:39 | LL | let y: Box<dyn for<'a> Foo<'a>> = x; - | ^ + | ^ one type is more general than the other + | + = note: expected trait object `dyn for<'r> Foo<'r>` + found trait object `dyn Foo<'_>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc1623.nll.stderr b/src/test/ui/rfc1623.nll.stderr index a3d94679434..cc247bbcb11 100644 --- a/src/test/ui/rfc1623.nll.stderr +++ b/src/test/ui/rfc1623.nll.stderr @@ -19,7 +19,7 @@ LL | struct SomeStruct<'x, 'y, 'z: 'x> { = note: required because it appears within the type `&SomeStruct` = note: shared static variables must have a type that implements `Sync` -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/rfc1623.rs:21:35 | LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { @@ -29,9 +29,12 @@ LL | | bar: &Bar { bools: &[true, true] }, LL | | f: &id, LL | | LL | | }; - | |_^ + | |_^ one type is more general than the other + | + = note: expected type `for<'r, 's> Fn<(&'r Foo<'s>,)>` + found type `Fn<(&Foo<'_>,)>` -error: higher-ranked subtype error +error[E0308]: mismatched types --> $DIR/rfc1623.rs:21:35 | LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { @@ -41,9 +44,12 @@ LL | | bar: &Bar { bools: &[true, true] }, LL | | f: &id, LL | | LL | | }; - | |_^ + | |_^ one type is more general than the other + | + = note: expected type `for<'r, 's> Fn<(&'r Foo<'s>,)>` + found type `Fn<(&Foo<'_>,)>` -error: higher-ranked subtype error +error: implementation of `FnOnce` is not general enough --> $DIR/rfc1623.rs:21:35 | LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { @@ -53,9 +59,12 @@ LL | | bar: &Bar { bools: &[true, true] }, LL | | f: &id, LL | | LL | | }; - | |_^ + | |_^ implementation of `FnOnce` is not general enough + | + = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'_>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2` -error: higher-ranked subtype error +error: implementation of `FnOnce` is not general enough --> $DIR/rfc1623.rs:21:35 | LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { @@ -65,8 +74,12 @@ LL | | bar: &Bar { bools: &[true, true] }, LL | | f: &id, LL | | LL | | }; - | |_^ + | |_^ implementation of `FnOnce` is not general enough + | + = note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `FnOnce<(&Foo<'1>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&Foo<'2>,)>`, for some specific lifetime `'2` error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/unboxed-closures/issue-30906.nll.stderr b/src/test/ui/unboxed-closures/issue-30906.nll.stderr index 2db392e8b8b..147a2097473 100644 --- a/src/test/ui/unboxed-closures/issue-30906.nll.stderr +++ b/src/test/ui/unboxed-closures/issue-30906.nll.stderr @@ -1,8 +1,11 @@ -error: higher-ranked subtype error +error: implementation of `FnOnce` is not general enough --> $DIR/issue-30906.rs:18:5 | LL | test(Compose(f, |_| {})); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: `fn(&'2 str) -> T` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2` error: aborting due to previous error diff --git a/src/test/ui/where-clauses/where-for-self-2.nll.stderr b/src/test/ui/where-clauses/where-for-self-2.nll.stderr index d0c476dc6ec..f65db78fc89 100644 --- a/src/test/ui/where-clauses/where-for-self-2.nll.stderr +++ b/src/test/ui/where-clauses/where-for-self-2.nll.stderr @@ -1,8 +1,11 @@ -error: higher-ranked subtype error +error: implementation of `Bar` is not general enough --> $DIR/where-for-self-2.rs:23:5 | LL | foo(&X); - | ^^^^^^^ + | ^^^^^^^ implementation of `Bar` is not general enough + | + = note: `&'0 u32` must implement `Bar`, for any lifetime `'0`... + = note: ...but `Bar` is actually implemented for the type `&'static u32` error: aborting due to previous error |
