Auto merge of #89229 - oli-obk:i_love_inferctxt, r=jackh726
Remove redundant member-constraint check impl trait will, for each lifetime in the hidden type, register a "member constraint" that says the lifetime must be equal or outlive one of the lifetimes of the impl trait. These member constraints will be solved by borrowck But, as you can see in the big red block of removed code, there was an ad-hoc check for member constraints happening at the site where they get registered. This check had some minor effects on diagnostics, but will fall down on its feet with my big type alias impl trait refactor. So we removed it and I pulled the removal out into a (hopefully) reviewable PR that works on master directly.
This commit is contained in:
commit
ec724ac075
38 changed files with 277 additions and 708 deletions
|
@ -689,6 +689,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// them down.
|
||||
let mut choice_regions: Vec<ty::RegionVid> = 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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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<Item = &'a str>
|
||||
) -> impl Iterator<Item = String> { // 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<i32>
|
||||
) -> impl FnMut(&mut Vec<i32>) -> &[i32] { // error!
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<FreeRegionMap<'tcx>> {
|
||||
|
|
|
@ -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<RegionResolutionError<'tcx>>) {
|
||||
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.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<RegionResolutionError<'tcx>>,
|
||||
) {
|
||||
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);
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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<T: TypeFoldable<'tcx>>(
|
||||
&self,
|
||||
|
@ -37,14 +23,12 @@ pub trait InferCtxtExt<'tcx> {
|
|||
value_span: Span,
|
||||
) -> InferOk<'tcx, T>;
|
||||
|
||||
fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(&self, free_region_relations: &FRR);
|
||||
fn constrain_opaque_types(&self);
|
||||
|
||||
fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
|
||||
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<FRR: FreeRegionRelations<'tcx>>(&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<FRR: FreeRegionRelations<'tcx>>(
|
||||
#[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,44 +295,8 @@ 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 {
|
||||
// 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,
|
||||
|
@ -363,74 +304,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
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),
|
||||
});
|
||||
}
|
||||
|
||||
/// As a fallback, we sometimes generate an "in constraint". For
|
||||
/// a case like `impl Foo<'a, 'b>`, where `'a` and `'b` cannot be
|
||||
|
|
|
@ -341,7 +341,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) {
|
||||
|
|
|
@ -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: consider adding the following bound: `'b: 'a`
|
||||
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 E0700`.
|
||||
|
|
|
@ -6,9 +6,15 @@
|
|||
trait Trait<'a> { }
|
||||
impl<T> 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)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,27 @@
|
|||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ret-impl-trait-one.rs:10:65
|
||||
|
|
||||
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
|
||||
| ------ ^^^^^^^^^^^^^^
|
||||
LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
|
||||
| ------ ^^^^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | ...but data from `b` is held across an await point here
|
||||
| | this `async fn` implicitly returns an `impl Future<Output = impl Trait<'a>>`
|
||||
| | ...but data from `a` is held across an await point here
|
||||
| | this `async fn` implicitly returns an `impl Future<Output = impl Trait<'a> + 'b>`
|
||||
| this parameter and the returned future are declared with different lifetimes...
|
||||
|
||||
error: aborting due to previous error
|
||||
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> {
|
||||
| -- ^^^^^^^^^^^^^^
|
||||
| |
|
||||
| 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 {
|
||||
| ++++
|
||||
|
||||
For more information about this error, try `rustc --explain E0623`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0623, E0700.
|
||||
For more information about an error, try `rustc --explain E0623`.
|
||||
|
|
|
@ -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`.
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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`.
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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<dyn Debug>, 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: consider adding the following bound: `'b: 'a`
|
||||
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<T:Debug>(x: T) -> impl Debug + 'static {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -86,5 +89,5 @@ LL | fn ty_param_wont_outlive_static<T:Debug>(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`.
|
||||
|
|
|
@ -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<dyn Debug + 'static> { Box::new(x) } //~ ERROR E0759
|
|||
fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) } //~ ERROR E0759
|
||||
|
||||
fn elided5(x: &i32) -> (Box<dyn Debug>, 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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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
|
||||
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 }
|
||||
| ^^^^^^^^^
|
||||
help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound
|
||||
| ---- ^^^^^^^^^
|
||||
| |
|
||||
| hidden type `&i32` captures the anonymous lifetime defined here
|
||||
|
|
||||
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<dyn Debug>, 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<dyn Debug>, 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<dyn Debug>, 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<dyn Debug>, 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<dyn Debug + '_>, 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<dyn Debug>, 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<T:Debug>(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<T:Debug>(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<dyn Debug> { Box::new(x) }
|
||||
| ---- ^ ...is captured here, requiring it to live as long as `'static`
|
||||
|
@ -172,7 +146,7 @@ LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { 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<dyn Debug> { 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<dyn Debug + 'a> { 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<dyn Debug + 'static> { 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<dyn Debug + 'static> { 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<dyn Debug + 'static> { 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<dyn Debug + 'static> { 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`.
|
||||
|
|
|
@ -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<Item=u32> {
|
||||
| - ^^^^^^^^^^^^^^^^^^^^^^^ 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<Item=u32> + '_ {
|
||||
| ++++
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/static-return-lifetime-infered.rs:9:37
|
||||
|
|
||||
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
|
||||
| -- ^^^^^^^^^^^^^^^^^^^^^^^ 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<Item=u32> + 'a {
|
||||
| ++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -4,10 +4,14 @@ struct A {
|
|||
|
||||
impl A {
|
||||
fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||
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<Item=u32> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||
| ----- this data with an anonymous lifetime `'_`...
|
||||
LL | self.x.iter().map(|a| a.0)
|
||||
| ------ ^^^^
|
||||
| |
|
||||
| ...is captured here...
|
||||
|
|
||||
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/static-return-lifetime-infered.rs:6:35
|
||||
|
|
||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
|
||||
| ----- ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [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<Item=u32> + '_ {
|
||||
| ++++
|
||||
|
||||
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:6:35
|
||||
|
|
||||
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
|
||||
| -------- this data with lifetime `'a`...
|
||||
LL | self.x.iter().map(|a| a.0)
|
||||
| ------ ^^^^
|
||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||
| ----- ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| ...is captured here...
|
||||
| hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:9:27: 9:34]>` captures the anonymous lifetime 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 '_, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
|
||||
| ++++
|
||||
|
||||
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<Item=u32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound
|
||||
| -- ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| hidden type `Map<std::slice::Iter<'a, (u32, u32)>, [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<Item=u32> + 'a {
|
||||
| ++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
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<Item=u32> {
|
||||
| -- ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| hidden type `Map<std::slice::Iter<'a, (u32, u32)>, [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<Item=u32> + 'a {
|
||||
| ++++
|
||||
|
||||
For more information about this error, try `rustc --explain E0759`.
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0700`.
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
struct Foo<'a>(&'a [u8]);
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
fn make_it(&self) -> impl Iterator<Item = u8> { //~ ERROR lifetime may not live
|
||||
fn make_it(&self) -> impl Iterator<Item = u8> {
|
||||
//~^ ERROR: captures lifetime that does not appear in bounds
|
||||
self.0.iter().copied()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<std::slice::Iter<'a, u8>>` captures the lifetime `'a` as defined here
|
||||
LL | fn make_it(&self) -> impl Iterator<Item = u8> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0700`.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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() {
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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() {
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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<dyn ObjectTrait<Assoc = i32>>) -> 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<dyn ObjectTrait<Assoc = i32>>) -> 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`.
|
||||
|
|
|
@ -18,7 +18,7 @@ mod bav {
|
|||
impl Bar for i32 {}
|
||||
|
||||
fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
|
||||
val.use_self() //~ ERROR E0597
|
||||
val.use_self() //~ ERROR cannot return reference to function parameter
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<dyn ObjectTrait<Assoc = i32>>) -> 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<dyn ObjectTrait<Assoc = i32>>) -> 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<dyn ObjectTrait<Assoc = i32> + '_> {
|
|||
|
||||
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`.
|
||||
|
|
|
@ -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<Item = Box<dyn Foo>> {
|
||||
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
|
||||
| |
|
||||
| let's call the lifetime of this reference `'1`
|
||||
| - 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<Item = Box<dyn Foo>> {
|
||||
| -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
| -- 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
|
||||
|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue