]> git.lizzy.rs Git - rust.git/commitdiff
Trait item lifetime resolution for GATs
authorSunjay Varma <varma.sunjay@gmail.com>
Wed, 13 Dec 2017 02:11:15 +0000 (21:11 -0500)
committerSunjay Varma <varma.sunjay@gmail.com>
Wed, 13 Dec 2017 02:23:52 +0000 (21:23 -0500)
src/librustc/middle/resolve_lifetime.rs

index bafd1e8e6cc5d5bddc1b4eb3c7a9cd148360a7c9..d455108dad2c98dcd346204fa8c29d8e00af0ee3 100644 (file)
@@ -624,30 +624,77 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
     }
 
     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);
+            },
         }
     }