From c738e6042d2925bbfb045982fabe1f902f8b7c72 Mon Sep 17 00:00:00 2001 From: purple-ice Date: Thu, 3 Jan 2019 20:15:01 +0200 Subject: [PATCH 01/18] Extend E0106, E0261 Added an example that points out hardly obvious mistake one could make when writing impl for a new type. --- src/librustc/diagnostics.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 4bc52e82f9be1..50beacf3e8cbb 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -362,6 +362,10 @@ struct Foo1 { x: &bool } // ^ expected lifetime parameter struct Foo2<'a> { x: &'a bool } // correct +impl Foo2 { ... } + // ^ expected lifetime parameter +impl<'a> Foo2<'a> { ... } // correct + struct Bar1 { x: Foo2 } // ^^^^ expected lifetime parameter struct Bar2<'a> { x: Foo2<'a> } // correct @@ -772,6 +776,24 @@ struct Foo<'a> { x: &'a str, } ``` + +Implementations need their own lifetime declarations: + +``` +// error, undeclared lifetime +impl Foo<'a> { + ... +} +``` + +Which are declared like this: + +``` +// correct +impl<'a> Foo<'a> { + ... +} +``` "##, E0262: r##" From adadefd8741d84ebfb5884fbd12f3202cd6fdb4f Mon Sep 17 00:00:00 2001 From: purple-ice Date: Fri, 4 Jan 2019 13:00:26 +0200 Subject: [PATCH 02/18] Fix changes for E0106, E0261 Replaced impl block dock with suggested one and made sure that blocks compile. --- src/librustc/diagnostics.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 50beacf3e8cbb..dd5144b1568fb 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -362,9 +362,9 @@ struct Foo1 { x: &bool } // ^ expected lifetime parameter struct Foo2<'a> { x: &'a bool } // correct -impl Foo2 { ... } +impl Foo2 {} // ^ expected lifetime parameter -impl<'a> Foo2<'a> { ... } // correct +impl<'a> Foo2<'a> {} // correct struct Bar1 { x: Foo2 } // ^^^^ expected lifetime parameter @@ -777,21 +777,32 @@ struct Foo<'a> { } ``` -Implementations need their own lifetime declarations: +Impl blocks declare lifetime parameters separately. You need to add lifetime +parameters to an impl block if you're implementing a type that has a lifetime +parameter of its own. +For example: -``` -// error, undeclared lifetime +```compile_fail,E0261 +// error, use of undeclared lifetime name `'a` impl Foo<'a> { - ... + fn foo<'a>(x: &'a str) {} +} + +struct Foo<'a> { + x: &'a str, } ``` -Which are declared like this: +This is fixed by declaring impl block like this: ``` // correct impl<'a> Foo<'a> { - ... + fn foo(x: &'a str) {} +} + +struct Foo<'a> { + x: &'a str, } ``` "##, From da06898a7539ff66e636a5bf9d3b176b865a2737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 16 Jan 2019 19:34:37 +0100 Subject: [PATCH 03/18] Avoid erase_regions_ty queries if there are no regions to erase It's overall faster to perform this extra check than to perform the query, even if the result is already in the query cache. --- src/librustc/ty/erase_regions.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs index bbf71c62ca69d..da7e021b2d54b 100644 --- a/src/librustc/ty/erase_regions.rs +++ b/src/librustc/ty/erase_regions.rs @@ -1,4 +1,4 @@ -use ty::{self, Ty, TyCtxt}; +use ty::{self, Ty, TyCtxt, TypeFlags}; use ty::fold::{TypeFolder, TypeFoldable}; pub(super) fn provide(providers: &mut ty::query::Providers<'_>) { @@ -21,6 +21,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn erase_regions(self, value: &T) -> T where T : TypeFoldable<'tcx> { + // If there's nothing to erase avoid performing the query at all + if !value.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { + return value.clone(); + } + let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); debug!("erase_regions({:?}) = {:?}", value, value1); value1 From 2ec0e85305e69d7f6e1bc0c704a6566ad38232a4 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 22 Jan 2019 18:51:54 +0530 Subject: [PATCH 04/18] Print a slightly clearer message when failing to spawn a thread --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index a55b32c08a303..eb8e0c1c8ac66 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -607,7 +607,7 @@ impl Builder { pub fn spawn(f: F) -> JoinHandle where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static { - Builder::new().spawn(f).unwrap() + Builder::new().spawn(f).expect("failed to spawn thread") } /// Gets a handle to the thread that invokes it. From 0cf97042d1317630e619b13a1b416f3b7794fb2a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 23 Jan 2019 12:05:00 +0100 Subject: [PATCH 05/18] Fix invalid background color --- src/librustdoc/html/static/themes/dark.css | 4 ---- src/librustdoc/html/static/themes/light.css | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 2cd1a8580890c..61392f1ce0f31 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -419,10 +419,6 @@ kbd { color: #ccc; } -.impl-items code { - background-color: rgba(0, 0, 0, 0); -} - #sidebar-toggle { background-color: #565656; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 4cf35f64d19a4..de6d847a30c77 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -414,10 +414,6 @@ kbd { color: #999; } -.impl-items code { - background-color: rgba(0, 0, 0, 0); -} - #sidebar-toggle { background-color: #F1F1F1; } From c375333362bd1b5f006f6d627ff129c2c54d620c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 26 Jan 2019 16:29:34 +0300 Subject: [PATCH 06/18] Pretty print `$crate` as `crate` or `crate_name` in more cases --- src/librustc_resolve/macros.rs | 10 +++++----- src/librustc_resolve/resolve_imports.rs | 5 +---- src/libsyntax/ext/base.rs | 16 ++-------------- src/libsyntax/ext/expand.rs | 7 +++---- src/test/pretty/dollar-crate.pp | 18 ++++++++++++++++++ src/test/pretty/dollar-crate.rs | 7 +++++++ 6 files changed, 36 insertions(+), 27 deletions(-) create mode 100644 src/test/pretty/dollar-crate.pp create mode 100644 src/test/pretty/dollar-crate.rs diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 286f9a758830b..e552795260465 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -15,7 +15,7 @@ use syntax::ast::{self, Ident}; use syntax::attr; use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Determinacy}; -use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension}; +use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, Mark}; use syntax::ext::tt::macro_rules; @@ -127,9 +127,9 @@ impl<'a> base::Resolver for Resolver<'a> { mark } - fn resolve_dollar_crates(&mut self, annotatable: &Annotatable) { - pub struct ResolveDollarCrates<'a, 'b: 'a> { - pub resolver: &'a mut Resolver<'b>, + fn resolve_dollar_crates(&mut self, fragment: &AstFragment) { + struct ResolveDollarCrates<'a, 'b: 'a> { + resolver: &'a mut Resolver<'b> } impl<'a> Visitor<'a> for ResolveDollarCrates<'a, '_> { fn visit_ident(&mut self, ident: Ident) { @@ -144,7 +144,7 @@ impl<'a> base::Resolver for Resolver<'a> { fn visit_mac(&mut self, _: &ast::Mac) {} } - annotatable.visit_with(&mut ResolveDollarCrates { resolver: self }); + fragment.visit_with(&mut ResolveDollarCrates { resolver: self }); } fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index fd55897522bf7..9a04c9d60b868 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -537,11 +537,8 @@ impl<'a> Resolver<'a> { primary_binding: &'a NameBinding<'a>, secondary_binding: &'a NameBinding<'a>) -> &'a NameBinding<'a> { self.arenas.alloc_name_binding(NameBinding { - kind: primary_binding.kind.clone(), ambiguity: Some((secondary_binding, kind)), - vis: primary_binding.vis, - span: primary_binding.span, - expansion: primary_binding.expansion, + ..primary_binding.clone() }) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 2793754e1033a..09e7e57f78cfa 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -14,7 +14,6 @@ use parse::token; use ptr::P; use smallvec::SmallVec; use symbol::{keywords, Ident, Symbol}; -use visit::Visitor; use ThinVec; use rustc_data_structures::fx::FxHashMap; @@ -136,17 +135,6 @@ impl Annotatable { _ => false, } } - - pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) { - match self { - Annotatable::Item(item) => visitor.visit_item(item), - Annotatable::TraitItem(trait_item) => visitor.visit_trait_item(trait_item), - Annotatable::ImplItem(impl_item) => visitor.visit_impl_item(impl_item), - Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item), - Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt), - Annotatable::Expr(expr) => visitor.visit_expr(expr), - } - } } // A more flexible ItemDecorator. @@ -742,7 +730,7 @@ pub trait Resolver { fn next_node_id(&mut self) -> ast::NodeId; fn get_module_scope(&mut self, id: ast::NodeId) -> Mark; - fn resolve_dollar_crates(&mut self, annotatable: &Annotatable); + fn resolve_dollar_crates(&mut self, fragment: &AstFragment); fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, derives: &[Mark]); fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc); @@ -776,7 +764,7 @@ impl Resolver for DummyResolver { fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID } fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() } - fn resolve_dollar_crates(&mut self, _annotatable: &Annotatable) {} + fn resolve_dollar_crates(&mut self, _fragment: &AstFragment) {} fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment, _derives: &[Mark]) {} fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc) {} diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9369e66cf83da..6e327c6a9dade 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -443,6 +443,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { /// prepares data for resolving paths of macro invocations. fn collect_invocations(&mut self, fragment: AstFragment, derives: &[Mark]) -> (AstFragment, Vec) { + // Resolve `$crate`s in the fragment for pretty-printing. + self.cx.resolver.resolve_dollar_crates(&fragment); + let (fragment_with_placeholders, invocations) = { let mut collector = InvocationCollector { cfg: StripUnconfigured { @@ -574,8 +577,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Some(invoc.fragment_kind.expect_from_annotatables(items)) } AttrProcMacro(ref mac, ..) => { - // Resolve `$crate`s in case we have to go though stringification. - self.cx.resolver.resolve_dollar_crates(&item); self.gate_proc_macro_attr_item(attr.span, &item); let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item { Annotatable::Item(item) => token::NtItem(item), @@ -917,8 +918,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { match *ext { ProcMacroDerive(ref ext, ..) => { - // Resolve `$crate`s in case we have to go though stringification. - self.cx.resolver.resolve_dollar_crates(&item); invoc.expansion_data.mark.set_expn_info(expn_info); let span = span.with_ctxt(self.cx.backtrace()); let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this diff --git a/src/test/pretty/dollar-crate.pp b/src/test/pretty/dollar-crate.pp new file mode 100644 index 0000000000000..3d2d949be2b2e --- /dev/null +++ b/src/test/pretty/dollar-crate.pp @@ -0,0 +1,18 @@ +#![feature(prelude_import)] +#![no_std] +#[prelude_import] +use ::std::prelude::v1::*; +#[macro_use] +extern crate std; +// pretty-compare-only +// pretty-mode:expanded +// pp-exact:dollar-crate.pp + +fn main() { + { + ::std::io::_print(::std::fmt::Arguments::new_v1(&["rust\n"], + &match () { + () => [], + })); + }; +} diff --git a/src/test/pretty/dollar-crate.rs b/src/test/pretty/dollar-crate.rs new file mode 100644 index 0000000000000..e46bc7f4859a7 --- /dev/null +++ b/src/test/pretty/dollar-crate.rs @@ -0,0 +1,7 @@ +// pretty-compare-only +// pretty-mode:expanded +// pp-exact:dollar-crate.pp + +fn main() { + println!("rust"); +} From 5e6702117223b61057957ca2593f03e3f45ccd8a Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 25 Jan 2019 14:29:47 -0500 Subject: [PATCH 07/18] add typo suggestion to unknown attribute error --- src/librustc_resolve/macros.rs | 70 +++++++++++++++++-- src/test/ui/issues/issue-49074.stderr | 2 +- .../ui/macros/macro-reexport-removed.stderr | 2 +- .../ui/proc-macro/derive-still-gated.stderr | 2 +- src/test/ui/suggestions/attribute-typos.rs | 13 ++++ .../ui/suggestions/attribute-typos.stderr | 27 +++++++ 6 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/suggestions/attribute-typos.rs create mode 100644 src/test/ui/suggestions/attribute-typos.stderr diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index fb5b6c97689d0..78b5518203084 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -19,7 +19,9 @@ use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, Mark}; use syntax::ext::tt::macro_rules; -use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue}; +use syntax::feature_gate::{ + feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES, +}; use syntax::symbol::{Symbol, keywords}; use syntax::visit::Visitor; use syntax::util::lev_distance::find_best_match_for_name; @@ -310,15 +312,18 @@ impl<'a> Resolver<'a> { if !features.rustc_attrs { let msg = "unless otherwise specified, attributes with the prefix \ `rustc_` are reserved for internal compiler diagnostics"; - feature_err(&self.session.parse_sess, "rustc_attrs", path.span, - GateIssue::Language, &msg).emit(); + self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs"); } } else if !features.custom_attribute { let msg = format!("The attribute `{}` is currently unknown to the \ compiler and may have meaning added to it in the \ future", path); - feature_err(&self.session.parse_sess, "custom_attribute", path.span, - GateIssue::Language, &msg).emit(); + self.report_unknown_attribute( + path.span, + &name, + &msg, + "custom_attribute", + ); } } } else { @@ -339,6 +344,61 @@ impl<'a> Resolver<'a> { Ok((def, self.get_macro(def))) } + fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) { + let mut err = feature_err( + &self.session.parse_sess, + feature, + span, + GateIssue::Language, + &msg, + ); + + let features = self.session.features_untracked(); + + let attr_candidates = BUILTIN_ATTRIBUTES + .iter() + .filter_map(|(name, _, _, gate)| { + if name.starts_with("rustc_") && !features.rustc_attrs { + return None; + } + + match gate { + AttributeGate::Gated(Stability::Unstable, ..) + if self.session.opts.unstable_features.is_nightly_build() => + { + Some(name) + } + AttributeGate::Gated(Stability::Deprecated(..), ..) => Some(name), + AttributeGate::Ungated => Some(name), + _ => None, + } + }) + .map(|name| Symbol::intern(name)) + .chain( + // Add built-in macro attributes as well. + self.builtin_macros.iter().filter_map(|(name, binding)| { + match binding.macro_kind() { + Some(MacroKind::Attr) => Some(*name), + _ => None, + } + }), + ) + .collect::>(); + + let lev_suggestion = find_best_match_for_name(attr_candidates.iter(), &name, None); + + if let Some(suggestion) = lev_suggestion { + err.span_suggestion( + span, + "a built-in attribute with a similar name exists", + suggestion.to_string(), + Applicability::MaybeIncorrect, + ); + } + + err.emit(); + } + pub fn resolve_macro_to_def_inner( &mut self, path: &ast::Path, diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr index d4648270f2d30..a25d8ee352686 100644 --- a/src/test/ui/issues/issue-49074.stderr +++ b/src/test/ui/issues/issue-49074.stderr @@ -2,7 +2,7 @@ error[E0658]: The attribute `marco_use` is currently unknown to the compiler and --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo - | ^^^^^^^^^ + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/macros/macro-reexport-removed.stderr b/src/test/ui/macros/macro-reexport-removed.stderr index 7c3555a92ed8b..6cfec3ee762dd 100644 --- a/src/test/ui/macros/macro-reexport-removed.stderr +++ b/src/test/ui/macros/macro-reexport-removed.stderr @@ -14,7 +14,7 @@ error[E0658]: The attribute `macro_reexport` is currently unknown to the compile --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/proc-macro/derive-still-gated.stderr b/src/test/ui/proc-macro/derive-still-gated.stderr index d54a593f78311..ece1b6212914d 100644 --- a/src/test/ui/proc-macro/derive-still-gated.stderr +++ b/src/test/ui/proc-macro/derive-still-gated.stderr @@ -2,7 +2,7 @@ error[E0658]: The attribute `derive_A` is currently unknown to the compiler and --> $DIR/derive-still-gated.rs:8:3 | LL | #[derive_A] //~ ERROR attribute `derive_A` is currently unknown - | ^^^^^^^^ + | ^^^^^^^^ help: a built-in attribute with a similar name exists: `derive` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs new file mode 100644 index 0000000000000..13c6308b97e85 --- /dev/null +++ b/src/test/ui/suggestions/attribute-typos.rs @@ -0,0 +1,13 @@ +#[deprcated] //~ ERROR E0658 +fn foo() {} //~| HELP a built-in attribute with a similar name exists + //~| SUGGESTION deprecated + //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable + +#[tests] //~ ERROR E0658 +fn bar() {} //~| HELP a built-in attribute with a similar name exists + //~| SUGGESTION test + //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable + +#[rustc_err] //~ ERROR E0658 +fn main() {} //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable + // don't suggest rustc attributes diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr new file mode 100644 index 0000000000000..e40da787e96ca --- /dev/null +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -0,0 +1,27 @@ +error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642) + --> $DIR/attribute-typos.rs:11:3 + | +LL | #[rustc_err] //~ ERROR E0658 + | ^^^^^^^^^ + | + = help: add #![feature(rustc_attrs)] to the crate attributes to enable + +error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/attribute-typos.rs:6:3 + | +LL | #[tests] //~ ERROR E0658 + | ^^^^^ help: a built-in attribute with a similar name exists: `test` + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error[E0658]: The attribute `deprcated` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/attribute-typos.rs:1:3 + | +LL | #[deprcated] //~ ERROR E0658 + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. From c775c2fe969219b9631e295e6ef7d05a3ea07e65 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 20 Dec 2018 22:49:32 +0100 Subject: [PATCH 08/18] libcore: remove unneeded allow(deprecated) --- src/libcore/fmt/mod.rs | 2 +- src/libcore/fmt/num.rs | 2 -- src/libcore/hash/sip.rs | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 935579f4943b6..530b2f52c0df2 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -2048,7 +2048,7 @@ macro_rules! tuple { ( $($name:ident,)+ ) => ( #[stable(feature = "rust1", since = "1.0.0")] impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized { - #[allow(non_snake_case, unused_assignments, deprecated)] + #[allow(non_snake_case, unused_assignments)] fn fmt(&self, f: &mut Formatter) -> Result { let mut builder = f.debug_tuple(""); let ($(ref $name,)*) = *self; diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index c7c8fc50efaae..db3984f4a17e3 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -1,7 +1,5 @@ //! Integer and floating-point number formatting -#![allow(deprecated)] - use fmt; use ops::{Div, Rem, Sub}; diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index 3377b831a9daa..18f09f4c5dda4 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -1,6 +1,6 @@ //! An implementation of SipHash. -#![allow(deprecated)] +#![allow(deprecated)] // the types in this module are deprecated use marker::PhantomData; use ptr; From c11e514e9dfd44eebe435408b32de4193d87860c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 20 Dec 2018 22:51:08 +0100 Subject: [PATCH 09/18] liballoc: remove unneeded allow(deprecated) --- src/liballoc/borrow.rs | 1 - src/liballoc/rc.rs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 603d73100a8b4..b47337e44b2fe 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -380,7 +380,6 @@ impl<'a, B: ?Sized> Hash for Cow<'a, B> } #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated)] impl<'a, T: ?Sized + ToOwned> AsRef for Cow<'a, T> { fn as_ref(&self) -> &T { self diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index d3a55c59ff69c..c0dc010fe59a5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - //! Single-threaded reference-counting pointers. 'Rc' stands for 'Reference //! Counted'. //! From a88414e007d9740c1c3d483ff778f7f2d3f32749 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Dec 2018 11:08:26 +0100 Subject: [PATCH 10/18] libcore: avoid mem::uninitialized and raw ptr casts --- src/libcore/fmt/num.rs | 28 +++++++++++++++++++++------- src/libcore/lib.rs | 1 + src/libcore/mem.rs | 14 ++++++++++++++ src/libcore/slice/sort.rs | 19 +++++++++++++------ 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index db3984f4a17e3..ff284d2978e70 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -6,7 +6,7 @@ use ops::{Div, Rem, Sub}; use str; use slice; use ptr; -use mem; +use mem::MaybeUninit; #[doc(hidden)] trait Int: PartialEq + PartialOrd + Div + Rem + @@ -51,7 +51,12 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - let mut buf: [u8; 128] = unsafe { mem::uninitialized() }; + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + let mut buf: [MaybeUninit; 128] = unsafe { + MaybeUninit::uninitialized().into_inner() + }; let mut curr = buf.len(); let base = T::from_u8(Self::BASE); if is_nonnegative { @@ -60,7 +65,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = x % base; // Get the current place value. x = x / base; // Deaccumulate the number. - *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. + byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -72,7 +77,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. - *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. + byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -80,7 +85,11 @@ trait GenericRadix { }; } } - let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) }; + let buf = &buf[curr..]; + let buf = unsafe { str::from_utf8_unchecked(slice::from_raw_parts( + MaybeUninit::first_ptr(buf), + buf.len() + )) }; f.pad_integral(is_nonnegative, Self::PREFIX, buf) } } @@ -194,9 +203,14 @@ macro_rules! impl_Display { // convert the negative num to positive by summing 1 to it's 2 complement (!self.$conv_fn()).wrapping_add(1) }; - let mut buf: [u8; 39] = unsafe { mem::uninitialized() }; + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + let mut buf: [MaybeUninit; 39] = unsafe { + MaybeUninit::uninitialized().into_inner() + }; let mut curr = buf.len() as isize; - let buf_ptr = buf.as_mut_ptr(); + let buf_ptr = MaybeUninit::first_mut_ptr(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); unsafe { diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 825e5148fd503..dbf0b15818909 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -60,6 +60,7 @@ test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] #![no_core] +#![warn(deprecated_in_future)] #![deny(missing_docs)] #![deny(intra_doc_link_resolution_failure)] #![deny(missing_debug_implementations)] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 0eeac5e1ea940..4631d32d186f6 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1148,4 +1148,18 @@ impl MaybeUninit { pub fn as_mut_ptr(&mut self) -> *mut T { unsafe { &mut *self.value as *mut T } } + + /// Get a pointer to the first contained values. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + pub fn first_ptr(this: &[MaybeUninit]) -> *const T { + this as *const [MaybeUninit] as *const T + } + + /// Get a mutable pointer to the first contained values. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + pub fn first_mut_ptr(this: &mut [MaybeUninit]) -> *mut T { + this as *mut [MaybeUninit] as *mut T + } } diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index dd9b49fb7a002..8eb6a4d54c0f6 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -216,14 +216,21 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize let mut block_l = BLOCK; let mut start_l = ptr::null_mut(); let mut end_l = ptr::null_mut(); - let mut offsets_l = MaybeUninit::<[u8; BLOCK]>::uninitialized(); + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + let mut offsets_l: [MaybeUninit; BLOCK] = unsafe { + MaybeUninit::uninitialized().into_inner() + }; // The current block on the right side (from `r.sub(block_r)` to `r`). let mut r = unsafe { l.add(v.len()) }; let mut block_r = BLOCK; let mut start_r = ptr::null_mut(); let mut end_r = ptr::null_mut(); - let mut offsets_r = MaybeUninit::<[u8; BLOCK]>::uninitialized(); + let mut offsets_r: [MaybeUninit; BLOCK] = unsafe { + MaybeUninit::uninitialized().into_inner() + }; // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient. @@ -262,8 +269,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_l == end_l { // Trace `block_l` elements from the left side. - start_l = offsets_l.as_mut_ptr() as *mut u8; - end_l = offsets_l.as_mut_ptr() as *mut u8; + start_l = MaybeUninit::first_mut_ptr(&mut offsets_l); + end_l = MaybeUninit::first_mut_ptr(&mut offsets_l); let mut elem = l; for i in 0..block_l { @@ -278,8 +285,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_r == end_r { // Trace `block_r` elements from the right side. - start_r = offsets_r.as_mut_ptr() as *mut u8; - end_r = offsets_r.as_mut_ptr() as *mut u8; + start_r = MaybeUninit::first_mut_ptr(&mut offsets_r); + end_r = MaybeUninit::first_mut_ptr(&mut offsets_r); let mut elem = r; for i in 0..block_r { From ffd73df7559be73398679d7f09447379dd0c2098 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Dec 2018 11:22:18 +0100 Subject: [PATCH 11/18] avoid mem::uninitialized in BTreeMap --- src/liballoc/collections/btree/node.rs | 25 ++++++++++++++++--------- src/liballoc/lib.rs | 1 + src/libcore/lib.rs | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index f9a21aa95db71..cc46bae01cb99 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -145,7 +145,7 @@ struct InternalNode { /// The pointers to the children of this node. `len + 1` of these are considered /// initialized and valid. - edges: [BoxedNode; 2 * B], + edges: [MaybeUninit>; 2 * B], } impl InternalNode { @@ -159,7 +159,10 @@ impl InternalNode { unsafe fn new() -> Self { InternalNode { data: LeafNode::new(), - edges: mem::uninitialized() + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + edges: MaybeUninit::uninitialized().into_inner(), } } } @@ -261,7 +264,7 @@ impl Root { -> NodeRef { debug_assert!(!self.is_shared_root()); let mut new_node = Box::new(unsafe { InternalNode::new() }); - new_node.edges[0] = unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }; + new_node.edges[0].set(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); self.node = BoxedNode::from_internal(new_node); self.height += 1; @@ -718,7 +721,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { unsafe { ptr::write(self.keys_mut().get_unchecked_mut(idx), key); ptr::write(self.vals_mut().get_unchecked_mut(idx), val); - ptr::write(self.as_internal_mut().edges.get_unchecked_mut(idx + 1), edge.node); + self.as_internal_mut().edges.get_unchecked_mut(idx + 1).set(edge.node); (*self.as_leaf_mut()).len += 1; @@ -749,7 +752,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { slice_insert(self.vals_mut(), 0, val); slice_insert( slice::from_raw_parts_mut( - self.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_mut_ptr(&mut self.as_internal_mut().edges), self.len()+1 ), 0, @@ -778,7 +781,9 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { let edge = match self.reborrow_mut().force() { ForceResult::Leaf(_) => None, ForceResult::Internal(internal) => { - let edge = ptr::read(internal.as_internal().edges.get_unchecked(idx + 1)); + let edge = ptr::read( + internal.as_internal().edges.get_unchecked(idx + 1).as_ptr() + ); let mut new_root = Root { node: edge, height: internal.height - 1 }; (*new_root.as_mut().as_leaf_mut()).parent = ptr::null(); Some(new_root) @@ -806,7 +811,7 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { ForceResult::Internal(mut internal) => { let edge = slice_remove( slice::from_raw_parts_mut( - internal.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_mut_ptr(&mut internal.as_internal_mut().edges), old_len+1 ), 0 @@ -1085,7 +1090,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: slice_insert( slice::from_raw_parts_mut( - self.node.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_mut_ptr(&mut self.node.as_internal_mut().edges), self.node.len() ), self.idx + 1, @@ -1140,7 +1145,9 @@ impl pub fn descend(self) -> NodeRef { NodeRef { height: self.node.height - 1, - node: unsafe { self.node.as_internal().edges.get_unchecked(self.idx).as_ptr() }, + node: unsafe { + self.node.as_internal().edges.get_unchecked(self.idx).get_ref().as_ptr() + }, root: self.node.root, _marker: PhantomData } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3050a93ef39a0..cf9d89ee05adf 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -63,6 +63,7 @@ #![no_std] #![needs_allocator] +#![warn(deprecated_in_future)] #![deny(intra_doc_link_resolution_failure)] #![deny(missing_debug_implementations)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index dbf0b15818909..4d7da3692fd84 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -58,8 +58,8 @@ issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] - #![no_core] + #![warn(deprecated_in_future)] #![deny(missing_docs)] #![deny(intra_doc_link_resolution_failure)] From 630aaa4e801393c55c8327f642aec2349adfaee3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Dec 2018 15:10:19 +0100 Subject: [PATCH 12/18] avoid some raw ptr casts in BTreeMap --- src/liballoc/collections/btree/node.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index cc46bae01cb99..8dd4aec136aa8 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -95,8 +95,8 @@ struct LeafNode { /// The arrays storing the actual data of the node. Only the first `len` elements of each /// array are initialized and valid. - keys: MaybeUninit<[K; CAPACITY]>, - vals: MaybeUninit<[V; CAPACITY]>, + keys: [MaybeUninit; CAPACITY], + vals: [MaybeUninit; CAPACITY], } impl LeafNode { @@ -106,8 +106,11 @@ impl LeafNode { LeafNode { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. - keys: MaybeUninit::uninitialized(), - vals: MaybeUninit::uninitialized(), + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + keys: MaybeUninit::uninitialized().into_inner(), + vals: MaybeUninit::uninitialized().into_inner(), parent: ptr::null(), parent_idx: MaybeUninit::uninitialized(), len: 0 @@ -626,7 +629,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { // We cannot be the root, so `as_leaf` is okay unsafe { slice::from_raw_parts( - self.as_leaf().vals.as_ptr() as *const V, + MaybeUninit::first_ptr(&self.as_leaf().vals), self.len() ) } @@ -653,7 +656,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } else { unsafe { slice::from_raw_parts_mut( - (*self.as_leaf_mut()).keys.as_mut_ptr() as *mut K, + MaybeUninit::first_mut_ptr(&mut (*self.as_leaf_mut()).keys), self.len() ) } @@ -664,7 +667,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { debug_assert!(!self.is_shared_root()); unsafe { slice::from_raw_parts_mut( - (*self.as_leaf_mut()).vals.as_mut_ptr() as *mut V, + MaybeUninit::first_mut_ptr(&mut (*self.as_leaf_mut()).vals), self.len() ) } From 22a947f3aa4b990efa135e3593fe7365bc7c36b9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 22 Dec 2018 11:02:06 +0100 Subject: [PATCH 13/18] add macro for creating uninitialized array --- src/liballoc/collections/btree/node.rs | 12 +++--------- src/libcore/fmt/num.rs | 14 ++------------ src/libcore/lib.rs | 1 + src/libcore/macros.rs | 17 +++++++++++++++++ src/libcore/slice/sort.rs | 11 ++--------- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 8dd4aec136aa8..25810d680fa4b 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -106,11 +106,8 @@ impl LeafNode { LeafNode { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - keys: MaybeUninit::uninitialized().into_inner(), - vals: MaybeUninit::uninitialized().into_inner(), + keys: uninitialized_array![_; CAPACITY], + vals: uninitialized_array![_; CAPACITY], parent: ptr::null(), parent_idx: MaybeUninit::uninitialized(), len: 0 @@ -162,10 +159,7 @@ impl InternalNode { unsafe fn new() -> Self { InternalNode { data: LeafNode::new(), - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - edges: MaybeUninit::uninitialized().into_inner(), + edges: uninitialized_array![_; 2*B], } } } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index ff284d2978e70..5283c6d7ef347 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -51,12 +51,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - let mut buf: [MaybeUninit; 128] = unsafe { - MaybeUninit::uninitialized().into_inner() - }; + let mut buf = uninitialized_array![u8; 128]; let mut curr = buf.len(); let base = T::from_u8(Self::BASE); if is_nonnegative { @@ -203,12 +198,7 @@ macro_rules! impl_Display { // convert the negative num to positive by summing 1 to it's 2 complement (!self.$conv_fn()).wrapping_add(1) }; - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - let mut buf: [MaybeUninit; 39] = unsafe { - MaybeUninit::uninitialized().into_inner() - }; + let mut buf = uninitialized_array![u8; 39]; let mut curr = buf.len() as isize; let buf_ptr = MaybeUninit::first_mut_ptr(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 4d7da3692fd84..1295acb44a543 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -123,6 +123,7 @@ #![feature(structural_match)] #![feature(abi_unadjusted)] #![feature(adx_target_feature)] +#![feature(maybe_uninit)] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 2f350df2f5c18..12b7adb8a9d26 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -547,6 +547,23 @@ macro_rules! unimplemented { ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); } +/// A macro to create an array of [`MaybeUninit`] +/// +/// This macro constructs and uninitialized array of the type `[MaybeUninit; N]`. +/// +/// [`MaybeUninit`]: mem/union.MaybeUninit.html +#[macro_export] +#[unstable(feature = "maybe_uninit", issue = "53491")] +macro_rules! uninitialized_array { + // This `into_inner` is safe because an array of `MaybeUninit` does not + // require initialization. + // FIXME(#49147): Could be replaced by an array initializer, once those can + // be any const expression. + ($t:ty; $size:expr) => (unsafe { + MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_inner() + }); +} + /// Built-in macros to the compiler itself. /// /// These macros do not have any corresponding definition with a `macro_rules!` diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index 8eb6a4d54c0f6..2ff67a4934f74 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -216,21 +216,14 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize let mut block_l = BLOCK; let mut start_l = ptr::null_mut(); let mut end_l = ptr::null_mut(); - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - let mut offsets_l: [MaybeUninit; BLOCK] = unsafe { - MaybeUninit::uninitialized().into_inner() - }; + let mut offsets_l: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; // The current block on the right side (from `r.sub(block_r)` to `r`). let mut r = unsafe { l.add(v.len()) }; let mut block_r = BLOCK; let mut start_r = ptr::null_mut(); let mut end_r = ptr::null_mut(); - let mut offsets_r: [MaybeUninit; BLOCK] = unsafe { - MaybeUninit::uninitialized().into_inner() - }; + let mut offsets_r: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient. From 0e8fb93249ee63edba83cd7f2f5f1b09819efa15 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jan 2019 10:49:11 +0100 Subject: [PATCH 14/18] Use warn() for extra diagnostics; with -D warnings this leads to errors This is needed to properly respect "deny_warnings = false" in config.toml --- src/liballoc/lib.rs | 4 ++-- src/libcore/lib.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index cf9d89ee05adf..d2ff1bae63561 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -64,8 +64,8 @@ #![needs_allocator] #![warn(deprecated_in_future)] -#![deny(intra_doc_link_resolution_failure)] -#![deny(missing_debug_implementations)] +#![warn(intra_doc_link_resolution_failure)] +#![warn(missing_debug_implementations)] #![cfg_attr(not(test), feature(fn_traits))] #![cfg_attr(not(test), feature(generator_trait))] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 1295acb44a543..1ef21832592ca 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -61,9 +61,9 @@ #![no_core] #![warn(deprecated_in_future)] -#![deny(missing_docs)] -#![deny(intra_doc_link_resolution_failure)] -#![deny(missing_debug_implementations)] +#![warn(missing_docs)] +#![warn(intra_doc_link_resolution_failure)] +#![warn(missing_debug_implementations)] #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] From 33a969d9faa6d935895a82cbe6e96ee83ba36b88 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jan 2019 11:04:30 +0100 Subject: [PATCH 15/18] fix typos, improve docs --- src/libcore/mem.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 4631d32d186f6..fdee86064e620 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1149,14 +1149,14 @@ impl MaybeUninit { unsafe { &mut *self.value as *mut T } } - /// Get a pointer to the first contained values. + /// Get a pointer to the first element of the array. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] pub fn first_ptr(this: &[MaybeUninit]) -> *const T { this as *const [MaybeUninit] as *const T } - /// Get a mutable pointer to the first contained values. + /// Get a mutable pointer to the first element of the array. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] pub fn first_mut_ptr(this: &mut [MaybeUninit]) -> *mut T { From 6a52ca3fb465544f62cee70bec9499b967939cc9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jan 2019 12:37:29 +0100 Subject: [PATCH 16/18] rename first_mut_ptr -> first_ptr_mut --- src/liballoc/collections/btree/node.rs | 10 +++++----- src/libcore/fmt/num.rs | 2 +- src/libcore/mem.rs | 2 +- src/libcore/slice/sort.rs | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 25810d680fa4b..e969e119dbe88 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -650,7 +650,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } else { unsafe { slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut (*self.as_leaf_mut()).keys), + MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys), self.len() ) } @@ -661,7 +661,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { debug_assert!(!self.is_shared_root()); unsafe { slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut (*self.as_leaf_mut()).vals), + MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).vals), self.len() ) } @@ -749,7 +749,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { slice_insert(self.vals_mut(), 0, val); slice_insert( slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut self.as_internal_mut().edges), + MaybeUninit::first_ptr_mut(&mut self.as_internal_mut().edges), self.len()+1 ), 0, @@ -808,7 +808,7 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { ForceResult::Internal(mut internal) => { let edge = slice_remove( slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut internal.as_internal_mut().edges), + MaybeUninit::first_ptr_mut(&mut internal.as_internal_mut().edges), old_len+1 ), 0 @@ -1087,7 +1087,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: slice_insert( slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut self.node.as_internal_mut().edges), + MaybeUninit::first_ptr_mut(&mut self.node.as_internal_mut().edges), self.node.len() ), self.idx + 1, diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 5283c6d7ef347..3a812337bb111 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -200,7 +200,7 @@ macro_rules! impl_Display { }; let mut buf = uninitialized_array![u8; 39]; let mut curr = buf.len() as isize; - let buf_ptr = MaybeUninit::first_mut_ptr(&mut buf); + let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); unsafe { diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index fdee86064e620..8b6d9d882b5ad 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1159,7 +1159,7 @@ impl MaybeUninit { /// Get a mutable pointer to the first element of the array. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub fn first_mut_ptr(this: &mut [MaybeUninit]) -> *mut T { + pub fn first_ptr_mut(this: &mut [MaybeUninit]) -> *mut T { this as *mut [MaybeUninit] as *mut T } } diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index 2ff67a4934f74..3f84faa049939 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -262,8 +262,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_l == end_l { // Trace `block_l` elements from the left side. - start_l = MaybeUninit::first_mut_ptr(&mut offsets_l); - end_l = MaybeUninit::first_mut_ptr(&mut offsets_l); + start_l = MaybeUninit::first_ptr_mut(&mut offsets_l); + end_l = MaybeUninit::first_ptr_mut(&mut offsets_l); let mut elem = l; for i in 0..block_l { @@ -278,8 +278,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_r == end_r { // Trace `block_r` elements from the right side. - start_r = MaybeUninit::first_mut_ptr(&mut offsets_r); - end_r = MaybeUninit::first_mut_ptr(&mut offsets_r); + start_r = MaybeUninit::first_ptr_mut(&mut offsets_r); + end_r = MaybeUninit::first_ptr_mut(&mut offsets_r); let mut elem = r; for i in 0..block_r { From a2b75eda955a46ec643b8277b1fb41c4fed94f4e Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 28 Jan 2019 09:30:43 -0600 Subject: [PATCH 17/18] review comments --- src/librustc/diagnostics.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index dd5144b1568fb..21aa4d7d15061 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -363,7 +363,7 @@ struct Foo1 { x: &bool } struct Foo2<'a> { x: &'a bool } // correct impl Foo2 {} - // ^ expected lifetime parameter + // ^^^^ expected lifetime parameter impl<'a> Foo2<'a> {} // correct struct Bar1 { x: Foo2 } @@ -770,40 +770,40 @@ struct Foo { These can be fixed by declaring lifetime parameters: ``` -fn foo<'a>(x: &'a str) {} - struct Foo<'a> { x: &'a str, } + +fn foo<'a>(x: &'a str) {} ``` Impl blocks declare lifetime parameters separately. You need to add lifetime parameters to an impl block if you're implementing a type that has a lifetime parameter of its own. For example: - + ```compile_fail,E0261 +struct Foo<'a> { + x: &'a str, +} + // error, use of undeclared lifetime name `'a` impl Foo<'a> { fn foo<'a>(x: &'a str) {} } - -struct Foo<'a> { - x: &'a str, -} ``` -This is fixed by declaring impl block like this: +This is fixed by declaring the impl block like this: ``` +struct Foo<'a> { + x: &'a str, +} + // correct impl<'a> Foo<'a> { fn foo(x: &'a str) {} } - -struct Foo<'a> { - x: &'a str, -} ``` "##, From 489a79247ddf5da8090019ff4da4b688ad55afa7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jan 2019 17:33:29 +0100 Subject: [PATCH 18/18] fix gdb debug printing --- src/etc/gdb_rust_pretty_printing.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index b9413563fd9ff..a6b09722e1c94 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -330,19 +330,20 @@ def children_of_node(boxed_node, height, want_values): leaf = node_ptr['data'] else: leaf = node_ptr.dereference() - keys = leaf['keys']['value']['value'] + keys = leaf['keys'] if want_values: - values = leaf['vals']['value']['value'] + values = leaf['vals'] length = int(leaf['len']) for i in xrange(0, length + 1): if height > 0: - for child in children_of_node(node_ptr['edges'][i], height - 1, want_values): + child_ptr = node_ptr['edges'][i]['value']['value'] + for child in children_of_node(child_ptr, height - 1, want_values): yield child if i < length: if want_values: - yield (keys[i], values[i]) + yield (keys[i]['value']['value'], values[i]['value']['value']) else: - yield keys[i] + yield keys[i]['value']['value'] class RustStdBTreeSetPrinter(object): def __init__(self, val):