From a99a7b7f35e3b30862058cc28ed4b0cf51638cf4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 22 Jun 2019 06:59:27 +0200 Subject: [PATCH 01/28] Remove FnBox. --- .../src/language-features/unsized-locals.md | 4 +- .../src/library-features/fnbox.md | 32 -------- src/liballoc/boxed.rs | 79 ------------------- src/libstd/lib.rs | 1 - .../run-pass/unsized-locals/fnbox-compat.rs | 13 --- 5 files changed, 1 insertion(+), 128 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/fnbox.md delete mode 100644 src/test/run-pass/unsized-locals/fnbox-compat.rs diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md index edc039f896b2c..343084b7db501 100644 --- a/src/doc/unstable-book/src/language-features/unsized-locals.md +++ b/src/doc/unstable-book/src/language-features/unsized-locals.md @@ -117,9 +117,7 @@ fn main () { } ``` -One of the objectives of this feature is to allow `Box`, instead of `Box` in the future. See [#28796] for details. - -[#28796]: https://github.com/rust-lang/rust/issues/28796 +One of the objectives of this feature is to allow `Box`. ## Variable length arrays diff --git a/src/doc/unstable-book/src/library-features/fnbox.md b/src/doc/unstable-book/src/library-features/fnbox.md deleted file mode 100644 index 97e32cc0acb12..0000000000000 --- a/src/doc/unstable-book/src/library-features/fnbox.md +++ /dev/null @@ -1,32 +0,0 @@ -# `fnbox` - -The tracking issue for this feature is [#28796] - -[#28796]: https://github.com/rust-lang/rust/issues/28796 - ------------------------- - -This had been a temporary alternative to the following impls: - -```rust,ignore -impl FnOnce for Box where F: FnOnce + ?Sized {} -impl FnMut for Box where F: FnMut + ?Sized {} -impl Fn for Box where F: Fn + ?Sized {} -``` - -The impls are parallel to these (relatively old) impls: - -```rust,ignore -impl FnOnce for &mut F where F: FnMut + ?Sized {} -impl FnMut for &mut F where F: FnMut + ?Sized {} -impl Fn for &mut F where F: Fn + ?Sized {} -impl FnOnce for &F where F: Fn + ?Sized {} -impl FnMut for &F where F: Fn + ?Sized {} -impl Fn for &F where F: Fn + ?Sized {} -``` - -Before the introduction of [`unsized_locals`][unsized_locals], we had been unable to provide the former impls. That means, unlike `&dyn Fn()` or `&mut dyn FnMut()` we could not use `Box` at that time. - -[unsized_locals]: ../language-features/unsized-locals.md - -`FnBox()` is an alternative approach to `Box` is delegated to `FnBox::call_box` which doesn't need unsized locals. As we now have `Box` working, the `fnbox` feature is going to be removed. diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 76b660fba685c..9109a730cce2d 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -761,85 +761,6 @@ impl + ?Sized> Fn for Box { } } -/// `FnBox` is deprecated and will be removed. -/// `Box` can be called directly, since Rust 1.35.0. -/// -/// `FnBox` is a version of the `FnOnce` intended for use with boxed -/// closure objects. The idea was that where one would normally store a -/// `Box` in a data structure, you whould use -/// `Box`. The two traits behave essentially the same, except -/// that a `FnBox` closure can only be called if it is boxed. -/// -/// # Examples -/// -/// Here is a snippet of code which creates a hashmap full of boxed -/// once closures and then removes them one by one, calling each -/// closure as it is removed. Note that the type of the closures -/// stored in the map is `Box i32>` and not `Box i32>`. -/// -/// ``` -/// #![feature(fnbox)] -/// #![allow(deprecated)] -/// -/// use std::boxed::FnBox; -/// use std::collections::HashMap; -/// -/// fn make_map() -> HashMap i32>> { -/// let mut map: HashMap i32>> = HashMap::new(); -/// map.insert(1, Box::new(|| 22)); -/// map.insert(2, Box::new(|| 44)); -/// map -/// } -/// -/// fn main() { -/// let mut map = make_map(); -/// for i in &[1, 2] { -/// let f = map.remove(&i).unwrap(); -/// assert_eq!(f(), i * 22); -/// } -/// } -/// ``` -/// -/// In Rust 1.35.0 or later, use `FnOnce`, `FnMut`, or `Fn` instead: -/// -/// ``` -/// use std::collections::HashMap; -/// -/// fn make_map() -> HashMap i32>> { -/// let mut map: HashMap i32>> = HashMap::new(); -/// map.insert(1, Box::new(|| 22)); -/// map.insert(2, Box::new(|| 44)); -/// map -/// } -/// -/// fn main() { -/// let mut map = make_map(); -/// for i in &[1, 2] { -/// let f = map.remove(&i).unwrap(); -/// assert_eq!(f(), i * 22); -/// } -/// } -/// ``` -#[rustc_paren_sugar] -#[unstable(feature = "fnbox", issue = "28796")] -#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")] -pub trait FnBox: FnOnce { - /// Performs the call operation. - fn call_box(self: Box, args: A) -> Self::Output; -} - -#[unstable(feature = "fnbox", issue = "28796")] -#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")] -#[allow(deprecated, deprecated_in_future)] -impl FnBox for F - where F: FnOnce -{ - fn call_box(self: Box, args: A) -> F::Output { - self.call_once(args) - } -} - #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U: ?Sized> CoerceUnsized> for Box {} diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e0ffc9ba92f11..60e06139eba99 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -262,7 +262,6 @@ #![feature(exhaustive_patterns)] #![feature(external_doc)] #![feature(fn_traits)] -#![feature(fnbox)] #![feature(generator_trait)] #![feature(hash_raw_entry)] #![feature(hashmap_internals)] diff --git a/src/test/run-pass/unsized-locals/fnbox-compat.rs b/src/test/run-pass/unsized-locals/fnbox-compat.rs deleted file mode 100644 index 74a4dd5d8515b..0000000000000 --- a/src/test/run-pass/unsized-locals/fnbox-compat.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![feature(fnbox)] -#![allow(deprecated, deprecated_in_future)] - -use std::boxed::FnBox; - -fn call_it(f: Box T>) -> T { - f() -} - -fn main() { - let s = "hello".to_owned(); - assert_eq!(&call_it(Box::new(|| s)) as &str, "hello"); -} From 1c12b1be330dd9c3de0b4fe599686d7c0c45e720 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Jun 2019 22:58:53 +0200 Subject: [PATCH 02/28] call out explicitly that general read needs to be called with an initialized buffer --- src/libstd/io/mod.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 917199f8ea8d0..7fba844897ffe 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -506,9 +506,18 @@ pub trait Read { /// /// No guarantees are provided about the contents of `buf` when this /// function is called, implementations cannot rely on any property of the - /// contents of `buf` being true. It is recommended that implementations + /// contents of `buf` being true. It is recommended that *implementations* /// only write data to `buf` instead of reading its contents. /// + /// Correspondingly, however, *users* of this trait may not assume any guarantees + /// about how the implementation uses `buf`. The trait is safe to implement, + /// so it is perfectly possible that the implementation might inspect that data. + /// As a caller, it is your responsibility to make sure that `buf` is initialized + /// before calling `read`. Calling `read` with an uninitialized `buf` (of the kind one + /// obtains via [`MaybeUninit`]) is not safe, and can lead to undefined behavior. + /// + /// [`MaybeUninit`]: ../mem/union.MaybeUninit.html + /// /// # Errors /// /// If this function encounters any form of I/O or other error, an error From bb26e07dd59088fc3a308ad7a56283ba4e53b5f8 Mon Sep 17 00:00:00 2001 From: Valentin Tolmer Date: Wed, 27 Feb 2019 17:10:59 +0100 Subject: [PATCH 03/28] Add debug assertions to write_bytes and copy* --- src/libcore/intrinsics.rs | 33 ++++++++++++++++++++++++++++++++- src/libcore/slice/mod.rs | 6 +++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index b30eff8baa9c8..93450cb4798a7 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -41,6 +41,8 @@ since = "1.18.0")] pub use crate::ptr::drop_in_place; +use crate::mem; + extern "rust-intrinsic" { // N.B., these intrinsics take raw pointers because they mutate aliased // memory, which is not valid for either `&` or `&mut`. @@ -1331,6 +1333,26 @@ extern "rust-intrinsic" { // (`transmute` also falls into this category, but it cannot be wrapped due to the // check that `T` and `U` have the same size.) +/// Checks whether `ptr` is properly aligned with respect to +/// `align_of::()`. +pub(crate) fn is_aligned_and_not_null(ptr: *const T) -> bool { + return !ptr.is_null() && ptr as usize % mem::align_of::() == 0; +} + +/// Checks whether the regions of memory starting at `src` and `dst` of size +/// `count * size_of::()` overlap. +fn overlaps(src: *const T, dst: *const T, count: usize) -> bool { + let src_usize = src as usize; + let dst_usize = dst as usize; + let size = mem::size_of::().checked_mul(count).unwrap(); + let diff = if src_usize > dst_usize { + src_usize - dst_usize + } else { + dst_usize - src_usize + }; + size > diff +} + /// Copies `count * size_of::()` bytes from `src` to `dst`. The source /// and destination must *not* overlap. /// @@ -1420,7 +1442,11 @@ pub unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); } - copy_nonoverlapping(src, dst, count); + + debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer"); + debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer"); + debug_assert!(!overlaps(src, dst, count), "attempt to copy to overlapping memory"); + copy_nonoverlapping(src, dst, count) } /// Copies `count * size_of::()` bytes from `src` to `dst`. The source @@ -1480,6 +1506,9 @@ pub unsafe fn copy(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { fn copy(src: *const T, dst: *mut T, count: usize); } + + debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer"); + debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer"); copy(src, dst, count) } @@ -1561,6 +1590,8 @@ pub unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { extern "rust-intrinsic" { fn write_bytes(dst: *mut T, val: u8, count: usize); } + + debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer"); write_bytes(dst, val, count) } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index c6d44324ef5ee..dba9a1445e84c 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -25,7 +25,7 @@ use crate::cmp::Ordering::{self, Less, Equal, Greater}; use crate::cmp; use crate::fmt; -use crate::intrinsics::{assume, exact_div, unchecked_sub}; +use crate::intrinsics::{assume, exact_div, unchecked_sub, is_aligned_and_not_null}; use crate::isize; use crate::iter::*; use crate::ops::{FnMut, Try, self}; @@ -5213,7 +5213,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { - debug_assert!(data as usize % mem::align_of::() == 0, "attempt to create unaligned slice"); + debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); debug_assert!(mem::size_of::().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering half the address space"); &*ptr::slice_from_raw_parts(data, len) @@ -5234,7 +5234,7 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { - debug_assert!(data as usize % mem::align_of::() == 0, "attempt to create unaligned slice"); + debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); debug_assert!(mem::size_of::().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering half the address space"); &mut *ptr::slice_from_raw_parts_mut(data, len) From 0533f129ecfb54ecae7e329949d7b1572368d0ae Mon Sep 17 00:00:00 2001 From: Valentin Tolmer Date: Wed, 27 Mar 2019 15:57:14 +0100 Subject: [PATCH 04/28] Handle null from LLVMRustGetSectionName --- src/librustc_codegen_llvm/llvm/ffi.rs | 4 +++- src/librustc_codegen_llvm/metadata.rs | 11 +++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index a5c295cd4525c..708ba79ec3ab2 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1736,7 +1736,9 @@ extern "C" { pub fn LLVMRustArchiveIteratorFree(AIR: &'a mut ArchiveIterator<'a>); pub fn LLVMRustDestroyArchive(AR: &'static mut Archive); - pub fn LLVMRustGetSectionName(SI: &SectionIterator<'_>, data: &mut *const c_char) -> size_t; + #[allow(improper_ctypes)] + pub fn LLVMRustGetSectionName(SI: &SectionIterator<'_>, + data: &mut Option>) -> size_t; #[allow(improper_ctypes)] pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index 7cf497cb5d036..9bddd29d2e88f 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -8,7 +8,6 @@ use rustc_data_structures::owning_ref::OwningRef; use rustc_codegen_ssa::METADATA_FILENAME; use std::path::Path; -use std::ptr; use std::slice; use rustc_fs_util::path_to_c_string; @@ -67,10 +66,14 @@ fn search_meta_section<'a>(of: &'a ObjectFile, unsafe { let si = mk_section_iter(of.llof); while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { - let mut name_buf = ptr::null(); + let mut name_buf = None; let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); - let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec(); - let name = String::from_utf8(name).unwrap(); + let name = name_buf.map_or( + "".to_string(), + |buf| String::from_utf8( + slice::from_raw_parts(buf.as_ptr() as *const u8, + name_len as usize) + .to_vec()).unwrap()); debug!("get_metadata_section: name {}", name); if read_metadata_section_name(target) == name { let cbuf = llvm::LLVMGetSectionContents(si.llsi); From 8a4573f841f219df32c97d25f400effee94e2474 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Jun 2019 23:15:37 +0200 Subject: [PATCH 05/28] format a bit --- src/librustc_codegen_llvm/metadata.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index 9bddd29d2e88f..42e91ef408f9d 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -69,11 +69,13 @@ fn search_meta_section<'a>(of: &'a ObjectFile, let mut name_buf = None; let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); let name = name_buf.map_or( - "".to_string(), + String::new(), // we got a NULL ptr, ignore `name_len` |buf| String::from_utf8( slice::from_raw_parts(buf.as_ptr() as *const u8, name_len as usize) - .to_vec()).unwrap()); + .to_vec() + ).unwrap() + ); debug!("get_metadata_section: name {}", name); if read_metadata_section_name(target) == name { let cbuf = llvm::LLVMGetSectionContents(si.llsi); From 4159b27c61e991c0abe7e87ad381bd0c07077dfc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Jun 2019 23:19:04 +0200 Subject: [PATCH 06/28] order things more traditionally --- src/libcore/intrinsics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 93450cb4798a7..2d47f08d70154 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -36,13 +36,13 @@ issue = "0")] #![allow(missing_docs)] +use crate::mem; + #[stable(feature = "drop_in_place", since = "1.8.0")] #[rustc_deprecated(reason = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.18.0")] pub use crate::ptr::drop_in_place; -use crate::mem; - extern "rust-intrinsic" { // N.B., these intrinsics take raw pointers because they mutate aliased // memory, which is not valid for either `&` or `&mut`. From 86ffeefc41528d39579cf478fa72156cfdb1932c Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Wed, 19 Jun 2019 21:55:18 +0100 Subject: [PATCH 07/28] Add suggestion for missing `.await` keyword --- src/libcore/future/future.rs | 1 + src/librustc/middle/lang_items.rs | 1 + src/librustc_typeck/check/demand.rs | 1 + src/librustc_typeck/check/mod.rs | 66 +++++++++++++++++++ .../async-await/dont-suggest-missing-await.rs | 21 ++++++ .../dont-suggest-missing-await.stderr | 12 ++++ .../async-await/suggest-missing-await.fixed | 32 +++++++++ .../ui/async-await/suggest-missing-await.rs | 32 +++++++++ .../async-await/suggest-missing-await.stderr | 27 ++++++++ 9 files changed, 193 insertions(+) create mode 100644 src/test/ui/async-await/dont-suggest-missing-await.rs create mode 100644 src/test/ui/async-await/dont-suggest-missing-await.stderr create mode 100644 src/test/ui/async-await/suggest-missing-await.fixed create mode 100644 src/test/ui/async-await/suggest-missing-await.rs create mode 100644 src/test/ui/async-await/suggest-missing-await.stderr diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index 0492fd709b8dc..acca8d7ba1533 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -25,6 +25,7 @@ use crate::task::{Context, Poll}; #[doc(spotlight)] #[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] +#[cfg_attr(not(bootstrap), lang = "future_trait")] pub trait Future { /// The type of value produced on completion. #[stable(feature = "futures_api", since = "1.36.0")] diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index d7abdb8ecbe10..a6e5bd275ae19 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -320,6 +320,7 @@ language_item_table! { FnMutTraitLangItem, "fn_mut", fn_mut_trait, Target::Trait; FnOnceTraitLangItem, "fn_once", fn_once_trait, Target::Trait; + FutureTraitLangItem, "future_trait", future_trait, Target::Trait; GeneratorStateLangItem, "generator_state", gen_state, Target::Enum; GeneratorTraitLangItem, "generator", gen_trait, Target::Trait; UnpinTraitLangItem, "unpin", unpin_trait, Target::Trait; diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index aff8eba3130d6..00164ff592209 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -127,6 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.suggest_compatible_variants(&mut err, expr, expected, expr_ty); self.suggest_ref_or_into(&mut err, expr, expected, expr_ty); + self.suggest_missing_await(&mut err, expr, expected, expr_ty); (expected, Some(err)) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0ec5c9763a0fb..a0215ddf1a131 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3913,6 +3913,72 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// A possible error is to forget to add `.await` when using futures: + /// + /// ``` + /// #![feature(async_await)] + /// + /// async fn make_u32() -> u32 { + /// 22 + /// } + /// + /// fn take_u32(x: u32) {} + /// + /// async fn foo() { + /// let x = make_u32(); + /// take_u32(x); + /// } + /// ``` + /// + /// This routine checks if the found type `T` implements `Future` where `U` is the + /// expected type. If this is the case, and we are inside of an async body, it suggests adding + /// `.await` to the tail of the expression. + fn suggest_missing_await( + &self, + err: &mut DiagnosticBuilder<'tcx>, + expr: &hir::Expr, + expected: Ty<'tcx>, + found: Ty<'tcx>, + ) { + // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the + // body isn't `async`. + let item_id = self.tcx().hir().get_parent_node_by_hir_id(self.body_id); + if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) { + let body = self.tcx().hir().body(body_id); + if let Some(hir::GeneratorKind::Async) = body.generator_kind { + let sp = expr.span; + // Check for `Future` implementations by constructing a predicate to + // prove: `::Output == U` + let future_trait = self.tcx.lang_items().future_trait().unwrap(); + let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id; + let predicate = ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate { + // `::Output` + projection_ty: ty::ProjectionTy { + // `T` + substs: self.tcx.mk_substs_trait( + found, + self.fresh_substs_for_item(sp, item_def_id) + ), + // `Future::Output` + item_def_id, + }, + ty: expected, + })); + let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate); + if self.infcx.predicate_may_hold(&obligation) { + if let Ok(code) = self.sess().source_map().span_to_snippet(sp) { + err.span_suggestion( + sp, + "consider using `.await` here", + format!("{}.await", code), + Applicability::MaybeIncorrect, + ); + } + } + } + } + } + /// A common error is to add an extra semicolon: /// /// ``` diff --git a/src/test/ui/async-await/dont-suggest-missing-await.rs b/src/test/ui/async-await/dont-suggest-missing-await.rs new file mode 100644 index 0000000000000..d551ef57985a1 --- /dev/null +++ b/src/test/ui/async-await/dont-suggest-missing-await.rs @@ -0,0 +1,21 @@ +// edition:2018 + +// This test ensures we don't make the suggestion in bodies that aren't `async`. + +#![feature(async_await)] + +fn take_u32(x: u32) {} + +async fn make_u32() -> u32 { + 22 +} + +async fn dont_suggest_await_in_closure() { + || { + let x = make_u32(); + take_u32(x) + //~^ ERROR mismatched types [E0308] + }; +} + +fn main() {} diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr new file mode 100644 index 0000000000000..c60b0d1f30e80 --- /dev/null +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-missing-await.rs:16:18 + | +LL | take_u32(x) + | ^ expected u32, found opaque type + | + = note: expected type `u32` + found type `impl std::future::Future` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/async-await/suggest-missing-await.fixed b/src/test/ui/async-await/suggest-missing-await.fixed new file mode 100644 index 0000000000000..282be368c69cd --- /dev/null +++ b/src/test/ui/async-await/suggest-missing-await.fixed @@ -0,0 +1,32 @@ +// edition:2018 +// run-rustfix + +#![feature(async_await)] + +fn take_u32(_x: u32) {} + +async fn make_u32() -> u32 { + 22 +} + +#[allow(unused)] +async fn suggest_await_in_async_fn() { + let x = make_u32(); + take_u32(x.await) + //~^ ERROR mismatched types [E0308] + //~| HELP consider using `.await` here + //~| SUGGESTION x.await +} + +#[allow(unused)] +async fn suggest_await_in_async_closure() { + async || { + let x = make_u32(); + take_u32(x.await) + //~^ ERROR mismatched types [E0308] + //~| HELP consider using `.await` here + //~| SUGGESTION x.await + }; +} + +fn main() {} diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs new file mode 100644 index 0000000000000..36103f050c147 --- /dev/null +++ b/src/test/ui/async-await/suggest-missing-await.rs @@ -0,0 +1,32 @@ +// edition:2018 +// run-rustfix + +#![feature(async_await)] + +fn take_u32(_x: u32) {} + +async fn make_u32() -> u32 { + 22 +} + +#[allow(unused)] +async fn suggest_await_in_async_fn() { + let x = make_u32(); + take_u32(x) + //~^ ERROR mismatched types [E0308] + //~| HELP consider using `.await` here + //~| SUGGESTION x.await +} + +#[allow(unused)] +async fn suggest_await_in_async_closure() { + async || { + let x = make_u32(); + take_u32(x) + //~^ ERROR mismatched types [E0308] + //~| HELP consider using `.await` here + //~| SUGGESTION x.await + }; +} + +fn main() {} diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr new file mode 100644 index 0000000000000..59c20dcfbc947 --- /dev/null +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/suggest-missing-await.rs:15:14 + | +LL | take_u32(x) + | ^ + | | + | expected u32, found opaque type + | help: consider using `.await` here: `x.await` + | + = note: expected type `u32` + found type `impl std::future::Future` + +error[E0308]: mismatched types + --> $DIR/suggest-missing-await.rs:25:18 + | +LL | take_u32(x) + | ^ + | | + | expected u32, found opaque type + | help: consider using `.await` here: `x.await` + | + = note: expected type `u32` + found type `impl std::future::Future` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From a68afc56bdf61b2ddd4f38ba4e3cabd7a4399c9b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Jun 2019 09:40:50 +0200 Subject: [PATCH 08/28] ignore some codegen tests in debug mode --- src/test/codegen/issue-45222.rs | 1 + src/test/codegen/issue-45466.rs | 1 + src/test/codegen/swap-small-types.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/test/codegen/issue-45222.rs b/src/test/codegen/issue-45222.rs index da65f2dfca5d1..7f99ca724cf73 100644 --- a/src/test/codegen/issue-45222.rs +++ b/src/test/codegen/issue-45222.rs @@ -1,4 +1,5 @@ // compile-flags: -O +// ignore-debug: the debug assertions get in the way #![crate_type = "lib"] diff --git a/src/test/codegen/issue-45466.rs b/src/test/codegen/issue-45466.rs index 7d6e31cc740f5..c79542767774a 100644 --- a/src/test/codegen/issue-45466.rs +++ b/src/test/codegen/issue-45466.rs @@ -1,4 +1,5 @@ // compile-flags: -O +// ignore-debug: the debug assertions get in the way #![crate_type="rlib"] diff --git a/src/test/codegen/swap-small-types.rs b/src/test/codegen/swap-small-types.rs index c8466fed7d1bd..6205e6a6559c9 100644 --- a/src/test/codegen/swap-small-types.rs +++ b/src/test/codegen/swap-small-types.rs @@ -1,5 +1,6 @@ // compile-flags: -O // only-x86_64 +// ignore-debug: the debug assertions get in the way #![crate_type = "lib"] From d3e1bf96dacab3e5c7c86321eb79fc916b28db87 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Jun 2019 09:42:25 +0200 Subject: [PATCH 09/28] nits --- src/libcore/intrinsics.rs | 2 +- src/librustc_codegen_llvm/metadata.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 2d47f08d70154..d9b68612785e9 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1336,7 +1336,7 @@ extern "rust-intrinsic" { /// Checks whether `ptr` is properly aligned with respect to /// `align_of::()`. pub(crate) fn is_aligned_and_not_null(ptr: *const T) -> bool { - return !ptr.is_null() && ptr as usize % mem::align_of::() == 0; + !ptr.is_null() && ptr as usize % mem::align_of::() == 0 } /// Checks whether the regions of memory starting at `src` and `dst` of size diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index 42e91ef408f9d..cd7255888118c 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -69,7 +69,7 @@ fn search_meta_section<'a>(of: &'a ObjectFile, let mut name_buf = None; let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); let name = name_buf.map_or( - String::new(), // we got a NULL ptr, ignore `name_len` + String::new(), // We got a NULL ptr, ignore `name_len`. |buf| String::from_utf8( slice::from_raw_parts(buf.as_ptr() as *const u8, name_len as usize) From 85ea4a1bf4a05ff18d6634db35eb41c3a6bca637 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 25 Jun 2019 23:09:25 +0900 Subject: [PATCH 10/28] Update new_debug_unreachable --- Cargo.lock | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eaec52a7a150c..98dd10955d57d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1030,7 +1030,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1760,11 +1760,8 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "nodrop" @@ -3450,7 +3447,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4038,14 +4035,6 @@ name = "unicode_categories" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unreachable" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "unstable-book-gen" version = "0.1.0" @@ -4124,11 +4113,6 @@ name = "version_check" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "vte" version = "0.3.3" @@ -4388,7 +4372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4" +"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" @@ -4552,7 +4536,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" "checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" @@ -4562,7 +4545,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum vte 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f42f536e22f7fcbb407639765c8fd78707a33109301f834a594758bedd6e8cf" "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" From b75021b31e43d59eb2b91fe45cfffcb7d25fb141 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 25 Jun 2019 21:02:19 +0300 Subject: [PATCH 11/28] refactor lexer to use idiomatic borrowing --- src/libsyntax/parse/lexer/mod.rs | 225 ++++++++++++++----------------- 1 file changed, 104 insertions(+), 121 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index ead5d543bec7d..7b9e3bc4d5102 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -321,33 +321,29 @@ impl<'a> StringReader<'a> { (pos - self.source_file.start_pos).to_usize() } - /// Calls `f` with a string slice of the source text spanning from `start` - /// up to but excluding `self.pos`, meaning the slice does not include - /// the character `self.ch`. - fn with_str_from(&self, start: BytePos, f: F) -> T - where F: FnOnce(&str) -> T + /// Slice of the source text from `start` up to but excluding `self.pos`, + /// meaning the slice does not include the character `self.ch`. + fn str_from(&self, start: BytePos) -> &str { - self.with_str_from_to(start, self.pos, f) + self.str_from_to(start, self.pos) } /// Creates a Name from a given offset to the current offset. fn name_from(&self, start: BytePos) -> ast::Name { debug!("taking an ident from {:?} to {:?}", start, self.pos); - self.with_str_from(start, Symbol::intern) + Symbol::intern(self.str_from(start)) } /// As name_from, with an explicit endpoint. fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name { debug!("taking an ident from {:?} to {:?}", start, end); - self.with_str_from_to(start, end, Symbol::intern) + Symbol::intern(self.str_from_to(start, end)) } - /// Calls `f` with a string slice of the source text spanning from `start` - /// up to but excluding `end`. - fn with_str_from_to(&self, start: BytePos, end: BytePos, f: F) -> T - where F: FnOnce(&str) -> T + /// Slice of the source text spanning from `start` up to but excluding `end`. + fn str_from_to(&self, start: BytePos, end: BytePos) -> &str { - f(&self.src[self.src_index(start)..self.src_index(end)]) + &self.src[self.src_index(start)..self.src_index(end)] } /// Converts CRLF to LF in the given string, raising an error on bare CR. @@ -456,8 +452,8 @@ impl<'a> StringReader<'a> { self.bump(); } - self.with_str_from(start, |string| { - if string == "_" { + match self.str_from(start) { + "_" => { self.sess.span_diagnostic .struct_span_warn(self.mk_sp(start, self.pos), "underscore literal suffix is not allowed") @@ -468,10 +464,9 @@ impl<'a> StringReader<'a> { ") .emit(); None - } else { - Some(Symbol::intern(string)) } - }) + name => Some(Symbol::intern(name)) + } } /// PRECONDITION: self.ch is not whitespace @@ -513,9 +508,7 @@ impl<'a> StringReader<'a> { } let kind = if doc_comment { - self.with_str_from(start_bpos, |string| { - token::DocComment(Symbol::intern(string)) - }) + token::DocComment(self.name_from(start_bpos)) } else { token::Comment }; @@ -615,23 +608,22 @@ impl<'a> StringReader<'a> { self.bump(); } - self.with_str_from(start_bpos, |string| { - // but comments with only "*"s between two "/"s are not - let kind = if is_block_doc_comment(string) { - let string = if has_cr { - self.translate_crlf(start_bpos, - string, - "bare CR not allowed in block doc-comment") - } else { - string.into() - }; - token::DocComment(Symbol::intern(&string[..])) + let string = self.str_from(start_bpos); + // but comments with only "*"s between two "/"s are not + let kind = if is_block_doc_comment(string) { + let string = if has_cr { + self.translate_crlf(start_bpos, + string, + "bare CR not allowed in block doc-comment") } else { - token::Comment + string.into() }; + token::DocComment(Symbol::intern(&string[..])) + } else { + token::Comment + }; - Some(Token::new(kind, self.mk_sp(start_bpos, self.pos))) - }) + Some(Token::new(kind, self.mk_sp(start_bpos, self.pos))) } /// Scan through any digits (base `scan_radix`) or underscores, @@ -838,20 +830,17 @@ impl<'a> StringReader<'a> { self.bump(); } - return Ok(self.with_str_from(start, |string| { - // FIXME: perform NFKC normalization here. (Issue #2253) - let name = ast::Name::intern(string); - - if is_raw_ident { - let span = self.mk_sp(raw_start, self.pos); - if !name.can_be_raw() { - self.err_span(span, &format!("`{}` cannot be a raw identifier", name)); - } - self.sess.raw_identifier_spans.borrow_mut().push(span); + // FIXME: perform NFKC normalization here. (Issue #2253) + let name = self.name_from(start); + if is_raw_ident { + let span = self.mk_sp(raw_start, self.pos); + if !name.can_be_raw() { + self.err_span(span, &format!("`{}` cannot be a raw identifier", name)); } + self.sess.raw_identifier_spans.borrow_mut().push(span); + } - token::Ident(name, is_raw_ident) - })); + return Ok(token::Ident(name, is_raw_ident)); } } @@ -1300,101 +1289,95 @@ impl<'a> StringReader<'a> { } fn validate_char_escape(&self, start_with_quote: BytePos) { - self.with_str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1), |lit| { - if let Err((off, err)) = unescape::unescape_char(lit) { + let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1)); + if let Err((off, err)) = unescape::unescape_char(lit) { + emit_unescape_error( + &self.sess.span_diagnostic, + lit, + self.mk_sp(start_with_quote, self.pos), + unescape::Mode::Char, + 0..off, + err, + ) + } + } + + fn validate_byte_escape(&self, start_with_quote: BytePos) { + let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1)); + if let Err((off, err)) = unescape::unescape_byte(lit) { + emit_unescape_error( + &self.sess.span_diagnostic, + lit, + self.mk_sp(start_with_quote, self.pos), + unescape::Mode::Byte, + 0..off, + err, + ) + } + } + + fn validate_str_escape(&self, start_with_quote: BytePos) { + let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1)); + unescape::unescape_str(lit, &mut |range, c| { + if let Err(err) = c { emit_unescape_error( &self.sess.span_diagnostic, lit, self.mk_sp(start_with_quote, self.pos), - unescape::Mode::Char, - 0..off, + unescape::Mode::Str, + range, err, ) } - }); + }) } - fn validate_byte_escape(&self, start_with_quote: BytePos) { - self.with_str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1), |lit| { - if let Err((off, err)) = unescape::unescape_byte(lit) { + fn validate_raw_str_escape(&self, content_start: BytePos, content_end: BytePos) { + let lit = self.str_from_to(content_start, content_end); + unescape::unescape_raw_str(lit, &mut |range, c| { + if let Err(err) = c { emit_unescape_error( &self.sess.span_diagnostic, lit, - self.mk_sp(start_with_quote, self.pos), - unescape::Mode::Byte, - 0..off, + self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)), + unescape::Mode::Str, + range, err, ) } - }); - } - - fn validate_str_escape(&self, start_with_quote: BytePos) { - self.with_str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1), |lit| { - unescape::unescape_str(lit, &mut |range, c| { - if let Err(err) = c { - emit_unescape_error( - &self.sess.span_diagnostic, - lit, - self.mk_sp(start_with_quote, self.pos), - unescape::Mode::Str, - range, - err, - ) - } - }) - }); - } - - fn validate_raw_str_escape(&self, content_start: BytePos, content_end: BytePos) { - self.with_str_from_to(content_start, content_end, |lit: &str| { - unescape::unescape_raw_str(lit, &mut |range, c| { - if let Err(err) = c { - emit_unescape_error( - &self.sess.span_diagnostic, - lit, - self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)), - unescape::Mode::Str, - range, - err, - ) - } - }) - }); + }) } fn validate_raw_byte_str_escape(&self, content_start: BytePos, content_end: BytePos) { - self.with_str_from_to(content_start, content_end, |lit: &str| { - unescape::unescape_raw_byte_str(lit, &mut |range, c| { - if let Err(err) = c { - emit_unescape_error( - &self.sess.span_diagnostic, - lit, - self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)), - unescape::Mode::ByteStr, - range, - err, - ) - } - }) - }); + let lit = self.str_from_to(content_start, content_end); + unescape::unescape_raw_byte_str(lit, &mut |range, c| { + if let Err(err) = c { + emit_unescape_error( + &self.sess.span_diagnostic, + lit, + self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)), + unescape::Mode::ByteStr, + range, + err, + ) + } + }) } fn validate_byte_str_escape(&self, start_with_quote: BytePos) { - self.with_str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1), |lit| { - unescape::unescape_byte_str(lit, &mut |range, c| { - if let Err(err) = c { - emit_unescape_error( - &self.sess.span_diagnostic, - lit, - self.mk_sp(start_with_quote, self.pos), - unescape::Mode::ByteStr, - range, - err, - ) - } - }) - }); + let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1)); + unescape::unescape_byte_str(lit, &mut |range, c| { + if let Err(err) = c { + emit_unescape_error( + &self.sess.span_diagnostic, + lit, + self.mk_sp(start_with_quote, self.pos), + unescape::Mode::ByteStr, + range, + err, + ) + } + }) } } From 0f34d7a7e5f068683097e0e664249bd6a417032f Mon Sep 17 00:00:00 2001 From: Erin Power Date: Sun, 23 Jun 2019 11:45:06 +0200 Subject: [PATCH 12/28] Updated RELEASES.md for 1.36.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Taiki Endo Co-Authored-By: Jonas Schievink Co-Authored-By: Torbjørn Birch Moltu --- RELEASES.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 91e3c5f721952..b6e2171f6eef9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,104 @@ +Version 1.36.0 (2019-07-04) +========================== + +Language +-------- +- [Non-Lexical Lifetimes are now enabled on the 2015 edition.][59114] +- [The order of traits in trait objects no longer affects the semantics of that + object.][59445] e.g. `dyn Send + fmt::Debug` is now equivalent to + `dyn fmt::Debug + Send`, where this was previously not the case. + +Libraries +--------- +- [`HashMap`'s implementation has been replaced with `hashbrown::HashMap` implementation.][58623] +- [`TryFromSliceError` now implements `From`.][60318] +- [`mem::needs_drop` is now available as a const fn.][60364] +- [`alloc::Layout::from_size_align_unchecked` is now available as a const fn.][60370] +- [`String` now implements `BorrowMut`.][60404] +- [`io::Cursor` now implements `Default`.][60234] +- [Both `NonNull::{dangling, cast}` are now const fns.][60244] +- [The `alloc` crate is now stable.][59675] `alloc` allows you to use a subset + of `std` (e.g. `Vec`, `Box`, `Arc`) in `#![no_std]` environments if the + environment has access to heap memory allocation. +- [`String` now implements `From<&String>`.][59825] +- [You can now pass multiple arguments to the `dbg!` macro.][59826] `dbg!` will + return a tuple of each argument when there is multiple arguments. +- [`Result::{is_err, is_ok}` are now `#[must_use]` and will produce a warning if + not used.][59648] + +Stabilized APIs +--------------- +- [`VecDeque::rotate_left`] +- [`VecDeque::rotate_right`] +- [`Iterator::copied`] +- [`io::IoSlice`] +- [`io::IoSliceMut`] +- [`Read::read_vectored`] +- [`Write::write_vectored`] +- [`str::as_mut_ptr`] +- [`mem::MaybeUninit`] +- [`pointer::align_offset`] +- [`future::Future`] +- [`task::Context`] +- [`task::RawWaker`] +- [`task::RawWakerVTable`] +- [`task::Waker`] +- [`task::Poll`] + +Cargo +----- +- [Cargo will now produce an error if you attempt to use the name of a required dependency as a feature.][cargo/6860] +- [You can now pass the `--offline` flag to run cargo without accessing the network.][cargo/6934] + +You can find further change's in [Cargo's 1.36.0 release notes][cargo-1-36-0]. + +Clippy +------ +There have been numerous additions and fixes to clippy, see [Clippy's 1.36.0 release notes][clippy-1-36-0] for more details. + +Misc +---- + +Compatibility Notes +------------------- +- With the stabilisation of `mem::MaybeUninit`, `mem::uninitialized` use is no + longer recommended, and will be deprecated in 1.38.0. + +[60318]: https://github.com/rust-lang/rust/pull/60318/ +[60364]: https://github.com/rust-lang/rust/pull/60364/ +[60370]: https://github.com/rust-lang/rust/pull/60370/ +[60404]: https://github.com/rust-lang/rust/pull/60404/ +[60234]: https://github.com/rust-lang/rust/pull/60234/ +[60244]: https://github.com/rust-lang/rust/pull/60244/ +[58623]: https://github.com/rust-lang/rust/pull/58623/ +[59648]: https://github.com/rust-lang/rust/pull/59648/ +[59675]: https://github.com/rust-lang/rust/pull/59675/ +[59825]: https://github.com/rust-lang/rust/pull/59825/ +[59826]: https://github.com/rust-lang/rust/pull/59826/ +[59445]: https://github.com/rust-lang/rust/pull/59445/ +[59114]: https://github.com/rust-lang/rust/pull/59114/ +[cargo/6860]: https://github.com/rust-lang/cargo/pull/6860/ +[cargo/6934]: https://github.com/rust-lang/cargo/pull/6934/ +[`VecDeque::rotate_left`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.rotate_left +[`VecDeque::rotate_right`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.rotate_right +[`Iterator::copied`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.copied +[`io::IoSlice`]: https://doc.rust-lang.org/std/io/struct.IoSlice.html +[`io::IoSliceMut`]: https://doc.rust-lang.org/std/io/struct.IoSliceMut.html +[`Read::read_vectored`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_vectored +[`Write::write_vectored`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_vectored +[`str::as_mut_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_mut_ptr +[`mem::MaybeUninit`]: https://doc.rust-lang.org/std/mem/union.MaybeUninit.html +[`pointer::align_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.align_offset +[`future::Future`]: https://doc.rust-lang.org/std/future/trait.Future.html +[`task::Context`]: https://doc.rust-lang.org/beta/std/task/struct.Context.html +[`task::RawWaker`]: https://doc.rust-lang.org/beta/std/task/struct.RawWaker.html +[`task::RawWakerVTable`]: https://doc.rust-lang.org/beta/std/task/struct.RawWakerVTable.html +[`task::Waker`]: https://doc.rust-lang.org/beta/std/task/struct.Waker.html +[`task::Poll`]: https://doc.rust-lang.org/beta/std/task/enum.Poll.html +[clippy-1-36-0]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-136 +[cargo-1-36-0]: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-136-2019-07-04 + + Version 1.35.0 (2019-05-23) ========================== @@ -62,7 +163,7 @@ Cargo - [You can now set `cargo:rustc-cdylib-link-arg` at build time to pass custom linker arguments when building a `cdylib`.][cargo/6298] Its usage is highly platform specific. - + Misc ---- - [The Rust toolchain is now available natively for musl based distros.][58575] From ba12e7862c58df2155011bb165a8ae1186828bc4 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Mon, 24 Jun 2019 17:48:21 -0700 Subject: [PATCH 13/28] Add more tests for async/await --- src/test/ui/async-await/async-fn-nonsend.rs | 59 ++++++++++++ .../ui/async-await/async-fn-nonsend.stderr | 87 ++++++++++++++++++ .../async-await/async-fn-send-uses-nonsend.rs | 59 ++++++++++++ .../ui/async-await/generics-and-bounds.rs | 90 +++++++++++++++++++ src/test/ui/async-await/no-async-const.rs | 8 ++ src/test/ui/async-await/no-async-const.stderr | 8 ++ src/test/ui/async-await/no-const-async.rs | 9 ++ src/test/ui/async-await/no-const-async.stderr | 18 ++++ 8 files changed, 338 insertions(+) create mode 100644 src/test/ui/async-await/async-fn-nonsend.rs create mode 100644 src/test/ui/async-await/async-fn-nonsend.stderr create mode 100644 src/test/ui/async-await/async-fn-send-uses-nonsend.rs create mode 100644 src/test/ui/async-await/generics-and-bounds.rs create mode 100644 src/test/ui/async-await/no-async-const.rs create mode 100644 src/test/ui/async-await/no-async-const.stderr create mode 100644 src/test/ui/async-await/no-const-async.rs create mode 100644 src/test/ui/async-await/no-const-async.stderr diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs new file mode 100644 index 0000000000000..612c1e29d82bd --- /dev/null +++ b/src/test/ui/async-await/async-fn-nonsend.rs @@ -0,0 +1,59 @@ +// compile-fail +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +use std::{ + cell::RefCell, + fmt::Debug, + rc::Rc, +}; + +fn non_sync() -> impl Debug { RefCell::new(()) } + +fn non_send() -> impl Debug { Rc::new(()) } + +fn take_ref(_: &T) {} + +async fn fut() {} + +async fn fut_arg(_: T) {} + +async fn local_dropped_before_await() { + // FIXME: it'd be nice for this to be allowed in a `Send` `async fn` + let x = non_send(); + drop(x); + fut().await; +} + +async fn non_send_temporary_in_match() { + // We could theoretically make this work as well (produce a `Send` future) + // for scrutinees / temporaries that can or will + // be dropped prior to the match body + // (e.g. `Copy` types). + match Some(non_send()) { + Some(_) => fut().await, + None => {} + } +} + +async fn non_sync_with_method_call() { + // FIXME: it'd be nice for this to work. + let f: &mut std::fmt::Formatter = panic!(); + if non_sync().fmt(f).unwrap() == () { + fut().await; + } +} + +fn assert_send(_: impl Send) {} + +pub fn pass_assert() { + assert_send(local_dropped_before_await()); + //~^ ERROR `std::rc::Rc<()>` cannot be sent between threads safely + assert_send(non_send_temporary_in_match()); + //~^ ERROR `std::rc::Rc<()>` cannot be sent between threads safely + assert_send(non_sync_with_method_call()); + //~^ ERROR `dyn std::fmt::Write` cannot be sent between threads safely + //~^^ ERROR `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely +} diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr new file mode 100644 index 0000000000000..7776a36a28f2b --- /dev/null +++ b/src/test/ui/async-await/async-fn-nonsend.stderr @@ -0,0 +1,87 @@ +error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely + --> $DIR/async-fn-nonsend.rs:52:5 + | +LL | assert_send(local_dropped_before_await()); + | ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely + | + = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` + = note: required because it appears within the type `impl std::fmt::Debug` + = note: required because it appears within the type `{impl std::fmt::Debug, impl std::future::Future, ()}` + = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:23:39: 28:2 {impl std::fmt::Debug, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:23:39: 28:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` +note: required by `assert_send` + --> $DIR/async-fn-nonsend.rs:49:1 + | +LL | fn assert_send(_: impl Send) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely + --> $DIR/async-fn-nonsend.rs:54:5 + | +LL | assert_send(non_send_temporary_in_match()); + | ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely + | + = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` + = note: required because it appears within the type `impl std::fmt::Debug` + = note: required because it appears within the type `{fn(impl std::fmt::Debug) -> std::option::Option {std::option::Option::::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option, impl std::future::Future, ()}` + = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:30:40: 39:2 {fn(impl std::fmt::Debug) -> std::option::Option {std::option::Option::::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:30:40: 39:2 {fn(impl std::fmt::Debug) -> std::option::Option {std::option::Option::::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option, impl std::future::Future, ()}]>` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` +note: required by `assert_send` + --> $DIR/async-fn-nonsend.rs:49:1 + | +LL | fn assert_send(_: impl Send) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `dyn std::fmt::Write` cannot be sent between threads safely + --> $DIR/async-fn-nonsend.rs:56:5 + | +LL | assert_send(non_sync_with_method_call()); + | ^^^^^^^^^^^ `dyn std::fmt::Write` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `dyn std::fmt::Write` + = note: required because of the requirements on the impl of `std::marker::Send` for `&mut dyn std::fmt::Write` + = note: required because it appears within the type `std::fmt::Formatter<'_>` + = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>` + = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}` + = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` +note: required by `assert_send` + --> $DIR/async-fn-nonsend.rs:49:1 + | +LL | fn assert_send(_: impl Send) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely + --> $DIR/async-fn-nonsend.rs:56:5 + | +LL | assert_send(non_sync_with_method_call()); + | ^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely + | + = help: within `std::fmt::ArgumentV1<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)` + = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>` + = note: required because it appears within the type `core::fmt::Void` + = note: required because it appears within the type `&core::fmt::Void` + = note: required because it appears within the type `std::fmt::ArgumentV1<'_>` + = note: required because of the requirements on the impl of `std::marker::Send` for `std::slice::Iter<'_, std::fmt::ArgumentV1<'_>>` + = note: required because it appears within the type `std::fmt::Formatter<'_>` + = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>` + = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}` + = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` +note: required by `assert_send` + --> $DIR/async-fn-nonsend.rs:49:1 + | +LL | fn assert_send(_: impl Send) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs new file mode 100644 index 0000000000000..f07fc2fceb5b6 --- /dev/null +++ b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs @@ -0,0 +1,59 @@ +// compile-pass +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +use std::{ + cell::RefCell, + fmt::Debug, + rc::Rc, +}; + +fn non_sync() -> impl Debug { RefCell::new(()) } + +fn non_send() -> impl Debug { Rc::new(()) } + +fn take_ref(_: &T) {} + +async fn fut() {} + +async fn fut_arg(_: T) {} + +async fn still_send() { + fut().await; + println!("{:?} {:?}", non_send(), non_sync()); + fut().await; + drop(non_send()); + drop(non_sync()); + fut().await; + fut_arg(non_sync()).await; + + // Note: all temporaries in `if let` and `match` scrutinee + // are dropped at the *end* of the blocks, so using `non_send()` + // in either of those positions with an await in the middle will + // cause a `!Send` future. It might be nice in the future to allow + // this for `Copy` types, since they can be "dropped" early without + // affecting the end user. + if let Some(_) = Some(non_sync()) { + fut().await; + } + match Some(non_sync()) { + Some(_) => fut().await, + None => fut().await, + } + + let _ = non_send(); + fut().await; + + { + let _x = non_send(); + } + fut().await; +} + +fn assert_send(_: impl Send) {} + +pub fn pass_assert() { + assert_send(still_send()); +} diff --git a/src/test/ui/async-await/generics-and-bounds.rs b/src/test/ui/async-await/generics-and-bounds.rs new file mode 100644 index 0000000000000..913f1435c6adf --- /dev/null +++ b/src/test/ui/async-await/generics-and-bounds.rs @@ -0,0 +1,90 @@ +// compile-pass +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +use std::future::Future; + +pub async fn simple_generic() {} + +pub trait Foo { + fn foo(&self) {} +} + +struct FooType; +impl Foo for FooType {} + +pub async fn call_generic_bound(f: F) { + f.foo() +} + +pub async fn call_where_clause(f: F) +where + F: Foo, +{ + f.foo() +} + +pub async fn call_impl_trait(f: impl Foo) { + f.foo() +} + +pub async fn call_with_ref(f: &impl Foo) { + f.foo() +} + +pub fn async_fn_with_same_generic_params_unifies() { + let mut a = call_generic_bound(FooType); + a = call_generic_bound(FooType); + + let mut b = call_where_clause(FooType); + b = call_where_clause(FooType); + + let mut c = call_impl_trait(FooType); + c = call_impl_trait(FooType); + + let f_one = FooType; + let f_two = FooType; + let mut d = call_with_ref(&f_one); + d = call_with_ref(&f_two); +} + +pub fn simple_generic_block() -> impl Future { + async move {} +} + +pub fn call_generic_bound_block(f: F) -> impl Future { + async move { f.foo() } +} + +pub fn call_where_clause_block(f: F) -> impl Future +where + F: Foo, +{ + async move { f.foo() } +} + +pub fn call_impl_trait_block(f: impl Foo) -> impl Future { + async move { f.foo() } +} + +pub fn call_with_ref_block<'a>(f: &'a (impl Foo + 'a)) -> impl Future + 'a { + async move { f.foo() } +} + +pub fn async_block_with_same_generic_params_unifies() { + let mut a = call_generic_bound_block(FooType); + a = call_generic_bound_block(FooType); + + let mut b = call_where_clause_block(FooType); + b = call_where_clause_block(FooType); + + let mut c = call_impl_trait_block(FooType); + c = call_impl_trait_block(FooType); + + let f_one = FooType; + let f_two = FooType; + let mut d = call_with_ref_block(&f_one); + d = call_with_ref_block(&f_two); +} diff --git a/src/test/ui/async-await/no-async-const.rs b/src/test/ui/async-await/no-async-const.rs new file mode 100644 index 0000000000000..1db314a5aa208 --- /dev/null +++ b/src/test/ui/async-await/no-async-const.rs @@ -0,0 +1,8 @@ +// compile-fail +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +pub async const fn x() {} +//~^ ERROR expected one of `fn` or `unsafe`, found `const` diff --git a/src/test/ui/async-await/no-async-const.stderr b/src/test/ui/async-await/no-async-const.stderr new file mode 100644 index 0000000000000..cdb1c6e2d7bd9 --- /dev/null +++ b/src/test/ui/async-await/no-async-const.stderr @@ -0,0 +1,8 @@ +error: expected one of `fn` or `unsafe`, found `const` + --> $DIR/no-async-const.rs:7:11 + | +LL | pub async const fn x() {} + | ^^^^^ expected one of `fn` or `unsafe` here + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs new file mode 100644 index 0000000000000..9f09d2188c7c0 --- /dev/null +++ b/src/test/ui/async-await/no-const-async.rs @@ -0,0 +1,9 @@ +// compile-fail +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +pub const async fn x() {} +//~^ ERROR expected identifier, found reserved keyword `async` +//~^^ expected `:`, found keyword `fn` diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr new file mode 100644 index 0000000000000..693fbf186f913 --- /dev/null +++ b/src/test/ui/async-await/no-const-async.stderr @@ -0,0 +1,18 @@ +error: expected identifier, found reserved keyword `async` + --> $DIR/no-const-async.rs:7:11 + | +LL | pub const async fn x() {} + | ^^^^^ expected identifier, found reserved keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | pub const r#async fn x() {} + | ^^^^^^^ + +error: expected `:`, found keyword `fn` + --> $DIR/no-const-async.rs:7:17 + | +LL | pub const async fn x() {} + | ^^ expected `:` + +error: aborting due to 2 previous errors + From 57db25e614dfc3ea3c407374a562501471eb1c5d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 25 Jun 2019 21:37:25 +0300 Subject: [PATCH 14/28] cleanup: rename name_from to symbol_from Lexer uses Symbols for a lot of stuff, not only for identifiers, so the "name" terminology is just confusing. --- src/libsyntax/parse/lexer/mod.rs | 39 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 7b9e3bc4d5102..4e4fe4256c9b0 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1,4 +1,3 @@ -use crate::ast; use crate::parse::ParseSess; use crate::parse::token::{self, Token, TokenKind}; use crate::symbol::{sym, Symbol}; @@ -328,14 +327,14 @@ impl<'a> StringReader<'a> { self.str_from_to(start, self.pos) } - /// Creates a Name from a given offset to the current offset. - fn name_from(&self, start: BytePos) -> ast::Name { + /// Creates a Symbol from a given offset to the current offset. + fn symbol_from(&self, start: BytePos) -> Symbol { debug!("taking an ident from {:?} to {:?}", start, self.pos); Symbol::intern(self.str_from(start)) } - /// As name_from, with an explicit endpoint. - fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name { + /// As symbol_from, with an explicit endpoint. + fn symbol_from_to(&self, start: BytePos, end: BytePos) -> Symbol { debug!("taking an ident from {:?} to {:?}", start, end); Symbol::intern(self.str_from_to(start, end)) } @@ -440,7 +439,7 @@ impl<'a> StringReader<'a> { } /// Eats *, if possible. - fn scan_optional_raw_name(&mut self) -> Option { + fn scan_optional_raw_name(&mut self) -> Option { if !ident_start(self.ch) { return None; } @@ -508,7 +507,7 @@ impl<'a> StringReader<'a> { } let kind = if doc_comment { - token::DocComment(self.name_from(start_bpos)) + token::DocComment(self.symbol_from(start_bpos)) } else { token::Comment }; @@ -537,7 +536,7 @@ impl<'a> StringReader<'a> { self.bump(); } return Some(Token::new( - token::Shebang(self.name_from(start)), + token::Shebang(self.symbol_from(start)), self.mk_sp(start, self.pos), )); } @@ -719,17 +718,17 @@ impl<'a> StringReader<'a> { let pos = self.pos; self.check_float_base(start_bpos, pos, base); - (token::Float, self.name_from(start_bpos)) + (token::Float, self.symbol_from(start_bpos)) } else { // it might be a float if it has an exponent if self.ch_is('e') || self.ch_is('E') { self.scan_float_exponent(); let pos = self.pos; self.check_float_base(start_bpos, pos, base); - return (token::Float, self.name_from(start_bpos)); + return (token::Float, self.symbol_from(start_bpos)); } // but we certainly have an integer! - (token::Integer, self.name_from(start_bpos)) + (token::Integer, self.symbol_from(start_bpos)) } } @@ -831,7 +830,7 @@ impl<'a> StringReader<'a> { } // FIXME: perform NFKC normalization here. (Issue #2253) - let name = self.name_from(start); + let name = self.symbol_from(start); if is_raw_ident { let span = self.mk_sp(raw_start, self.pos); if !name.can_be_raw() { @@ -1006,7 +1005,7 @@ impl<'a> StringReader<'a> { // lifetimes shouldn't end with a single quote // if we find one, then this is an invalid character literal if self.ch_is('\'') { - let symbol = self.name_from(start); + let symbol = self.symbol_from(start); self.bump(); self.validate_char_escape(start_with_quote); return Ok(TokenKind::lit(token::Char, symbol, None)); @@ -1024,7 +1023,7 @@ impl<'a> StringReader<'a> { // Include the leading `'` in the real identifier, for macro // expansion purposes. See #12512 for the gory details of why // this is necessary. - return Ok(token::Lifetime(self.name_from(start_with_quote))); + return Ok(token::Lifetime(self.symbol_from(start_with_quote))); } let msg = "unterminated character literal"; let symbol = self.scan_single_quoted_string(start_with_quote, msg); @@ -1052,7 +1051,7 @@ impl<'a> StringReader<'a> { }, Some('r') => { let (start, end, hash_count) = self.scan_raw_string(); - let symbol = self.name_from_to(start, end); + let symbol = self.symbol_from_to(start, end); self.validate_raw_byte_str_escape(start, end); (token::ByteStrRaw(hash_count), symbol) @@ -1073,7 +1072,7 @@ impl<'a> StringReader<'a> { } 'r' => { let (start, end, hash_count) = self.scan_raw_string(); - let symbol = self.name_from_to(start, end); + let symbol = self.symbol_from_to(start, end); self.validate_raw_str_escape(start, end); let suffix = self.scan_optional_raw_name(); @@ -1174,7 +1173,7 @@ impl<'a> StringReader<'a> { fn scan_single_quoted_string(&mut self, start_with_quote: BytePos, - unterminated_msg: &str) -> ast::Name { + unterminated_msg: &str) -> Symbol { // assumes that first `'` is consumed let start = self.pos; // lex `'''` as a single char, for recovery @@ -1206,12 +1205,12 @@ impl<'a> StringReader<'a> { } } - let id = self.name_from(start); + let id = self.symbol_from(start); self.bump(); id } - fn scan_double_quoted_string(&mut self, unterminated_msg: &str) -> ast::Name { + fn scan_double_quoted_string(&mut self, unterminated_msg: &str) -> Symbol { debug_assert!(self.ch_is('\"')); let start_with_quote = self.pos; self.bump(); @@ -1226,7 +1225,7 @@ impl<'a> StringReader<'a> { } self.bump(); } - let id = self.name_from(start); + let id = self.symbol_from(start); self.bump(); id } From 390f717a0af5851271792da9ff235c95f3db2556 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Jun 2019 22:59:00 +0200 Subject: [PATCH 15/28] tweak wording --- src/libstd/io/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 7fba844897ffe..3d0568c16cdf6 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -509,10 +509,10 @@ pub trait Read { /// contents of `buf` being true. It is recommended that *implementations* /// only write data to `buf` instead of reading its contents. /// - /// Correspondingly, however, *users* of this trait may not assume any guarantees + /// Correspondingly, however, *callers* of this method may not assume any guarantees /// about how the implementation uses `buf`. The trait is safe to implement, - /// so it is perfectly possible that the implementation might inspect that data. - /// As a caller, it is your responsibility to make sure that `buf` is initialized + // so it is possible that the code that's supposed to write to the buffer might also read + // from it. It is your responsibility to make sure that `buf` is initialized /// before calling `read`. Calling `read` with an uninitialized `buf` (of the kind one /// obtains via [`MaybeUninit`]) is not safe, and can lead to undefined behavior. /// From dedcd97e92f190ee99aa271c6cfd8978f123d731 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 25 Jun 2019 23:08:10 +0200 Subject: [PATCH 16/28] Use f{32,64}::from_bits --- src/libserialize/opaque.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs index a6a5c318079f1..75988198eb9b5 100644 --- a/src/libserialize/opaque.rs +++ b/src/libserialize/opaque.rs @@ -296,13 +296,13 @@ impl<'a> serialize::Decoder for Decoder<'a> { #[inline] fn read_f64(&mut self) -> Result { let bits = self.read_u64()?; - Ok(unsafe { ::std::mem::transmute(bits) }) + Ok(f64::from_bits(bits)) } #[inline] fn read_f32(&mut self) -> Result { let bits = self.read_u32()?; - Ok(unsafe { ::std::mem::transmute(bits) }) + Ok(f32::from_bits(bits)) } #[inline] From 12806b70506508c4ec187f0223e1e86f89167448 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 25 Jun 2019 23:22:45 +0200 Subject: [PATCH 17/28] Fix clippy::redundant_field_names --- .../vec_linked_list.rs | 2 +- .../annotate_snippet_emitter_writer.rs | 2 +- src/librustc_errors/diagnostic.rs | 2 +- src/librustc_target/spec/fuchsia_base.rs | 2 +- src/libserialize/json.rs | 2 +- src/libsyntax/ast.rs | 4 ++-- src/libsyntax/ext/build.rs | 2 +- src/libsyntax/ext/expand.rs | 6 +++--- src/libsyntax/ext/tt/quoted.rs | 2 +- src/libsyntax/ext/tt/transcribe.rs | 6 +++--- src/libsyntax/feature_gate.rs | 2 +- src/libsyntax/parse/parser.rs | 18 +++++++++--------- src/libsyntax/source_map.rs | 8 ++++---- 13 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/librustc_data_structures/vec_linked_list.rs b/src/librustc_data_structures/vec_linked_list.rs index c00c707a43542..0fb8060031843 100644 --- a/src/librustc_data_structures/vec_linked_list.rs +++ b/src/librustc_data_structures/vec_linked_list.rs @@ -8,7 +8,7 @@ where Ls: Links, { VecLinkedListIterator { - links: links, + links, current: first, } } diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 7ed2fddf72d23..3641d355ef19c 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -94,7 +94,7 @@ impl<'a> DiagnosticConverter<'a> { annotation_type: Self::annotation_type_for_level(self.level), }), footer: vec![], - slices: slices, + slices, }) } else { // FIXME(#59346): Is it ok to return None if there's no source_map? diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index fc1fd960c4ace..424d7c0038389 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -388,7 +388,7 @@ impl Diagnostic { }], msg: msg.to_owned(), style: SuggestionStyle::CompletelyHidden, - applicability: applicability, + applicability, }); self } diff --git a/src/librustc_target/spec/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs index 4e4f2fa0cf34c..48749dff941ac 100644 --- a/src/librustc_target/spec/fuchsia_base.rs +++ b/src/librustc_target/spec/fuchsia_base.rs @@ -19,7 +19,7 @@ pub fn opts() -> TargetOptions { is_like_fuchsia: true, linker_is_gnu: true, has_rpath: false, - pre_link_args: pre_link_args, + pre_link_args, pre_link_objects_exe: vec![ "Scrt1.o".to_string() ], diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 2c3bea80e349b..826954ce2168c 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -461,7 +461,7 @@ impl<'a> Encoder<'a> { /// Creates a new JSON encoder whose output will be written to the writer /// specified. pub fn new(writer: &'a mut dyn fmt::Write) -> Encoder<'a> { - Encoder { writer: writer, is_emitting_map_key: false, } + Encoder { writer, is_emitting_map_key: false, } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f2fac16db01d2..c627596bbdf20 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1832,7 +1832,7 @@ impl Arg { lt, MutTy { ty: infer_ty, - mutbl: mutbl, + mutbl, }, ), span, @@ -2120,7 +2120,7 @@ impl PolyTraitRef { PolyTraitRef { bound_generic_params: generic_params, trait_ref: TraitRef { - path: path, + path, ref_id: DUMMY_NODE_ID, }, span, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 9d4bf7d518d75..baf1031de1e7c 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -815,7 +815,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn pat(&self, span: Span, pat: PatKind) -> P { - P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span }) + P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span }) } fn pat_wild(&self, span: Span) -> P { self.pat(span, PatKind::Wild) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 945cf36af46fe..5473f55aa3370 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -231,7 +231,7 @@ pub struct MacroExpander<'a, 'b> { impl<'a, 'b> MacroExpander<'a, 'b> { pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self { - MacroExpander { cx: cx, monotonic: monotonic } + MacroExpander { cx, monotonic } } pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { @@ -377,7 +377,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => item.clone(), }; invocations.push(Invocation { - kind: InvocationKind::Derive { path: path.clone(), item: item }, + kind: InvocationKind::Derive { path: path.clone(), item }, fragment_kind: invoc.fragment_kind, expansion_data: ExpansionData { mark, @@ -944,7 +944,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment { - self.collect(kind, InvocationKind::Bang { mac: mac, ident: None, span: span }) + self.collect(kind, InvocationKind::Bang { mac, ident: None, span }) } fn collect_attr(&mut self, diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index 6f5ce89bc315a..ccf9db842ab6e 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -319,7 +319,7 @@ fn parse_tree( tokenstream::TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited( span, Lrc::new(Delimited { - delim: delim, + delim, tts: parse( tts.into(), expect_matchers, diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index c51f4b20c31c0..ea7f8e356aa63 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -23,8 +23,8 @@ enum Frame { impl Frame { /// Construct a new frame around the delimited set of tokens. fn new(tts: Vec) -> Frame { - let forest = Lrc::new(quoted::Delimited { delim: token::NoDelim, tts: tts }); - Frame::Delimited { forest: forest, idx: 0, span: DelimSpan::dummy() } + let forest = Lrc::new(quoted::Delimited { delim: token::NoDelim, tts }); + Frame::Delimited { forest, idx: 0, span: DelimSpan::dummy() } } } @@ -248,7 +248,7 @@ pub fn transcribe( // the previous results (from outside the Delimited). quoted::TokenTree::Delimited(mut span, delimited) => { span = span.apply_mark(cx.current_expansion.mark); - stack.push(Frame::Delimited { forest: delimited, idx: 0, span: span }); + stack.push(Frame::Delimited { forest: delimited, idx: 0, span }); result_stack.push(mem::replace(&mut result, Vec::new())); } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c405acd8ee3f6..a6e8441a915e0 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1665,7 +1665,7 @@ impl<'a> Context<'a> { } pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) { - let cx = Context { features: features, parse_sess: parse_sess, plugin_attributes: &[] }; + let cx = Context { features, parse_sess, plugin_attributes: &[] }; cx.check_attribute( attr, attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a1440f2eba47e..fc206580e3811 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -290,10 +290,10 @@ crate enum LastToken { } impl TokenCursorFrame { - fn new(sp: DelimSpan, delim: DelimToken, tts: &TokenStream) -> Self { + fn new(span: DelimSpan, delim: DelimToken, tts: &TokenStream) -> Self { TokenCursorFrame { - delim: delim, - span: sp, + delim, + span, open_delim: delim == token::NoDelim, tree_cursor: tts.clone().into_trees(), close_delim: delim == token::NoDelim, @@ -1449,7 +1449,7 @@ impl<'a> Parser<'a> { let opt_lifetime = if self.check_lifetime() { Some(self.expect_lifetime()) } else { None }; let mutbl = self.parse_mutability(); let ty = self.parse_ty_no_plus()?; - return Ok(TyKind::Rptr(opt_lifetime, MutTy { ty: ty, mutbl: mutbl })); + return Ok(TyKind::Rptr(opt_lifetime, MutTy { ty, mutbl })); } fn parse_ptr(&mut self) -> PResult<'a, MutTy> { @@ -1467,7 +1467,7 @@ impl<'a> Parser<'a> { Mutability::Immutable }; let t = self.parse_ty_no_plus()?; - Ok(MutTy { ty: t, mutbl: mutbl }) + Ok(MutTy { ty: t, mutbl }) } fn is_named_argument(&self) -> bool { @@ -4366,7 +4366,7 @@ impl<'a> Parser<'a> { self.report_invalid_macro_expansion_item(); } - (ident, ast::MacroDef { tokens: tokens, legacy: true }) + (ident, ast::MacroDef { tokens, legacy: true }) } _ => return Ok(None), }; @@ -6789,12 +6789,12 @@ impl<'a> Parser<'a> { let hi = self.token.span; self.expect(&token::Semi)?; Ok(ast::ForeignItem { - ident: ident, - attrs: attrs, + ident, + attrs, node: ForeignItemKind::Ty, id: ast::DUMMY_NODE_ID, span: lo.to(hi), - vis: vis + vis }) } diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index c0307263387ec..ac30cbb471aea 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -150,7 +150,7 @@ impl SourceMap { -> SourceMap { SourceMap { files: Default::default(), - file_loader: file_loader, + file_loader, path_mapping, } } @@ -396,7 +396,7 @@ impl SourceMap { let f = (*self.files.borrow().source_files)[idx].clone(); match f.lookup_line(pos) { - Some(line) => Ok(SourceFileAndLine { sf: f, line: line }), + Some(line) => Ok(SourceFileAndLine { sf: f, line }), None => Err(f) } } @@ -511,7 +511,7 @@ impl SourceMap { start_col, end_col: hi.col }); - Ok(FileLines {file: lo.file, lines: lines}) + Ok(FileLines {file: lo.file, lines}) } /// Extracts the source surrounding the given `Span` using the `extract_source` function. The @@ -820,7 +820,7 @@ impl SourceMap { let idx = self.lookup_source_file_idx(bpos); let sf = (*self.files.borrow().source_files)[idx].clone(); let offset = bpos - sf.start_pos; - SourceFileAndBytePos {sf: sf, pos: offset} + SourceFileAndBytePos {sf, pos: offset} } /// Converts an absolute BytePos to a CharPos relative to the source_file. From 6c93b47c010f09d6f1ec8303898984944fdbd6f0 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Wed, 26 Jun 2019 14:04:37 +0200 Subject: [PATCH 18/28] Fix clippy::cast_losless --- src/librustc_data_structures/fingerprint.rs | 4 ++-- src/librustc_data_structures/sip128.rs | 6 +++--- src/librustc_data_structures/stable_hasher.rs | 2 +- src/libserialize/json.rs | 12 ++++++------ src/libserialize/leb128.rs | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/librustc_data_structures/fingerprint.rs b/src/librustc_data_structures/fingerprint.rs index c4c0db5801209..7975c62b90fb6 100644 --- a/src/librustc_data_structures/fingerprint.rs +++ b/src/librustc_data_structures/fingerprint.rs @@ -39,8 +39,8 @@ impl Fingerprint { // you want. #[inline] pub fn combine_commutative(self, other: Fingerprint) -> Fingerprint { - let a = (self.1 as u128) << 64 | self.0 as u128; - let b = (other.1 as u128) << 64 | other.0 as u128; + let a = u128::from(self.1) << 64 | u128::from(self.0); + let b = u128::from(other.1) << 64 | u128::from(other.0); let c = a.wrapping_add(b); diff --git a/src/librustc_data_structures/sip128.rs b/src/librustc_data_structures/sip128.rs index 06f157f972932..7838a90089024 100644 --- a/src/librustc_data_structures/sip128.rs +++ b/src/librustc_data_structures/sip128.rs @@ -70,15 +70,15 @@ unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 { let mut i = 0; // current byte index (from LSB) in the output u64 let mut out = 0; if i + 3 < len { - out = load_int_le!(buf, start + i, u32) as u64; + out = u64::from(load_int_le!(buf, start + i, u32)); i += 4; } if i + 1 < len { - out |= (load_int_le!(buf, start + i, u16) as u64) << (i * 8); + out |= u64::from(load_int_le!(buf, start + i, u16)) << (i * 8); i += 2 } if i < len { - out |= (*buf.get_unchecked(start + i) as u64) << (i * 8); + out |= u64::from(*buf.get_unchecked(start + i)) << (i * 8); i += 1; } debug_assert_eq!(i, len); diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 0c81c27a96ee5..47dfc1d1688d0 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -44,7 +44,7 @@ impl StableHasher { impl StableHasherResult for u128 { fn finish(hasher: StableHasher) -> Self { let (_0, _1) = hasher.finalize(); - (_0 as u128) | ((_1 as u128) << 64) + u128::from(_0) | (u128::from(_1) << 64) } } diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 826954ce2168c..a7e7c09f9ae44 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -513,7 +513,7 @@ impl<'a> crate::Encoder for Encoder<'a> { emit_enquoted_if_mapkey!(self, fmt_number_or_null(v)) } fn emit_f32(&mut self, v: f32) -> EncodeResult { - self.emit_f64(v as f64) + self.emit_f64(f64::from(v)) } fn emit_char(&mut self, v: char) -> EncodeResult { @@ -763,7 +763,7 @@ impl<'a> crate::Encoder for PrettyEncoder<'a> { emit_enquoted_if_mapkey!(self, fmt_number_or_null(v)) } fn emit_f32(&mut self, v: f32) -> EncodeResult { - self.emit_f64(v as f64) + self.emit_f64(f64::from(v)) } fn emit_char(&mut self, v: char) -> EncodeResult { @@ -1698,12 +1698,12 @@ impl> Parser { if n2 < 0xDC00 || n2 > 0xDFFF { return self.error(LoneLeadingSurrogateInHexEscape) } - let c = (((n1 - 0xD800) as u32) << 10 | - (n2 - 0xDC00) as u32) + 0x1_0000; + let c = (u32::from(n1 - 0xD800) << 10 | + u32::from(n2 - 0xDC00)) + 0x1_0000; res.push(char::from_u32(c).unwrap()); } - n => match char::from_u32(n as u32) { + n => match char::from_u32(u32::from(n)) { Some(c) => res.push(c), None => return self.error(InvalidUnicodeCodePoint), }, @@ -2405,7 +2405,7 @@ impl ToJson for Json { } impl ToJson for f32 { - fn to_json(&self) -> Json { (*self as f64).to_json() } + fn to_json(&self) -> Json { f64::from(*self).to_json() } } impl ToJson for f64 { diff --git a/src/libserialize/leb128.rs b/src/libserialize/leb128.rs index 16ff59489e718..f9d80842d7558 100644 --- a/src/libserialize/leb128.rs +++ b/src/libserialize/leb128.rs @@ -123,7 +123,7 @@ pub fn read_signed_leb128(data: &[u8], start_position: usize) -> (i128, usize) { loop { byte = data[position]; position += 1; - result |= ((byte & 0x7F) as i128) << shift; + result |= i128::from(byte & 0x7F) << shift; shift += 7; if (byte & 0x80) == 0 { From 33f58baf6eb6beea0ec5c93b1c81714b05eae378 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Wed, 26 Jun 2019 14:07:08 +0200 Subject: [PATCH 19/28] Fix clippy::redundant_closure --- src/librustc_data_structures/obligation_forest/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 4490e5f86d2bd..557e5e2186f11 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -263,7 +263,7 @@ impl ObligationForest { done_cache: Default::default(), waiting_cache: Default::default(), scratch: Some(vec![]), - obligation_tree_id_generator: (0..).map(|i| ObligationTreeId(i)), + obligation_tree_id_generator: (0..).map(ObligationTreeId), error_cache: Default::default(), } } From 1af1f6277e78cb3e1d9c3aafc1e5a65c58916023 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Wed, 26 Jun 2019 14:11:40 +0200 Subject: [PATCH 20/28] Fix clippy::print_with_newline --- src/librustc_errors/emitter.rs | 4 ++-- src/libsyntax/print/pp.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index fca8298409a61..a2717ab7ad8a9 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1339,7 +1339,7 @@ impl EmitterWriter { } let mut dst = self.dst.writable(); - match write!(dst, "\n") { + match writeln!(dst) { Err(e) => panic!("failed to emit error: {}", e), _ => { match dst.flush() { @@ -1598,7 +1598,7 @@ fn emit_to_destination(rendered_buffer: &[Vec], dst.reset()?; } if !short_message && (!lvl.is_failure_note() || pos != rendered_buffer.len() - 1) { - write!(dst, "\n")?; + writeln!(dst)?; } } dst.flush()?; diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 45eb6995a7699..f5412f3e21602 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -497,7 +497,7 @@ impl<'a> Printer<'a> { pub fn print_newline(&mut self, amount: isize) -> io::Result<()> { debug!("NEWLINE {}", amount); - let ret = write!(self.out, "\n"); + let ret = writeln!(self.out); self.pending_indentation = 0; self.indent(amount); ret From ad62b4203ce3f0bd4c7c348aeabca4f49d5ce075 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Wed, 26 Jun 2019 14:14:27 +0200 Subject: [PATCH 21/28] Fix clippy::precedence --- src/librustc_data_structures/sip128.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_data_structures/sip128.rs b/src/librustc_data_structures/sip128.rs index 7838a90089024..e5de359e4759e 100644 --- a/src/librustc_data_structures/sip128.rs +++ b/src/librustc_data_structures/sip128.rs @@ -237,7 +237,7 @@ impl Hasher for SipHasher128 { if self.ntail != 0 { needed = 8 - self.ntail; - self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << 8 * self.ntail; + self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail); if length < needed { self.ntail += length; return From 5cb841d72e70f92fc4318833db4824d07ab4c911 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Wed, 26 Jun 2019 13:48:41 +0100 Subject: [PATCH 22/28] Don't ICE on item in `.await` expression --- src/librustc/hir/lowering.rs | 1 - src/librustc/hir/mod.rs | 2 +- src/librustc_typeck/check/expr.rs | 20 ++++++-- src/test/ui/async-await/issues/issue-51719.rs | 3 +- .../ui/async-await/issues/issue-51719.stderr | 4 +- src/test/ui/async-await/issues/issue-62009.rs | 19 +++++++ .../ui/async-await/issues/issue-62009.stderr | 49 +++++++++++++++++++ 7 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/async-await/issues/issue-62009.rs create mode 100644 src/test/ui/async-await/issues/issue-62009.stderr diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1b8e2999afe6a..9c4a208f0f9fc 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -5795,7 +5795,6 @@ impl<'a> LoweringContext<'a> { err.span_label(item_sp, "this is not `async`"); } err.emit(); - return hir::ExprKind::Err; } } let span = self.mark_span_with_reason( diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 2b46170a6d232..6df1c2d8c77e5 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1713,7 +1713,7 @@ pub enum GeneratorMovability { } /// The yield kind that caused an `ExprKind::Yield`. -#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable)] pub enum YieldSource { /// An `.await`. Await, diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 85da325197143..21fa219a1cab2 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -295,8 +295,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Index(ref base, ref idx) => { self.check_expr_index(base, idx, needs, expr) } - ExprKind::Yield(ref value, _) => { - self.check_expr_yield(value, expr) + ExprKind::Yield(ref value, ref src) => { + self.check_expr_yield(value, expr, src) } hir::ExprKind::Err => { tcx.types.err @@ -1541,12 +1541,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_expr_yield(&self, value: &'tcx hir::Expr, expr: &'tcx hir::Expr) -> Ty<'tcx> { + fn check_expr_yield( + &self, + value: &'tcx hir::Expr, + expr: &'tcx hir::Expr, + src: &'tcx hir::YieldSource + ) -> Ty<'tcx> { match self.yield_ty { Some(ty) => { self.check_expr_coercable_to_type(&value, ty); } - None => { + // Given that this `yield` expression was generated as a result of lowering a `.await`, + // we know that the yield type must be `()`; however, the context won't contain this + // information. Hence, we check the source of the yield expression here and check its + // value's type against `()` (this check should always hold). + None if src == &hir::YieldSource::Await => { + self.check_expr_coercable_to_type(&value, self.tcx.mk_unit()); + } + _ => { struct_span_err!(self.tcx.sess, expr.span, E0627, "yield statement outside of generator literal").emit(); } diff --git a/src/test/ui/async-await/issues/issue-51719.rs b/src/test/ui/async-await/issues/issue-51719.rs index 5966edd0bf098..361a49c2774ec 100644 --- a/src/test/ui/async-await/issues/issue-51719.rs +++ b/src/test/ui/async-await/issues/issue-51719.rs @@ -7,7 +7,8 @@ async fn foo() {} fn make_generator() { - let _gen = || foo.await; //~ ERROR `await` is only allowed inside `async` functions and blocks + let _gen = || foo().await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks } fn main() {} diff --git a/src/test/ui/async-await/issues/issue-51719.stderr b/src/test/ui/async-await/issues/issue-51719.stderr index c06165b24468f..2a9fb6cf0df6e 100644 --- a/src/test/ui/async-await/issues/issue-51719.stderr +++ b/src/test/ui/async-await/issues/issue-51719.stderr @@ -1,8 +1,8 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-51719.rs:10:19 | -LL | let _gen = || foo.await; - | -- ^^^^^^^^^ only allowed inside `async` functions and blocks +LL | let _gen = || foo().await; + | -- ^^^^^^^^^^^ only allowed inside `async` functions and blocks | | | this is not `async` diff --git a/src/test/ui/async-await/issues/issue-62009.rs b/src/test/ui/async-await/issues/issue-62009.rs new file mode 100644 index 0000000000000..e2d58cac24d94 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-62009.rs @@ -0,0 +1,19 @@ +// edition:2018 + +#![feature(async_await)] + +async fn print_dur() {} + +fn main() { + async { let (); }.await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks + async { + //~^ ERROR `await` is only allowed inside `async` functions and blocks + let task1 = print_dur().await; + }.await; + (async || 2333)().await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks + (|_| 2333).await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks + //~^^ ERROR +} diff --git a/src/test/ui/async-await/issues/issue-62009.stderr b/src/test/ui/async-await/issues/issue-62009.stderr new file mode 100644 index 0000000000000..53d1f34fe4f9b --- /dev/null +++ b/src/test/ui/async-await/issues/issue-62009.stderr @@ -0,0 +1,49 @@ +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009.rs:8:5 + | +LL | fn main() { + | ---- this is not `async` +LL | async { let (); }.await; + | ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009.rs:10:5 + | +LL | fn main() { + | ---- this is not `async` +... +LL | / async { +LL | | +LL | | let task1 = print_dur().await; +LL | | }.await; + | |___________^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009.rs:14:5 + | +LL | fn main() { + | ---- this is not `async` +... +LL | (async || 2333)().await; + | ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009.rs:16:5 + | +LL | fn main() { + | ---- this is not `async` +... +LL | (|_| 2333).await; + | ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0277]: the trait bound `[closure@$DIR/issue-62009.rs:16:5: 16:15]: std::future::Future` is not satisfied + --> $DIR/issue-62009.rs:16:5 + | +LL | (|_| 2333).await; + | ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009.rs:16:5: 16:15]` + | + = note: required by `std::future::poll_with_tls_context` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. From 182ce772efee7d3951e807113f069f9bceb87ef6 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 26 Jun 2019 11:21:59 -0500 Subject: [PATCH 23/28] remove old fixme --- src/libsyntax/parse/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index 07fe521edb037..0ea0b2a694d7d 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -942,7 +942,7 @@ impl<'a> Parser<'a> { // {foo(bar {}} // - ^ // | | - // | help: `)` may belong here (FIXME: #58270) + // | help: `)` may belong here // | // unclosed delimiter if let Some(sp) = unmatched.unclosed_span { From 72ca844ca7d9debbb849eb3aa16c5c4df14d1293 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 26 Jun 2019 10:23:27 -0700 Subject: [PATCH 24/28] Add regression test for MIR drop generation in async loops Fixes #61986. --- src/test/ui/async-await/issues/issue-61986.rs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/ui/async-await/issues/issue-61986.rs diff --git a/src/test/ui/async-await/issues/issue-61986.rs b/src/test/ui/async-await/issues/issue-61986.rs new file mode 100644 index 0000000000000..da8b22bc104bf --- /dev/null +++ b/src/test/ui/async-await/issues/issue-61986.rs @@ -0,0 +1,21 @@ +// compile-pass +// edition:2018 +// +// Tests that we properly handle StorageDead/StorageLives for temporaries +// created in async loop bodies. + +#![feature(async_await)] + +async fn bar() -> Option<()> { + Some(()) +} + +async fn listen() { + while let Some(_) = bar().await { + String::new(); + } +} + +fn main() { + listen(); +} From 7e62050b2381e732808d236d2bb2056ba2edcee8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 26 Jun 2019 10:57:00 -0700 Subject: [PATCH 25/28] Update books --- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-guide | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/book b/src/doc/book index 9aacfcc4c5b10..6c0d83499c8e7 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 9aacfcc4c5b102c8cda195932addefd32fe955d2 +Subproject commit 6c0d83499c8e77e06a71d28c5e1adccec278d4f3 diff --git a/src/doc/nomicon b/src/doc/nomicon index c656171b749b7..341c221116a8b 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit c656171b749b7307f21371dd0d3278efee5573b8 +Subproject commit 341c221116a8b9f1010cf1eece952b80c5ec7f54 diff --git a/src/doc/reference b/src/doc/reference index 08ae27a4921ca..7a5aab5fd50d6 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 08ae27a4921ca53967656a7391c82f6c0ddd1ccc +Subproject commit 7a5aab5fd50d6290679beb4cf42fa5f46ed22aec diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index b27472962986e..62b3ff2cb44dd 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit b27472962986e85c94f4183b1a6d2207660d3ed6 +Subproject commit 62b3ff2cb44dd8b648c3ef2a9347c3706d148014 diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide index f55e97c145cf3..abf512fc9cc96 160000 --- a/src/doc/rustc-guide +++ b/src/doc/rustc-guide @@ -1 +1 @@ -Subproject commit f55e97c145cf37fd664db2e0e2f2d05df328bf4f +Subproject commit abf512fc9cc969dcbea69aa15b44586bbeb13c2d From e053eede872b1992c55fbdaeec104b7c84a23f1a Mon Sep 17 00:00:00 2001 From: Julien Cretin Date: Wed, 26 Jun 2019 20:34:12 +0200 Subject: [PATCH 26/28] Remove outdated question_mark_macro_sep lint --- src/librustc/lint/builtin.rs | 7 ------- src/librustc/lint/mod.rs | 3 +-- src/librustc_lint/lib.rs | 6 ------ src/libsyntax/early_buffered_lints.rs | 2 -- 4 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index f7af51e47526c..45e598531b969 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -348,12 +348,6 @@ declare_lint! { /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`. pub mod parser { - declare_lint! { - pub QUESTION_MARK_MACRO_SEP, - Allow, - "detects the use of `?` as a macro separator" - } - declare_lint! { pub ILL_FORMED_ATTRIBUTE_INPUT, Warn, @@ -444,7 +438,6 @@ declare_lint_pass! { PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, - parser::QUESTION_MARK_MACRO_SEP, parser::ILL_FORMED_ATTRIBUTE_INPUT, DEPRECATED_IN_FUTURE, AMBIGUOUS_ASSOCIATED_ITEMS, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 041944d887bd9..309af4b72c127 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -27,7 +27,7 @@ use crate::hir::def_id::{CrateNum, LOCAL_CRATE}; use crate::hir::intravisit; use crate::hir; use crate::lint::builtin::BuiltinLintDiagnostics; -use crate::lint::builtin::parser::{QUESTION_MARK_MACRO_SEP, ILL_FORMED_ATTRIBUTE_INPUT}; +use crate::lint::builtin::parser::ILL_FORMED_ATTRIBUTE_INPUT; use crate::session::{Session, DiagnosticMessageId}; use crate::ty::TyCtxt; use crate::ty::query::Providers; @@ -80,7 +80,6 @@ impl Lint { /// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`. pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self { match lint_id { - BufferedEarlyLintId::QuestionMarkMacroSep => QUESTION_MARK_MACRO_SEP, BufferedEarlyLintId::IllFormedAttributeInput => ILL_FORMED_ATTRIBUTE_INPUT, } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index ec8a9c6fbb2a8..d808a15982e37 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -42,7 +42,6 @@ use rustc::lint::builtin::{ INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, - parser::QUESTION_MARK_MACRO_SEP, parser::ILL_FORMED_ATTRIBUTE_INPUT, }; use rustc::session; @@ -404,11 +403,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #50504 ", edition: None, }, - FutureIncompatibleInfo { - id: LintId::of(QUESTION_MARK_MACRO_SEP), - reference: "issue #48075 ", - edition: Some(Edition::Edition2018), - }, FutureIncompatibleInfo { id: LintId::of(MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS), reference: "issue #52234 ", diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs index 598c8459d1590..b26a1165fed1d 100644 --- a/src/libsyntax/early_buffered_lints.rs +++ b/src/libsyntax/early_buffered_lints.rs @@ -9,8 +9,6 @@ use syntax_pos::MultiSpan; /// Since we cannot import `LintId`s from `rustc::lint`, we define some Ids here which can later be /// passed to `rustc::lint::Lint::from_parser_lint_id` to get a `rustc::lint::Lint`. pub enum BufferedEarlyLintId { - /// Usage of `?` as a macro separator is deprecated. - QuestionMarkMacroSep, IllFormedAttributeInput, } From b366f2b5fa9b60fbadf3b96a8fd528d76dec7450 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 26 Jun 2019 07:50:30 -0400 Subject: [PATCH 27/28] Implement mem::{zeroed,uninitialized} in terms of MaybeUninit. Refs #62061 --- src/libcore/intrinsics.rs | 16 +++++++--------- src/libcore/mem/mod.rs | 6 ++---- src/librustc_codegen_llvm/intrinsic.rs | 2 +- src/librustc_typeck/check/intrinsic.rs | 1 - src/test/run-pass/intrinsics/intrinsic-uninit.rs | 13 ------------- src/test/ui/init-unsafe.rs | 1 + src/test/ui/init-unsafe.stderr | 2 +- 7 files changed, 12 insertions(+), 29 deletions(-) delete mode 100644 src/test/run-pass/intrinsics/intrinsic-uninit.rs diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index b30eff8baa9c8..f613dde05a573 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -700,17 +700,15 @@ extern "rust-intrinsic" { /// which is unsafe unless `T` is `Copy`. Also, even if T is /// `Copy`, an all-zero value may not correspond to any legitimate /// state for the type in question. + #[unstable(feature = "core_intrinsics", + reason = "intrinsics are unlikely to ever be stabilized, instead \ + they should be used through stabilized interfaces \ + in the rest of the standard library", + issue = "0")] + #[rustc_deprecated(reason = "no longer used by rustc, will be removed - use MaybeUnint instead", + since = "1.37.0")] pub fn init() -> T; - /// Creates an uninitialized value. - /// - /// `uninit` is unsafe because there is no guarantee of what its - /// contents are. In particular its drop-flag may be set to any - /// state, which means it may claim either dropped or - /// undropped. In the general case one must use `ptr::write` to - /// initialize memory previous set to the result of `uninit`. - pub fn uninit() -> T; - /// Moves a value out of scope without running drop glue. pub fn forget(_: T); diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index 770d1ca8e7501..e90dfcd3b96d3 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -450,8 +450,7 @@ pub const fn needs_drop() -> bool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn zeroed() -> T { - intrinsics::panic_if_uninhabited::(); - intrinsics::init() + MaybeUninit::zeroed().assume_init() } /// Bypasses Rust's normal memory-initialization checks by pretending to @@ -476,8 +475,7 @@ pub unsafe fn zeroed() -> T { #[rustc_deprecated(since = "1.38.0", reason = "use `mem::MaybeUninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { - intrinsics::panic_if_uninhabited::(); - intrinsics::uninit() + MaybeUninit::uninit().assume_init() } /// Swaps the values at two mutable locations, without deinitializing either one. diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 7831c200114a5..69f8356f66920 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -234,7 +234,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { return; } // Effectively no-ops - "uninit" | "forget" => { + "forget" => { return; } "needs_drop" => { diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 8c2b8d1565f2f..72234ab84ad3b 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -145,7 +145,6 @@ pub fn check_intrinsic_type<'tcx>(tcx: TyCtxt<'tcx>, it: &hir::ForeignItem) { "rustc_peek" => (1, vec![param(0)], param(0)), "panic_if_uninhabited" => (1, Vec::new(), tcx.mk_unit()), "init" => (1, Vec::new(), param(0)), - "uninit" => (1, Vec::new(), param(0)), "forget" => (1, vec![param(0)], tcx.mk_unit()), "transmute" => (2, vec![ param(0) ], param(1)), "move_val_init" => { diff --git a/src/test/run-pass/intrinsics/intrinsic-uninit.rs b/src/test/run-pass/intrinsics/intrinsic-uninit.rs deleted file mode 100644 index 9555efb639b50..0000000000000 --- a/src/test/run-pass/intrinsics/intrinsic-uninit.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![feature(intrinsics)] - -mod rusti { - extern "rust-intrinsic" { - pub fn uninit() -> T; - } -} -pub fn main() { - let _a : isize = unsafe {rusti::uninit()}; -} diff --git a/src/test/ui/init-unsafe.rs b/src/test/ui/init-unsafe.rs index 92b21c4efa3a2..3d65cfc234092 100644 --- a/src/test/ui/init-unsafe.rs +++ b/src/test/ui/init-unsafe.rs @@ -1,3 +1,4 @@ +#![allow(deprecated)] #![feature(core_intrinsics)] use std::intrinsics::{init}; diff --git a/src/test/ui/init-unsafe.stderr b/src/test/ui/init-unsafe.stderr index 857142dff64b7..e1126316af34e 100644 --- a/src/test/ui/init-unsafe.stderr +++ b/src/test/ui/init-unsafe.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/init-unsafe.rs:7:17 + --> $DIR/init-unsafe.rs:8:17 | LL | let stuff = init::(); | ^^^^^^^^^^^^^^^ call to unsafe function From 768d5001575091dd298fbfce3b7b03a3c3faf117 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 26 Jun 2019 17:22:39 -0700 Subject: [PATCH 28/28] save-analysis: use buffered writes Otherwise it ends up writing the file byte at a time, which can be very slow for large outputs. --- src/librustc_save_analysis/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 19ed9e214073c..ab82f75f74f4b 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -29,6 +29,7 @@ use std::cell::Cell; use std::default::Default; use std::env; use std::fs::File; +use std::io::BufWriter; use std::path::{Path, PathBuf}; use syntax::ast::{self, Attribute, DUMMY_NODE_ID, NodeId, PatKind}; @@ -1025,7 +1026,7 @@ impl<'a> DumpHandler<'a> { } } - fn output_file(&self, ctx: &SaveContext<'_, '_>) -> (File, PathBuf) { + fn output_file(&self, ctx: &SaveContext<'_, '_>) -> (BufWriter, PathBuf) { let sess = &ctx.tcx.sess; let file_name = match ctx.config.output_file { Some(ref s) => PathBuf::from(s), @@ -1059,9 +1060,9 @@ impl<'a> DumpHandler<'a> { info!("Writing output to {}", file_name.display()); - let output_file = File::create(&file_name).unwrap_or_else( + let output_file = BufWriter::new(File::create(&file_name).unwrap_or_else( |e| sess.fatal(&format!("Could not open {}: {}", file_name.display(), e)), - ); + )); (output_file, file_name) }