Fixed bug with Self type param coming before lifetimes.

This commit is contained in:
Alexander Regueiro 2018-11-01 21:52:56 +00:00
parent c04559fe9e
commit 417168587b
4 changed files with 52 additions and 30 deletions

View 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 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
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, ..)

View File

@ -357,14 +357,12 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
.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));

View 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.
//
@ -12,25 +12,6 @@
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;

View File

@ -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() {}