Fixed bug with Self type param coming before lifetimes.
This commit is contained in:
parent
c04559fe9e
commit
417168587b
@ -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, ..)
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
32
src/test/run-pass/traits/trait-alias-syntax.rs
Normal file
32
src/test/run-pass/traits/trait-alias-syntax.rs
Normal 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() {}
|
Loading…
Reference in New Issue
Block a user