Skip to content

Commit 3c85f41

Browse files
authored
Auto merge of #34805 - michaelwoerister:stable-bounds-encoding, r=eddyb
tyencode: Make sure that projection bounds are handled in stable order. Fixes #34796. r? @alexcrichton
2 parents 935bd76 + 5ad5072 commit 3c85f41

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

src/librustc_metadata/tyencode.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,14 @@ pub fn enc_existential_bounds<'a,'tcx>(w: &mut Cursor<Vec<u8>>,
407407

408408
enc_region(w, cx, bs.region_bound);
409409

410-
for tp in &bs.projection_bounds {
410+
// Encode projection_bounds in a stable order
411+
let mut projection_bounds: Vec<_> = bs.projection_bounds
412+
.iter()
413+
.map(|b| (b.item_name().as_str(), b))
414+
.collect();
415+
projection_bounds.sort_by_key(|&(ref name, _)| name.clone());
416+
417+
for tp in projection_bounds.iter().map(|&(_, tp)| tp) {
411418
write!(w, "P");
412419
enc_projection_predicate(w, cx, &tp.0);
413420
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2016 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+
#![crate_type = "lib"]
12+
pub trait Future {
13+
type Item;
14+
type Error;
15+
}
16+
17+
impl Future for u32 {
18+
type Item = ();
19+
type Error = Box<()>;
20+
}
21+
22+
fn foo() -> Box<Future<Item=(), Error=Box<()>>> {
23+
Box::new(0u32)
24+
}
25+
26+
pub fn bar<F, A, B>(_s: F)
27+
where F: Fn(A) -> B,
28+
{
29+
foo();
30+
}

src/test/run-pass/issue34796.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2016 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+
// This test case exposes conditions where the encoding of a trait object type
12+
// with projection predicates would differ between this crate and the upstream
13+
// crate, because the predicates were encoded in different order within each
14+
// crate. This led to different symbol hashes of functions using these type,
15+
// which in turn led to linker errors because the two crates would not agree on
16+
// the symbol name.
17+
// The fix was to make the order in which predicates get encoded stable.
18+
19+
// aux-build:issue34796aux.rs
20+
extern crate issue34796aux;
21+
22+
fn mk<T>() -> T { loop {} }
23+
24+
struct Data<T, E> {
25+
data: T,
26+
error: E,
27+
}
28+
29+
fn main() {
30+
issue34796aux::bar(|()| {
31+
Data::<(), std::io::Error> {
32+
data: mk(),
33+
error: mk(),
34+
}
35+
})
36+
}

0 commit comments

Comments
 (0)