rustc: add Span
s to inferred_outlives_of
predicates.
This commit is contained in:
parent
8e0007f829
commit
93cac9c3da
5 changed files with 39 additions and 23 deletions
|
@ -191,7 +191,7 @@ rustc_queries! {
|
||||||
|
|
||||||
/// Returns the inferred outlives predicates (e.g., for `struct
|
/// Returns the inferred outlives predicates (e.g., for `struct
|
||||||
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
|
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
|
||||||
query inferred_outlives_of(_: DefId) -> &'tcx [ty::Predicate<'tcx>] {}
|
query inferred_outlives_of(_: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {}
|
||||||
|
|
||||||
/// Maps from the `DefId` of a trait to the list of
|
/// Maps from the `DefId` of a trait to the list of
|
||||||
/// super-predicates. This is a subset of the full list of
|
/// super-predicates. This is a subset of the full list of
|
||||||
|
|
|
@ -1136,7 +1136,7 @@ pub struct CratePredicatesMap<'tcx> {
|
||||||
/// For each struct with outlive bounds, maps to a vector of the
|
/// For each struct with outlive bounds, maps to a vector of the
|
||||||
/// predicate of its outlive bounds. If an item has no outlives
|
/// predicate of its outlive bounds. If an item has no outlives
|
||||||
/// bounds, it will have no entry.
|
/// bounds, it will have no entry.
|
||||||
pub predicates: FxHashMap<DefId, &'tcx [ty::Predicate<'tcx>]>,
|
pub predicates: FxHashMap<DefId, &'tcx [(ty::Predicate<'tcx>, Span)]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
|
impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
|
||||||
|
|
|
@ -1497,10 +1497,10 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN
|
||||||
|
|
||||||
impl ExplicitOutlivesRequirements {
|
impl ExplicitOutlivesRequirements {
|
||||||
fn lifetimes_outliving_lifetime<'tcx>(
|
fn lifetimes_outliving_lifetime<'tcx>(
|
||||||
inferred_outlives: &'tcx [ty::Predicate<'tcx>],
|
inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
|
||||||
index: u32,
|
index: u32,
|
||||||
) -> Vec<ty::Region<'tcx>> {
|
) -> Vec<ty::Region<'tcx>> {
|
||||||
inferred_outlives.iter().filter_map(|pred| {
|
inferred_outlives.iter().filter_map(|(pred, _)| {
|
||||||
match pred {
|
match pred {
|
||||||
ty::Predicate::RegionOutlives(outlives) => {
|
ty::Predicate::RegionOutlives(outlives) => {
|
||||||
let outlives = outlives.skip_binder();
|
let outlives = outlives.skip_binder();
|
||||||
|
@ -1517,10 +1517,10 @@ impl ExplicitOutlivesRequirements {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lifetimes_outliving_type<'tcx>(
|
fn lifetimes_outliving_type<'tcx>(
|
||||||
inferred_outlives: &'tcx [ty::Predicate<'tcx>],
|
inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
|
||||||
index: u32,
|
index: u32,
|
||||||
) -> Vec<ty::Region<'tcx>> {
|
) -> Vec<ty::Region<'tcx>> {
|
||||||
inferred_outlives.iter().filter_map(|pred| {
|
inferred_outlives.iter().filter_map(|(pred, _)| {
|
||||||
match pred {
|
match pred {
|
||||||
ty::Predicate::TypeOutlives(outlives) => {
|
ty::Predicate::TypeOutlives(outlives) => {
|
||||||
let outlives = outlives.skip_binder();
|
let outlives = outlives.skip_binder();
|
||||||
|
@ -1539,7 +1539,7 @@ impl ExplicitOutlivesRequirements {
|
||||||
&self,
|
&self,
|
||||||
param: &'tcx hir::GenericParam,
|
param: &'tcx hir::GenericParam,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
inferred_outlives: &'tcx [ty::Predicate<'tcx>],
|
inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
|
||||||
ty_generics: &'tcx ty::Generics,
|
ty_generics: &'tcx ty::Generics,
|
||||||
) -> Vec<ty::Region<'tcx>> {
|
) -> Vec<ty::Region<'tcx>> {
|
||||||
let index = ty_generics.param_def_id_to_index[
|
let index = ty_generics.param_def_id_to_index[
|
||||||
|
|
|
@ -1970,20 +1970,19 @@ fn predicates_defined_on(
|
||||||
);
|
);
|
||||||
let inferred_outlives = tcx.inferred_outlives_of(def_id);
|
let inferred_outlives = tcx.inferred_outlives_of(def_id);
|
||||||
if !inferred_outlives.is_empty() {
|
if !inferred_outlives.is_empty() {
|
||||||
let span = tcx.def_span(def_id);
|
|
||||||
debug!(
|
debug!(
|
||||||
"predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
|
"predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
|
||||||
def_id,
|
def_id,
|
||||||
inferred_outlives,
|
inferred_outlives,
|
||||||
);
|
);
|
||||||
|
if result.predicates.is_empty() {
|
||||||
|
result.predicates = inferred_outlives;
|
||||||
|
} else {
|
||||||
result.predicates = tcx.arena.alloc_from_iter(
|
result.predicates = tcx.arena.alloc_from_iter(
|
||||||
result.predicates.iter().copied().chain(
|
result.predicates.iter().chain(inferred_outlives).copied(),
|
||||||
// FIXME(eddyb) use better spans - maybe add `Span`s
|
|
||||||
// to `inferred_outlives_of` predicates as well?
|
|
||||||
inferred_outlives.iter().map(|&p| (p, span)),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
|
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use rustc::ty::query::Providers;
|
||||||
use rustc::ty::subst::GenericArgKind;
|
use rustc::ty::subst::GenericArgKind;
|
||||||
use rustc::ty::{self, CratePredicatesMap, TyCtxt};
|
use rustc::ty::{self, CratePredicatesMap, TyCtxt};
|
||||||
use syntax::symbol::sym;
|
use syntax::symbol::sym;
|
||||||
|
use syntax_pos::Span;
|
||||||
|
|
||||||
mod explicit;
|
mod explicit;
|
||||||
mod implicit_infer;
|
mod implicit_infer;
|
||||||
|
@ -23,7 +24,7 @@ pub fn provide(providers: &mut Providers<'_>) {
|
||||||
fn inferred_outlives_of(
|
fn inferred_outlives_of(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
item_def_id: DefId,
|
item_def_id: DefId,
|
||||||
) -> &[ty::Predicate<'_>] {
|
) -> &[(ty::Predicate<'_>, Span)] {
|
||||||
let id = tcx
|
let id = tcx
|
||||||
.hir()
|
.hir()
|
||||||
.as_local_hir_id(item_def_id)
|
.as_local_hir_id(item_def_id)
|
||||||
|
@ -43,7 +44,7 @@ fn inferred_outlives_of(
|
||||||
if tcx.has_attr(item_def_id, sym::rustc_outlives) {
|
if tcx.has_attr(item_def_id, sym::rustc_outlives) {
|
||||||
let mut pred: Vec<String> = predicates
|
let mut pred: Vec<String> = predicates
|
||||||
.iter()
|
.iter()
|
||||||
.map(|out_pred| match out_pred {
|
.map(|(out_pred, _)| match out_pred {
|
||||||
ty::Predicate::RegionOutlives(p) => p.to_string(),
|
ty::Predicate::RegionOutlives(p) => p.to_string(),
|
||||||
ty::Predicate::TypeOutlives(p) => p.to_string(),
|
ty::Predicate::TypeOutlives(p) => p.to_string(),
|
||||||
err => bug!("unexpected predicate {:?}", err),
|
err => bug!("unexpected predicate {:?}", err),
|
||||||
|
@ -96,19 +97,35 @@ fn inferred_outlives_crate(
|
||||||
let predicates = global_inferred_outlives
|
let predicates = global_inferred_outlives
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(&def_id, set)| {
|
.map(|(&def_id, set)| {
|
||||||
let predicates = tcx.arena.alloc_from_iter(set
|
let def_span = tcx.def_span(def_id);
|
||||||
|
let generics = tcx.generics_of(def_id);
|
||||||
|
let predicates = &*tcx.arena.alloc_from_iter(set
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(
|
.filter_map(
|
||||||
|ty::OutlivesPredicate(kind1, region2)| match kind1.unpack() {
|
|ty::OutlivesPredicate(kind1, region2)| match kind1.unpack() {
|
||||||
GenericArgKind::Type(ty1) => {
|
GenericArgKind::Type(ty1) => {
|
||||||
Some(ty::Predicate::TypeOutlives(ty::Binder::bind(
|
// FIXME(eddyb) compute `Span`s in `implicit_infer`.
|
||||||
|
let span = match &ty1.kind {
|
||||||
|
ty::Param(p) => {
|
||||||
|
tcx.def_span(generics.type_param(p, tcx).def_id)
|
||||||
|
}
|
||||||
|
_ => def_span,
|
||||||
|
};
|
||||||
|
Some((ty::Predicate::TypeOutlives(ty::Binder::bind(
|
||||||
ty::OutlivesPredicate(ty1, region2)
|
ty::OutlivesPredicate(ty1, region2)
|
||||||
)))
|
)), span))
|
||||||
}
|
}
|
||||||
GenericArgKind::Lifetime(region1) => {
|
GenericArgKind::Lifetime(region1) => {
|
||||||
Some(ty::Predicate::RegionOutlives(
|
// FIXME(eddyb) compute `Span`s in `implicit_infer`.
|
||||||
|
let span = match region1 {
|
||||||
|
ty::RegionKind::ReEarlyBound(p) => {
|
||||||
|
tcx.def_span(generics.region_param(p, tcx).def_id)
|
||||||
|
}
|
||||||
|
_ => def_span,
|
||||||
|
};
|
||||||
|
Some((ty::Predicate::RegionOutlives(
|
||||||
ty::Binder::bind(ty::OutlivesPredicate(region1, region2))
|
ty::Binder::bind(ty::OutlivesPredicate(region1, region2))
|
||||||
))
|
), span))
|
||||||
}
|
}
|
||||||
GenericArgKind::Const(_) => {
|
GenericArgKind::Const(_) => {
|
||||||
// Generic consts don't impose any constraints.
|
// Generic consts don't impose any constraints.
|
||||||
|
@ -116,7 +133,7 @@ fn inferred_outlives_crate(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
(def_id, &*predicates)
|
(def_id, predicates)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
tcx.arena.alloc(ty::CratePredicatesMap {
|
tcx.arena.alloc(ty::CratePredicatesMap {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue