Skip to content

Commit 4171685

Browse files
author
Alexander Regueiro
committed
Fixed bug with Self type param coming before lifetimes.
1 parent c04559f commit 4171685

File tree

4 files changed

+52
-30
lines changed

4 files changed

+52
-30
lines changed

src/librustc/middle/resolve_lifetime.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,17 @@ fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap {
447447
map
448448
}
449449

450+
/// In traits, there is an implicit `Self` type parameter which comes before the generics.
451+
/// We have to account for this when computing the index of the other generic parameters.
452+
/// This function returns whether there is such an implicit parameter defined on the given item.
453+
fn sub_items_have_self_param(node: &hir::ItemKind) -> bool {
454+
match *node {
455+
hir::ItemKind::Trait(..) |
456+
hir::ItemKind::TraitAlias(..) => true,
457+
_ => false,
458+
}
459+
}
460+
450461
impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
451462
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
452463
NestedVisitorMap::All(&self.tcx.hir)
@@ -522,8 +533,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
522533
hir::ItemKind::Impl(..) => true,
523534
_ => false,
524535
};
525-
// These kinds of items have only early bound lifetime parameters.
526-
let mut index = if let hir::ItemKind::Trait(..) = item.node {
536+
// These kinds of items have only early-bound lifetime parameters.
537+
let mut index = if sub_items_have_self_param(&item.node) {
527538
1 // Self comes before lifetimes
528539
} else {
529540
0
@@ -1602,8 +1613,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
16021613
let mut index = 0;
16031614
if let Some(parent_id) = parent_id {
16041615
let parent = self.tcx.hir.expect_item(parent_id);
1605-
if let hir::ItemKind::Trait(..) = parent.node {
1606-
index += 1; // Self comes first.
1616+
if sub_items_have_self_param(&parent.node) {
1617+
index += 1; // Self comes before lifetimes
16071618
}
16081619
match parent.node {
16091620
hir::ItemKind::Trait(_, _, ref generics, ..)

src/librustc_typeck/collect.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -357,14 +357,12 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
357357
.flat_map(|bp| {
358358
let bt = if is_param(self.tcx, &bp.bounded_ty, param_id) {
359359
Some(ty)
360-
} else if only_self_bounds.0 {
361-
None
362-
} else {
360+
} else if !only_self_bounds.0 {
363361
Some(self.to_ty(&bp.bounded_ty))
362+
} else {
363+
None
364364
};
365-
bp.bounds.iter().filter_map(move |b| {
366-
if let Some(bt) = bt { Some((bt, b)) } else { None }
367-
})
365+
bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b)))
368366
})
369367
.flat_map(|(bt, b)| predicates_from_bound(self, bt, b));
370368

src/test/run-pass/traits/trait-alias-bounds.rs

+1-20
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -12,25 +12,6 @@
1212

1313
use std::marker::PhantomData;
1414

15-
trait SimpleAlias = Default;
16-
trait GenericAlias<T> = Iterator<Item = T>;
17-
trait Partial<T> = IntoIterator<Item = T>;
18-
trait SpecificAlias = GenericAlias<i32>;
19-
trait PartialEqRef<'a, T> = PartialEq<&'a T>;
20-
trait StaticAlias = 'static;
21-
22-
trait Things<T> {}
23-
trait Romeo {}
24-
#[allow(dead_code)]
25-
struct The<T>(T);
26-
#[allow(dead_code)]
27-
struct Fore<T>(T);
28-
impl<T, U> Things<T> for The<U> {}
29-
impl<T> Romeo for Fore<T> {}
30-
31-
trait WithWhere<Art, Thou> = Romeo + Romeo where Fore<(Art, Thou)>: Romeo;
32-
trait BareWhere<Wild, Are> = where The<Wild>: Things<Are>;
33-
3415
trait Empty {}
3516
trait EmptyAlias = Empty;
3617
trait CloneDefault = Clone + Default;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(trait_alias)]
12+
13+
trait SimpleAlias = Default;
14+
trait GenericAlias<T> = Iterator<Item = T>;
15+
trait Partial<T> = IntoIterator<Item = T>;
16+
trait SpecificAlias = GenericAlias<i32>;
17+
trait PartialEqRef<'a, T: 'a> = PartialEq<&'a T>;
18+
trait StaticAlias = 'static;
19+
20+
trait Things<T> {}
21+
trait Romeo {}
22+
#[allow(dead_code)]
23+
struct The<T>(T);
24+
#[allow(dead_code)]
25+
struct Fore<T>(T);
26+
impl<T, U> Things<T> for The<U> {}
27+
impl<T> Romeo for Fore<T> {}
28+
29+
trait WithWhere<Art, Thou> = Romeo + Romeo where Fore<(Art, Thou)>: Romeo;
30+
trait BareWhere<Wild, Are> = where The<Wild>: Things<Are>;
31+
32+
fn main() {}

0 commit comments

Comments
 (0)