From 968ea1ce32ac894a7d58702c409233638aa5592d Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 4 Apr 2019 21:25:08 +0100 Subject: [PATCH 01/28] Mark variables captured by reference as mutable correctly --- src/librustc_mir/borrow_check/mod.rs | 96 ++++++++++++++++++++++------ src/test/ui/nll/extra-unused-mut.rs | 19 +++--- 2 files changed, 87 insertions(+), 28 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index a8c151a22eebc..ab3239820e3a2 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -28,7 +28,7 @@ use std::collections::BTreeMap; use syntax_pos::Span; use crate::dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathIndex}; -use crate::dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MoveError}; +use crate::dataflow::move_paths::{HasMoveData, InitLocation, LookupResult, MoveData, MoveError}; use crate::dataflow::Borrows; use crate::dataflow::DataflowResultsConsumer; use crate::dataflow::FlowAtLocation; @@ -1206,25 +1206,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } = self.infcx.tcx.mir_borrowck(def_id); debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars); for field in used_mut_upvars { - // This relies on the current way that by-value - // captures of a closure are copied/moved directly - // when generating MIR. - match operands[field.index()] { - Operand::Move(Place::Base(PlaceBase::Local(local))) - | Operand::Copy(Place::Base(PlaceBase::Local(local))) => { - self.used_mut.insert(local); - } - Operand::Move(ref place @ Place::Projection(_)) - | Operand::Copy(ref place @ Place::Projection(_)) => { - if let Some(field) = place.is_upvar_field_projection( - self.mir, &self.infcx.tcx) { - self.used_mut_upvars.push(field); - } - } - Operand::Move(Place::Base(PlaceBase::Static(..))) - | Operand::Copy(Place::Base(PlaceBase::Static(..))) - | Operand::Constant(..) => {} - } + self.propagate_closure_used_mut_upvar(&operands[field.index()]); } } AggregateKind::Adt(..) @@ -1239,6 +1221,80 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } + fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) { + let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| { + match *place { + Place::Projection { .. } => { + if let Some(field) = place.is_upvar_field_projection( + this.mir, &this.infcx.tcx) { + this.used_mut_upvars.push(field); + } + } + Place::Base(PlaceBase::Local(local)) => { + this.used_mut.insert(local); + } + Place::Base(PlaceBase::Static(_)) => {} + } + }; + + // This relies on the current way that by-value + // captures of a closure are copied/moved directly + // when generating MIR. + match *operand { + Operand::Move(Place::Base(PlaceBase::Local(local))) + | Operand::Copy(Place::Base(PlaceBase::Local(local))) + if self.mir.local_decls[local].is_user_variable.is_none() => + { + if self.mir.local_decls[local].ty.is_mutable_pointer() { + // The variable will be marked as mutable by the borrow. + return; + } + // This is an edge case where we have a `move` closure + // inside a non-move closure, and the inner closure + // contains a mutation: + // + // let mut i = 0; + // || { move || { i += 1; }; }; + // + // In this case our usual strategy of assuming that the + // variable will be captured by mutable reference is + // wrong, since `i` can be copied into the inner + // closure from a shared reference. + // + // As such we have to search for the local that this + // capture comes from and mark it as being used as mut. + + let temp_mpi = self.move_data.rev_lookup.find_local(local); + let init = if let [init_index] = *self.move_data.init_path_map[temp_mpi] { + &self.move_data.inits[init_index] + } else { + bug!("temporary should be initialized exactly once") + }; + + let loc = match init.location { + InitLocation::Statement(stmt) => stmt, + _ => bug!("temporary initialized in arguments"), + }; + + let bbd = &self.mir[loc.block]; + let stmt = &bbd.statements[loc.statement_index]; + debug!("temporary assigned in: stmt={:?}", stmt); + + if let StatementKind::Assign(_, box Rvalue::Ref(_, _, ref source)) = stmt.kind { + propagate_closure_used_mut_place(self, source); + } else { + bug!("closures should only capture user variables \ + or references to user variables"); + } + } + Operand::Move(ref place) + | Operand::Copy(ref place) => { + propagate_closure_used_mut_place(self, place); + } + Operand::Constant(..) => {} + } + } + fn consume_operand( &mut self, context: Context, diff --git a/src/test/ui/nll/extra-unused-mut.rs b/src/test/ui/nll/extra-unused-mut.rs index d5f0b0ddf18bf..6d0d6e16a6775 100644 --- a/src/test/ui/nll/extra-unused-mut.rs +++ b/src/test/ui/nll/extra-unused-mut.rs @@ -1,6 +1,6 @@ // extra unused mut lint tests for #51918 -// run-pass +// compile-pass #![feature(generators, nll)] #![deny(unused_mut)] @@ -53,11 +53,14 @@ fn if_guard(x: Result) { } } -fn main() { - ref_argument(0); - mutable_upvar(); - generator_mutable_upvar(); - ref_closure_argument(); - parse_dot_or_call_expr_with(Vec::new()); - if_guard(Ok(0)); +// #59620 +fn nested_closures() { + let mut i = 0; + [].iter().for_each(|_: &i32| { + [].iter().for_each(move |_: &i32| { + i += 1; + }); + }); } + +fn main() {} From 63080b3c25046b29cbbaef8d587c7da91a302fce Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 5 Apr 2019 22:42:40 +0300 Subject: [PATCH 02/28] remove lookup_char_pos_adj It is now exactly equivalent to lookup_char_pos. --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/mir/interpret/error.rs | 4 ++-- src/libsyntax/diagnostics/metadata.rs | 4 ++-- src/libsyntax/source_map.rs | 16 +++------------- src/libsyntax_pos/lib.rs | 13 +------------ 5 files changed, 9 insertions(+), 30 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 19663161fe3fa..8cfcc466b4019 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -278,7 +278,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } fn explain_span(self, heading: &str, span: Span) -> (String, Option) { - let lo = self.sess.source_map().lookup_char_pos_adj(span.lo()); + let lo = self.sess.source_map().lookup_char_pos(span.lo()); ( format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1), Some(span), diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 280e75476b72a..b9c4d312adb7b 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -65,8 +65,8 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> { write!(f, "inside call to `{}`", self.instance)?; } if !self.call_site.is_dummy() { - let lo = tcx.sess.source_map().lookup_char_pos_adj(self.call_site.lo()); - write!(f, " at {}:{}:{}", lo.filename, lo.line, lo.col.to_usize() + 1)?; + let lo = tcx.sess.source_map().lookup_char_pos(self.call_site.lo()); + write!(f, " at {}:{}:{}", lo.file.name, lo.line, lo.col.to_usize() + 1)?; } Ok(()) }) diff --git a/src/libsyntax/diagnostics/metadata.rs b/src/libsyntax/diagnostics/metadata.rs index 704135fe1d589..53f37bb10bdc0 100644 --- a/src/libsyntax/diagnostics/metadata.rs +++ b/src/libsyntax/diagnostics/metadata.rs @@ -36,9 +36,9 @@ pub struct ErrorLocation { impl ErrorLocation { /// Creates an error location from a span. pub fn from_span(ecx: &ExtCtxt<'_>, sp: Span) -> ErrorLocation { - let loc = ecx.source_map().lookup_char_pos_adj(sp.lo()); + let loc = ecx.source_map().lookup_char_pos(sp.lo()); ErrorLocation { - filename: loc.filename, + filename: loc.file.name.clone(), line: loc.line } } diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 62a6972122abd..08abbf5e8a4dc 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -388,16 +388,6 @@ impl SourceMap { } } - pub fn lookup_char_pos_adj(&self, pos: BytePos) -> LocWithOpt { - let loc = self.lookup_char_pos(pos); - LocWithOpt { - filename: loc.file.name.clone(), - line: loc.line, - col: loc.col, - file: Some(loc.file) - } - } - /// Returns `Some(span)`, a union of the lhs and rhs span. The lhs must precede the rhs. If /// there are gaps between lhs and rhs, the resulting union will cross these gaps. /// For this to work, the spans have to be: @@ -438,10 +428,10 @@ impl SourceMap { return "no-location".to_string(); } - let lo = self.lookup_char_pos_adj(sp.lo()); - let hi = self.lookup_char_pos_adj(sp.hi()); + let lo = self.lookup_char_pos(sp.lo()); + let hi = self.lookup_char_pos(sp.hi()); format!("{}:{}:{}: {}:{}", - lo.filename, + lo.file.name, lo.line, lo.col.to_usize() + 1, hi.line, diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index db1543ff13f7e..81cf804cf0b73 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -1295,7 +1295,7 @@ impl Sub for CharPos { } // _____________________________________________________________________________ -// Loc, LocWithOpt, SourceFileAndLine, SourceFileAndBytePos +// Loc, SourceFileAndLine, SourceFileAndBytePos // /// A source code location used for error reporting. @@ -1311,17 +1311,6 @@ pub struct Loc { pub col_display: usize, } -/// A source code location used as the result of `lookup_char_pos_adj`. -// Actually, *none* of the clients use the filename *or* file field; -// perhaps they should just be removed. -#[derive(Debug)] -pub struct LocWithOpt { - pub filename: FileName, - pub line: usize, - pub col: CharPos, - pub file: Option>, -} - // Used to be structural records. #[derive(Debug)] pub struct SourceFileAndLine { pub sf: Lrc, pub line: usize } From 1c3979ca16df0c94be65c967ba6a82410e42db24 Mon Sep 17 00:00:00 2001 From: Bastian Gruber Date: Sat, 6 Apr 2019 11:57:02 +0200 Subject: [PATCH 03/28] Add book.toml to tools/unstable, add copy_book_toml to scipt --- .../unstable-book-gen/src}/book.toml | 1 + src/tools/unstable-book-gen/src/main.rs | 7 +++++++ 2 files changed, 8 insertions(+) rename src/{doc/unstable-book => tools/unstable-book-gen/src}/book.toml (57%) diff --git a/src/doc/unstable-book/book.toml b/src/tools/unstable-book-gen/src/book.toml similarity index 57% rename from src/doc/unstable-book/book.toml rename to src/tools/unstable-book-gen/src/book.toml index 5534340f0db16..5b2e19bd7aa78 100644 --- a/src/doc/unstable-book/book.toml +++ b/src/tools/unstable-book-gen/src/book.toml @@ -1,2 +1,3 @@ [book] title = "The Rust Unstable Book" +author = "The Rust Community" diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index 427014ce7fe55..ec8654adb41d7 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -116,6 +116,11 @@ fn copy_recursive(path: &Path, to: &Path) { } } +fn copy_book_toml(path: &Path) { + let mut file = t!(File::create(&path.join("book.toml"))); + t!(file.write_fmt(format_args!(include_str!("book.toml")); +} + fn main() { let src_path_str = env::args_os().skip(1).next().expect("source path required"); let dest_path_str = env::args_os().skip(2).next().expect("destination path required"); @@ -141,4 +146,6 @@ fn main() { copy_recursive(&doc_src_path, &dest_path); generate_summary(&dest_path, &lang_features, &lib_features); + + copy_book_toml(&dest_path); } From 5ddb339c9d34e96ebceb9bb40436c736d0f9fddd Mon Sep 17 00:00:00 2001 From: Bastian Gruber Date: Sat, 6 Apr 2019 12:00:43 +0200 Subject: [PATCH 04/28] Remove copy_book_toml method in favor for copy_recursive --- src/tools/unstable-book-gen/src/main.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index ec8654adb41d7..427014ce7fe55 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -116,11 +116,6 @@ fn copy_recursive(path: &Path, to: &Path) { } } -fn copy_book_toml(path: &Path) { - let mut file = t!(File::create(&path.join("book.toml"))); - t!(file.write_fmt(format_args!(include_str!("book.toml")); -} - fn main() { let src_path_str = env::args_os().skip(1).next().expect("source path required"); let dest_path_str = env::args_os().skip(2).next().expect("destination path required"); @@ -146,6 +141,4 @@ fn main() { copy_recursive(&doc_src_path, &dest_path); generate_summary(&dest_path, &lang_features, &lib_features); - - copy_book_toml(&dest_path); } From 280277a28b38d5f9a17f79fcb52b79486005bd64 Mon Sep 17 00:00:00 2001 From: Bastian Gruber Date: Sat, 6 Apr 2019 12:05:45 +0200 Subject: [PATCH 05/28] path -> from --- src/tools/unstable-book-gen/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index 427014ce7fe55..d65c427523a26 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -102,8 +102,8 @@ fn generate_unstable_book_files(src :&Path, out: &Path, features :&Features) { } } -fn copy_recursive(path: &Path, to: &Path) { - for entry in t!(fs::read_dir(path)) { +fn copy_recursive(from: &Path, to: &Path) { + for entry in t!(fs::read_dir(from)) { let e = t!(entry); let t = t!(e.metadata()); let dest = &to.join(e.file_name()); From 34c1572a42e7e148dc9bf21126b26f49fcaf1a56 Mon Sep 17 00:00:00 2001 From: Bastian Gruber Date: Sun, 7 Apr 2019 19:29:20 +0200 Subject: [PATCH 06/28] Change root path for unstable-book --- .../src => doc/unstable-book}/book.toml | 0 src/tools/tidy/src/unstable_book.rs | 8 ++++---- src/tools/unstable-book-gen/src/main.rs | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) rename src/{tools/unstable-book-gen/src => doc/unstable-book}/book.toml (100%) diff --git a/src/tools/unstable-book-gen/src/book.toml b/src/doc/unstable-book/book.toml similarity index 100% rename from src/tools/unstable-book-gen/src/book.toml rename to src/doc/unstable-book/book.toml diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index cd60f36b1d273..f7e40ce4bae36 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -3,13 +3,13 @@ use std::fs; use std::path; use crate::features::{collect_lang_features, collect_lib_features, Features, Status}; -pub const PATH_STR: &str = "doc/unstable-book/src"; +pub const PATH_STR: &str = "doc/unstable-book"; -pub const COMPILER_FLAGS_DIR: &str = "compiler-flags"; +pub const COMPILER_FLAGS_DIR: &str = "src/compiler-flags"; -pub const LANG_FEATURES_DIR: &str = "language-features"; +pub const LANG_FEATURES_DIR: &str = "src/language-features"; -pub const LIB_FEATURES_DIR: &str = "library-features"; +pub const LIB_FEATURES_DIR: &str = "src/library-features"; /// Builds the path to the Unstable Book source directory from the Rust 'src' directory. pub fn unstable_book_path(base_src_path: &path::Path) -> path::PathBuf { diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index d65c427523a26..e92d174a4e1d4 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -52,7 +52,7 @@ fn set_to_summary_str(set: &BTreeSet, dir: &str fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Features) { let compiler_flags = collect_unstable_book_section_file_names( - &path.join("compiler-flags")); + &path.join("src/compiler-flags")); let compiler_flags_str = set_to_summary_str(&compiler_flags, "compiler-flags"); @@ -61,11 +61,11 @@ fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Featur let unstable_lib_features = collect_unstable_feature_names(&lib_features); let lang_features_str = set_to_summary_str(&unstable_lang_features, - LANG_FEATURES_DIR); + "language-features"); let lib_features_str = set_to_summary_str(&unstable_lib_features, - LIB_FEATURES_DIR); + "library-features"); - let mut file = t!(File::create(&path.join("SUMMARY.md"))); + let mut file = t!(File::create(&path.join("src/SUMMARY.md"))); t!(file.write_fmt(format_args!(include_str!("SUMMARY.md"), compiler_flags = compiler_flags_str, language_features = lang_features_str, @@ -120,7 +120,7 @@ fn main() { let src_path_str = env::args_os().skip(1).next().expect("source path required"); let dest_path_str = env::args_os().skip(2).next().expect("destination path required"); let src_path = Path::new(&src_path_str); - let dest_path = Path::new(&dest_path_str).join("src"); + let dest_path = Path::new(&dest_path_str); let lang_features = collect_lang_features(src_path, &mut false); let lib_features = collect_lib_features(src_path).into_iter().filter(|&(ref name, _)| { From b8e9da7c0885f624d186499f7521bae71381a97c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 8 Apr 2019 10:32:35 +0200 Subject: [PATCH 07/28] `asm!` output can neither be promotable nor const --- src/librustc_mir/transform/promote_consts.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 43723aaf568da..9c792a35bb429 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -101,7 +101,6 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> { if *temp == TempState::Undefined { match context { PlaceContext::MutatingUse(MutatingUseContext::Store) | - PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) | PlaceContext::MutatingUse(MutatingUseContext::Call) => { *temp = TempState::Defined { location, From 6b018444081a6a2940889bec495acea923e365cf Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 8 Apr 2019 15:28:00 +0200 Subject: [PATCH 08/28] Generalize initial "not const" assignments --- src/librustc_mir/transform/promote_consts.rs | 15 ++++++---- src/librustc_mir/transform/qualify_consts.rs | 31 ++++++++------------ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 9c792a35bb429..ddf963c7fa9b5 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -44,8 +44,8 @@ pub enum TempState { impl TempState { pub fn is_promotable(&self) -> bool { debug!("is_promotable: self={:?}", self); - if let TempState::Defined { uses, .. } = *self { - uses > 0 + if let TempState::Defined { .. } = *self { + true } else { false } @@ -80,9 +80,14 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> { context: PlaceContext<'tcx>, location: Location) { debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location); - // We're only interested in temporaries - if self.mir.local_kind(index) != LocalKind::Temp { - return; + // We're only interested in temporaries and the return place + match self.mir.local_kind(index) { + | LocalKind::Temp + | LocalKind::ReturnPointer + => {}, + | LocalKind::Arg + | LocalKind::Var + => return, } // Ignore drops, if the temp gets promoted, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 1faa9ad0d0da4..6272425012b98 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -631,26 +631,21 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { }; for (local, decl) in mir.local_decls.iter_enumerated() { - match mir.local_kind(local) { - LocalKind::Arg => { - let qualifs = cx.qualifs_in_any_value_of_ty(decl.ty); - for (per_local, qualif) in &mut cx.per_local.as_mut().zip(qualifs).0 { - if *qualif { - per_local.insert(local); - } + if let LocalKind::Arg = mir.local_kind(local) { + let qualifs = cx.qualifs_in_any_value_of_ty(decl.ty); + for (per_local, qualif) in &mut cx.per_local.as_mut().zip(qualifs).0 { + if *qualif { + per_local.insert(local); } - cx.per_local[IsNotConst].insert(local); - } - - LocalKind::Var if mode == Mode::Fn => { - cx.per_local[IsNotConst].insert(local); - } - - LocalKind::Temp if !temps[local].is_promotable() => { - cx.per_local[IsNotConst].insert(local); } - - _ => {} + } + if !temps[local].is_promotable() { + cx.per_local[IsNotConst].insert(local); + } + if let LocalKind::Var = mir.local_kind(local) { + // Sanity check to prevent implicit and explicit promotion of + // named locals + assert!(cx.per_local[IsNotConst].contains(local)); } } From ec5206588fe31e631d8f8b1d27400f18744b448e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 8 Apr 2019 15:32:31 +0200 Subject: [PATCH 09/28] Explicit promotion is indistinguishable from explicit promotion Implicit promotion on the other hand has very strict rules on what may be done --- src/librustc_mir/transform/qualify_consts.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 6272425012b98..9095b78dd726a 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -508,13 +508,11 @@ impl Qualif for IsNotConst { } } -// Refers to temporaries which cannot be promoted as -// promote_consts decided they weren't simple enough. -// FIXME(oli-obk,eddyb): Remove this flag entirely and -// solely process this information via `IsNotConst`. -struct IsNotPromotable; +/// Refers to temporaries which cannot be promoted *implicitly*. +/// Explicit promotion e.g. for constant arguments declared via `rustc_args_required_const`. +struct IsNotImplicitlyPromotable; -impl Qualif for IsNotPromotable { +impl Qualif for IsNotImplicitlyPromotable { const IDX: usize = 3; fn in_call( @@ -550,7 +548,7 @@ macro_rules! static_assert_seq_qualifs { static_assert!(SEQ_QUALIFS: QUALIF_COUNT == $i); }; } -static_assert_seq_qualifs!(0 => HasMutInterior, NeedsDrop, IsNotConst, IsNotPromotable); +static_assert_seq_qualifs!(0 => HasMutInterior, NeedsDrop, IsNotConst, IsNotImplicitlyPromotable); impl ConstCx<'_, 'tcx> { fn qualifs_in_any_value_of_ty(&self, ty: Ty<'tcx>) -> PerQualif { @@ -558,7 +556,7 @@ impl ConstCx<'_, 'tcx> { qualifs[HasMutInterior] = HasMutInterior::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs[NeedsDrop] = NeedsDrop::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs[IsNotConst] = IsNotConst::in_any_value_of_ty(self, ty).unwrap_or(false); - qualifs[IsNotPromotable] = IsNotPromotable::in_any_value_of_ty(self, ty).unwrap_or(false); + qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs } @@ -567,7 +565,7 @@ impl ConstCx<'_, 'tcx> { qualifs[HasMutInterior] = HasMutInterior::in_local(self, local); qualifs[NeedsDrop] = NeedsDrop::in_local(self, local); qualifs[IsNotConst] = IsNotConst::in_local(self, local); - qualifs[IsNotPromotable] = IsNotPromotable::in_local(self, local); + qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_local(self, local); qualifs } @@ -576,7 +574,7 @@ impl ConstCx<'_, 'tcx> { qualifs[HasMutInterior] = HasMutInterior::in_value(self, source); qualifs[NeedsDrop] = NeedsDrop::in_value(self, source); qualifs[IsNotConst] = IsNotConst::in_value(self, source); - qualifs[IsNotPromotable] = IsNotPromotable::in_value(self, source); + qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_value(self, source); qualifs } } From d3d56732a7278881900ce6709892636bdc546862 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 8 Apr 2019 15:36:00 +0200 Subject: [PATCH 10/28] Get rid of "is not const" naming --- src/librustc_mir/transform/qualify_consts.rs | 32 ++++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 9095b78dd726a..8dd060d7a150d 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -365,11 +365,11 @@ impl Qualif for NeedsDrop { } } -// Not constant at all - non-`const fn` calls, asm!, +// Not promotable at all - non-`const fn` calls, asm!, // pointer comparisons, ptr-to-int casts, etc. -struct IsNotConst; +struct IsNotPromotable; -impl Qualif for IsNotConst { +impl Qualif for IsNotPromotable { const IDX: usize = 2; fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool { @@ -548,14 +548,14 @@ macro_rules! static_assert_seq_qualifs { static_assert!(SEQ_QUALIFS: QUALIF_COUNT == $i); }; } -static_assert_seq_qualifs!(0 => HasMutInterior, NeedsDrop, IsNotConst, IsNotImplicitlyPromotable); +static_assert_seq_qualifs!(0 => HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable); impl ConstCx<'_, 'tcx> { fn qualifs_in_any_value_of_ty(&self, ty: Ty<'tcx>) -> PerQualif { let mut qualifs = PerQualif::default(); qualifs[HasMutInterior] = HasMutInterior::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs[NeedsDrop] = NeedsDrop::in_any_value_of_ty(self, ty).unwrap_or(false); - qualifs[IsNotConst] = IsNotConst::in_any_value_of_ty(self, ty).unwrap_or(false); + qualifs[IsNotPromotable] = IsNotPromotable::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs } @@ -564,7 +564,7 @@ impl ConstCx<'_, 'tcx> { let mut qualifs = PerQualif::default(); qualifs[HasMutInterior] = HasMutInterior::in_local(self, local); qualifs[NeedsDrop] = NeedsDrop::in_local(self, local); - qualifs[IsNotConst] = IsNotConst::in_local(self, local); + qualifs[IsNotPromotable] = IsNotPromotable::in_local(self, local); qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_local(self, local); qualifs } @@ -573,7 +573,7 @@ impl ConstCx<'_, 'tcx> { let mut qualifs = PerQualif::default(); qualifs[HasMutInterior] = HasMutInterior::in_value(self, source); qualifs[NeedsDrop] = NeedsDrop::in_value(self, source); - qualifs[IsNotConst] = IsNotConst::in_value(self, source); + qualifs[IsNotPromotable] = IsNotPromotable::in_value(self, source); qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_value(self, source); qualifs } @@ -638,12 +638,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { } } if !temps[local].is_promotable() { - cx.per_local[IsNotConst].insert(local); + cx.per_local[IsNotPromotable].insert(local); } if let LocalKind::Var = mir.local_kind(local) { // Sanity check to prevent implicit and explicit promotion of // named locals - assert!(cx.per_local[IsNotConst].contains(local)); + assert!(cx.per_local[IsNotPromotable].contains(local)); } } @@ -691,11 +691,11 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { // the borrowed place is disallowed from being borrowed, // due to either a mutable borrow (with some exceptions), // or an shared borrow of a value with interior mutability. - // Then `HasMutInterior` is replaced with `IsNotConst`, + // Then `HasMutInterior` is replaced with `IsNotPromotable`, // to avoid duplicate errors (e.g. from reborrowing). if qualifs[HasMutInterior] { qualifs[HasMutInterior] = false; - qualifs[IsNotConst] = true; + qualifs[IsNotPromotable] = true; if self.mode != Mode::Fn { if let BorrowKind::Mut { .. } = kind { @@ -810,7 +810,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { } } - // Ensure the `IsNotConst` qualification is preserved. + // Ensure the `IsNotPromotable` qualification is preserved. // NOTE(eddyb) this is actually unnecessary right now, as // we never replace the local's qualif, but we might in // the future, and so it serves to catch changes that unset @@ -818,7 +818,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { // be replaced with calling `insert` to re-set the bit). if kind == LocalKind::Temp { if !self.temp_promotion_state[index].is_promotable() { - assert!(self.cx.per_local[IsNotConst].contains(index)); + assert!(self.cx.per_local[IsNotPromotable].contains(index)); } } } @@ -904,7 +904,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { // Account for errors in consts by using the // conservative type qualification instead. - if qualifs[IsNotConst] { + if qualifs[IsNotPromotable] { qualifs = self.qualifs_in_any_value_of_ty(mir.return_ty()); } @@ -1319,7 +1319,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { // which happens even without the user requesting it. // We can error out with a hard error if the argument is not // constant here. - if !IsNotConst::in_operand(self, arg) { + if !IsNotPromotable::in_operand(self, arg) { debug!("visit_terminator_kind: candidate={:?}", candidate); self.promotion_candidates.push(candidate); } else { @@ -1437,7 +1437,7 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if mir.return_ty().references_error() { tcx.sess.delay_span_bug(mir.span, "mir_const_qualif: Mir had errors"); - return (1 << IsNotConst::IDX, Lrc::new(BitSet::new_empty(0))); + return (1 << IsNotPromotable::IDX, Lrc::new(BitSet::new_empty(0))); } Checker::new(tcx, def_id, mir, Mode::Const).check_const() From c63b9fff3f1e589d75db982e9839f9d52c5c57cc Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 8 Apr 2019 16:24:59 +0200 Subject: [PATCH 11/28] Pacify tidy --- src/librustc_mir/transform/qualify_consts.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 8dd060d7a150d..ae13e18ff03b0 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -548,7 +548,9 @@ macro_rules! static_assert_seq_qualifs { static_assert!(SEQ_QUALIFS: QUALIF_COUNT == $i); }; } -static_assert_seq_qualifs!(0 => HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable); +static_assert_seq_qualifs!( + 0 => HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable +); impl ConstCx<'_, 'tcx> { fn qualifs_in_any_value_of_ty(&self, ty: Ty<'tcx>) -> PerQualif { @@ -556,7 +558,8 @@ impl ConstCx<'_, 'tcx> { qualifs[HasMutInterior] = HasMutInterior::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs[NeedsDrop] = NeedsDrop::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs[IsNotPromotable] = IsNotPromotable::in_any_value_of_ty(self, ty).unwrap_or(false); - qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_any_value_of_ty(self, ty).unwrap_or(false); + qualifs[IsNotImplicitlyPromotable] = + IsNotImplicitlyPromotable::in_any_value_of_ty(self, ty).unwrap_or(false); qualifs } From ae4717d95010f2d75ba02c200ecd0ace7de0a93b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 8 Apr 2019 18:34:45 +0200 Subject: [PATCH 12/28] Elaborate on implicit promotability --- src/librustc_mir/transform/qualify_consts.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index ae13e18ff03b0..5f8e7ad796ba3 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -509,7 +509,10 @@ impl Qualif for IsNotPromotable { } /// Refers to temporaries which cannot be promoted *implicitly*. -/// Explicit promotion e.g. for constant arguments declared via `rustc_args_required_const`. +/// Explicit promotion e.g. for constant arguments declared via `rustc_args_required_const` or by +/// happening inside a constant, static or const fn. Inside a const context all constness rules +/// apply, so implicit promotion simply has to follow the regular constant rules (modulo interior +/// mutability or `Drop` rules which are handled `HasMutInterior` and `NeedsDrop` respectively) struct IsNotImplicitlyPromotable; impl Qualif for IsNotImplicitlyPromotable { From 03727a4f257fc86b467457a1e87d06d56e62d5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 8 Apr 2019 20:44:31 +0200 Subject: [PATCH 13/28] Clean up jobserver integration --- src/librustc_data_structures/Cargo.toml | 2 +- src/librustc_data_structures/jobserver.rs | 128 ++-------------------- 2 files changed, 8 insertions(+), 122 deletions(-) diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 63e44d82a28c3..d586b376d45b6 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["dylib"] [dependencies] ena = "0.13" log = "0.4" -jobserver_crate = { version = "0.1", package = "jobserver" } +jobserver_crate = { version = "0.1.13", package = "jobserver" } lazy_static = "1" rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } serialize = { path = "../libserialize" } diff --git a/src/librustc_data_structures/jobserver.rs b/src/librustc_data_structures/jobserver.rs index 48ac8125a0d66..b42ccb932b9dc 100644 --- a/src/librustc_data_structures/jobserver.rs +++ b/src/librustc_data_structures/jobserver.rs @@ -1,89 +1,5 @@ -use jobserver_crate::{Client, HelperThread, Acquired}; +use jobserver_crate::Client; use lazy_static::lazy_static; -use std::sync::{Condvar, Arc, Mutex}; -use std::mem; - -#[derive(Default)] -struct LockedProxyData { - /// The number of free thread tokens, this may include the implicit token given to the process - free: usize, - - /// The number of threads waiting for a token - waiters: usize, - - /// The number of tokens we requested from the server - requested: usize, - - /// Stored tokens which will be dropped when we no longer need them - tokens: Vec, -} - -impl LockedProxyData { - fn request_token(&mut self, thread: &Mutex) { - self.requested += 1; - thread.lock().unwrap().request_token(); - } - - fn release_token(&mut self, cond_var: &Condvar) { - if self.waiters > 0 { - self.free += 1; - cond_var.notify_one(); - } else { - if self.tokens.is_empty() { - // We are returning the implicit token - self.free += 1; - } else { - // Return a real token to the server - self.tokens.pop().unwrap(); - } - } - } - - fn take_token(&mut self, thread: &Mutex) -> bool { - if self.free > 0 { - self.free -= 1; - self.waiters -= 1; - - // We stole some token reqested by someone else - // Request another one - if self.requested + self.free < self.waiters { - self.request_token(thread); - } - - true - } else { - false - } - } - - fn new_requested_token(&mut self, token: Acquired, cond_var: &Condvar) { - self.requested -= 1; - - // Does anything need this token? - if self.waiters > 0 { - self.free += 1; - self.tokens.push(token); - cond_var.notify_one(); - } else { - // Otherwise we'll just drop it - mem::drop(token); - } - } -} - -#[derive(Default)] -struct ProxyData { - lock: Mutex, - cond_var: Condvar, -} - -/// A helper type which makes managing jobserver tokens easier. -/// It also allows you to treat the implicit token given to the process -/// in the same manner as requested tokens. -struct Proxy { - thread: Mutex, - data: Arc, -} lazy_static! { // We can only call `from_env` once per process @@ -105,20 +21,12 @@ lazy_static! { // per-process. static ref GLOBAL_CLIENT: Client = unsafe { Client::from_env().unwrap_or_else(|| { - Client::new(32).expect("failed to create jobserver") + let client = Client::new(32).expect("failed to create jobserver"); + // Acquire a token for the main thread which we can release later + client.acquire_raw().ok(); + client }) }; - - static ref GLOBAL_PROXY: Proxy = { - let data = Arc::new(ProxyData::default()); - - Proxy { - data: data.clone(), - thread: Mutex::new(client().into_helper_thread(move |token| { - data.lock.lock().unwrap().new_requested_token(token.unwrap(), &data.cond_var); - }).unwrap()), - } - }; } pub fn client() -> Client { @@ -126,31 +34,9 @@ pub fn client() -> Client { } pub fn acquire_thread() { - GLOBAL_PROXY.acquire_token(); + GLOBAL_CLIENT.acquire_raw().ok(); } pub fn release_thread() { - GLOBAL_PROXY.release_token(); -} - -impl Proxy { - fn release_token(&self) { - self.data.lock.lock().unwrap().release_token(&self.data.cond_var); - } - - fn acquire_token(&self) { - let mut data = self.data.lock.lock().unwrap(); - data.waiters += 1; - if data.take_token(&self.thread) { - return; - } - // Request a token for us - data.request_token(&self.thread); - loop { - data = self.data.cond_var.wait(data).unwrap(); - if data.take_token(&self.thread) { - return; - } - } - } + GLOBAL_CLIENT.release_raw().ok(); } From 1ad46cd1ede1c246802e5fc3d988d8c6aaa9ac46 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 9 Apr 2019 15:38:32 -0700 Subject: [PATCH 14/28] Fix links on keyword docs. - Make links relative. - Adjust links from old 2018-edition book. - Fix broken link in `let` docs. --- src/libstd/keyword_docs.rs | 55 +++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index 7b0d1549e061a..ffe50f11e8a50 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -25,8 +25,7 @@ /// /// For more information on what `as` is capable of, see the [Reference] /// -/// [Reference]: -/// https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions +/// [Reference]: ../reference/expressions/operator-expr.html#type-cast-expressions /// [`crate`]: keyword.crate.html mod as_keyword { } @@ -80,8 +79,8 @@ mod as_keyword { } /// /// [pointer]: primitive.pointer.html /// [Rust Book]: -/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants -/// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html +/// ../book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants +/// [Reference]: ../reference/items/constant-items.html mod const_keyword { } #[doc(keyword = "crate")] @@ -114,7 +113,7 @@ mod const_keyword { } /// } /// ``` /// -/// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html +/// [Reference]: ../reference/items/extern-crates.html mod crate_keyword { } #[doc(keyword = "enum")] @@ -169,8 +168,8 @@ mod crate_keyword { } /// /// [Algebraic Data Types]: https://en.wikipedia.org/wiki/Algebraic_data_type /// [`Option`]: option/enum.Option.html -/// [Rust Book]: https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html -/// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html +/// [Rust Book]: ../book/ch06-01-defining-an-enum.html +/// [Reference]: ../reference/items/enumerations.html mod enum_keyword { } #[doc(keyword = "extern")] @@ -211,8 +210,8 @@ mod enum_keyword { } /// For more information on FFI, check the [Rust book] or the [Reference]. /// /// [Rust book]: -/// https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code -/// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html +/// ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code +/// [Reference]: ../reference/items/external-blocks.html mod extern_keyword { } #[doc(keyword = "fn")] @@ -278,8 +277,8 @@ mod extern_keyword { } /// /// [`impl`]: keyword.impl.html /// [`extern`]: keyword.extern.html -/// [Rust book]: https://doc.rust-lang.org/book/ch03-03-how-functions-work.html -/// [Reference]: https://doc.rust-lang.org/reference/items/functions.html +/// [Rust book]: ../book/ch03-03-how-functions-work.html +/// [Reference]: ../reference/items/functions.html mod fn_keyword { } #[doc(keyword = "for")] @@ -352,12 +351,11 @@ mod fn_keyword { } /// For more information on for-loops, see the [Rust book] or the [Reference]. /// /// [`impl`]: keyword.impl.html -/// [higher-ranked trait bounds]: -/// https://doc.rust-lang.org/nightly/reference/trait-bounds.html#higher-ranked-trait-bounds +/// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds /// [`IntoIterator`]: iter/trait.IntoIterator.html /// [Rust book]: -/// https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for -/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops +/// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for +/// [Reference]: ../reference/expressions/loop-expr.html#iterator-loops mod for_keyword { } #[doc(keyword = "if")] @@ -430,9 +428,8 @@ mod for_keyword { } /// /// For more information on `if` expressions, see the [Rust book] or the [Reference]. /// -/// [Rust book]: -/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions -/// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html +/// [Rust book]: ../book/ch03-05-control-flow.html#if-expressions +/// [Reference]: ../reference/expressions/if-expr.html mod if_keyword { } #[doc(keyword = "impl")] @@ -493,10 +490,9 @@ mod if_keyword { } /// /// For more information on `impl Trait` syntax, see the [Rust book][book2]. /// -/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch05-03-method-syntax.html -/// [Reference]: https://doc.rust-lang.org/reference/items/implementations.html -/// [book2]: -/// https://doc.rust-lang.org/stable/book/2018-edition/ch10-02-traits.html#returning-traits +/// [book1]: ../book/ch05-03-method-syntax.html +/// [Reference]: ../reference/items/implementations.html +/// [book2]: ../book/ch10-02-traits.html#returning-types-that-implement-traits mod impl_keyword { } #[doc(keyword = "let")] @@ -554,13 +550,12 @@ mod impl_keyword { } /// enumerations. `while let` also exists, which runs a loop with a pattern matched value until /// that pattern can't be matched. /// -/// For more information on the `let` keyword, see the [Rust book] or the [Reference] +/// For more information on the `let` keyword, see the [Rust book][book2] or the [Reference] /// -/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch06-02-match.html +/// [book1]: ../book/ch06-02-match.html /// [`if`]: keyword.if.html -/// [book2]: -/// https://doc.rust-lang.org/stable/book/2018-edition/ch18-01-all-the-places-for-patterns.html#let-statements -/// [Reference]: https://doc.rust-lang.org/reference/statements.html#let-statements +/// [book2]: ../book/ch18-01-all-the-places-for-patterns.html#let-statements +/// [Reference]: ../reference/statements.html#let-statements mod let_keyword { } #[doc(keyword = "loop")] @@ -605,7 +600,7 @@ mod let_keyword { } /// /// For more information on `loop` and loops in general, see the [Reference]. /// -/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html +/// [Reference]: ../reference/expressions/loop-expr.html mod loop_keyword { } #[doc(keyword = "struct")] @@ -712,6 +707,6 @@ mod loop_keyword { } /// [Reference][reference]. /// /// [`PhantomData`]: marker/struct.PhantomData.html -/// [book]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html -/// [reference]: https://doc.rust-lang.org/reference/items/structs.html +/// [book]: ../book/ch05-01-defining-structs.html +/// [reference]: ../reference/items/structs.html mod struct_keyword { } From 6635fbed4ca8c65822f99e994735bd1877fb063e Mon Sep 17 00:00:00 2001 From: CrLF0710 Date: Wed, 10 Apr 2019 00:46:28 +0800 Subject: [PATCH 15/28] Eliminate `FnBox` usages from libstd. --- src/libstd/sys/cloudabi/thread.rs | 3 +-- src/libstd/sys/redox/thread.rs | 3 +-- src/libstd/sys/sgx/thread.rs | 8 +++----- src/libstd/sys/unix/thread.rs | 3 +-- src/libstd/sys/wasi/thread.rs | 3 +-- src/libstd/sys/wasm/thread.rs | 3 +-- src/libstd/sys/windows/thread.rs | 3 +-- src/libstd/sys_common/at_exit_imp.rs | 5 ++--- src/libstd/sys_common/thread.rs | 3 +-- src/libstd/thread/mod.rs | 5 +++-- 10 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs index f853346e0e63c..7da16c4d247aa 100644 --- a/src/libstd/sys/cloudabi/thread.rs +++ b/src/libstd/sys/cloudabi/thread.rs @@ -1,4 +1,3 @@ -use crate::boxed::FnBox; use crate::cmp; use crate::ffi::CStr; use crate::io; @@ -22,7 +21,7 @@ unsafe impl Sync for Thread {} impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(stack: usize, p: Box) -> io::Result { + pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = box p; let mut native: libc::pthread_t = mem::zeroed(); let mut attr: libc::pthread_attr_t = mem::zeroed(); diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs index ae0b91b4d6c7d..9d40a7e8bb8b3 100644 --- a/src/libstd/sys/redox/thread.rs +++ b/src/libstd/sys/redox/thread.rs @@ -1,4 +1,3 @@ -use crate::boxed::FnBox; use crate::ffi::CStr; use crate::io; use crate::mem; @@ -19,7 +18,7 @@ unsafe impl Sync for Thread {} impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(_stack: usize, p: Box) -> io::Result { + pub unsafe fn new(_stack: usize, p: Box) -> io::Result { let p = box p; let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?; diff --git a/src/libstd/sys/sgx/thread.rs b/src/libstd/sys/sgx/thread.rs index 565a523ebe06f..b9f42d4ad1c59 100644 --- a/src/libstd/sys/sgx/thread.rs +++ b/src/libstd/sys/sgx/thread.rs @@ -1,5 +1,4 @@ #![cfg_attr(test, allow(dead_code))] // why is this necessary? -use crate::boxed::FnBox; use crate::ffi::CStr; use crate::io; use crate::time::Duration; @@ -13,17 +12,16 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; mod task_queue { use crate::sync::{Mutex, MutexGuard, Once}; use crate::sync::mpsc; - use crate::boxed::FnBox; pub type JoinHandle = mpsc::Receiver<()>; pub(super) struct Task { - p: Box, + p: Box, done: mpsc::Sender<()>, } impl Task { - pub(super) fn new(p: Box) -> (Task, JoinHandle) { + pub(super) fn new(p: Box) -> (Task, JoinHandle) { let (done, recv) = mpsc::channel(); (Task { p, done }, recv) } @@ -51,7 +49,7 @@ mod task_queue { impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(_stack: usize, p: Box) + pub unsafe fn new(_stack: usize, p: Box) -> io::Result { let mut queue_lock = task_queue::lock(); diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index feb15e8f585ab..f7d604ac4c8c1 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -1,4 +1,3 @@ -use crate::boxed::FnBox; use crate::cmp; use crate::ffi::CStr; use crate::io; @@ -39,7 +38,7 @@ unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t, impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(stack: usize, p: Box) + pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = box p; let mut native: libc::pthread_t = mem::zeroed(); diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 9d3c6ac59d186..5e69e4d948fee 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -1,4 +1,3 @@ -use crate::boxed::FnBox; use crate::cmp; use crate::ffi::CStr; use crate::io; @@ -13,7 +12,7 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(_stack: usize, _p: Box) + pub unsafe fn new(_stack: usize, _p: Box) -> io::Result { unsupported() diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index a65c413119f8c..1dc786cd5d7b6 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -1,4 +1,3 @@ -use crate::boxed::FnBox; use crate::ffi::CStr; use crate::io; use crate::sys::{unsupported, Void}; @@ -10,7 +9,7 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(_stack: usize, _p: Box) + pub unsafe fn new(_stack: usize, _p: Box) -> io::Result { unsupported() diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index 1b0a811f13b72..ebdf3612e0602 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -1,4 +1,3 @@ -use crate::boxed::FnBox; use crate::io; use crate::ffi::CStr; use crate::mem; @@ -20,7 +19,7 @@ pub struct Thread { impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(stack: usize, p: Box) + pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = box p; diff --git a/src/libstd/sys_common/at_exit_imp.rs b/src/libstd/sys_common/at_exit_imp.rs index 1181b86161199..cdb72ee872e04 100644 --- a/src/libstd/sys_common/at_exit_imp.rs +++ b/src/libstd/sys_common/at_exit_imp.rs @@ -2,12 +2,11 @@ //! //! Documentation can be found on the `rt::at_exit` function. -use crate::boxed::FnBox; use crate::ptr; use crate::mem; use crate::sys_common::mutex::Mutex; -type Queue = Vec>; +type Queue = Vec>; // NB these are specifically not types from `std::sync` as they currently rely // on poisoning and this module needs to operate at a lower level than requiring @@ -61,7 +60,7 @@ pub fn cleanup() { } } -pub fn push(f: Box) -> bool { +pub fn push(f: Box) -> bool { unsafe { let _guard = LOCK.lock(); if init() { diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs index b2142e753085a..6ab0d5cbe9c96 100644 --- a/src/libstd/sys_common/thread.rs +++ b/src/libstd/sys_common/thread.rs @@ -1,4 +1,3 @@ -use crate::boxed::FnBox; use crate::env; use crate::sync::atomic::{self, Ordering}; use crate::sys::stack_overflow; @@ -11,7 +10,7 @@ pub unsafe fn start_thread(main: *mut u8) { let _handler = stack_overflow::Handler::new(); // Finally, let's run some code. - Box::from_raw(main as *mut Box)() + Box::from_raw(main as *mut Box)() } pub fn min_stack() -> usize { diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index cb507971091a4..c59226e0c0b98 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -157,7 +157,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::any::Any; -use crate::boxed::FnBox; use crate::cell::UnsafeCell; use crate::ffi::{CStr, CString}; use crate::fmt; @@ -488,7 +487,9 @@ impl Builder { // returning. native: Some(imp::Thread::new( stack_size, - mem::transmute::, Box>(Box::new(main)) + mem::transmute::, Box>(Box::new( + main, + )), )?), thread: my_thread, packet: Packet(my_packet), From 2f975529a04766c0a7624672f0a02fc1b7b44118 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 10 Apr 2019 03:21:11 +0000 Subject: [PATCH 16/28] Re-export NonZero signed variant in std --- src/libstd/num.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/num.rs b/src/libstd/num.rs index 828d5720eec1e..d67d0b55a799d 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -13,6 +13,8 @@ pub use core::num::Wrapping; #[stable(feature = "nonzero", since = "1.28.0")] pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize}; +#[stable(feature = "signed_nonzero", since = "1.34.0")] +pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize}; #[cfg(test)] use crate::fmt; #[cfg(test)] use crate::ops::{Add, Sub, Mul, Div, Rem}; From 404df312d304c4abeb583d55223ac6c2f1a768ae Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 10 Apr 2019 06:33:43 +0000 Subject: [PATCH 17/28] Update ui test --- src/test/ui/try-block/try-block-bad-type.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr index 6687bd9d9e1ff..07e7149793c14 100644 --- a/src/test/ui/try-block/try-block-bad-type.stderr +++ b/src/test/ui/try-block/try-block-bad-type.stderr @@ -6,9 +6,9 @@ LL | Err("")?; | = help: the following implementations were found: > - > > > + > and 2 others = note: required by `std::convert::From::from` From f10394ae0c5f2f73d1eba688c2cf5832eb38bc96 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 10 Apr 2019 11:21:19 +0200 Subject: [PATCH 18/28] Documentation should have proper grammar --- src/librustc_mir/transform/qualify_consts.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 5f8e7ad796ba3..3154f8e89e394 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -509,10 +509,13 @@ impl Qualif for IsNotPromotable { } /// Refers to temporaries which cannot be promoted *implicitly*. -/// Explicit promotion e.g. for constant arguments declared via `rustc_args_required_const` or by -/// happening inside a constant, static or const fn. Inside a const context all constness rules +/// Explicit promotion happens e.g. for constant arguments declared via `rustc_args_required_const`. +/// Inside a const context all constness rules /// apply, so implicit promotion simply has to follow the regular constant rules (modulo interior -/// mutability or `Drop` rules which are handled `HasMutInterior` and `NeedsDrop` respectively) +/// mutability or `Drop` rules which are handled `HasMutInterior` and `NeedsDrop` respectively). +/// Implicit promotion inside regular functions does not happen if `const fn` calls are involved, +/// as the call may be perfectly alright at runtime, but fail at compile time e.g. due to addresses +/// being compared inside the function. struct IsNotImplicitlyPromotable; impl Qualif for IsNotImplicitlyPromotable { From acf3ddb5ad163ea98f8935b045fc6d15faefa454 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 10 Apr 2019 12:51:25 -0700 Subject: [PATCH 19/28] std: Add `{read,write}_vectored` for more types This commit implements the `{read,write}_vectored` methods on more types in the standard library, namely: * `std::fs::File` * `std::process::ChildStd{in,out,err}` * `std::io::Std{in,out,err}` * `std::io::Std{in,out,err}Lock` * `std::io::Std{in,out,err}Raw` Where supported the OS implementations hook up to native support, otherwise it falls back to the already-defaulted implementation. --- src/libstd/fs.rs | 20 ++++++++++- src/libstd/io/stdio.rs | 51 ++++++++++++++++++++++++++- src/libstd/process.rs | 16 ++++++++- src/libstd/sys/cloudabi/shims/fs.rs | 10 +++++- src/libstd/sys/cloudabi/shims/pipe.rs | 10 +++++- src/libstd/sys/redox/fs.rs | 10 +++++- src/libstd/sys/redox/pipe.rs | 10 +++++- src/libstd/sys/sgx/fs.rs | 10 +++++- src/libstd/sys/sgx/pipe.rs | 15 +++++--- src/libstd/sys/unix/fs.rs | 10 +++++- src/libstd/sys/unix/pipe.rs | 10 +++++- src/libstd/sys/unix/stdio.rs | 30 +++++++++------- src/libstd/sys/wasi/pipe.rs | 10 +++++- src/libstd/sys/wasi/stdio.rs | 18 ++++++++-- src/libstd/sys/wasm/fs.rs | 10 +++++- src/libstd/sys/wasm/pipe.rs | 10 +++++- src/libstd/sys/windows/fs.rs | 10 +++++- src/libstd/sys/windows/handle.rs | 14 +++++++- src/libstd/sys/windows/pipe.rs | 10 +++++- 19 files changed, 247 insertions(+), 37 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 14ff4d72f8795..dea198d8c9178 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -9,7 +9,7 @@ use crate::fmt; use crate::ffi::OsString; -use crate::io::{self, SeekFrom, Seek, Read, Initializer, Write}; +use crate::io::{self, SeekFrom, Seek, Read, Initializer, Write, IoVec, IoVecMut}; use crate::path::{Path, PathBuf}; use crate::sys::fs as fs_imp; use crate::sys_common::{AsInnerMut, FromInner, AsInner, IntoInner}; @@ -615,6 +615,10 @@ impl Read for File { self.inner.read(buf) } + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.inner.read_vectored(bufs) + } + #[inline] unsafe fn initializer(&self) -> Initializer { Initializer::nop() @@ -625,6 +629,11 @@ impl Write for File { fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.write(buf) } + + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.inner.write_vectored(bufs) + } + fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } #[stable(feature = "rust1", since = "1.0.0")] @@ -639,6 +648,10 @@ impl Read for &File { self.inner.read(buf) } + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.inner.read_vectored(bufs) + } + #[inline] unsafe fn initializer(&self) -> Initializer { Initializer::nop() @@ -649,6 +662,11 @@ impl Write for &File { fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.write(buf) } + + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.inner.write_vectored(bufs) + } + fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 0bbff5769ab82..1848ddeab6556 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -5,7 +5,7 @@ use crate::io::prelude::*; use crate::cell::RefCell; use crate::fmt; use crate::io::lazy::Lazy; -use crate::io::{self, Initializer, BufReader, LineWriter}; +use crate::io::{self, Initializer, BufReader, LineWriter, IoVec, IoVecMut}; use crate::sync::{Arc, Mutex, MutexGuard}; use crate::sys::stdio; use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard}; @@ -75,6 +75,10 @@ fn stderr_raw() -> io::Result { stdio::Stderr::new().map(StderrRaw) } impl Read for StdinRaw { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.0.read(buf) } + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + #[inline] unsafe fn initializer(&self) -> Initializer { Initializer::nop() @@ -82,10 +86,20 @@ impl Read for StdinRaw { } impl Write for StdoutRaw { fn write(&mut self, buf: &[u8]) -> io::Result { self.0.write(buf) } + + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + fn flush(&mut self) -> io::Result<()> { self.0.flush() } } impl Write for StderrRaw { fn write(&mut self, buf: &[u8]) -> io::Result { self.0.write(buf) } + + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + fn flush(&mut self) -> io::Result<()> { self.0.flush() } } @@ -102,6 +116,14 @@ impl io::Write for Maybe { } } + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + let total = bufs.iter().map(|b| b.len()).sum(); + match self { + Maybe::Real(w) => handle_ebadf(w.write_vectored(bufs), total), + Maybe::Fake => Ok(total), + } + } + fn flush(&mut self) -> io::Result<()> { match *self { Maybe::Real(ref mut w) => handle_ebadf(w.flush(), ()), @@ -117,6 +139,13 @@ impl io::Read for Maybe { Maybe::Fake => Ok(0) } } + + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + match self { + Maybe::Real(r) => handle_ebadf(r.read_vectored(bufs), 0), + Maybe::Fake => Ok(0) + } + } } fn handle_ebadf(r: io::Result, default: T) -> io::Result { @@ -305,6 +334,9 @@ impl Read for Stdin { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.lock().read(buf) } + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.lock().read_vectored(bufs) + } #[inline] unsafe fn initializer(&self) -> Initializer { Initializer::nop() @@ -325,6 +357,11 @@ impl Read for StdinLock<'_> { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.inner.read(buf) } + + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.inner.read_vectored(bufs) + } + #[inline] unsafe fn initializer(&self) -> Initializer { Initializer::nop() @@ -483,6 +520,9 @@ impl Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result { self.lock().write(buf) } + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.lock().write_vectored(bufs) + } fn flush(&mut self) -> io::Result<()> { self.lock().flush() } @@ -498,6 +538,9 @@ impl Write for StdoutLock<'_> { fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.borrow_mut().write(buf) } + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.inner.borrow_mut().write_vectored(bufs) + } fn flush(&mut self) -> io::Result<()> { self.inner.borrow_mut().flush() } @@ -636,6 +679,9 @@ impl Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result { self.lock().write(buf) } + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.lock().write_vectored(bufs) + } fn flush(&mut self) -> io::Result<()> { self.lock().flush() } @@ -651,6 +697,9 @@ impl Write for StderrLock<'_> { fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.borrow_mut().write(buf) } + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.inner.borrow_mut().write_vectored(bufs) + } fn flush(&mut self) -> io::Result<()> { self.inner.borrow_mut().flush() } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index e0c9b7cad86ca..ef5626700e87a 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -111,7 +111,7 @@ use crate::io::prelude::*; use crate::ffi::OsStr; use crate::fmt; use crate::fs; -use crate::io::{self, Initializer}; +use crate::io::{self, Initializer, IoVec, IoVecMut}; use crate::path::Path; use crate::str; use crate::sys::pipe::{read2, AnonPipe}; @@ -225,6 +225,10 @@ impl Write for ChildStdin { self.inner.write(buf) } + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + self.inner.write_vectored(bufs) + } + fn flush(&mut self) -> io::Result<()> { Ok(()) } @@ -271,6 +275,11 @@ impl Read for ChildStdout { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.inner.read(buf) } + + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.inner.read_vectored(bufs) + } + #[inline] unsafe fn initializer(&self) -> Initializer { Initializer::nop() @@ -318,6 +327,11 @@ impl Read for ChildStderr { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.inner.read(buf) } + + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.inner.read_vectored(bufs) + } + #[inline] unsafe fn initializer(&self) -> Initializer { Initializer::nop() diff --git a/src/libstd/sys/cloudabi/shims/fs.rs b/src/libstd/sys/cloudabi/shims/fs.rs index ee045b8e51544..abd7f0fd3ee57 100644 --- a/src/libstd/sys/cloudabi/shims/fs.rs +++ b/src/libstd/sys/cloudabi/shims/fs.rs @@ -1,7 +1,7 @@ use crate::ffi::OsString; use crate::fmt; use crate::hash::{Hash, Hasher}; -use crate::io::{self, SeekFrom}; +use crate::io::{self, SeekFrom, IoVec, IoVecMut}; use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; use crate::sys::{unsupported, Void}; @@ -198,10 +198,18 @@ impl File { match self.0 {} } + pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result { + match self.0 {} + } + pub fn write(&self, _buf: &[u8]) -> io::Result { match self.0 {} } + pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result { + match self.0 {} + } + pub fn flush(&self) -> io::Result<()> { match self.0 {} } diff --git a/src/libstd/sys/cloudabi/shims/pipe.rs b/src/libstd/sys/cloudabi/shims/pipe.rs index f3debb9504742..804d3e001ac15 100644 --- a/src/libstd/sys/cloudabi/shims/pipe.rs +++ b/src/libstd/sys/cloudabi/shims/pipe.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::io::{self, IoVec, IoVecMut}; use crate::sys::Void; pub struct AnonPipe(Void); @@ -8,10 +8,18 @@ impl AnonPipe { match self.0 {} } + pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result { + match self.0 {} + } + pub fn write(&self, _buf: &[u8]) -> io::Result { match self.0 {} } + pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result { + match self.0 {} + } + pub fn diverge(&self) -> ! { match self.0 {} } diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs index ebefbc942103c..c86c6000eaead 100644 --- a/src/libstd/sys/redox/fs.rs +++ b/src/libstd/sys/redox/fs.rs @@ -2,7 +2,7 @@ use crate::os::unix::prelude::*; use crate::ffi::{OsString, OsStr}; use crate::fmt; -use crate::io::{self, Error, SeekFrom}; +use crate::io::{self, Error, SeekFrom, IoVec, IoVecMut}; use crate::path::{Path, PathBuf}; use crate::sync::Arc; use crate::sys::fd::FileDesc; @@ -278,10 +278,18 @@ impl File { self.0.read(buf) } + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + crate::io::default_read_vectored(|buf| self.read(buf), bufs) + } + pub fn write(&self, buf: &[u8]) -> io::Result { self.0.write(buf) } + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + crate::io::default_write_vectored(|buf| self.write(buf), bufs) + } + pub fn flush(&self) -> io::Result<()> { Ok(()) } pub fn seek(&self, pos: SeekFrom) -> io::Result { diff --git a/src/libstd/sys/redox/pipe.rs b/src/libstd/sys/redox/pipe.rs index 911ba9c3f6524..b926968f7b325 100644 --- a/src/libstd/sys/redox/pipe.rs +++ b/src/libstd/sys/redox/pipe.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::io::{self, IoVec, IoVecMut}; use crate::sys::{cvt, syscall}; use crate::sys::fd::FileDesc; @@ -24,10 +24,18 @@ impl AnonPipe { self.0.read(buf) } + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + crate::io::default_read_vectored(|buf| self.read(buf), bufs) + } + pub fn write(&self, buf: &[u8]) -> io::Result { self.0.write(buf) } + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + crate::io::default_write_vectored(|buf| self.write(buf), bufs) + } + pub fn fd(&self) -> &FileDesc { &self.0 } pub fn into_fd(self) -> FileDesc { self.0 } } diff --git a/src/libstd/sys/sgx/fs.rs b/src/libstd/sys/sgx/fs.rs index 68c8e9356a89a..c3c898eb23e56 100644 --- a/src/libstd/sys/sgx/fs.rs +++ b/src/libstd/sys/sgx/fs.rs @@ -1,7 +1,7 @@ use crate::ffi::OsString; use crate::fmt; use crate::hash::{Hash, Hasher}; -use crate::io::{self, SeekFrom}; +use crate::io::{self, SeekFrom, IoVec, IoVecMut}; use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; use crate::sys::{unsupported, Void}; @@ -200,10 +200,18 @@ impl File { match self.0 {} } + pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result { + match self.0 {} + } + pub fn write(&self, _buf: &[u8]) -> io::Result { match self.0 {} } + pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result { + match self.0 {} + } + pub fn flush(&self) -> io::Result<()> { match self.0 {} } diff --git a/src/libstd/sys/sgx/pipe.rs b/src/libstd/sys/sgx/pipe.rs index 2582b993b608e..804d3e001ac15 100644 --- a/src/libstd/sys/sgx/pipe.rs +++ b/src/libstd/sys/sgx/pipe.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::io::{self, IoVec, IoVecMut}; use crate::sys::Void; pub struct AnonPipe(Void); @@ -8,18 +8,23 @@ impl AnonPipe { match self.0 {} } + pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result { + match self.0 {} + } + pub fn write(&self, _buf: &[u8]) -> io::Result { match self.0 {} } + pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result { + match self.0 {} + } + pub fn diverge(&self) -> ! { match self.0 {} } } -pub fn read2(p1: AnonPipe, - _v1: &mut Vec, - _p2: AnonPipe, - _v2: &mut Vec) -> io::Result<()> { +pub fn read2(p1: AnonPipe, _v1: &mut Vec, _p2: AnonPipe, _v2: &mut Vec) -> io::Result<()> { match p1.0 {} } diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index dc3dcb5817c05..a14db108c3423 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -2,7 +2,7 @@ use crate::os::unix::prelude::*; use crate::ffi::{CString, CStr, OsString, OsStr}; use crate::fmt; -use crate::io::{self, Error, ErrorKind, SeekFrom}; +use crate::io::{self, Error, ErrorKind, SeekFrom, IoVec, IoVecMut}; use crate::mem; use crate::path::{Path, PathBuf}; use crate::ptr; @@ -560,6 +560,10 @@ impl File { self.0.read(buf) } + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { self.0.read_at(buf, offset) } @@ -568,6 +572,10 @@ impl File { self.0.write(buf) } + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { self.0.write_at(buf, offset) } diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index bc3c026adab8f..a7792d42af9ed 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::io::{self, IoVec, IoVecMut}; use crate::mem; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::fd::FileDesc; @@ -60,10 +60,18 @@ impl AnonPipe { self.0.read(buf) } + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + pub fn write(&self, buf: &[u8]) -> io::Result { self.0.write(buf) } + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + pub fn fd(&self) -> &FileDesc { &self.0 } pub fn into_fd(self) -> FileDesc { self.0 } } diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs index 35f163bbdb10f..bc2986f624e5c 100644 --- a/src/libstd/sys/unix/stdio.rs +++ b/src/libstd/sys/unix/stdio.rs @@ -1,5 +1,6 @@ -use crate::io; +use crate::io::{self, IoVec, IoVecMut}; use crate::sys::fd::FileDesc; +use crate::mem::ManuallyDrop; pub struct Stdin(()); pub struct Stdout(()); @@ -11,10 +12,11 @@ impl Stdin { impl io::Read for Stdin { fn read(&mut self, buf: &mut [u8]) -> io::Result { - let fd = FileDesc::new(libc::STDIN_FILENO); - let ret = fd.read(buf); - fd.into_raw(); // do not close this FD - ret + ManuallyDrop::new(FileDesc::new(libc::STDIN_FILENO)).read(buf) + } + + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + ManuallyDrop::new(FileDesc::new(libc::STDIN_FILENO)).read_vectored(bufs) } } @@ -24,10 +26,11 @@ impl Stdout { impl io::Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result { - let fd = FileDesc::new(libc::STDOUT_FILENO); - let ret = fd.write(buf); - fd.into_raw(); // do not close this FD - ret + ManuallyDrop::new(FileDesc::new(libc::STDOUT_FILENO)).write(buf) + } + + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + ManuallyDrop::new(FileDesc::new(libc::STDOUT_FILENO)).write_vectored(bufs) } fn flush(&mut self) -> io::Result<()> { @@ -41,10 +44,11 @@ impl Stderr { impl io::Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result { - let fd = FileDesc::new(libc::STDERR_FILENO); - let ret = fd.write(buf); - fd.into_raw(); // do not close this FD - ret + ManuallyDrop::new(FileDesc::new(libc::STDERR_FILENO)).write(buf) + } + + fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result { + ManuallyDrop::new(FileDesc::new(libc::STDERR_FILENO)).write_vectored(bufs) } fn flush(&mut self) -> io::Result<()> { diff --git a/src/libstd/sys/wasi/pipe.rs b/src/libstd/sys/wasi/pipe.rs index 2582b993b608e..aa6bf8076f649 100644 --- a/src/libstd/sys/wasi/pipe.rs +++ b/src/libstd/sys/wasi/pipe.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::io::{self, IoVec, IoVecMut}; use crate::sys::Void; pub struct AnonPipe(Void); @@ -8,10 +8,18 @@ impl AnonPipe { match self.0 {} } + pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result { + match self.0 {} + } + pub fn write(&self, _buf: &[u8]) -> io::Result { match self.0 {} } + pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result { + match self.0 {} + } + pub fn diverge(&self) -> ! { match self.0 {} } diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs index 192947886668f..bdad40848916e 100644 --- a/src/libstd/sys/wasi/stdio.rs +++ b/src/libstd/sys/wasi/stdio.rs @@ -13,8 +13,12 @@ impl Stdin { } pub fn read(&self, data: &mut [u8]) -> io::Result { + self.read_vectored(&mut [IoVecMut::new(data)]) + } + + pub fn read_vectored(&self, data: &mut [IoVecMut<'_>]) -> io::Result { ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) }) - .read(&mut [IoVecMut::new(data)]) + .read(data) } } @@ -24,8 +28,12 @@ impl Stdout { } pub fn write(&self, data: &[u8]) -> io::Result { + self.write_vectored(&[IoVec::new(data)]) + } + + pub fn write_vectored(&self, data: &[IoVec<'_>]) -> io::Result { ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDOUT_FILENO as u32) }) - .write(&[IoVec::new(data)]) + .write(data) } pub fn flush(&self) -> io::Result<()> { @@ -39,8 +47,12 @@ impl Stderr { } pub fn write(&self, data: &[u8]) -> io::Result { + self.write_vectored(&[IoVec::new(data)]) + } + + pub fn write_vectored(&self, data: &[IoVec<'_>]) -> io::Result { ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDERR_FILENO as u32) }) - .write(&[IoVec::new(data)]) + .write(data) } pub fn flush(&self) -> io::Result<()> { diff --git a/src/libstd/sys/wasm/fs.rs b/src/libstd/sys/wasm/fs.rs index 68c8e9356a89a..c3c898eb23e56 100644 --- a/src/libstd/sys/wasm/fs.rs +++ b/src/libstd/sys/wasm/fs.rs @@ -1,7 +1,7 @@ use crate::ffi::OsString; use crate::fmt; use crate::hash::{Hash, Hasher}; -use crate::io::{self, SeekFrom}; +use crate::io::{self, SeekFrom, IoVec, IoVecMut}; use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; use crate::sys::{unsupported, Void}; @@ -200,10 +200,18 @@ impl File { match self.0 {} } + pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result { + match self.0 {} + } + pub fn write(&self, _buf: &[u8]) -> io::Result { match self.0 {} } + pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result { + match self.0 {} + } + pub fn flush(&self) -> io::Result<()> { match self.0 {} } diff --git a/src/libstd/sys/wasm/pipe.rs b/src/libstd/sys/wasm/pipe.rs index 2582b993b608e..aa6bf8076f649 100644 --- a/src/libstd/sys/wasm/pipe.rs +++ b/src/libstd/sys/wasm/pipe.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::io::{self, IoVec, IoVecMut}; use crate::sys::Void; pub struct AnonPipe(Void); @@ -8,10 +8,18 @@ impl AnonPipe { match self.0 {} } + pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result { + match self.0 {} + } + pub fn write(&self, _buf: &[u8]) -> io::Result { match self.0 {} } + pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result { + match self.0 {} + } + pub fn diverge(&self) -> ! { match self.0 {} } diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 4ebbb0707f78a..1d8e47a4793ef 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -2,7 +2,7 @@ use crate::os::windows::prelude::*; use crate::ffi::OsString; use crate::fmt; -use crate::io::{self, Error, SeekFrom}; +use crate::io::{self, Error, SeekFrom, IoVec, IoVecMut}; use crate::mem; use crate::path::{Path, PathBuf}; use crate::ptr; @@ -314,6 +314,10 @@ impl File { self.handle.read(buf) } + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.handle.read_vectored(bufs) + } + pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { self.handle.read_at(buf, offset) } @@ -322,6 +326,10 @@ impl File { self.handle.write(buf) } + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + self.handle.write_vectored(bufs) + } + pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { self.handle.write_at(buf, offset) } diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs index 02549088c8704..c3fa6c4e0bd51 100644 --- a/src/libstd/sys/windows/handle.rs +++ b/src/libstd/sys/windows/handle.rs @@ -1,7 +1,7 @@ #![unstable(issue = "0", feature = "windows_handle")] use crate::cmp; -use crate::io::{self, ErrorKind, Read}; +use crate::io::{self, ErrorKind, Read, IoVec, IoVecMut}; use crate::mem; use crate::ops::Deref; use crate::ptr; @@ -89,6 +89,10 @@ impl RawHandle { } } + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + crate::io::default_read_vectored(|buf| self.read(buf), bufs) + } + pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { let mut read = 0; let len = cmp::min(buf.len(), ::max_value() as usize) as c::DWORD; @@ -169,6 +173,10 @@ impl RawHandle { Ok(amt as usize) } + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + crate::io::default_write_vectored(|buf| self.write(buf), bufs) + } + pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { let mut written = 0; let len = cmp::min(buf.len(), ::max_value() as usize) as c::DWORD; @@ -199,4 +207,8 @@ impl<'a> Read for &'a RawHandle { fn read(&mut self, buf: &mut [u8]) -> io::Result { (**self).read(buf) } + + fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + (**self).read_vectored(bufs) + } } diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index b38727830f37f..6613d3a056775 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -1,7 +1,7 @@ use crate::os::windows::prelude::*; use crate::ffi::OsStr; -use crate::io; +use crate::io::{self, IoVec, IoVecMut}; use crate::mem; use crate::path::Path; use crate::ptr; @@ -166,9 +166,17 @@ impl AnonPipe { self.inner.read(buf) } + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + self.inner.read_vectored(bufs) + } + pub fn write(&self, buf: &[u8]) -> io::Result { self.inner.write(buf) } + + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + self.inner.write_vectored(bufs) + } } pub fn read2(p1: AnonPipe, From 825a11ea3bb8a4b1a07d4e03a009b2ca4205c6a9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Apr 2019 22:31:42 +0200 Subject: [PATCH 20/28] Fix attributes position in type declaration --- src/librustdoc/html/render.rs | 9 +++------ src/librustdoc/html/static/rustdoc.css | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 866d8fe682a7b..bd134af55897e 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3117,7 +3117,6 @@ fn item_trait( // FIXME: we should be using a derived_id for the Anchors here write!(w, "{{\n")?; for t in &types { - write!(w, " ")?; render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?; write!(w, ";\n")?; } @@ -3125,7 +3124,6 @@ fn item_trait( w.write_str("\n")?; } for t in &consts { - write!(w, " ")?; render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?; write!(w, ";\n")?; } @@ -3133,7 +3131,6 @@ fn item_trait( w.write_str("\n")?; } for (pos, m) in required.iter().enumerate() { - write!(w, " ")?; render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?; write!(w, ";\n")?; @@ -3145,7 +3142,6 @@ fn item_trait( w.write_str("\n")?; } for (pos, m) in provided.iter().enumerate() { - write!(w, " ")?; render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?; match m.inner { clean::MethodItem(ref inner) if !inner.generics.where_predicates.is_empty() => { @@ -3454,8 +3450,9 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>, (0, true) }; render_attributes(w, meth)?; - write!(w, "{}{}{}{}{}{}fn {name}\ + write!(w, "{}{}{}{}{}{}{}fn {name}\ {generics}{decl}{where_clause}", + if parent == ItemType::Trait { " " } else { "" }, VisSpace(&meth.visibility), ConstnessSpace(header.constness), UnsafetySpace(header.unsafety), @@ -3755,7 +3752,7 @@ const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[ "non_exhaustive" ]; -fn render_attributes(w: &mut fmt::Formatter<'_>, it: &clean::Item) -> fmt::Result { +fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result { let mut attrs = String::new(); for attr in &it.attrs.other_attrs { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 5314255ac322b..2228e58b0d232 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1577,3 +1577,17 @@ div.name.expand::before { left: -15px; top: 2px; } + +/* This part is to fix the "Expand attributes" part in the type declaration. */ +.type-decl > pre > :first-child { + margin-left: 0 !important; +} +.type-decl > pre > :nth-child(2) { + margin-left: 1.8em !important; +} +.type-decl > pre > .toggle-attributes { + margin-left: 2.2em; +} +.type-decl > pre > .docblock.attributes { + margin-left: 4em; +} From d7f5c50a335204e00565c978f5eb7fac40468f96 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 28 Mar 2019 12:36:13 -0500 Subject: [PATCH 21/28] make duplicate matcher bindings a hard error --- src/librustc/lint/builtin.rs | 6 -- src/librustc/lint/mod.rs | 3 +- src/librustc_lint/lib.rs | 7 +-- src/libsyntax/early_buffered_lints.rs | 2 - src/libsyntax/ext/tt/macro_rules.rs | 16 ++---- .../macros/macro-multiple-matcher-bindings.rs | 12 ++-- .../macro-multiple-matcher-bindings.stderr | 57 +++++++++++-------- 7 files changed, 44 insertions(+), 59 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index cbdeda7b90206..bfb0b3e4a6b2d 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -352,12 +352,6 @@ declare_lint! { "outlives requirements can be inferred" } -declare_lint! { - pub DUPLICATE_MATCHER_BINDING_NAME, - Deny, - "duplicate macro matcher binding name" -} - /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`. pub mod parser { declare_lint! { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 5ebb915d57f54..112c247d4d663 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -26,7 +26,7 @@ use rustc_data_structures::sync::{self, Lrc}; use crate::hir::def_id::{CrateNum, LOCAL_CRATE}; use crate::hir::intravisit; use crate::hir; -use crate::lint::builtin::{BuiltinLintDiagnostics, DUPLICATE_MATCHER_BINDING_NAME}; +use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::builtin::parser::{QUESTION_MARK_MACRO_SEP, ILL_FORMED_ATTRIBUTE_INPUT}; use crate::session::{Session, DiagnosticMessageId}; use crate::ty::TyCtxt; @@ -82,7 +82,6 @@ impl Lint { match lint_id { BufferedEarlyLintId::QuestionMarkMacroSep => QUESTION_MARK_MACRO_SEP, BufferedEarlyLintId::IllFormedAttributeInput => ILL_FORMED_ATTRIBUTE_INPUT, - BufferedEarlyLintId::DuplicateMacroMatcherBindingName => DUPLICATE_MATCHER_BINDING_NAME, } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 07c505c6bde08..4a2d6dc68ae59 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -428,11 +428,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #57644 ", edition: None, }, - FutureIncompatibleInfo { - id: LintId::of(DUPLICATE_MATCHER_BINDING_NAME), - reference: "issue #57593 ", - edition: None, - }, FutureIncompatibleInfo { id: LintId::of(NESTED_IMPL_TRAIT), reference: "issue #59014 ", @@ -494,6 +489,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { "no longer a warning, #[no_mangle] statics always exported"); store.register_removed("bad_repr", "replaced with a generic attribute input check"); + store.register_removed("duplicate_matcher_binding_name", + "converted into hard error, see https://github.com/rust-lang/rust/issues/57742"); } pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) { diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs index 29cb9cd7f30b5..977e6d4587709 100644 --- a/src/libsyntax/early_buffered_lints.rs +++ b/src/libsyntax/early_buffered_lints.rs @@ -12,8 +12,6 @@ pub enum BufferedEarlyLintId { /// Usage of `?` as a macro separator is deprecated. QuestionMarkMacroSep, IllFormedAttributeInput, - /// Usage of a duplicate macro matcher binding name. - DuplicateMacroMatcherBindingName, } /// Stores buffered lint info which can later be passed to `librustc`. diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 12912044e4e3d..b1b9d25b3d56b 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -497,22 +497,14 @@ fn check_lhs_duplicate_matcher_bindings( node_id: ast::NodeId, ) -> bool { use self::quoted::TokenTree; - use crate::early_buffered_lints::BufferedEarlyLintId; for tt in tts { match *tt { TokenTree::MetaVarDecl(span, name, _kind) => { if let Some(&prev_span) = metavar_names.get(&name) { - // FIXME(mark-i-m): in a few cycles, make this a hard error. - // sess.span_diagnostic - // .struct_span_err(span, "duplicate matcher binding") - // .span_note(prev_span, "previous declaration was here") - // .emit(); - sess.buffer_lint( - BufferedEarlyLintId::DuplicateMacroMatcherBindingName, - crate::source_map::MultiSpan::from(vec![prev_span, span]), - node_id, - "duplicate matcher binding" - ); + sess.span_diagnostic + .struct_span_err(span, "duplicate matcher binding") + .span_note(prev_span, "previous declaration was here") + .emit(); return false; } else { metavar_names.insert(name, span); diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.rs b/src/test/ui/macros/macro-multiple-matcher-bindings.rs index 23d566780c855..f31af2365ff25 100644 --- a/src/test/ui/macros/macro-multiple-matcher-bindings.rs +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.rs @@ -1,16 +1,12 @@ // Test that duplicate matcher binding names are caught at declaration time, rather than at macro // invocation time. -// -// FIXME(mark-i-m): Update this when it becomes a hard error. - -// compile-pass #![allow(unused_macros)] #![warn(duplicate_matcher_binding_name)] macro_rules! foo1 { - ($a:ident, $a:ident) => {}; //~WARNING duplicate matcher binding - ($a:ident, $a:path) => {}; //~WARNING duplicate matcher binding + ($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding + ($a:ident, $a:path) => {}; //~ERROR duplicate matcher binding } macro_rules! foo2 { @@ -19,8 +15,8 @@ macro_rules! foo2 { } macro_rules! foo3 { - ($a:ident, $($a:ident),*) => {}; //~WARNING duplicate matcher binding - ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARNING duplicate matcher binding + ($a:ident, $($a:ident),*) => {}; //~ERROR duplicate matcher binding + ($($a:ident)+ # $($($a:path),+);*) => {}; //~ERROR duplicate matcher binding } fn main() {} diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.stderr b/src/test/ui/macros/macro-multiple-matcher-bindings.stderr index f7970dbd2eb22..65362388d7de1 100644 --- a/src/test/ui/macros/macro-multiple-matcher-bindings.stderr +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.stderr @@ -1,41 +1,50 @@ -warning: duplicate matcher binding - --> $DIR/macro-multiple-matcher-bindings.rs:12:6 +error: duplicate matcher binding + --> $DIR/macro-multiple-matcher-bindings.rs:7:16 | LL | ($a:ident, $a:ident) => {}; - | ^^^^^^^^ ^^^^^^^^ + | ^^^^^^^^ | -note: lint level defined here - --> $DIR/macro-multiple-matcher-bindings.rs:9:9 +note: previous declaration was here + --> $DIR/macro-multiple-matcher-bindings.rs:7:6 | -LL | #![warn(duplicate_matcher_binding_name)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57593 +LL | ($a:ident, $a:ident) => {}; + | ^^^^^^^^ -warning: duplicate matcher binding - --> $DIR/macro-multiple-matcher-bindings.rs:13:6 +error: duplicate matcher binding + --> $DIR/macro-multiple-matcher-bindings.rs:8:16 | LL | ($a:ident, $a:path) => {}; - | ^^^^^^^^ ^^^^^^^ + | ^^^^^^^ + | +note: previous declaration was here + --> $DIR/macro-multiple-matcher-bindings.rs:8:6 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57593 +LL | ($a:ident, $a:path) => {}; + | ^^^^^^^^ -warning: duplicate matcher binding - --> $DIR/macro-multiple-matcher-bindings.rs:22:6 +error: duplicate matcher binding + --> $DIR/macro-multiple-matcher-bindings.rs:17:18 | LL | ($a:ident, $($a:ident),*) => {}; - | ^^^^^^^^ ^^^^^^^^ + | ^^^^^^^^ + | +note: previous declaration was here + --> $DIR/macro-multiple-matcher-bindings.rs:17:6 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57593 +LL | ($a:ident, $($a:ident),*) => {}; + | ^^^^^^^^ -warning: duplicate matcher binding - --> $DIR/macro-multiple-matcher-bindings.rs:23:8 +error: duplicate matcher binding + --> $DIR/macro-multiple-matcher-bindings.rs:18:25 | LL | ($($a:ident)+ # $($($a:path),+);*) => {}; - | ^^^^^^^^ ^^^^^^^ + | ^^^^^^^ + | +note: previous declaration was here + --> $DIR/macro-multiple-matcher-bindings.rs:18:8 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57593 +LL | ($($a:ident)+ # $($($a:path),+);*) => {}; + | ^^^^^^^^ + +error: aborting due to 4 previous errors From 6fd3f5acaf2757ed3f3507a8a918e4071c5809a8 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 10 Apr 2019 21:32:46 -0500 Subject: [PATCH 22/28] forgot one --- src/librustc/lint/builtin.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index bfb0b3e4a6b2d..28a2a1eaf6b49 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -456,7 +456,6 @@ declare_lint_pass! { DEPRECATED_IN_FUTURE, AMBIGUOUS_ASSOCIATED_ITEMS, NESTED_IMPL_TRAIT, - DUPLICATE_MATCHER_BINDING_NAME, MUTABLE_BORROW_RESERVATION_CONFLICT, ] } From e149dc02a44f87d0dacba470db709b822b16db88 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 11 Apr 2019 15:09:43 -0500 Subject: [PATCH 23/28] remove warn --- src/test/ui/macros/macro-multiple-matcher-bindings.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.rs b/src/test/ui/macros/macro-multiple-matcher-bindings.rs index f31af2365ff25..7d39dc0a52f2e 100644 --- a/src/test/ui/macros/macro-multiple-matcher-bindings.rs +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.rs @@ -2,7 +2,6 @@ // invocation time. #![allow(unused_macros)] -#![warn(duplicate_matcher_binding_name)] macro_rules! foo1 { ($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding From ca1ab3ed30fc41308b0f14135b293f3d9d89e53f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 12 Apr 2019 12:18:23 +1000 Subject: [PATCH 24/28] In `-Zprint-type-size` output, sort enum variants by size. It's useful to see the biggest variants first. --- src/librustc/session/code_stats.rs | 8 +++++- .../ui/print_type_sizes/multiple_types.stdout | 4 +-- .../ui/print_type_sizes/niche-filling.stdout | 28 +++++++++---------- src/test/ui/print_type_sizes/padding.stdout | 10 +++---- .../ui/print_type_sizes/repr-align.stdout | 4 +-- src/test/ui/print_type_sizes/variants.stdout | 4 +-- 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/librustc/session/code_stats.rs b/src/librustc/session/code_stats.rs index 730abacf6f691..0f535249b5e2a 100644 --- a/src/librustc/session/code_stats.rs +++ b/src/librustc/session/code_stats.rs @@ -57,7 +57,13 @@ impl CodeStats { overall_size: Size, packed: bool, opt_discr_size: Option, - variants: Vec) { + mut variants: Vec) { + // Sort variants so the largest ones are shown first. A stable sort is + // used here so that source code order is preserved for all variants + // that have the same size. + variants.sort_by(|info1, info2| { + info2.size.cmp(&info1.size) + }); let info = TypeSizeInfo { kind, type_description: type_desc.to_string(), diff --git a/src/test/ui/print_type_sizes/multiple_types.stdout b/src/test/ui/print_type_sizes/multiple_types.stdout index eed9af26987b4..6411881545843 100644 --- a/src/test/ui/print_type_sizes/multiple_types.stdout +++ b/src/test/ui/print_type_sizes/multiple_types.stdout @@ -1,9 +1,9 @@ print-type-size type: `Enum`: 51 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes -print-type-size variant `Small`: 7 bytes -print-type-size field `.0`: 7 bytes print-type-size variant `Large`: 50 bytes print-type-size field `.0`: 50 bytes +print-type-size variant `Small`: 7 bytes +print-type-size field `.0`: 7 bytes print-type-size type: `FiftyBytes`: 50 bytes, alignment: 1 bytes print-type-size field `.0`: 50 bytes print-type-size type: `SevenBytes`: 7 bytes, alignment: 1 bytes diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout index 0789c6d7f3486..9cdb2ae4f57e0 100644 --- a/src/test/ui/print_type_sizes/niche-filling.stdout +++ b/src/test/ui/print_type_sizes/niche-filling.stdout @@ -4,15 +4,15 @@ print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size end padding: 1 bytes print-type-size type: `MyOption`: 12 bytes, alignment: 4 bytes -print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 12 bytes print-type-size field `.0`: 12 bytes -print-type-size type: `EmbeddedDiscr`: 8 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes +print-type-size type: `EmbeddedDiscr`: 8 bytes, alignment: 4 bytes print-type-size variant `Record`: 7 bytes print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes +print-type-size variant `None`: 0 bytes print-type-size end padding: 1 bytes print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes print-type-size field `.val`: 4 bytes @@ -20,59 +20,59 @@ print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size end padding: 1 bytes print-type-size type: `Enum4<(), char, (), ()>`: 4 bytes, alignment: 4 bytes -print-type-size variant `One`: 0 bytes -print-type-size field `.0`: 0 bytes print-type-size variant `Two`: 4 bytes print-type-size field `.0`: 4 bytes +print-type-size variant `One`: 0 bytes +print-type-size field `.0`: 0 bytes print-type-size variant `Three`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size variant `Four`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes -print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes -print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes +print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes print-type-size field `.0`: 4 bytes print-type-size type: `Enum4<(), (), (), MyOption>`: 2 bytes, alignment: 1 bytes +print-type-size variant `Four`: 2 bytes +print-type-size field `.0`: 2 bytes print-type-size variant `One`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size variant `Two`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size variant `Three`: 0 bytes print-type-size field `.0`: 0 bytes -print-type-size variant `Four`: 2 bytes -print-type-size field `.0`: 2 bytes print-type-size type: `MyOption>`: 2 bytes, alignment: 1 bytes -print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 2 bytes print-type-size field `.0`: 2 bytes +print-type-size variant `None`: 0 bytes print-type-size type: `MyOption`: 2 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes -print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 1 bytes print-type-size field `.0`: 1 bytes +print-type-size variant `None`: 0 bytes print-type-size type: `Enum4<(), (), bool, ()>`: 1 bytes, alignment: 1 bytes +print-type-size variant `Three`: 1 bytes +print-type-size field `.0`: 1 bytes print-type-size variant `One`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size variant `Two`: 0 bytes print-type-size field `.0`: 0 bytes -print-type-size variant `Three`: 1 bytes -print-type-size field `.0`: 1 bytes print-type-size variant `Four`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size type: `MyOption`: 1 bytes, alignment: 1 bytes -print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 1 bytes print-type-size field `.0`: 1 bytes -print-type-size type: `MyOption`: 1 bytes, alignment: 1 bytes print-type-size variant `None`: 0 bytes +print-type-size type: `MyOption`: 1 bytes, alignment: 1 bytes print-type-size variant `Some`: 1 bytes print-type-size field `.0`: 1 bytes +print-type-size variant `None`: 0 bytes print-type-size type: `std::cmp::Ordering`: 1 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Less`: 0 bytes diff --git a/src/test/ui/print_type_sizes/padding.stdout b/src/test/ui/print_type_sizes/padding.stdout index 0eaff7118b35c..9afdf76245df7 100644 --- a/src/test/ui/print_type_sizes/padding.stdout +++ b/src/test/ui/print_type_sizes/padding.stdout @@ -1,21 +1,21 @@ print-type-size type: `E1`: 12 bytes, alignment: 4 bytes print-type-size discriminant: 1 bytes +print-type-size variant `B`: 11 bytes +print-type-size padding: 3 bytes +print-type-size field `.0`: 8 bytes, alignment: 4 bytes print-type-size variant `A`: 7 bytes print-type-size field `.1`: 1 bytes print-type-size padding: 2 bytes print-type-size field `.0`: 4 bytes, alignment: 4 bytes +print-type-size type: `E2`: 12 bytes, alignment: 4 bytes +print-type-size discriminant: 1 bytes print-type-size variant `B`: 11 bytes print-type-size padding: 3 bytes print-type-size field `.0`: 8 bytes, alignment: 4 bytes -print-type-size type: `E2`: 12 bytes, alignment: 4 bytes -print-type-size discriminant: 1 bytes print-type-size variant `A`: 7 bytes print-type-size field `.0`: 1 bytes print-type-size padding: 2 bytes print-type-size field `.1`: 4 bytes, alignment: 4 bytes -print-type-size variant `B`: 11 bytes -print-type-size padding: 3 bytes -print-type-size field `.0`: 8 bytes, alignment: 4 bytes print-type-size type: `S`: 8 bytes, alignment: 4 bytes print-type-size field `.g`: 4 bytes print-type-size field `.a`: 1 bytes diff --git a/src/test/ui/print_type_sizes/repr-align.stdout b/src/test/ui/print_type_sizes/repr-align.stdout index 7df12f040b15d..33671bd8e14bc 100644 --- a/src/test/ui/print_type_sizes/repr-align.stdout +++ b/src/test/ui/print_type_sizes/repr-align.stdout @@ -1,10 +1,10 @@ print-type-size type: `E`: 32 bytes, alignment: 16 bytes print-type-size discriminant: 4 bytes -print-type-size variant `A`: 4 bytes -print-type-size field `.0`: 4 bytes print-type-size variant `B`: 28 bytes print-type-size padding: 12 bytes print-type-size field `.0`: 16 bytes, alignment: 16 bytes +print-type-size variant `A`: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `S`: 32 bytes, alignment: 16 bytes print-type-size field `.c`: 16 bytes print-type-size field `.a`: 4 bytes diff --git a/src/test/ui/print_type_sizes/variants.stdout b/src/test/ui/print_type_sizes/variants.stdout index eed9af26987b4..6411881545843 100644 --- a/src/test/ui/print_type_sizes/variants.stdout +++ b/src/test/ui/print_type_sizes/variants.stdout @@ -1,9 +1,9 @@ print-type-size type: `Enum`: 51 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes -print-type-size variant `Small`: 7 bytes -print-type-size field `.0`: 7 bytes print-type-size variant `Large`: 50 bytes print-type-size field `.0`: 50 bytes +print-type-size variant `Small`: 7 bytes +print-type-size field `.0`: 7 bytes print-type-size type: `FiftyBytes`: 50 bytes, alignment: 1 bytes print-type-size field `.0`: 50 bytes print-type-size type: `SevenBytes`: 7 bytes, alignment: 1 bytes From 1ce6645d1f6e80325f2c13ae72b879c66d09c644 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 12 Apr 2019 12:41:17 +0200 Subject: [PATCH 25/28] MaybeUninit: remove deprecated functions --- src/libcore/mem.rs | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 66bcf1f7d0101..e887426554701 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1152,15 +1152,6 @@ impl MaybeUninit { MaybeUninit { uninit: () } } - /// Deprecated before stabilization. - #[unstable(feature = "maybe_uninit", issue = "53491")] - #[inline(always)] - // FIXME: still used by stdsimd - // #[rustc_deprecated(since = "1.35.0", reason = "use `uninit` instead")] - pub const fn uninitialized() -> MaybeUninit { - Self::uninit() - } - /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being /// filled with `0` bytes. It depends on `T` whether that already makes for /// proper initialization. For example, `MaybeUninit::zeroed()` is initialized, @@ -1221,14 +1212,6 @@ impl MaybeUninit { } } - /// Deprecated before stabilization. - #[unstable(feature = "maybe_uninit", issue = "53491")] - #[inline(always)] - #[rustc_deprecated(since = "1.35.0", reason = "use `write` instead")] - pub fn set(&mut self, val: T) -> &mut T { - self.write(val) - } - /// Gets a pointer to the contained value. Reading from this pointer or turning it /// into a reference is undefined behavior unless the `MaybeUninit` is initialized. /// @@ -1346,15 +1329,6 @@ impl MaybeUninit { ManuallyDrop::into_inner(self.value) } - /// Deprecated before stabilization. - #[unstable(feature = "maybe_uninit", issue = "53491")] - #[inline(always)] - // FIXME: still used by stdsimd - // #[rustc_deprecated(since = "1.35.0", reason = "use `assume_init` instead")] - pub unsafe fn into_initialized(self) -> T { - self.assume_init() - } - /// Reads the value from the `MaybeUninit` container. The resulting `T` is subject /// to the usual drop handling. /// @@ -1417,14 +1391,6 @@ impl MaybeUninit { self.as_ptr().read() } - /// Deprecated before stabilization. - #[unstable(feature = "maybe_uninit", issue = "53491")] - #[inline(always)] - #[rustc_deprecated(since = "1.35.0", reason = "use `read` instead")] - pub unsafe fn read_initialized(&self) -> T { - self.read() - } - /// Gets a reference to the contained value. /// /// # Safety From fc928a18bad0b6aa275a6908351b164f6f4abcd6 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 3 Apr 2019 19:50:28 +0200 Subject: [PATCH 26/28] Stabilize the `alloc` crate. This implements RFC 2480: * https://github.com/rust-lang/rfcs/pull/2480 * https://github.com/rust-lang/rfcs/blob/master/text/2480-liballoc.md Closes https://github.com/rust-lang/rust/issues/27783 --- src/liballoc/lib.rs | 5 +---- src/liballoc/prelude/mod.rs | 1 - src/liballoc/raw_vec.rs | 4 ++-- src/libarena/lib.rs | 1 - src/libpanic_unwind/lib.rs | 2 -- src/libstd/lib.rs | 1 - .../run-make-fulldeps/sysroot-crates-are-unstable/test.py | 4 ++-- src/test/run-pass/array-slice-vec/vec-macro-no-std.rs | 2 +- src/test/run-pass/extern/extern-prelude-core.rs | 2 +- src/test/run-pass/extern/extern-prelude-core.stderr | 2 +- src/test/run-pass/for-loop-while/for-loop-no-std.rs | 2 +- src/test/run-pass/format-no-std.rs | 2 +- .../run-pass/structs-enums/unit-like-struct-drop-run.rs | 3 --- src/test/ui/allocator-submodule.rs | 2 -- src/test/ui/allocator-submodule.stderr | 2 +- src/test/ui/error-codes/E0254.rs | 1 - src/test/ui/error-codes/E0254.stderr | 2 +- src/test/ui/error-codes/E0259.rs | 2 +- src/test/ui/error-codes/E0260.rs | 1 - src/test/ui/error-codes/E0260.stderr | 2 +- src/test/ui/missing/missing-alloc_error_handler.rs | 2 +- src/test/ui/missing/missing-allocator.rs | 2 +- src/test/ui/resolve_self_super_hint.rs | 1 - src/test/ui/resolve_self_super_hint.stderr | 8 ++++---- src/test/ui/rust-2018/remove-extern-crate.fixed | 1 - src/test/ui/rust-2018/remove-extern-crate.rs | 1 - src/test/ui/rust-2018/remove-extern-crate.stderr | 8 ++++---- src/test/ui/unnecessary-extern-crate.rs | 2 +- 28 files changed, 25 insertions(+), 43 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 90ff56814fbb1..9129ce61d8c82 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -51,10 +51,7 @@ //! default global allocator. It is not compatible with the libc allocator API. #![allow(unused_attributes)] -#![unstable(feature = "alloc", - reason = "this library is unlikely to be stabilized in its current \ - form or name", - issue = "27783")] +#![stable(feature = "alloc", since = "1.36.0")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))] diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs index 33cc51d173203..0534ad3edc79d 100644 --- a/src/liballoc/prelude/mod.rs +++ b/src/liballoc/prelude/mod.rs @@ -5,7 +5,6 @@ //! //! ``` //! # #![allow(unused_imports)] -//! # #![feature(alloc)] //! #![feature(alloc_prelude)] //! extern crate alloc; //! use alloc::prelude::v1::*; diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index fe28fe5095cce..d1fc5ac3b30d4 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -256,7 +256,7 @@ impl RawVec { /// # Examples /// /// ``` - /// # #![feature(alloc, raw_vec_internals)] + /// # #![feature(raw_vec_internals)] /// # extern crate alloc; /// # use std::ptr; /// # use alloc::raw_vec::RawVec; @@ -460,7 +460,7 @@ impl RawVec { /// # Examples /// /// ``` - /// # #![feature(alloc, raw_vec_internals)] + /// # #![feature(raw_vec_internals)] /// # extern crate alloc; /// # use std::ptr; /// # use alloc::raw_vec::RawVec; diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 0a5b79c36aad8..f2913295bdce3 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -13,7 +13,6 @@ #![deny(rust_2018_idioms)] -#![feature(alloc)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(raw_vec_internals)] diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 9d3d8f6185bb3..72ddafb420ce7 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -19,8 +19,6 @@ #![deny(rust_2018_idioms)] -#![feature(allocator_api)] -#![feature(alloc)] #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(libc)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d11dee8fc9707..ee6ba3f438f15 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -229,7 +229,6 @@ #![feature(align_offset)] #![feature(alloc_error_handler)] #![feature(alloc_layout_extra)] -#![feature(alloc)] #![feature(allocator_api)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] diff --git a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py index e0fa4e8f5debe..855b6421cf822 100644 --- a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py +++ b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py @@ -7,8 +7,8 @@ # This is a whitelist of files which are stable crates or simply are not crates, # we don't check for the instability of these crates as they're all stable! -STABLE_CRATES = ['std', 'core', 'proc_macro', 'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o', - 'clang_rt'] +STABLE_CRATES = ['std', 'alloc', 'core', 'proc_macro', + 'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o', 'clang_rt'] def convert_to_string(s): diff --git a/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs b/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs index 7f7f1e4331507..443895f7c4824 100644 --- a/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs +++ b/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs @@ -2,7 +2,7 @@ // ignore-emscripten no no_std executables -#![feature(lang_items, start, rustc_private, alloc)] +#![feature(lang_items, start, rustc_private)] #![no_std] extern crate std as other; diff --git a/src/test/run-pass/extern/extern-prelude-core.rs b/src/test/run-pass/extern/extern-prelude-core.rs index a5d31009f9cee..f0d43404b0046 100644 --- a/src/test/run-pass/extern/extern-prelude-core.rs +++ b/src/test/run-pass/extern/extern-prelude-core.rs @@ -1,5 +1,5 @@ // run-pass -#![feature(extern_prelude, lang_items, start, alloc)] +#![feature(extern_prelude, lang_items, start)] #![no_std] extern crate std as other; diff --git a/src/test/run-pass/extern/extern-prelude-core.stderr b/src/test/run-pass/extern/extern-prelude-core.stderr index 417483af707ca..8d2a0b7425f2a 100644 --- a/src/test/run-pass/extern/extern-prelude-core.stderr +++ b/src/test/run-pass/extern/extern-prelude-core.stderr @@ -1,7 +1,7 @@ warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable --> $DIR/extern-prelude-core.rs:2:12 | -LL | #![feature(extern_prelude, lang_items, start, alloc)] +LL | #![feature(extern_prelude, lang_items, start)] | ^^^^^^^^^^^^^^ | = note: #[warn(stable_features)] on by default diff --git a/src/test/run-pass/for-loop-while/for-loop-no-std.rs b/src/test/run-pass/for-loop-while/for-loop-no-std.rs index 877429f5d3900..65a33c5f16f1d 100644 --- a/src/test/run-pass/for-loop-while/for-loop-no-std.rs +++ b/src/test/run-pass/for-loop-while/for-loop-no-std.rs @@ -1,6 +1,6 @@ // run-pass #![allow(unused_imports)] -#![feature(lang_items, start, alloc)] +#![feature(lang_items, start)] #![no_std] extern crate std as other; diff --git a/src/test/run-pass/format-no-std.rs b/src/test/run-pass/format-no-std.rs index 0f3a5c277b4c5..32f7a4a07c499 100644 --- a/src/test/run-pass/format-no-std.rs +++ b/src/test/run-pass/format-no-std.rs @@ -1,6 +1,6 @@ // ignore-emscripten no no_std executables -#![feature(lang_items, start, alloc)] +#![feature(lang_items, start)] #![no_std] extern crate std as other; diff --git a/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs b/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs index dfe73875215c5..980fd97e2c678 100644 --- a/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs +++ b/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs @@ -3,9 +3,6 @@ // Make sure the destructor is run for unit-like structs. - -#![feature(alloc)] - use std::thread; struct Foo; diff --git a/src/test/ui/allocator-submodule.rs b/src/test/ui/allocator-submodule.rs index a1cca50ba9817..7a8d86b8da18c 100644 --- a/src/test/ui/allocator-submodule.rs +++ b/src/test/ui/allocator-submodule.rs @@ -1,8 +1,6 @@ // Tests that it is possible to create a global allocator in a submodule, rather than in the crate // root. -#![feature(alloc, allocator_api, global_allocator)] - extern crate alloc; use std::{ diff --git a/src/test/ui/allocator-submodule.stderr b/src/test/ui/allocator-submodule.stderr index 26d7aa80eee16..91c7c0f6b8e24 100644 --- a/src/test/ui/allocator-submodule.stderr +++ b/src/test/ui/allocator-submodule.stderr @@ -1,5 +1,5 @@ error: `global_allocator` cannot be used in submodules - --> $DIR/allocator-submodule.rs:27:5 + --> $DIR/allocator-submodule.rs:25:5 | LL | static MY_HEAP: MyAlloc = MyAlloc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/error-codes/E0254.rs b/src/test/ui/error-codes/E0254.rs index 706cd347e134a..d166aff565792 100644 --- a/src/test/ui/error-codes/E0254.rs +++ b/src/test/ui/error-codes/E0254.rs @@ -1,4 +1,3 @@ -#![feature(alloc)] #![allow(unused_extern_crates, non_camel_case_types)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0254.stderr b/src/test/ui/error-codes/E0254.stderr index c2d013da41747..10456fd5a5dc1 100644 --- a/src/test/ui/error-codes/E0254.stderr +++ b/src/test/ui/error-codes/E0254.stderr @@ -1,5 +1,5 @@ error[E0254]: the name `alloc` is defined multiple times - --> $DIR/E0254.rs:12:5 + --> $DIR/E0254.rs:11:5 | LL | extern crate alloc; | ------------------- previous import of the extern crate `alloc` here diff --git a/src/test/ui/error-codes/E0259.rs b/src/test/ui/error-codes/E0259.rs index cda3db34dfc41..c83561be9c6a5 100644 --- a/src/test/ui/error-codes/E0259.rs +++ b/src/test/ui/error-codes/E0259.rs @@ -1,4 +1,4 @@ -#![feature(alloc, rustc_private)] +#![feature(rustc_private)] #![allow(unused_extern_crates)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0260.rs b/src/test/ui/error-codes/E0260.rs index 80382c0d2fcb5..73b8934159fcf 100644 --- a/src/test/ui/error-codes/E0260.rs +++ b/src/test/ui/error-codes/E0260.rs @@ -1,4 +1,3 @@ -#![feature(alloc)] #![allow(unused_extern_crates)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0260.stderr b/src/test/ui/error-codes/E0260.stderr index bfe2ed0cfc778..7d0b3022914d8 100644 --- a/src/test/ui/error-codes/E0260.stderr +++ b/src/test/ui/error-codes/E0260.stderr @@ -1,5 +1,5 @@ error[E0260]: the name `alloc` is defined multiple times - --> $DIR/E0260.rs:6:1 + --> $DIR/E0260.rs:5:1 | LL | extern crate alloc; | ------------------- previous import of the extern crate `alloc` here diff --git a/src/test/ui/missing/missing-alloc_error_handler.rs b/src/test/ui/missing/missing-alloc_error_handler.rs index 1a9e8688e8a42..ae0c067bb5f3e 100644 --- a/src/test/ui/missing/missing-alloc_error_handler.rs +++ b/src/test/ui/missing/missing-alloc_error_handler.rs @@ -3,7 +3,7 @@ #![no_std] #![crate_type = "staticlib"] -#![feature(panic_handler, alloc_error_handler, alloc)] +#![feature(panic_handler, alloc_error_handler)] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { diff --git a/src/test/ui/missing/missing-allocator.rs b/src/test/ui/missing/missing-allocator.rs index dbb10d1e7b97e..6d867e2e8b48e 100644 --- a/src/test/ui/missing/missing-allocator.rs +++ b/src/test/ui/missing/missing-allocator.rs @@ -3,7 +3,7 @@ #![no_std] #![crate_type = "staticlib"] -#![feature(panic_handler, alloc_error_handler, alloc)] +#![feature(panic_handler, alloc_error_handler)] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { diff --git a/src/test/ui/resolve_self_super_hint.rs b/src/test/ui/resolve_self_super_hint.rs index 91a01cc0fa231..a9423830d9040 100644 --- a/src/test/ui/resolve_self_super_hint.rs +++ b/src/test/ui/resolve_self_super_hint.rs @@ -1,4 +1,3 @@ -#![feature(alloc)] #![allow(unused_extern_crates)] mod a { diff --git a/src/test/ui/resolve_self_super_hint.stderr b/src/test/ui/resolve_self_super_hint.stderr index 03214cad8e41a..14cdae97d14f3 100644 --- a/src/test/ui/resolve_self_super_hint.stderr +++ b/src/test/ui/resolve_self_super_hint.stderr @@ -1,17 +1,17 @@ error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:6:9 + --> $DIR/resolve_self_super_hint.rs:5:9 | LL | use alloc::HashMap; | ^^^^^ help: a similar path exists: `self::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:11:13 + --> $DIR/resolve_self_super_hint.rs:10:13 | LL | use alloc::HashMap; | ^^^^^ help: a similar path exists: `super::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:16:17 + --> $DIR/resolve_self_super_hint.rs:15:17 | LL | use alloc::HashMap; | ^^^^^ @@ -20,7 +20,7 @@ LL | use alloc::HashMap; | help: a similar path exists: `a::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:21:21 + --> $DIR/resolve_self_super_hint.rs:20:21 | LL | use alloc::HashMap; | ^^^^^ diff --git a/src/test/ui/rust-2018/remove-extern-crate.fixed b/src/test/ui/rust-2018/remove-extern-crate.fixed index a977e00c0131b..17449caf84fb4 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.fixed +++ b/src/test/ui/rust-2018/remove-extern-crate.fixed @@ -4,7 +4,6 @@ // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate -#![feature(alloc)] #![warn(rust_2018_idioms)] diff --git a/src/test/ui/rust-2018/remove-extern-crate.rs b/src/test/ui/rust-2018/remove-extern-crate.rs index cafe82d846ed8..fb2217df0005d 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.rs +++ b/src/test/ui/rust-2018/remove-extern-crate.rs @@ -4,7 +4,6 @@ // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate -#![feature(alloc)] #![warn(rust_2018_idioms)] extern crate core; diff --git a/src/test/ui/rust-2018/remove-extern-crate.stderr b/src/test/ui/rust-2018/remove-extern-crate.stderr index 4e08b7aa6a03d..549693201b703 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.stderr +++ b/src/test/ui/rust-2018/remove-extern-crate.stderr @@ -1,24 +1,24 @@ warning: unused extern crate - --> $DIR/remove-extern-crate.rs:10:1 + --> $DIR/remove-extern-crate.rs:9:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: remove it | note: lint level defined here - --> $DIR/remove-extern-crate.rs:8:9 + --> $DIR/remove-extern-crate.rs:7:9 | LL | #![warn(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)] warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:11:1 + --> $DIR/remove-extern-crate.rs:10:1 | LL | extern crate core as another_name; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:29:5 + --> $DIR/remove-extern-crate.rs:28:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: convert it to a `use` diff --git a/src/test/ui/unnecessary-extern-crate.rs b/src/test/ui/unnecessary-extern-crate.rs index e25b99bcb61dd..67eaaf4b6c21b 100644 --- a/src/test/ui/unnecessary-extern-crate.rs +++ b/src/test/ui/unnecessary-extern-crate.rs @@ -1,7 +1,7 @@ // edition:2018 #![deny(unused_extern_crates)] -#![feature(alloc, test, rustc_private, crate_visibility_modifier)] +#![feature(test, rustc_private, crate_visibility_modifier)] extern crate libc; //~^ ERROR unused extern crate From b27bcc0a17230179d010d914e06bb90ccadca1f7 Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Fri, 12 Apr 2019 13:57:42 -0600 Subject: [PATCH 27/28] Fix paste error in split_ascii_whitespace docs. --- src/libcore/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f54d7badc3ae0..8d28be621d647 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2712,7 +2712,7 @@ impl str { /// All kinds of ASCII whitespace are considered: /// /// ``` - /// let mut iter = " Mary had\ta little \n\t lamb".split_whitespace(); + /// let mut iter = " Mary had\ta little \n\t lamb".split_ascii_whitespace(); /// assert_eq!(Some("Mary"), iter.next()); /// assert_eq!(Some("had"), iter.next()); /// assert_eq!(Some("a"), iter.next()); From 0a9b214b503265e42e86ca7846577664efb1819e Mon Sep 17 00:00:00 2001 From: Kornel Date: Sat, 13 Apr 2019 00:38:46 +0100 Subject: [PATCH 28/28] Exclude some copies of old book editions from search engines --- src/doc/robots.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/doc/robots.txt b/src/doc/robots.txt index a54ec508c1bef..61ee12739fb37 100644 --- a/src/doc/robots.txt +++ b/src/doc/robots.txt @@ -17,3 +17,11 @@ Disallow: /1.0.0-beta.2/ Disallow: /1.0.0-beta.3/ Disallow: /1.0.0-beta.4/ Disallow: /1.0.0-beta.5/ +Disallow: /book/first-edition/ +Disallow: /book/second-edition/ +Disallow: /stable/book/first-edition/ +Disallow: /stable/book/second-edition/ +Disallow: /beta/book/first-edition/ +Disallow: /beta/book/second-edition/ +Disallow: /nightly/book/first-edition/ +Disallow: /nightly/book/second-edition/