about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSunjay Varma <varma.sunjay@gmail.com>2017-12-12 21:11:15 -0500
committerSunjay Varma <varma.sunjay@gmail.com>2017-12-12 21:23:52 -0500
commit8cfaf1bab206f331d84830a818033009dcce0303 (patch)
treedf045bfa25fc0c05cf9bafedcd4aaecdad28d6df
parent442b7bd10ab1955832fac39e47671327747033c6 (diff)
downloadrust-8cfaf1bab206f331d84830a818033009dcce0303.tar.gz
rust-8cfaf1bab206f331d84830a818033009dcce0303.zip
Trait item lifetime resolution for GATs
-rw-r--r--src/librustc/middle/resolve_lifetime.rs87
1 files changed, 67 insertions, 20 deletions
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index bafd1e8e6cc..d455108dad2 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -624,30 +624,77 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     }
 
     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
-        let tcx = self.tcx;
-        if let hir::TraitItemKind::Method(ref sig, _) = trait_item.node {
-            self.visit_early_late(
-                Some(tcx.hir.get_parent(trait_item.id)),
-                &sig.decl,
-                &trait_item.generics,
-                |this| intravisit::walk_trait_item(this, trait_item),
-            )
-        } else {
-            intravisit::walk_trait_item(self, trait_item);
+        use self::hir::TraitItemKind::*;
+        match trait_item.node {
+            Method(ref sig, _) => {
+                let tcx = self.tcx;
+                self.visit_early_late(
+                    Some(tcx.hir.get_parent(trait_item.id)),
+                    &sig.decl,
+                    &trait_item.generics,
+                    |this| intravisit::walk_trait_item(this, trait_item),
+                );
+            },
+            Type(ref bounds, ref ty) => {
+                let generics = &trait_item.generics;
+                let mut index = self.next_early_index();
+                debug!("visit_ty: index = {}", index);
+                let lifetimes = generics.lifetimes.iter()
+                    .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
+                    .collect();
+
+                let next_early_index = index + generics.ty_params.len() as u32;
+                let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
+                self.with(scope, |_old_scope, this| {
+                    this.visit_generics(generics);
+                    for bound in bounds {
+                        this.visit_ty_param_bound(bound);
+                    }
+                    if let Some(ty) = ty {
+                        this.visit_ty(ty);
+                    }
+                });
+            },
+            Const(_, _) => {
+                // Only methods and types support generics.
+                assert!(!trait_item.generics.is_parameterized());
+                intravisit::walk_trait_item(self, trait_item);
+            },
         }
     }
 
     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
-        let tcx = self.tcx;
-        if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
-            self.visit_early_late(
-                Some(tcx.hir.get_parent(impl_item.id)),
-                &sig.decl,
-                &impl_item.generics,
-                |this| intravisit::walk_impl_item(this, impl_item),
-            )
-        } else {
-            intravisit::walk_impl_item(self, impl_item);
+        use self::hir::ImplItemKind::*;
+        match impl_item.node {
+            Method(ref sig, _) => {
+                let tcx = self.tcx;
+                self.visit_early_late(
+                    Some(tcx.hir.get_parent(impl_item.id)),
+                    &sig.decl,
+                    &impl_item.generics,
+                    |this| intravisit::walk_impl_item(this, impl_item),
+                )
+            },
+            Type(ref ty) => {
+                let generics = &impl_item.generics;
+                let mut index = self.next_early_index();
+                debug!("visit_ty: index = {}", index);
+                let lifetimes = generics.lifetimes.iter()
+                    .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
+                    .collect();
+
+                let next_early_index = index + generics.ty_params.len() as u32;
+                let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
+                self.with(scope, |_old_scope, this| {
+                    this.visit_generics(generics);
+                    this.visit_ty(ty);
+                });
+            },
+            Const(_, _) => {
+                // Only methods and types support generics.
+                assert!(!impl_item.generics.is_parameterized());
+                intravisit::walk_impl_item(self, impl_item);
+            },
         }
     }