diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 21c26af8178ff..22bb3a29425ee 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -689,6 +689,16 @@ impl<'tcx> RegionInferenceContext<'tcx> { // them down. let mut choice_regions: Vec = choice_regions.to_vec(); + // Convert to the SCC representative: sometimes we have inference + // variables in the member constraint that wind up equated with + // universal regions. The scc representative is the minimal numbered + // one from the corresponding scc so it will be the universal region + // if one exists. + for c_r in &mut choice_regions { + let scc = self.constraint_sccs.scc(*c_r); + *c_r = self.scc_representatives[scc]; + } + // The 'member region' in a member constraint is part of the // hidden type, which must be in the root universe. Therefore, // it cannot have any placeholders in its value. diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 70c74940d6235..f71cf09ecf630 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -1,20 +1,18 @@ use rustc_data_structures::frozen::Frozen; use rustc_data_structures::transitive_relation::TransitiveRelation; use rustc_infer::infer::canonical::QueryRegionConstraints; -use rustc_infer::infer::free_regions::FreeRegionRelations; use rustc_infer::infer::outlives; use rustc_infer::infer::region_constraints::GenericKind; use rustc_infer::infer::InferCtxt; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::query::OutlivesBound; -use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt}; +use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; use std::rc::Rc; use type_op::TypeOpOutput; use crate::{ - nll::ToRegionVid, type_check::constraint_conversion, type_check::{Locations, MirTypeckRegionConstraints}, universal_regions::UniversalRegions, @@ -383,21 +381,3 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { } } } - -/// This trait is used by the `impl-trait` constraint code to abstract -/// over the `FreeRegionMap` from lexical regions and -/// `UniversalRegions` (from NLL)`. -impl<'tcx> FreeRegionRelations<'tcx> for UniversalRegionRelations<'tcx> { - fn sub_free_regions( - &self, - _tcx: TyCtxt<'tcx>, - shorter: ty::Region<'tcx>, - longer: ty::Region<'tcx>, - ) -> bool { - let shorter = shorter.to_region_vid(); - assert!(self.universal_regions.is_universal_region(shorter)); - let longer = longer.to_region_vid(); - assert!(self.universal_regions.is_universal_region(longer)); - self.outlives(longer, shorter) - } -} diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 7bf119863fdc7..7e69e710d6868 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -36,7 +36,7 @@ use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_trait_selection::infer::InferCtxtExt as _; -use rustc_trait_selection::opaque_types::{GenerateMemberConstraints, InferCtxtExt}; +use rustc_trait_selection::opaque_types::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::query::type_op; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; @@ -185,7 +185,6 @@ pub(crate) fn type_check<'mir, 'tcx>( ®ion_bound_pairs, implicit_region_bound, &mut borrowck_context, - &universal_region_relations, |mut cx| { cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output); liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table); @@ -253,15 +252,7 @@ pub(crate) fn type_check<'mir, 'tcx>( } #[instrument( - skip( - infcx, - body, - promoted, - region_bound_pairs, - borrowck_context, - universal_region_relations, - extra - ), + skip(infcx, body, promoted, region_bound_pairs, borrowck_context, extra), level = "debug" )] fn type_check_internal<'a, 'tcx, R>( @@ -272,7 +263,6 @@ fn type_check_internal<'a, 'tcx, R>( region_bound_pairs: &'a RegionBoundPairs<'tcx>, implicit_region_bound: ty::Region<'tcx>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, - universal_region_relations: &'a UniversalRegionRelations<'tcx>, extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R, ) -> R { let mut checker = TypeChecker::new( @@ -282,7 +272,6 @@ fn type_check_internal<'a, 'tcx, R>( region_bound_pairs, implicit_region_bound, borrowck_context, - universal_region_relations, ); let errors_reported = { let mut verifier = TypeVerifier::new(&mut checker, body, promoted); @@ -901,7 +890,6 @@ struct TypeChecker<'a, 'tcx> { implicit_region_bound: ty::Region<'tcx>, reported_errors: FxHashSet<(Ty<'tcx>, Span)>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, - universal_region_relations: &'a UniversalRegionRelations<'tcx>, } struct BorrowCheckContext<'a, 'tcx> { @@ -1050,7 +1038,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { region_bound_pairs: &'a RegionBoundPairs<'tcx>, implicit_region_bound: ty::Region<'tcx>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, - universal_region_relations: &'a UniversalRegionRelations<'tcx>, ) -> Self { let mut checker = Self { infcx, @@ -1062,7 +1049,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { implicit_region_bound, borrowck_context, reported_errors: Default::default(), - universal_region_relations, }; checker.check_user_type_annotations(); checker @@ -1322,8 +1308,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ), )?; - let universal_region_relations = self.universal_region_relations; - // Finally, if we instantiated the anon types successfully, we // have to solve any bounds (e.g., `-> impl Iterator` needs to // prove that `T: Iterator` where `T` is the type we @@ -1335,12 +1319,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::OpaqueType, CustomTypeOp::new( |infcx| { - infcx.constrain_opaque_type( - opaque_type_key, - &opaque_decl, - GenerateMemberConstraints::IfNoStaticBound, - universal_region_relations, - ); + infcx.constrain_opaque_type(opaque_type_key, &opaque_decl); Ok(InferOk { value: (), obligations: vec![] }) }, || "opaque_type_map".to_string(), diff --git a/compiler/rustc_error_codes/src/error_codes/E0482.md b/compiler/rustc_error_codes/src/error_codes/E0482.md index 58ebf43cc98ce..ad363816e1890 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0482.md +++ b/compiler/rustc_error_codes/src/error_codes/E0482.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + A lifetime of a returned value does not outlive the function call. Erroneous code example: -```compile_fail,E0482 +```compile_fail,E0700 fn prefix<'a>( words: impl Iterator ) -> impl Iterator { // error! @@ -41,7 +43,7 @@ fn prefix( A similar lifetime problem might arise when returning closures: -```compile_fail,E0482 +```compile_fail,E0700 fn foo( x: &mut Vec ) -> impl FnMut(&mut Vec) -> &[i32] { // error! diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 126c25f0c38c7..2173ff1f9ab03 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -386,21 +386,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit(); } - - RegionResolutionError::MemberConstraintFailure { - hidden_ty, - member_region, - span, - } => { - let hidden_ty = self.resolve_vars_if_possible(hidden_ty); - unexpected_hidden_region_diagnostic( - self.tcx, - span, - hidden_ty, - member_region, - ) - .emit(); - } } } } @@ -438,8 +423,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { RegionResolutionError::GenericBoundFailure(..) => true, RegionResolutionError::ConcreteFailure(..) | RegionResolutionError::SubSupConflict(..) - | RegionResolutionError::UpperBoundUniverseConflict(..) - | RegionResolutionError::MemberConstraintFailure { .. } => false, + | RegionResolutionError::UpperBoundUniverseConflict(..) => false, }; let mut errors = if errors.iter().all(|e| is_bound_failure(e)) { @@ -454,7 +438,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _) => rvo.span(), RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => rvo.span(), - RegionResolutionError::MemberConstraintFailure { span, .. } => span, }); errors } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 5f99a23f86e88..167a8893a11c8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -53,9 +53,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::RelateObjectBound(span) => { label_or_note(span, "...so that it can be closed over into an object"); } - infer::CallReturn(span) => { - label_or_note(span, "...so that return value is valid for the call"); - } infer::DataBorrowed(ty, span) => { label_or_note( span, @@ -281,23 +278,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); err } - infer::CallReturn(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0482, - "lifetime of return value does not outlive the function call" - ); - note_and_explain_region( - self.tcx, - &mut err, - "the return value is only valid for ", - sup, - "", - None, - ); - err - } infer::DataBorrowed(ty, span) => { let mut err = struct_span_err!( self.tcx.sess, diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs index 728dc2de37031..4814b65e320ab 100644 --- a/compiler/rustc_infer/src/infer/free_regions.rs +++ b/compiler/rustc_infer/src/infer/free_regions.rs @@ -66,8 +66,6 @@ impl<'tcx> FreeRegionMap<'tcx> { /// follows. If we know that `r_b: 'static`, then this function /// will return true, even though we don't know anything that /// directly relates `r_a` and `r_b`. - /// - /// Also available through the `FreeRegionRelations` trait below. pub fn sub_free_regions( &self, tcx: TyCtxt<'tcx>, @@ -131,27 +129,6 @@ impl<'tcx> FreeRegionMap<'tcx> { } } -/// The NLL region handling code represents free region relations in a -/// slightly different way; this trait allows functions to be abstract -/// over which version is in use. -pub trait FreeRegionRelations<'tcx> { - /// Tests whether `r_a <= r_b`. Both must be free regions or - /// `'static`. - fn sub_free_regions( - &self, - tcx: TyCtxt<'tcx>, - shorter: ty::Region<'tcx>, - longer: ty::Region<'tcx>, - ) -> bool; -} - -impl<'tcx> FreeRegionRelations<'tcx> for FreeRegionMap<'tcx> { - fn sub_free_regions(&self, tcx: TyCtxt<'tcx>, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool { - // invoke the "inherent method" - self.sub_free_regions(tcx, r_a, r_b) - } -} - impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> { type Lifted = FreeRegionMap<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option> { diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 869fd225d5114..4c9dcab26b14f 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -2,7 +2,6 @@ use crate::infer::region_constraints::Constraint; use crate::infer::region_constraints::GenericKind; -use crate::infer::region_constraints::MemberConstraint; use crate::infer::region_constraints::RegionConstraintData; use crate::infer::region_constraints::VarInfos; use crate::infer::region_constraints::VerifyBound; @@ -20,7 +19,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic}; use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar}; use rustc_middle::ty::{Region, RegionVid}; -use rustc_span::Span; use std::fmt; /// This function performs lexical region resolution given a complete @@ -28,13 +26,13 @@ use std::fmt; /// iteration to find region values which satisfy all constraints, /// assuming such values can be found. It returns the final values of /// all the variables as well as a set of errors that must be reported. +#[instrument(level = "debug", skip(region_rels, var_infos, data))] pub fn resolve<'tcx>( region_rels: &RegionRelations<'_, 'tcx>, var_infos: VarInfos, data: RegionConstraintData<'tcx>, mode: RegionckMode, ) -> (LexicalRegionResolutions<'tcx>, Vec>) { - debug!("RegionConstraintData: resolve_regions()"); let mut errors = vec![]; let mut resolver = LexicalResolver { region_rels, var_infos, data }; match mode { @@ -109,11 +107,6 @@ pub enum RegionResolutionError<'tcx> { SubregionOrigin<'tcx>, // cause of the constraint Region<'tcx>, // the placeholder `'b` ), - - /// Indicates a failure of a `MemberConstraint`. These arise during - /// impl trait processing explicitly -- basically, the impl trait's hidden type - /// included some region that it was not supposed to. - MemberConstraintFailure { span: Span, hidden_ty: Ty<'tcx>, member_region: Region<'tcx> }, } struct RegionAndOrigin<'tcx> { @@ -150,12 +143,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { let graph = self.construct_graph(); self.expand_givens(&graph); - loop { - self.expansion(&mut var_data); - if !self.enforce_member_constraints(&graph, &mut var_data) { - break; - } - } + self.expansion(&mut var_data); self.collect_errors(&mut var_data, errors); self.collect_var_errors(&var_data, &graph, errors); var_data @@ -233,120 +221,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } - /// Enforce all member constraints and return true if anything - /// changed. See `enforce_member_constraint` for more details. - fn enforce_member_constraints( - &self, - graph: &RegionGraph<'tcx>, - var_values: &mut LexicalRegionResolutions<'tcx>, - ) -> bool { - // Note: we don't use the `any` combinator because we don't - // want to stop at the first constraint that makes a change. - let mut any_changed = false; - for member_constraint in &self.data.member_constraints { - any_changed |= self.enforce_member_constraint(graph, member_constraint, var_values); - } - any_changed - } - - /// Enforce a constraint like - /// - /// ``` - /// 'r member of ['c...] - /// ``` - /// - /// We look for all choice regions from the list `'c...` that: - /// - /// (a) are greater than the current value of `'r` (which is a lower bound) - /// - /// and - /// - /// (b) are compatible with the upper bounds of `'r` that we can - /// find by traversing the graph. - /// - /// From that list, we look for a *minimal* option `'c_min`. If we - /// find one, then we can enforce that `'r: 'c_min`. - fn enforce_member_constraint( - &self, - graph: &RegionGraph<'tcx>, - member_constraint: &MemberConstraint<'tcx>, - var_values: &mut LexicalRegionResolutions<'tcx>, - ) -> bool { - debug!("enforce_member_constraint(member_constraint={:#?})", member_constraint); - - // The constraint is some inference variable (`vid`) which - // must be equal to one of the options. - let member_vid = match member_constraint.member_region { - ty::ReVar(vid) => *vid, - _ => return false, - }; - - // The current value of `vid` is a lower bound LB -- i.e., we - // know that `LB <= vid` must be true. - let member_lower_bound: ty::Region<'tcx> = match var_values.value(member_vid) { - VarValue::ErrorValue => return false, - VarValue::Value(r) => r, - }; - - // Find all the "upper bounds" -- that is, each region `b` such that - // `r0 <= b` must hold. - let (member_upper_bounds, ..) = - self.collect_bounding_regions(graph, member_vid, OUTGOING, None); - - // Get an iterator over the *available choice* -- that is, - // each choice region `c` where `lb <= c` and `c <= ub` for all the - // upper bounds `ub`. - debug!("enforce_member_constraint: upper_bounds={:#?}", member_upper_bounds); - let mut options = member_constraint.choice_regions.iter().filter(|option| { - self.sub_concrete_regions(member_lower_bound, option) - && member_upper_bounds - .iter() - .all(|upper_bound| self.sub_concrete_regions(option, upper_bound.region)) - }); - - // If there is more than one option, we only make a choice if - // there is a single *least* choice -- i.e., some available - // region that is `<=` all the others. - let mut least_choice: ty::Region<'tcx> = match options.next() { - Some(&r) => r, - None => return false, - }; - debug!("enforce_member_constraint: least_choice={:?}", least_choice); - for &option in options { - debug!("enforce_member_constraint: option={:?}", option); - if !self.sub_concrete_regions(least_choice, option) { - if self.sub_concrete_regions(option, least_choice) { - debug!("enforce_member_constraint: new least choice"); - least_choice = option; - } else { - debug!("enforce_member_constraint: no least choice"); - return false; - } - } - } - - // (#72087) Different `ty::Regions` can be known to be equal, for - // example, we know that `'a` and `'static` are equal in a function - // with a parameter of type `&'static &'a ()`. - // - // When we have two equal regions like this `expansion` will use - // `lub_concrete_regions` to pick a canonical representative. The same - // choice is needed here so that we don't end up in a cycle of - // `expansion` changing the region one way and the code here changing - // it back. - let lub = self.lub_concrete_regions(least_choice, member_lower_bound); - debug!( - "enforce_member_constraint: final least choice = {:?}\nlub = {:?}", - least_choice, lub - ); - if lub != member_lower_bound { - *var_values.value_mut(member_vid) = VarValue::Value(least_choice); - true - } else { - false - } - } - fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len()); let mut changes = Vec::new(); @@ -461,6 +335,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } /// True if `a <= b`, but not defined over inference variables. + #[instrument(level = "trace", skip(self))] fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool { let tcx = self.tcx(); let sub_free_regions = |r1, r2| self.region_rels.free_regions.sub_free_regions(tcx, r1, r2); @@ -492,6 +367,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { /// /// Neither `a` nor `b` may be an inference variable (hence the /// term "concrete regions"). + #[instrument(level = "trace", skip(self))] fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { let r = match (a, b) { (&ReLateBound(..), _) | (_, &ReLateBound(..)) | (&ReErased, _) | (_, &ReErased) => { @@ -562,13 +438,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { /// After expansion is complete, go and check upper bounds (i.e., /// cases where the region cannot grow larger than a fixed point) /// and check that they are satisfied. + #[instrument(skip(self, var_data, errors))] fn collect_errors( &self, var_data: &mut LexicalRegionResolutions<'tcx>, errors: &mut Vec>, ) { for (constraint, origin) in &self.data.constraints { - debug!("collect_errors: constraint={:?} origin={:?}", constraint, origin); + debug!(?constraint, ?origin); match *constraint { Constraint::RegSubVar(..) | Constraint::VarSubVar(..) => { // Expansion will ensure that these constraints hold. Ignore. @@ -580,7 +457,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } debug!( - "collect_errors: region error at {:?}: \ + "region error at {:?}: \ cannot verify that {:?} <= {:?}", origin, sub, sup ); @@ -606,7 +483,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // collect them later. if !self.sub_concrete_regions(a_region, b_region) { debug!( - "collect_errors: region error at {:?}: \ + "region error at {:?}: \ cannot verify that {:?}={:?} <= {:?}", origin, a_vid, a_region, b_region ); @@ -616,23 +493,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } - // Check that all member constraints are satisfied. - for member_constraint in &self.data.member_constraints { - let member_region = var_data.normalize(self.tcx(), member_constraint.member_region); - let choice_regions = member_constraint - .choice_regions - .iter() - .map(|&choice_region| var_data.normalize(self.tcx(), choice_region)); - if !choice_regions.clone().any(|choice_region| member_region == choice_region) { - let span = self.tcx().def_span(member_constraint.opaque_type_def_id); - errors.push(RegionResolutionError::MemberConstraintFailure { - span, - hidden_ty: member_constraint.hidden_ty, - member_region, - }); - } - } - for verify in &self.data.verifys { debug!("collect_errors: verify={:?}", verify); let sub = var_data.normalize(self.tcx(), verify.region); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 18836d5a68e26..6b905f67e683f 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -417,9 +417,6 @@ pub enum SubregionOrigin<'tcx> { /// (&'a &'b T) where a >= b ReferenceOutlivesReferent(Ty<'tcx>, Span), - /// Region in return type of invoked fn must enclose call - CallReturn(Span), - /// Comparing the signature and requirements of an impl method against /// the containing trait. CompareImplMethodObligation { @@ -1803,7 +1800,6 @@ impl<'tcx> SubregionOrigin<'tcx> { ReborrowUpvar(a, _) => a, DataBorrowed(_, a) => a, ReferenceOutlivesReferent(_, a) => a, - CallReturn(a) => a, CompareImplMethodObligation { span, .. } => span, CompareImplTypeObligation { span, .. } => span, } diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index c2205462680fc..6c5e6b1cfc385 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -4,10 +4,9 @@ use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic; -use rustc_infer::infer::free_regions::FreeRegionRelations; use rustc_infer::infer::opaque_types::OpaqueTypeDecl; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_infer::infer::{self, InferCtxt, InferOk}; +use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst}; use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt}; @@ -15,19 +14,6 @@ use rustc_span::Span; use std::ops::ControlFlow; -/// Whether member constraints should be generated for all opaque types -#[derive(Debug)] -pub enum GenerateMemberConstraints { - /// The default, used by typeck - WhenRequired, - /// The borrow checker needs member constraints in any case where we don't - /// have a `'static` bound. This is because the borrow checker has more - /// flexibility in the values of regions. For example, given `f<'a, 'b>` - /// the borrow checker can have an inference variable outlive `'a` and `'b`, - /// but not be equal to `'static`. - IfNoStaticBound, -} - pub trait InferCtxtExt<'tcx> { fn instantiate_opaque_types>( &self, @@ -37,14 +23,12 @@ pub trait InferCtxtExt<'tcx> { value_span: Span, ) -> InferOk<'tcx, T>; - fn constrain_opaque_types>(&self, free_region_relations: &FRR); + fn constrain_opaque_types(&self); - fn constrain_opaque_type>( + fn constrain_opaque_type( &self, opaque_type_key: OpaqueTypeKey<'tcx>, opaque_defn: &OpaqueTypeDecl<'tcx>, - mode: GenerateMemberConstraints, - free_region_relations: &FRR, ); /*private*/ @@ -270,26 +254,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// - `opaque_types` -- the map produced by `instantiate_opaque_types` /// - `free_region_relations` -- something that can be used to relate /// the free regions (`'a`) that appear in the impl trait. - fn constrain_opaque_types>(&self, free_region_relations: &FRR) { + fn constrain_opaque_types(&self) { let opaque_types = self.inner.borrow().opaque_types.clone(); for (opaque_type_key, opaque_defn) in opaque_types { - self.constrain_opaque_type( - opaque_type_key, - &opaque_defn, - GenerateMemberConstraints::WhenRequired, - free_region_relations, - ); + self.constrain_opaque_type(opaque_type_key, &opaque_defn); } } /// See `constrain_opaque_types` for documentation. - #[instrument(level = "debug", skip(self, free_region_relations))] - fn constrain_opaque_type>( + #[instrument(level = "debug", skip(self))] + fn constrain_opaque_type( &self, opaque_type_key: OpaqueTypeKey<'tcx>, opaque_defn: &OpaqueTypeDecl<'tcx>, - mode: GenerateMemberConstraints, - free_region_relations: &FRR, ) { let def_id = opaque_type_key.def_id; @@ -318,118 +295,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { hir::OpaqueTyOrigin::TyAlias => 0, }; - let span = tcx.def_span(def_id); - - // Check if the `impl Trait` bounds include region bounds. - // For example, this would be true for: - // - // fn foo<'a, 'b, 'c>() -> impl Trait<'c> + 'a + 'b - // - // but false for: - // - // fn foo<'c>() -> impl Trait<'c> - // - // unless `Trait` was declared like: - // - // trait Trait<'c>: 'c - // - // in which case it would be true. - // - // This is used during regionck to decide whether we need to - // impose any additional constraints to ensure that region - // variables in `concrete_ty` wind up being constrained to - // something from `substs` (or, at minimum, things that outlive - // the fn body). (Ultimately, writeback is responsible for this - // check.) - let bounds = tcx.explicit_item_bounds(def_id); - debug!("{:#?}", bounds); - let bounds = bounds.iter().map(|(bound, _)| bound.subst(tcx, opaque_type_key.substs)); - debug!("{:#?}", bounds); - let opaque_type = tcx.mk_opaque(def_id, opaque_type_key.substs); - - let required_region_bounds = required_region_bounds(tcx, opaque_type, bounds); - if !required_region_bounds.is_empty() { - for required_region in required_region_bounds { - concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { - tcx, - op: |r| self.sub_regions(infer::CallReturn(span), required_region, r), - }); - } - if let GenerateMemberConstraints::IfNoStaticBound = mode { - self.generate_member_constraint( - concrete_ty, - opaque_defn, - opaque_type_key, - first_own_region, - ); - } - return; - } - - // There were no `required_region_bounds`, - // so we have to search for a `least_region`. - // Go through all the regions used as arguments to the - // opaque type. These are the parameters to the opaque - // type; so in our example above, `substs` would contain - // `['a]` for the first impl trait and `'b` for the - // second. - let mut least_region = None; - - for subst_arg in &opaque_type_key.substs[first_own_region..] { - let subst_region = match subst_arg.unpack() { - GenericArgKind::Lifetime(r) => r, - GenericArgKind::Type(_) | GenericArgKind::Const(_) => continue, - }; - - // Compute the least upper bound of it with the other regions. - debug!(?least_region); - debug!(?subst_region); - match least_region { - None => least_region = Some(subst_region), - Some(lr) => { - if free_region_relations.sub_free_regions(self.tcx, lr, subst_region) { - // keep the current least region - } else if free_region_relations.sub_free_regions(self.tcx, subst_region, lr) { - // switch to `subst_region` - least_region = Some(subst_region); - } else { - // There are two regions (`lr` and - // `subst_region`) which are not relatable. We - // can't find a best choice. Therefore, - // instead of creating a single bound like - // `'r: 'a` (which is our preferred choice), - // 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_member_constraint( - concrete_ty, - opaque_defn, - opaque_type_key, - first_own_region, - ); - } - } - } - } - - let least_region = least_region.unwrap_or(tcx.lifetimes.re_static); - debug!(?least_region); - - if let GenerateMemberConstraints::IfNoStaticBound = mode { - if least_region != tcx.lifetimes.re_static { - self.generate_member_constraint( - concrete_ty, - opaque_defn, - opaque_type_key, - first_own_region, - ); - } - } - concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { - tcx, - op: |r| self.sub_regions(infer::CallReturn(span), least_region, r), - }); + // The regions that appear in the hidden type must be equal to + // one of the regions in scope for the opaque type. + self.generate_member_constraint( + concrete_ty, + opaque_defn, + opaque_type_key, + first_own_region, + ); } /// As a fallback, we sometimes generate an "in constraint". For diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs index 79443010fbb3d..85602f1159392 100644 --- a/compiler/rustc_typeck/src/check/regionck.rs +++ b/compiler/rustc_typeck/src/check/regionck.rs @@ -296,7 +296,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { self.visit_body(body); self.visit_region_obligations(body_id.hir_id); - self.constrain_opaque_types(self.outlives_environment.free_region_map()); + self.constrain_opaque_types(); } fn visit_region_obligations(&mut self, hir_id: hir::HirId) { diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr index b6841da1f0ba9..9b0018d8904ac 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr @@ -1,13 +1,31 @@ error: lifetime may not live long enough - --> $DIR/ret-impl-trait-one.rs:10:65 + --> $DIR/ret-impl-trait-one.rs:10:85 + | +LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { + | ________________________________--__--_______________________________________________^ + | | | | + | | | lifetime `'b` defined here + | | lifetime `'a` defined here +LL | | +LL | | (a, b) +LL | | } + | |_^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/ret-impl-trait-one.rs:16:65 | LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { - | -- -- ^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a` - | | | - | | lifetime `'b` defined here - | lifetime `'a` defined here + | -- ^^^^^^^^^^^^^^ + | | + | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here + | +help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound | - = help: consider adding the following bound: `'b: 'a` +LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { + | ++++ -error: aborting due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs index 7e084217c2607..4f32489014d53 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs @@ -6,9 +6,15 @@ trait Trait<'a> { } impl Trait<'_> for T { } +// Fails to recognize that both 'a and 'b are mentioned and should thus be accepted +async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { + //~^ ERROR lifetime mismatch + (a, b) +} + // Only `'a` permitted in return type, not `'b`. async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { - //~^ ERROR lifetime mismatch + //~^ ERROR captures lifetime that does not appear in bounds (a, b) } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr index 8e28605721cb5..bcd96367e2fae 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -1,13 +1,27 @@ error[E0623]: lifetime mismatch --> $DIR/ret-impl-trait-one.rs:10:65 | +LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { + | ------ ^^^^^^^^^^^^^^^^^^^ + | | | + | | ...but data from `a` is held across an await point here + | | this `async fn` implicitly returns an `impl Future + 'b>` + | this parameter and the returned future are declared with different lifetimes... + +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/ret-impl-trait-one.rs:16:65 + | LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { - | ------ ^^^^^^^^^^^^^^ - | | | - | | ...but data from `b` is held across an await point here - | | this `async fn` implicitly returns an `impl Future>` - | this parameter and the returned future are declared with different lifetimes... + | -- ^^^^^^^^^^^^^^ + | | + | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here + | +help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound + | +LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { + | ++++ -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0623`. +Some errors have detailed explanations: E0623, E0700. +For more information about an error, try `rustc --explain E0623`. diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr deleted file mode 100644 index bfe656c7e2b49..0000000000000 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unrelated.rs:16:74 - | -LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> - | -- ^^^^^^^^^^^^^^^^^^ - | | - | hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here - | -help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound - | -LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + 'b - | ++++ - -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-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr index a6bc8fec2838e..bfe656c7e2b49 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 @@ -2,13 +2,14 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea --> $DIR/ordinary-bounds-unrelated.rs:16:74 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> - | ^^^^^^^^^^^^^^^^^^ + | -- ^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here | -note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body - --> $DIR/ordinary-bounds-unrelated.rs:16:74 +help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound | -LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> - | ^^^^^^^^^^^^^^^^^^ +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + 'b + | ++++ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr deleted file mode 100644 index 75c2dd8e9d39e..0000000000000 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unsuited.rs:18:62 - | -LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> - | -- ^^^^^^^^^^^^^^^^^^ - | | - | hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here - | -help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound - | -LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + 'b - | ++++ - -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-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr index a219e74741541..75c2dd8e9d39e 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 @@ -2,13 +2,14 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea --> $DIR/ordinary-bounds-unsuited.rs:18:62 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> - | ^^^^^^^^^^^^^^^^^^ + | -- ^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here | -note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body - --> $DIR/ordinary-bounds-unsuited.rs:18:62 +help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound | -LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> - | ^^^^^^^^^^^^^^^^^^ +LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + 'b + | ++++ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index 812093e6e7621..eaf341248a180 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -1,31 +1,31 @@ -error: lifetime may not live long enough +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/must_outlive_least_region_or_bound.rs:3:23 | LL | fn elided(x: &i32) -> impl Copy { x } - | - ^^^^^^^^^ opaque type requires that `'1` must outlive `'static` + | ---- ^^^^^^^^^ | | - | let's call the lifetime of this reference `'1` + | hidden type `&i32` captures the anonymous lifetime defined here | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound +help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ++++ -error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:5:32 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/must_outlive_least_region_or_bound.rs:6:32 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | -- ^^^^^^^^^ opaque type requires that `'a` must outlive `'static` + | -- ^^^^^^^^^ | | - | lifetime `'a` defined here + | hidden type `&'a i32` captures the lifetime `'a` as defined here | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound +help: to declare that the `impl Trait` captures 'a, you can add an explicit `'a` lifetime bound | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ++++ error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:7:46 + --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | - ^ returning this value requires that `'1` must outlive `'static` @@ -35,7 +35,7 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x } = help: consider replacing `'1` with `'static` error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:9:55 + --> $DIR/must_outlive_least_region_or_bound.rs:11:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` @@ -43,7 +43,7 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } = help: consider replacing `'a` with `'static` error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/must_outlive_least_region_or_bound.rs:11:41 + --> $DIR/must_outlive_least_region_or_bound.rs:13:41 | LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } | ---- ^ lifetime `'a` required @@ -51,33 +51,36 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:22:24 + --> $DIR/must_outlive_least_region_or_bound.rs:24:55 | LL | fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } - | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` + | - ^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` | | | let's call the lifetime of this reference `'1` error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:28:69 + --> $DIR/must_outlive_least_region_or_bound.rs:29:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` | = help: consider replacing `'a` with `'static` -error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:32:61 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/must_outlive_least_region_or_bound.rs:33:61 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - | -- -- lifetime `'b` defined here ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a` - | | - | lifetime `'a` defined here + | -- ^^^^^^^^^^^^^^^^ + | | + | hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:35:5: 35:31]` captures the lifetime `'b` as defined here + | +help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound | - = help: consider adding the following bound: `'b: 'a` +LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) + 'b { + | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:37:51 + --> $DIR/must_outlive_least_region_or_bound.rs:38:51 | LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | ^^^^^^^^^^^^^^^^^^^^ @@ -86,5 +89,5 @@ LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { error: aborting due to 9 previous errors -Some errors have detailed explanations: E0310, E0621. +Some errors have detailed explanations: E0310, E0621, E0700. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index 51f488e45a6f3..69d2843ff3f01 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -1,8 +1,10 @@ use std::fmt::Debug; -fn elided(x: &i32) -> impl Copy { x } //~ ERROR E0759 +fn elided(x: &i32) -> impl Copy { x } +//~^ ERROR: captures lifetime that does not appear in bounds -fn explicit<'a>(x: &'a i32) -> impl Copy { x } //~ ERROR E0759 +fn explicit<'a>(x: &'a i32) -> impl Copy { x } +//~^ ERROR: captures lifetime that does not appear in bounds fn elided2(x: &i32) -> impl Copy + 'static { x } //~ ERROR E0759 @@ -20,7 +22,6 @@ fn elided4(x: &i32) -> Box { Box::new(x) } //~ ERROR E0759 fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } //~ ERROR E0759 fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } //~ ERROR E0759 -//~^ ERROR E0759 trait LifetimeTrait<'a> {} impl<'a> LifetimeTrait<'a> for &'a i32 {} @@ -30,7 +31,7 @@ fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } //~ ERRO // Tests that a closure type containing 'b cannot be returned from a type where // only 'a was expected. fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - //~^ ERROR lifetime mismatch + //~^ ERROR: captures lifetime that does not appear in bounds move |_| println!("{}", y) } diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 81ba89b0e05f7..d65dea7adc90b 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -1,41 +1,31 @@ -error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:3:35 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/must_outlive_least_region_or_bound.rs:3:23 | LL | fn elided(x: &i32) -> impl Copy { x } - | ---- ^ ...is captured here... + | ---- ^^^^^^^^^ | | - | this data with an anonymous lifetime `'_`... - | -note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:3:23 + | hidden type `&i32` captures the anonymous lifetime defined here | -LL | fn elided(x: &i32) -> impl Copy { x } - | ^^^^^^^^^ -help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound +help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ++++ -error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:5:44 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/must_outlive_least_region_or_bound.rs:6:32 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | ------- ^ ...is captured here... - | | - | this data with lifetime `'a`... + | -- ^^^^^^^^^ + | | + | hidden type `&'a i32` captures the lifetime `'a` as defined here | -note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:5:32 - | -LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | ^^^^^^^^^ -help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'a` lifetime bound +help: to declare that the `impl Trait` captures 'a, you can add an explicit `'a` lifetime bound | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ++++ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:7:46 + --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ---- ^ ...is captured here... @@ -43,7 +33,7 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | this data with an anonymous lifetime `'_`... | note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:7:24 + --> $DIR/must_outlive_least_region_or_bound.rs:9:24 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^^^^^^^^ @@ -57,7 +47,7 @@ LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } | ~~~~~~~~~~~~ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:9:55 + --> $DIR/must_outlive_least_region_or_bound.rs:11:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ------- ^ ...is captured here... @@ -65,7 +55,7 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | this data with lifetime `'a`... | note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:9:33 + --> $DIR/must_outlive_least_region_or_bound.rs:11:33 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^^^^^^^^ @@ -79,7 +69,7 @@ LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } | ~~~~~~~~~~~~ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/must_outlive_least_region_or_bound.rs:11:24 + --> $DIR/must_outlive_least_region_or_bound.rs:13:24 | LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } | ---- ^^^^^^^^^^^^^^ lifetime `'a` required @@ -87,7 +77,7 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:22:65 + --> $DIR/must_outlive_least_region_or_bound.rs:24:65 | LL | fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } | ---- this data with an anonymous lifetime `'_`... ^ ...is captured here, requiring it to live as long as `'static` @@ -101,34 +91,14 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can LL | fn elided5(x: &i32) -> (Box, impl Debug + '_) { (Box::new(x), x) } | ++++ -error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:22:69 - | -LL | fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } - | ---- this data with an anonymous lifetime `'_`... ^ ...is captured here... - | -note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:22:41 - | -LL | fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } - | ^^^^^^^^^^ -help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound - | -LL | fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } - | ++++ -help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound - | -LL | fn elided5(x: &i32) -> (Box, impl Debug + '_) { (Box::new(x), x) } - | ++++ - error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:28:69 + --> $DIR/must_outlive_least_region_or_bound.rs:29:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- this data with lifetime `'a`... ^ ...is captured here... | note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:28:34 + --> $DIR/must_outlive_least_region_or_bound.rs:29:34 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -141,17 +111,21 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x } | ~~~~~~~~~~~~ -error[E0623]: lifetime mismatch - --> $DIR/must_outlive_least_region_or_bound.rs:32:61 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/must_outlive_least_region_or_bound.rs:33:61 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - | ------- ^^^^^^^^^^^^^^^^ - | | | - | | ...but data from `y` is returned here - | this parameter and the return type are declared with different lifetimes... + | -- ^^^^^^^^^^^^^^^^ + | | + | hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:35:5: 35:31]` captures the lifetime `'b` as defined here + | +help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound + | +LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) + 'b { + | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:37:51 + --> $DIR/must_outlive_least_region_or_bound.rs:38:51 | LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds @@ -159,7 +133,7 @@ LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | help: consider adding an explicit lifetime bound...: `T: 'static +` error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:14:50 + --> $DIR/must_outlive_least_region_or_bound.rs:16:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ---- ^ ...is captured here, requiring it to live as long as `'static` @@ -172,7 +146,7 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ++++ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:16:59 + --> $DIR/must_outlive_least_region_or_bound.rs:18:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ------- ^ ...is captured here, requiring it to live as long as `'static` @@ -185,7 +159,7 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ++++ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:18:60 + --> $DIR/must_outlive_least_region_or_bound.rs:20:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ---- ^ ...is captured here, requiring it to live as long as `'static` @@ -202,7 +176,7 @@ LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } | ~~~~~~~~~~~~ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/must_outlive_least_region_or_bound.rs:20:69 + --> $DIR/must_outlive_least_region_or_bound.rs:22:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ------- this data with lifetime `'a`... ^ ...is captured here, requiring it to live as long as `'static` @@ -216,7 +190,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) } | ~~~~~~~~~~~~ -error: aborting due to 14 previous errors +error: aborting due to 13 previous errors -Some errors have detailed explanations: E0310, E0621, E0623, E0759. +Some errors have detailed explanations: E0310, E0621, E0700, E0759. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr deleted file mode 100644 index a3aeff50eee4c..0000000000000 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr +++ /dev/null @@ -1,28 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/static-return-lifetime-infered.rs:6:35 - | -LL | fn iter_values_anon(&self) -> impl Iterator { - | - ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` - | | - | let's call the lifetime of this reference `'1` - | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound - | -LL | fn iter_values_anon(&self) -> impl Iterator + '_ { - | ++++ - -error: lifetime may not live long enough - --> $DIR/static-return-lifetime-infered.rs:9:37 - | -LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -- ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static` - | | - | lifetime `'a` defined here - | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound - | -LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { - | ++++ - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.rs b/src/test/ui/impl-trait/static-return-lifetime-infered.rs index 518c52f5de4d7..d792c6eafb32f 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.rs +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.rs @@ -4,10 +4,14 @@ struct A { impl A { fn iter_values_anon(&self) -> impl Iterator { - self.x.iter().map(|a| a.0) //~ ERROR E0759 + //~^ ERROR: captures lifetime that does not appear in bounds + //~| ERROR: captures lifetime that does not appear in bounds + self.x.iter().map(|a| a.0) } fn iter_values<'a>(&'a self) -> impl Iterator { - self.x.iter().map(|a| a.0) //~ ERROR E0759 + //~^ ERROR: captures lifetime that does not appear in bounds + //~| ERROR: captures lifetime that does not appear in bounds + self.x.iter().map(|a| a.0) } } diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index ebd0b6a128180..0d68f8c825f70 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -1,43 +1,55 @@ -error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/static-return-lifetime-infered.rs:7:16 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/static-return-lifetime-infered.rs:6:35 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- this data with an anonymous lifetime `'_`... -LL | self.x.iter().map(|a| a.0) - | ------ ^^^^ - | | - | ...is captured here... + | ----- ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:9:27: 9:34]>` captures the anonymous lifetime defined here + | +help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound | -note: ...and is required to live as long as `'static` here +LL | fn iter_values_anon(&self) -> impl Iterator + '_ { + | ++++ + +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/static-return-lifetime-infered.rs:6:35 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound + | ----- ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:9:27: 9:34]>` captures the anonymous lifetime defined here + | +help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ++++ -error[E0759]: `self` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/static-return-lifetime-infered.rs:10:16 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/static-return-lifetime-infered.rs:11:37 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -------- this data with lifetime `'a`... -LL | self.x.iter().map(|a| a.0) - | ------ ^^^^ - | | - | ...is captured here... + | -- ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:14:27: 14:34]>` captures the lifetime `'a` as defined here | -note: ...and is required to live as long as `'static` here - --> $DIR/static-return-lifetime-infered.rs:9:37 +help: to declare that the `impl Trait` captures 'a, you can add an explicit `'a` lifetime bound + | +LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { + | ++++ + +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/static-return-lifetime-infered.rs:11:37 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound + | -- ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:14:27: 14:34]>` captures the lifetime `'a` as defined here + | +help: to declare that the `impl Trait` captures 'a, you can add an explicit `'a` lifetime bound | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ++++ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0759`. +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/nll/issue-73159-rpit-static.rs b/src/test/ui/nll/issue-73159-rpit-static.rs index a5455a3f9eb7b..e29ba09b3694d 100644 --- a/src/test/ui/nll/issue-73159-rpit-static.rs +++ b/src/test/ui/nll/issue-73159-rpit-static.rs @@ -6,7 +6,8 @@ struct Foo<'a>(&'a [u8]); impl<'a> Foo<'a> { - fn make_it(&self) -> impl Iterator { //~ ERROR lifetime may not live + fn make_it(&self) -> impl Iterator { + //~^ ERROR: captures lifetime that does not appear in bounds self.0.iter().copied() } } diff --git a/src/test/ui/nll/issue-73159-rpit-static.stderr b/src/test/ui/nll/issue-73159-rpit-static.stderr index 60b1552701af9..6c7cd0c825493 100644 --- a/src/test/ui/nll/issue-73159-rpit-static.stderr +++ b/src/test/ui/nll/issue-73159-rpit-static.stderr @@ -1,10 +1,11 @@ -error: lifetime may not live long enough +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/issue-73159-rpit-static.rs:9:26 | LL | impl<'a> Foo<'a> { - | -- lifetime `'a` defined here + | -- hidden type `Copied>` captures the lifetime `'a` as defined here LL | fn make_it(&self) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs index bcdf643c0b9d1..8af23aad7261b 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs @@ -8,7 +8,7 @@ trait Foo<'a> { impl<'a, T> Foo<'a> for T { } fn foo<'a, T>(x: &T) -> impl Foo<'a> { -//~^ ERROR explicit lifetime required in the type of `x` [E0621] +//~^ ERROR captures lifetime that does not appear in bounds x } diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr index d05fc793967ae..21d1eea54e6c5 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -1,14 +1,16 @@ -error[E0621]: explicit lifetime required in the type of `x` +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/impl-trait-captures.rs:10:25 | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { - | ^^^^^^^^^^^^ lifetime `ReEarlyBound(0, 'a)` required + | -- ^^^^^^^^^^^^ + | | + | hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[e9f4]::foo), BrAnon(0)) T` captures the anonymous lifetime defined here | -help: add explicit lifetime `ReEarlyBound(0, 'a)` to the type of `x` +help: to declare that the `impl Trait` captures ReFree(DefId(0:8 ~ impl_trait_captures[e9f4]::foo), BrAnon(0)), you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[e9f4]::foo), BrAnon(0))` lifetime bound | -LL | fn foo<'a, T>(x: &ReEarlyBound(0, 'a) T) -> impl Foo<'a> { - | ~~~~~~~~~~~~~~~~~~~~~~ +LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[e9f4]::foo), BrAnon(0)) { + | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error: aborting due to previous error -For more information about this error, try `rustc --explain E0621`. +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr deleted file mode 100644 index 5d0b2c2ebdf68..0000000000000 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37 - | -LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | - ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` - | | - | let's call the lifetime of this reference `'1` - | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound - | -LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self } - | ++++ - -error: aborting due to previous error - diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs index 43998ca8c5784..a1e7f4aa875ee 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs @@ -6,7 +6,7 @@ struct Foo; impl Foo { async fn f(self: Pin<&Self>) -> impl Clone { self } - //~^ ERROR E0759 + //~^ ERROR: captures lifetime that does not appear in bounds } fn main() { diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 04cd2b78da124..953d7cd6a0769 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -1,17 +1,16 @@ -error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- ---------- ...and is required to live as long as `'static` here - | | | - | | this data with an anonymous lifetime `'_`... - | ...is captured here... + | - ^^^^^^^^^^ + | | + | hidden type `Pin<&Foo>` captures the lifetime `'_` as defined here | -help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound +help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound | LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ++++ error: aborting due to previous error -For more information about this error, try `rustc --explain E0759`. +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr deleted file mode 100644 index 4301d8f767a51..0000000000000 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31 - | -LL | fn f(self: Pin<&Self>) -> impl Clone { self } - | - ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` - | | - | let's call the lifetime of this reference `'1` - | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound - | -LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } - | ++++ - -error: aborting due to previous error - diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs index 04935fc52ab9e..4db2fa7dcb81e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs @@ -3,7 +3,8 @@ use std::pin::Pin; struct Foo; impl Foo { - fn f(self: Pin<&Self>) -> impl Clone { self } //~ ERROR E0759 + fn f(self: Pin<&Self>) -> impl Clone { self } + //~^ ERROR: captures lifetime that does not appear in bounds } fn main() { diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 54e75aeec3e36..faa1233ffde63 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -1,21 +1,16 @@ -error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 - | -LL | fn f(self: Pin<&Self>) -> impl Clone { self } - | ---------- ^^^^ ...is captured here... - | | - | this data with an anonymous lifetime `'_`... - | -note: ...and is required to live as long as `'static` here +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^^^^^^^ -help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound + | ----- ^^^^^^^^^^ + | | + | hidden type `Pin<&Foo>` captures the anonymous lifetime defined here + | +help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ++++ error: aborting due to previous error -For more information about this error, try `rustc --explain E0759`. +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr index 80d3c940eb7c6..2dc300ac76f27 100644 --- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr +++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr @@ -1,17 +1,8 @@ -error[E0597]: `val` does not live long enough +error[E0515]: cannot return reference to function parameter `val` --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:21:9 | -LL | fn use_it<'a>(val: Box>) -> impl OtherTrait<'a> { - | -- lifetime `'a` defined here ------------------- opaque type requires that `val` is borrowed for `'a` LL | val.use_self() - | ^^^^^^^^^^^^^^ borrowed value does not live long enough -LL | } - | - `val` dropped here while still borrowed - | -help: you can add a bound to the opaque type to make it last less than `'static` and match `'a` - | -LL | fn use_it<'a>(val: Box>) -> impl OtherTrait<'a> + 'a { - | ++++ + | ^^^^^^^^^^^^^^ returns a reference to data owned by the current function error[E0515]: cannot return reference to function parameter `val` --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:43:9 @@ -27,5 +18,4 @@ LL | val.use_self() error: aborting due to 3 previous errors -Some errors have detailed explanations: E0515, E0597. -For more information about an error, try `rustc --explain E0515`. +For more information about this error, try `rustc --explain E0515`. diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs index b2dc16a27e310..0045d3fcf1c7b 100644 --- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs +++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs @@ -18,7 +18,7 @@ mod bav { impl Bar for i32 {} fn use_it<'a>(val: Box>) -> impl OtherTrait<'a> { - val.use_self() //~ ERROR E0597 + val.use_self() //~ ERROR cannot return reference to function parameter } } diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr index e8c3a7908f521..2961d8d7eacc9 100644 --- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr +++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr @@ -1,17 +1,8 @@ -error[E0597]: `val` does not live long enough +error[E0515]: cannot return reference to function parameter `val` --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:21:9 | -LL | fn use_it<'a>(val: Box>) -> impl OtherTrait<'a> { - | -- lifetime `'a` defined here ------------------- opaque type requires that `val` is borrowed for `'a` LL | val.use_self() - | ^^^^^^^^^^^^^^ borrowed value does not live long enough -LL | } - | - `val` dropped here while still borrowed - | -help: you can add a bound to the opaque type to make it last less than `'static` and match `'a` - | -LL | fn use_it<'a>(val: Box>) -> impl OtherTrait<'a> + 'a { - | ++++ + | ^^^^^^^^^^^^^^ returns a reference to data owned by the current function error[E0515]: cannot return reference to function parameter `val` --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:43:9 @@ -47,5 +38,4 @@ LL | impl MyTrait for Box + '_> { error: aborting due to 4 previous errors -Some errors have detailed explanations: E0515, E0597. -For more information about an error, try `rustc --explain E0515`. +For more information about this error, try `rustc --explain E0515`. diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr index b579635ca7c08..3ed3827b97da3 100644 --- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr +++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr @@ -1,10 +1,13 @@ error: lifetime may not live long enough - --> $DIR/trait-object-nested-in-impl-trait.rs:27:23 + --> $DIR/trait-object-nested-in-impl-trait.rs:28:9 | -LL | fn iter(&self) -> impl Iterator> { - | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` - | | - | let's call the lifetime of this reference `'1` +LL | fn iter(&self) -> impl Iterator> { + | - let's call the lifetime of this reference `'1` +LL | / Iter { +LL | | current: None, +LL | | remaining: self.0.iter(), +LL | | } + | |_________^ returning this value requires that `'1` must outlive `'static` | help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound | @@ -34,12 +37,15 @@ LL | | } | |_________^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/trait-object-nested-in-impl-trait.rs:60:30 + --> $DIR/trait-object-nested-in-impl-trait.rs:61:9 | -LL | fn iter<'a>(&'a self) -> impl Iterator> { - | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static` - | | - | lifetime `'a` defined here +LL | fn iter<'a>(&'a self) -> impl Iterator> { + | -- lifetime `'a` defined here +LL | / Iter { +LL | | current: None, +LL | | remaining: self.0.iter(), +LL | | } + | |_________^ returning this value requires that `'a` must outlive `'static` | help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound |