From: Alexander Regueiro Date: Thu, 1 Nov 2018 21:52:56 +0000 (+0000) Subject: Fixed bug with Self type param coming before lifetimes. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=417168587beda80b97e9de83b61cbb8517a61dbc;p=rust.git Fixed bug with Self type param coming before lifetimes. --- diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 361abb16896..a387765085a 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -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( 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, ..) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 917fb887e0b..c136d76e358 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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)); diff --git a/src/test/run-pass/traits/trait-alias-bounds.rs b/src/test/run-pass/traits/trait-alias-bounds.rs index c1c3989107b..d8ac1a8c634 100644 --- a/src/test/run-pass/traits/trait-alias-bounds.rs +++ b/src/test/run-pass/traits/trait-alias-bounds.rs @@ -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. // @@ -12,25 +12,6 @@ use std::marker::PhantomData; -trait SimpleAlias = Default; -trait GenericAlias = Iterator; -trait Partial = IntoIterator; -trait SpecificAlias = GenericAlias; -trait PartialEqRef<'a, T> = PartialEq<&'a T>; -trait StaticAlias = 'static; - -trait Things {} -trait Romeo {} -#[allow(dead_code)] -struct The(T); -#[allow(dead_code)] -struct Fore(T); -impl Things for The {} -impl Romeo for Fore {} - -trait WithWhere = Romeo + Romeo where Fore<(Art, Thou)>: Romeo; -trait BareWhere = where The: Things; - 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 index 00000000000..a9b7afb0ea3 --- /dev/null +++ b/src/test/run-pass/traits/trait-alias-syntax.rs @@ -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 or the MIT license +// , 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 = Iterator; +trait Partial = IntoIterator; +trait SpecificAlias = GenericAlias; +trait PartialEqRef<'a, T: 'a> = PartialEq<&'a T>; +trait StaticAlias = 'static; + +trait Things {} +trait Romeo {} +#[allow(dead_code)] +struct The(T); +#[allow(dead_code)] +struct Fore(T); +impl Things for The {} +impl Romeo for Fore {} + +trait WithWhere = Romeo + Romeo where Fore<(Art, Thou)>: Romeo; +trait BareWhere = where The: Things; + +fn main() {}