]> git.lizzy.rs Git - rust.git/commitdiff
Fixed bug with Self type param coming before lifetimes.
authorAlexander Regueiro <alexreg@me.com>
Thu, 1 Nov 2018 21:52:56 +0000 (21:52 +0000)
committerAlexander Regueiro <alexreg@me.com>
Sat, 3 Nov 2018 04:28:29 +0000 (04:28 +0000)
src/librustc/middle/resolve_lifetime.rs
src/librustc_typeck/collect.rs
src/test/run-pass/traits/trait-alias-bounds.rs
src/test/run-pass/traits/trait-alias-syntax.rs [new file with mode: 0644]

index 361abb1689619e1cd92ee0557b54cfef1f17b292..a387765085a29c940362c952c719d12a8214f17f 100644 (file)
@@ -447,6 +447,17 @@ fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap {
     map
 }
 
+/// In traits, there is an implicit `Self` type parameter which comes before the generics.
+/// We have to account for this when computing the index of the other generic parameters.
+/// This function returns whether there is such an implicit parameter defined on the given item.
+fn sub_items_have_self_param(node: &hir::ItemKind) -> bool {
+    match *node {
+        hir::ItemKind::Trait(..) |
+        hir::ItemKind::TraitAlias(..) => true,
+        _ => false,
+    }
+}
+
 impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
         NestedVisitorMap::All(&self.tcx.hir)
@@ -522,8 +533,8 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                     hir::ItemKind::Impl(..) => true,
                     _ => false,
                 };
-                // These kinds of items have only early bound lifetime parameters.
-                let mut index = if let hir::ItemKind::Trait(..) = item.node {
+                // These kinds of items have only early-bound lifetime parameters.
+                let mut index = if sub_items_have_self_param(&item.node) {
                     1 // Self comes before lifetimes
                 } else {
                     0
@@ -1602,8 +1613,8 @@ fn visit_early_late<F>(
         let mut index = 0;
         if let Some(parent_id) = parent_id {
             let parent = self.tcx.hir.expect_item(parent_id);
-            if let hir::ItemKind::Trait(..) = parent.node {
-                index += 1; // Self comes first.
+            if sub_items_have_self_param(&parent.node) {
+                index += 1; // Self comes before lifetimes
             }
             match parent.node {
                 hir::ItemKind::Trait(_, _, ref generics, ..)
index 917fb887e0b89be84b48cb38d6e7e722171bef29..c136d76e358d38b54309450a41c5b8d0597ca20d 100644 (file)
@@ -357,14 +357,12 @@ fn type_parameter_bounds_in_generics(
             .flat_map(|bp| {
                 let bt = if is_param(self.tcx, &bp.bounded_ty, param_id) {
                     Some(ty)
-                } else if only_self_bounds.0 {
-                    None
-                } else {
+                } else if !only_self_bounds.0 {
                     Some(self.to_ty(&bp.bounded_ty))
+                } else {
+                    None
                 };
-                bp.bounds.iter().filter_map(move |b| {
-                    if let Some(bt) = bt { Some((bt, b)) } else { None }
-                })
+                bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b)))
             })
             .flat_map(|(bt, b)| predicates_from_bound(self, bt, b));
 
index c1c3989107b28081b2435f053ccb930d316b6985..d8ac1a8c63464025cfcf01e467b6096ec4bd490c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 
 use std::marker::PhantomData;
 
-trait SimpleAlias = Default;
-trait GenericAlias<T> = Iterator<Item = T>;
-trait Partial<T> = IntoIterator<Item = T>;
-trait SpecificAlias = GenericAlias<i32>;
-trait PartialEqRef<'a, T> = PartialEq<&'a T>;
-trait StaticAlias = 'static;
-
-trait Things<T> {}
-trait Romeo {}
-#[allow(dead_code)]
-struct The<T>(T);
-#[allow(dead_code)]
-struct Fore<T>(T);
-impl<T, U> Things<T> for The<U> {}
-impl<T> Romeo for Fore<T> {}
-
-trait WithWhere<Art, Thou> = Romeo + Romeo where Fore<(Art, Thou)>: Romeo;
-trait BareWhere<Wild, Are> = where The<Wild>: Things<Are>;
-
 trait Empty {}
 trait EmptyAlias = Empty;
 trait CloneDefault = Clone + Default;
diff --git a/src/test/run-pass/traits/trait-alias-syntax.rs b/src/test/run-pass/traits/trait-alias-syntax.rs
new file mode 100644 (file)
index 0000000..a9b7afb
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(trait_alias)]
+
+trait SimpleAlias = Default;
+trait GenericAlias<T> = Iterator<Item = T>;
+trait Partial<T> = IntoIterator<Item = T>;
+trait SpecificAlias = GenericAlias<i32>;
+trait PartialEqRef<'a, T: 'a> = PartialEq<&'a T>;
+trait StaticAlias = 'static;
+
+trait Things<T> {}
+trait Romeo {}
+#[allow(dead_code)]
+struct The<T>(T);
+#[allow(dead_code)]
+struct Fore<T>(T);
+impl<T, U> Things<T> for The<U> {}
+impl<T> Romeo for Fore<T> {}
+
+trait WithWhere<Art, Thou> = Romeo + Romeo where Fore<(Art, Thou)>: Romeo;
+trait BareWhere<Wild, Are> = where The<Wild>: Things<Are>;
+
+fn main() {}