Remove DefId
from EarlyParamRegion
(tedium/diagnostics)
This commit is contained in:
parent
bd6344d829
commit
fe2d7794ca
27 changed files with 266 additions and 157 deletions
|
@ -1,4 +1,5 @@
|
||||||
use rustc_errors::Diag;
|
use rustc_errors::Diag;
|
||||||
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_infer::infer::canonical::Canonical;
|
use rustc_infer::infer::canonical::Canonical;
|
||||||
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
|
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||||
use rustc_infer::infer::region_constraints::Constraint;
|
use rustc_infer::infer::region_constraints::Constraint;
|
||||||
|
@ -241,7 +242,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
|
||||||
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
type_op_prove_predicate_with_cause(&ocx, key, cause);
|
type_op_prove_predicate_with_cause(&ocx, key, cause);
|
||||||
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +288,7 @@ where
|
||||||
let (param_env, value) = key.into_parts();
|
let (param_env, value) = key.into_parts();
|
||||||
let _ = ocx.normalize(&cause, param_env, value.value);
|
let _ = ocx.normalize(&cause, param_env, value.value);
|
||||||
|
|
||||||
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +319,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
|
||||||
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
|
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
|
||||||
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,6 +343,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
|
||||||
) -> Option<Diag<'tcx>> {
|
) -> Option<Diag<'tcx>> {
|
||||||
try_extract_error_from_region_constraints(
|
try_extract_error_from_region_constraints(
|
||||||
mbcx.infcx,
|
mbcx.infcx,
|
||||||
|
mbcx.mir_def_id(),
|
||||||
placeholder_region,
|
placeholder_region,
|
||||||
error_region,
|
error_region,
|
||||||
self.region_constraints.as_ref().unwrap(),
|
self.region_constraints.as_ref().unwrap(),
|
||||||
|
@ -358,6 +360,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
|
||||||
#[instrument(skip(ocx), level = "debug")]
|
#[instrument(skip(ocx), level = "debug")]
|
||||||
fn try_extract_error_from_fulfill_cx<'tcx>(
|
fn try_extract_error_from_fulfill_cx<'tcx>(
|
||||||
ocx: &ObligationCtxt<'_, 'tcx>,
|
ocx: &ObligationCtxt<'_, 'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
) -> Option<Diag<'tcx>> {
|
) -> Option<Diag<'tcx>> {
|
||||||
|
@ -368,6 +371,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
|
||||||
let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
|
let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
|
||||||
try_extract_error_from_region_constraints(
|
try_extract_error_from_region_constraints(
|
||||||
ocx.infcx,
|
ocx.infcx,
|
||||||
|
generic_param_scope,
|
||||||
placeholder_region,
|
placeholder_region,
|
||||||
error_region,
|
error_region,
|
||||||
®ion_constraints,
|
®ion_constraints,
|
||||||
|
@ -379,6 +383,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
|
||||||
#[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))]
|
#[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))]
|
||||||
fn try_extract_error_from_region_constraints<'tcx>(
|
fn try_extract_error_from_region_constraints<'tcx>(
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
region_constraints: &RegionConstraintData<'tcx>,
|
region_constraints: &RegionConstraintData<'tcx>,
|
||||||
|
@ -452,12 +457,15 @@ fn try_extract_error_from_region_constraints<'tcx>(
|
||||||
RegionResolutionError::ConcreteFailure(cause.clone(), sub_region, placeholder_region)
|
RegionResolutionError::ConcreteFailure(cause.clone(), sub_region, placeholder_region)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
NiceRegionError::new(&infcx.err_ctxt(), error).try_report_from_nll().or_else(|| {
|
NiceRegionError::new(&infcx.err_ctxt(), generic_param_scope, error)
|
||||||
|
.try_report_from_nll()
|
||||||
|
.or_else(|| {
|
||||||
if let SubregionOrigin::Subtype(trace) = cause {
|
if let SubregionOrigin::Subtype(trace) = cause {
|
||||||
Some(
|
Some(
|
||||||
infcx
|
infcx.err_ctxt().report_and_explain_type_error(
|
||||||
.err_ctxt()
|
*trace,
|
||||||
.report_and_explain_type_error(*trace, TypeError::RegionsPlaceholderMismatch),
|
TypeError::RegionsPlaceholderMismatch,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -361,6 +361,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
|
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
|
||||||
let diag = unexpected_hidden_region_diagnostic(
|
let diag = unexpected_hidden_region_diagnostic(
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
|
self.mir_def_id(),
|
||||||
span,
|
span,
|
||||||
named_ty,
|
named_ty,
|
||||||
named_region,
|
named_region,
|
||||||
|
@ -453,7 +454,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
// Check if we can use one of the "nice region errors".
|
// Check if we can use one of the "nice region errors".
|
||||||
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
|
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
|
||||||
let infer_err = self.infcx.err_ctxt();
|
let infer_err = self.infcx.err_ctxt();
|
||||||
let nice = NiceRegionError::new_from_span(&infer_err, cause.span, o, f);
|
let nice =
|
||||||
|
NiceRegionError::new_from_span(&infer_err, self.mir_def_id(), cause.span, o, f);
|
||||||
if let Some(diag) = nice.try_report_from_nll() {
|
if let Some(diag) = nice.try_report_from_nll() {
|
||||||
self.buffer_error(diag);
|
self.buffer_error(diag);
|
||||||
return;
|
return;
|
||||||
|
@ -843,14 +845,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
if *outlived_f != ty::ReStatic {
|
if *outlived_f != ty::ReStatic {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let suitable_region = self.infcx.tcx.is_suitable_region(f);
|
let suitable_region = self.infcx.tcx.is_suitable_region(self.mir_def_id(), f);
|
||||||
let Some(suitable_region) = suitable_region else {
|
let Some(suitable_region) = suitable_region else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id);
|
let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id);
|
||||||
|
|
||||||
let param = if let Some(param) = find_param_with_region(self.infcx.tcx, f, outlived_f) {
|
let param = if let Some(param) =
|
||||||
|
find_param_with_region(self.infcx.tcx, self.mir_def_id(), f, outlived_f)
|
||||||
|
{
|
||||||
param
|
param
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -959,7 +963,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let param = match find_param_with_region(tcx, f, o) {
|
let param = match find_param_with_region(tcx, self.mir_def_id(), f, o) {
|
||||||
Some(param) => param,
|
Some(param) => param,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
@ -1022,25 +1026,30 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some((ty_sub, _)) = self
|
let Some((ty_sub, _)) =
|
||||||
.infcx
|
self.infcx.tcx.is_suitable_region(self.mir_def_id(), sub).and_then(|anon_reg| {
|
||||||
.tcx
|
find_anon_type(self.infcx.tcx, self.mir_def_id(), sub, &anon_reg.bound_region)
|
||||||
.is_suitable_region(sub)
|
})
|
||||||
.and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.bound_region))
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some((ty_sup, _)) = self
|
let Some((ty_sup, _)) =
|
||||||
.infcx
|
self.infcx.tcx.is_suitable_region(self.mir_def_id(), sup).and_then(|anon_reg| {
|
||||||
.tcx
|
find_anon_type(self.infcx.tcx, self.mir_def_id(), sup, &anon_reg.bound_region)
|
||||||
.is_suitable_region(sup)
|
})
|
||||||
.and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.bound_region))
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag);
|
suggest_adding_lifetime_params(
|
||||||
|
self.infcx.tcx,
|
||||||
|
diag,
|
||||||
|
self.mir_def_id(),
|
||||||
|
sub,
|
||||||
|
ty_sup,
|
||||||
|
ty_sub,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
|
|
|
@ -289,7 +289,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
debug!("give_region_a_name: error_region = {:?}", error_region);
|
debug!("give_region_a_name: error_region = {:?}", error_region);
|
||||||
match *error_region {
|
match *error_region {
|
||||||
ty::ReEarlyParam(ebr) => ebr.has_name().then(|| {
|
ty::ReEarlyParam(ebr) => ebr.has_name().then(|| {
|
||||||
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
|
let def_id = tcx.generics_of(self.mir_def_id()).region_param(ebr, tcx).def_id;
|
||||||
|
let span = tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
|
||||||
RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyParamRegion(span) }
|
RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyParamRegion(span) }
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -912,7 +913,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
let region_parent = tcx.parent(region.def_id);
|
let region_def = tcx.generics_of(self.mir_def_id()).region_param(region, tcx).def_id;
|
||||||
|
let region_parent = tcx.parent(region_def);
|
||||||
let DefKind::Impl { .. } = tcx.def_kind(region_parent) else {
|
let DefKind::Impl { .. } = tcx.def_kind(region_parent) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
@ -925,7 +927,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
Some(RegionName {
|
Some(RegionName {
|
||||||
name: self.synthesize_region_name(),
|
name: self.synthesize_region_name(),
|
||||||
source: RegionNameSource::AnonRegionFromImplSignature(
|
source: RegionNameSource::AnonRegionFromImplSignature(
|
||||||
tcx.def_span(region.def_id),
|
tcx.def_span(region_def),
|
||||||
// FIXME(compiler-errors): Does this ever actually show up
|
// FIXME(compiler-errors): Does this ever actually show up
|
||||||
// anywhere other than the self type? I couldn't create an
|
// anywhere other than the self type? I couldn't create an
|
||||||
// example of a `'_` in the impl's trait being referenceable.
|
// example of a `'_` in the impl's trait being referenceable.
|
||||||
|
|
|
@ -925,7 +925,6 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||||
Ok(ty::Region::new_early_param(
|
Ok(ty::Region::new_early_param(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ty::EarlyParamRegion {
|
ty::EarlyParamRegion {
|
||||||
def_id: e.def_id,
|
|
||||||
name: e.name,
|
name: e.name,
|
||||||
index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
|
index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
|
||||||
},
|
},
|
||||||
|
|
|
@ -675,11 +675,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||||
let region_param = gat_generics.param_at(*region_a_idx, tcx);
|
let region_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||||
let region_param = ty::Region::new_early_param(
|
let region_param = ty::Region::new_early_param(
|
||||||
tcx,
|
tcx,
|
||||||
ty::EarlyParamRegion {
|
ty::EarlyParamRegion { index: region_param.index, name: region_param.name },
|
||||||
def_id: region_param.def_id,
|
|
||||||
index: region_param.index,
|
|
||||||
name: region_param.name,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
// The predicate we expect to see. (In our example,
|
// The predicate we expect to see. (In our example,
|
||||||
// `Self: 'me`.)
|
// `Self: 'me`.)
|
||||||
|
@ -708,21 +704,13 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||||
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
|
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||||
let region_a_param = ty::Region::new_early_param(
|
let region_a_param = ty::Region::new_early_param(
|
||||||
tcx,
|
tcx,
|
||||||
ty::EarlyParamRegion {
|
ty::EarlyParamRegion { index: region_a_param.index, name: region_a_param.name },
|
||||||
def_id: region_a_param.def_id,
|
|
||||||
index: region_a_param.index,
|
|
||||||
name: region_a_param.name,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
// Same for the region.
|
// Same for the region.
|
||||||
let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
|
let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
|
||||||
let region_b_param = ty::Region::new_early_param(
|
let region_b_param = ty::Region::new_early_param(
|
||||||
tcx,
|
tcx,
|
||||||
ty::EarlyParamRegion {
|
ty::EarlyParamRegion { index: region_b_param.index, name: region_b_param.name },
|
||||||
def_id: region_b_param.def_id,
|
|
||||||
index: region_b_param.index,
|
|
||||||
name: region_b_param.name,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
// The predicate we expect to see.
|
// The predicate we expect to see.
|
||||||
bounds.insert(
|
bounds.insert(
|
||||||
|
|
|
@ -453,7 +453,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
||||||
poly_trait_ref,
|
poly_trait_ref,
|
||||||
|_| {
|
|_| {
|
||||||
ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
|
ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
|
||||||
def_id: item_def_id,
|
|
||||||
index: 0,
|
index: 0,
|
||||||
name: Symbol::intern(<_name),
|
name: Symbol::intern(<_name),
|
||||||
})
|
})
|
||||||
|
|
|
@ -323,7 +323,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
|
||||||
if let ty::ReEarlyParam(..) = *orig_lifetime {
|
if let ty::ReEarlyParam(..) = *orig_lifetime {
|
||||||
let dup_lifetime = ty::Region::new_early_param(
|
let dup_lifetime = ty::Region::new_early_param(
|
||||||
tcx,
|
tcx,
|
||||||
ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name },
|
ty::EarlyParamRegion { index: param.index, name: param.name },
|
||||||
);
|
);
|
||||||
let span = tcx.def_span(param.def_id);
|
let span = tcx.def_span(param.def_id);
|
||||||
predicates.push((
|
predicates.push((
|
||||||
|
|
|
@ -280,7 +280,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
|
let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
|
||||||
let generics = tcx.generics_of(item_def_id);
|
let generics = tcx.generics_of(item_def_id);
|
||||||
let index = generics.param_def_id_to_index[&def_id];
|
let index = generics.param_def_id_to_index[&def_id];
|
||||||
ty::Region::new_early_param(tcx, ty::EarlyParamRegion { def_id, index, name })
|
ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(rbv::ResolvedArg::Free(scope, id)) => {
|
Some(rbv::ResolvedArg::Free(scope, id)) => {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use rustc_errors::{
|
||||||
MultiSpan, SubdiagMessageOp, Subdiagnostic,
|
MultiSpan, SubdiagMessageOp, Subdiagnostic,
|
||||||
};
|
};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::intravisit::{walk_ty, Visitor};
|
use rustc_hir::intravisit::{walk_ty, Visitor};
|
||||||
use rustc_hir::FnRetTy;
|
use rustc_hir::FnRetTy;
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
|
@ -344,6 +345,7 @@ impl Subdiagnostic for LifetimeMismatchLabels {
|
||||||
|
|
||||||
pub struct AddLifetimeParamsSuggestion<'a> {
|
pub struct AddLifetimeParamsSuggestion<'a> {
|
||||||
pub tcx: TyCtxt<'a>,
|
pub tcx: TyCtxt<'a>,
|
||||||
|
pub generic_param_scope: LocalDefId,
|
||||||
pub sub: Region<'a>,
|
pub sub: Region<'a>,
|
||||||
pub ty_sup: &'a hir::Ty<'a>,
|
pub ty_sup: &'a hir::Ty<'a>,
|
||||||
pub ty_sub: &'a hir::Ty<'a>,
|
pub ty_sub: &'a hir::Ty<'a>,
|
||||||
|
@ -357,7 +359,8 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
|
||||||
_f: &F,
|
_f: &F,
|
||||||
) {
|
) {
|
||||||
let mut mk_suggestion = || {
|
let mut mk_suggestion = || {
|
||||||
let Some(anon_reg) = self.tcx.is_suitable_region(self.sub) else {
|
let Some(anon_reg) = self.tcx.is_suitable_region(self.generic_param_scope, self.sub)
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::fluent_generated as fluent;
|
use crate::fluent_generated as fluent;
|
||||||
use crate::infer::error_reporting::nice_region_error::find_anon_type;
|
use crate::infer::error_reporting::nice_region_error::find_anon_type;
|
||||||
use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic};
|
use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic};
|
||||||
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_span::{symbol::kw, Span};
|
use rustc_span::{symbol::kw, Span};
|
||||||
|
@ -14,12 +15,15 @@ struct DescriptionCtx<'a> {
|
||||||
impl<'a> DescriptionCtx<'a> {
|
impl<'a> DescriptionCtx<'a> {
|
||||||
fn new<'tcx>(
|
fn new<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
alt_span: Option<Span>,
|
alt_span: Option<Span>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let (span, kind, arg) = match *region {
|
let (span, kind, arg) = match *region {
|
||||||
ty::ReEarlyParam(ref br) => {
|
ty::ReEarlyParam(br) => {
|
||||||
let scope = region.free_region_binding_scope(tcx).expect_local();
|
let scope = tcx
|
||||||
|
.parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id)
|
||||||
|
.expect_local();
|
||||||
let span = if let Some(param) =
|
let span = if let Some(param) =
|
||||||
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
|
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
|
||||||
{
|
{
|
||||||
|
@ -35,11 +39,12 @@ impl<'a> DescriptionCtx<'a> {
|
||||||
}
|
}
|
||||||
ty::ReLateParam(ref fr) => {
|
ty::ReLateParam(ref fr) => {
|
||||||
if !fr.bound_region.is_named()
|
if !fr.bound_region.is_named()
|
||||||
&& let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
|
&& let Some((ty, _)) =
|
||||||
|
find_anon_type(tcx, generic_param_scope, region, &fr.bound_region)
|
||||||
{
|
{
|
||||||
(Some(ty.span), "defined_here", String::new())
|
(Some(ty.span), "defined_here", String::new())
|
||||||
} else {
|
} else {
|
||||||
let scope = region.free_region_binding_scope(tcx).expect_local();
|
let scope = fr.scope.expect_local();
|
||||||
match fr.bound_region {
|
match fr.bound_region {
|
||||||
ty::BoundRegionKind::BrNamed(_, name) => {
|
ty::BoundRegionKind::BrNamed(_, name) => {
|
||||||
let span = if let Some(param) = tcx
|
let span = if let Some(param) = tcx
|
||||||
|
@ -143,12 +148,17 @@ pub struct RegionExplanation<'a> {
|
||||||
impl RegionExplanation<'_> {
|
impl RegionExplanation<'_> {
|
||||||
pub fn new<'tcx>(
|
pub fn new<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
alt_span: Option<Span>,
|
alt_span: Option<Span>,
|
||||||
prefix: PrefixKind,
|
prefix: PrefixKind,
|
||||||
suffix: SuffixKind,
|
suffix: SuffixKind,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
Some(Self { desc: DescriptionCtx::new(tcx, region, alt_span)?, prefix, suffix })
|
Some(Self {
|
||||||
|
desc: DescriptionCtx::new(tcx, generic_param_scope, region, alt_span)?,
|
||||||
|
prefix,
|
||||||
|
suffix,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,6 +161,7 @@ impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> {
|
||||||
pub(super) fn note_and_explain_region<'tcx>(
|
pub(super) fn note_and_explain_region<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
suffix: &str,
|
suffix: &str,
|
||||||
|
@ -168,7 +169,7 @@ pub(super) fn note_and_explain_region<'tcx>(
|
||||||
) {
|
) {
|
||||||
let (description, span) = match *region {
|
let (description, span) = match *region {
|
||||||
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => {
|
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => {
|
||||||
msg_span_from_named_region(tcx, region, alt_span)
|
msg_span_from_named_region(tcx, generic_param_scope, region, alt_span)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReError(_) => return,
|
ty::ReError(_) => return,
|
||||||
|
@ -187,23 +188,27 @@ pub(super) fn note_and_explain_region<'tcx>(
|
||||||
fn explain_free_region<'tcx>(
|
fn explain_free_region<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
suffix: &str,
|
suffix: &str,
|
||||||
) {
|
) {
|
||||||
let (description, span) = msg_span_from_named_region(tcx, region, None);
|
let (description, span) = msg_span_from_named_region(tcx, generic_param_scope, region, None);
|
||||||
|
|
||||||
label_msg_span(err, prefix, description, span, suffix);
|
label_msg_span(err, prefix, description, span, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msg_span_from_named_region<'tcx>(
|
fn msg_span_from_named_region<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
alt_span: Option<Span>,
|
alt_span: Option<Span>,
|
||||||
) -> (String, Option<Span>) {
|
) -> (String, Option<Span>) {
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReEarlyParam(ref br) => {
|
ty::ReEarlyParam(br) => {
|
||||||
let scope = region.free_region_binding_scope(tcx).expect_local();
|
let scope = tcx
|
||||||
|
.parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id)
|
||||||
|
.expect_local();
|
||||||
let span = if let Some(param) =
|
let span = if let Some(param) =
|
||||||
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
|
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
|
||||||
{
|
{
|
||||||
|
@ -220,21 +225,21 @@ fn msg_span_from_named_region<'tcx>(
|
||||||
}
|
}
|
||||||
ty::ReLateParam(ref fr) => {
|
ty::ReLateParam(ref fr) => {
|
||||||
if !fr.bound_region.is_named()
|
if !fr.bound_region.is_named()
|
||||||
&& let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
|
&& let Some((ty, _)) =
|
||||||
|
find_anon_type(tcx, generic_param_scope, region, &fr.bound_region)
|
||||||
{
|
{
|
||||||
("the anonymous lifetime defined here".to_string(), Some(ty.span))
|
("the anonymous lifetime defined here".to_string(), Some(ty.span))
|
||||||
} else {
|
} else {
|
||||||
let scope = region.free_region_binding_scope(tcx).expect_local();
|
|
||||||
match fr.bound_region {
|
match fr.bound_region {
|
||||||
ty::BoundRegionKind::BrNamed(_, name) => {
|
ty::BoundRegionKind::BrNamed(_, name) => {
|
||||||
let span = if let Some(param) = tcx
|
let span = if let Some(param) = tcx
|
||||||
.hir()
|
.hir()
|
||||||
.get_generics(scope)
|
.get_generics(generic_param_scope)
|
||||||
.and_then(|generics| generics.get_named(name))
|
.and_then(|generics| generics.get_named(name))
|
||||||
{
|
{
|
||||||
param.span
|
param.span
|
||||||
} else {
|
} else {
|
||||||
tcx.def_span(scope)
|
tcx.def_span(generic_param_scope)
|
||||||
};
|
};
|
||||||
let text = if name == kw::UnderscoreLifetime {
|
let text = if name == kw::UnderscoreLifetime {
|
||||||
"the anonymous lifetime as defined here".to_string()
|
"the anonymous lifetime as defined here".to_string()
|
||||||
|
@ -245,11 +250,11 @@ fn msg_span_from_named_region<'tcx>(
|
||||||
}
|
}
|
||||||
ty::BrAnon => (
|
ty::BrAnon => (
|
||||||
"the anonymous lifetime as defined here".to_string(),
|
"the anonymous lifetime as defined here".to_string(),
|
||||||
Some(tcx.def_span(scope)),
|
Some(tcx.def_span(generic_param_scope)),
|
||||||
),
|
),
|
||||||
_ => (
|
_ => (
|
||||||
format!("the lifetime `{region}` as defined here"),
|
format!("the lifetime `{region}` as defined here"),
|
||||||
Some(tcx.def_span(scope)),
|
Some(tcx.def_span(generic_param_scope)),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,6 +307,7 @@ fn label_msg_span(
|
||||||
#[instrument(level = "trace", skip(tcx))]
|
#[instrument(level = "trace", skip(tcx))]
|
||||||
pub fn unexpected_hidden_region_diagnostic<'tcx>(
|
pub fn unexpected_hidden_region_diagnostic<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
span: Span,
|
span: Span,
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
hidden_region: ty::Region<'tcx>,
|
hidden_region: ty::Region<'tcx>,
|
||||||
|
@ -327,11 +333,12 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
|
||||||
explain_free_region(
|
explain_free_region(
|
||||||
tcx,
|
tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
&format!("hidden type `{hidden_ty}` captures "),
|
&format!("hidden type `{hidden_ty}` captures "),
|
||||||
hidden_region,
|
hidden_region,
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
if let Some(reg_info) = tcx.is_suitable_region(hidden_region) {
|
if let Some(reg_info) = tcx.is_suitable_region(generic_param_scope, hidden_region) {
|
||||||
let fn_returns = tcx.return_type_impl_or_dyn_traits(reg_info.def_id);
|
let fn_returns = tcx.return_type_impl_or_dyn_traits(reg_info.def_id);
|
||||||
nice_region_error::suggest_new_region_bound(
|
nice_region_error::suggest_new_region_bound(
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -349,6 +356,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
|
||||||
explain_free_region(
|
explain_free_region(
|
||||||
tcx,
|
tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
&format!("hidden type `{}` captures ", hidden_ty),
|
&format!("hidden type `{}` captures ", hidden_ty),
|
||||||
hidden_region,
|
hidden_region,
|
||||||
"",
|
"",
|
||||||
|
@ -376,6 +384,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
|
||||||
note_and_explain_region(
|
note_and_explain_region(
|
||||||
tcx,
|
tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
&format!("hidden type `{hidden_ty}` captures "),
|
&format!("hidden type `{hidden_ty}` captures "),
|
||||||
hidden_region,
|
hidden_region,
|
||||||
"",
|
"",
|
||||||
|
@ -450,7 +459,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
for error in errors {
|
for error in errors {
|
||||||
debug!("report_region_errors: error = {:?}", error);
|
debug!("report_region_errors: error = {:?}", error);
|
||||||
|
|
||||||
guar = Some(if let Some(guar) = self.try_report_nice_region_error(&error) {
|
let e = if let Some(guar) =
|
||||||
|
self.try_report_nice_region_error(generic_param_scope, &error)
|
||||||
|
{
|
||||||
guar
|
guar
|
||||||
} else {
|
} else {
|
||||||
match error.clone() {
|
match error.clone() {
|
||||||
|
@ -463,9 +474,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
// general bit of code that displays the error information
|
// general bit of code that displays the error information
|
||||||
RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
|
RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
|
||||||
if sub.is_placeholder() || sup.is_placeholder() {
|
if sub.is_placeholder() || sup.is_placeholder() {
|
||||||
self.report_placeholder_failure(origin, sub, sup).emit()
|
self.report_placeholder_failure(generic_param_scope, origin, sub, sup)
|
||||||
|
.emit()
|
||||||
} else {
|
} else {
|
||||||
self.report_concrete_failure(origin, sub, sup).emit()
|
self.report_concrete_failure(generic_param_scope, origin, sub, sup)
|
||||||
|
.emit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,12 +501,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
_,
|
_,
|
||||||
) => {
|
) => {
|
||||||
if sub_r.is_placeholder() {
|
if sub_r.is_placeholder() {
|
||||||
self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit()
|
self.report_placeholder_failure(
|
||||||
|
generic_param_scope,
|
||||||
|
sub_origin,
|
||||||
|
sub_r,
|
||||||
|
sup_r,
|
||||||
|
)
|
||||||
|
.emit()
|
||||||
} else if sup_r.is_placeholder() {
|
} else if sup_r.is_placeholder() {
|
||||||
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit()
|
self.report_placeholder_failure(
|
||||||
|
generic_param_scope,
|
||||||
|
sup_origin,
|
||||||
|
sub_r,
|
||||||
|
sup_r,
|
||||||
|
)
|
||||||
|
.emit()
|
||||||
} else {
|
} else {
|
||||||
self.report_sub_sup_conflict(
|
self.report_sub_sup_conflict(
|
||||||
var_origin, sub_origin, sub_r, sup_origin, sup_r,
|
generic_param_scope,
|
||||||
|
var_origin,
|
||||||
|
sub_origin,
|
||||||
|
sub_r,
|
||||||
|
sup_origin,
|
||||||
|
sup_r,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -514,7 +544,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
// value.
|
// value.
|
||||||
let sub_r = self.tcx.lifetimes.re_erased;
|
let sub_r = self.tcx.lifetimes.re_erased;
|
||||||
|
|
||||||
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit()
|
self.report_placeholder_failure(
|
||||||
|
generic_param_scope,
|
||||||
|
sup_origin,
|
||||||
|
sub_r,
|
||||||
|
sup_r,
|
||||||
|
)
|
||||||
|
.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionResolutionError::CannotNormalize(clause, origin) => {
|
RegionResolutionError::CannotNormalize(clause, origin) => {
|
||||||
|
@ -526,7 +562,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
.emit()
|
.emit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
};
|
||||||
|
|
||||||
|
guar = Some(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
guar.unwrap()
|
guar.unwrap()
|
||||||
|
@ -2347,7 +2385,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
'_explain: {
|
'_explain: {
|
||||||
let (description, span) = match sub.kind() {
|
let (description, span) = match sub.kind() {
|
||||||
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
|
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
|
||||||
msg_span_from_named_region(self.tcx, sub, Some(span))
|
msg_span_from_named_region(self.tcx, generic_param_scope, sub, Some(span))
|
||||||
}
|
}
|
||||||
_ => (format!("lifetime `{sub}`"), Some(span)),
|
_ => (format!("lifetime `{sub}`"), Some(span)),
|
||||||
};
|
};
|
||||||
|
@ -2398,7 +2436,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
let suggestion_scope = {
|
let suggestion_scope = {
|
||||||
let lifetime_scope = match sub.kind() {
|
let lifetime_scope = match sub.kind() {
|
||||||
ty::ReStatic => hir::def_id::CRATE_DEF_ID,
|
ty::ReStatic => hir::def_id::CRATE_DEF_ID,
|
||||||
_ => match self.tcx.is_suitable_region(sub) {
|
_ => match self.tcx.is_suitable_region(generic_param_scope, sub) {
|
||||||
Some(info) => info.def_id,
|
Some(info) => info.def_id,
|
||||||
None => generic_param_scope,
|
None => generic_param_scope,
|
||||||
},
|
},
|
||||||
|
@ -2410,7 +2448,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut suggs = vec![];
|
let mut suggs = vec![];
|
||||||
let lt_name = self.suggest_name_region(sub, &mut suggs);
|
let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs);
|
||||||
|
|
||||||
if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span
|
if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span
|
||||||
&& suggestion_scope == type_scope
|
&& suggestion_scope == type_scope
|
||||||
|
@ -2455,6 +2493,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
|
|
||||||
pub fn suggest_name_region(
|
pub fn suggest_name_region(
|
||||||
&self,
|
&self,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
lifetime: Region<'tcx>,
|
lifetime: Region<'tcx>,
|
||||||
add_lt_suggs: &mut Vec<(Span, String)>,
|
add_lt_suggs: &mut Vec<(Span, String)>,
|
||||||
) -> String {
|
) -> String {
|
||||||
|
@ -2501,7 +2540,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (lifetime_def_id, lifetime_scope) = match self.tcx.is_suitable_region(lifetime) {
|
let (lifetime_def_id, lifetime_scope) =
|
||||||
|
match self.tcx.is_suitable_region(generic_param_scope, lifetime) {
|
||||||
Some(info) if !lifetime.has_name() => {
|
Some(info) if !lifetime.has_name() => {
|
||||||
(info.bound_region.get_id().unwrap().expect_local(), info.def_id)
|
(info.bound_region.get_id().unwrap().expect_local(), info.def_id)
|
||||||
}
|
}
|
||||||
|
@ -2557,6 +2597,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
|
|
||||||
fn report_sub_sup_conflict(
|
fn report_sub_sup_conflict(
|
||||||
&self,
|
&self,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
var_origin: RegionVariableOrigin,
|
var_origin: RegionVariableOrigin,
|
||||||
sub_origin: SubregionOrigin<'tcx>,
|
sub_origin: SubregionOrigin<'tcx>,
|
||||||
sub_region: Region<'tcx>,
|
sub_region: Region<'tcx>,
|
||||||
|
@ -2568,6 +2609,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
note_and_explain_region(
|
note_and_explain_region(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
"first, the lifetime cannot outlive ",
|
"first, the lifetime cannot outlive ",
|
||||||
sup_region,
|
sup_region,
|
||||||
"...",
|
"...",
|
||||||
|
@ -2590,6 +2632,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
note_and_explain_region(
|
note_and_explain_region(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
"...but the lifetime must also be valid for ",
|
"...but the lifetime must also be valid for ",
|
||||||
sub_region,
|
sub_region,
|
||||||
"...",
|
"...",
|
||||||
|
@ -2613,6 +2656,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
note_and_explain_region(
|
note_and_explain_region(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
"but, the lifetime must be valid for ",
|
"but, the lifetime must be valid for ",
|
||||||
sub_region,
|
sub_region,
|
||||||
"...",
|
"...",
|
||||||
|
|
|
@ -13,6 +13,7 @@ use crate::infer::TyCtxt;
|
||||||
|
|
||||||
use rustc_errors::Subdiagnostic;
|
use rustc_errors::Subdiagnostic;
|
||||||
use rustc_errors::{Diag, ErrorGuaranteed};
|
use rustc_errors::{Diag, ErrorGuaranteed};
|
||||||
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::Ty;
|
use rustc_hir::Ty;
|
||||||
use rustc_middle::ty::Region;
|
use rustc_middle::ty::Region;
|
||||||
|
|
||||||
|
@ -66,17 +67,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine whether the sub and sup consist of both anonymous (elided) regions.
|
// Determine whether the sub and sup consist of both anonymous (elided) regions.
|
||||||
let anon_reg_sup = self.tcx().is_suitable_region(sup)?;
|
let anon_reg_sup = self.tcx().is_suitable_region(self.generic_param_scope, sup)?;
|
||||||
|
|
||||||
let anon_reg_sub = self.tcx().is_suitable_region(sub)?;
|
let anon_reg_sub = self.tcx().is_suitable_region(self.generic_param_scope, sub)?;
|
||||||
let scope_def_id_sup = anon_reg_sup.def_id;
|
let scope_def_id_sup = anon_reg_sup.def_id;
|
||||||
let bregion_sup = anon_reg_sup.bound_region;
|
let bregion_sup = anon_reg_sup.bound_region;
|
||||||
let scope_def_id_sub = anon_reg_sub.def_id;
|
let scope_def_id_sub = anon_reg_sub.def_id;
|
||||||
let bregion_sub = anon_reg_sub.bound_region;
|
let bregion_sub = anon_reg_sub.bound_region;
|
||||||
|
|
||||||
let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?;
|
let ty_sup = find_anon_type(self.tcx(), self.generic_param_scope, sup, &bregion_sup)?;
|
||||||
|
|
||||||
let ty_sub = find_anon_type(self.tcx(), sub, &bregion_sub)?;
|
let ty_sub = find_anon_type(self.tcx(), self.generic_param_scope, sub, &bregion_sub)?;
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}",
|
"try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}",
|
||||||
|
@ -127,8 +128,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let suggestion =
|
let suggestion = AddLifetimeParamsSuggestion {
|
||||||
AddLifetimeParamsSuggestion { tcx: self.tcx(), sub, ty_sup, ty_sub, add_note: true };
|
tcx: self.tcx(),
|
||||||
|
sub,
|
||||||
|
ty_sup,
|
||||||
|
ty_sub,
|
||||||
|
add_note: true,
|
||||||
|
generic_param_scope: self.generic_param_scope,
|
||||||
|
};
|
||||||
let err = LifetimeMismatch { span, labels, suggestion };
|
let err = LifetimeMismatch { span, labels, suggestion };
|
||||||
let reported = self.tcx().dcx().emit_err(err);
|
let reported = self.tcx().dcx().emit_err(err);
|
||||||
Some(reported)
|
Some(reported)
|
||||||
|
@ -139,11 +146,19 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
/// removed in favour of public_errors::AddLifetimeParamsSuggestion
|
/// removed in favour of public_errors::AddLifetimeParamsSuggestion
|
||||||
pub fn suggest_adding_lifetime_params<'tcx>(
|
pub fn suggest_adding_lifetime_params<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
err: &mut Diag<'_>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
sub: Region<'tcx>,
|
sub: Region<'tcx>,
|
||||||
ty_sup: &'tcx Ty<'_>,
|
ty_sup: &'tcx Ty<'_>,
|
||||||
ty_sub: &'tcx Ty<'_>,
|
ty_sub: &'tcx Ty<'_>,
|
||||||
err: &mut Diag<'_>,
|
|
||||||
) {
|
) {
|
||||||
let suggestion = AddLifetimeParamsSuggestion { tcx, sub, ty_sup, ty_sub, add_note: false };
|
let suggestion = AddLifetimeParamsSuggestion {
|
||||||
|
tcx,
|
||||||
|
sub,
|
||||||
|
ty_sup,
|
||||||
|
ty_sub,
|
||||||
|
add_note: false,
|
||||||
|
generic_param_scope,
|
||||||
|
};
|
||||||
suggestion.add_to_diag(err);
|
suggestion.add_to_diag(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use core::ops::ControlFlow;
|
use core::ops::ControlFlow;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
|
@ -23,10 +24,11 @@ use rustc_middle::ty::{self, Region, TyCtxt};
|
||||||
/// for e.g., `&u8` and `Vec<&u8>`.
|
/// for e.g., `&u8` and `Vec<&u8>`.
|
||||||
pub fn find_anon_type<'tcx>(
|
pub fn find_anon_type<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
region: Region<'tcx>,
|
region: Region<'tcx>,
|
||||||
br: &ty::BoundRegionKind,
|
br: &ty::BoundRegionKind,
|
||||||
) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> {
|
) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> {
|
||||||
let anon_reg = tcx.is_suitable_region(region)?;
|
let anon_reg = tcx.is_suitable_region(generic_param_scope, region)?;
|
||||||
let fn_sig = tcx.hir_node_by_def_id(anon_reg.def_id).fn_sig()?;
|
let fn_sig = tcx.hir_node_by_def_id(anon_reg.def_id).fn_sig()?;
|
||||||
|
|
||||||
fn_sig
|
fn_sig
|
||||||
|
|
|
@ -57,6 +57,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
|
|
||||||
let expl = note_and_explain::RegionExplanation::new(
|
let expl = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
|
self.generic_param_scope,
|
||||||
sup,
|
sup,
|
||||||
Some(binding_span),
|
Some(binding_span),
|
||||||
note_and_explain::PrefixKind::Empty,
|
note_and_explain::PrefixKind::Empty,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::infer::error_reporting::TypeErrCtxt;
|
||||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||||
use crate::infer::lexical_region_resolve::RegionResolutionError::*;
|
use crate::infer::lexical_region_resolve::RegionResolutionError::*;
|
||||||
use rustc_errors::{Diag, ErrorGuaranteed};
|
use rustc_errors::{Diag, ErrorGuaranteed};
|
||||||
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -23,30 +24,39 @@ pub use util::find_param_with_region;
|
||||||
impl<'cx, 'tcx> TypeErrCtxt<'cx, 'tcx> {
|
impl<'cx, 'tcx> TypeErrCtxt<'cx, 'tcx> {
|
||||||
pub fn try_report_nice_region_error(
|
pub fn try_report_nice_region_error(
|
||||||
&'cx self,
|
&'cx self,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
error: &RegionResolutionError<'tcx>,
|
error: &RegionResolutionError<'tcx>,
|
||||||
) -> Option<ErrorGuaranteed> {
|
) -> Option<ErrorGuaranteed> {
|
||||||
NiceRegionError::new(self, error.clone()).try_report()
|
NiceRegionError::new(self, generic_param_scope, error.clone()).try_report()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NiceRegionError<'cx, 'tcx> {
|
pub struct NiceRegionError<'cx, 'tcx> {
|
||||||
cx: &'cx TypeErrCtxt<'cx, 'tcx>,
|
cx: &'cx TypeErrCtxt<'cx, 'tcx>,
|
||||||
|
/// The innermost definition that introduces generic parameters that may be involved in
|
||||||
|
/// the region errors we are dealing with.
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
error: Option<RegionResolutionError<'tcx>>,
|
error: Option<RegionResolutionError<'tcx>>,
|
||||||
regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>,
|
regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
|
impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
|
||||||
pub fn new(cx: &'cx TypeErrCtxt<'cx, 'tcx>, error: RegionResolutionError<'tcx>) -> Self {
|
pub fn new(
|
||||||
Self { cx, error: Some(error), regions: None }
|
cx: &'cx TypeErrCtxt<'cx, 'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
|
error: RegionResolutionError<'tcx>,
|
||||||
|
) -> Self {
|
||||||
|
Self { cx, error: Some(error), regions: None, generic_param_scope }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_span(
|
pub fn new_from_span(
|
||||||
cx: &'cx TypeErrCtxt<'cx, 'tcx>,
|
cx: &'cx TypeErrCtxt<'cx, 'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
span: Span,
|
span: Span,
|
||||||
sub: ty::Region<'tcx>,
|
sub: ty::Region<'tcx>,
|
||||||
sup: ty::Region<'tcx>,
|
sup: ty::Region<'tcx>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { cx, error: None, regions: Some((span, sub, sup)) }
|
Self { cx, error: None, regions: Some((span, sub, sup)), generic_param_scope }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
|
|
|
@ -27,12 +27,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
// version new_ty of its type where the anonymous region is replaced
|
// version new_ty of its type where the anonymous region is replaced
|
||||||
// with the named one.
|
// with the named one.
|
||||||
let (named, anon, anon_param_info, region_info) = if sub.has_name()
|
let (named, anon, anon_param_info, region_info) = if sub.has_name()
|
||||||
&& let Some(region_info) = self.tcx().is_suitable_region(sup)
|
&& let Some(region_info) = self.tcx().is_suitable_region(self.generic_param_scope, sup)
|
||||||
&& let Some(anon_param_info) = self.find_param_with_region(sup, sub)
|
&& let Some(anon_param_info) = self.find_param_with_region(sup, sub)
|
||||||
{
|
{
|
||||||
(sub, sup, anon_param_info, region_info)
|
(sub, sup, anon_param_info, region_info)
|
||||||
} else if sup.has_name()
|
} else if sup.has_name()
|
||||||
&& let Some(region_info) = self.tcx().is_suitable_region(sub)
|
&& let Some(region_info) = self.tcx().is_suitable_region(self.generic_param_scope, sub)
|
||||||
&& let Some(anon_param_info) = self.find_param_with_region(sub, sup)
|
&& let Some(anon_param_info) = self.find_param_with_region(sub, sup)
|
||||||
{
|
{
|
||||||
(sup, sub, anon_param_info, region_info)
|
(sup, sub, anon_param_info, region_info)
|
||||||
|
@ -72,7 +72,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if find_anon_type(self.tcx(), anon, &br).is_some()
|
if find_anon_type(self.tcx(), self.generic_param_scope, anon, &br).is_some()
|
||||||
&& self.is_self_anon(is_first, scope_def_id)
|
&& self.is_self_anon(is_first, scope_def_id)
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -49,7 +49,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() {
|
if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() {
|
||||||
// This may have a closure and it would cause ICE
|
// This may have a closure and it would cause ICE
|
||||||
// through `find_param_with_region` (#78262).
|
// through `find_param_with_region` (#78262).
|
||||||
let anon_reg_sup = tcx.is_suitable_region(*sup_r)?;
|
let anon_reg_sup = tcx.is_suitable_region(self.generic_param_scope, *sup_r)?;
|
||||||
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
|
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
|
||||||
if fn_returns.is_empty() {
|
if fn_returns.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -92,7 +92,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
"try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
|
"try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
|
||||||
var_origin, sub_origin, sub_r, sup_origin, sup_r
|
var_origin, sub_origin, sub_r, sup_origin, sup_r
|
||||||
);
|
);
|
||||||
let anon_reg_sup = tcx.is_suitable_region(*sup_r)?;
|
let anon_reg_sup = tcx.is_suitable_region(self.generic_param_scope, *sup_r)?;
|
||||||
debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
|
debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
|
||||||
let sp = var_origin.span();
|
let sp = var_origin.span();
|
||||||
let return_sp = sub_origin.span();
|
let return_sp = sub_origin.span();
|
||||||
|
|
|
@ -37,13 +37,15 @@ pub struct AnonymousParamInfo<'tcx> {
|
||||||
#[instrument(skip(tcx), level = "debug")]
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
pub fn find_param_with_region<'tcx>(
|
pub fn find_param_with_region<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
anon_region: Region<'tcx>,
|
anon_region: Region<'tcx>,
|
||||||
replace_region: Region<'tcx>,
|
replace_region: Region<'tcx>,
|
||||||
) -> Option<AnonymousParamInfo<'tcx>> {
|
) -> Option<AnonymousParamInfo<'tcx>> {
|
||||||
let (id, bound_region) = match *anon_region {
|
let (id, bound_region) = match *anon_region {
|
||||||
ty::ReLateParam(late_param) => (late_param.scope, late_param.bound_region),
|
ty::ReLateParam(late_param) => (late_param.scope, late_param.bound_region),
|
||||||
ty::ReEarlyParam(ebr) => {
|
ty::ReEarlyParam(ebr) => {
|
||||||
(tcx.parent(ebr.def_id), ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name))
|
let region_def = tcx.generics_of(generic_param_scope).region_param(ebr, tcx).def_id;
|
||||||
|
(tcx.parent(region_def), ty::BoundRegionKind::BrNamed(region_def, ebr.name))
|
||||||
}
|
}
|
||||||
_ => return None, // not a free region
|
_ => return None, // not a free region
|
||||||
};
|
};
|
||||||
|
@ -53,7 +55,7 @@ pub fn find_param_with_region<'tcx>(
|
||||||
|
|
||||||
// FIXME: use def_kind
|
// FIXME: use def_kind
|
||||||
// Don't perform this on closures
|
// Don't perform this on closures
|
||||||
match tcx.hir_node_by_def_id(def_id) {
|
match tcx.hir_node_by_def_id(generic_param_scope) {
|
||||||
hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
|
hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +112,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
anon_region: Region<'tcx>,
|
anon_region: Region<'tcx>,
|
||||||
replace_region: Region<'tcx>,
|
replace_region: Region<'tcx>,
|
||||||
) -> Option<AnonymousParamInfo<'tcx>> {
|
) -> Option<AnonymousParamInfo<'tcx>> {
|
||||||
find_param_with_region(self.tcx(), anon_region, replace_region)
|
find_param_with_region(self.tcx(), self.generic_param_scope, anon_region, replace_region)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here, we check for the case where the anonymous region
|
// Here, we check for the case where the anonymous region
|
||||||
|
|
|
@ -75,6 +75,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
|
|
||||||
pub(super) fn report_concrete_failure(
|
pub(super) fn report_concrete_failure(
|
||||||
&self,
|
&self,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
sub: Region<'tcx>,
|
sub: Region<'tcx>,
|
||||||
sup: Region<'tcx>,
|
sup: Region<'tcx>,
|
||||||
|
@ -89,6 +90,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
note_and_explain_region(
|
note_and_explain_region(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
"",
|
"",
|
||||||
sup,
|
sup,
|
||||||
" doesn't meet the lifetime requirements",
|
" doesn't meet the lifetime requirements",
|
||||||
|
@ -99,6 +101,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
note_and_explain_region(
|
note_and_explain_region(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
"the required lifetime does not necessarily outlive ",
|
"the required lifetime does not necessarily outlive ",
|
||||||
sub,
|
sub,
|
||||||
"",
|
"",
|
||||||
|
@ -106,10 +109,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
note_and_explain_region(self.tcx, &mut err, "", sup, "...", None);
|
|
||||||
note_and_explain_region(
|
note_and_explain_region(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
|
"",
|
||||||
|
sup,
|
||||||
|
"...",
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
note_and_explain_region(
|
||||||
|
self.tcx,
|
||||||
|
&mut err,
|
||||||
|
generic_param_scope,
|
||||||
"...does not necessarily outlive ",
|
"...does not necessarily outlive ",
|
||||||
sub,
|
sub,
|
||||||
"",
|
"",
|
||||||
|
@ -122,6 +134,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
infer::Reborrow(span) => {
|
infer::Reborrow(span) => {
|
||||||
let reference_valid = note_and_explain::RegionExplanation::new(
|
let reference_valid = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sub,
|
sub,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::RefValidFor,
|
note_and_explain::PrefixKind::RefValidFor,
|
||||||
|
@ -129,6 +142,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
let content_valid = note_and_explain::RegionExplanation::new(
|
let content_valid = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sup,
|
sup,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::ContentValidFor,
|
note_and_explain::PrefixKind::ContentValidFor,
|
||||||
|
@ -142,6 +156,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
infer::RelateObjectBound(span) => {
|
infer::RelateObjectBound(span) => {
|
||||||
let object_valid = note_and_explain::RegionExplanation::new(
|
let object_valid = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sub,
|
sub,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::TypeObjValidFor,
|
note_and_explain::PrefixKind::TypeObjValidFor,
|
||||||
|
@ -149,6 +164,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
let pointer_valid = note_and_explain::RegionExplanation::new(
|
let pointer_valid = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sup,
|
sup,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::SourcePointerValidFor,
|
note_and_explain::PrefixKind::SourcePointerValidFor,
|
||||||
|
@ -170,7 +186,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
note_and_explain::SuffixKind::Empty
|
note_and_explain::SuffixKind::Empty
|
||||||
};
|
};
|
||||||
let note = note_and_explain::RegionExplanation::new(
|
let note = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx, sub, opt_span, prefix, suffix,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
|
sub,
|
||||||
|
opt_span,
|
||||||
|
prefix,
|
||||||
|
suffix,
|
||||||
);
|
);
|
||||||
self.dcx().create_err(FulfillReqLifetime {
|
self.dcx().create_err(FulfillReqLifetime {
|
||||||
span,
|
span,
|
||||||
|
@ -181,6 +202,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
infer::RelateRegionParamBound(span) => {
|
infer::RelateRegionParamBound(span) => {
|
||||||
let param_instantiated = note_and_explain::RegionExplanation::new(
|
let param_instantiated = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sup,
|
sup,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::LfParamInstantiatedWith,
|
note_and_explain::PrefixKind::LfParamInstantiatedWith,
|
||||||
|
@ -188,6 +210,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
let param_must_outlive = note_and_explain::RegionExplanation::new(
|
let param_must_outlive = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sub,
|
sub,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::LfParamMustOutlive,
|
note_and_explain::PrefixKind::LfParamMustOutlive,
|
||||||
|
@ -201,6 +224,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
infer::ReferenceOutlivesReferent(ty, span) => {
|
infer::ReferenceOutlivesReferent(ty, span) => {
|
||||||
let pointer_valid = note_and_explain::RegionExplanation::new(
|
let pointer_valid = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sub,
|
sub,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::PointerValidFor,
|
note_and_explain::PrefixKind::PointerValidFor,
|
||||||
|
@ -208,6 +232,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
let data_valid = note_and_explain::RegionExplanation::new(
|
let data_valid = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sup,
|
sup,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::DataValidFor,
|
note_and_explain::PrefixKind::DataValidFor,
|
||||||
|
@ -239,7 +264,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
|
infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
|
||||||
let mut err = self.report_concrete_failure(*parent, sub, sup);
|
let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup);
|
||||||
|
|
||||||
// Don't mention the item name if it's an RPITIT, since that'll just confuse
|
// Don't mention the item name if it's an RPITIT, since that'll just confuse
|
||||||
// folks.
|
// folks.
|
||||||
|
@ -262,6 +287,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
infer::AscribeUserTypeProvePredicate(span) => {
|
infer::AscribeUserTypeProvePredicate(span) => {
|
||||||
let instantiated = note_and_explain::RegionExplanation::new(
|
let instantiated = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sup,
|
sup,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::LfInstantiatedWith,
|
note_and_explain::PrefixKind::LfInstantiatedWith,
|
||||||
|
@ -269,6 +295,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
let must_outlive = note_and_explain::RegionExplanation::new(
|
let must_outlive = note_and_explain::RegionExplanation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
|
generic_param_scope,
|
||||||
sub,
|
sub,
|
||||||
None,
|
None,
|
||||||
note_and_explain::PrefixKind::LfMustOutlive,
|
note_and_explain::PrefixKind::LfMustOutlive,
|
||||||
|
@ -347,6 +374,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
|
|
||||||
pub(super) fn report_placeholder_failure(
|
pub(super) fn report_placeholder_failure(
|
||||||
&self,
|
&self,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
placeholder_origin: SubregionOrigin<'tcx>,
|
placeholder_origin: SubregionOrigin<'tcx>,
|
||||||
sub: Region<'tcx>,
|
sub: Region<'tcx>,
|
||||||
sup: Region<'tcx>,
|
sup: Region<'tcx>,
|
||||||
|
@ -368,7 +396,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
&& !span.is_dummy()
|
&& !span.is_dummy()
|
||||||
{
|
{
|
||||||
let span = *span;
|
let span = *span;
|
||||||
self.report_concrete_failure(placeholder_origin, sub, sup)
|
self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup)
|
||||||
.with_span_note(span, "the lifetime requirement is introduced here")
|
.with_span_note(span, "the lifetime requirement is introduced here")
|
||||||
} else {
|
} else {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
|
@ -380,7 +408,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
let terr = TypeError::RegionsPlaceholderMismatch;
|
let terr = TypeError::RegionsPlaceholderMismatch;
|
||||||
return self.report_and_explain_type_error(trace, terr);
|
return self.report_and_explain_type_error(trace, terr);
|
||||||
}
|
}
|
||||||
_ => return self.report_concrete_failure(placeholder_origin, sub, sup),
|
_ => {
|
||||||
|
return self.report_concrete_failure(
|
||||||
|
generic_param_scope,
|
||||||
|
placeholder_origin,
|
||||||
|
sub,
|
||||||
|
sup,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1950,14 +1950,22 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN
|
||||||
|
|
||||||
impl ExplicitOutlivesRequirements {
|
impl ExplicitOutlivesRequirements {
|
||||||
fn lifetimes_outliving_lifetime<'tcx>(
|
fn lifetimes_outliving_lifetime<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)],
|
inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)],
|
||||||
def_id: DefId,
|
item: DefId,
|
||||||
|
lifetime: DefId,
|
||||||
) -> Vec<ty::Region<'tcx>> {
|
) -> Vec<ty::Region<'tcx>> {
|
||||||
|
let item_generics = tcx.generics_of(item);
|
||||||
|
|
||||||
inferred_outlives
|
inferred_outlives
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(clause, _)| match clause.kind().skip_binder() {
|
.filter_map(|(clause, _)| match clause.kind().skip_binder() {
|
||||||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
|
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
|
||||||
ty::ReEarlyParam(ebr) if ebr.def_id == def_id => Some(b),
|
ty::ReEarlyParam(ebr)
|
||||||
|
if item_generics.region_param(ebr, tcx).def_id == lifetime =>
|
||||||
|
{
|
||||||
|
Some(b)
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1986,6 +1994,7 @@ impl ExplicitOutlivesRequirements {
|
||||||
bounds: &hir::GenericBounds<'_>,
|
bounds: &hir::GenericBounds<'_>,
|
||||||
inferred_outlives: &[ty::Region<'tcx>],
|
inferred_outlives: &[ty::Region<'tcx>],
|
||||||
predicate_span: Span,
|
predicate_span: Span,
|
||||||
|
item: DefId,
|
||||||
) -> Vec<(usize, Span)> {
|
) -> Vec<(usize, Span)> {
|
||||||
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
|
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
|
||||||
|
|
||||||
|
@ -2000,7 +2009,7 @@ impl ExplicitOutlivesRequirements {
|
||||||
let is_inferred = match tcx.named_bound_var(lifetime.hir_id) {
|
let is_inferred = match tcx.named_bound_var(lifetime.hir_id) {
|
||||||
Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives
|
Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives
|
||||||
.iter()
|
.iter()
|
||||||
.any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { ebr.def_id == def_id })),
|
.any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { tcx.generics_of(item).region_param(ebr, tcx).def_id == def_id })),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2109,7 +2118,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
Self::lifetimes_outliving_lifetime(
|
Self::lifetimes_outliving_lifetime(
|
||||||
|
cx.tcx,
|
||||||
inferred_outlives,
|
inferred_outlives,
|
||||||
|
item.owner_id.to_def_id(),
|
||||||
region_def_id,
|
region_def_id,
|
||||||
),
|
),
|
||||||
&predicate.bounds,
|
&predicate.bounds,
|
||||||
|
@ -2152,6 +2163,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
||||||
bounds,
|
bounds,
|
||||||
&relevant_lifetimes,
|
&relevant_lifetimes,
|
||||||
predicate_span,
|
predicate_span,
|
||||||
|
item.owner_id.to_def_id(),
|
||||||
);
|
);
|
||||||
bound_count += bound_spans.len();
|
bound_count += bound_spans.len();
|
||||||
|
|
||||||
|
|
|
@ -1488,13 +1488,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
|
/// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
|
||||||
pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option<FreeRegionInfo> {
|
pub fn is_suitable_region(
|
||||||
|
self,
|
||||||
|
generic_param_scope: LocalDefId,
|
||||||
|
mut region: Region<'tcx>,
|
||||||
|
) -> Option<FreeRegionInfo> {
|
||||||
let (suitable_region_binding_scope, bound_region) = loop {
|
let (suitable_region_binding_scope, bound_region) = loop {
|
||||||
let def_id = match region.kind() {
|
let def_id =
|
||||||
ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?,
|
region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
|
||||||
ty::ReEarlyParam(ebr) => ebr.def_id.as_local()?,
|
|
||||||
_ => return None, // not a free region
|
|
||||||
};
|
|
||||||
let scope = self.local_parent(def_id);
|
let scope = self.local_parent(def_id);
|
||||||
if self.def_kind(scope) == DefKind::OpaqueTy {
|
if self.def_kind(scope) == DefKind::OpaqueTy {
|
||||||
// Lifetime params of opaque types are synthetic and thus irrelevant to
|
// Lifetime params of opaque types are synthetic and thus irrelevant to
|
||||||
|
@ -2633,7 +2634,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
return ty::Region::new_early_param(
|
return ty::Region::new_early_param(
|
||||||
self,
|
self,
|
||||||
ty::EarlyParamRegion {
|
ty::EarlyParamRegion {
|
||||||
def_id: ebv,
|
|
||||||
index: generics
|
index: generics
|
||||||
.param_def_id_to_index(self, ebv)
|
.param_def_id_to_index(self, ebv)
|
||||||
.expect("early-bound var should be present in fn generics"),
|
.expect("early-bound var should be present in fn generics"),
|
||||||
|
|
|
@ -66,7 +66,7 @@ pub struct GenericParamDef {
|
||||||
impl GenericParamDef {
|
impl GenericParamDef {
|
||||||
pub fn to_early_bound_region_data(&self) -> ty::EarlyParamRegion {
|
pub fn to_early_bound_region_data(&self) -> ty::EarlyParamRegion {
|
||||||
if let GenericParamDefKind::Lifetime = self.kind {
|
if let GenericParamDefKind::Lifetime = self.kind {
|
||||||
ty::EarlyParamRegion { def_id: self.def_id, index: self.index, name: self.name }
|
ty::EarlyParamRegion { index: self.index, name: self.name }
|
||||||
} else {
|
} else {
|
||||||
bug!("cannot convert a non-lifetime parameter def to an early bound region")
|
bug!("cannot convert a non-lifetime parameter def to an early bound region")
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,33 +265,6 @@ impl<'tcx> Region<'tcx> {
|
||||||
flags
|
flags
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an early-bound or free region, returns the `DefId` where it was bound.
|
|
||||||
/// For example, consider the regions in this snippet of code:
|
|
||||||
///
|
|
||||||
/// ```ignore (illustrative)
|
|
||||||
/// impl<'a> Foo {
|
|
||||||
/// // ^^ -- early bound, declared on an impl
|
|
||||||
///
|
|
||||||
/// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c
|
|
||||||
/// // ^^ ^^ ^ anonymous, late-bound
|
|
||||||
/// // | early-bound, appears in where-clauses
|
|
||||||
/// // late-bound, appears only in fn args
|
|
||||||
/// {..}
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Here, `free_region_binding_scope('a)` would return the `DefId`
|
|
||||||
/// of the impl, and for all the other highlighted regions, it
|
|
||||||
/// would return the `DefId` of the function. In other cases (not shown), this
|
|
||||||
/// function might return the `DefId` of a closure.
|
|
||||||
pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId {
|
|
||||||
match *self {
|
|
||||||
ty::ReEarlyParam(br) => tcx.parent(br.def_id),
|
|
||||||
ty::ReLateParam(fr) => fr.scope,
|
|
||||||
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// True for free regions other than `'static`.
|
/// True for free regions other than `'static`.
|
||||||
pub fn is_param(self) -> bool {
|
pub fn is_param(self) -> bool {
|
||||||
matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_))
|
matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_))
|
||||||
|
|
|
@ -771,7 +771,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
|
||||||
use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind};
|
use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind};
|
||||||
match self {
|
match self {
|
||||||
ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion {
|
ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion {
|
||||||
def_id: tables.region_def(early_reg.def_id),
|
def_id: tables.region_def(todo!()),
|
||||||
index: early_reg.index,
|
index: early_reg.index,
|
||||||
name: early_reg.name.to_string(),
|
name: early_reg.name.to_string(),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -185,6 +185,7 @@ fn do_normalize_predicates<'tcx>(
|
||||||
predicates: Vec<ty::Clause<'tcx>>,
|
predicates: Vec<ty::Clause<'tcx>>,
|
||||||
) -> Result<Vec<ty::Clause<'tcx>>, ErrorGuaranteed> {
|
) -> Result<Vec<ty::Clause<'tcx>>, ErrorGuaranteed> {
|
||||||
let span = cause.span;
|
let span = cause.span;
|
||||||
|
|
||||||
// FIXME. We should really... do something with these region
|
// FIXME. We should really... do something with these region
|
||||||
// obligations. But this call just continues the older
|
// obligations. But this call just continues the older
|
||||||
// behavior (i.e., doesn't cause any new bugs), and it would
|
// behavior (i.e., doesn't cause any new bugs), and it would
|
||||||
|
|
|
@ -79,11 +79,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
|
||||||
orig_lt,
|
orig_lt,
|
||||||
ty::Region::new_early_param(
|
ty::Region::new_early_param(
|
||||||
tcx,
|
tcx,
|
||||||
ty::EarlyParamRegion {
|
ty::EarlyParamRegion { index: param.index, name: param.name },
|
||||||
def_id: param.def_id,
|
|
||||||
index: param.index,
|
|
||||||
name: param.name,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0])` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/impl-trait-captures.rs:11:5
|
--> $DIR/impl-trait-captures.rs:11:5
|
||||||
|
|
|
|
||||||
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
|
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
|
||||||
|
@ -8,7 +8,7 @@ LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
|
||||||
LL | x
|
LL | x
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: to declare that `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:14 ~ impl_trait_captures[aeb9]::foo::{opaque#0}::'a)_'a/#2])` captures `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`, you can add an explicit `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))` lifetime bound
|
help: to declare that `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#2])` captures `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`, you can add an explicit `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))` lifetime bound
|
||||||
|
|
|
|
||||||
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) {
|
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) {
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue