Skip to content

Commit 0e89f57

Browse files
author
Alexander Regueiro
committed
Added tests.
1 parent d08a42b commit 0e89f57

File tree

13 files changed

+133
-42
lines changed

13 files changed

+133
-42
lines changed

src/librustc/diagnostics.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,7 +2134,7 @@ static X: u32 = 42;
21342134

21352135

21362136
register_diagnostics! {
2137-
// E0006 // merged with E0005
2137+
// E0006, // merged with E0005
21382138
// E0101, // replaced with E0282
21392139
// E0102, // replaced with E0282
21402140
// E0134,
@@ -2183,9 +2183,7 @@ register_diagnostics! {
21832183
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
21842184
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
21852185
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
2186-
21872186
E0697, // closures cannot be static
2188-
21892187
E0707, // multiple elided lifetimes used in arguments of `async fn`
21902188
E0708, // `async` non-`move` closures with arguments are not currently supported
21912189
E0709, // multiple different lifetimes used in arguments of `async fn`

src/librustc/ty/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,11 +1239,11 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>;
12391239
/// This kind of predicate has no *direct* correspondent in the
12401240
/// syntax, but it roughly corresponds to the syntactic forms:
12411241
///
1242-
/// 1. `T : TraitRef<..., Item=Type>`
1242+
/// 1. `T: TraitRef<..., Item=Type>`
12431243
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
12441244
///
12451245
/// In particular, form #1 is "desugared" to the combination of a
1246-
/// normal trait predicate (`T : TraitRef<...>`) and one of these
1246+
/// normal trait predicate (`T: TraitRef<...>`) and one of these
12471247
/// predicates. Form #2 is a broader form in that it also permits
12481248
/// equality between arbitrary types. Processing an instance of
12491249
/// Form #2 eventually yields one of these `ProjectionPredicate`

src/librustc_typeck/astconv.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -831,15 +831,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
831831
let tcx = self.tcx();
832832

833833
if !speculative {
834-
// Given something like `U : SomeTrait<T=X>`, we want to produce a
834+
// Given something like `U: SomeTrait<T = X>`, we want to produce a
835835
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
836836
// subtle in the event that `T` is defined in a supertrait of
837837
// `SomeTrait`, because in that case we need to upcast.
838838
//
839839
// That is, consider this case:
840840
//
841841
// ```
842-
// trait SubTrait : SuperTrait<int> { }
842+
// trait SubTrait: SuperTrait<int> { }
843843
// trait SuperTrait<A> { type T; }
844844
//
845845
// ... B : SubTrait<T=foo> ...
@@ -879,17 +879,20 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
879879
}
880880
}
881881

882+
let supertraits = traits::supertraits(tcx, trait_ref);
882883
let candidate = if self.trait_defines_associated_type_named(trait_ref.def_id(),
883884
binding.item_name) {
884885
// Simple case: X is defined in the current trait.
885886
Ok(trait_ref)
886887
} else {
887888
// Otherwise, we have to walk through the supertraits to find
888889
// those that do.
889-
let candidates = traits::supertraits(tcx, trait_ref).filter(|r| {
890+
let candidates = supertraits.filter(|r| {
890891
self.trait_defines_associated_type_named(r.def_id(), binding.item_name)
891892
});
892-
self.one_bound_for_assoc_type(candidates, &trait_ref.to_string(),
893+
let candidates = candidates.collect::<Vec<_>>();
894+
debug!("foo: candidates: {:?}", candidates);
895+
self.one_bound_for_assoc_type(candidates.into_iter(), &trait_ref.to_string(),
893896
binding.item_name, binding.span)
894897
}?;
895898

@@ -905,6 +908,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
905908
}
906909
tcx.check_stability(assoc_ty.def_id, Some(ref_id), binding.span);
907910

911+
debug!("foo: info: {:?} {:?} {:?} {:?} {:?}", trait_ref, binding.item_name, speculative, assoc_ty.def_id, dup_bindings);
908912
if !speculative {
909913
dup_bindings.entry(assoc_ty.def_id)
910914
.and_modify(|prev_span| {
@@ -921,6 +925,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
921925
})
922926
.or_insert(binding.span);
923927
}
928+
static mut ABC: u32 = 0;
929+
unsafe {
930+
ABC += 1;
931+
if ABC == 3 {
932+
assert!(false);
933+
}
934+
};
924935

925936
Ok(candidate.map_bound(|trait_ref| {
926937
ty::ProjectionPredicate {
@@ -1017,8 +1028,25 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
10171028
}));
10181029
}
10191030

1020-
for (projection_bound, _) in &projection_bounds {
1021-
associated_types.remove(&projection_bound.projection_def_id());
1031+
let mut seen_projection_bounds = FxHashMap::default();
1032+
for (projection_bound, span) in projection_bounds.iter().rev() {
1033+
let bound_def_id = projection_bound.projection_def_id();
1034+
seen_projection_bounds.entry(bound_def_id)
1035+
.and_modify(|prev_span| {
1036+
let assoc_item = tcx.associated_item(bound_def_id);
1037+
let trait_def_id = assoc_item.container.id();
1038+
struct_span_err!(tcx.sess, *span, E0719,
1039+
"the value of the associated type `{}` (from the trait `{}`) \
1040+
is already specified",
1041+
assoc_item.ident,
1042+
tcx.item_path_str(trait_def_id))
1043+
.span_label(*span, "re-bound here")
1044+
.span_label(*prev_span, format!("binding for `{}`", assoc_item.ident))
1045+
.emit();
1046+
})
1047+
.or_insert(*span);
1048+
1049+
associated_types.remove(&bound_def_id);
10221050
}
10231051

10241052
for item_def_id in associated_types {
@@ -1132,7 +1160,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
11321160
span)
11331161
}
11341162

1135-
// Checks that bounds contains exactly one element and reports appropriate
1163+
// Checks that `bounds` contains exactly one element and reports appropriate
11361164
// errors otherwise.
11371165
fn one_bound_for_assoc_type<I>(&self,
11381166
mut bounds: I,

src/librustc_typeck/check/wfcheck.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ use errors::{DiagnosticBuilder, DiagnosticId};
2828
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
2929
use rustc::hir;
3030

31-
/// Helper type of a temporary returned by .for_item(...).
31+
/// Helper type of a temporary returned by `.for_item(...)`.
3232
/// Necessary because we can't write the following bound:
33-
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>).
33+
/// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>)`.
3434
struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
3535
inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>,
3636
id: ast::NodeId,

src/librustc_typeck/collect.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,18 +1978,18 @@ pub enum SizedByDefault {
19781978
No,
19791979
}
19801980

1981-
/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
1982-
/// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1983-
/// built-in trait (formerly known as kind): Send.
1981+
/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty`
1982+
/// or a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1983+
/// built-in trait `Send`.
19841984
pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
19851985
astconv: &dyn AstConv<'gcx, 'tcx>,
19861986
param_ty: Ty<'tcx>,
19871987
ast_bounds: &[hir::GenericBound],
19881988
sized_by_default: SizedByDefault,
19891989
span: Span,
19901990
) -> Bounds<'tcx> {
1991-
let mut region_bounds = vec![];
1992-
let mut trait_bounds = vec![];
1991+
let mut region_bounds = Vec::new();
1992+
let mut trait_bounds = Vec::new();
19931993

19941994
for ast_bound in ast_bounds {
19951995
match *ast_bound {
@@ -1999,7 +1999,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
19991999
}
20002000
}
20012001

2002-
let mut projection_bounds = vec![];
2002+
let mut projection_bounds = Vec::new();
20032003

20042004
let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
20052005
(astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span)

src/librustc_typeck/diagnostics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4909,4 +4909,5 @@ register_diagnostics! {
49094909
E0641, // cannot cast to/from a pointer with an unknown kind
49104910
E0645, // trait aliases not finished
49114911
E0698, // type inside generator must be known in this context
4912+
E0719, // duplicate values for associated type binding
49124913
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
trait Foo: Fn(i32) -> i32 + Send {}
12+
13+
impl<T: ?Sized + Fn(i32) -> i32 + Send> Foo for T {}
14+
15+
fn wants_foo(f: Box<Foo>) -> i32 {
16+
f(42)
17+
}
18+
19+
fn main() {
20+
let f = Box::new(|x| x);
21+
assert_eq!(wants_foo(f), 42);
22+
}

src/test/run-pass/traits/trait-alias-object-type.rs renamed to src/test/run-pass/traits/trait-alias-objects.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ pub fn main() {
2121
let b = Box::new(456) as Box<dyn Foo>;
2222
assert!(*b == 456);
2323

24-
// FIXME(alexreg): associated type should be gotten from trait alias definition
25-
// let c: &dyn I32Iterator = &vec![123].into_iter();
26-
// assert_eq!(c.next(), Some(123));
24+
let c: &mut dyn I32Iterator<Item = u32> = &mut vec![123].into_iter();
25+
assert_eq!(c.next(), Some(123));
2726
}

src/test/ui/error-codes/E0191.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,4 @@ trait Trait {
1414

1515
type Foo = Trait; //~ ERROR E0191
1616

17-
fn main() {
18-
}
17+
fn main() {}

src/test/ui/error-codes/E0719.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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 I32Iterator = Iterator<Item = i32>;
14+
15+
pub fn main() {
16+
let _: &I32Iterator<Item = f32>; //~ ERROR E0719
17+
}

src/test/ui/issue-51947.rs

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/test/ui/issues/issue-51947.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
// compile-pass
12+
13+
#![crate_type = "lib"]
14+
#![feature(linkage)]
15+
16+
// MergeFunctions will merge these via an anonymous internal
17+
// backing function, which must be named if ThinLTO buffers are used
18+
19+
#[linkage = "weak"]
20+
pub fn fn1(a: u32, b: u32, c: u32) -> u32 {
21+
a + b + c
22+
}
23+
24+
#[linkage = "weak"]
25+
pub fn fn2(a: u32, b: u32, c: u32) -> u32 {
26+
a + b + c
27+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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 I32Iterator = Iterator<Item = i32>;
14+
trait I32Iterator2 = I32Iterator<Item = i32>;
15+
trait U32Iterator = I32Iterator2<Item = i32>;
16+
17+
pub fn main() {}

0 commit comments

Comments
 (0)