Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 05b4554

Browse files
committedApr 5, 2019
Auto merge of #59741 - Centril:rollup-3us4b8q, r=Centril
Rollup of 6 pull requests Successful merges: - #58894 (Fix invalid bounds string generation in rustdoc) - #59599 (Updated RELEASES.md for 1.34.0) - #59624 (SGX target: Use linker option to avoid code CGU assignment kludge) - #59696 (Remove invalid assertion back::link::from add_upstream_rust_crates().) - #59707 (Add missing tryfrom example) - #59727 (wasi: Use shared API for preopened fds) Failed merges: r? @ghost
2 parents acd8dd6 + 8455818 commit 05b4554

File tree

19 files changed

+356
-144
lines changed

19 files changed

+356
-144
lines changed
 

‎RELEASES.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,149 @@
1+
Version 1.34.0 (2019-04-11)
2+
==========================
3+
4+
Language
5+
--------
6+
- [You can now use `#[deprecated = "reason"]`][58166] as a shorthand for
7+
`#[deprecated(note = "reason")]`. This was previously allowed by mistake
8+
but had no effect.
9+
- [You can now accept token streams in `#[attr()]`,`#[attr[]]`, and
10+
`#[attr{}]` procedural macros.][57367]
11+
- [You can now write `extern crate self as foo;`][57407] to import your
12+
crate's root into the extern prelude.
13+
14+
15+
Compiler
16+
--------
17+
- [You can now target `riscv64imac-unknown-none-elf` and
18+
`riscv64gc-unknown-none-elf`.][58406]
19+
- [You can now enable linker plugin LTO optimisations with
20+
`-C linker-plugin-lto`.][58057] This allows rustc to compile your Rust code
21+
into LLVM bitcode allowing LLVM to perform LTO optimisations across C/C++ FFI
22+
boundaries.
23+
- [You can now target `powerpc64-unknown-freebsd`.][57809]
24+
25+
26+
Libraries
27+
---------
28+
- [The trait bounds have been removed on some of `HashMap<K, V, S>`'s and
29+
`HashSet<T, S>`'s basic methods.][58370] Most notably you no longer require
30+
the `Hash` trait to create an iterator.
31+
- [The `Ord` trait bounds have been removed on some of `BinaryHeap<T>`'s basic
32+
methods.][58421] Most notably you no longer require the `Ord` trait to create
33+
an iterator.
34+
- [The methods `overflowing_neg` and `wrapping_neg` are now `const` functions
35+
for all numeric types.][58044]
36+
- [Indexing a `str` is now generic over all types that
37+
implement `SliceIndex<str>`.][57604]
38+
- [`str::trim`, `str::trim_matches`, `str::trim_{start, end}`, and
39+
`str::trim_{start, end}_matches` are now `#[must_use]`][57106] and will
40+
produce a warning if their returning type is unused.
41+
- [The methods `checked_pow`, `saturating_pow`, `wrapping_pow`, and
42+
`overflowing_pow` are now available for all numeric types.][57873] These are
43+
equivalvent to methods such as `wrapping_add` for the `pow` operation.
44+
45+
46+
Stabilized APIs
47+
---------------
48+
49+
#### std & core
50+
* [`Any::type_id`]
51+
* [`Error::type_id`]
52+
* [`atomic::AtomicI16`]
53+
* [`atomic::AtomicI32`]
54+
* [`atomic::AtomicI64`]
55+
* [`atomic::AtomicI8`]
56+
* [`atomic::AtomicU16`]
57+
* [`atomic::AtomicU32`]
58+
* [`atomic::AtomicU64`]
59+
* [`atomic::AtomicU8`]
60+
* [`convert::Infallible`]
61+
* [`convert::TryFrom`]
62+
* [`convert::TryInto`]
63+
* [`iter::from_fn`]
64+
* [`iter::successors`]
65+
* [`num::NonZeroI128`]
66+
* [`num::NonZeroI16`]
67+
* [`num::NonZeroI32`]
68+
* [`num::NonZeroI64`]
69+
* [`num::NonZeroI8`]
70+
* [`num::NonZeroIsize`]
71+
* [`slice::sort_by_cached_key`]
72+
* [`str::escape_debug`]
73+
* [`str::escape_default`]
74+
* [`str::escape_unicode`]
75+
* [`str::split_ascii_whitespace`]
76+
77+
#### std
78+
* [`Instant::checked_add`]
79+
* [`Instant::checked_sub`]
80+
* [`SystemTime::checked_add`]
81+
* [`SystemTime::checked_sub`]
82+
83+
Cargo
84+
-----
85+
- [You can now use alternative registries to crates.io.][cargo/6654]
86+
87+
Misc
88+
----
89+
- [You can now use the `?` operator in your documentation tests without manually
90+
adding `fn main() -> Result<(), _> {}`.][56470]
91+
92+
Compatibility Notes
93+
-------------------
94+
- [`Command::before_exec` is now deprecated in favor of the
95+
unsafe method `Command::pre_exec`.][58059]
96+
- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you
97+
can now use `const` functions in `static` variables.
98+
99+
[58370]: https://github.com/rust-lang/rust/pull/58370/
100+
[58406]: https://github.com/rust-lang/rust/pull/58406/
101+
[58421]: https://github.com/rust-lang/rust/pull/58421/
102+
[58166]: https://github.com/rust-lang/rust/pull/58166/
103+
[58044]: https://github.com/rust-lang/rust/pull/58044/
104+
[58057]: https://github.com/rust-lang/rust/pull/58057/
105+
[58059]: https://github.com/rust-lang/rust/pull/58059/
106+
[57809]: https://github.com/rust-lang/rust/pull/57809/
107+
[57873]: https://github.com/rust-lang/rust/pull/57873/
108+
[57604]: https://github.com/rust-lang/rust/pull/57604/
109+
[57367]: https://github.com/rust-lang/rust/pull/57367/
110+
[57407]: https://github.com/rust-lang/rust/pull/57407/
111+
[57425]: https://github.com/rust-lang/rust/pull/57425/
112+
[57106]: https://github.com/rust-lang/rust/pull/57106/
113+
[56470]: https://github.com/rust-lang/rust/pull/56470/
114+
[cargo/6654]: https://github.com/rust-lang/cargo/pull/6654/
115+
[`Any::type_id`]: https://doc.rust-lang.org/std/any/trait.Any.html#tymethod.type_id
116+
[`Error::type_id`]: https://doc.rust-lang.org/std/error/trait.Error.html#tymethod.type_id
117+
[`atomic::AtomicI16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI16.html
118+
[`atomic::AtomicI32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI32.html
119+
[`atomic::AtomicI64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI64.html
120+
[`atomic::AtomicI8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI8.html
121+
[`atomic::AtomicU16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU16.html
122+
[`atomic::AtomicU32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU32.html
123+
[`atomic::AtomicU64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU64.html
124+
[`atomic::AtomicU8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU8.html
125+
[`convert::Infallible`]: https://doc.rust-lang.org/std/convert/enum.Infallible.html
126+
[`convert::TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html
127+
[`convert::TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html
128+
[`iter::from_fn`]: https://doc.rust-lang.org/std/iter/fn.from_fn.html
129+
[`iter::successors`]: https://doc.rust-lang.org/std/iter/fn.successors.html
130+
[`num::NonZeroI128`]: https://doc.rust-lang.org/std/num/struct.NonZeroI128.html
131+
[`num::NonZeroI16`]: https://doc.rust-lang.org/std/num/struct.NonZeroI16.html
132+
[`num::NonZeroI32`]: https://doc.rust-lang.org/std/num/struct.NonZeroI32.html
133+
[`num::NonZeroI64`]: https://doc.rust-lang.org/std/num/struct.NonZeroI64.html
134+
[`num::NonZeroI8`]: https://doc.rust-lang.org/std/num/struct.NonZeroI8.html
135+
[`num::NonZeroIsize`]: https://doc.rust-lang.org/std/num/struct.NonZeroIsize.html
136+
[`slice::sort_by_cached_key`]: https://doc.rust-lang.org/std/slice/fn.sort_by_cached_key
137+
[`str::escape_debug`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_debug
138+
[`str::escape_default`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_default
139+
[`str::escape_unicode`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_unicode
140+
[`str::split_ascii_whitespace`]: https://doc.rust-lang.org/std/primitive.str.html#method.split_ascii_whitespace
141+
[`Instant::checked_add`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_add
142+
[`Instant::checked_sub`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_sub
143+
[`SystemTime::checked_add`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_add
144+
[`SystemTime::checked_sub`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_sub
145+
146+
1147
Version 1.33.0 (2019-02-28)
2148
==========================
3149

@@ -99,6 +245,8 @@ Stabilized APIs
99245

100246
Cargo
101247
-----
248+
- [You can now publish crates that require a feature flag to compile with
249+
`cargo publish --features` or `cargo publish --all-features`.][cargo/6453]
102250
- [Cargo should now rebuild a crate if a file was modified during the initial
103251
build.][cargo/6484]
104252

@@ -135,6 +283,7 @@ Compatibility Notes
135283
[57535]: https://github.com/rust-lang/rust/pull/57535/
136284
[57566]: https://github.com/rust-lang/rust/pull/57566/
137285
[57615]: https://github.com/rust-lang/rust/pull/57615/
286+
[cargo/6453]: https://github.com/rust-lang/cargo/pull/6453/
138287
[cargo/6484]: https://github.com/rust-lang/cargo/pull/6484/
139288
[`unix::FileExt::read_exact_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.read_exact_at
140289
[`unix::FileExt::write_all_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.write_all_at

‎src/ci/docker/dist-various-2/build-wasi-toolchain.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export PATH=`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH
1212
git clone https://github.com/CraneStation/wasi-sysroot
1313

1414
cd wasi-sysroot
15-
git reset --hard 320054e84f8f2440def3b1c8700cedb8fd697bf8
15+
git reset --hard e5f14be38362f1ab83302895a6e74b2ffd0e2302
1616
make -j$(nproc) INSTALL_DIR=/wasm32-unknown-wasi install
1717

1818
cd ..

‎src/libcore/convert.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,26 @@ pub trait TryInto<T>: Sized {
429429
/// When the `!` type is stablized `Infallible` and `!` will be
430430
/// equivalent.
431431
///
432+
/// `TryFrom<T>` can be implemented as follows:
433+
///
434+
/// ```
435+
/// use std::convert::TryFrom;
436+
///
437+
/// struct SuperiorThanZero(i32);
438+
///
439+
/// impl TryFrom<i32> for SuperiorThanZero {
440+
/// type Error = &'static str;
441+
///
442+
/// fn try_from(value: i32) -> Result<Self, Self::Error> {
443+
/// if value < 0 {
444+
/// Err("SuperiorThanZero only accepts value superior than zero!")
445+
/// } else {
446+
/// Ok(SuperiorThanZero(value))
447+
/// }
448+
/// }
449+
/// }
450+
/// ```
451+
///
432452
/// # Examples
433453
///
434454
/// As described, [`i32`] implements `TryFrom<i64>`:

‎src/librustc_codegen_llvm/back/link.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,10 +1396,6 @@ fn add_upstream_rust_crates(cmd: &mut dyn Linker,
13961396

13971397
// Same thing as above, but for dynamic crates instead of static crates.
13981398
fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
1399-
// If we're performing LTO, then it should have been previously required
1400-
// that all upstream rust dependencies were available in an rlib format.
1401-
assert!(!are_upstream_rust_objects_already_included(sess));
1402-
14031399
// Just need to tell the linker about where the library lives and
14041400
// what its name is
14051401
let parent = cratepath.parent();

‎src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ pub fn target() -> Result<Target, String> {
2121
"-Wl,--no-undefined-version",
2222
"-Wl,-Bsymbolic",
2323
"-Wl,--export-dynamic",
24+
// The following symbols are needed by libunwind, which is linked after
25+
// libstd. Make sure they're included in the link.
26+
"-Wl,-u,__rust_abort",
27+
"-Wl,-u,__rust_c_alloc",
28+
"-Wl,-u,__rust_c_dealloc",
29+
"-Wl,-u,__rust_print_err",
30+
"-Wl,-u,__rust_rwlock_rdlock",
31+
"-Wl,-u,__rust_rwlock_unlock",
32+
"-Wl,-u,__rust_rwlock_wrlock",
2433
];
2534

2635
const EXPORT_SYMBOLS: &[&str] = &[

‎src/librustc_typeck/collect.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1918,7 +1918,10 @@ fn explicit_predicates_of<'a, 'tcx>(
19181918
}
19191919
}
19201920

1921-
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
1921+
let hir_id = match tcx.hir().as_local_hir_id(def_id) {
1922+
Some(hir_id) => hir_id,
1923+
None => return tcx.predicates_of(def_id),
1924+
};
19221925
let node = tcx.hir().get_by_hir_id(hir_id);
19231926

19241927
let mut is_trait = None;

‎src/librustdoc/clean/auto_trait.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
568568
(replaced.clone(), replaced.clean(self.cx))
569569
});
570570

571-
let full_generics = (&type_generics, &tcx.predicates_of(did));
571+
let full_generics = (&type_generics, &tcx.explicit_predicates_of(did));
572572
let Generics {
573573
params: mut generic_params,
574574
..

‎src/librustdoc/clean/blanket_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
132132
.collect();
133133

134134
let ty = self.cx.get_real_ty(def_id, def_ctor, &real_name, generics);
135-
let predicates = infcx.tcx.predicates_of(impl_def_id);
135+
let predicates = infcx.tcx.explicit_predicates_of(impl_def_id);
136136

137137
impls.push(Item {
138138
source: infcx.tcx.def_span(impl_def_id).clean(self.cx),

‎src/librustdoc/clean/inline.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
228228
}
229229

230230
fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum {
231-
let predicates = cx.tcx.predicates_of(did);
231+
let predicates = cx.tcx.explicit_predicates_of(did);
232232

233233
clean::Enum {
234234
generics: (cx.tcx.generics_of(did), &predicates).clean(cx),
@@ -238,7 +238,7 @@ fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum {
238238
}
239239

240240
fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct {
241-
let predicates = cx.tcx.predicates_of(did);
241+
let predicates = cx.tcx.explicit_predicates_of(did);
242242
let variant = cx.tcx.adt_def(did).non_enum_variant();
243243

244244
clean::Struct {
@@ -254,7 +254,7 @@ fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct {
254254
}
255255

256256
fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
257-
let predicates = cx.tcx.predicates_of(did);
257+
let predicates = cx.tcx.explicit_predicates_of(did);
258258
let variant = cx.tcx.adt_def(did).non_enum_variant();
259259

260260
clean::Union {
@@ -266,7 +266,7 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
266266
}
267267

268268
fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {
269-
let predicates = cx.tcx.predicates_of(did);
269+
let predicates = cx.tcx.explicit_predicates_of(did);
270270

271271
clean::Typedef {
272272
type_: cx.tcx.type_of(did).clean(cx),
@@ -325,7 +325,7 @@ pub fn build_impl(cx: &DocContext<'_>, did: DefId, ret: &mut Vec<clean::Item>) {
325325
}
326326
}
327327

328-
let predicates = tcx.predicates_of(did);
328+
let predicates = tcx.explicit_predicates_of(did);
329329
let (trait_items, generics) = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
330330
match tcx.hir().expect_item_by_hir_id(hir_id).node {
331331
hir::ItemKind::Impl(.., ref gen, _, _, ref item_ids) => {

‎src/librustdoc/clean/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2288,7 +2288,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
22882288
}
22892289
ty::AssociatedKind::Method => {
22902290
let generics = (cx.tcx.generics_of(self.def_id),
2291-
&cx.tcx.predicates_of(self.def_id)).clean(cx);
2291+
&cx.tcx.explicit_predicates_of(self.def_id)).clean(cx);
22922292
let sig = cx.tcx.fn_sig(self.def_id);
22932293
let mut decl = (self.def_id, sig).clean(cx);
22942294

@@ -2361,7 +2361,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
23612361
// are actually located on the trait/impl itself, so we need to load
23622362
// all of the generics from there and then look for bounds that are
23632363
// applied to this associated type in question.
2364-
let predicates = cx.tcx.predicates_of(did);
2364+
let predicates = cx.tcx.explicit_predicates_of(did);
23652365
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
23662366
let mut bounds = generics.where_predicates.iter().filter_map(|pred| {
23672367
let (name, self_type, trait_, bounds) = match *pred {
@@ -3069,7 +3069,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
30693069
ty::Opaque(def_id, substs) => {
30703070
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
30713071
// by looking up the projections associated with the def_id.
3072-
let predicates_of = cx.tcx.predicates_of(def_id);
3072+
let predicates_of = cx.tcx.explicit_predicates_of(def_id);
30733073
let substs = cx.tcx.lift(&substs).expect("Opaque lift failed");
30743074
let bounds = predicates_of.instantiate(cx.tcx, substs);
30753075
let mut regions = vec![];

‎src/libstd/sys/sgx/alloc.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::alloc::{GlobalAlloc, Layout, System};
1+
use crate::alloc::{self, GlobalAlloc, Layout, System};
22

33
use super::waitqueue::SpinMutex;
44

@@ -30,3 +30,17 @@ unsafe impl GlobalAlloc for System {
3030
DLMALLOC.lock().realloc(ptr, layout.size(), layout.align(), new_size)
3131
}
3232
}
33+
34+
// The following functions are needed by libunwind. These symbols are named
35+
// in pre-link args for the target specification, so keep that in sync.
36+
#[cfg(not(test))]
37+
#[no_mangle]
38+
pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 {
39+
alloc::alloc(Layout::from_size_align_unchecked(size, align))
40+
}
41+
42+
#[cfg(not(test))]
43+
#[no_mangle]
44+
pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) {
45+
alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align))
46+
}

‎src/libstd/sys/sgx/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ pub unsafe fn abort_internal() -> ! {
130130
abi::usercalls::exit(true)
131131
}
132132

133+
// This function is needed by the panic runtime. The symbol is named in
134+
// pre-link args for the target specification, so keep that in sync.
135+
#[cfg(not(test))]
136+
#[no_mangle]
137+
// NB. used by both libunwind and libpanic_abort
138+
pub unsafe extern "C" fn __rust_abort() {
139+
abort_internal();
140+
}
141+
133142
pub fn hashmap_random_keys() -> (u64, u64) {
134143
fn rdrand64() -> u64 {
135144
unsafe {

‎src/libstd/sys/sgx/rwlock.rs

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
#[cfg(not(test))]
2-
use crate::alloc::{self, Layout};
31
use crate::num::NonZeroUsize;
4-
#[cfg(not(test))]
5-
use crate::slice;
6-
#[cfg(not(test))]
7-
use crate::str;
82

93
use super::waitqueue::{
104
try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable,
@@ -165,10 +159,11 @@ impl RWLock {
165159
pub unsafe fn destroy(&self) {}
166160
}
167161

162+
// The following functions are needed by libunwind. These symbols are named
163+
// in pre-link args for the target specification, so keep that in sync.
168164
#[cfg(not(test))]
169165
const EINVAL: i32 = 22;
170166

171-
// used by libunwind port
172167
#[cfg(not(test))]
173168
#[no_mangle]
174169
pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
@@ -198,39 +193,6 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
198193
return 0;
199194
}
200195

201-
// the following functions are also used by the libunwind port. They're
202-
// included here to make sure parallel codegen and LTO don't mess things up.
203-
#[cfg(not(test))]
204-
#[no_mangle]
205-
pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
206-
if s < 0 {
207-
return;
208-
}
209-
let buf = slice::from_raw_parts(m as *const u8, s as _);
210-
if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) {
211-
eprint!("{}", s);
212-
}
213-
}
214-
215-
#[cfg(not(test))]
216-
#[no_mangle]
217-
// NB. used by both libunwind and libpanic_abort
218-
pub unsafe extern "C" fn __rust_abort() {
219-
crate::sys::abort_internal();
220-
}
221-
222-
#[cfg(not(test))]
223-
#[no_mangle]
224-
pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 {
225-
alloc::alloc(Layout::from_size_align_unchecked(size, align))
226-
}
227-
228-
#[cfg(not(test))]
229-
#[no_mangle]
230-
pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) {
231-
alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align))
232-
}
233-
234196
#[cfg(test)]
235197
mod tests {
236198
use super::*;

‎src/libstd/sys/sgx/stdio.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ use fortanix_sgx_abi as abi;
22

33
use crate::io;
44
use crate::sys::fd::FileDesc;
5+
#[cfg(not(test))]
6+
use crate::slice;
7+
#[cfg(not(test))]
8+
use crate::str;
59

610
pub struct Stdin(());
711
pub struct Stdout(());
@@ -62,3 +66,17 @@ pub fn is_ebadf(err: &io::Error) -> bool {
6266
pub fn panic_output() -> Option<impl io::Write> {
6367
super::abi::panic::SgxPanicOutput::new()
6468
}
69+
70+
// This function is needed by libunwind. The symbol is named in pre-link args
71+
// for the target specification, so keep that in sync.
72+
#[cfg(not(test))]
73+
#[no_mangle]
74+
pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
75+
if s < 0 {
76+
return;
77+
}
78+
let buf = slice::from_raw_parts(m as *const u8, s as _);
79+
if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) {
80+
eprint!("{}", s);
81+
}
82+
}

‎src/libstd/sys/wasi/fs.rs

Lines changed: 86 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
use crate::collections::HashMap;
2-
use crate::ffi::{OsStr, OsString};
1+
use crate::ffi::{CStr, CString, OsStr, OsString};
32
use crate::fmt;
43
use crate::io::{self, IoVec, IoVecMut, SeekFrom};
54
use crate::iter;
65
use crate::mem::{self, ManuallyDrop};
76
use crate::os::wasi::ffi::{OsStrExt, OsStringExt};
87
use crate::path::{Path, PathBuf};
98
use crate::ptr;
10-
use crate::sync::atomic::{AtomicPtr, Ordering::SeqCst};
119
use crate::sync::Arc;
1210
use crate::sys::fd::{DirCookie, WasiFd};
1311
use crate::sys::time::SystemTime;
14-
use crate::sys::{cvt_wasi, unsupported};
12+
use crate::sys::unsupported;
1513
use crate::sys_common::FromInner;
1614

1715
pub use crate::sys_common::fs::copy;
@@ -230,7 +228,11 @@ impl DirEntry {
230228
}
231229

232230
pub fn metadata(&self) -> io::Result<FileAttr> {
233-
metadata_at(&self.inner.dir.fd, 0, OsStr::from_bytes(&self.name).as_ref())
231+
metadata_at(
232+
&self.inner.dir.fd,
233+
0,
234+
OsStr::from_bytes(&self.name).as_ref(),
235+
)
234236
}
235237

236238
pub fn file_type(&self) -> io::Result<FileType> {
@@ -377,8 +379,8 @@ impl OpenOptions {
377379

378380
impl File {
379381
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
380-
let (dir, file) = open_parent(path)?;
381-
open_at(&dir, file, opts)
382+
let (dir, file) = open_parent(path, libc::__WASI_RIGHT_PATH_OPEN)?;
383+
open_at(&dir, &file, opts)
382384
}
383385

384386
pub fn open_at(&self, path: &Path, opts: &OpenOptions) -> io::Result<File> {
@@ -475,7 +477,7 @@ impl DirBuilder {
475477
}
476478

477479
pub fn mkdir(&self, p: &Path) -> io::Result<()> {
478-
let (dir, file) = open_parent(p)?;
480+
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY)?;
479481
dir.create_directory(file.as_os_str().as_bytes())
480482
}
481483
}
@@ -506,13 +508,13 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
506508
}
507509

508510
pub fn unlink(p: &Path) -> io::Result<()> {
509-
let (dir, file) = open_parent(p)?;
511+
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_UNLINK_FILE)?;
510512
dir.unlink_file(file.as_os_str().as_bytes())
511513
}
512514

513515
pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
514-
let (old, old_file) = open_parent(old)?;
515-
let (new, new_file) = open_parent(new)?;
516+
let (old, old_file) = open_parent(old, libc::__WASI_RIGHT_PATH_RENAME_SOURCE)?;
517+
let (new, new_file) = open_parent(new, libc::__WASI_RIGHT_PATH_RENAME_TARGET)?;
516518
old.rename(
517519
old_file.as_os_str().as_bytes(),
518520
&new,
@@ -527,13 +529,13 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
527529
}
528530

529531
pub fn rmdir(p: &Path) -> io::Result<()> {
530-
let (dir, file) = open_parent(p)?;
532+
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY)?;
531533
dir.remove_directory(file.as_os_str().as_bytes())
532534
}
533535

534536
pub fn readlink(p: &Path) -> io::Result<PathBuf> {
535-
let (dir, file) = open_parent(p)?;
536-
read_link(&dir, file)
537+
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_READLINK)?;
538+
read_link(&dir, &file)
537539
}
538540

539541
fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> {
@@ -568,13 +570,13 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> {
568570
}
569571

570572
pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
571-
let (dst, dst_file) = open_parent(dst)?;
573+
let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_SYMLINK)?;
572574
dst.symlink(src.as_os_str().as_bytes(), dst_file.as_os_str().as_bytes())
573575
}
574576

575577
pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
576-
let (src, src_file) = open_parent(src)?;
577-
let (dst, dst_file) = open_parent(dst)?;
578+
let (src, src_file) = open_parent(src, libc::__WASI_RIGHT_PATH_LINK_SOURCE)?;
579+
let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_LINK_TARGET)?;
578580
src.link(
579581
libc::__WASI_LOOKUP_SYMLINK_FOLLOW,
580582
src_file.as_os_str().as_bytes(),
@@ -584,13 +586,13 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
584586
}
585587

586588
pub fn stat(p: &Path) -> io::Result<FileAttr> {
587-
let (dir, file) = open_parent(p)?;
588-
metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, file)
589+
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?;
590+
metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, &file)
589591
}
590592

591593
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
592-
let (dir, file) = open_parent(p)?;
593-
metadata_at(&dir, 0, file)
594+
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?;
595+
metadata_at(&dir, 0, &file)
594596
}
595597

596598
fn metadata_at(
@@ -621,72 +623,69 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
621623
Ok(File { fd })
622624
}
623625

624-
// FIXME: we shouldn't implement this. It'd be much better to share this between
625-
// libc (the wasi-sysroot) and Rust as the logic here is likely far more tricky
626-
// than what we're executing below. For now this is a stopgap to enable this
627-
// module, but we should add an official API in upstream wasi-libc which looks
628-
// like this.
629-
//
630-
// In the meantime this is highly unlikely to be correct. It allows some basic
631-
// testing but is not at all robust.
632-
fn open_parent(p: &Path) -> io::Result<(&'static WasiFd, &Path)> {
633-
let map = preopened_map();
634-
for ancestor in p.ancestors() {
635-
if let Some(fd) = map.get(ancestor) {
636-
let tail = p.strip_prefix(ancestor).unwrap();
637-
let tail = if tail == Path::new("") {
638-
".".as_ref()
639-
} else {
640-
tail
641-
};
642-
return Ok((fd, tail))
643-
}
644-
}
645-
let msg = format!("failed to find a preopened file descriptor to open {:?}", p);
646-
return Err(io::Error::new(io::ErrorKind::Other, msg));
647-
648-
type Preopened = HashMap<PathBuf, ManuallyDrop<WasiFd>>;
649-
fn preopened_map() -> &'static Preopened {
650-
static PTR: AtomicPtr<Preopened> = AtomicPtr::new(ptr::null_mut());
651-
unsafe {
652-
let ptr = PTR.load(SeqCst);
653-
if !ptr.is_null() {
654-
return &*ptr;
655-
}
656-
657-
let mut map = Box::new(HashMap::new());
658-
for fd in 3.. {
659-
let mut buf = mem::zeroed();
660-
if cvt_wasi(libc::__wasi_fd_prestat_get(fd, &mut buf)).is_err() {
661-
break;
662-
}
663-
if buf.pr_type != libc::__WASI_PREOPENTYPE_DIR {
664-
continue;
665-
}
666-
let len = buf.u.dir.pr_name_len;
667-
let mut v = vec![0u8; len];
668-
let res = cvt_wasi(libc::__wasi_fd_prestat_dir_name(
669-
fd,
670-
v.as_mut_ptr() as *mut i8,
671-
v.len(),
672-
));
673-
if res.is_err() {
674-
continue;
675-
}
676-
let path = PathBuf::from(OsString::from_vec(v));
677-
map.insert(path, ManuallyDrop::new(WasiFd::from_raw(fd)));
678-
}
679-
let ptr = Box::into_raw(map);
680-
match PTR.compare_exchange(ptr::null_mut(), ptr, SeqCst, SeqCst) {
681-
Ok(_) => &*ptr,
682-
683-
// If we lost the race for initialization clean up the map we
684-
// made and just use the one that's already there
685-
Err(other) => {
686-
drop(Box::from_raw(ptr));
687-
&*other
688-
}
689-
}
626+
/// Attempts to open a bare path `p`.
627+
///
628+
/// WASI has no fundamental capability to do this. All syscalls and operations
629+
/// are relative to already-open file descriptors. The C library, however,
630+
/// manages a map of preopened file descriptors to their path, and then the C
631+
/// library provides an API to look at this. In other words, when you want to
632+
/// open a path `p`, you have to find a previously opened file descriptor in a
633+
/// global table and then see if `p` is relative to that file descriptor.
634+
///
635+
/// This function, if successful, will return two items:
636+
///
637+
/// * The first is a `ManuallyDrop<WasiFd>`. This represents a preopened file
638+
/// descriptor which we don't have ownership of, but we can use. You shouldn't
639+
/// actually drop the `fd`.
640+
///
641+
/// * The second is a path that should be a part of `p` and represents a
642+
/// relative traversal from the file descriptor specified to the desired
643+
/// location `p`.
644+
///
645+
/// If successful you can use the returned file descriptor to perform
646+
/// file-descriptor-relative operations on the path returned as well. The
647+
/// `rights` argument indicates what operations are desired on the returned file
648+
/// descriptor, and if successful the returned file descriptor should have the
649+
/// appropriate rights for performing `rights` actions.
650+
///
651+
/// Note that this can fail if `p` doesn't look like it can be opened relative
652+
/// to any preopened file descriptor.
653+
fn open_parent(
654+
p: &Path,
655+
rights: libc::__wasi_rights_t,
656+
) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
657+
let p = CString::new(p.as_os_str().as_bytes())?;
658+
unsafe {
659+
let mut ret = ptr::null();
660+
let fd = __wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret);
661+
if fd == -1 {
662+
let msg = format!(
663+
"failed to find a preopened file descriptor \
664+
through which {:?} could be opened",
665+
p
666+
);
667+
return Err(io::Error::new(io::ErrorKind::Other, msg));
690668
}
669+
let path = Path::new(OsStr::from_bytes(CStr::from_ptr(ret).to_bytes()));
670+
671+
// FIXME: right now `path` is a pointer into `p`, the `CString` above.
672+
// When we return `p` is deallocated and we can't use it, so we need to
673+
// currently separately allocate `path`. If this becomes an issue though
674+
// we should probably turn this into a closure-taking interface or take
675+
// `&CString` and then pass off `&Path` tied to the same lifetime.
676+
let path = path.to_path_buf();
677+
678+
return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path));
679+
}
680+
681+
// FIXME(rust-lang/libc#1314) use the `libc` crate for this when the API
682+
// there is published
683+
extern "C" {
684+
pub fn __wasilibc_find_relpath(
685+
path: *const libc::c_char,
686+
rights_base: libc::__wasi_rights_t,
687+
rights_inheriting: libc::__wasi_rights_t,
688+
relative_path: *mut *const libc::c_char,
689+
) -> libc::c_int;
691690
}
692691
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-include ../tools.mk
2+
3+
# Test that we don't run into an assertion when using a Rust dylib dependency
4+
# while compiling with full LTO.
5+
# See https://github.com/rust-lang/rust/issues/59137
6+
7+
all:
8+
$(RUSTC) a_dylib.rs --crate-type=dylib -C prefer-dynamic
9+
$(RUSTC) main.rs -C lto
10+
$(call RUN,main)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
pub fn foo() {
3+
println!("bar");
4+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
extern crate a_dylib;
3+
4+
fn main() {
5+
a_dylib::foo();
6+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std::marker::PhantomData;
2+
3+
// @has useless_lifetime_bound/struct.Scope.html
4+
// @!has - '//*[@class="rust struct"]' "'env: 'env"
5+
pub struct Scope<'env> {
6+
_marker: PhantomData<&'env mut &'env ()>,
7+
}
8+
9+
// @has useless_lifetime_bound/struct.Scope.html
10+
// @!has - '//*[@class="rust struct"]' "T: 'a + 'a"
11+
pub struct SomeStruct<'a, T: 'a> {
12+
_marker: PhantomData<&'a T>,
13+
}

0 commit comments

Comments
 (0)
Please sign in to comment.