about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2019-10-18 04:24:22 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-10-24 20:06:37 +0300
commit93cac9c3da06e1fbbdee10df7525234ffc7c76cd (patch)
tree8c4d3d33ea26b7cb62c2ae9ed8243f76e537e0d4 /src
parent8e0007f829661e57d008d2e908c95f6e84b04b25 (diff)
downloadrust-93cac9c3da06e1fbbdee10df7525234ffc7c76cd.tar.gz
rust-93cac9c3da06e1fbbdee10df7525234ffc7c76cd.zip
rustc: add `Span`s to `inferred_outlives_of` predicates.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/query/mod.rs2
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc_lint/builtin.rs10
-rw-r--r--src/librustc_typeck/collect.rs15
-rw-r--r--src/librustc_typeck/outlives/mod.rs33
5 files changed, 39 insertions, 23 deletions
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index fdca6d0e17a..7cae74b59c7 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -191,7 +191,7 @@ rustc_queries! {
 
         /// Returns the inferred outlives predicates (e.g., for `struct
         /// 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
         /// super-predicates. This is a subset of the full list of
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index feede00fea1..e58ba9d6a2b 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1136,7 +1136,7 @@ pub struct CratePredicatesMap<'tcx> {
     /// For each struct with outlive bounds, maps to a vector of the
     /// predicate of its outlive bounds. If an item has no outlives
     /// 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> {
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index ad674911e6f..7c19449f96b 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1497,10 +1497,10 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN
 
 impl ExplicitOutlivesRequirements {
     fn lifetimes_outliving_lifetime<'tcx>(
-        inferred_outlives: &'tcx [ty::Predicate<'tcx>],
+        inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
         index: u32,
     ) -> Vec<ty::Region<'tcx>> {
-        inferred_outlives.iter().filter_map(|pred| {
+        inferred_outlives.iter().filter_map(|(pred, _)| {
             match pred {
                 ty::Predicate::RegionOutlives(outlives) => {
                     let outlives = outlives.skip_binder();
@@ -1517,10 +1517,10 @@ impl ExplicitOutlivesRequirements {
     }
 
     fn lifetimes_outliving_type<'tcx>(
-        inferred_outlives: &'tcx [ty::Predicate<'tcx>],
+        inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
         index: u32,
     ) -> Vec<ty::Region<'tcx>> {
-        inferred_outlives.iter().filter_map(|pred| {
+        inferred_outlives.iter().filter_map(|(pred, _)| {
             match pred {
                 ty::Predicate::TypeOutlives(outlives) => {
                     let outlives = outlives.skip_binder();
@@ -1539,7 +1539,7 @@ impl ExplicitOutlivesRequirements {
         &self,
         param: &'tcx hir::GenericParam,
         tcx: TyCtxt<'tcx>,
-        inferred_outlives: &'tcx [ty::Predicate<'tcx>],
+        inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
         ty_generics: &'tcx ty::Generics,
     ) -> Vec<ty::Region<'tcx>> {
         let index = ty_generics.param_def_id_to_index[
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index d4c64512f98..78347ded726 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1970,19 +1970,18 @@ fn predicates_defined_on(
     );
     let inferred_outlives = tcx.inferred_outlives_of(def_id);
     if !inferred_outlives.is_empty() {
-        let span = tcx.def_span(def_id);
         debug!(
             "predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
             def_id,
             inferred_outlives,
         );
-        result.predicates = tcx.arena.alloc_from_iter(
-            result.predicates.iter().copied().chain(
-                // FIXME(eddyb) use better spans - maybe add `Span`s
-                // to `inferred_outlives_of` predicates as well?
-                inferred_outlives.iter().map(|&p| (p, span)),
-            ),
-        );
+        if result.predicates.is_empty() {
+            result.predicates = inferred_outlives;
+        } else {
+            result.predicates = tcx.arena.alloc_from_iter(
+                result.predicates.iter().chain(inferred_outlives).copied(),
+            );
+        }
     }
     debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
     result
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index cdb83eb328a..b2699fffc2c 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -5,6 +5,7 @@ use rustc::ty::query::Providers;
 use rustc::ty::subst::GenericArgKind;
 use rustc::ty::{self, CratePredicatesMap, TyCtxt};
 use syntax::symbol::sym;
+use syntax_pos::Span;
 
 mod explicit;
 mod implicit_infer;
@@ -23,7 +24,7 @@ pub fn provide(providers: &mut Providers<'_>) {
 fn inferred_outlives_of(
     tcx: TyCtxt<'_>,
     item_def_id: DefId,
-) -> &[ty::Predicate<'_>] {
+) -> &[(ty::Predicate<'_>, Span)] {
     let id = tcx
         .hir()
         .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) {
                     let mut pred: Vec<String> = predicates
                         .iter()
-                        .map(|out_pred| match out_pred {
+                        .map(|(out_pred, _)| match out_pred {
                             ty::Predicate::RegionOutlives(p) => p.to_string(),
                             ty::Predicate::TypeOutlives(p) => p.to_string(),
                             err => bug!("unexpected predicate {:?}", err),
@@ -96,19 +97,35 @@ fn inferred_outlives_crate(
     let predicates = global_inferred_outlives
         .iter()
         .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()
                 .filter_map(
                     |ty::OutlivesPredicate(kind1, region2)| match kind1.unpack() {
                         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)
-                            )))
+                            )), span))
                         }
                         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))
-                            ))
+                            ), span))
                         }
                         GenericArgKind::Const(_) => {
                             // Generic consts don't impose any constraints.
@@ -116,7 +133,7 @@ fn inferred_outlives_crate(
                         }
                     },
                 ));
-            (def_id, &*predicates)
+            (def_id, predicates)
         }).collect();
 
     tcx.arena.alloc(ty::CratePredicatesMap {