From d6ec0ae77742713800613685cbb5a28fd75e8662 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 3 Jun 2019 16:31:44 -0400 Subject: [PATCH] enforce and report pick-constraint errors The error message here is not great. --- src/librustc/infer/error_reporting/mod.rs | 22 ++- .../infer/lexical_region_resolve/mod.rs | 31 ++++ src/librustc/infer/mod.rs | 5 +- src/librustc/infer/opaque_types/mod.rs | 144 ++++++++++++------ src/librustc/infer/region_constraints/mod.rs | 19 ++- .../multiple-lifetimes/inverse-bounds.stderr | 22 ++- .../ordinary-bounds-pick-original.stderr | 48 ++++++ .../ordinary-bounds-pick-other.stderr | 25 +++ .../ordinary-bounds-unrelated.stderr | 13 +- .../ordinary-bounds-unsuited.stderr | 13 +- .../needs_least_region_or_bound.stderr | 46 +++++- 11 files changed, 323 insertions(+), 65 deletions(-) create mode 100644 src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.stderr create mode 100644 src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.stderr diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 65225163a25a..ead75dcd7980 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -53,6 +53,7 @@ use crate::infer::{self, SuppressRegionErrors}; use crate::hir; use crate::hir::def_id::DefId; use crate::hir::Node; +use crate::infer::opaque_types; use crate::middle::region; use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::ty::error::TypeError; @@ -375,6 +376,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); } } + + RegionResolutionError::PickConstraintFailure { + opaque_type_def_id, + hidden_ty, + pick_region, + span: _, + option_regions: _, + } => { + let hidden_ty = self.resolve_vars_if_possible(&hidden_ty); + opaque_types::report_unexpected_hidden_region( + self.tcx, + Some(region_scope_tree), + opaque_type_def_id, + hidden_ty, + pick_region, + ); + } } } } @@ -411,7 +429,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e { RegionResolutionError::GenericBoundFailure(..) => true, RegionResolutionError::ConcreteFailure(..) - | RegionResolutionError::SubSupConflict(..) => false, + | RegionResolutionError::SubSupConflict(..) + | RegionResolutionError::PickConstraintFailure { .. } => false, }; let mut errors = if errors.iter().all(|e| is_bound_failure(e)) { @@ -429,6 +448,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(), RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _) => rvo.span(), + RegionResolutionError::PickConstraintFailure { span, .. } => span, }); errors } diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 68371a0d6cbe..ac8db3c43365 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -1,5 +1,6 @@ //! Lexical region resolution. +use crate::hir::def_id::DefId; use crate::infer::region_constraints::Constraint; use crate::infer::region_constraints::GenericKind; use crate::infer::region_constraints::PickConstraint; @@ -22,6 +23,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::fmt; use std::u32; +use syntax_pos::Span; mod graphviz; @@ -81,6 +83,17 @@ pub enum RegionResolutionError<'tcx> { SubregionOrigin<'tcx>, Region<'tcx>, ), + + /// Indicates a failure of a `PickConstraint`. These arise during + /// impl trait processing explicitly -- basically, the impl trait's hidden type + /// included some region that it was not supposed to. + PickConstraintFailure { + span: Span, + opaque_type_def_id: DefId, + hidden_ty: Ty<'tcx>, + pick_region: Region<'tcx>, + option_regions: Vec>, + }, } struct RegionAndOrigin<'tcx> { @@ -550,6 +563,24 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + for pick_constraint in &self.data.pick_constraints { + let pick_region = var_data.normalize(self.tcx(), pick_constraint.pick_region); + let option_regions = pick_constraint + .option_regions + .iter() + .map(|&option_region| var_data.normalize(self.tcx(), option_region)); + if !option_regions.clone().any(|option_region| pick_region == option_region) { + let span = self.tcx().def_span(pick_constraint.opaque_type_def_id); + errors.push(RegionResolutionError::PickConstraintFailure { + span, + opaque_type_def_id: pick_constraint.opaque_type_def_id, + hidden_ty: pick_constraint.hidden_ty, + pick_region, + option_regions: option_regions.collect(), + }); + } + } + for verify in &self.data.verifys { debug!("collect_errors: verify={:?}", verify); let sub = var_data.normalize(self.tcx(), verify.region); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index ba42c7a54418..f6c6b5e93a79 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -909,13 +909,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// the set `regions`. pub fn pick_constraint( &self, - origin: SubregionOrigin<'tcx>, + opaque_type_def_id: DefId, + hidden_ty: Ty<'tcx>, region: ty::Region<'tcx>, in_regions: &Rc>>, ) { debug!("sub_regions({:?} <: {:?})", region, in_regions); self.borrow_region_constraints() - .pick_constraint(origin, region, in_regions); + .pick_constraint(opaque_type_def_id, hidden_ty, region, in_regions); } pub fn subtype_predicate( diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 733155ad501a..ca859045c6bb 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -3,6 +3,7 @@ use crate::hir::def_id::DefId; use crate::hir::Node; use crate::infer::outlives::free_region_map::FreeRegionRelations; use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind}; +use crate::middle::region; use crate::traits::{self, PredicateObligation}; use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::subst::{InternalSubsts, Kind, SubstsRef, UnpackedKind}; @@ -10,7 +11,6 @@ use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt}; use crate::util::nodemap::DefIdMap; use rustc_data_structures::fx::FxHashMap; use std::rc::Rc; -use syntax::source_map::Span; pub type OpaqueTypeMap<'tcx> = DefIdMap>; @@ -374,11 +374,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // we will create a "in bound" like `'r in // ['a, 'b, 'c]`, where `'a..'c` are the // regions that appear in the impl trait. - return self.generate_in_constraint( - span, + return self.generate_pick_constraint( concrete_ty, abstract_type_generics, opaque_defn, + def_id, ); } } @@ -399,14 +399,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// related, we would generate a constraint `'r in ['a, 'b, /// 'static]` for each region `'r` that appears in the hidden type /// (i.e., it must be equal to `'a`, `'b`, or `'static`). - fn generate_in_constraint( + fn generate_pick_constraint( &self, - span: Span, concrete_ty: Ty<'tcx>, abstract_type_generics: &ty::Generics, opaque_defn: &OpaqueTypeDecl<'tcx>, + opaque_type_def_id: DefId, ) { - let in_regions: Rc>> = Rc::new( + // Create the set of option regions: each region in the hidden + // type can be equal to any of the region parameters of the + // opaque type definition. + let option_regions: Rc>> = Rc::new( abstract_type_generics .params .iter() @@ -421,7 +424,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { tcx: self.tcx, - op: |r| self.pick_constraint(infer::CallReturn(span), r, &in_regions), + op: |r| self.pick_constraint( + opaque_type_def_id, + concrete_ty, + r, + &option_regions, + ), }); } @@ -445,7 +453,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// # Parameters /// /// - `def_id`, the `impl Trait` type - /// - `opaque_defn`, the opaque definition created in `instantiate_opaque_types` /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of /// `opaque_defn.concrete_ty` @@ -492,6 +499,83 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } +pub fn report_unexpected_hidden_region( + tcx: TyCtxt<'_, '_, 'tcx>, + region_scope_tree: Option<®ion::ScopeTree>, + opaque_type_def_id: DefId, + hidden_ty: Ty<'tcx>, + hidden_region: ty::Region<'tcx>, +) { + let span = tcx.def_span(opaque_type_def_id); + let mut err = struct_span_err!( + tcx.sess, + span, + E0700, + "hidden type for `impl Trait` captures lifetime that does not appear in bounds", + ); + + // Explain the region we are capturing. + if let ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty = hidden_region { + // Assuming regionck succeeded (*), we ought to always be + // capturing *some* region from the fn header, and hence it + // ought to be free. So under normal circumstances, we will go + // down this path which gives a decent human readable + // explanation. + // + // (*) if not, the `tainted_by_errors` flag would be set to + // true in any case, so we wouldn't be here at all. + tcx.note_and_explain_free_region( + &mut err, + &format!("hidden type `{}` captures ", hidden_ty), + hidden_region, + "", + ); + } else { + // Ugh. This is a painful case: the hidden region is not one + // that we can easily summarize or explain. This can happens + // in a case like + // `src/test/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`: + // + // ``` + // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> { + // if condition() { a } else { b } + // } + // ``` + // + // Here the captured lifetime is the intersection of `'a` and + // `'b`, which we can't quite express. This prticulararticular + // is kind of an unfortunate error anyway. + + if let Some(region_scope_tree) = region_scope_tree { + // If the `region_scope_tree` is available, this is being + // invoked from the "region inferencer error". We can at + // least report a really cryptic error for now. + tcx.note_and_explain_region( + region_scope_tree, + &mut err, + &format!("hidden type `{}` captures ", hidden_ty), + hidden_region, + "", + ); + } else { + // If the `region_scope_tree` is *unavailable*, this is + // being invoked by the code that comes *after* region + // inferencing. This is a bug, as the region inferencer + // ought to have noticed the failed constraint and invoked + // error reporting, which in turn should have prevented us + // from getting trying to infer the hidden type + // completely. + span_bug!( + span, + "hidden type captures unexpected lifetime `{:?}` but no region inference failure", + hidden_region, + ); + } + } + + err.emit(); +} + // Visitor that requires that (almost) all regions in the type visited outlive // `least_region`. We cannot use `push_outlives_components` because regions in // closure signatures are not included in their outlives components. We need to @@ -640,45 +724,13 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { None => { if !self.map_missing_regions_to_empty && !self.tainted_by_errors { if let Some(hidden_ty) = self.hidden_ty.take() { - let span = self.tcx.def_span(self.opaque_type_def_id); - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0700, - "hidden type for `impl Trait` captures lifetime that \ - does not appear in bounds", + report_unexpected_hidden_region( + self.tcx, + None, + self.opaque_type_def_id, + hidden_ty, + r, ); - - // Explain the region we are capturing. - match r { - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty => { - // Assuming regionck succeeded (*), we - // ought to always be capturing *some* region - // from the fn header, and hence it ought to - // be free. So under normal circumstances, we will - // go down this path which gives a decent human readable - // explanation. - // - // (*) if not, the `tainted_by_errors` - // flag would be set to true in any - // case, so we wouldn't be here at - // all. - self.tcx.note_and_explain_free_region( - &mut err, - &format!("hidden type `{}` captures ", hidden_ty), - r, - "", - ); - } - _ => { - // This case should not happen: it indicates that regionck - // failed to enforce an "in constraint". - err.note(&format!("hidden type `{}` captures `{:?}`", hidden_ty, r)); - err.note(&format!("this is likely a bug in the compiler, please file an issue on github")); - } - } - - err.emit(); } } self.tcx.lifetimes.re_empty diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index fa64690ded47..1340fb807ee2 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -9,6 +9,7 @@ use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::unify as ut; +use crate::hir::def_id::DefId; use crate::ty::ReStatic; use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{ReLateBound, ReVar}; @@ -151,8 +152,16 @@ impl Constraint<'_> { /// ``` #[derive(Debug, Clone)] pub struct PickConstraint<'tcx> { - pub origin: SubregionOrigin<'tcx>, + /// the def-id of the opaque type causing this constraint: used for error reporting + pub opaque_type_def_id: DefId, + + /// the hidden type in which `pick_region` appears: used for error reporting + pub hidden_ty: Ty<'tcx>, + + /// the region R0 pub pick_region: Region<'tcx>, + + /// the options O1..On pub option_regions: Rc>>, } @@ -664,7 +673,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> { pub fn pick_constraint( &mut self, - origin: SubregionOrigin<'tcx>, + opaque_type_def_id: DefId, + hidden_ty: Ty<'tcx>, pick_region: ty::Region<'tcx>, option_regions: &Rc>>, ) { @@ -675,7 +685,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } self.data.pick_constraints.push(PickConstraint { - origin, pick_region, option_regions: option_regions.clone() + opaque_type_def_id, + hidden_ty, + pick_region, + option_regions: option_regions.clone() }); } diff --git a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr index 182d07733ffd..13fb6f5d73e0 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr @@ -1,15 +1,25 @@ -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds +error: impl Trait captures unexpected lifetime --> $DIR/inverse-bounds.rs:15:70 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e> - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ only lifetimes that appear in the impl Trait bounds may be captured | -note: hidden type `Invert<'c>` captures the lifetime 'c as defined on the function body at 15:25 - --> $DIR/inverse-bounds.rs:15:25 +note: hidden type captures the lifetime 'd as defined on the function body at 15:29 + --> $DIR/inverse-bounds.rs:15:29 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e> - | ^^ + | ^^ +note: hidden type would be allowed to capture the lifetime 'd as defined on the function body at 15:29 + --> $DIR/inverse-bounds.rs:15:29 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e> + | ^^ +note: hidden type would be allowed to capture the lifetime 'e as defined on the function body at 15:33 + --> $DIR/inverse-bounds.rs:15:33 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e> + | ^^ + = note: hidden type would be allowed to capture the static lifetime error: aborting due to previous error -For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.stderr new file mode 100644 index 000000000000..43e92ac68272 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.stderr @@ -0,0 +1,48 @@ +error: impl Trait captures unexpected lifetime + --> $DIR/ordinary-bounds-pick-original.rs:11:50 + | +LL | fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^^^^^^^^^^^^^^^^^ only lifetimes that appear in the impl Trait bounds may be captured + | +note: hidden type captures the lifetime 'a as defined on the function body at 11:17 + --> $DIR/ordinary-bounds-pick-original.rs:11:17 + | +LL | fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^ +note: hidden type would be allowed to capture the lifetime 'a as defined on the function body at 11:17 + --> $DIR/ordinary-bounds-pick-original.rs:11:17 + | +LL | fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^ +note: hidden type would be allowed to capture the lifetime 'b as defined on the function body at 11:21 + --> $DIR/ordinary-bounds-pick-original.rs:11:21 + | +LL | fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^ + = note: hidden type would be allowed to capture the static lifetime + +error: impl Trait captures unexpected lifetime + --> $DIR/ordinary-bounds-pick-original.rs:11:50 + | +LL | fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^^^^^^^^^^^^^^^^^ only lifetimes that appear in the impl Trait bounds may be captured + | +note: hidden type captures the lifetime 'b as defined on the function body at 11:21 + --> $DIR/ordinary-bounds-pick-original.rs:11:21 + | +LL | fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^ +note: hidden type would be allowed to capture the lifetime 'a as defined on the function body at 11:17 + --> $DIR/ordinary-bounds-pick-original.rs:11:17 + | +LL | fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^ +note: hidden type would be allowed to capture the lifetime 'b as defined on the function body at 11:21 + --> $DIR/ordinary-bounds-pick-original.rs:11:21 + | +LL | fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^ + = note: hidden type would be allowed to capture the static lifetime + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.stderr new file mode 100644 index 000000000000..ff09f9471079 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.stderr @@ -0,0 +1,25 @@ +error: impl Trait captures unexpected lifetime + --> $DIR/ordinary-bounds-pick-other.rs:18:74 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + | ^^^^^^^^^^^^^^^^^^ only lifetimes that appear in the impl Trait bounds may be captured + | +note: hidden type captures the lifetime 'e as defined on the function body at 18:33 + --> $DIR/ordinary-bounds-pick-other.rs:18:33 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + | ^^ +note: hidden type would be allowed to capture the lifetime 'd as defined on the function body at 18:29 + --> $DIR/ordinary-bounds-pick-other.rs:18:29 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + | ^^ +note: hidden type would be allowed to capture the lifetime 'e as defined on the function body at 18:33 + --> $DIR/ordinary-bounds-pick-other.rs:18:33 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + | ^^ + = note: hidden type would be allowed to capture the static lifetime + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr index 9b505c66dc11..cd2d46ac1821 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr @@ -4,8 +4,17 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> | ^^^^^^^^^^^^^^^^^^ | - = note: hidden type `Ordinary<'_>` captures `ReScope(CallSite(24))` - = note: this is likely a bug in the compiler, please file an issue on github +note: hidden type `Ordinary<'_>` captures the scope of call-site for function at 23:1 + --> $DIR/ordinary-bounds-unrelated.rs:23:1 + | +LL | / { +LL | | // Hidden type `Ordinary<'0>` with constraints: +LL | | // +LL | | // ``` +... | +LL | | if condition() { a } else { b } +LL | | } + | |_^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr index d258948c7735..59ce93fa78b6 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr @@ -4,8 +4,17 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> | ^^^^^^^^^^^^^^^^^^ | - = note: hidden type `Ordinary<'_>` captures `ReScope(CallSite(24))` - = note: this is likely a bug in the compiler, please file an issue on github +note: hidden type `Ordinary<'_>` captures the scope of call-site for function at 22:1 + --> $DIR/ordinary-bounds-unsuited.rs:22:1 + | +LL | / { +LL | | // We return a value: +LL | | // +LL | | // ``` +... | +LL | | if condition() { a } else { b } +LL | | } + | |_^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/needs_least_region_or_bound.stderr b/src/test/ui/impl-trait/needs_least_region_or_bound.stderr index f1b4d9c58f39..9b9196a213da 100644 --- a/src/test/ui/impl-trait/needs_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/needs_least_region_or_bound.stderr @@ -1,8 +1,48 @@ -error: ambiguous lifetime bound in `impl Trait` +error: impl Trait captures unexpected lifetime --> $DIR/needs_least_region_or_bound.rs:6:55 | LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only lifetimes that appear in the impl Trait bounds may be captured + | +note: hidden type captures the lifetime 'a as defined on the function body at 6:20 + --> $DIR/needs_least_region_or_bound.rs:6:20 + | +LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + | ^^ +note: hidden type would be allowed to capture the lifetime 'a as defined on the function body at 6:20 + --> $DIR/needs_least_region_or_bound.rs:6:20 + | +LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + | ^^ +note: hidden type would be allowed to capture the lifetime 'b as defined on the function body at 6:24 + --> $DIR/needs_least_region_or_bound.rs:6:24 + | +LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + | ^^ + = note: hidden type would be allowed to capture the static lifetime -error: aborting due to previous error +error: impl Trait captures unexpected lifetime + --> $DIR/needs_least_region_or_bound.rs:6:55 + | +LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only lifetimes that appear in the impl Trait bounds may be captured + | +note: hidden type captures the lifetime 'b as defined on the function body at 6:24 + --> $DIR/needs_least_region_or_bound.rs:6:24 + | +LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + | ^^ +note: hidden type would be allowed to capture the lifetime 'a as defined on the function body at 6:20 + --> $DIR/needs_least_region_or_bound.rs:6:20 + | +LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + | ^^ +note: hidden type would be allowed to capture the lifetime 'b as defined on the function body at 6:24 + --> $DIR/needs_least_region_or_bound.rs:6:24 + | +LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + | ^^ + = note: hidden type would be allowed to capture the static lifetime + +error: aborting due to 2 previous errors