From c08902b084081867ee437d621e605d231d2ba109 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 15:21:36 +0000 Subject: [PATCH 01/39] Prevent deprecation warning for items deprecated in the future --- src/librustc/middle/stability.rs | 36 ++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 29c8ac046b815..652920f95c3cb 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -559,9 +559,41 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { + fn deprecation_in_effect(since: Option<&str>, rustc: Option<&str>) -> bool { + fn parse_version(ver: &str) -> Vec { + // We ignore non-integer components of the version (e.g. "nightly"). + ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect() + } + + if since.is_none() || rustc.is_none() { + // By default, a deprecation warning applies to + // the current version of the compiler. + true + } else { + let since: Vec = parse_version(since.unwrap()); + let rustc: Vec = parse_version(rustc.unwrap()); + // We simply treat invalid `since` attributes as relating to a previous + // Rust version, thus always displaying the warning. + if since.len() != 3 { + return true; + } + since <= rustc + } + } + + // If the deprecation is scheduled for a future Rust + // version, then we should display no warning message. + let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since { + let since = sym.as_str(); + !deprecation_in_effect(Some(since.as_ref()), option_env!("CFG_RELEASE")) + } else { + false + }; + let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id)); - let skip = self.lookup_deprecation_entry(parent_def_id) - .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); + let skip = deprecated_in_future_version || + self.lookup_deprecation_entry(parent_def_id) + .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); if !skip { lint_deprecated(def_id, id, depr_entry.attr.note); } From ecaf1f57eaeca759528f1ef99017a7ee4763e307 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 15:51:11 +0000 Subject: [PATCH 02/39] Add future deprecation warning to rustdoc --- src/librustc/middle/stability.rs | 48 +++++++++++++++++--------------- src/librustdoc/html/render.rs | 22 ++++++++++++--- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 652920f95c3cb..d1202b59e04f5 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -470,6 +470,30 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor()); } +/// Check whether an item marked with `deprecated(since="X")` is currently +/// deprecated (i.e. whether X is not greater than the current rustc version). +pub fn deprecation_in_effect(since: &str) -> bool { + fn parse_version(ver: &str) -> Vec { + // We ignore non-integer components of the version (e.g. "nightly"). + ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect() + } + + if let Some(rustc) = option_env!("CFG_RELEASE") { + let since: Vec = parse_version(since); + let rustc: Vec = parse_version(rustc); + // We simply treat invalid `since` attributes as relating to a previous + // Rust version, thus always displaying the warning. + if since.len() != 3 { + return true; + } + since <= rustc + } else { + // By default, a deprecation warning applies to + // the current version of the compiler. + true + } +} + struct Checker<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } @@ -559,33 +583,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { - fn deprecation_in_effect(since: Option<&str>, rustc: Option<&str>) -> bool { - fn parse_version(ver: &str) -> Vec { - // We ignore non-integer components of the version (e.g. "nightly"). - ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect() - } - - if since.is_none() || rustc.is_none() { - // By default, a deprecation warning applies to - // the current version of the compiler. - true - } else { - let since: Vec = parse_version(since.unwrap()); - let rustc: Vec = parse_version(rustc.unwrap()); - // We simply treat invalid `since` attributes as relating to a previous - // Rust version, thus always displaying the warning. - if since.len() != 3 { - return true; - } - since <= rustc - } - } - // If the deprecation is scheduled for a future Rust // version, then we should display no warning message. let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since { let since = sym.as_str(); - !deprecation_in_effect(Some(since.as_ref()), option_env!("CFG_RELEASE")) + !deprecation_in_effect(since.as_ref()) } else { false }; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 678e1762a5519..5c7825f2dd623 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2108,9 +2108,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec{}", text)) }; @@ -2160,7 +2166,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec{}", text)) } From 101e17df96f528bba1ea661751edc65175bc9e3c Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 17:02:04 +0000 Subject: [PATCH 03/39] Add tests for items deprecated in the future --- src/test/compile-fail/deprecation-lint.rs | 8 ++++++++ src/test/rustdoc/deprecated-future.rs | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/test/rustdoc/deprecated-future.rs diff --git a/src/test/compile-fail/deprecation-lint.rs b/src/test/compile-fail/deprecation-lint.rs index a058234a64921..93eb6b6b11544 100644 --- a/src/test/compile-fail/deprecation-lint.rs +++ b/src/test/compile-fail/deprecation-lint.rs @@ -180,6 +180,11 @@ mod this_crate { #[deprecated(since = "1.0.0", note = "text")] pub fn deprecated_text() {} + #[deprecated(since = "99.99.99", note = "text")] + pub fn deprecated_future() {} + #[deprecated(since = "99.99.99", note = "text")] + pub fn deprecated_future_text() {} + pub struct MethodTester; impl MethodTester { @@ -266,6 +271,9 @@ mod this_crate { ::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text ::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + deprecated_future(); // Fine; no error. + deprecated_future_text(); // Fine; no error. + let _ = DeprecatedStruct { //~^ ERROR use of deprecated item 'this_crate::DeprecatedStruct': text i: 0 //~ ERROR use of deprecated item 'this_crate::DeprecatedStruct::i': text diff --git a/src/test/rustdoc/deprecated-future.rs b/src/test/rustdoc/deprecated-future.rs new file mode 100644 index 0000000000000..6ba54039ed3f7 --- /dev/null +++ b/src/test/rustdoc/deprecated-future.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(deprecated)] + +// @has deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \ +// 'This will be deprecated in 99.99.99: effectively never' +#[deprecated(since = "99.99.99", note = "effectively never")] +pub struct S; From 7fdee5deb9e9457dc7b6cacd1cd7006d7ffc585a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 30 Mar 2018 15:43:22 +0200 Subject: [PATCH 04/39] fix targetted value background --- src/librustdoc/html/static/themes/dark.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 2d0fe55f70d26..09776569f80bf 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -239,7 +239,7 @@ a.test-arrow:hover{ } :target > code { - background: #FDFFD3; + background-color: #494a3d; } pre.compile_fail { From adaaeeaee341d9cc4472afc8287704dd5cea521e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 30 Mar 2018 16:10:05 +0200 Subject: [PATCH 05/39] Add missing anchor for union type fields --- src/librustdoc/html/render.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index ff6cc56e5b4f5..38696bb71493d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2801,10 +2801,15 @@ fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, write!(w, "

Fields

")?; for (field, ty) in fields { - write!(w, "{name}: {ty} + let name = field.name.as_ref().expect("union field name"); + let id = format!("{}.{}", ItemType::StructField, name); + write!(w, "\ + \ + \ ", + id = id, + name = name, shortty = ItemType::StructField, - name = field.name.as_ref().unwrap(), ty = ty)?; if let Some(stability_class) = field.stability_class() { write!(w, "", From d0eeb291dddb99ad6f2aedafa5355556b40e483f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 30 Mar 2018 14:20:16 +0200 Subject: [PATCH 06/39] Add support for variant and types fields for intra links --- src/librustdoc/clean/mod.rs | 25 +++++++++++++++++++++--- src/test/rustdoc/struct-field.rs | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/test/rustdoc/struct-field.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3a79c14f4ec2a..bff22292cc0a4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1013,8 +1013,7 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option let ty = cx.resolver.borrow_mut() .with_scope(*id, |resolver| { - resolver.resolve_str_path_error(DUMMY_SP, - &path, false) + resolver.resolve_str_path_error(DUMMY_SP, &path, false) })?; match ty.def { Def::Struct(did) | Def::Union(did) | Def::Enum(did) | Def::TyAlias(did) => { @@ -1029,7 +1028,27 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option }; Ok((ty.def, Some(format!("{}.{}", out, item_name)))) } else { - Err(()) + let is_enum = match ty.def { + Def::Enum(_) => true, + _ => false, + }; + let elem = if is_enum { + cx.tcx.adt_def(did).all_fields().find(|item| item.name == item_name) + } else { + cx.tcx.adt_def(did) + .non_enum_variant() + .fields + .iter() + .find(|item| item.name == item_name) + }; + if let Some(item) = elem { + Ok((ty.def, + Some(format!("{}.{}", + if is_enum { "variant" } else { "structfield" }, + item.name)))) + } else { + Err(()) + } } } Def::Trait(did) => { diff --git a/src/test/rustdoc/struct-field.rs b/src/test/rustdoc/struct-field.rs new file mode 100644 index 0000000000000..c5016bac7d394 --- /dev/null +++ b/src/test/rustdoc/struct-field.rs @@ -0,0 +1,33 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +// ignore-tidy-linelength + +// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/struct.Foo.html#structfield.bar"]' 'Foo::bar' +// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/union.Bar.html#structfield.foo"]' 'Bar::foo' +// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/enum.Uniooon.html#X.v"]' 'Uniooon::X' + +//! Test with [Foo::bar], [Bar::foo], [Uniooon::X] + +pub struct Foo { + pub bar: usize, +} + +pub union Bar { + pub foo: u32, +} + +pub enum Uniooon { + F, + X, + Y, +} From fa1d125ae6b8dd4a472510ef3478daaff831ae2c Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 31 Mar 2018 00:50:53 -0400 Subject: [PATCH 07/39] Add test for rustdoc ignore test This will check for regression on issue #32556 --- src/test/rustdoc/issue-32556.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/rustdoc/issue-32556.rs diff --git a/src/test/rustdoc/issue-32556.rs b/src/test/rustdoc/issue-32556.rs new file mode 100644 index 0000000000000..a9f191989fe35 --- /dev/null +++ b/src/test/rustdoc/issue-32556.rs @@ -0,0 +1,17 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// Blah blah blah +/// ``` ignore +/// bad_assert!(); +/// ``` +pub fn foo() {} + + From 48e3c961eb9d659217416490b02a7417f338c3fa Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 31 Mar 2018 01:26:02 -0400 Subject: [PATCH 08/39] Fix tidy trailing newlines --- src/test/rustdoc/issue-32556.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/rustdoc/issue-32556.rs b/src/test/rustdoc/issue-32556.rs index a9f191989fe35..f08a548efe27d 100644 --- a/src/test/rustdoc/issue-32556.rs +++ b/src/test/rustdoc/issue-32556.rs @@ -13,5 +13,3 @@ /// bad_assert!(); /// ``` pub fn foo() {} - - From fb7deda27419eae61da3cbf5a5b1b4f51ae16d04 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 30 Mar 2018 23:06:05 -0700 Subject: [PATCH 09/39] Add #[must_use] to a few standard library methods Chosen to start a precedent of using it on ones that are potentially-expensive and where using it for side effects is particularly discouraged. Discuss :) --- src/liballoc/borrow.rs | 1 + src/libcore/clone.rs | 1 + src/libcore/iter/iterator.rs | 1 + src/librustc_mir/build/mod.rs | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index acae0daa86b6b..c6741ddb822d5 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -59,6 +59,7 @@ pub trait ToOwned { /// let vv: Vec = v.to_owned(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[must_use = "cloning is often expensive and is not expected to have side effects"] fn to_owned(&self) -> Self::Owned; /// Uses borrowed data to replace owned data, usually by cloning. diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index d25f498b99efe..c175ae15d28fe 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -105,6 +105,7 @@ pub trait Clone : Sized { /// assert_eq!("Hello", hello.clone()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[must_use = "cloning is often expensive and is not expected to have side effects"] fn clone(&self) -> Self; /// Performs copy-assignment from `source`. diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 31f77f92435d8..42fd90512923b 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1368,6 +1368,7 @@ pub trait Iterator { /// [`Result`]: ../../std/result/enum.Result.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] fn collect>(self) -> B where Self: Sized { FromIterator::from_iter(self) } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 8494c043f90fc..6f5fcc9e421cc 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -317,7 +317,7 @@ newtype_index!(ScopeId); /// macro (and methods below) makes working with `BlockAnd` much more /// convenient. -#[must_use] // if you don't use one of these results, you're leaving a dangling edge +#[must_use = "if you don't use one of these results, you're leaving a dangling edge"] struct BlockAnd(BasicBlock, T); trait BlockAndExtension { From 42bc0712f127906bca9063a6659c18aea2ddd9da Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 31 Mar 2018 16:08:58 -0400 Subject: [PATCH 10/39] Remove whitespace --- src/test/rustdoc/issue-32556.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/rustdoc/issue-32556.rs b/src/test/rustdoc/issue-32556.rs index f08a548efe27d..c08c2d6e162ac 100644 --- a/src/test/rustdoc/issue-32556.rs +++ b/src/test/rustdoc/issue-32556.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -9,7 +9,7 @@ // except according to those terms. /// Blah blah blah -/// ``` ignore +/// ```ignore /// bad_assert!(); /// ``` pub fn foo() {} From cb3097567f92adc32f15c1cc4619220e3c98505b Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 31 Mar 2018 16:23:50 -0400 Subject: [PATCH 11/39] Add ignore reason --- src/test/rustdoc/issue-32556.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/rustdoc/issue-32556.rs b/src/test/rustdoc/issue-32556.rs index c08c2d6e162ac..3ab138079a1f0 100644 --- a/src/test/rustdoc/issue-32556.rs +++ b/src/test/rustdoc/issue-32556.rs @@ -9,7 +9,7 @@ // except according to those terms. /// Blah blah blah -/// ```ignore +/// ```ignore (testing rustdoc's handling of ignore) /// bad_assert!(); /// ``` pub fn foo() {} From 44ad8fd1360244c873ee18786b02542627752727 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 31 Mar 2018 18:31:22 +0100 Subject: [PATCH 12/39] Shorten deprecation note --- src/librustdoc/html/render.rs | 4 ++-- src/test/rustdoc/deprecated-future.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5c7825f2dd623..194e301af3dd4 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2113,7 +2113,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec Vec Date: Sat, 31 Mar 2018 20:35:11 -0400 Subject: [PATCH 13/39] Unignore borrowck test Unignores a test that has been fixed. See #44831 --- .../borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/compile-fail/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs b/src/test/compile-fail/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs index df0a05dfaee0e..f2e6d51d064d1 100644 --- a/src/test/compile-fail/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs +++ b/src/test/compile-fail/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-test will be fixed later // revisions: ast mir //[mir]compile-flags: -Z borrowck=mir From 7a28ffce90271b82f89fd6a3fa110b5c25795ce2 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 31 Mar 2018 12:47:49 +0200 Subject: [PATCH 14/39] Fix miri Discriminant() for non-ADT --- src/librustc_mir/interpret/eval_context.rs | 29 ++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b8bfcd756cd23..cf3241fe9be66 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -743,20 +743,29 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M Discriminant(ref place) => { let ty = self.place_ty(place); + let layout = self.layout_of(ty)?; let place = self.eval_place(place)?; let discr_val = self.read_discriminant_value(place, ty)?; - if let ty::TyAdt(adt_def, _) = ty.sty { - trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(*self.tcx).collect::>()); - if adt_def.discriminants(*self.tcx).all(|v| { - discr_val != v.val - }) - { - return err!(InvalidDiscriminant); + match layout.variants { + layout::Variants::Single { index } => { + assert_eq!(discr_val, index as u128); + } + layout::Variants::Tagged { .. } | + layout::Variants::NicheFilling { .. } => { + if let ty::TyAdt(adt_def, _) = ty.sty { + trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(*self.tcx).collect::>()); + if adt_def.discriminants(*self.tcx).all(|v| { + discr_val != v.val + }) + { + return err!(InvalidDiscriminant); + } + } else { + bug!("rustc only generates Rvalue::Discriminant for enums"); + } } - self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?; - } else { - bug!("rustc only generates Rvalue::Discriminant for enums"); } + self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?; } } From 8f9ec1cb06524a483b1bfc81c9912ebb7d46cb52 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 2 Apr 2018 00:14:44 +0300 Subject: [PATCH 15/39] avoid IdxSets containing garbage above the universe length This makes sure that all bits in each IdxSet between the universe length and the end of the word are all zero instead of being in an indeterminate state. This fixes a crash with RUST_LOG=rustc_mir, and is probably a good idea anyway. --- src/librustc_data_structures/indexed_set.rs | 74 ++++++++++++++++++++- src/librustc_mir/dataflow/impls/mod.rs | 4 +- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/librustc_data_structures/indexed_set.rs b/src/librustc_data_structures/indexed_set.rs index 7ab6a2691488e..c9495587c4687 100644 --- a/src/librustc_data_structures/indexed_set.rs +++ b/src/librustc_data_structures/indexed_set.rs @@ -121,7 +121,9 @@ impl IdxSetBuf { /// Creates set holding every element whose index falls in range 0..universe_size. pub fn new_filled(universe_size: usize) -> Self { - Self::new(!0, universe_size) + let mut result = Self::new(!0, universe_size); + result.trim_to(universe_size); + result } /// Creates set holding no elements. @@ -168,6 +170,36 @@ impl IdxSet { } } + /// Sets all elements up to `universe_size` + pub fn set_up_to(&mut self, universe_size: usize) { + for b in &mut self.bits { + *b = !0; + } + self.trim_to(universe_size); + } + + /// Clear all elements above `universe_size`. + fn trim_to(&mut self, universe_size: usize) { + let word_bits = mem::size_of::() * 8; + + // `trim_block` is the first block where some bits have + // to be cleared. + let trim_block = universe_size / word_bits; + + // all the blocks above it have to be completely cleared. + if trim_block < self.bits.len() { + for b in &mut self.bits[trim_block+1..] { + *b = 0; + } + + // at that block, the `universe_size % word_bits` lsbs + // should remain. + let remaining_bits = universe_size % word_bits; + let mask = (1< bool { self.bits.clear_bit(elem.index()) @@ -252,3 +284,43 @@ impl<'a, T: Idx> Iterator for Iter<'a, T> { } } } + +#[test] +fn test_trim_to() { + use std::cmp; + + for i in 0..256 { + let mut idx_buf: IdxSetBuf = IdxSetBuf::new_filled(128); + idx_buf.trim_to(i); + + let elems: Vec = idx_buf.iter().collect(); + let expected: Vec = (0..cmp::min(i, 128)).collect(); + assert_eq!(elems, expected); + } +} + +#[test] +fn test_set_up_to() { + for i in 0..128 { + for mut idx_buf in + vec![IdxSetBuf::new_empty(128), IdxSetBuf::new_filled(128)] + .into_iter() + { + idx_buf.set_up_to(i); + + let elems: Vec = idx_buf.iter().collect(); + let expected: Vec = (0..i).collect(); + assert_eq!(elems, expected); + } + } +} + +#[test] +fn test_new_filled() { + for i in 0..128 { + let mut idx_buf = IdxSetBuf::new_filled(i); + let elems: Vec = idx_buf.iter().collect(); + let expected: Vec = (0..i).collect(); + assert_eq!(elems, expected); + } +} diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index c5f5492cd2c2c..287640439c0e8 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -389,7 +389,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> // sets on_entry bits for Arg places fn start_block_effect(&self, entry_set: &mut IdxSet) { // set all bits to 1 (uninit) before gathering counterevidence - for e in entry_set.words_mut() { *e = !0; } + entry_set.set_up_to(self.bits_per_block()); drop_flag_effects_for_function_entry( self.tcx, self.mir, self.mdpe, @@ -443,7 +443,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedPlaces<'a, 'gcx, 'tc // sets on_entry bits for Arg places fn start_block_effect(&self, entry_set: &mut IdxSet) { - for e in entry_set.words_mut() { *e = 0; } + entry_set.clear(); drop_flag_effects_for_function_entry( self.tcx, self.mir, self.mdpe, From 196b1426bec62b590df790c5f715d46075e01840 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Sun, 1 Apr 2018 22:50:22 -0600 Subject: [PATCH 16/39] Stabilize String::replace_range Fixes #44643 --- src/liballoc/string.rs | 11 +++++------ src/liballoc/tests/string.rs | 30 +++++++++++++++--------------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index aa202e2362892..b95aae02894ed 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1517,7 +1517,7 @@ impl String { } } - /// Creates a splicing iterator that removes the specified range in the string, + /// Removes the specified range in the string, /// and replaces it with the given string. /// The given string doesn't need to be the same length as the range. /// @@ -1537,21 +1537,20 @@ impl String { /// Basic usage: /// /// ``` - /// #![feature(splice)] /// let mut s = String::from("α is alpha, β is beta"); /// let beta_offset = s.find('β').unwrap_or(s.len()); /// /// // Replace the range up until the β from the string - /// s.splice(..beta_offset, "Α is capital alpha; "); + /// s.replace_range(..beta_offset, "Α is capital alpha; "); /// assert_eq!(s, "Α is capital alpha; β is beta"); /// ``` - #[unstable(feature = "splice", reason = "recently added", issue = "44643")] - pub fn splice(&mut self, range: R, replace_with: &str) + #[stable(feature = "splice", since = "1.27.0")] + pub fn replace_range(&mut self, range: R, replace_with: &str) where R: RangeBounds { // Memory safety // - // The String version of Splice does not have the memory safety issues + // Replace_range does not have the memory safety issues of a vector Splice. // of the vector version. The data is just plain bytes. match range.start() { diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index d1e746ea43b45..cb4a17a22d8a4 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -443,53 +443,53 @@ fn test_drain() { } #[test] -fn test_splice() { +fn test_replace_range() { let mut s = "Hello, world!".to_owned(); - s.splice(7..12, "世界"); + s.replace_range(7..12, "世界"); assert_eq!(s, "Hello, 世界!"); } #[test] #[should_panic] -fn test_splice_char_boundary() { +fn test_replace_range_char_boundary() { let mut s = "Hello, 世界!".to_owned(); - s.splice(..8, ""); + s.replace_range(..8, ""); } #[test] -fn test_splice_inclusive_range() { +fn test_replace_range_inclusive_range() { let mut v = String::from("12345"); - v.splice(2..=3, "789"); + v.replace_range(2..=3, "789"); assert_eq!(v, "127895"); - v.splice(1..=2, "A"); + v.replace_range(1..=2, "A"); assert_eq!(v, "1A895"); } #[test] #[should_panic] -fn test_splice_out_of_bounds() { +fn test_replace_range_out_of_bounds() { let mut s = String::from("12345"); - s.splice(5..6, "789"); + s.replace_range(5..6, "789"); } #[test] #[should_panic] -fn test_splice_inclusive_out_of_bounds() { +fn test_replace_range_inclusive_out_of_bounds() { let mut s = String::from("12345"); - s.splice(5..=5, "789"); + s.replace_range(5..=5, "789"); } #[test] -fn test_splice_empty() { +fn test_replace_range_empty() { let mut s = String::from("12345"); - s.splice(1..2, ""); + s.replace_range(1..2, ""); assert_eq!(s, "1345"); } #[test] -fn test_splice_unbounded() { +fn test_replace_range_unbounded() { let mut s = String::from("12345"); - s.splice(.., ""); + s.replace_range(.., ""); assert_eq!(s, ""); } From 85310860c25c8525c03b2ffe12674c1914917aa0 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 2 Apr 2018 09:10:44 -0700 Subject: [PATCH 17/39] Add performance note to fs::read docs --- src/libstd/fs.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 479e4d08f4b4d..7bd1adc411ae4 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -231,7 +231,9 @@ fn initial_buffer_size(file: &File) -> usize { /// Read the entire contents of a file into a bytes vector. /// /// This is a convenience function for using [`File::open`] and [`read_to_end`] -/// with fewer imports and without an intermediate variable. +/// with fewer imports and without an intermediate variable. It pre-allocates a +/// buffer based on the file size when available, so it is generally faster than +/// reading into a vector created with `Vec::new()`. /// /// [`File::open`]: struct.File.html#method.open /// [`read_to_end`]: ../io/trait.Read.html#method.read_to_end @@ -270,7 +272,9 @@ pub fn read>(path: P) -> io::Result> { /// Read the entire contents of a file into a string. /// /// This is a convenience function for using [`File::open`] and [`read_to_string`] -/// with fewer imports and without an intermediate variable. +/// with fewer imports and without an intermediate variable. It pre-allocates a +/// buffer based on the file size when available, so it is generally faster than +/// reading into a string created with `String::new()`. /// /// [`File::open`]: struct.File.html#method.open /// [`read_to_string`]: ../io/trait.Read.html#method.read_to_string From f9cc0307fec0c37941186d9588ef437268bd5c92 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 2 Apr 2018 18:52:04 +0200 Subject: [PATCH 18/39] Fix url for intra link provided method --- src/librustdoc/clean/mod.rs | 8 +++++- src/test/rustdoc/default-trait-method-link.rs | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc/default-trait-method-link.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e3ba482eecfee..49596732d2f2f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1101,7 +1101,13 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option let kind = match item.kind { ty::AssociatedKind::Const if is_val => "associatedconstant", ty::AssociatedKind::Type if !is_val => "associatedtype", - ty::AssociatedKind::Method if is_val => "tymethod", + ty::AssociatedKind::Method if is_val => { + if item.defaultness.has_value() { + "method" + } else { + "tymethod" + } + } _ => return Err(()) }; diff --git a/src/test/rustdoc/default-trait-method-link.rs b/src/test/rustdoc/default-trait-method-link.rs new file mode 100644 index 0000000000000..9cde446eb941e --- /dev/null +++ b/src/test/rustdoc/default-trait-method-link.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +// @has foo/trait.Foo.html '//a[@href="../foo/trait.Foo.html#tymethod.req"]' 'req' +// @has foo/trait.Foo.html '//a[@href="../foo/trait.Foo.html#method.prov"]' 'prov' + +/// Always make sure to implement [`req`], but you don't have to implement [`prov`]. +/// +/// [`req`]: Foo::req +/// [`prov`]: Foo::prov +pub trait Foo { + /// Required + fn req(); + /// Provided + fn prov() {} +} From a2a0f21ba1d2d0d54e8a34d39d7435cbb4efe7e9 Mon Sep 17 00:00:00 2001 From: Rolf van de Krol Date: Mon, 2 Apr 2018 21:48:56 +0200 Subject: [PATCH 19/39] Fix typo --- src/libstd/io/buffered.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index cefff2f143ce7..3e9ae261ab649 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -180,7 +180,7 @@ impl BufReader { /// /// # Examples /// - /// ```no_ru + /// ```no_run /// # #![feature(bufreader_buffer)] /// use std::io::{BufReader, BufRead}; /// use std::fs::File; From b2ed9dd546e33ded4a80acd02e1710fe811936b2 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 2 Apr 2018 22:57:47 +0100 Subject: [PATCH 20/39] Replace as_ref with & --- src/librustc/middle/stability.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d1202b59e04f5..328b2db2b5828 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -587,7 +587,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // version, then we should display no warning message. let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since { let since = sym.as_str(); - !deprecation_in_effect(since.as_ref()) + !deprecation_in_effect(&since) } else { false }; From 1c8d10bce503bdd66921005dbd0b86a31745e5a7 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 2 Apr 2018 16:33:09 -0700 Subject: [PATCH 21/39] Stabilize iter_rfold in 1.27.0 --- src/liballoc/lib.rs | 1 - src/libcore/iter/traits.rs | 4 +--- src/libcore/tests/lib.rs | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index e6a311041f544..cbdb135c78c1c 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -100,7 +100,6 @@ #![feature(fundamental)] #![feature(generic_param_attrs)] #![cfg_attr(stage0, feature(i128_type))] -#![feature(iter_rfold)] #![feature(lang_items)] #![feature(needs_allocator)] #![feature(nonzero)] diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index c3aebc4fb23ce..f84dc98912f62 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -491,7 +491,6 @@ pub trait DoubleEndedIterator: Iterator { /// Basic usage: /// /// ``` - /// #![feature(iter_rfold)] /// let a = [1, 2, 3]; /// /// // the sum of all of the elements of a @@ -505,7 +504,6 @@ pub trait DoubleEndedIterator: Iterator { /// and continuing with each element from the back until the front: /// /// ``` - /// #![feature(iter_rfold)] /// let numbers = [1, 2, 3, 4, 5]; /// /// let zero = "0".to_string(); @@ -517,7 +515,7 @@ pub trait DoubleEndedIterator: Iterator { /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))"); /// ``` #[inline] - #[unstable(feature = "iter_rfold", issue = "44705")] + #[stable(feature = "iter_rfold", since = "1.27.0")] fn rfold(mut self, accum: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1a68f04532d20..e04968a635993 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -29,7 +29,6 @@ #![feature(iterator_flatten)] #![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(iter_rfind)] -#![feature(iter_rfold)] #![feature(iterator_repeat_with)] #![feature(nonzero)] #![feature(pattern)] From d8c4c83dadb3a8d539bf0f4ad8260bc87420ca37 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 2 Apr 2018 16:37:06 -0700 Subject: [PATCH 22/39] Stabilize iter_rfind in 1.27.0 --- src/libcore/iter/traits.rs | 8 ++------ src/libcore/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index f84dc98912f62..ee278651c8d12 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -522,7 +522,7 @@ pub trait DoubleEndedIterator: Iterator { self.try_rfold(accum, move |acc, x| AlwaysOk(f(acc, x))).0 } - /// Searches for an element of an iterator from the right that satisfies a predicate. + /// Searches for an element of an iterator from the back that satisfies a predicate. /// /// `rfind()` takes a closure that returns `true` or `false`. It applies /// this closure to each element of the iterator, starting at the end, and if any @@ -545,8 +545,6 @@ pub trait DoubleEndedIterator: Iterator { /// Basic usage: /// /// ``` - /// #![feature(iter_rfind)] - /// /// let a = [1, 2, 3]; /// /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2)); @@ -557,8 +555,6 @@ pub trait DoubleEndedIterator: Iterator { /// Stopping at the first `true`: /// /// ``` - /// #![feature(iter_rfind)] - /// /// let a = [1, 2, 3]; /// /// let mut iter = a.iter(); @@ -569,7 +565,7 @@ pub trait DoubleEndedIterator: Iterator { /// assert_eq!(iter.next_back(), Some(&1)); /// ``` #[inline] - #[unstable(feature = "iter_rfind", issue = "39480")] + #[stable(feature = "iter_rfind", since = "1.27.0")] fn rfind

(&mut self, mut predicate: P) -> Option where Self: Sized, P: FnMut(&Self::Item) -> bool diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index e04968a635993..8a34660d556bf 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -28,7 +28,6 @@ #![feature(iterator_try_fold)] #![feature(iterator_flatten)] #![cfg_attr(stage0, feature(conservative_impl_trait))] -#![feature(iter_rfind)] #![feature(iterator_repeat_with)] #![feature(nonzero)] #![feature(pattern)] From 9db63bb033271c7b9c9f4315eb6db3314758a33e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 2 Apr 2018 16:40:53 -0700 Subject: [PATCH 23/39] Stabilize iterator_try_fold in 1.27.0 --- src/libcore/iter/iterator.rs | 7 ++----- src/libcore/iter/traits.rs | 4 +--- src/libcore/tests/lib.rs | 1 - 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 31f77f92435d8..a54e0e0065565 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1446,7 +1446,6 @@ pub trait Iterator { /// Basic usage: /// /// ``` - /// #![feature(iterator_try_fold)] /// let a = [1, 2, 3]; /// /// // the checked sum of all of the elements of the array @@ -1458,7 +1457,6 @@ pub trait Iterator { /// Short-circuiting: /// /// ``` - /// #![feature(iterator_try_fold)] /// let a = [10, 20, 30, 100, 40, 50]; /// let mut it = a.iter(); /// @@ -1472,7 +1470,7 @@ pub trait Iterator { /// assert_eq!(it.next(), Some(&40)); /// ``` #[inline] - #[unstable(feature = "iterator_try_fold", issue = "45594")] + #[stable(feature = "iterator_try_fold", since = "1.27.0")] fn try_fold(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try { @@ -1495,7 +1493,6 @@ pub trait Iterator { /// # Examples /// /// ``` - /// #![feature(iterator_try_fold)] /// use std::fs::rename; /// use std::io::{stdout, Write}; /// use std::path::Path; @@ -1512,7 +1509,7 @@ pub trait Iterator { /// assert_eq!(it.next(), Some("stale_bread.json")); /// ``` #[inline] - #[unstable(feature = "iterator_try_fold", issue = "45594")] + #[stable(feature = "iterator_try_fold", since = "1.27.0")] fn try_for_each(&mut self, mut f: F) -> R where Self: Sized, F: FnMut(Self::Item) -> R, R: Try { diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index ee278651c8d12..ddbb59989424f 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -427,7 +427,6 @@ pub trait DoubleEndedIterator: Iterator { /// Basic usage: /// /// ``` - /// #![feature(iterator_try_fold)] /// let a = ["1", "2", "3"]; /// let sum = a.iter() /// .map(|&s| s.parse::()) @@ -438,7 +437,6 @@ pub trait DoubleEndedIterator: Iterator { /// Short-circuiting: /// /// ``` - /// #![feature(iterator_try_fold)] /// let a = ["1", "rust", "3"]; /// let mut it = a.iter(); /// let sum = it @@ -452,7 +450,7 @@ pub trait DoubleEndedIterator: Iterator { /// assert_eq!(it.next_back(), Some(&"1")); /// ``` #[inline] - #[unstable(feature = "iterator_try_fold", issue = "45594")] + #[stable(feature = "iterator_try_fold", since = "1.27.0")] fn try_rfold(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try { diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8a34660d556bf..16150cd82beb1 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -25,7 +25,6 @@ #![feature(iterator_step_by)] #![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] -#![feature(iterator_try_fold)] #![feature(iterator_flatten)] #![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(iterator_repeat_with)] From 58217edd2fbb9f51b5838c6da97ef8dc4bfdef33 Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Mon, 2 Apr 2018 17:21:37 -0700 Subject: [PATCH 24/39] run-pass/attr-stmt-expr: expand test cases --- .../proc-macro/attr-stmt-expr.rs | 14 +++++++++++++- .../proc-macro/auxiliary/attr-stmt-expr.rs | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs b/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs index 082dd63992968..98316c62ef135 100644 --- a/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs +++ b/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs @@ -14,7 +14,8 @@ #![feature(proc_macro, stmt_expr_attributes)] extern crate attr_stmt_expr; -use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr}; +use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr, + no_output, noop}; fn print_str(string: &'static str) { // macros are handled a bit differently @@ -29,6 +30,17 @@ fn main() { #[expect_print_stmt] println!("{}", string); + let _: () = { + #[no_output] + "Hello, world!" + }; + + let _: &'static str = #[noop] "Hello, world!"; + + let _: &'static str = { + #[noop] "Hello, world!" + }; + #[expect_expr] print_str("string") } diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs index 189e6bbd00dba..972368b7b532a 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs @@ -44,3 +44,18 @@ pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream { assert_eq!(item.to_string(), "println!(\"{}\" , string)"); item } + +#[proc_macro_attribute] +pub fn no_output(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert!(!item.to_string().is_empty()); + "".parse().unwrap() + +} + +#[proc_macro_attribute] +pub fn noop(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert!(!item.to_string().is_empty()); + item +} From 9ab5788e0e73d1d7edbc025627e34bb8d4fa9bdd Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Mon, 2 Apr 2018 19:34:06 -0600 Subject: [PATCH 25/39] Fix "since" version for getpid feature. It was stabilized right before the beta branch was cut for 1.26.0. See https://github.com/rust-lang/rust/pull/49523#issuecomment-377996315 --- src/libstd/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index b463a6d88fe8e..40bc84f4bc104 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1426,7 +1426,7 @@ pub fn abort() -> ! { /// ``` /// /// -#[stable(feature = "getpid", since = "1.27.0")] +#[stable(feature = "getpid", since = "1.26.0")] pub fn id() -> u32 { ::sys::os::getpid() } From e75c6a741eded857b2ab06b63ebd3848d9203343 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Mon, 2 Apr 2018 19:41:22 -0600 Subject: [PATCH 26/39] Remove splice page from unstable book. --- .../src/library-features/splice.md | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/splice.md diff --git a/src/doc/unstable-book/src/library-features/splice.md b/src/doc/unstable-book/src/library-features/splice.md deleted file mode 100644 index 2e4bb1a5257c9..0000000000000 --- a/src/doc/unstable-book/src/library-features/splice.md +++ /dev/null @@ -1,22 +0,0 @@ -# `splice` - -The tracking issue for this feature is: [#44643] - -[#44643]: https://github.com/rust-lang/rust/issues/44643 - ------------------------- - -The `splice()` method on `String` allows you to replace a range -of values in a string with another range of values. - -A simple example: - -```rust -#![feature(splice)] -let mut s = String::from("α is alpha, β is beta"); -let beta_offset = s.find('β').unwrap_or(s.len()); - -// Replace the range up until the β from the string -s.splice(..beta_offset, "Α is capital alpha; "); -assert_eq!(s, "Α is capital alpha; β is beta"); -``` From f5c42655b597d37c2e79ac48e60ef4b796d84e3e Mon Sep 17 00:00:00 2001 From: Vadzim Dambrouski Date: Tue, 3 Apr 2018 15:33:18 +0300 Subject: [PATCH 27/39] Fix warning when compilin libcore on 16bit targets. Fixes #49617 --- src/libcore/iter/range.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 72b48b565719c..5d57207763e47 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -488,6 +488,7 @@ macro_rules! try_from_unbounded { } // unsigned to signed (only positive bound) +#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] macro_rules! try_from_upper_bounded { ($($target:ty),*) => {$( impl PrivateTryFromUsize for $target { From 93a3e93bf3015df01f9759ab4ca4fd7a6932d8a1 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Tue, 3 Apr 2018 09:11:41 -0400 Subject: [PATCH 28/39] tweak fmt::Arguments docs Remove an outdated claim about passing something or other to a function. Also swap the variable names in the example. --- src/libcore/fmt/mod.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 62994ed15cc6d..d55219d7226e6 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -401,10 +401,9 @@ impl<'a> Arguments<'a> { /// safely be done, so no constructors are given and the fields are private /// to prevent modification. /// -/// The [`format_args!`] macro will safely create an instance of this structure -/// and pass it to a function or closure, passed as the first argument. The -/// macro validates the format string at compile-time so usage of the [`write`] -/// and [`format`] functions can be safely performed. +/// The [`format_args!`] macro will safely create an instance of this structure. +/// The macro validates the format string at compile-time so usage of the +/// [`write`] and [`format`] functions can be safely performed. /// /// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug` /// and `Display` contexts as seen below. The example also shows that `Debug` @@ -412,8 +411,8 @@ impl<'a> Arguments<'a> { /// in `format_args!`. /// /// ```rust -/// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); -/// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2)); +/// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); +/// let display = format!("{}", format_args!("{} foo {:?}", 1, 2)); /// assert_eq!("1 foo 2", display); /// assert_eq!(display, debug); /// ``` From 333b0a0471c2593e46c8f13124ee28178f5c9643 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Tue, 3 Apr 2018 09:20:04 -0400 Subject: [PATCH 29/39] tweak format_args! docs Swap the variable names in the example. --- src/libstd/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 47609f17221ef..5ef7c15965505 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -341,8 +341,8 @@ pub mod builtin { /// format string in `format_args!`. /// /// ```rust - /// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); - /// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2)); + /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); + /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2)); /// assert_eq!("1 foo 2", display); /// assert_eq!(display, debug); /// ``` From da0ceeff5a7839427c751cf056e16e67217b12ea Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 1 Apr 2018 16:55:25 +0200 Subject: [PATCH 30/39] Introduce Vec::resize_with method (see #41758) --- src/liballoc/vec.rs | 64 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 2eedb964f88ba..0fd4178bd95f1 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1306,6 +1306,49 @@ impl Vec { } other } + + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. + /// + /// If `new_len` is greater than `len`, the `Vec` is extended by the + /// difference, with each additional slot filled with the result of + /// calling the closure `f`. The return values from `f` will end up + /// in the `Vec` in the order they have been generated. + /// + /// If `new_len` is less than `len`, the `Vec` is simply truncated. + /// + /// This method uses a closure to create new values on every push. If + /// you'd rather [`Clone`] a given value, use [`resize`]. If you want + /// to use the [`Default`] trait to generate values, you can pass + /// [`Default::default()`] as the second argument.. + /// + /// # Examples + /// + /// ``` + /// #![feature(vec_resize_with)] + /// + /// let mut vec = vec![1, 2, 3]; + /// vec.resize_with(5, Default::default); + /// assert_eq!(vec, [1, 2, 3, 0, 0]); + /// + /// let mut vec = vec![]; + /// let mut p = 1; + /// vec.resize_with(4, || { p *= 2; p }); + /// assert_eq!(vec, [2, 4, 8, 16]); + /// ``` + /// + /// [`resize`]: #method.resize + /// [`Clone`]: ../../std/clone/trait.Clone.html + #[unstable(feature = "vec_resize_with", issue = "41758")] + pub fn resize_with(&mut self, new_len: usize, f: F) + where F: FnMut() -> T + { + let len = self.len(); + if new_len > len { + self.extend_with(new_len - len, ExtendFunc(f)); + } else { + self.truncate(new_len); + } + } } impl Vec { @@ -1316,8 +1359,8 @@ impl Vec { /// If `new_len` is less than `len`, the `Vec` is simply truncated. /// /// This method requires [`Clone`] to be able clone the passed value. If - /// you'd rather create a value with [`Default`] instead, see - /// [`resize_default`]. + /// you need more flexibility (or want to rely on [`Default`] instead of + /// [`Clone`]), use [`resize_with`]. /// /// # Examples /// @@ -1333,7 +1376,7 @@ impl Vec { /// /// [`Clone`]: ../../std/clone/trait.Clone.html /// [`Default`]: ../../std/default/trait.Default.html - /// [`resize_default`]: #method.resize_default + /// [`resize_with`]: #method.resize_with #[stable(feature = "vec_resize", since = "1.5.0")] pub fn resize(&mut self, new_len: usize, value: T) { let len = self.len(); @@ -1412,24 +1455,31 @@ impl Vec { // This code generalises `extend_with_{element,default}`. trait ExtendWith { - fn next(&self) -> T; + fn next(&mut self) -> T; fn last(self) -> T; } struct ExtendElement(T); impl ExtendWith for ExtendElement { - fn next(&self) -> T { self.0.clone() } + fn next(&mut self) -> T { self.0.clone() } fn last(self) -> T { self.0 } } struct ExtendDefault; impl ExtendWith for ExtendDefault { - fn next(&self) -> T { Default::default() } + fn next(&mut self) -> T { Default::default() } fn last(self) -> T { Default::default() } } + +struct ExtendFunc(F); +impl T> ExtendWith for ExtendFunc { + fn next(&mut self) -> T { (self.0)() } + fn last(mut self) -> T { (self.0)() } +} + impl Vec { /// Extend the vector by `n` values, using the given generator. - fn extend_with>(&mut self, n: usize, value: E) { + fn extend_with>(&mut self, n: usize, mut value: E) { self.reserve(n); unsafe { From 77b570f831c128278f3716f887f3d8e0efe6801e Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 3 Apr 2018 12:38:53 -0400 Subject: [PATCH 31/39] Re-write the documentation index The docs team has decided that we're framing resources in three ways: "learning Rust," "using Rust," "mastering Rust." This is a more useful split than "beginner/intermediate/advanced." As we add more resources in the future, we expect "using Rust" to grow. "the bookshelf" as a concept is great, but isn't really organized along these lines. As such, this reorganizes the docs along these lines. --- src/doc/index.md | 109 +++++++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/src/doc/index.md b/src/doc/index.md index 3add2774105e0..2e36831d7e86f 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -6,55 +6,72 @@ nav { } -This page is an overview of the documentation included with your Rust install. -Other unofficial documentation may exist elsewhere; for example, the [Rust -Learning] project collects documentation from the community, and [Docs.rs] -builds documentation for individual Rust packages. +Welcome to an overview of the documentation provided by the Rust project. +All of these projects are managed by the Docs Team; there are other +unofficial documentation resources as well! -# API Documentation +Many of these resources take the form of "books"; we collectively call these +"The Rust Bookshelf." Some are large, some are small. -Rust provides a standard library with a number of features; [we host its -documentation here][api]. +## Learn Rust -# Extended Error Documentation +If you'd like to learn Rust, this is the spot for you! All of these resources +assume that you have programmed before, but not in any specific language: + +### The Rust Programming Language + +Affectionately nicknamed "the book," [The Rust Programming +Language](book/index.html) will give you an overview of the language from +first principles. You'll build a few projects along the way, and by the end, +you'll have a solid grasp of the language. + +### Rust By Example + +If reading multiple hundreds of pages about a language isn't your style, then +[Rust By Example](rust-by-example/index.html) has you covered. While the book talks about code with +a lot of words, RBE shows off a bunch of code, and keeps the talking to a +minimum. It also includes exercises! + +## Use Rust + +Once you've gotten familliar with the language, these resources can help you +when you're actually using it day-to-day. + +### The Standard Library + +Rust's standard library has [extensive API documentation](std/index.html), +with explanations of how to use various things, as well as example code for +accomplishing various tasks. + +### The Cargo Book + +[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and dependency manager. + +### The Rustdoc Book + +[The Rustdoc Book](rustdoc/index.html) describes our documentation tool, `rustdoc`. + +### Extended Error Listing Many of Rust's errors come with error codes, and you can request extended -diagnostics from the compiler on those errors. We also [have the text of those -extended errors on the web][err], if you prefer to read them that way. - -# The Rust Bookshelf - -Rust provides a number of book-length sets of documentation, collectively -nicknamed 'The Rust Bookshelf.' - -* [The Rust Programming Language][book] teaches you how to program in Rust. -* [Rust By Example][rbe] teaches you how to program in Rust using editable examples. -* [The Cargo Book][cargo-book] is a guide to Cargo, Rust's build tool and dependency manager. -* [The Unstable Book][unstable-book] has documentation for unstable features. -* [The Rustonomicon][nomicon] is your guidebook to the dark arts of unsafe Rust. -* [The Reference][ref] is not a formal spec, but is more detailed and comprehensive than the book. -* [The Rustdoc Book][rustdoc-book] describes our documentation tool, `rustdoc`. - -Initially, documentation lands in the Unstable Book, and then, as part of the -stabilization process, is moved into the Book, Nomicon, or Reference. - -Another few words about the reference: it is guaranteed to be accurate, but not -complete. We have a policy that features must have documentation to be stabilized, -but we did not always have this policy, and so there are some stable things that -are not yet in the reference. We're working on back-filling things that landed -before this policy was put into place. That work is being tracked -[here][refchecklist]. - -[Rust Learning]: https://github.com/ctjhoa/rust-learning -[Docs.rs]: https://docs.rs/ -[api]: std/index.html -[ref]: reference/index.html -[refchecklist]: https://github.com/rust-lang-nursery/reference/issues/9 -[err]: error-index.html -[book]: book/index.html -[rbe]: rust-by-example/index.html -[nomicon]: nomicon/index.html -[unstable-book]: unstable-book/index.html -[rustdoc-book]: rustdoc/index.html -[cargo-book]: cargo/index.html +diagnostics from the compiler on those errors. You can also [read them +here](error-index.html), if you prefer to read them that way. + +## Master Rust + +Once you're quite familiar with the language, you may find these advanced +resources useful. + +### The Reference + +[The Reference](reference/index.html) is not a formal spec, but is more detailed and +comprehensive than the book. + +### The Rustonomicon + +[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of unsafe +Rust. It's also sometimes called "the 'nomicon." + +### The Unstable Book +[The Unstable Book](unstable-book/index.html) has documentation for unstable features. From 1ce98f34d38fa9338ff696f904bcb8c01856f935 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 2 Apr 2018 09:11:07 -0700 Subject: [PATCH 32/39] Cross-reference fs::read functions from io::Read docs --- src/libstd/io/mod.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 63b631ace9693..3b8c42ddb39d8 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -595,6 +595,11 @@ pub trait Read { /// Ok(()) /// } /// ``` + /// + /// (See also the [`std::fs::read`] convenience function for reading from a + /// file.) + /// + /// [`std::fs::read`]: ../fs/fn.read.html #[stable(feature = "rust1", since = "1.0.0")] fn read_to_end(&mut self, buf: &mut Vec) -> Result { read_to_end(self, buf) @@ -633,6 +638,11 @@ pub trait Read { /// Ok(()) /// } /// ``` + /// + /// (See also the [`std::fs::read_to_string`] convenience function for + /// reading from a file.) + /// + /// [`std::fs::read_to_string`]: ../fs/fn.read_to_string.html #[stable(feature = "rust1", since = "1.0.0")] fn read_to_string(&mut self, buf: &mut String) -> Result { // Note that we do *not* call `.read_to_end()` here. We are passing From 390f8367e74d72317ab4aa5097048243073968fa Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 2 Apr 2018 09:31:04 -0700 Subject: [PATCH 33/39] Add performance notes to BufReader/BufWriter docs --- src/libstd/io/buffered.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index cefff2f143ce7..91f07ecc6639e 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -25,6 +25,12 @@ use memchr; /// results in a system call. A `BufReader` performs large, infrequent reads on /// the underlying [`Read`] and maintains an in-memory buffer of the results. /// +/// `BufReader` can improve the speed of programs that make *small* and +/// *repeated* read calls to the same file or network socket. It does not +/// help when reading very large amounts at once, or reading just one or a few +/// times. It also provides no advantage when reading from a source that is +/// already in memory, like a `Vec`. +/// /// [`Read`]: ../../std/io/trait.Read.html /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read /// [`TcpStream`]: ../../std/net/struct.TcpStream.html @@ -359,6 +365,12 @@ impl Seek for BufReader { /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying /// writer in large, infrequent batches. /// +/// `BufWriter` can improve the speed of programs that make *small* and +/// *repeated* write calls to the same file or network socket. It does not +/// help when writing very large amounts at once, or writing just one or a few +/// times. It also provides no advantage when writing to a destination that is +/// in memory, like a `Vec`. +/// /// When the `BufWriter` is dropped, the contents of its buffer will be written /// out. However, any errors that happen in the process of flushing the buffer /// when the writer is dropped will be ignored. Code that wishes to handle such From 3627e43dc42446aef70997e9670811a1ae6bee42 Mon Sep 17 00:00:00 2001 From: lloydmeta Date: Wed, 4 Apr 2018 10:25:37 +0900 Subject: [PATCH 34/39] Add a test for the fix to issue #43058 Followed the instructions laid out here https://github.com/rust-lang/rust/issues/43058#issuecomment-378389971 --- src/test/ui/nll/issue-43058.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/ui/nll/issue-43058.rs diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs new file mode 100644 index 0000000000000..ccea5279e072f --- /dev/null +++ b/src/test/ui/nll/issue-43058.rs @@ -0,0 +1,26 @@ +#![feature(nll)] + +use std::borrow::Cow; + +#[derive(Clone, Debug)] +struct S<'a> { + name: Cow<'a, str> +} + +#[derive(Clone, Debug)] +struct T<'a> { + s: Cow<'a, [S<'a>]> +} + +fn main() { + let s1 = [S { name: Cow::Borrowed("Test1") }, S { name: Cow::Borrowed("Test2") }]; + let b1 = T { s: Cow::Borrowed(&s1) }; + let s2 = [S { name: Cow::Borrowed("Test3") }, S { name: Cow::Borrowed("Test4") }]; + let b2 = T { s: Cow::Borrowed(&s2) }; + + let mut v = Vec::new(); + v.push(b1); + v.push(b2); + + println!("{:?}", v); +} \ No newline at end of file From f2cc501f5f982b18f3ecc4717820024d58065574 Mon Sep 17 00:00:00 2001 From: lloydmeta Date: Wed, 4 Apr 2018 10:33:52 +0900 Subject: [PATCH 35/39] Formatting --- src/test/ui/nll/issue-43058.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs index ccea5279e072f..91ac7e4004260 100644 --- a/src/test/ui/nll/issue-43058.rs +++ b/src/test/ui/nll/issue-43058.rs @@ -1,3 +1,15 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully + #![feature(nll)] use std::borrow::Cow; @@ -23,4 +35,4 @@ fn main() { v.push(b2); println!("{:?}", v); -} \ No newline at end of file +} From 97ac479066a16d06ad4eb2cc2a4f58d1e7aa37b8 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Tue, 3 Apr 2018 19:47:37 -0600 Subject: [PATCH 36/39] Stabilize parent_id() Fixes #46104 --- src/libstd/sys/unix/ext/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 60309bec6d4fc..7b4ec20d91fb4 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -193,7 +193,7 @@ impl IntoRawFd for process::ChildStderr { } /// Returns the OS-assigned process identifier associated with this process's parent. -#[unstable(feature = "unix_ppid", issue = "46104")] +#[stable(feature = "unix_ppid", since = "1.27.0")] pub fn parent_id() -> u32 { ::sys::os::getppid() } From db859f5043e0e7a34be9fe67128133c5287ba039 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 4 Apr 2018 09:00:35 +0300 Subject: [PATCH 37/39] Update Cargo This includes at least two notable changes: * a regression is fixed where Cargo would update index on every operation https://github.com/rust-lang/cargo/pull/5288 * a new unstable `--out-dir` option is implemented https://github.com/rust-lang/cargo/pull/5203 --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index d63299b6eafae..b70ab13b31628 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit d63299b6eafae99bfe1fd5ddc75bc7cf67ed58f9 +Subproject commit b70ab13b31628e91b05961d55c07abf20ad49de6 From a98179937680377c10a0d61033daa85b156fbe21 Mon Sep 17 00:00:00 2001 From: Valentine Valyaeff Date: Wed, 4 Apr 2018 11:36:38 +0300 Subject: [PATCH 38/39] Regression test for #46314 --- src/test/ui/nll/decl-macro-illegal-copy.rs | 39 +++++++++++++++++++ .../ui/nll/decl-macro-illegal-copy.stderr | 14 +++++++ 2 files changed, 53 insertions(+) create mode 100644 src/test/ui/nll/decl-macro-illegal-copy.rs create mode 100644 src/test/ui/nll/decl-macro-illegal-copy.stderr diff --git a/src/test/ui/nll/decl-macro-illegal-copy.rs b/src/test/ui/nll/decl-macro-illegal-copy.rs new file mode 100644 index 0000000000000..1525791c88112 --- /dev/null +++ b/src/test/ui/nll/decl-macro-illegal-copy.rs @@ -0,0 +1,39 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for #46314 + +#![feature(nll)] +#![feature(decl_macro)] + +struct NonCopy(String); + +struct Wrapper { + inner: NonCopy, +} + +macro inner_copy($wrapper:ident) { + $wrapper.inner +} + +fn main() { + let wrapper = Wrapper { + inner: NonCopy("foo".into()), + }; + assert_two_non_copy( + inner_copy!(wrapper), + wrapper.inner, + //~^ ERROR use of moved value: `wrapper.inner` [E0382] + ); +} + +fn assert_two_non_copy(a: NonCopy, b: NonCopy) { + assert_eq!(a.0, b.0); +} diff --git a/src/test/ui/nll/decl-macro-illegal-copy.stderr b/src/test/ui/nll/decl-macro-illegal-copy.stderr new file mode 100644 index 0000000000000..8bc25c23e0178 --- /dev/null +++ b/src/test/ui/nll/decl-macro-illegal-copy.stderr @@ -0,0 +1,14 @@ +error[E0382]: use of moved value: `wrapper.inner` + --> $DIR/decl-macro-illegal-copy.rs:32:9 + | +LL | $wrapper.inner + | -------------- value moved here +... +LL | wrapper.inner, + | ^^^^^^^^^^^^^ value used here after move + | + = note: move occurs because `wrapper.inner` has type `NonCopy`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. From ac4f69bea4d41dffe9d56fb4117bd244a6b6acbe Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 3 Apr 2018 17:50:31 +0200 Subject: [PATCH 39/39] miri: add public alloc_kind accessor --- src/librustc_mir/interpret/memory.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3a28eae2d1c49..4823f654055f9 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -352,6 +352,10 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { .ok_or(EvalErrorKind::ExecuteMemory.into()) } + pub fn get_alloc_kind(&self, id: AllocId) -> Option> { + self.alloc_kind.get(&id).cloned() + } + /// For debugging, print an allocation and all allocations it points to, recursively. pub fn dump_alloc(&self, id: AllocId) { self.dump_allocs(vec![id]);