Auto merge of #52680 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 7 pull requests Successful merges: - #52391 (Add unaligned volatile intrinsics) - #52402 (impl PartialEq+Eq for BuildHasherDefault) - #52645 (Allow declaring existential types inside blocks) - #52656 (Stablize Redox Unix Sockets) - #52658 (Prefer `Option::map`/etc over `match` wherever it improves clarity) - #52668 (clarify pointer offset function safety concerns) - #52677 (Release notes: add some missing 1.28 libs stabilization) Failed merges: r? @ghost
This commit is contained in:
commit
1398572403
24
RELEASES.md
24
RELEASES.md
@ -52,6 +52,16 @@ Stabilized APIs
|
|||||||
---------------
|
---------------
|
||||||
- [`Iterator::step_by`]
|
- [`Iterator::step_by`]
|
||||||
- [`Path::ancestors`]
|
- [`Path::ancestors`]
|
||||||
|
- [`SystemTime::UNIX_EPOCH`]
|
||||||
|
- [`alloc::GlobalAlloc`]
|
||||||
|
- [`alloc::Layout`]
|
||||||
|
- [`alloc::LayoutErr`]
|
||||||
|
- [`alloc::System`]
|
||||||
|
- [`alloc::alloc`]
|
||||||
|
- [`alloc::alloc_zeroed`]
|
||||||
|
- [`alloc::dealloc`]
|
||||||
|
- [`alloc::realloc`]
|
||||||
|
- [`alloc::handle_alloc_error`]
|
||||||
- [`btree_map::Entry::or_default`]
|
- [`btree_map::Entry::or_default`]
|
||||||
- [`fmt::Alignment`]
|
- [`fmt::Alignment`]
|
||||||
- [`hash_map::Entry::or_default`]
|
- [`hash_map::Entry::or_default`]
|
||||||
@ -122,6 +132,16 @@ Compatibility Notes
|
|||||||
[cargo/5584]: https://github.com/rust-lang/cargo/pull/5584/
|
[cargo/5584]: https://github.com/rust-lang/cargo/pull/5584/
|
||||||
[`Iterator::step_by`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.step_by
|
[`Iterator::step_by`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.step_by
|
||||||
[`Path::ancestors`]: https://doc.rust-lang.org/std/path/struct.Path.html#method.ancestors
|
[`Path::ancestors`]: https://doc.rust-lang.org/std/path/struct.Path.html#method.ancestors
|
||||||
|
[`SystemTime::UNIX_EPOCH`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#associatedconstant.UNIX_EPOCH
|
||||||
|
[`alloc::GlobalAlloc`]: https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html
|
||||||
|
[`alloc::Layout`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html
|
||||||
|
[`alloc::LayoutErr`]: https://doc.rust-lang.org/std/alloc/struct.LayoutErr.html
|
||||||
|
[`alloc::System`]: https://doc.rust-lang.org/std/alloc/struct.System.html
|
||||||
|
[`alloc::alloc`]: https://doc.rust-lang.org/std/alloc/fn.alloc.html
|
||||||
|
[`alloc::alloc_zeroed`]: https://doc.rust-lang.org/std/alloc/fn.alloc_zeroed.html
|
||||||
|
[`alloc::dealloc`]: https://doc.rust-lang.org/std/alloc/fn.dealloc.html
|
||||||
|
[`alloc::realloc`]: https://doc.rust-lang.org/std/alloc/fn.realloc.html
|
||||||
|
[`alloc::handle_alloc_error`]: https://doc.rust-lang.org/std/alloc/fn.handle_alloc_error.html
|
||||||
[`btree_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
|
[`btree_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
|
||||||
[`fmt::Alignment`]: https://doc.rust-lang.org/std/fmt/enum.Alignment.html
|
[`fmt::Alignment`]: https://doc.rust-lang.org/std/fmt/enum.Alignment.html
|
||||||
[`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
|
[`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
|
||||||
@ -3162,7 +3182,7 @@ Stabilized APIs
|
|||||||
* [`UnixDatagram::shutdown`](http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.shutdown)
|
* [`UnixDatagram::shutdown`](http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.shutdown)
|
||||||
* RawFd impls for `UnixDatagram`
|
* RawFd impls for `UnixDatagram`
|
||||||
* `{BTree,Hash}Map::values_mut`
|
* `{BTree,Hash}Map::values_mut`
|
||||||
* [`<[_]>::binary_search_by_key`](http://doc.rust-lang.org/beta/std/primitive.slice.html#method.binary_search_by_key)
|
* [`<[_]>::binary_search_by_key`](http://doc.rust-lang.org/std/primitive.slice.html#method.binary_search_by_key)
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
---------
|
---------
|
||||||
@ -4080,7 +4100,7 @@ Compatibility Notes
|
|||||||
[1.6bh]: https://github.com/rust-lang/rust/pull/29811
|
[1.6bh]: https://github.com/rust-lang/rust/pull/29811
|
||||||
[1.6c]: https://github.com/rust-lang/cargo/pull/2192
|
[1.6c]: https://github.com/rust-lang/cargo/pull/2192
|
||||||
[1.6cc]: https://github.com/rust-lang/cargo/pull/2131
|
[1.6cc]: https://github.com/rust-lang/cargo/pull/2131
|
||||||
[1.6co]: http://doc.rust-lang.org/beta/core/index.html
|
[1.6co]: http://doc.rust-lang.org/core/index.html
|
||||||
[1.6dv]: https://github.com/rust-lang/rust/pull/30000
|
[1.6dv]: https://github.com/rust-lang/rust/pull/30000
|
||||||
[1.6f]: https://github.com/rust-lang/rust/pull/29129
|
[1.6f]: https://github.com/rust-lang/rust/pull/29129
|
||||||
[1.6m]: https://github.com/rust-lang/rust/pull/29828
|
[1.6m]: https://github.com/rust-lang/rust/pull/29828
|
||||||
|
@ -542,6 +542,16 @@ impl<H> Default for BuildHasherDefault<H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(since = "1.29.0", feature = "build_hasher_eq")]
|
||||||
|
impl<H> PartialEq for BuildHasherDefault<H> {
|
||||||
|
fn eq(&self, _other: &BuildHasherDefault<H>) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(since = "1.29.0", feature = "build_hasher_eq")]
|
||||||
|
impl<H> Eq for BuildHasherDefault<H> {}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
mod impls {
|
mod impls {
|
||||||
|
@ -1085,6 +1085,15 @@ extern "rust-intrinsic" {
|
|||||||
/// [`std::ptr::write_volatile`](../../std/ptr/fn.write_volatile.html).
|
/// [`std::ptr::write_volatile`](../../std/ptr/fn.write_volatile.html).
|
||||||
pub fn volatile_store<T>(dst: *mut T, val: T);
|
pub fn volatile_store<T>(dst: *mut T, val: T);
|
||||||
|
|
||||||
|
/// Perform a volatile load from the `src` pointer
|
||||||
|
/// The pointer is not required to be aligned.
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
pub fn unaligned_volatile_load<T>(src: *const T) -> T;
|
||||||
|
/// Perform a volatile store to the `dst` pointer.
|
||||||
|
/// The pointer is not required to be aligned.
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
pub fn unaligned_volatile_store<T>(dst: *mut T, val: T);
|
||||||
|
|
||||||
/// Returns the square root of an `f32`
|
/// Returns the square root of an `f32`
|
||||||
pub fn sqrtf32(x: f32) -> f32;
|
pub fn sqrtf32(x: f32) -> f32;
|
||||||
/// Returns the square root of an `f64`
|
/// Returns the square root of an `f64`
|
||||||
|
@ -591,7 +591,7 @@ impl<T: ?Sized> *const T {
|
|||||||
/// Behavior:
|
/// Behavior:
|
||||||
///
|
///
|
||||||
/// * Both the starting and resulting pointer must be either in bounds or one
|
/// * Both the starting and resulting pointer must be either in bounds or one
|
||||||
/// byte past the end of an allocated object.
|
/// byte past the end of *the same* allocated object.
|
||||||
///
|
///
|
||||||
/// * The computed offset, **in bytes**, cannot overflow an `isize`.
|
/// * The computed offset, **in bytes**, cannot overflow an `isize`.
|
||||||
///
|
///
|
||||||
@ -643,9 +643,15 @@ impl<T: ?Sized> *const T {
|
|||||||
///
|
///
|
||||||
/// The resulting pointer does not need to be in bounds, but it is
|
/// The resulting pointer does not need to be in bounds, but it is
|
||||||
/// potentially hazardous to dereference (which requires `unsafe`).
|
/// potentially hazardous to dereference (which requires `unsafe`).
|
||||||
|
/// In particular, the resulting pointer may *not* be used to access a
|
||||||
|
/// different allocated object than the one `self` points to. In other
|
||||||
|
/// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
|
||||||
|
/// *not* the same as `y`, and dereferencing it is undefined behavior
|
||||||
|
/// unless `x` and `y` point into the same allocated object.
|
||||||
///
|
///
|
||||||
/// Always use `.offset(count)` instead when possible, because `offset`
|
/// Always use `.offset(count)` instead when possible, because `offset`
|
||||||
/// allows the compiler to optimize better.
|
/// allows the compiler to optimize better. If you need to cross object
|
||||||
|
/// boundaries, cast the pointer to an integer and do the arithmetic there.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -1340,7 +1346,7 @@ impl<T: ?Sized> *mut T {
|
|||||||
/// Behavior:
|
/// Behavior:
|
||||||
///
|
///
|
||||||
/// * Both the starting and resulting pointer must be either in bounds or one
|
/// * Both the starting and resulting pointer must be either in bounds or one
|
||||||
/// byte past the end of an allocated object.
|
/// byte past the end of *the same* allocated object.
|
||||||
///
|
///
|
||||||
/// * The computed offset, **in bytes**, cannot overflow an `isize`.
|
/// * The computed offset, **in bytes**, cannot overflow an `isize`.
|
||||||
///
|
///
|
||||||
@ -1391,9 +1397,15 @@ impl<T: ?Sized> *mut T {
|
|||||||
///
|
///
|
||||||
/// The resulting pointer does not need to be in bounds, but it is
|
/// The resulting pointer does not need to be in bounds, but it is
|
||||||
/// potentially hazardous to dereference (which requires `unsafe`).
|
/// potentially hazardous to dereference (which requires `unsafe`).
|
||||||
|
/// In particular, the resulting pointer may *not* be used to access a
|
||||||
|
/// different allocated object than the one `self` points to. In other
|
||||||
|
/// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
|
||||||
|
/// *not* the same as `y`, and dereferencing it is undefined behavior
|
||||||
|
/// unless `x` and `y` point into the same allocated object.
|
||||||
///
|
///
|
||||||
/// Always use `.offset(count)` instead when possible, because `offset`
|
/// Always use `.offset(count)` instead when possible, because `offset`
|
||||||
/// allows the compiler to optimize better.
|
/// allows the compiler to optimize better. If you need to cross object
|
||||||
|
/// boundaries, cast the pointer to an integer and do the arithmetic there.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -696,13 +696,10 @@ impl<'a> Iterator for CharIndices<'a> {
|
|||||||
impl<'a> DoubleEndedIterator for CharIndices<'a> {
|
impl<'a> DoubleEndedIterator for CharIndices<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<(usize, char)> {
|
fn next_back(&mut self) -> Option<(usize, char)> {
|
||||||
match self.iter.next_back() {
|
self.iter.next_back().map(|ch| {
|
||||||
None => None,
|
let index = self.front_offset + self.iter.iter.len();
|
||||||
Some(ch) => {
|
(index, ch)
|
||||||
let index = self.front_offset + self.iter.iter.len();
|
})
|
||||||
Some((index, ch))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,11 +190,10 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
|
|||||||
for command in self.subcommands.iter().chain(Some(self)).rev() {
|
for command in self.subcommands.iter().chain(Some(self)).rev() {
|
||||||
if let Some(ref condition) = command.condition {
|
if let Some(ref condition) = command.condition {
|
||||||
if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
|
if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
|
||||||
options.contains(&(c.name().as_str().to_string(),
|
options.contains(&(
|
||||||
match c.value_str().map(|s| s.as_str().to_string()) {
|
c.name().as_str().to_string(),
|
||||||
Some(s) => Some(s),
|
c.value_str().map(|s| s.as_str().to_string())
|
||||||
None => None
|
))
|
||||||
}))
|
|
||||||
}) {
|
}) {
|
||||||
debug!("evaluate: skipping {:?} due to condition", command);
|
debug!("evaluate: skipping {:?} due to condition", command);
|
||||||
continue
|
continue
|
||||||
|
@ -2697,15 +2697,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.opt_associated_item(def_id)
|
self.opt_associated_item(def_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
match item {
|
item.and_then(|trait_item|
|
||||||
Some(trait_item) => {
|
match trait_item.container {
|
||||||
match trait_item.container {
|
TraitContainer(_) => None,
|
||||||
TraitContainer(_) => None,
|
ImplContainer(def_id) => Some(def_id),
|
||||||
ImplContainer(def_id) => Some(def_id),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => None
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
|
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
|
||||||
|
@ -54,6 +54,7 @@ bitflags! {
|
|||||||
pub struct MemFlags: u8 {
|
pub struct MemFlags: u8 {
|
||||||
const VOLATILE = 1 << 0;
|
const VOLATILE = 1 << 0;
|
||||||
const NONTEMPORAL = 1 << 1;
|
const NONTEMPORAL = 1 << 1;
|
||||||
|
const UNALIGNED = 1 << 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,7 +603,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
let ptr = self.check_store(val, ptr);
|
let ptr = self.check_store(val, ptr);
|
||||||
unsafe {
|
unsafe {
|
||||||
let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
|
let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
|
||||||
llvm::LLVMSetAlignment(store, align.abi() as c_uint);
|
let align = if flags.contains(MemFlags::UNALIGNED) {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
align.abi() as c_uint
|
||||||
|
};
|
||||||
|
llvm::LLVMSetAlignment(store, align);
|
||||||
if flags.contains(MemFlags::VOLATILE) {
|
if flags.contains(MemFlags::VOLATILE) {
|
||||||
llvm::LLVMSetVolatile(store, llvm::True);
|
llvm::LLVMSetVolatile(store, llvm::True);
|
||||||
}
|
}
|
||||||
|
@ -234,15 +234,20 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
memset_intrinsic(bx, true, substs.type_at(0),
|
memset_intrinsic(bx, true, substs.type_at(0),
|
||||||
args[0].immediate(), args[1].immediate(), args[2].immediate())
|
args[0].immediate(), args[1].immediate(), args[2].immediate())
|
||||||
}
|
}
|
||||||
"volatile_load" => {
|
"volatile_load" | "unaligned_volatile_load" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
let mut ptr = args[0].immediate();
|
let mut ptr = args[0].immediate();
|
||||||
if let PassMode::Cast(ty) = fn_ty.ret.mode {
|
if let PassMode::Cast(ty) = fn_ty.ret.mode {
|
||||||
ptr = bx.pointercast(ptr, ty.llvm_type(cx).ptr_to());
|
ptr = bx.pointercast(ptr, ty.llvm_type(cx).ptr_to());
|
||||||
}
|
}
|
||||||
let load = bx.volatile_load(ptr);
|
let load = bx.volatile_load(ptr);
|
||||||
|
let align = if name == "unaligned_volatile_load" {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
cx.align_of(tp_ty).abi() as u32
|
||||||
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMSetAlignment(load, cx.align_of(tp_ty).abi() as u32);
|
llvm::LLVMSetAlignment(load, align);
|
||||||
}
|
}
|
||||||
to_immediate(bx, load, cx.layout_of(tp_ty))
|
to_immediate(bx, load, cx.layout_of(tp_ty))
|
||||||
},
|
},
|
||||||
@ -251,6 +256,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
args[1].val.volatile_store(bx, dst);
|
args[1].val.volatile_store(bx, dst);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
"unaligned_volatile_store" => {
|
||||||
|
let dst = args[0].deref(bx.cx);
|
||||||
|
args[1].val.unaligned_volatile_store(bx, dst);
|
||||||
|
return;
|
||||||
|
},
|
||||||
"prefetch_read_data" | "prefetch_write_data" |
|
"prefetch_read_data" | "prefetch_write_data" |
|
||||||
"prefetch_read_instruction" | "prefetch_write_instruction" => {
|
"prefetch_read_instruction" | "prefetch_write_instruction" => {
|
||||||
let expect = cx.get_intrinsic(&("llvm.prefetch"));
|
let expect = cx.get_intrinsic(&("llvm.prefetch"));
|
||||||
|
@ -276,6 +276,10 @@ impl<'a, 'tcx> OperandValue {
|
|||||||
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
|
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
|
||||||
|
self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
|
pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
|
||||||
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
|
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
|
||||||
}
|
}
|
||||||
|
@ -824,17 +824,14 @@ impl<'a> Context<'a> {
|
|||||||
if rlib.is_none() && rmeta.is_none() && dylib.is_none() {
|
if rlib.is_none() && rmeta.is_none() && dylib.is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
match slot {
|
slot.map(|(_, metadata)|
|
||||||
Some((_, metadata)) => {
|
Library {
|
||||||
Some(Library {
|
dylib,
|
||||||
dylib,
|
rlib,
|
||||||
rlib,
|
rmeta,
|
||||||
rmeta,
|
metadata,
|
||||||
metadata,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
None => None,
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,9 +270,9 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
"roundf32" => (0, vec![ tcx.types.f32 ], tcx.types.f32),
|
"roundf32" => (0, vec![ tcx.types.f32 ], tcx.types.f32),
|
||||||
"roundf64" => (0, vec![ tcx.types.f64 ], tcx.types.f64),
|
"roundf64" => (0, vec![ tcx.types.f64 ], tcx.types.f64),
|
||||||
|
|
||||||
"volatile_load" =>
|
"volatile_load" | "unaligned_volatile_load" =>
|
||||||
(1, vec![ tcx.mk_imm_ptr(param(0)) ], param(0)),
|
(1, vec![ tcx.mk_imm_ptr(param(0)) ], param(0)),
|
||||||
"volatile_store" =>
|
"volatile_store" | "unaligned_volatile_store" =>
|
||||||
(1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil()),
|
(1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil()),
|
||||||
|
|
||||||
"ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" |
|
"ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" |
|
||||||
|
@ -53,10 +53,7 @@ impl<'a> Parser<'a> {
|
|||||||
F: FnOnce(&mut Parser) -> Option<T>,
|
F: FnOnce(&mut Parser) -> Option<T>,
|
||||||
{
|
{
|
||||||
self.read_atomically(move |p| {
|
self.read_atomically(move |p| {
|
||||||
match cb(p) {
|
cb(p).filter(|_| p.is_eof())
|
||||||
Some(x) => if p.is_eof() {Some(x)} else {None},
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,10 +1065,7 @@ impl<'a> Iterator for Ancestors<'a> {
|
|||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let next = self.next;
|
let next = self.next;
|
||||||
self.next = match next {
|
self.next = next.and_then(Path::parent);
|
||||||
Some(path) => path.parent(),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![unstable(feature = "unix_socket_redox", reason = "new feature", issue="51553")]
|
#![stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
|
|
||||||
//! Unix-specific networking functionality
|
//! Unix-specific networking functionality
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ use sys::{cvt, fd::FileDesc, syscall};
|
|||||||
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub struct SocketAddr(());
|
pub struct SocketAddr(());
|
||||||
|
|
||||||
impl SocketAddr {
|
impl SocketAddr {
|
||||||
@ -64,6 +65,7 @@ impl SocketAddr {
|
|||||||
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
/// assert_eq!(addr.as_pathname(), None);
|
/// assert_eq!(addr.as_pathname(), None);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn as_pathname(&self) -> Option<&Path> {
|
pub fn as_pathname(&self) -> Option<&Path> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -91,10 +93,12 @@ impl SocketAddr {
|
|||||||
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
/// assert_eq!(addr.is_unnamed(), true);
|
/// assert_eq!(addr.is_unnamed(), true);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn is_unnamed(&self) -> bool {
|
pub fn is_unnamed(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl fmt::Debug for SocketAddr {
|
impl fmt::Debug for SocketAddr {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(fmt, "SocketAddr")
|
write!(fmt, "SocketAddr")
|
||||||
@ -115,8 +119,10 @@ impl fmt::Debug for SocketAddr {
|
|||||||
/// stream.read_to_string(&mut response).unwrap();
|
/// stream.read_to_string(&mut response).unwrap();
|
||||||
/// println!("{}", response);
|
/// println!("{}", response);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub struct UnixStream(FileDesc);
|
pub struct UnixStream(FileDesc);
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl fmt::Debug for UnixStream {
|
impl fmt::Debug for UnixStream {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut builder = fmt.debug_struct("UnixStream");
|
let mut builder = fmt.debug_struct("UnixStream");
|
||||||
@ -147,6 +153,7 @@ impl UnixStream {
|
|||||||
/// }
|
/// }
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
|
pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
|
||||||
if let Some(s) = path.as_ref().to_str() {
|
if let Some(s) = path.as_ref().to_str() {
|
||||||
cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC))
|
cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC))
|
||||||
@ -177,6 +184,7 @@ impl UnixStream {
|
|||||||
/// }
|
/// }
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
|
pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
|
||||||
let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC))
|
let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC))
|
||||||
.map(FileDesc::new)?;
|
.map(FileDesc::new)?;
|
||||||
@ -200,6 +208,7 @@ impl UnixStream {
|
|||||||
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
/// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
|
/// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn try_clone(&self) -> io::Result<UnixStream> {
|
pub fn try_clone(&self) -> io::Result<UnixStream> {
|
||||||
self.0.duplicate().map(UnixStream)
|
self.0.duplicate().map(UnixStream)
|
||||||
}
|
}
|
||||||
@ -214,6 +223,7 @@ impl UnixStream {
|
|||||||
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||||
Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox"))
|
Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox"))
|
||||||
}
|
}
|
||||||
@ -228,6 +238,7 @@ impl UnixStream {
|
|||||||
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
/// let addr = socket.peer_addr().expect("Couldn't get peer address");
|
/// let addr = socket.peer_addr().expect("Couldn't get peer address");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||||
Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox"))
|
Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox"))
|
||||||
}
|
}
|
||||||
@ -266,6 +277,7 @@ impl UnixStream {
|
|||||||
/// let err = result.unwrap_err();
|
/// let err = result.unwrap_err();
|
||||||
/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
|
/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn set_read_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
|
pub fn set_read_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox"))
|
Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox"))
|
||||||
}
|
}
|
||||||
@ -304,6 +316,7 @@ impl UnixStream {
|
|||||||
/// let err = result.unwrap_err();
|
/// let err = result.unwrap_err();
|
||||||
/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
|
/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn set_write_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
|
pub fn set_write_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox"))
|
Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox"))
|
||||||
}
|
}
|
||||||
@ -320,6 +333,7 @@ impl UnixStream {
|
|||||||
/// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
|
/// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
|
||||||
/// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
|
/// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||||
Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox"))
|
Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox"))
|
||||||
}
|
}
|
||||||
@ -336,6 +350,7 @@ impl UnixStream {
|
|||||||
/// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
|
/// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
|
||||||
/// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
|
/// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||||
Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox"))
|
Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox"))
|
||||||
}
|
}
|
||||||
@ -350,6 +365,7 @@ impl UnixStream {
|
|||||||
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
/// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
|
/// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||||
self.0.set_nonblocking(nonblocking)
|
self.0.set_nonblocking(nonblocking)
|
||||||
}
|
}
|
||||||
@ -369,6 +385,7 @@ impl UnixStream {
|
|||||||
///
|
///
|
||||||
/// # Platform specific
|
/// # Platform specific
|
||||||
/// On Redox this always returns None.
|
/// On Redox this always returns None.
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
@ -390,11 +407,13 @@ impl UnixStream {
|
|||||||
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
/// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
|
/// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
|
pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox"))
|
Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl io::Read for UnixStream {
|
impl io::Read for UnixStream {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
io::Read::read(&mut &*self, buf)
|
io::Read::read(&mut &*self, buf)
|
||||||
@ -406,6 +425,7 @@ impl io::Read for UnixStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl<'a> io::Read for &'a UnixStream {
|
impl<'a> io::Read for &'a UnixStream {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.0.read(buf)
|
self.0.read(buf)
|
||||||
@ -417,6 +437,7 @@ impl<'a> io::Read for &'a UnixStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl io::Write for UnixStream {
|
impl io::Write for UnixStream {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
io::Write::write(&mut &*self, buf)
|
io::Write::write(&mut &*self, buf)
|
||||||
@ -427,6 +448,7 @@ impl io::Write for UnixStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl<'a> io::Write for &'a UnixStream {
|
impl<'a> io::Write for &'a UnixStream {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.write(buf)
|
self.0.write(buf)
|
||||||
@ -437,18 +459,21 @@ impl<'a> io::Write for &'a UnixStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl AsRawFd for UnixStream {
|
impl AsRawFd for UnixStream {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
self.0.raw()
|
self.0.raw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl FromRawFd for UnixStream {
|
impl FromRawFd for UnixStream {
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
|
unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
|
||||||
UnixStream(FileDesc::new(fd))
|
UnixStream(FileDesc::new(fd))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl IntoRawFd for UnixStream {
|
impl IntoRawFd for UnixStream {
|
||||||
fn into_raw_fd(self) -> RawFd {
|
fn into_raw_fd(self) -> RawFd {
|
||||||
self.0.into_raw()
|
self.0.into_raw()
|
||||||
@ -483,8 +508,10 @@ impl IntoRawFd for UnixStream {
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub struct UnixListener(FileDesc);
|
pub struct UnixListener(FileDesc);
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl fmt::Debug for UnixListener {
|
impl fmt::Debug for UnixListener {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut builder = fmt.debug_struct("UnixListener");
|
let mut builder = fmt.debug_struct("UnixListener");
|
||||||
@ -512,6 +539,7 @@ impl UnixListener {
|
|||||||
/// }
|
/// }
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
|
pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
|
||||||
if let Some(s) = path.as_ref().to_str() {
|
if let Some(s) = path.as_ref().to_str() {
|
||||||
cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC))
|
cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC))
|
||||||
@ -545,6 +573,7 @@ impl UnixListener {
|
|||||||
/// Err(e) => println!("accept function failed: {:?}", e),
|
/// Err(e) => println!("accept function failed: {:?}", e),
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
|
pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
|
||||||
self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(())))
|
self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(())))
|
||||||
}
|
}
|
||||||
@ -564,6 +593,7 @@ impl UnixListener {
|
|||||||
///
|
///
|
||||||
/// let listener_copy = listener.try_clone().expect("try_clone failed");
|
/// let listener_copy = listener.try_clone().expect("try_clone failed");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn try_clone(&self) -> io::Result<UnixListener> {
|
pub fn try_clone(&self) -> io::Result<UnixListener> {
|
||||||
self.0.duplicate().map(UnixListener)
|
self.0.duplicate().map(UnixListener)
|
||||||
}
|
}
|
||||||
@ -579,6 +609,7 @@ impl UnixListener {
|
|||||||
///
|
///
|
||||||
/// let addr = listener.local_addr().expect("Couldn't get local address");
|
/// let addr = listener.local_addr().expect("Couldn't get local address");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||||
Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox"))
|
Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox"))
|
||||||
}
|
}
|
||||||
@ -594,6 +625,7 @@ impl UnixListener {
|
|||||||
///
|
///
|
||||||
/// listener.set_nonblocking(true).expect("Couldn't set non blocking");
|
/// listener.set_nonblocking(true).expect("Couldn't set non blocking");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||||
self.0.set_nonblocking(nonblocking)
|
self.0.set_nonblocking(nonblocking)
|
||||||
}
|
}
|
||||||
@ -614,6 +646,7 @@ impl UnixListener {
|
|||||||
///
|
///
|
||||||
/// # Platform specific
|
/// # Platform specific
|
||||||
/// On Redox this always returns None.
|
/// On Redox this always returns None.
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
@ -649,29 +682,34 @@ impl UnixListener {
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub fn incoming<'a>(&'a self) -> Incoming<'a> {
|
pub fn incoming<'a>(&'a self) -> Incoming<'a> {
|
||||||
Incoming { listener: self }
|
Incoming { listener: self }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl AsRawFd for UnixListener {
|
impl AsRawFd for UnixListener {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
self.0.raw()
|
self.0.raw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl FromRawFd for UnixListener {
|
impl FromRawFd for UnixListener {
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
|
unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
|
||||||
UnixListener(FileDesc::new(fd))
|
UnixListener(FileDesc::new(fd))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl IntoRawFd for UnixListener {
|
impl IntoRawFd for UnixListener {
|
||||||
fn into_raw_fd(self) -> RawFd {
|
fn into_raw_fd(self) -> RawFd {
|
||||||
self.0.into_raw()
|
self.0.into_raw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl<'a> IntoIterator for &'a UnixListener {
|
impl<'a> IntoIterator for &'a UnixListener {
|
||||||
type Item = io::Result<UnixStream>;
|
type Item = io::Result<UnixStream>;
|
||||||
type IntoIter = Incoming<'a>;
|
type IntoIter = Incoming<'a>;
|
||||||
@ -712,10 +750,12 @@ impl<'a> IntoIterator for &'a UnixListener {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
pub struct Incoming<'a> {
|
pub struct Incoming<'a> {
|
||||||
listener: &'a UnixListener,
|
listener: &'a UnixListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")]
|
||||||
impl<'a> Iterator for Incoming<'a> {
|
impl<'a> Iterator for Incoming<'a> {
|
||||||
type Item = io::Result<UnixStream>;
|
type Item = io::Result<UnixStream>;
|
||||||
|
|
||||||
|
@ -156,16 +156,15 @@ pub fn log_enabled() -> Option<PrintFormat> {
|
|||||||
_ => return Some(PrintFormat::Full),
|
_ => return Some(PrintFormat::Full),
|
||||||
}
|
}
|
||||||
|
|
||||||
let val = match env::var_os("RUST_BACKTRACE") {
|
let val = env::var_os("RUST_BACKTRACE").and_then(|x|
|
||||||
Some(x) => if &x == "0" {
|
if &x == "0" {
|
||||||
None
|
None
|
||||||
} else if &x == "full" {
|
} else if &x == "full" {
|
||||||
Some(PrintFormat::Full)
|
Some(PrintFormat::Full)
|
||||||
} else {
|
} else {
|
||||||
Some(PrintFormat::Short)
|
Some(PrintFormat::Short)
|
||||||
},
|
}
|
||||||
None => None,
|
);
|
||||||
};
|
|
||||||
ENABLED.store(match val {
|
ENABLED.store(match val {
|
||||||
Some(v) => v as isize,
|
Some(v) => v as isize,
|
||||||
None => 1,
|
None => 1,
|
||||||
|
@ -4391,6 +4391,11 @@ impl<'a> Parser<'a> {
|
|||||||
self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
|
self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_existential_type_decl(&self) -> bool {
|
||||||
|
self.token.is_keyword(keywords::Existential) &&
|
||||||
|
self.look_ahead(1, |t| t.is_keyword(keywords::Type))
|
||||||
|
}
|
||||||
|
|
||||||
fn is_auto_trait_item(&mut self) -> bool {
|
fn is_auto_trait_item(&mut self) -> bool {
|
||||||
// auto trait
|
// auto trait
|
||||||
(self.token.is_keyword(keywords::Auto)
|
(self.token.is_keyword(keywords::Auto)
|
||||||
@ -4495,6 +4500,7 @@ impl<'a> Parser<'a> {
|
|||||||
!self.is_union_item() &&
|
!self.is_union_item() &&
|
||||||
!self.is_crate_vis() &&
|
!self.is_crate_vis() &&
|
||||||
!self.is_extern_non_path() &&
|
!self.is_extern_non_path() &&
|
||||||
|
!self.is_existential_type_decl() &&
|
||||||
!self.is_auto_trait_item() {
|
!self.is_auto_trait_item() {
|
||||||
let pth = self.parse_path(PathStyle::Expr)?;
|
let pth = self.parse_path(PathStyle::Expr)?;
|
||||||
|
|
||||||
|
@ -138,17 +138,13 @@ pub fn nil_ty<'r>() -> Ty<'r> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
|
fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
|
||||||
match *lt {
|
lt.map(|s|
|
||||||
Some(s) => Some(cx.lifetime(span, Ident::from_str(s))),
|
cx.lifetime(span, Ident::from_str(s))
|
||||||
None => None,
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
|
fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
|
||||||
match *lt {
|
mk_lifetime(cx, span, lt).into_iter().collect()
|
||||||
Some(s) => vec![cx.lifetime(span, Ident::from_str(s))],
|
|
||||||
None => vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Ty<'a> {
|
impl<'a> Ty<'a> {
|
||||||
|
@ -10,17 +10,24 @@
|
|||||||
|
|
||||||
#![feature(core_intrinsics, volatile)]
|
#![feature(core_intrinsics, volatile)]
|
||||||
|
|
||||||
use std::intrinsics::{volatile_load, volatile_store};
|
use std::intrinsics::{
|
||||||
|
unaligned_volatile_load, unaligned_volatile_store, volatile_load, volatile_store,
|
||||||
|
};
|
||||||
use std::ptr::{read_volatile, write_volatile};
|
use std::ptr::{read_volatile, write_volatile};
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut i : isize = 1;
|
let mut i: isize = 1;
|
||||||
volatile_store(&mut i, 2);
|
volatile_store(&mut i, 2);
|
||||||
assert_eq!(volatile_load(&i), 2);
|
assert_eq!(volatile_load(&i), 2);
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut i : isize = 1;
|
let mut i: isize = 1;
|
||||||
|
unaligned_volatile_store(&mut i, 2);
|
||||||
|
assert_eq!(unaligned_volatile_load(&i), 2);
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
let mut i: isize = 1;
|
||||||
write_volatile(&mut i, 2);
|
write_volatile(&mut i, 2);
|
||||||
assert_eq!(read_volatile(&i), 2);
|
assert_eq!(read_volatile(&i), 2);
|
||||||
}
|
}
|
||||||
|
22
src/test/ui/impl-trait/existential_type_in_fn_body.rs
Normal file
22
src/test/ui/impl-trait/existential_type_in_fn_body.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// compile-pass
|
||||||
|
|
||||||
|
#![feature(existential_type)]
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
existential type Existential: Debug;
|
||||||
|
|
||||||
|
fn f() -> Existential {}
|
||||||
|
println!("{:?}", f());
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user