From 962bf69e073b6349ddcf275443c2a814407cab2f Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 1 Jul 2019 00:52:18 +0100 Subject: [PATCH 01/79] Take substs into account in `conservative_is_privately_uninhabited` --- src/librustc/ty/sty.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 8bfbd8b854b03..b787f8e3d076d 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1702,22 +1702,21 @@ impl<'tcx> TyS<'tcx> { /// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero /// size, to account for partial initialisation. See #49298 for details.) pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool { - // FIXME(varkor): we can make this less conversative by substituting concrete - // type arguments. match self.sty { ty::Never => true, ty::Adt(def, _) if def.is_union() => { // For now, `union`s are never considered uninhabited. false } - ty::Adt(def, _) => { + ty::Adt(def, substs) => { // Any ADT is uninhabited if either: // (a) It has no variants (i.e. an empty `enum`); // (b) Each of its variants (a single one in the case of a `struct`) has at least // one uninhabited field. def.variants.iter().all(|var| { var.fields.iter().any(|field| { - tcx.type_of(field.did).conservative_is_privately_uninhabited(tcx) + tcx.type_of(field.did).subst(tcx, substs) + .conservative_is_privately_uninhabited(tcx) }) }) } From 5397dfce77f3b3d903580843af3da37615a44e74 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 8 Jul 2019 18:12:06 +0200 Subject: [PATCH 02/79] =?UTF-8?q?Remove=20obsolete=20=E2=80=9Cshould=20not?= =?UTF-8?q?=20have=20to=20exist=E2=80=9D=20reasons?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/liballoc/slice.rs | 4 +--- src/liballoc/str.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index bc4ae16798478..9a23cdc1768f3 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -595,9 +595,7 @@ pub trait SliceConcat: Sized { fn join(slice: &[Self], sep: &Separator) -> Self::Output; } -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "27747")] impl> SliceConcat for V { type Output = Vec; diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 37a1046d0942d..b6512487ddd56 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -71,9 +71,7 @@ pub use core::str::SplitAsciiWhitespace; #[stable(feature = "str_escape", since = "1.34.0")] pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "27747")] impl> SliceConcat for S { type Output = String; From 01d93bf59523c4e5c00cf8933c551adc73953cd1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 8 Jul 2019 17:47:49 +0200 Subject: [PATCH 03/79] Split the SliceConcat trait into Concat and Join --- src/liballoc/slice.rs | 74 +++++++++++++++++++++++++++++++++---------- src/liballoc/str.rs | 17 +++++++--- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 9a23cdc1768f3..d7a9f83ad242e 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -494,10 +494,10 @@ impl [T] { /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn concat(&self) -> T::Output - where T: SliceConcat + pub fn concat(&self) -> >::Output + where Self: Concat { - SliceConcat::concat(self) + Concat::concat(self) } /// Flattens a slice of `T` into a single value `Self::Output`, placing a @@ -510,10 +510,10 @@ impl [T] { /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); /// ``` #[stable(feature = "rename_connect_to_join", since = "1.3.0")] - pub fn join(&self, sep: &Separator) -> T::Output - where T: SliceConcat + pub fn join(&self, sep: &Separator) -> >::Output + where Self: Join { - SliceConcat::join(self, sep) + Join::join(self, sep) } /// Flattens a slice of `T` into a single value `Self::Output`, placing a @@ -528,10 +528,10 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - pub fn connect(&self, sep: &Separator) -> T::Output - where T: SliceConcat + pub fn connect(&self, sep: &Separator) -> >::Output + where Self: Join { - SliceConcat::join(self, sep) + Join::join(self, sep) } } @@ -578,28 +578,63 @@ impl [u8] { // Extension traits for slices over specific kinds of data //////////////////////////////////////////////////////////////////////////////// -/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat) -/// and [`[T]::join`](../../std/primitive.slice.html#method.join) +/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat). +/// +/// Note: the `Item` type parameter is not used in this trait, +/// but it allows impls to be more generic. +/// Without it, we get this error: +/// +/// ```error +/// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predica +/// --> src/liballoc/slice.rs:608:6 +/// | +/// 608 | impl> Concat for [V] { +/// | ^ unconstrained type parameter +/// ``` +/// +/// This is because there could exist `V` types with multiple `Borrow<[_]>` impls, +/// such that multiple `T` types would apply: +/// +/// ``` +/// # #[allow(dead_code)] +/// pub struct Foo(Vec, Vec); +/// +/// impl std::borrow::Borrow<[u32]> for Foo { +/// fn borrow(&self) -> &[u32] { &self.0 } +/// } +/// +/// impl std::borrow::Borrow<[String]> for Foo { +/// fn borrow(&self) -> &[String] { &self.1 } +/// } +/// ``` #[unstable(feature = "slice_concat_trait", issue = "27747")] -pub trait SliceConcat: Sized { +pub trait Concat { #[unstable(feature = "slice_concat_trait", issue = "27747")] /// The resulting type after concatenation type Output; /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat) #[unstable(feature = "slice_concat_trait", issue = "27747")] - fn concat(slice: &[Self]) -> Self::Output; + fn concat(slice: &Self) -> Self::Output; +} + +/// Helper trait for [`[T]::join`](../../std/primitive.slice.html#method.join) +#[unstable(feature = "slice_concat_trait", issue = "27747")] +pub trait Join { + #[unstable(feature = "slice_concat_trait", issue = "27747")] + /// The resulting type after concatenation + type Output; /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join) #[unstable(feature = "slice_concat_trait", issue = "27747")] - fn join(slice: &[Self], sep: &Separator) -> Self::Output; + fn join(slice: &Self, sep: &Separator) -> Self::Output; } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> SliceConcat for V { +impl> Concat for [V] { type Output = Vec; - fn concat(slice: &[Self]) -> Vec { + fn concat(slice: &Self) -> Vec { let size = slice.iter().map(|slice| slice.borrow().len()).sum(); let mut result = Vec::with_capacity(size); for v in slice { @@ -607,8 +642,13 @@ impl> SliceConcat for V { } result } +} + +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join for [V] { + type Output = Vec; - fn join(slice: &[Self], sep: &T) -> Vec { + fn join(slice: &Self, sep: &T) -> Vec { let mut iter = slice.iter(); let first = match iter.next() { Some(first) => first, diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index b6512487ddd56..726ac1907fa86 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -37,7 +37,7 @@ use core::unicode::conversions; use crate::borrow::ToOwned; use crate::boxed::Box; -use crate::slice::{SliceConcat, SliceIndex}; +use crate::slice::{Concat, Join, SliceIndex}; use crate::string::String; use crate::vec::Vec; @@ -71,15 +71,22 @@ pub use core::str::SplitAsciiWhitespace; #[stable(feature = "str_escape", since = "1.34.0")] pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; +/// Note: `str` in `Concat` is not meaningful here. +/// This type parameter of the trait only exists to enable another impl. #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> SliceConcat for S { +impl> Concat for [S] { type Output = String; - fn concat(slice: &[Self]) -> String { - Self::join(slice, "") + fn concat(slice: &Self) -> String { + Join::join(slice, "") } +} + +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join for [S] { + type Output = String; - fn join(slice: &[Self], sep: &str) -> String { + fn join(slice: &Self, sep: &str) -> String { unsafe { String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) ) } From 283f6762caebb723a17ce82e1fc120928697cfb9 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 8 Jul 2019 17:50:27 +0200 Subject: [PATCH 04/79] Take separator by value in `[T]::join` --- src/liballoc/slice.rs | 10 +++++----- src/liballoc/str.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index d7a9f83ad242e..1b18dbeda9c11 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -510,7 +510,7 @@ impl [T] { /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); /// ``` #[stable(feature = "rename_connect_to_join", since = "1.3.0")] - pub fn join(&self, sep: &Separator) -> >::Output + pub fn join(&self, sep: Separator) -> >::Output where Self: Join { Join::join(self, sep) @@ -528,7 +528,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - pub fn connect(&self, sep: &Separator) -> >::Output + pub fn connect(&self, sep: Separator) -> >::Output where Self: Join { Join::join(self, sep) @@ -620,14 +620,14 @@ pub trait Concat { /// Helper trait for [`[T]::join`](../../std/primitive.slice.html#method.join) #[unstable(feature = "slice_concat_trait", issue = "27747")] -pub trait Join { +pub trait Join { #[unstable(feature = "slice_concat_trait", issue = "27747")] /// The resulting type after concatenation type Output; /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join) #[unstable(feature = "slice_concat_trait", issue = "27747")] - fn join(slice: &Self, sep: &Separator) -> Self::Output; + fn join(slice: &Self, sep: Separator) -> Self::Output; } #[unstable(feature = "slice_concat_ext", issue = "27747")] @@ -645,7 +645,7 @@ impl> Concat for [V] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join for [V] { +impl> Join<&'_ T> for [V] { type Output = Vec; fn join(slice: &Self, sep: &T) -> Vec { diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 726ac1907fa86..f57cf96a64196 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -83,7 +83,7 @@ impl> Concat for [S] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join for [S] { +impl> Join<&'_ str> for [S] { type Output = String; fn join(slice: &Self, sep: &str) -> String { From b62a77b4905150b14c8b0fd6e685f528e4f90ea7 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 8 Jul 2019 18:08:54 +0200 Subject: [PATCH 05/79] Add joining slices of slices with a slice separator, not just a single item --- src/liballoc/slice.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 1b18dbeda9c11..d475c628ff193 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -508,6 +508,7 @@ impl [T] { /// ``` /// assert_eq!(["hello", "world"].join(" "), "hello world"); /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); + /// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]); /// ``` #[stable(feature = "rename_connect_to_join", since = "1.3.0")] pub fn join(&self, sep: Separator) -> >::Output @@ -654,7 +655,7 @@ impl> Join<&'_ T> for [V] { Some(first) => first, None => return vec![], }; - let size = slice.iter().map(|slice| slice.borrow().len()).sum::() + slice.len() - 1; + let size = slice.iter().map(|v| v.borrow().len()).sum::() + slice.len() - 1; let mut result = Vec::with_capacity(size); result.extend_from_slice(first.borrow()); @@ -666,6 +667,29 @@ impl> Join<&'_ T> for [V] { } } +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join<&'_ [T]> for [V] { + type Output = Vec; + + fn join(slice: &Self, sep: &[T]) -> Vec { + let mut iter = slice.iter(); + let first = match iter.next() { + Some(first) => first, + None => return vec![], + }; + let size = slice.iter().map(|v| v.borrow().len()).sum::() + + sep.len() * (slice.len() - 1); + let mut result = Vec::with_capacity(size); + result.extend_from_slice(first.borrow()); + + for v in iter { + result.extend_from_slice(sep); + result.extend_from_slice(v.borrow()) + } + result + } +} + //////////////////////////////////////////////////////////////////////////////// // Standard trait implementations for slices //////////////////////////////////////////////////////////////////////////////// From d0635ee5f74badbf72355b7e29d7f0723e8551da Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 9 Jul 2019 18:19:01 +0200 Subject: [PATCH 06/79] Update src/liballoc/slice.rs Co-Authored-By: Mazdak Farrokhzad --- src/liballoc/slice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index d475c628ff193..848df2f9dcf90 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -646,7 +646,7 @@ impl> Concat for [V] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join<&'_ T> for [V] { +impl> Join<&T> for [V] { type Output = Vec; fn join(slice: &Self, sep: &T) -> Vec { From bbc9366c1a2d4d071b54cc1af23706a36741b444 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 9 Jul 2019 18:19:10 +0200 Subject: [PATCH 07/79] Update src/liballoc/slice.rs Co-Authored-By: Mazdak Farrokhzad --- src/liballoc/slice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 848df2f9dcf90..881d499c0745b 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -668,7 +668,7 @@ impl> Join<&T> for [V] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join<&'_ [T]> for [V] { +impl> Join<&[T]> for [V] { type Output = Vec; fn join(slice: &Self, sep: &[T]) -> Vec { From 5f7768a976edc296c62479b936993b4dc9af065b Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 9 Jul 2019 18:19:18 +0200 Subject: [PATCH 08/79] Update src/liballoc/str.rs Co-Authored-By: Mazdak Farrokhzad --- src/liballoc/str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index f57cf96a64196..9a1342c30d502 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -83,7 +83,7 @@ impl> Concat for [S] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join<&'_ str> for [S] { +impl> Join<&str> for [S] { type Output = String; fn join(slice: &Self, sep: &str) -> String { From dee3d27d9d69aa66429cec5fb8ca7cdd46ab6019 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sun, 23 Jun 2019 14:19:18 -0400 Subject: [PATCH 09/79] allow clippy::unreadable_literal in unicode tables Also modifies the generation script to emit 2018 edition paths. --- src/libcore/unicode/tables.rs | 2 +- src/libcore/unicode/unicode.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs index 758cdb0b7cfba..2659ba61e0ccb 100644 --- a/src/libcore/unicode/tables.rs +++ b/src/libcore/unicode/tables.rs @@ -1,6 +1,6 @@ // NOTE: The following code was generated by "./unicode.py", do not edit directly -#![allow(missing_docs, non_upper_case_globals, non_snake_case)] +#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] use crate::unicode::version::UnicodeVersion; use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie}; diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py index a0539cd9ca9b6..5389d1cf80383 100755 --- a/src/libcore/unicode/unicode.py +++ b/src/libcore/unicode/unicode.py @@ -79,10 +79,10 @@ class UnicodeFiles(object): PREAMBLE = """\ // NOTE: The following code was generated by "./unicode.py", do not edit directly -#![allow(missing_docs, non_upper_case_globals, non_snake_case)] +#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] -use unicode::version::UnicodeVersion; -use unicode::bool_trie::{{BoolTrie, SmallBoolTrie}}; +use crate::unicode::version::UnicodeVersion; +use crate::unicode::bool_trie::{{BoolTrie, SmallBoolTrie}}; """.format(year=datetime.datetime.now().year) # Mapping taken from Table 12 from: From ccb5d0a7c170434bb2ced860ec7139f4c6f964ce Mon Sep 17 00:00:00 2001 From: Scott Wolchok Date: Tue, 16 Jul 2019 13:29:40 -0700 Subject: [PATCH 10/79] Support SDKROOT env var on iOS Following what clang does (https://github.com/llvm/llvm-project/blob/296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678), allow allow SDKROOT to tell us where the Apple SDK lives so we don't have to invoke xcrun. --- src/librustc_target/spec/apple_ios_base.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs index 3068ed8d206cd..40cc7f420106b 100644 --- a/src/librustc_target/spec/apple_ios_base.rs +++ b/src/librustc_target/spec/apple_ios_base.rs @@ -1,3 +1,4 @@ +use std::env; use std::io; use std::process::Command; use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; @@ -27,6 +28,12 @@ impl Arch { } pub fn get_sdk_root(sdk_name: &str) -> Result { + if let Some(sdkroot) = env::var("SDKROOT").ok() { + let sdkroot_path = Path::new(sdkroot); + if sdkroot_path.is_absolute() && sdkroot_path != Path::new("/") && sdkroot_path.exists() { + return Ok(sdkroot); + } + } let res = Command::new("xcrun") .arg("--show-sdk-path") .arg("-sdk") From 795f93b8af25a2efd19bd5b01367e827d8da73e5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 17 Jul 2019 09:28:02 -0700 Subject: [PATCH 11/79] ci: Install clang on Windows through tarballs Previously we used the executables built the LLVM project but these executables are difficult to run in a CI environment, they can accidentally pollute global state, etc. In testing some of the possible 4-core machine environments for Azure this step would frequently cause issues. To assuage these future issues and hopefully make builds slightly more self-contained, this commit changes to install from a tarball instead. The tarball isn't provided by LLVM itself, but we use the offical LLVM installer to extract itself and then we pack up the LLVM installation directory into the tarball. --- .azure-pipelines/steps/install-clang.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.azure-pipelines/steps/install-clang.yml b/.azure-pipelines/steps/install-clang.yml index 0cd6f24e32c7c..45ec767e0b875 100644 --- a/.azure-pipelines/steps/install-clang.yml +++ b/.azure-pipelines/steps/install-clang.yml @@ -26,12 +26,18 @@ steps: # # Original downloaded here came from # http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.exe -- script: | - powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf %TEMP%\LLVM-7.0.0-win64.exe https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/LLVM-7.0.0-win64.exe" - set CLANG_DIR=%CD%\citools\clang-rust - %TEMP%\LLVM-7.0.0-win64.exe /S /NCRC /D=%CLANG_DIR% - set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --set llvm.clang-cl=%CLANG_DIR%\bin\clang-cl.exe - echo ##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]%RUST_CONFIGURE_ARGS% +# That installer was run through `wine` on Linux and then the resulting +# installation directory (found in `$HOME/.wine/drive_c/Program Files/LLVM`) was +# packaged up into a tarball. We've had issues otherwise that the installer will +# randomly hang, provide not a lot of useful information, pollute global state, +# etc. In general the tarball is just more confined and easier to deal with when +# working with various CI environments. +- bash: | + set -e + mkdir -p citools + cd citools + curl -f https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/LLVM-7.0.0-win64.tar.gz | tar xzf - + echo "##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]$RUST_CONFIGURE_ARGS --set llvm.clang-cl=`pwd`/clang-rust/bin/clang-cl.exe" condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],'')) displayName: Install clang (Windows) From bb9bf0ca9a9eaeb14e910ff23037c02c14cdb494 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 18 Jul 2019 18:37:23 +0300 Subject: [PATCH 12/79] Add riscv32i-unknown-none-elf target --- src/ci/docker/dist-various-1/Dockerfile | 1 + src/librustc_target/spec/mod.rs | 1 + .../spec/riscv32i_unknown_none_elf.rs | 32 +++++++++++++++++++ src/tools/build-manifest/src/main.rs | 1 + 4 files changed, 35 insertions(+) create mode 100644 src/librustc_target/spec/riscv32i_unknown_none_elf.rs diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 5ab4be328a9f7..2a81de75a69b9 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -112,6 +112,7 @@ ENV TARGETS=$TARGETS,thumbv7em-none-eabihf ENV TARGETS=$TARGETS,thumbv8m.base-none-eabi ENV TARGETS=$TARGETS,thumbv8m.main-none-eabi ENV TARGETS=$TARGETS,thumbv8m.main-none-eabihf +ENV TARGETS=$TARGETS,riscv32i-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imc-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf ENV TARGETS=$TARGETS,riscv64imac-unknown-none-elf diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1fdc9b015ba39..ac1e1ed962fdf 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -464,6 +464,7 @@ supported_targets! { ("aarch64-unknown-hermit", aarch64_unknown_hermit), ("x86_64-unknown-hermit", x86_64_unknown_hermit), + ("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf), ("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf), ("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf), ("riscv64imac-unknown-none-elf", riscv64imac_unknown_none_elf), diff --git a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs new file mode 100644 index 0000000000000..314778408f7e5 --- /dev/null +++ b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs @@ -0,0 +1,32 @@ +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, + Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(), + llvm_target: "riscv32".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: "unknown".to_string(), + arch: "riscv32".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + + options: TargetOptions { + linker: Some("rust-lld".to_string()), + cpu: "generic-rv32".to_string(), + max_atomic_width: None, + atomic_cas: false, + features: String::new(), + executables: true, + panic_strategy: PanicStrategy::Abort, + relocation_model: "static".to_string(), + emit_debug_gdb_scripts: false, + abi_blacklist: super::riscv_base::abi_blacklist(), + eliminate_frame_pointer: false, + .. Default::default() + }, + }) +} diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index b6e087c3844fa..20176557bcbeb 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -92,6 +92,7 @@ static TARGETS: &[&str] = &[ "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", + "riscv32i-unknown-none-elf", "riscv32imc-unknown-none-elf", "riscv32imac-unknown-none-elf", "riscv64imac-unknown-none-elf", From 3427a14bdf19437c455e54af704e0250ea8aa79b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 19 Jul 2019 14:21:06 +0200 Subject: [PATCH 13/79] Remove support for -Zlower-128bit-ops It is broken and unused --- src/librustc/middle/lang_items.rs | 28 --- src/librustc/session/config.rs | 4 - src/librustc/ty/context.rs | 36 +--- src/librustc_mir/interpret/intrinsics.rs | 15 +- src/librustc_mir/transform/inline.rs | 7 - src/librustc_mir/transform/lower_128bit.rs | 230 --------------------- src/librustc_mir/transform/mod.rs | 3 - src/librustc_target/spec/mod.rs | 5 - 8 files changed, 3 insertions(+), 325 deletions(-) delete mode 100644 src/librustc_mir/transform/lower_128bit.rs diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index bdd48b3447498..cc09a0b20cfd5 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -367,34 +367,6 @@ language_item_table! { DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait; - // A lang item for each of the 128-bit operators we can optionally lower. - I128AddFnLangItem, "i128_add", i128_add_fn, Target::Fn; - U128AddFnLangItem, "u128_add", u128_add_fn, Target::Fn; - I128SubFnLangItem, "i128_sub", i128_sub_fn, Target::Fn; - U128SubFnLangItem, "u128_sub", u128_sub_fn, Target::Fn; - I128MulFnLangItem, "i128_mul", i128_mul_fn, Target::Fn; - U128MulFnLangItem, "u128_mul", u128_mul_fn, Target::Fn; - I128DivFnLangItem, "i128_div", i128_div_fn, Target::Fn; - U128DivFnLangItem, "u128_div", u128_div_fn, Target::Fn; - I128RemFnLangItem, "i128_rem", i128_rem_fn, Target::Fn; - U128RemFnLangItem, "u128_rem", u128_rem_fn, Target::Fn; - I128ShlFnLangItem, "i128_shl", i128_shl_fn, Target::Fn; - U128ShlFnLangItem, "u128_shl", u128_shl_fn, Target::Fn; - I128ShrFnLangItem, "i128_shr", i128_shr_fn, Target::Fn; - U128ShrFnLangItem, "u128_shr", u128_shr_fn, Target::Fn; - // And overflow versions for the operators that are checkable. - // While MIR calls these Checked*, they return (T,bool), not Option. - I128AddoFnLangItem, "i128_addo", i128_addo_fn, Target::Fn; - U128AddoFnLangItem, "u128_addo", u128_addo_fn, Target::Fn; - I128SuboFnLangItem, "i128_subo", i128_subo_fn, Target::Fn; - U128SuboFnLangItem, "u128_subo", u128_subo_fn, Target::Fn; - I128MuloFnLangItem, "i128_mulo", i128_mulo_fn, Target::Fn; - U128MuloFnLangItem, "u128_mulo", u128_mulo_fn, Target::Fn; - I128ShloFnLangItem, "i128_shlo", i128_shlo_fn, Target::Fn; - U128ShloFnLangItem, "u128_shlo", u128_shlo_fn, Target::Fn; - I128ShroFnLangItem, "i128_shro", i128_shro_fn, Target::Fn; - U128ShroFnLangItem, "u128_shro", u128_shro_fn, Target::Fn; - // Align offset for stride != 1, must not panic. AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index db8e2f64e3066..54d28b32accda 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1406,10 +1406,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, saturating_float_casts: bool = (false, parse_bool, [TRACKED], "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ the max/min integer respectively, and NaN is mapped to 0"), - lower_128bit_ops: Option = (None, parse_opt_bool, [TRACKED], - "rewrite operators on i128 and u128 into lang item calls (typically provided \ - by compiler-builtins) so codegen doesn't need to support them, - overriding the default for the current target"), human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], "generate human-readable, predictable names for codegen units"), dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 16fc46b66d9f4..9746f46dbaccc 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata; use crate::middle::lang_items; use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use crate::middle::stability; -use crate::mir::{self, Body, interpret, ProjectionKind}; +use crate::mir::{Body, interpret, ProjectionKind}; use crate::mir::interpret::{ConstValue, Allocation, Scalar}; use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst}; use crate::ty::ReprOptions; @@ -1297,40 +1297,6 @@ impl<'tcx> TyCtxt<'tcx> { self.get_lang_items(LOCAL_CRATE) } - /// Due to missing llvm support for lowering 128 bit math to software emulation - /// (on some targets), the lowering can be done in MIR. - /// - /// This function only exists until said support is implemented. - pub fn is_binop_lang_item(&self, def_id: DefId) -> Option<(mir::BinOp, bool)> { - let items = self.lang_items(); - let def_id = Some(def_id); - if items.i128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } - else if items.u128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } - else if items.i128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) } - else if items.u128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) } - else if items.i128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) } - else if items.u128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) } - else if items.i128_div_fn() == def_id { Some((mir::BinOp::Div, false)) } - else if items.u128_div_fn() == def_id { Some((mir::BinOp::Div, false)) } - else if items.i128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) } - else if items.u128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) } - else if items.i128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) } - else if items.u128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) } - else if items.i128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) } - else if items.u128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) } - else if items.i128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) } - else if items.u128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) } - else if items.i128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) } - else if items.u128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) } - else if items.i128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) } - else if items.u128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) } - else if items.i128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) } - else if items.u128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) } - else if items.i128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) } - else if items.u128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) } - else { None } - } - pub fn stability(self) -> &'tcx stability::Index<'tcx> { self.stability_index(LOCAL_CRATE) } diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index cf36c10a614e5..097bc3fabd159 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -230,21 +230,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &mut self, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, M::PointerTag>], - dest: Option>, + _dest: Option>, ) -> InterpResult<'tcx, bool> { let def_id = instance.def_id(); - // Some fn calls are actually BinOp intrinsics - if let Some((op, oflo)) = self.tcx.is_binop_lang_item(def_id) { - let dest = dest.expect("128 lowerings can't diverge"); - let l = self.read_immediate(args[0])?; - let r = self.read_immediate(args[1])?; - if oflo { - self.binop_with_overflow(op, l, r, dest)?; - } else { - self.binop_ignore_overflow(op, l, r, dest)?; - } - return Ok(true); - } else if Some(def_id) == self.tcx.lang_items().panic_fn() { + if Some(def_id) == self.tcx.lang_items().panic_fn() { assert!(args.len() == 1); // &(&'static str, &'static str, u32, u32) let place = self.deref_operand(args[0])?; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 04ee14f5f59be..61685f445c8db 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -232,13 +232,6 @@ impl Inliner<'tcx> { return false; } - // Do not inline {u,i}128 lang items, codegen const eval depends - // on detecting calls to these lang items and intercepting them - if tcx.is_binop_lang_item(callsite.callee).is_some() { - debug!(" not inlining 128bit integer lang item"); - return false; - } - let codegen_fn_attrs = tcx.codegen_fn_attrs(callsite.callee); let hinted = match codegen_fn_attrs.inline { diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs deleted file mode 100644 index f09a77d486c7e..0000000000000 --- a/src/librustc_mir/transform/lower_128bit.rs +++ /dev/null @@ -1,230 +0,0 @@ -//! Replaces 128-bit operators with lang item calls - -use rustc::hir::def_id::DefId; -use rustc::middle::lang_items::LangItem; -use rustc::mir::*; -use rustc::ty::{self, List, Ty, TyCtxt}; -use rustc_data_structures::indexed_vec::{Idx}; -use crate::transform::{MirPass, MirSource}; - -pub struct Lower128Bit; - -impl MirPass for Lower128Bit { - fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { - let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops; - let target_default = tcx.sess.host.options.i128_lowering; - if !debugging_override.unwrap_or(target_default) { - return - } - - self.lower_128bit_ops(tcx, body); -} -} - -impl Lower128Bit { - fn lower_128bit_ops<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut new_blocks = Vec::new(); - let cur_len = body.basic_blocks().len(); - - let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); - for block in basic_blocks.iter_mut() { - for i in (0..block.statements.len()).rev() { - let (lang_item, rhs_kind) = - if let Some((lang_item, rhs_kind)) = - lower_to(&block.statements[i], local_decls, tcx) - { - (lang_item, rhs_kind) - } else { - continue; - }; - - let rhs_override_ty = rhs_kind.ty(tcx); - let cast_local = - match rhs_override_ty { - None => None, - Some(ty) => { - let local_decl = LocalDecl::new_internal( - ty, block.statements[i].source_info.span); - Some(local_decls.push(local_decl)) - }, - }; - - let storage_dead = cast_local.map(|local| { - Statement { - source_info: block.statements[i].source_info, - kind: StatementKind::StorageDead(local), - } - }); - let after_call = BasicBlockData { - statements: storage_dead.into_iter() - .chain(block.statements.drain((i+1)..)).collect(), - is_cleanup: block.is_cleanup, - terminator: block.terminator.take(), - }; - - let bin_statement = block.statements.pop().unwrap(); - let source_info = bin_statement.source_info; - let (place, lhs, mut rhs) = match bin_statement.kind { - StatementKind::Assign(place, box rvalue) => { - match rvalue { - Rvalue::BinaryOp(_, lhs, rhs) - | Rvalue::CheckedBinaryOp(_, lhs, rhs) => (place, lhs, rhs), - _ => bug!(), - } - } - _ => bug!() - }; - - if let Some(local) = cast_local { - block.statements.push(Statement { - source_info: source_info, - kind: StatementKind::StorageLive(local), - }); - block.statements.push(Statement { - source_info: source_info, - kind: StatementKind::Assign( - Place::from(local), - box Rvalue::Cast( - CastKind::Misc, - rhs, - rhs_override_ty.unwrap())), - }); - rhs = Operand::Move(Place::from(local)); - } - - let call_did = check_lang_item_type( - lang_item, &place, &lhs, &rhs, local_decls, tcx); - - let bb = BasicBlock::new(cur_len + new_blocks.len()); - new_blocks.push(after_call); - - block.terminator = - Some(Terminator { - source_info, - kind: TerminatorKind::Call { - func: Operand::function_handle(tcx, call_did, - List::empty(), source_info.span), - args: vec![lhs, rhs], - destination: Some((place, bb)), - cleanup: None, - from_hir_call: false, - }, - }); - } - } - - basic_blocks.extend(new_blocks); - } -} - -fn check_lang_item_type<'tcx, D>( - lang_item: LangItem, - place: &Place<'tcx>, - lhs: &Operand<'tcx>, - rhs: &Operand<'tcx>, - local_decls: &D, - tcx: TyCtxt<'tcx>, -) -> DefId -where - D: HasLocalDecls<'tcx>, -{ - let did = tcx.require_lang_item(lang_item); - let poly_sig = tcx.fn_sig(did); - let sig = poly_sig.no_bound_vars().unwrap(); - let lhs_ty = lhs.ty(local_decls, tcx); - let rhs_ty = rhs.ty(local_decls, tcx); - let place_ty = place.ty(local_decls, tcx).ty; - let expected = [lhs_ty, rhs_ty, place_ty]; - assert_eq!(sig.inputs_and_output[..], expected, - "lang item `{}`", tcx.def_path_str(did)); - did -} - -fn lower_to<'tcx, D>( - statement: &Statement<'tcx>, - local_decls: &D, - tcx: TyCtxt<'tcx>, -) -> Option<(LangItem, RhsKind)> -where - D: HasLocalDecls<'tcx>, -{ - match statement.kind { - StatementKind::Assign(_, box Rvalue::BinaryOp(bin_op, ref lhs, _)) => { - let ty = lhs.ty(local_decls, tcx); - if let Some(is_signed) = sign_of_128bit(ty) { - return item_for_op(bin_op, is_signed); - } - }, - StatementKind::Assign(_, box Rvalue::CheckedBinaryOp(bin_op, ref lhs, _)) => { - let ty = lhs.ty(local_decls, tcx); - if let Some(is_signed) = sign_of_128bit(ty) { - return item_for_checked_op(bin_op, is_signed); - } - }, - _ => {}, - } - None -} - -#[derive(Copy, Clone)] -enum RhsKind { - Unchanged, - ForceU128, - ForceU32, -} - -impl RhsKind { - fn ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option> { - match *self { - RhsKind::Unchanged => None, - RhsKind::ForceU128 => Some(tcx.types.u128), - RhsKind::ForceU32 => Some(tcx.types.u32), - } - } -} - -fn sign_of_128bit(ty: Ty<'_>) -> Option { - match ty.sty { - ty::Int(syntax::ast::IntTy::I128) => Some(true), - ty::Uint(syntax::ast::UintTy::U128) => Some(false), - _ => None, - } -} - -fn item_for_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { - let i = match (bin_op, is_signed) { - (BinOp::Add, true) => (LangItem::I128AddFnLangItem, RhsKind::Unchanged), - (BinOp::Add, false) => (LangItem::U128AddFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, true) => (LangItem::I128SubFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, false) => (LangItem::U128SubFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, true) => (LangItem::I128MulFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, false) => (LangItem::U128MulFnLangItem, RhsKind::Unchanged), - (BinOp::Div, true) => (LangItem::I128DivFnLangItem, RhsKind::Unchanged), - (BinOp::Div, false) => (LangItem::U128DivFnLangItem, RhsKind::Unchanged), - (BinOp::Rem, true) => (LangItem::I128RemFnLangItem, RhsKind::Unchanged), - (BinOp::Rem, false) => (LangItem::U128RemFnLangItem, RhsKind::Unchanged), - (BinOp::Shl, true) => (LangItem::I128ShlFnLangItem, RhsKind::ForceU32), - (BinOp::Shl, false) => (LangItem::U128ShlFnLangItem, RhsKind::ForceU32), - (BinOp::Shr, true) => (LangItem::I128ShrFnLangItem, RhsKind::ForceU32), - (BinOp::Shr, false) => (LangItem::U128ShrFnLangItem, RhsKind::ForceU32), - _ => return None, - }; - Some(i) -} - -fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { - let i = match (bin_op, is_signed) { - (BinOp::Add, true) => (LangItem::I128AddoFnLangItem, RhsKind::Unchanged), - (BinOp::Add, false) => (LangItem::U128AddoFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, true) => (LangItem::I128SuboFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, false) => (LangItem::U128SuboFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, true) => (LangItem::I128MuloFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, false) => (LangItem::U128MuloFnLangItem, RhsKind::Unchanged), - (BinOp::Shl, true) => (LangItem::I128ShloFnLangItem, RhsKind::ForceU128), - (BinOp::Shl, false) => (LangItem::U128ShloFnLangItem, RhsKind::ForceU128), - (BinOp::Shr, true) => (LangItem::I128ShroFnLangItem, RhsKind::ForceU128), - (BinOp::Shr, false) => (LangItem::U128ShroFnLangItem, RhsKind::ForceU128), - _ => bug!("That should be all the checked ones?"), - }; - Some(i) -} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 9e23d06145330..c7e6eed1d9a2e 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -34,7 +34,6 @@ pub mod copy_prop; pub mod const_prop; pub mod generator; pub mod inline; -pub mod lower_128bit; pub mod uniform_array_move_out; pub(crate) fn provide(providers: &mut Providers<'_>) { @@ -272,8 +271,6 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> { // From here on out, regions are gone. &erase_regions::EraseRegions, - &lower_128bit::Lower128Bit, - // Optimizations begin. &uniform_array_move_out::RestoreSubsliceArrayMoveOut, diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1fdc9b015ba39..e78fda61a4396 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -731,10 +731,6 @@ pub struct TargetOptions { /// for this target unconditionally. pub no_builtins: bool, - /// Whether to lower 128-bit operations to compiler_builtins calls. Use if - /// your backend only supports 64-bit and smaller math. - pub i128_lowering: bool, - /// The codegen backend to use for this target, typically "llvm" pub codegen_backend: String, @@ -850,7 +846,6 @@ impl Default for TargetOptions { requires_lto: false, singlethread: false, no_builtins: false, - i128_lowering: false, codegen_backend: "llvm".to_string(), default_hidden_visibility: false, embed_bitcode: false, From e8a1e73ff5fa0b2a085aa23d013c536c4e7c9675 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Jul 2019 11:27:13 +0200 Subject: [PATCH 14/79] Update compiler_builtins to 0.1.18 --- Cargo.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8e9850e6436e..fe1b090c5467e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ dependencies = [ name = "alloc" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -110,7 +110,7 @@ dependencies = [ "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", @@ -122,7 +122,7 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -335,7 +335,7 @@ name = "cfg-if" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -464,7 +464,7 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -795,7 +795,7 @@ name = "dlmalloc" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -960,7 +960,7 @@ name = "fortanix-sgx-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -1137,7 +1137,7 @@ name = "hashbrown" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-alloc 1.0.0", "rustc-std-workspace-core 1.0.0", ] @@ -1956,7 +1956,7 @@ dependencies = [ name = "panic_abort" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1967,7 +1967,7 @@ version = "0.0.0" dependencies = [ "alloc 0.0.0", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "unwind 0.0.0", @@ -2138,7 +2138,7 @@ name = "profiler_builtins" version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2675,7 +2675,7 @@ name = "rustc-demangle" version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -2781,7 +2781,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3000,7 +3000,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3063,7 +3063,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3181,7 +3181,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3488,7 +3488,7 @@ dependencies = [ "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4114,7 +4114,7 @@ version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4328,7 +4328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" -"checksum compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "ad9b4731b9e701aefe9e6bd1e9173f30526661508f9aaadaa5caec25ddf95585" +"checksum compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1c086a06d6f52f9c0d50cacdc021bfb6034ddeec9fb7e62f099f13f65472f4" "checksum compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" From 21b502b275ca7d9a7f43c4e1cf09b0b547ecc645 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 20 Jul 2019 13:19:36 +0200 Subject: [PATCH 15/79] warn that raw pointers must be aligned when used, and that writes cause drop --- src/libstd/primitive_docs.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 65fd8c83e1ce5..cab58799d68d4 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -362,8 +362,11 @@ mod prim_unit { } /// /// *[See also the `std::ptr` module](ptr/index.html).* /// -/// Working with raw pointers in Rust is uncommon, -/// typically limited to a few patterns. +/// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. +/// Raw pointers can be unaligned or null when unused. However, when a raw pointer is used to +/// load/store data from/to memory, they must be non-null and aligned. +/// Storing through a raw pointer (`*ptr = data`) calls `drop` on the old value, so +/// [`write`] must be used if memory is not already initialized. /// /// Use the [`null`] and [`null_mut`] functions to create null pointers, and the /// [`is_null`] method of the `*const T` and `*mut T` types to check for null. @@ -442,6 +445,7 @@ mod prim_unit { } /// [`offset`]: ../std/primitive.pointer.html#method.offset /// [`into_raw`]: ../std/boxed/struct.Box.html#method.into_raw /// [`drop`]: ../std/mem/fn.drop.html +/// [`write`]: ../std/ptr/fn.write.html #[stable(feature = "rust1", since = "1.0.0")] mod prim_pointer { } From 2e6b13a649ce4a8f5a608d10133dd2b4b30c35c1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 20 Jul 2019 13:20:08 +0200 Subject: [PATCH 16/79] references must be aligned; also move up the warning that fn ptrs must be non-NULL --- src/libstd/primitive_docs.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index cab58799d68d4..95b803e3461ec 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -895,9 +895,9 @@ mod prim_usize { } /// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut` /// operators on a value, or by using a `ref` or `ref mut` pattern. /// -/// For those familiar with pointers, a reference is just a pointer that is assumed to not be null. -/// In fact, `Option<&T>` has the same memory representation as a nullable pointer, and can be -/// passed across FFI boundaries as such. +/// For those familiar with pointers, a reference is just a pointer that is assumed to be +/// aligned and not null. In fact, `Option<&T>` has the same memory representation as a +/// nullable but aligned pointer, and can be passed across FFI boundaries as such. /// /// In most cases, references can be used much like the original value. Field access, method /// calling, and indexing work the same (save for mutability rules, of course). In addition, the @@ -1040,6 +1040,11 @@ mod prim_ref { } /// [`FnMut`]: ops/trait.FnMut.html /// [`FnOnce`]: ops/trait.FnOnce.html /// +/// Function pointers are pointers that point to *code*, not data. They can be called +/// just like functions. Like references, function pointers are assumed to not be null, +/// so if you want to pass a function pointer over FFI and be able to accommodate null pointers, +/// make your type `Option` with your required signature. +/// /// Plain function pointers are obtained by casting either plain functions, or closures that don't /// capture an environment: /// @@ -1095,10 +1100,6 @@ mod prim_ref { } /// /// These markers can be combined, so `unsafe extern "stdcall" fn()` is a valid type. /// -/// Like references in rust, function pointers are assumed to not be null, so if you want to pass a -/// function pointer over FFI and be able to accommodate null pointers, make your type -/// `Option` with your required signature. -/// /// Function pointers implement the following traits: /// /// * [`Clone`] From 93de733f021598ff6d0fa25c7d6f9dbb7dd58da7 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Jul 2019 14:38:50 +0200 Subject: [PATCH 17/79] Remove tests for -Zlower-128bit-ops --- src/test/mir-opt/lower_128bit_debug_test.rs | 226 -------------------- src/test/mir-opt/lower_128bit_test.rs | 149 ------------- 2 files changed, 375 deletions(-) delete mode 100644 src/test/mir-opt/lower_128bit_debug_test.rs delete mode 100644 src/test/mir-opt/lower_128bit_test.rs diff --git a/src/test/mir-opt/lower_128bit_debug_test.rs b/src/test/mir-opt/lower_128bit_debug_test.rs deleted file mode 100644 index 1d23bac4ee206..0000000000000 --- a/src/test/mir-opt/lower_128bit_debug_test.rs +++ /dev/null @@ -1,226 +0,0 @@ -// asmjs can't even pass i128 as arguments or return values, so ignore it. -// this will hopefully be fixed by the LLVM 5 upgrade (#43370) -// ignore-asmjs -// ignore-emscripten - -// compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=yes - -static TEST_SIGNED: i128 = const_signed(-222); -static TEST_UNSIGNED: u128 = const_unsigned(200); - -const fn const_signed(mut x: i128) -> i128 { - ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7 -} - -const fn const_unsigned(mut x: u128) -> u128 { - ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7 -} - -fn test_signed(mut x: i128) -> i128 { - x += 1; - x -= 2; - x *= 3; - x /= 4; - x %= 5; - x <<= 6; - x >>= 7; - x -} - -fn test_unsigned(mut x: u128) -> u128 { - x += 1; - x -= 2; - x *= 3; - x /= 4; - x %= 5; - x <<= 6; - x >>= 7; - x -} - -fn check(x: i128, y: u128) { - assert_eq!(test_signed(x), -1); - assert_eq!(const_signed(x), -1); - assert_eq!(TEST_SIGNED, -1); - assert_eq!(test_unsigned(y), 2); - assert_eq!(const_unsigned(y), 2); - assert_eq!(TEST_UNSIGNED, 2); -} - -fn main() { - check(-222, 200); -} - -// END RUST SOURCE - -// START rustc.const_signed.Lower128Bit.after.mir -// _8 = _1; -// _9 = const compiler_builtins::int::addsub::rust_i128_addo(move _8, const 1i128) -> bb10; -// ... -// _7 = move (_9.0: i128); -// ... -// _10 = const compiler_builtins::int::addsub::rust_i128_subo(move _7, const 2i128) -> bb11; -// ... -// _6 = move (_10.0: i128); -// ... -// _11 = const compiler_builtins::int::mul::rust_i128_mulo(move _6, const 3i128) -> bb12; -// ... -// _5 = move (_11.0: i128); -// ... -// _12 = Eq(const 4i128, const 0i128); -// assert(!move _12, "attempt to divide by zero") -> bb4; -// ... -// _13 = Eq(const 4i128, const -1i128); -// _14 = Eq(_5, const -170141183460469231731687303715884105728i128); -// _15 = BitAnd(move _13, move _14); -// assert(!move _15, "attempt to divide with overflow") -> bb5; -// ... -// _4 = const compiler_builtins::int::sdiv::rust_i128_div(move _5, const 4i128) -> bb13; -// ... -// _17 = Eq(const 5i128, const -1i128); -// _18 = Eq(_4, const -170141183460469231731687303715884105728i128); -// _19 = BitAnd(move _17, move _18); -// assert(!move _19, "attempt to calculate the remainder with overflow") -> bb7; -// ... -// _3 = const compiler_builtins::int::sdiv::rust_i128_rem(move _4, const 5i128) -> bb15; -// ... -// _2 = move (_20.0: i128); -// ... -// _23 = const 7i32 as u128 (Misc); -// _21 = const compiler_builtins::int::shift::rust_i128_shro(move _2, move _23) -> bb16; -// ... -// _0 = move (_21.0: i128); -// ... -// assert(!move (_9.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_10.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_11.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// _16 = Eq(const 5i128, const 0i128); -// assert(!move _16, "attempt to calculate the remainder with a divisor of zero") -> bb6; -// ... -// assert(!move (_20.1: bool), "attempt to shift left with overflow") -> bb8; -// ... -// _22 = const 6i32 as u128 (Misc); -// _20 = const compiler_builtins::int::shift::rust_i128_shlo(move _3, move _22) -> bb14; -// ... -// assert(!move (_21.1: bool), "attempt to shift right with overflow") -> bb9; -// END rustc.const_signed.Lower128Bit.after.mir - -// START rustc.const_unsigned.Lower128Bit.after.mir -// _8 = _1; -// _9 = const compiler_builtins::int::addsub::rust_u128_addo(move _8, const 1u128) -> bb8; -// ... -// _7 = move (_9.0: u128); -// ... -// _10 = const compiler_builtins::int::addsub::rust_u128_subo(move _7, const 2u128) -> bb9; -// ... -// _6 = move (_10.0: u128); -// ... -// _11 = const compiler_builtins::int::mul::rust_u128_mulo(move _6, const 3u128) -> bb10; -// ... -// _5 = move (_11.0: u128); -// ... -// _12 = Eq(const 4u128, const 0u128); -// assert(!move _12, "attempt to divide by zero") -> bb4; -// ... -// _4 = const compiler_builtins::int::udiv::rust_u128_div(move _5, const 4u128) -> bb11; -// ... -// _3 = const compiler_builtins::int::udiv::rust_u128_rem(move _4, const 5u128) -> bb13; -// ... -// _2 = move (_14.0: u128); -// ... -// _17 = const 7i32 as u128 (Misc); -// _15 = const compiler_builtins::int::shift::rust_u128_shro(move _2, move _17) -> bb14; -// ... -// _0 = move (_15.0: u128); -// ... -// assert(!move (_9.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_10.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_11.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// _13 = Eq(const 5u128, const 0u128); -// assert(!move _13, "attempt to calculate the remainder with a divisor of zero") -> bb5; -// ... -// assert(!move (_14.1: bool), "attempt to shift left with overflow") -> bb6; -// ... -// _16 = const 6i32 as u128 (Misc); -// _14 = const compiler_builtins::int::shift::rust_u128_shlo(move _3, move _16) -> bb12; -// ... -// assert(!move (_15.1: bool), "attempt to shift right with overflow") -> bb7; -// END rustc.const_unsigned.Lower128Bit.after.mir - -// START rustc.test_signed.Lower128Bit.after.mir -// _2 = const compiler_builtins::int::addsub::rust_i128_addo(_1, const 1i128) -> bb10; -// ... -// _1 = move (_2.0: i128); -// _3 = const compiler_builtins::int::addsub::rust_i128_subo(_1, const 2i128) -> bb11; -// ... -// _1 = move (_3.0: i128); -// _4 = const compiler_builtins::int::mul::rust_i128_mulo(_1, const 3i128) -> bb12; -// ... -// _1 = move (_4.0: i128); -// ... -// _1 = const compiler_builtins::int::sdiv::rust_i128_div(_1, const 4i128) -> bb13; -// ... -// _1 = const compiler_builtins::int::sdiv::rust_i128_rem(_1, const 5i128) -> bb15; -// ... -// _1 = move (_13.0: i128); -// ... -// _16 = const 7i32 as u128 (Misc); -// _14 = const compiler_builtins::int::shift::rust_i128_shro(_1, move _16) -> bb16; -// ... -// _1 = move (_14.0: i128); -// ... -// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_3.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_4.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// assert(!move (_13.1: bool), "attempt to shift left with overflow") -> bb8; -// ... -// _15 = const 6i32 as u128 (Misc); -// _13 = const compiler_builtins::int::shift::rust_i128_shlo(_1, move _15) -> bb14; -// ... -// assert(!move (_14.1: bool), "attempt to shift right with overflow") -> bb9; -// END rustc.test_signed.Lower128Bit.after.mir - -// START rustc.test_unsigned.Lower128Bit.after.mir -// _2 = const compiler_builtins::int::addsub::rust_u128_addo(_1, const 1u128) -> bb8; -// ... -// _1 = move (_2.0: u128); -// _3 = const compiler_builtins::int::addsub::rust_u128_subo(_1, const 2u128) -> bb9; -// ... -// _1 = move (_3.0: u128); -// _4 = const compiler_builtins::int::mul::rust_u128_mulo(_1, const 3u128) -> bb10; -// ... -// _1 = move (_4.0: u128); -// ... -// _1 = const compiler_builtins::int::udiv::rust_u128_div(_1, const 4u128) -> bb11; -// ... -// _1 = const compiler_builtins::int::udiv::rust_u128_rem(_1, const 5u128) -> bb13; -// ... -// _1 = move (_7.0: u128); -// ... -// _10 = const 7i32 as u128 (Misc); -// _8 = const compiler_builtins::int::shift::rust_u128_shro(_1, move _10) -> bb14; -// ... -// _1 = move (_8.0: u128); -// ... -// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_3.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_4.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// assert(!move (_7.1: bool), "attempt to shift left with overflow") -> bb6; -// ... -// _9 = const 6i32 as u128 (Misc); -// _7 = const compiler_builtins::int::shift::rust_u128_shlo(_1, move _9) -> bb12; -// ... -// assert(!move (_8.1: bool), "attempt to shift right with overflow") -> bb7; -// END rustc.test_unsigned.Lower128Bit.after.mir diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs deleted file mode 100644 index 7528330b030ce..0000000000000 --- a/src/test/mir-opt/lower_128bit_test.rs +++ /dev/null @@ -1,149 +0,0 @@ -// ignore-emscripten - -// compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no -O - -static TEST_SIGNED: i128 = const_signed(-222); -static TEST_UNSIGNED: u128 = const_unsigned(200); - -const fn const_signed(mut x: i128) -> i128 { - ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7 -} - -const fn const_unsigned(mut x: u128) -> u128 { - ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7 -} - -fn test_signed(mut x: i128) -> i128 { - x += 1; - x -= 2; - x *= 3; - x /= 4; - x %= 5; - x <<= 6; - x >>= 7; - x -} - -fn test_unsigned(mut x: u128) -> u128 { - x += 1; - x -= 2; - x *= 3; - x /= 4; - x %= 5; - x <<= 6; - x >>= 7; - x -} - -fn check(x: i128, y: u128) { - assert_eq!(test_signed(x), -1); - assert_eq!(const_signed(x), -1); - assert_eq!(TEST_SIGNED, -1); - assert_eq!(test_unsigned(y), 2); - assert_eq!(const_unsigned(y), 2); - assert_eq!(TEST_UNSIGNED, 2); -} - -fn main() { - check(-222, 200); -} - -// END RUST SOURCE - -// START rustc.const_signed.Lower128Bit.after.mir -// _7 = const compiler_builtins::int::addsub::rust_i128_add(move _8, const 1i128) -> bb7; -// ... -// _10 = Eq(const 4i128, const -1i128); -// _11 = Eq(_5, const -170141183460469231731687303715884105728i128); -// _12 = BitAnd(move _10, move _11); -// assert(!move _12, "attempt to divide with overflow") -> bb2; -// ... -// _4 = const compiler_builtins::int::sdiv::rust_i128_div(move _5, const 4i128) -> bb8; -// ... -// _14 = Eq(const 5i128, const -1i128); -// _15 = Eq(_4, const -170141183460469231731687303715884105728i128); -// _16 = BitAnd(move _14, move _15); -// assert(!move _16, "attempt to calculate the remainder with overflow") -> bb4; -// ... -// _3 = const compiler_builtins::int::sdiv::rust_i128_rem(move _4, const 5i128) -> bb11; -// ... -// _9 = Eq(const 4i128, const 0i128); -// assert(!move _9, "attempt to divide by zero") -> bb1; -// ... -// _5 = const compiler_builtins::int::mul::rust_i128_mul(move _6, const 3i128) -> bb5; -// ... -// _6 = const compiler_builtins::int::addsub::rust_i128_sub(move _7, const 2i128) -> bb6; -// ... -// _13 = Eq(const 5i128, const 0i128); -// assert(!move _13, "attempt to calculate the remainder with a divisor of zero") -> bb3; -// ... -// _17 = const 7i32 as u32 (Misc); -// _0 = const compiler_builtins::int::shift::rust_i128_shr(move _2, move _17) -> bb9; -// ... -// _18 = const 6i32 as u32 (Misc); -// _2 = const compiler_builtins::int::shift::rust_i128_shl(move _3, move _18) -> bb10; -// END rustc.const_signed.Lower128Bit.after.mir - -// START rustc.const_unsigned.Lower128Bit.after.mir -// _8 = _1; -// _7 = const compiler_builtins::int::addsub::rust_u128_add(move _8, const 1u128) -> bb5; -// ... -// _4 = const compiler_builtins::int::udiv::rust_u128_div(move _5, const 4u128) -> bb6; -// ... -// _3 = const compiler_builtins::int::udiv::rust_u128_rem(move _4, const 5u128) -> bb9; -// ... -// _9 = Eq(const 4u128, const 0u128); -// assert(!move _9, "attempt to divide by zero") -> bb1; -// ... -// _5 = const compiler_builtins::int::mul::rust_u128_mul(move _6, const 3u128) -> bb3; -// ... -// _6 = const compiler_builtins::int::addsub::rust_u128_sub(move _7, const 2u128) -> bb4; -// ... -// _10 = Eq(const 5u128, const 0u128); -// assert(!move _10, "attempt to calculate the remainder with a divisor of zero") -> bb2; -// ... -// return; -// ... -// _11 = const 7i32 as u32 (Misc); -// _0 = const compiler_builtins::int::shift::rust_u128_shr(move _2, move _11) -> bb7; -// ... -// _12 = const 6i32 as u32 (Misc); -// _2 = const compiler_builtins::int::shift::rust_u128_shl(move _3, move _12) -> bb8; - -// END rustc.const_unsigned.Lower128Bit.after.mir - -// START rustc.test_signed.Lower128Bit.after.mir -// _1 = const compiler_builtins::int::addsub::rust_i128_add(_1, const 1i128) -> bb7; -// ... -// _1 = const compiler_builtins::int::sdiv::rust_i128_div(_1, const 4i128) -> bb8; -// ... -// _1 = const compiler_builtins::int::sdiv::rust_i128_rem(_1, const 5i128) -> bb11; -// ... -// _1 = const compiler_builtins::int::mul::rust_i128_mul(_1, const 3i128) -> bb5; -// ... -// _1 = const compiler_builtins::int::addsub::rust_i128_sub(_1, const 2i128) -> bb6; -// ... -// _10 = const 7i32 as u32 (Misc); -// _1 = const compiler_builtins::int::shift::rust_i128_shr(_1, move _10) -> bb9; -// ... -// _11 = const 6i32 as u32 (Misc); -// _1 = const compiler_builtins::int::shift::rust_i128_shl(_1, move _11) -> bb10; -// END rustc.test_signed.Lower128Bit.after.mir - -// START rustc.test_unsigned.Lower128Bit.after.mir -// _1 = const compiler_builtins::int::addsub::rust_u128_add(_1, const 1u128) -> bb5; -// ... -// _1 = const compiler_builtins::int::udiv::rust_u128_div(_1, const 4u128) -> bb6; -// ... -// _1 = const compiler_builtins::int::udiv::rust_u128_rem(_1, const 5u128) -> bb9; -// ... -// _1 = const compiler_builtins::int::mul::rust_u128_mul(_1, const 3u128) -> bb3; -// ... -// _1 = const compiler_builtins::int::addsub::rust_u128_sub(_1, const 2u128) -> bb4; -// ... -// _4 = const 7i32 as u32 (Misc); -// _1 = const compiler_builtins::int::shift::rust_u128_shr(_1, move _4) -> bb7; -// ... -// _5 = const 6i32 as u32 (Misc); -// _1 = const compiler_builtins::int::shift::rust_u128_shl(_1, move _5) -> bb8; -// END rustc.test_unsigned.Lower128Bit.after.mir From b9784b18c2d18dee7100529fd0cbadc8fa331a62 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 20 Jul 2019 12:12:12 +0200 Subject: [PATCH 18/79] Don't link mcjit/interpreter LLVM components --- src/librustc_llvm/build.rs | 13 +++---------- src/rustllvm/PassWrapper.cpp | 2 -- src/rustllvm/rustllvm.h | 4 ---- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 21fa872c8dadb..3def2d8232f63 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -71,7 +71,8 @@ fn main() { let mut optional_components = vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc", - "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"]; + "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx", + "hexagon"]; let mut version_cmd = Command::new(&llvm_config); version_cmd.arg("--version"); @@ -82,27 +83,19 @@ fn main() { if let (Some(major), Some(minor)) = (parts.next(), parts.next()) { (major, minor) } else { - (3, 9) + (6, 0) }; - if major > 3 { - optional_components.push("hexagon"); - } - if major > 6 { optional_components.push("riscv"); } - // FIXME: surely we don't need all these components, right? Stuff like mcjit - // or interpreter the compiler itself never uses. let required_components = &["ipo", "bitreader", "bitwriter", "linker", "asmparser", - "mcjit", "lto", - "interpreter", "instrumentation"]; let components = output(Command::new(&llvm_config).arg("--components")); diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 7d20086d9a22e..0cda3465dc093 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -26,8 +26,6 @@ using namespace llvm; using namespace llvm::legacy; -extern cl::opt EnableARMEHABI; - typedef struct LLVMOpaquePass *LLVMPassRef; typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index a9d267cdb3175..c3f0d174d4b41 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -1,15 +1,11 @@ #include "llvm-c/BitReader.h" #include "llvm-c/Core.h" -#include "llvm-c/ExecutionEngine.h" #include "llvm-c/Object.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/Lint.h" #include "llvm/Analysis/Passes.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/Interpreter.h" -#include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/LLVMContext.h" From f502bf78cba8974cdfbd20f3b524d86b982e5e2b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Jul 2019 12:08:19 +0200 Subject: [PATCH 19/79] sync with nomicon: raw ptr must be non-dangling and aligned every time it is dereferenced --- src/libstd/primitive_docs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 95b803e3461ec..0f66e8cd47ea3 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -363,8 +363,8 @@ mod prim_unit { } /// *[See also the `std::ptr` module](ptr/index.html).* /// /// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. -/// Raw pointers can be unaligned or null when unused. However, when a raw pointer is used to -/// load/store data from/to memory, they must be non-null and aligned. +/// Raw pointers can be unaligned or null when unused. However, when a raw pointer is +/// dereferenced (using the `*` operator), it must be non-null and aligned. /// Storing through a raw pointer (`*ptr = data`) calls `drop` on the old value, so /// [`write`] must be used if memory is not already initialized. /// From 40812224cad0d8b89d52fc1ffc3d44e1615794d4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Jul 2019 12:13:57 +0200 Subject: [PATCH 20/79] apply feedback --- src/libstd/primitive_docs.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 0f66e8cd47ea3..5fa15f1fbde36 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -363,10 +363,11 @@ mod prim_unit { } /// *[See also the `std::ptr` module](ptr/index.html).* /// /// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. -/// Raw pointers can be unaligned or null when unused. However, when a raw pointer is +/// Raw pointers can be unaligned or [`null`] when unused. However, when a raw pointer is /// dereferenced (using the `*` operator), it must be non-null and aligned. -/// Storing through a raw pointer (`*ptr = data`) calls `drop` on the old value, so -/// [`write`] must be used if memory is not already initialized. +/// Storing through a raw pointer using `*ptr = data` calls `drop` on the old value, so +/// [`write`] must be used if memory is not already initialized---otherwise `drop` +/// would be called on the uninitialized memory. /// /// Use the [`null`] and [`null_mut`] functions to create null pointers, and the /// [`is_null`] method of the `*const T` and `*mut T` types to check for null. @@ -896,7 +897,8 @@ mod prim_usize { } /// operators on a value, or by using a `ref` or `ref mut` pattern. /// /// For those familiar with pointers, a reference is just a pointer that is assumed to be -/// aligned and not null. In fact, `Option<&T>` has the same memory representation as a +/// aligned, not null, and pointing to valid (initialized) memory. +/// In fact, `Option<&T>` has the same memory representation as a /// nullable but aligned pointer, and can be passed across FFI boundaries as such. /// /// In most cases, references can be used much like the original value. Field access, method From c442dae5b89f175c2aa52877cb4f693b0f2b2ca6 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 11 Jun 2019 18:36:15 +0200 Subject: [PATCH 21/79] Ignore NLL migrate mode test in the Polonius compare-mode This is test specific to the NLL migrate mode which is irrelevant to -Z polonius. It can't currently be encoded depending on migrate-mode and NLL/Polonius mode, so the NLL compare-mode also ignores it. --- src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr | 2 +- src/test/ui/borrowck/borrowck-migrate-to-nll.rs | 1 + src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr index 663164cfc2c1c..d97883ad47a50 100644 --- a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr @@ -1,5 +1,5 @@ warning[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/borrowck-migrate-to-nll.rs:25:18 + --> $DIR/borrowck-migrate-to-nll.rs:26:18 | LL | (|| { let bar = foo; bar.take() })(); | ^^ --- diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs index 5b7018df91931..a64df9df25948 100644 --- a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs @@ -10,6 +10,7 @@ // just ignore it instead: // ignore-compare-mode-nll +// ignore-compare-mode-polonius // revisions: zflag edition //[zflag]compile-flags: -Z borrowck=migrate diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr index 663164cfc2c1c..d97883ad47a50 100644 --- a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr @@ -1,5 +1,5 @@ warning[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/borrowck-migrate-to-nll.rs:25:18 + --> $DIR/borrowck-migrate-to-nll.rs:26:18 | LL | (|| { let bar = foo; bar.take() })(); | ^^ --- From d4ca9a349ca67f3e23692a1ebfbce919da307738 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 11 Jun 2019 18:53:54 +0200 Subject: [PATCH 22/79] Ignore test issue-45983 in the polonius compare mode There is no difference between the NLL and Polonius outputs, and it manually tests NLLs. --- src/test/ui/borrowck/issue-45983.migrate.stderr | 2 +- src/test/ui/borrowck/issue-45983.nll.stderr | 4 ++-- src/test/ui/borrowck/issue-45983.rs | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/ui/borrowck/issue-45983.migrate.stderr b/src/test/ui/borrowck/issue-45983.migrate.stderr index 3a6b2f69a1ffc..c1564cf07e68a 100644 --- a/src/test/ui/borrowck/issue-45983.migrate.stderr +++ b/src/test/ui/borrowck/issue-45983.migrate.stderr @@ -1,5 +1,5 @@ error: borrowed data cannot be stored outside of its closure - --> $DIR/issue-45983.rs:19:27 + --> $DIR/issue-45983.rs:20:27 | LL | let x = None; | - borrowed data cannot be stored into here... diff --git a/src/test/ui/borrowck/issue-45983.nll.stderr b/src/test/ui/borrowck/issue-45983.nll.stderr index 94360b65ffe36..dff0b4cebace9 100644 --- a/src/test/ui/borrowck/issue-45983.nll.stderr +++ b/src/test/ui/borrowck/issue-45983.nll.stderr @@ -1,5 +1,5 @@ error[E0521]: borrowed data escapes outside of closure - --> $DIR/issue-45983.rs:19:18 + --> $DIR/issue-45983.rs:20:18 | LL | let x = None; | - `x` is declared here, outside of the closure body @@ -9,7 +9,7 @@ LL | give_any(|y| x = Some(y)); | `y` is a reference that is only valid in the closure body error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/issue-45983.rs:19:18 + --> $DIR/issue-45983.rs:20:18 | LL | let x = None; | - help: consider changing this to be mutable: `mut x` diff --git a/src/test/ui/borrowck/issue-45983.rs b/src/test/ui/borrowck/issue-45983.rs index a2656f5939aa1..3cd282077424b 100644 --- a/src/test/ui/borrowck/issue-45983.rs +++ b/src/test/ui/borrowck/issue-45983.rs @@ -7,6 +7,7 @@ // revisions, don't worry about the --compare-mode=nll on this test. // ignore-compare-mode-nll +// ignore-compare-mode-polonius //[nll]compile-flags: -Z borrowck=mir From 273bfd43c1c1b315ef7996ac5ef4ca2a1f1ebd2f Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 11 Jun 2019 19:02:13 +0200 Subject: [PATCH 23/79] Ignore two-phase-reservation-sharing-interference-2.rs in Polonius compare mode This is just a difference from the test construction, it's ignore-compare-mode-nll and manually checks migrate/nll over edition2015/2018. This failure is because the `migrate2015` and `migrate2018` revisions are ran with `-Zpolonius`. There is no actual difference in the errors output by NLLs and Polonius. --- ...se-reservation-sharing-interference-2.migrate2015.stderr | 6 +++--- ...se-reservation-sharing-interference-2.migrate2018.stderr | 6 +++--- ...-phase-reservation-sharing-interference-2.nll2015.stderr | 6 +++--- ...-phase-reservation-sharing-interference-2.nll2018.stderr | 6 +++--- .../two-phase-reservation-sharing-interference-2.rs | 1 + 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr index 565e433f77361..88e9ced03ddde 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:18:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:19:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -11,7 +11,7 @@ LL | v.extend(shared); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:28:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:29:5 | LL | v.extend(&v); | ^^------^--^ @@ -21,7 +21,7 @@ LL | v.extend(&v); | mutable borrow occurs here warning: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:39:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:40:5 | LL | let shared = &v; | -- immutable borrow occurs here diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2018.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2018.stderr index 565e433f77361..88e9ced03ddde 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2018.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2018.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:18:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:19:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -11,7 +11,7 @@ LL | v.extend(shared); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:28:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:29:5 | LL | v.extend(&v); | ^^------^--^ @@ -21,7 +21,7 @@ LL | v.extend(&v); | mutable borrow occurs here warning: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:39:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:40:5 | LL | let shared = &v; | -- immutable borrow occurs here diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr index 730741c7a9ae2..52017394e898e 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:18:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:19:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -10,7 +10,7 @@ LL | v.extend(shared); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:28:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:29:5 | LL | v.extend(&v); | ^^------^--^ @@ -20,7 +20,7 @@ LL | v.extend(&v); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:39:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:40:5 | LL | let shared = &v; | -- immutable borrow occurs here diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr index 730741c7a9ae2..52017394e898e 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:18:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:19:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -10,7 +10,7 @@ LL | v.extend(shared); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:28:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:29:5 | LL | v.extend(&v); | ^^------^--^ @@ -20,7 +20,7 @@ LL | v.extend(&v); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:39:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:40:5 | LL | let shared = &v; | -- immutable borrow occurs here diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.rs b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.rs index de1af3aaa05e4..14f687c23780c 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.rs +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.rs @@ -3,6 +3,7 @@ // everyone else. //ignore-compare-mode-nll +//ignore-compare-mode-polonius //revisions: migrate2015 migrate2018 nll2015 nll2018 From 63c837ef8db1e7452a6ef2faf2660d8038ed5ad5 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 11 Jun 2019 19:08:56 +0200 Subject: [PATCH 24/79] Ignore feature-gate-nll.rs in Polonius compare mode This is a test about turning the NLL feature gate on, ignored by the NLL compare-mode. --- src/test/ui/feature-gates/feature-gate-nll.rs | 1 + src/test/ui/feature-gates/feature-gate-nll.stderr | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/ui/feature-gates/feature-gate-nll.rs b/src/test/ui/feature-gates/feature-gate-nll.rs index ec5eacd162547..8ec752409ab00 100644 --- a/src/test/ui/feature-gates/feature-gate-nll.rs +++ b/src/test/ui/feature-gates/feature-gate-nll.rs @@ -3,6 +3,7 @@ // Don't use compare-mode=nll, since that turns on NLL. // ignore-compare-mode-nll +// ignore-compare-mode-polonius #![feature(rustc_attrs)] diff --git a/src/test/ui/feature-gates/feature-gate-nll.stderr b/src/test/ui/feature-gates/feature-gate-nll.stderr index 37542d52dc2ce..e5b28bbfa2477 100644 --- a/src/test/ui/feature-gates/feature-gate-nll.stderr +++ b/src/test/ui/feature-gates/feature-gate-nll.stderr @@ -1,5 +1,5 @@ warning[E0502]: cannot borrow `*x.1` as immutable because it is also borrowed as mutable - --> $DIR/feature-gate-nll.rs:14:13 + --> $DIR/feature-gate-nll.rs:15:13 | LL | let m = &mut x; | ------ mutable borrow occurs here @@ -14,7 +14,7 @@ LL | m; = note: for more information, try `rustc --explain E0729` error: compilation successful - --> $DIR/feature-gate-nll.rs:10:1 + --> $DIR/feature-gate-nll.rs:11:1 | LL | / fn main() { LL | | let mut x = (33, &0); From 51c15fae61cdf3af53a127b0c062fdacd596ebea Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 11 Jun 2019 19:12:45 +0200 Subject: [PATCH 25/79] Ignore test issue-45696-scribble-on-boxed-borrow.rs in Polonius compare mode Once again, the difference is in the test construction, it is ignored in compare-mode NLL and tested manually with revisions, and fails because the `migrate` revision is ran with `-Zpolonius`. There is no actual difference in the errors output by NLLs and Polonius. --- .../issue-45696-scribble-on-boxed-borrow.migrate.stderr | 8 ++++---- .../issue-45696-scribble-on-boxed-borrow.nll.stderr | 6 +++--- .../ui/issues/issue-45696-scribble-on-boxed-borrow.rs | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr index 479b724ad18f1..2e99572d01828 100644 --- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr +++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr @@ -1,5 +1,5 @@ warning[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:51:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:52:5 | LL | fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -14,7 +14,7 @@ LL | } = note: for more information, try `rustc --explain E0729` warning[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:62:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:63:5 | LL | fn boxed_scribbled<'a>(s: Box>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -29,7 +29,7 @@ LL | } = note: for more information, try `rustc --explain E0729` warning[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:73:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:74:5 | LL | fn boxed_boxed_scribbled<'a>(s: Box>>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -44,7 +44,7 @@ LL | } = note: for more information, try `rustc --explain E0729` error: compilation successful - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:80:1 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:81:1 | LL | / fn main() { LL | | let mut x = 1; diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr index 1b9fb0499260c..45b22511d27d6 100644 --- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr +++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr @@ -1,5 +1,5 @@ error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:51:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:52:5 | LL | fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -10,7 +10,7 @@ LL | } | - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:62:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:63:5 | LL | fn boxed_scribbled<'a>(s: Box>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -21,7 +21,7 @@ LL | } | - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:73:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:74:5 | LL | fn boxed_boxed_scribbled<'a>(s: Box>>) -> &'a mut u32 { | -- lifetime `'a` defined here diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs index f568efa487cd7..9f261884f3d2d 100644 --- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs +++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs @@ -7,6 +7,7 @@ // revisions: nll migrate // ignore-compare-mode-nll +// ignore-compare-mode-polonius // This test is going to pass in the migrate revision, because the AST-borrowck // accepted this code in the past (see notes below). So we use `#[rustc_error]` From ff350f8efa1882c34a2d4e2d48b1fed62b2fae31 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 11 Jun 2019 19:21:24 +0200 Subject: [PATCH 26/79] Bless output of test ui/emit-artifact-notifications.rs for Polonius --- src/test/ui/emit-artifact-notifications.polonius.stderr | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/test/ui/emit-artifact-notifications.polonius.stderr diff --git a/src/test/ui/emit-artifact-notifications.polonius.stderr b/src/test/ui/emit-artifact-notifications.polonius.stderr new file mode 100644 index 0000000000000..47b48b399c25c --- /dev/null +++ b/src/test/ui/emit-artifact-notifications.polonius.stderr @@ -0,0 +1 @@ +{"artifact":"$TEST_BUILD_DIR/emit-artifact-notifications.polonius/libemit_artifact_notifications.rmeta","emit":"metadata"} From 2824db1388dbd300c80466b10dc736d2780b8000 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 11 Jun 2019 19:24:50 +0200 Subject: [PATCH 27/79] Bless output of test save-analysis/emit-notifications.rs for Polonius --- src/test/ui/save-analysis/emit-notifications.polonius.stderr | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/test/ui/save-analysis/emit-notifications.polonius.stderr diff --git a/src/test/ui/save-analysis/emit-notifications.polonius.stderr b/src/test/ui/save-analysis/emit-notifications.polonius.stderr new file mode 100644 index 0000000000000..a1a1b8c63dac3 --- /dev/null +++ b/src/test/ui/save-analysis/emit-notifications.polonius.stderr @@ -0,0 +1,2 @@ +{"artifact":"$TEST_BUILD_DIR/save-analysis/emit-notifications.polonius/save-analysis/libemit_notifications.json","emit":"save-analysis"} +{"artifact":"$TEST_BUILD_DIR/save-analysis/emit-notifications.polonius/libemit_notifications.rlib","emit":"link"} From 94101046ffe4e6a01819631d00d3802a838af98a Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 11 Jun 2019 19:33:36 +0200 Subject: [PATCH 28/79] Bless output of test nll/loan_ends_mid_block_pair.rs for Polonius --- .../loan_ends_mid_block_pair.polonius.stderr | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr diff --git a/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr b/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr new file mode 100644 index 0000000000000..c9537d42c41af --- /dev/null +++ b/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr @@ -0,0 +1,38 @@ +error[E0506]: cannot assign to `data.0` because it is borrowed + --> $DIR/loan_ends_mid_block_pair.rs:12:5 + | +LL | let c = &mut data.0; + | ----------- borrow of `data.0` occurs here +LL | capitalize(c); +LL | data.0 = 'e'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here +... +LL | capitalize(c); + | - borrow later used here + +error[E0506]: cannot assign to `data.0` because it is borrowed + --> $DIR/loan_ends_mid_block_pair.rs:14:5 + | +LL | let c = &mut data.0; + | ----------- borrow of `data.0` occurs here +... +LL | data.0 = 'f'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here +LL | data.0 = 'g'; +LL | capitalize(c); + | - borrow later used here + +error[E0506]: cannot assign to `data.0` because it is borrowed + --> $DIR/loan_ends_mid_block_pair.rs:15:5 + | +LL | let c = &mut data.0; + | ----------- borrow of `data.0` occurs here +... +LL | data.0 = 'g'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here +LL | capitalize(c); + | - borrow later used here + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0506`. From 6a7c15ed25c17dfae87cc8561e7171ab749377e3 Mon Sep 17 00:00:00 2001 From: lqd Date: Wed, 12 Jun 2019 12:55:18 +0200 Subject: [PATCH 29/79] Bless output of test consts/promote_const_let.rs for Polonius --- .../consts/promote_const_let.polonius.stderr | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/ui/consts/promote_const_let.polonius.stderr diff --git a/src/test/ui/consts/promote_const_let.polonius.stderr b/src/test/ui/consts/promote_const_let.polonius.stderr new file mode 100644 index 0000000000000..cf41bd7bdb1eb --- /dev/null +++ b/src/test/ui/consts/promote_const_let.polonius.stderr @@ -0,0 +1,29 @@ +error[E0597]: `y` does not live long enough + --> $DIR/promote_const_let.rs:4:9 + | +LL | let x: &'static u32 = { + | - borrow later stored here +LL | let y = 42; +LL | &y + | ^^ borrowed value does not live long enough +LL | }; + | - `y` dropped here while still borrowed + +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote_const_let.rs:6:28 + | +LL | let x: &'static u32 = &{ + | ____________------------____^ + | | | + | | type annotation requires that borrow lasts for `'static` +LL | | let y = 42; +LL | | y +LL | | }; + | |_____^ creates a temporary which is freed while still in use +LL | } + | - temporary value is freed at the end of this statement + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0597, E0716. +For more information about an error, try `rustc --explain E0597`. From c5a1bc1e5c45c507b247e92d33a35190257c6726 Mon Sep 17 00:00:00 2001 From: lqd Date: Wed, 12 Jun 2019 13:01:26 +0200 Subject: [PATCH 30/79] Bless output of test nll/get_default.rs for Polonius 2 of the 3 errors are "fixed by Polonius" :tada: --- src/test/ui/nll/get_default.polonius.stderr | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/nll/get_default.polonius.stderr diff --git a/src/test/ui/nll/get_default.polonius.stderr b/src/test/ui/nll/get_default.polonius.stderr new file mode 100644 index 0000000000000..2df6d5d61fc46 --- /dev/null +++ b/src/test/ui/nll/get_default.polonius.stderr @@ -0,0 +1,15 @@ +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable + --> $DIR/get_default.rs:32:17 + | +LL | match map.get() { + | --- immutable borrow occurs here +LL | Some(v) => { +LL | map.set(String::new()); // Both AST and MIR error here + | ^^^ mutable borrow occurs here +LL | +LL | return v; + | - immutable borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. From 292d5c18c93df1a502a03f228e36c4c1da3d3f6b Mon Sep 17 00:00:00 2001 From: lqd Date: Wed, 12 Jun 2019 19:27:59 +0200 Subject: [PATCH 31/79] Bless output of test generator/ref-escapes-but-not-over-yield.rs for Polonius --- ...escapes-but-not-over-yield.polonius.stderr | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr new file mode 100644 index 0000000000000..530bf368f676e --- /dev/null +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr @@ -0,0 +1,20 @@ +error[E0597]: `b` does not live long enough + --> $DIR/ref-escapes-but-not-over-yield.rs:11:13 + | +LL | let mut b = move || { + | _________________- +LL | | yield(); +LL | | let b = 5; +LL | | a = &b; + | | ^^ borrowed value does not live long enough +LL | | +LL | | }; + | | - + | | | + | | `b` dropped here while still borrowed + | |_____... and the borrow might be used here, when that temporary is dropped and runs the destructor for generator + | a temporary with access to the borrow is created here ... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. From 6fe52928a3dd9a69ebd6422a23aba879871026c4 Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 28 Jun 2019 13:37:08 +0200 Subject: [PATCH 32/79] Bless output of test borrowck/borrowck-escaping-closure-error-2.rs for Polonius --- ...owck-escaping-closure-error-2.polonius.stderr | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr new file mode 100644 index 0000000000000..89af8764557ff --- /dev/null +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr @@ -0,0 +1,16 @@ +error[E0597]: `books` does not live long enough + --> $DIR/borrowck-escaping-closure-error-2.rs:11:17 + | +LL | Box::new(|| books.push(4)) + | ------------^^^^^--------- + | | | | + | | | borrowed value does not live long enough + | | value captured here + | borrow later used here +LL | +LL | } + | - `books` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. From 7db61e78c01b93cceb28cf87e69d5d6c0ca0b482 Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 28 Jun 2019 14:21:48 +0200 Subject: [PATCH 33/79] Bless output of test borrowck/two-phase-surprise-no-conflict.rs for Polonius --- ...phase-surprise-no-conflict.polonius.stderr | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr diff --git a/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr b/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr new file mode 100644 index 0000000000000..7b246426a2333 --- /dev/null +++ b/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr @@ -0,0 +1,148 @@ +error[E0503]: cannot use `self.cx` because it was mutably borrowed + --> $DIR/two-phase-surprise-no-conflict.rs:21:23 + | +LL | let _mut_borrow = &mut *self; + | ---------- borrow of `*self` occurs here +LL | let _access = self.cx; + | ^^^^^^^ use of borrowed `*self` +LL | +LL | _mut_borrow; + | ----------- borrow later used here + +error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-surprise-no-conflict.rs:57:17 + | +LL | self.hash_expr(&self.cx_mut.body(eid).value); + | ^^^^^---------^^-----------^^^^^^^^^^^^^^^^^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:119:51 + | +LL | reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut))); + | --- --------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:122:54 + | +LL | reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut))); + | --- -------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:125:53 + | +LL | reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut))); + | --- ------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:128:44 + | +LL | reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut)); + | --- ------------ ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-surprise-no-conflict.rs:138:5 + | +LL | reg.register_bound(Box::new(CapturePass::new(®.sess_mut))); + | ^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-surprise-no-conflict.rs:141:5 + | +LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut))); + | ^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-surprise-no-conflict.rs:144:5 + | +LL | reg.register_ref(&CapturePass::new(®.sess_mut)); + | ^^^^------------^^^^^^^^^^^^^^^^^^^-------------^^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0499]: cannot borrow `*reg` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:154:5 + | +LL | reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); + | ^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^ + | | | | + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:154:54 + | +LL | reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); + | --- -------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `*reg` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:158:5 + | +LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); + | ^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^ + | | | | + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:158:53 + | +LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); + | --- ------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `*reg` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:162:5 + | +LL | reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut)); + | ^^^^------------^^^^^^^^^^^^^^^^^^^^^^^-----------------^^ + | | | | + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:162:44 + | +LL | reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut)); + | --- ------------ ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error: aborting due to 15 previous errors + +Some errors have detailed explanations: E0499, E0502, E0503. +For more information about an error, try `rustc --explain E0499`. From 08c25b5122574e1dca21c673cb6d2e7ceee489b1 Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 28 Jun 2019 14:26:05 +0200 Subject: [PATCH 34/79] Bless output of test dropck/dropck_trait_cycle_checked.rs for Polonius --- ...dropck_trait_cycle_checked.polonius.stderr | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr diff --git a/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr b/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr new file mode 100644 index 0000000000000..dbcb0fcebb73d --- /dev/null +++ b/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr @@ -0,0 +1,74 @@ +error[E0597]: `o2` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:111:13 + | +LL | o1.set0(&o2); + | ^^^ borrowed value does not live long enough +... +LL | } + | - + | | + | `o2` dropped here while still borrowed + | borrow might be used here, when `o2` is dropped and runs the destructor for type `std::boxed::Box>` + +error[E0597]: `o3` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:112:13 + | +LL | o1.set1(&o3); + | ^^^ borrowed value does not live long enough +... +LL | } + | - + | | + | `o3` dropped here while still borrowed + | borrow might be used here, when `o3` is dropped and runs the destructor for type `std::boxed::Box>` + +error[E0597]: `o2` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:113:13 + | +LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); + | -------- cast requires that `o2` is borrowed for `'static` +... +LL | o2.set0(&o2); + | ^^^ borrowed value does not live long enough +... +LL | } + | - `o2` dropped here while still borrowed + +error[E0597]: `o3` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:114:13 + | +LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); + | -------- cast requires that `o3` is borrowed for `'static` +... +LL | o2.set1(&o3); + | ^^^ borrowed value does not live long enough +... +LL | } + | - `o3` dropped here while still borrowed + +error[E0597]: `o1` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:115:13 + | +LL | o3.set0(&o1); + | ^^^ borrowed value does not live long enough +LL | o3.set1(&o2); +LL | } + | - + | | + | `o1` dropped here while still borrowed + | borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box>` + +error[E0597]: `o2` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:116:13 + | +LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); + | -------- cast requires that `o2` is borrowed for `'static` +... +LL | o3.set1(&o2); + | ^^^ borrowed value does not live long enough +LL | } + | - `o2` dropped here while still borrowed + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0597`. From 9a82f52e59c39e3a101a51cc6902ab0064c61c6a Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 5 Jul 2019 19:18:36 +0200 Subject: [PATCH 35/79] Create a dedicated polonius test folder --- src/test/ui/nll/{ => polonius}/polonius-smoke-test.rs | 0 src/test/ui/nll/{ => polonius}/polonius-smoke-test.stderr | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/nll/{ => polonius}/polonius-smoke-test.rs (100%) rename src/test/ui/nll/{ => polonius}/polonius-smoke-test.stderr (100%) diff --git a/src/test/ui/nll/polonius-smoke-test.rs b/src/test/ui/nll/polonius/polonius-smoke-test.rs similarity index 100% rename from src/test/ui/nll/polonius-smoke-test.rs rename to src/test/ui/nll/polonius/polonius-smoke-test.rs diff --git a/src/test/ui/nll/polonius-smoke-test.stderr b/src/test/ui/nll/polonius/polonius-smoke-test.stderr similarity index 100% rename from src/test/ui/nll/polonius-smoke-test.stderr rename to src/test/ui/nll/polonius/polonius-smoke-test.stderr From a7b924654070f59297e86ff372ac74c5c701929f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 22 Jul 2019 10:33:11 +0200 Subject: [PATCH 36/79] weasle, weasle --- src/libstd/primitive_docs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 5fa15f1fbde36..b7196a8670138 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -1043,9 +1043,9 @@ mod prim_ref { } /// [`FnOnce`]: ops/trait.FnOnce.html /// /// Function pointers are pointers that point to *code*, not data. They can be called -/// just like functions. Like references, function pointers are assumed to not be null, -/// so if you want to pass a function pointer over FFI and be able to accommodate null pointers, -/// make your type `Option` with your required signature. +/// just like functions. Like references, function pointers are, among other things, assumed to +/// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null +/// pointers, make your type `Option` with your required signature. /// /// Plain function pointers are obtained by casting either plain functions, or closures that don't /// capture an environment: From 6d9a4f978313798a275a150ffd0f103609484ebd Mon Sep 17 00:00:00 2001 From: lqd Date: Mon, 15 Jul 2019 15:54:43 +0200 Subject: [PATCH 37/79] Polonius facts: kill loans on Call terminators and StorageDead --- .../borrow_check/nll/constraint_generation.rs | 74 +++++++++++++++---- src/test/ui/nll/polonius/calls-kill-loans.rs | 24 ++++++ 2 files changed, 82 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/nll/polonius/calls-kill-loans.rs diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 055568f0a27a2..25d0eaafc0049 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -6,8 +6,8 @@ use crate::borrow_check::nll::region_infer::values::LivenessValues; use rustc::infer::InferCtxt; use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; -use rustc::mir::{BasicBlock, BasicBlockData, Location, Body, Place, PlaceBase, Rvalue}; -use rustc::mir::{SourceInfo, Statement, Terminator}; +use rustc::mir::{BasicBlock, BasicBlockData, Location, Body, Place, PlaceBase, Rvalue, TerminatorKind}; +use rustc::mir::{Local, SourceInfo, Statement, StatementKind, Terminator}; use rustc::mir::UserTypeProjection; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid, Ty}; @@ -114,6 +114,17 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { self.location_table .start_index(location.successor_within_block()), )); + + // If there are borrows on this now dead local, we need to record them as `killed`. + if let StatementKind::StorageDead(ref local) = statement.kind { + record_killed_borrows_for_local( + all_facts, + self.borrow_set, + self.location_table, + local, + location, + ); + } } self.super_statement(statement, location); @@ -127,20 +138,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { ) { // When we see `X = ...`, then kill borrows of // `(*X).foo` and so forth. - if let Some(all_facts) = self.all_facts { - if let Place { - base: PlaceBase::Local(temp), - projection: None, - } = place { - if let Some(borrow_indices) = self.borrow_set.local_map.get(temp) { - all_facts.killed.reserve(borrow_indices.len()); - for &borrow_index in borrow_indices { - let location_index = self.location_table.mid_index(location); - all_facts.killed.push((borrow_index, location_index)); - } - } - } - } + self.record_killed_borrows_for_place(place, location); self.super_assign(place, rvalue, location); } @@ -167,6 +165,14 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { } } + // A `Call` terminator's return value can be a local which has borrows, + // so we need to record those as `killed` as well. + if let TerminatorKind::Call { ref destination, .. } = terminator.kind { + if let Some((place, _)) = destination { + self.record_killed_borrows_for_place(place, location); + } + } + self.super_terminator(terminator, location); } @@ -201,4 +207,40 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { self.liveness_constraints.add_element(vid, location); }); } + + /// When recording facts for Polonius, records the borrows on the specified place + /// as `killed`. For example, when assigning to a local, or on a call's return destination. + fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Location) { + if let Some(all_facts) = self.all_facts { + if let Place { + base: PlaceBase::Local(local), + projection: None, + } = place { + record_killed_borrows_for_local( + all_facts, + self.borrow_set, + self.location_table, + local, + location, + ); + } + } + } +} + +/// When recording facts for Polonius, records the borrows on the specified local as `killed`. +fn record_killed_borrows_for_local( + all_facts: &mut AllFacts, + borrow_set: &BorrowSet<'_>, + location_table: &LocationTable, + local: &Local, + location: Location, +) { + if let Some(borrow_indices) = borrow_set.local_map.get(local) { + all_facts.killed.reserve(borrow_indices.len()); + for &borrow_index in borrow_indices { + let location_index = location_table.mid_index(location); + all_facts.killed.push((borrow_index, location_index)); + } + } } diff --git a/src/test/ui/nll/polonius/calls-kill-loans.rs b/src/test/ui/nll/polonius/calls-kill-loans.rs new file mode 100644 index 0000000000000..3121571478893 --- /dev/null +++ b/src/test/ui/nll/polonius/calls-kill-loans.rs @@ -0,0 +1,24 @@ +// `Call` terminators can write to a local which has existing loans +// and those need to be killed like a regular assignment to a local. +// This is a simplified version of issue 47680, is correctly accepted +// by NLL but was incorrectly rejected by Polonius because of these +// missing `killed` facts. + +// build-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct Thing; + +impl Thing { + fn next(&mut self) -> &mut Self { unimplemented!() } +} + +fn main() { + let mut temp = &mut Thing; + + loop { + let v = temp.next(); + temp = v; // accepted by NLL, was incorrectly rejected by Polonius + } +} From 0bd2b3235808e50f1568d89bb85e2ec6f8397e49 Mon Sep 17 00:00:00 2001 From: lqd Date: Mon, 15 Jul 2019 18:04:41 +0200 Subject: [PATCH 38/79] Bless output of test borrowck/promote-ref-mut-in-let-issue-46557.rs for Polonius --- ...ref-mut-in-let-issue-46557.polonius.stderr | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr new file mode 100644 index 0000000000000..a5b2e8762746c --- /dev/null +++ b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr @@ -0,0 +1,59 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:5:21 + | +LL | let ref mut x = 1234543; + | ^^^^^^^ creates a temporary which is freed while still in use +LL | x + | - borrow later used here +LL | } + | - temporary value is freed at the end of this statement + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:10:25 + | +LL | let (ref mut x, ) = (1234543, ); + | ^^^^^^^^^^^ creates a temporary which is freed while still in use +LL | x + | - borrow later used here +LL | } + | - temporary value is freed at the end of this statement + | + = note: consider using a `let` binding to create a longer lived value + +error[E0515]: cannot return value referencing temporary value + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:15:5 + | +LL | match 1234543 { + | ^ ------- temporary value created here + | _____| + | | +LL | | ref mut x => x +LL | | } + | |_____^ returns a value referencing data owned by the current function + +error[E0515]: cannot return value referencing temporary value + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:21:5 + | +LL | match (123443,) { + | ^ --------- temporary value created here + | _____| + | | +LL | | (ref mut x,) => x, +LL | | } + | |_____^ returns a value referencing data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:27:5 + | +LL | &mut 1234543 + | ^^^^^------- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0515, E0716. +For more information about an error, try `rustc --explain E0515`. From ed1625f29eabb0659cd9799623922c86a2e4415b Mon Sep 17 00:00:00 2001 From: lqd Date: Mon, 15 Jul 2019 18:22:02 +0200 Subject: [PATCH 39/79] Ignore test hrtb/issue-30786.rs in Polonius compare mode --- src/test/ui/hrtb/issue-30786.migrate.stderr | 6 +++--- src/test/ui/hrtb/issue-30786.nll.stderr | 4 ++-- src/test/ui/hrtb/issue-30786.rs | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/test/ui/hrtb/issue-30786.migrate.stderr b/src/test/ui/hrtb/issue-30786.migrate.stderr index 9a4f877282245..e7deca7644b0e 100644 --- a/src/test/ui/hrtb/issue-30786.migrate.stderr +++ b/src/test/ui/hrtb/issue-30786.migrate.stderr @@ -1,11 +1,11 @@ error: implementation of `Stream` is not general enough - --> $DIR/issue-30786.rs:107:22 + --> $DIR/issue-30786.rs:108:22 | LL | let map = source.map(|x: &_| x); | ^^^ | - = note: `Stream` would have to be implemented for the type `&'0 mut Map`, for any lifetime `'0` - = note: but `Stream` is actually implemented for the type `&'1 mut Map`, for some specific lifetime `'1` + = note: `Stream` would have to be implemented for the type `&'0 mut Map`, for any lifetime `'0` + = note: but `Stream` is actually implemented for the type `&'1 mut Map`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr index 5c865d76851d3..8614d86d93ac3 100644 --- a/src/test/ui/hrtb/issue-30786.nll.stderr +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/issue-30786.rs:111:18 + --> $DIR/issue-30786.rs:112:18 | LL | let filter = map.filter(|x: &_| true); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/issue-30786.rs:113:17 + --> $DIR/issue-30786.rs:114:17 | LL | let count = filter.count(); // Assert that we still have a valid stream. | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs index 321b83c3459d0..b9920a1950498 100644 --- a/src/test/ui/hrtb/issue-30786.rs +++ b/src/test/ui/hrtb/issue-30786.rs @@ -12,6 +12,7 @@ // revisions, don't worry about the --compare-mode=nll on this test. // ignore-compare-mode-nll +// ignore-compare-mode-polonius //[nll]compile-flags: -Z borrowck=mir From 40e6b025b27892877935c96315920b382083fcce Mon Sep 17 00:00:00 2001 From: lqd Date: Mon, 15 Jul 2019 18:26:51 +0200 Subject: [PATCH 40/79] Bless output of test nll/return-ref-mut-issue-46557.rs for Polonius --- .../return-ref-mut-issue-46557.polonius.stderr | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr new file mode 100644 index 0000000000000..8e3cf59cffb44 --- /dev/null +++ b/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr @@ -0,0 +1,15 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/return-ref-mut-issue-46557.rs:4:21 + | +LL | let ref mut x = 1234543; + | ^^^^^^^ creates a temporary which is freed while still in use +LL | x + | - borrow later used here +LL | } + | - temporary value is freed at the end of this statement + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0716`. From 9bd9b0d9bf616e8a8e7f6b4c3580041b007dd868 Mon Sep 17 00:00:00 2001 From: lqd Date: Mon, 15 Jul 2019 18:50:50 +0200 Subject: [PATCH 41/79] Add test extracted from rand, checking that StorageDead kills loans Like "call-kills-loans", Polonius didn't know about some `killed` facts. --- .../nll/polonius/storagedead-kills-loans.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/ui/nll/polonius/storagedead-kills-loans.rs diff --git a/src/test/ui/nll/polonius/storagedead-kills-loans.rs b/src/test/ui/nll/polonius/storagedead-kills-loans.rs new file mode 100644 index 0000000000000..3c121d3cd1882 --- /dev/null +++ b/src/test/ui/nll/polonius/storagedead-kills-loans.rs @@ -0,0 +1,28 @@ +// Whenever a `StorageDead` MIR statement destroys a value `x`, +// we should kill all loans of `x`. This is extracted from `rand 0.4.6`, +// is correctly accepted by NLL but was incorrectly rejected by +// Polonius because of these missing `killed` facts. + +// build-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +use std::{io, mem}; +use std::io::Read; + +fn fill(r: &mut Read, mut buf: &mut [u8]) -> io::Result<()> { + while buf.len() > 0 { + match r.read(buf).unwrap() { + 0 => return Err(io::Error::new(io::ErrorKind::Other, + "end of file reached")), + n => buf = &mut mem::replace(&mut buf, &mut [])[n..], + // ^- Polonius had multiple errors on the previous line (where NLL has none) + // as it didn't know `buf` was killed here, and would + // incorrectly reject both the borrow expression, and the assignment. + } + } + Ok(()) +} + +fn main() { +} From 606f7984e7fd0c33b6c7bd040dfd057569f1c19b Mon Sep 17 00:00:00 2001 From: lqd Date: Mon, 15 Jul 2019 18:51:55 +0200 Subject: [PATCH 42/79] Rename test so that both "kills-loans" tests match names --- .../nll/polonius/{calls-kill-loans.rs => call-kills-loans.rs} | 0 src/test/ui/nll/polonius/storagedead-kills-loans.rs | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename src/test/ui/nll/polonius/{calls-kill-loans.rs => call-kills-loans.rs} (100%) diff --git a/src/test/ui/nll/polonius/calls-kill-loans.rs b/src/test/ui/nll/polonius/call-kills-loans.rs similarity index 100% rename from src/test/ui/nll/polonius/calls-kill-loans.rs rename to src/test/ui/nll/polonius/call-kills-loans.rs diff --git a/src/test/ui/nll/polonius/storagedead-kills-loans.rs b/src/test/ui/nll/polonius/storagedead-kills-loans.rs index 3c121d3cd1882..f69bfdf459320 100644 --- a/src/test/ui/nll/polonius/storagedead-kills-loans.rs +++ b/src/test/ui/nll/polonius/storagedead-kills-loans.rs @@ -10,7 +10,8 @@ use std::{io, mem}; use std::io::Read; -fn fill(r: &mut Read, mut buf: &mut [u8]) -> io::Result<()> { +#[allow(dead_code)] +fn fill(r: &mut dyn Read, mut buf: &mut [u8]) -> io::Result<()> { while buf.len() > 0 { match r.read(buf).unwrap() { 0 => return Err(io::Error::new(io::ErrorKind::Other, From 9e0fb6fad256124354778783a135f3b0ac0553ee Mon Sep 17 00:00:00 2001 From: lqd Date: Mon, 15 Jul 2019 18:57:16 +0200 Subject: [PATCH 43/79] Make both polonius loans tests check-pass --- src/test/ui/nll/polonius/call-kills-loans.rs | 2 +- src/test/ui/nll/polonius/storagedead-kills-loans.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/nll/polonius/call-kills-loans.rs b/src/test/ui/nll/polonius/call-kills-loans.rs index 3121571478893..57dc140110246 100644 --- a/src/test/ui/nll/polonius/call-kills-loans.rs +++ b/src/test/ui/nll/polonius/call-kills-loans.rs @@ -4,7 +4,7 @@ // by NLL but was incorrectly rejected by Polonius because of these // missing `killed` facts. -// build-pass +// check-pass // compile-flags: -Z borrowck=mir -Z polonius // ignore-compare-mode-nll diff --git a/src/test/ui/nll/polonius/storagedead-kills-loans.rs b/src/test/ui/nll/polonius/storagedead-kills-loans.rs index f69bfdf459320..ff801cbf9f35d 100644 --- a/src/test/ui/nll/polonius/storagedead-kills-loans.rs +++ b/src/test/ui/nll/polonius/storagedead-kills-loans.rs @@ -3,7 +3,7 @@ // is correctly accepted by NLL but was incorrectly rejected by // Polonius because of these missing `killed` facts. -// build-pass +// check-pass // compile-flags: -Z borrowck=mir -Z polonius // ignore-compare-mode-nll From 823ab42e66cc966098030616e36e4aa7417dcf7f Mon Sep 17 00:00:00 2001 From: lqd Date: Mon, 15 Jul 2019 19:04:50 +0200 Subject: [PATCH 44/79] Bless output of test unboxed-closures/unboxed-closures-failed-recursive-fn-1.rs for Polonius --- ...ures-failed-recursive-fn-1.polonius.stderr | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr new file mode 100644 index 0000000000000..4b906f75149af --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr @@ -0,0 +1,60 @@ +error[E0597]: `factorial` does not live long enough + --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:15:17 + | +LL | let f = |x: u32| -> u32 { + | --------------- value captured here +LL | let g = factorial.as_ref().unwrap(); + | ^^^^^^^^^ borrowed value does not live long enough +... +LL | } + | - + | | + | `factorial` dropped here while still borrowed + | borrow might be used here, when `factorial` is dropped and runs the destructor for type `std::option::Option u32>>` + +error[E0506]: cannot assign to `factorial` because it is borrowed + --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:20:5 + | +LL | let f = |x: u32| -> u32 { + | --------------- borrow of `factorial` occurs here +LL | let g = factorial.as_ref().unwrap(); + | --------- borrow occurs due to use in closure +... +LL | factorial = Some(Box::new(f)); + | ^^^^^^^^^ + | | + | assignment to borrowed `factorial` occurs here + | borrow later used here + +error[E0597]: `factorial` does not live long enough + --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:28:17 + | +LL | let f = |x: u32| -> u32 { + | --------------- value captured here +LL | let g = factorial.as_ref().unwrap(); + | ^^^^^^^^^ borrowed value does not live long enough +... +LL | } + | - + | | + | `factorial` dropped here while still borrowed + | borrow might be used here, when `factorial` is dropped and runs the destructor for type `std::option::Option u32>>` + +error[E0506]: cannot assign to `factorial` because it is borrowed + --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:33:5 + | +LL | let f = |x: u32| -> u32 { + | --------------- borrow of `factorial` occurs here +LL | let g = factorial.as_ref().unwrap(); + | --------- borrow occurs due to use in closure +... +LL | factorial = Some(Box::new(f)); + | ^^^^^^^^^ + | | + | assignment to borrowed `factorial` occurs here + | borrow later used here + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0506, E0597. +For more information about an error, try `rustc --explain E0506`. From 2f3e36f51a7055da3b55253edad7df594b0711d7 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 16 Jul 2019 17:30:41 +0200 Subject: [PATCH 45/79] Polonius: generate `killed` facts for assignments to projections --- .../borrow_check/nll/constraint_generation.rs | 89 ++++++++++++++++--- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 25d0eaafc0049..95c3299693b68 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -3,12 +3,15 @@ use crate::borrow_check::location::LocationTable; use crate::borrow_check::nll::ToRegionVid; use crate::borrow_check::nll::facts::AllFacts; use crate::borrow_check::nll::region_infer::values::LivenessValues; +use crate::borrow_check::places_conflict; use rustc::infer::InferCtxt; use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; -use rustc::mir::{BasicBlock, BasicBlockData, Location, Body, Place, PlaceBase, Rvalue, TerminatorKind}; -use rustc::mir::{Local, SourceInfo, Statement, StatementKind, Terminator}; -use rustc::mir::UserTypeProjection; +use rustc::mir::{ + BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceBase, Projection, + ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, + UserTypeProjection, +}; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid, Ty}; use rustc::ty::subst::SubstsRef; @@ -27,6 +30,7 @@ pub(super) fn generate_constraints<'cx, 'tcx>( liveness_constraints, location_table, all_facts, + body, }; for (bb, data) in body.basic_blocks().iter_enumerated() { @@ -41,6 +45,7 @@ struct ConstraintGeneration<'cg, 'cx, 'tcx> { location_table: &'cg LocationTable, liveness_constraints: &'cg mut LivenessValues, borrow_set: &'cg BorrowSet<'tcx>, + body: &'cg Body<'tcx>, } impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { @@ -212,17 +217,73 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { /// as `killed`. For example, when assigning to a local, or on a call's return destination. fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Location) { if let Some(all_facts) = self.all_facts { - if let Place { - base: PlaceBase::Local(local), - projection: None, - } = place { - record_killed_borrows_for_local( - all_facts, - self.borrow_set, - self.location_table, - local, - location, - ); + // Depending on the `Place` we're killing: + // - if it's a local, or a single deref of a local, + // we kill all the borrows on the local. + // - if it's a deeper projection, we have to filter which + // of the borrows are killed: the ones whose `borrowed_place` + // conflicts with the `place`. + match place { + Place { + base: PlaceBase::Local(local), + projection: None, + } | + Place { + base: PlaceBase::Local(local), + projection: Some(box Projection { + base: None, + elem: ProjectionElem::Deref, + }), + } => { + debug!( + "Recording `killed` facts for borrows of local={:?} at location={:?}", + local, location + ); + + record_killed_borrows_for_local( + all_facts, + self.borrow_set, + self.location_table, + local, + location, + ); + } + + Place { + base: PlaceBase::Static(_), + .. + } => { + // Ignore kills of static or static mut variables. + } + + Place { + base: PlaceBase::Local(local), + projection: Some(_), + } => { + // Kill conflicting borrows of the innermost local. + debug!( + "Recording `killed` facts for borrows of \ + innermost projected local={:?} at location={:?}", + local, location + ); + + if let Some(borrow_indices) = self.borrow_set.local_map.get(local) { + for &borrow_index in borrow_indices { + let places_conflict = places_conflict::places_conflict( + self.infcx.tcx, + self.body, + &self.borrow_set.borrows[borrow_index].borrowed_place, + place, + places_conflict::PlaceConflictBias::NoOverlap, + ); + + if places_conflict { + let location_index = self.location_table.mid_index(location); + all_facts.killed.push((borrow_index, location_index)); + } + } + } + } } } } From d41e002111dd61efa08d996cfc1085fc00472288 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 16 Jul 2019 17:32:38 +0200 Subject: [PATCH 46/79] Add test checking various assignments are accepted in Polonius --- .../ui/nll/polonius/assignment-kills-loans.rs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/test/ui/nll/polonius/assignment-kills-loans.rs diff --git a/src/test/ui/nll/polonius/assignment-kills-loans.rs b/src/test/ui/nll/polonius/assignment-kills-loans.rs new file mode 100644 index 0000000000000..8301f603cb4d3 --- /dev/null +++ b/src/test/ui/nll/polonius/assignment-kills-loans.rs @@ -0,0 +1,88 @@ +#![allow(dead_code)] + +// This tests the various kinds of assignments there are. Polonius used to generate `killed` +// facts only on simple assigments, but not projections, incorrectly causing errors to be emitted +// for code accepted by NLL. They are all variations from example code in the NLL RFC. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct List { + value: T, + next: Option>>, +} + +// Assignment to a local: the `list` assignment should clear the existing +// borrows of `list.value` and `list.next` +fn assignment_to_local(mut list: &mut List) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + list = n; + } else { + return result; + } + } +} + +// Assignment to a deref projection: the `*list` assignment should clear the existing +// borrows of `list.value` and `list.next` +fn assignment_to_deref_projection(mut list: Box<&mut List>) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + *list = n; + } else { + return result; + } + } +} + +// Assignment to a field projection: the `list.0` assignment should clear the existing +// borrows of `list.0.value` and `list.0.next` +fn assignment_to_field_projection(mut list: (&mut List,)) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.0.value); + if let Some(n) = list.0.next.as_mut() { + list.0 = n; + } else { + return result; + } + } +} + +// Assignment to a deref field projection: the `*list.0` assignment should clear the existing +// borrows of `list.0.value` and `list.0.next` +fn assignment_to_deref_field_projection(mut list: (Box<&mut List>,)) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.0.value); + if let Some(n) = list.0.next.as_mut() { + *list.0 = n; + } else { + return result; + } + } +} + +// Similar to `assignment_to_deref_field_projection` but through a longer projection chain +fn assignment_through_projection_chain( + mut list: (((((Box<&mut List>,),),),),), +) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut ((((list.0).0).0).0).0.value); + if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { + *((((list.0).0).0).0).0 = n; + } else { + return result; + } + } +} + +fn main() { +} \ No newline at end of file From 770129c28039ab7501cdc0f2f7ca1a38e22208f0 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 16 Jul 2019 17:33:16 +0200 Subject: [PATCH 47/79] Add test to check that assignments to projections do not kill too many loans --- .../polonius/assignment-to-differing-field.rs | 50 ++++++++++++++++++ .../assignment-to-differing-field.stderr | 51 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/test/ui/nll/polonius/assignment-to-differing-field.rs create mode 100644 src/test/ui/nll/polonius/assignment-to-differing-field.stderr diff --git a/src/test/ui/nll/polonius/assignment-to-differing-field.rs b/src/test/ui/nll/polonius/assignment-to-differing-field.rs new file mode 100644 index 0000000000000..c0ba1b983fc35 --- /dev/null +++ b/src/test/ui/nll/polonius/assignment-to-differing-field.rs @@ -0,0 +1,50 @@ +#![allow(dead_code)] + +// Compared to `assignment-kills-loans.rs`, we check here +// that we do not kill too many borrows. Assignments to the `.1` +// field projections should leave the borrows on `.0` intact. + +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct List { + value: T, + next: Option>>, +} + + +fn assignment_to_field_projection<'a, T>( + mut list: (&'a mut List, &'a mut List), +) -> Vec<&'a mut T> { + let mut result = vec![]; + loop { + result.push(&mut (list.0).value); + //~^ ERROR cannot borrow `list.0.value` as mutable + + if let Some(n) = (list.0).next.as_mut() { + //~^ ERROR cannot borrow `list.0.next` as mutable + list.1 = n; + } else { + return result; + } + } +} + +fn assignment_through_projection_chain<'a, T>( + mut list: (((((Box<&'a mut List>, Box<&'a mut List>),),),),), +) -> Vec<&'a mut T> { + let mut result = vec![]; + loop { + result.push(&mut ((((list.0).0).0).0).0.value); + //~^ ERROR cannot borrow `list.0.0.0.0.0.value` as mutable + + if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { + //~^ ERROR cannot borrow `list.0.0.0.0.0.next` as mutable + *((((list.0).0).0).0).1 = n; + } else { + return result; + } + } +} + +fn main() {} diff --git a/src/test/ui/nll/polonius/assignment-to-differing-field.stderr b/src/test/ui/nll/polonius/assignment-to-differing-field.stderr new file mode 100644 index 0000000000000..07ca021b53bce --- /dev/null +++ b/src/test/ui/nll/polonius/assignment-to-differing-field.stderr @@ -0,0 +1,51 @@ +error[E0499]: cannot borrow `list.0.value` as mutable more than once at a time + --> $DIR/assignment-to-differing-field.rs:21:21 + | +LL | fn assignment_to_field_projection<'a, T>( + | -- lifetime `'a` defined here +... +LL | result.push(&mut (list.0).value); + | ^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop +... +LL | return result; + | ------ returning this value requires that `list.0.value` is borrowed for `'a` + +error[E0499]: cannot borrow `list.0.next` as mutable more than once at a time + --> $DIR/assignment-to-differing-field.rs:24:26 + | +LL | fn assignment_to_field_projection<'a, T>( + | -- lifetime `'a` defined here +... +LL | if let Some(n) = (list.0).next.as_mut() { + | ^^^^^^^^^^^^^--------- + | | + | mutable borrow starts here in previous iteration of loop + | argument requires that `list.0.next` is borrowed for `'a` + +error[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time + --> $DIR/assignment-to-differing-field.rs:38:21 + | +LL | fn assignment_through_projection_chain<'a, T>( + | -- lifetime `'a` defined here +... +LL | result.push(&mut ((((list.0).0).0).0).0.value); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop +... +LL | return result; + | ------ returning this value requires that `list.0.0.0.0.0.value` is borrowed for `'a` + +error[E0499]: cannot borrow `list.0.0.0.0.0.next` as mutable more than once at a time + --> $DIR/assignment-to-differing-field.rs:41:26 + | +LL | fn assignment_through_projection_chain<'a, T>( + | -- lifetime `'a` defined here +... +LL | if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^--------- + | | + | mutable borrow starts here in previous iteration of loop + | argument requires that `list.0.0.0.0.0.next` is borrowed for `'a` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0499`. From c7f9a71d7875e5acced7f3a1b9f05a46be2104f4 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 16 Jul 2019 17:34:06 +0200 Subject: [PATCH 48/79] issue-46589 passes in Polonius and fails in NLL, duplicate it and manually check each outcome --- src/test/ui/nll/issue-46589.rs | 6 +++++ src/test/ui/nll/issue-46589.stderr | 2 +- src/test/ui/nll/polonius/issue-46589.rs | 32 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/nll/polonius/issue-46589.rs diff --git a/src/test/ui/nll/issue-46589.rs b/src/test/ui/nll/issue-46589.rs index 8c0c356e96721..0a4c20d15159f 100644 --- a/src/test/ui/nll/issue-46589.rs +++ b/src/test/ui/nll/issue-46589.rs @@ -1,3 +1,9 @@ +// This tests passes in Polonius mode, so is skipped in the automated compare-mode. +// We will manually check it passes in Polonius tests, as we can't have a test here +// which conditionally passes depending on a test revision/compile-flags. + +// ignore-compare-mode-polonius + struct Foo; impl Foo { diff --git a/src/test/ui/nll/issue-46589.stderr b/src/test/ui/nll/issue-46589.stderr index 397909a436610..82cd364eeffd0 100644 --- a/src/test/ui/nll/issue-46589.stderr +++ b/src/test/ui/nll/issue-46589.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `**other` as mutable more than once at a time - --> $DIR/issue-46589.rs:17:21 + --> $DIR/issue-46589.rs:23:21 | LL | *other = match (*other).get_self() { | -------- first mutable borrow occurs here diff --git a/src/test/ui/nll/polonius/issue-46589.rs b/src/test/ui/nll/polonius/issue-46589.rs new file mode 100644 index 0000000000000..b5792587ff0ec --- /dev/null +++ b/src/test/ui/nll/polonius/issue-46589.rs @@ -0,0 +1,32 @@ +// This test is a copy of `ui/nll/issue-46589.rs` which fails in NLL but succeeds in Polonius. +// As we can't have a test here which conditionally passes depending on a test +// revision/compile-flags. We ensure here that it passes in Polonius mode. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct Foo; + +impl Foo { + fn get_self(&mut self) -> Option<&mut Self> { + Some(self) + } + + fn new_self(&mut self) -> &mut Self { + self + } + + fn trigger_bug(&mut self) { + let other = &mut (&mut *self); + + *other = match (*other).get_self() { + Some(s) => s, + None => (*other).new_self() + }; + + let c = other; + } +} + +fn main() {} From c0eab36bce7625bc45dec180dd08c7aa679cf1d7 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 16 Jul 2019 17:35:21 +0200 Subject: [PATCH 49/79] Bless output of test nll/loan_ends_mid_block_pair.rs for Polonius, again Fixing assignments to projections made the Polonius output exactly the same as the NLL one. --- .../loan_ends_mid_block_pair.polonius.stderr | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr b/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr index c9537d42c41af..eb8442b31d7c7 100644 --- a/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr +++ b/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr @@ -10,29 +10,6 @@ LL | data.0 = 'e'; LL | capitalize(c); | - borrow later used here -error[E0506]: cannot assign to `data.0` because it is borrowed - --> $DIR/loan_ends_mid_block_pair.rs:14:5 - | -LL | let c = &mut data.0; - | ----------- borrow of `data.0` occurs here -... -LL | data.0 = 'f'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here -LL | data.0 = 'g'; -LL | capitalize(c); - | - borrow later used here - -error[E0506]: cannot assign to `data.0` because it is borrowed - --> $DIR/loan_ends_mid_block_pair.rs:15:5 - | -LL | let c = &mut data.0; - | ----------- borrow of `data.0` occurs here -... -LL | data.0 = 'g'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here -LL | capitalize(c); - | - borrow later used here - -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0506`. From e16bede3f503b85685e80b39942fbc0b0e11a721 Mon Sep 17 00:00:00 2001 From: lqd Date: Tue, 16 Jul 2019 18:51:13 +0200 Subject: [PATCH 50/79] fix tidy --- src/test/ui/nll/polonius/assignment-kills-loans.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/nll/polonius/assignment-kills-loans.rs b/src/test/ui/nll/polonius/assignment-kills-loans.rs index 8301f603cb4d3..a80c62d19d5a6 100644 --- a/src/test/ui/nll/polonius/assignment-kills-loans.rs +++ b/src/test/ui/nll/polonius/assignment-kills-loans.rs @@ -85,4 +85,4 @@ fn assignment_through_projection_chain( } fn main() { -} \ No newline at end of file +} From 91967816c3851b4b796ce774bde49a9f47681bca Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 22 Jul 2019 15:32:58 +0200 Subject: [PATCH 51/79] account for non-drop-glue types --- src/libstd/primitive_docs.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index b7196a8670138..ead1987d04b56 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -365,9 +365,10 @@ mod prim_unit { } /// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. /// Raw pointers can be unaligned or [`null`] when unused. However, when a raw pointer is /// dereferenced (using the `*` operator), it must be non-null and aligned. +/// /// Storing through a raw pointer using `*ptr = data` calls `drop` on the old value, so -/// [`write`] must be used if memory is not already initialized---otherwise `drop` -/// would be called on the uninitialized memory. +/// [`write`] must be used if the type has drop glue and memory is not already +/// initialized---otherwise `drop` would be called on the uninitialized memory. /// /// Use the [`null`] and [`null_mut`] functions to create null pointers, and the /// [`is_null`] method of the `*const T` and `*mut T` types to check for null. From 4b339688b5b49e38545336b27845b7d1e31a5b80 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 10 Aug 2018 12:01:18 -0500 Subject: [PATCH 52/79] add support for hexagon-unknown-linux-musl --- src/libcore/lib.rs | 1 + src/libpanic_unwind/gcc.rs | 3 + src/librustc_codegen_llvm/llvm_util.rs | 2 +- .../spec/hexagon_unknown_linux_musl.rs | 36 ++++++++++++ src/librustc_target/spec/mod.rs | 1 + src/libstd/env.rs | 5 ++ src/libstd/os/linux/raw.rs | 56 +++++++++++++++++++ src/libstd/os/raw/mod.rs | 2 + src/libstd/sys_common/alloc.rs | 3 +- src/libunwind/libunwind.rs | 3 + 10 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 src/librustc_target/spec/hexagon_unknown_linux_musl.rs diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index fe149d634e223..2b3bad8894e60 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -120,6 +120,7 @@ #![feature(cmpxchg16b_target_feature)] #![feature(rtm_target_feature)] #![feature(f16c_target_feature)] +#![feature(hexagon_target_feature)] #![feature(const_slice_len)] #![feature(const_str_as_bytes)] #![feature(const_str_len)] diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index e2b743b379704..236ed15050571 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -126,6 +126,9 @@ const UNWIND_DATA_REG: (i32, i32) = (6, 7); // R6, R7 #[cfg(target_arch = "sparc64")] const UNWIND_DATA_REG: (i32, i32) = (24, 25); // I0, I1 +#[cfg(target_arch = "hexagon")] +const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 + // The following code is based on GCC's C and C++ personality routines. For reference, see: // https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index 274c89659628d..541d3d98b79bd 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -174,7 +174,7 @@ const X86_WHITELIST: &[(&str, Option)] = &[ const HEXAGON_WHITELIST: &[(&str, Option)] = &[ ("hvx", Some(sym::hexagon_target_feature)), - ("hvx-double", Some(sym::hexagon_target_feature)), + ("hvx-length128b", Some(sym::hexagon_target_feature)), ]; const POWERPC_WHITELIST: &[(&str, Option)] = &[ diff --git a/src/librustc_target/spec/hexagon_unknown_linux_musl.rs b/src/librustc_target/spec/hexagon_unknown_linux_musl.rs new file mode 100644 index 0000000000000..1d3b13d488366 --- /dev/null +++ b/src/librustc_target/spec/hexagon_unknown_linux_musl.rs @@ -0,0 +1,36 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult, LinkArgs}; + +pub fn target() -> TargetResult { + let mut base = super::linux_musl_base::opts(); + base.cpu = "hexagonv60".to_string(); + base.max_atomic_width = Some(32); + // FIXME: HVX length defaults are per-CPU + base.features = "-small-data,+hvx-length128b".to_string(); + + base.crt_static_default = false; + base.atomic_cas = true; + base.has_rpath = true; + base.linker_is_gnu = false; + base.dynamic_linking = true; + base.executables = true; + + base.pre_link_args = LinkArgs::new(); + base.post_link_args = LinkArgs::new(); + + Ok(Target { + llvm_target: "hexagon-unknown-linux-musl".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: concat!("e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32", + ":32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32", + ":32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048", + ":2048:2048").to_string(), + arch: "hexagon".to_string(), + target_os: "linux".to_string(), + target_env: "musl".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: base, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1fdc9b015ba39..6a43d97eb925a 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -368,6 +368,7 @@ supported_targets! { ("i586-unknown-linux-musl", i586_unknown_linux_musl), ("mips-unknown-linux-musl", mips_unknown_linux_musl), ("mipsel-unknown-linux-musl", mipsel_unknown_linux_musl), + ("hexagon-unknown-linux-musl", hexagon_unknown_linux_musl), ("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc), ("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc), diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 00e840a53e9c0..1f5de25b65c90 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -975,6 +975,11 @@ mod arch { pub const ARCH: &str = "wasm32"; } +#[cfg(target_arch = "hexagon")] +mod arch { + pub const ARCH: &'static str = "hexagon"; +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/libstd/os/linux/raw.rs b/src/libstd/os/linux/raw.rs index 77eeacb4b477c..21e1cf8a22b4b 100644 --- a/src/libstd/os/linux/raw.rs +++ b/src/libstd/os/linux/raw.rs @@ -147,6 +147,62 @@ mod arch { } } +#[cfg(target_arch = "hexagon")] +mod arch { + use crate::os::raw::{c_long, c_int, c_longlong, culonglong}; + + #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = c_longlong; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = c_long; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = c_ulonglong; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = c_uint; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = c_longlong; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long; + + #[repr(C)] + #[derive(Clone)] + #[stable(feature = "raw_ext", since = "1.1.0")] + pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: ::dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ::c_ulonglong, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: ::c_uint, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: ::c_uint, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: ::c_uint, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: ::c_uint, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: ::c_ulonglong, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __pad1: ::c_ulong, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: ::c_longlong, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: ::blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __pad2: ::c_int, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: ::blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: ::time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: ::c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: ::time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: ::c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: ::time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: ::c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __pad3: [::c_int;2], + } +} + #[cfg(any(target_arch = "mips64", target_arch = "s390x", target_arch = "sparc64"))] diff --git a/src/libstd/os/raw/mod.rs b/src/libstd/os/raw/mod.rs index c0b0b6d40d891..cf8be393a4049 100644 --- a/src/libstd/os/raw/mod.rs +++ b/src/libstd/os/raw/mod.rs @@ -11,6 +11,7 @@ #[doc(include = "os/raw/char.md")] #[cfg(any(all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", + target_arch = "hexagon", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "s390x")), @@ -34,6 +35,7 @@ #[doc(include = "os/raw/char.md")] #[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", + target_arch = "hexagon", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "s390x")), diff --git a/src/libstd/sys_common/alloc.rs b/src/libstd/sys_common/alloc.rs index 978a70bee0983..1cfc7ed17f2e4 100644 --- a/src/libstd/sys_common/alloc.rs +++ b/src/libstd/sys_common/alloc.rs @@ -12,7 +12,8 @@ use crate::ptr; target_arch = "powerpc", target_arch = "powerpc64", target_arch = "asmjs", - target_arch = "wasm32")))] + target_arch = "wasm32", + target_arch = "hexagon")))] pub const MIN_ALIGN: usize = 8; #[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64", diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs index 30897970fa220..aacbfc547d472 100644 --- a/src/libunwind/libunwind.rs +++ b/src/libunwind/libunwind.rs @@ -56,6 +56,9 @@ pub const unwinder_private_data_size: usize = 2; #[cfg(target_os = "emscripten")] pub const unwinder_private_data_size: usize = 20; +#[cfg(all(target_arch = "hexagon", target_os = "linux"))] +pub const unwinder_private_data_size: usize = 35; + #[repr(C)] pub struct _Unwind_Exception { pub exception_class: _Unwind_Exception_Class, From f78cd4de454c4b55c95137f2db07b4f36b86c3af Mon Sep 17 00:00:00 2001 From: Pyry Kontio Date: Sun, 16 Jun 2019 17:10:13 +0900 Subject: [PATCH 53/79] Fix building_llvm in sanity check, add swig sanity check. --- src/bootstrap/sanity.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index dc65fb9b79706..4e3930c8da7fc 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -78,8 +78,11 @@ pub fn check(build: &mut Build) { // We need cmake, but only if we're actually building LLVM or sanitizers. let building_llvm = build.hosts.iter() - .filter_map(|host| build.config.target_config.get(host)) - .any(|config| config.llvm_config.is_none()); + .map(|host| build.config.target_config + .get(host) + .map(|config| config.llvm_config.is_none()) + .unwrap_or(true)) + .any(|build_llvm_ourselves| build_llvm_ourselves); if building_llvm || build.config.sanitizers { cmd_finder.must_have("cmake"); } @@ -106,6 +109,14 @@ pub fn check(build: &mut Build) { build.config.ninja = true; } } + + if build.config.lldb_enabled { + cmd_finder.must_have("swig"); + let out = output(Command::new("swig").arg("-version")); + if !out.contains("SWIG Version 3") && !out.contains("SWIG Version 4") { + panic!("Ensure that Swig 3.x.x or 4.x.x is installed."); + } + } } build.config.python = build.config.python.take().map(|p| cmd_finder.must_have(p)) From ba78db310b2ddf9b5f8e6c87a58e8ea8df374e16 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 14 May 2019 21:50:39 +0200 Subject: [PATCH 54/79] libsyntax: factor out file path resolving This allows the same logic used by `include_X!` macros to be used by `#[doc(include)]`. --- src/libsyntax/ext/source_util.rs | 33 ++++++-------------------------- src/libsyntax/lib.rs | 1 + src/libsyntax/util/path.rs | 28 +++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 27 deletions(-) create mode 100644 src/libsyntax/util/path.rs diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index c2ba8b983f5a8..aad390f3bf601 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -6,13 +6,13 @@ use crate::print::pprust; use crate::ptr::P; use crate::symbol::Symbol; use crate::tokenstream; +use crate::util::path; use smallvec::SmallVec; -use syntax_pos::{self, Pos, Span, FileName}; +use syntax_pos::{self, Pos, Span}; use std::fs; use std::io::ErrorKind; -use std::path::PathBuf; use rustc_data_structures::sync::Lrc; // These macros all relate to the file system; they either return @@ -78,9 +78,9 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstrea None => return DummyResult::any(sp), }; // The file will be added to the code map by the parser - let path = res_rel_file(cx, sp, file); + let file = path::resolve(file, sp, cx.source_map()); let directory_ownership = DirectoryOwnership::Owned { relative: None }; - let p = parse::new_sub_parser_from_file(cx.parse_sess(), &path, directory_ownership, None, sp); + let p = parse::new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp); struct ExpandResult<'a> { p: parse::parser::Parser<'a>, @@ -115,7 +115,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::To Some(f) => f, None => return DummyResult::expr(sp) }; - let file = res_rel_file(cx, sp, file); + let file = path::resolve(file, sp, cx.source_map()); match fs::read_to_string(&file) { Ok(src) => { let interned_src = Symbol::intern(&src); @@ -143,7 +143,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream:: Some(f) => f, None => return DummyResult::expr(sp) }; - let file = res_rel_file(cx, sp, file); + let file = path::resolve(file, sp, cx.source_map()); match fs::read(&file) { Ok(bytes) => { // Add the contents to the source map if it contains UTF-8. @@ -164,24 +164,3 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream:: } } } - -// resolve a file-system path to an absolute file-system path (if it -// isn't already) -fn res_rel_file(cx: &mut ExtCtxt<'_>, sp: syntax_pos::Span, arg: String) -> PathBuf { - let arg = PathBuf::from(arg); - // Relative paths are resolved relative to the file in which they are found - // after macro expansion (that is, they are unhygienic). - if !arg.is_absolute() { - let callsite = sp.source_callsite(); - let mut path = match cx.source_map().span_to_unmapped_path(callsite) { - FileName::Real(path) => path, - FileName::DocTest(path, _) => path, - other => panic!("cannot resolve relative path in non-file source `{}`", other), - }; - path.pop(); - path.push(arg); - path - } else { - arg - } -} diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 3dea1977c4dac..1b2873b1de7bc 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -135,6 +135,7 @@ pub mod util { #[cfg(test)] pub mod parser_testing; pub mod map_in_place; + pub mod path; } pub mod json; diff --git a/src/libsyntax/util/path.rs b/src/libsyntax/util/path.rs new file mode 100644 index 0000000000000..a3511bac8e7d9 --- /dev/null +++ b/src/libsyntax/util/path.rs @@ -0,0 +1,28 @@ +use crate::source_map::SourceMap; +use std::path::PathBuf; +use syntax_pos::{Span, FileName}; + +/// Resolve a path mentioned inside Rust code. +/// +/// This unifies the logic used for resolving `include_X!`, and `#[doc(include)]` file paths. +/// +/// Returns an absolute path to the file that `path` refers to. +pub fn resolve(path: impl Into, span: Span, map: &SourceMap) -> PathBuf { + let path = path.into(); + + // Relative paths are resolved relative to the file in which they are found + // after macro expansion (that is, they are unhygienic). + if !path.is_absolute() { + let callsite = span.source_callsite(); + let mut result = match map.span_to_unmapped_path(callsite) { + FileName::Real(path) => path, + FileName::DocTest(path, _) => path, + other => panic!("cannot resolve relative path in non-file source `{}`", other), + }; + result.pop(); + result.push(path); + result + } else { + path + } +} From 138e08ccf6f6c6caf55a135bd0edcba8e6855df5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 18 May 2019 15:56:53 +0200 Subject: [PATCH 55/79] Make #[doc(include)] paths behave like other paths This makes them relative to the containing file instead of the crate root --- src/libstd/os/raw/mod.rs | 48 ++++++++++++++++++++++++------------- src/libsyntax/ext/expand.rs | 7 ++---- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/libstd/os/raw/mod.rs b/src/libstd/os/raw/mod.rs index c0b0b6d40d891..fd50657800d50 100644 --- a/src/libstd/os/raw/mod.rs +++ b/src/libstd/os/raw/mod.rs @@ -8,7 +8,8 @@ #![stable(feature = "raw_os", since = "1.1.0")] -#[doc(include = "os/raw/char.md")] +#[cfg_attr(stage0, doc(include = "os/raw/char.md"))] +#[cfg_attr(not(stage0), doc(include = "char.md"))] #[cfg(any(all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc", @@ -31,7 +32,8 @@ target_arch = "powerpc")), all(target_os = "fuchsia", target_arch = "aarch64")))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8; -#[doc(include = "os/raw/char.md")] +#[cfg_attr(stage0, doc(include = "os/raw/char.md"))] +#[cfg_attr(not(stage0), doc(include = "char.md"))] #[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc", @@ -54,37 +56,51 @@ target_arch = "powerpc")), all(target_os = "fuchsia", target_arch = "aarch64"))))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8; -#[doc(include = "os/raw/schar.md")] +#[cfg_attr(stage0, doc(include = "os/raw/schar.md"))] +#[cfg_attr(not(stage0), doc(include = "schar.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8; -#[doc(include = "os/raw/uchar.md")] +#[cfg_attr(stage0, doc(include = "os/raw/uchar.md"))] +#[cfg_attr(not(stage0), doc(include = "uchar.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8; -#[doc(include = "os/raw/short.md")] +#[cfg_attr(stage0, doc(include = "os/raw/short.md"))] +#[cfg_attr(not(stage0), doc(include = "short.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_short = i16; -#[doc(include = "os/raw/ushort.md")] +#[cfg_attr(stage0, doc(include = "os/raw/ushort.md"))] +#[cfg_attr(not(stage0), doc(include = "ushort.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ushort = u16; -#[doc(include = "os/raw/int.md")] +#[cfg_attr(stage0, doc(include = "os/raw/int.md"))] +#[cfg_attr(not(stage0), doc(include = "int.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_int = i32; -#[doc(include = "os/raw/uint.md")] +#[cfg_attr(stage0, doc(include = "os/raw/uint.md"))] +#[cfg_attr(not(stage0), doc(include = "uint.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uint = u32; -#[doc(include = "os/raw/long.md")] +#[cfg_attr(stage0, doc(include = "os/raw/long.md"))] +#[cfg_attr(not(stage0), doc(include = "long.md"))] #[cfg(any(target_pointer_width = "32", windows))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i32; -#[doc(include = "os/raw/ulong.md")] +#[cfg_attr(stage0, doc(include = "os/raw/ulong.md"))] +#[cfg_attr(not(stage0), doc(include = "ulong.md"))] #[cfg(any(target_pointer_width = "32", windows))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u32; -#[doc(include = "os/raw/long.md")] +#[cfg_attr(stage0, doc(include = "os/raw/long.md"))] +#[cfg_attr(not(stage0), doc(include = "long.md"))] #[cfg(all(target_pointer_width = "64", not(windows)))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i64; -#[doc(include = "os/raw/ulong.md")] +#[cfg_attr(stage0, doc(include = "os/raw/ulong.md"))] +#[cfg_attr(not(stage0), doc(include = "ulong.md"))] #[cfg(all(target_pointer_width = "64", not(windows)))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u64; -#[doc(include = "os/raw/longlong.md")] +#[cfg_attr(stage0, doc(include = "os/raw/longlong.md"))] +#[cfg_attr(not(stage0), doc(include = "longlong.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_longlong = i64; -#[doc(include = "os/raw/ulonglong.md")] +#[cfg_attr(stage0, doc(include = "os/raw/ulonglong.md"))] +#[cfg_attr(not(stage0), doc(include = "ulonglong.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulonglong = u64; -#[doc(include = "os/raw/float.md")] +#[cfg_attr(stage0, doc(include = "os/raw/float.md"))] +#[cfg_attr(not(stage0), doc(include = "float.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_float = f32; -#[doc(include = "os/raw/double.md")] +#[cfg_attr(stage0, doc(include = "os/raw/double.md"))] +#[cfg_attr(not(stage0), doc(include = "double.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_double = f64; #[stable(feature = "raw_os", since = "1.1.0")] diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index ae72f1fd108ed..6cfcfdfbf7d85 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -17,6 +17,7 @@ use crate::symbol::{sym, Symbol}; use crate::tokenstream::{TokenStream, TokenTree}; use crate::visit::{self, Visitor}; use crate::util::map_in_place::MapInPlace; +use crate::util::path; use errors::{Applicability, FatalError}; use smallvec::{smallvec, SmallVec}; @@ -1253,7 +1254,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { return noop_visit_attribute(at, self); } - let filename = self.cx.root_path.join(file.to_string()); + let filename = path::resolve(&*file.as_str(), it.span(), self.cx.source_map()); match fs::read_to_string(&filename) { Ok(src) => { let src_interned = Symbol::intern(&src); @@ -1302,10 +1303,6 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { ); err.span_label(lit.span, "couldn't read file"); - if e.kind() == ErrorKind::NotFound { - err.help("external doc paths are relative to the crate root"); - } - err.emit(); } } From 1cc7c211f5ff566f0ea2270197a15d1ab8c429bf Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 19 May 2019 13:33:16 +0200 Subject: [PATCH 56/79] Adjust docs to new #[doc(include)] behaviour --- src/doc/rustdoc/src/unstable-features.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 1d9510c9aacab..6e32468b64dee 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -183,9 +183,8 @@ Book][unstable-masked] and [its tracking issue][issue-masked]. As designed in [RFC 1990], Rustdoc can read an external file to use as a type's documentation. This is useful if certain documentation is so long that it would break the flow of reading the source. -Instead of writing it all inline, writing `#[doc(include = "sometype.md")]` (where `sometype.md` is -a file adjacent to the `lib.rs` for the crate) will ask Rustdoc to instead read that file and use it -as if it were written inline. +Instead of writing it all inline, writing `#[doc(include = "sometype.md")]` will ask Rustdoc to +instead read that file and use it as if it were written inline. [RFC 1990]: https://github.com/rust-lang/rfcs/pull/1990 From 8ccf52c1c6cffde2905d7ad0ebfa36a9e8a0c319 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 22 Jun 2019 20:37:25 +0200 Subject: [PATCH 57/79] stage0 -> bootstrap --- src/libstd/os/raw/mod.rs | 64 ++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/libstd/os/raw/mod.rs b/src/libstd/os/raw/mod.rs index fd50657800d50..340b2a5d5519e 100644 --- a/src/libstd/os/raw/mod.rs +++ b/src/libstd/os/raw/mod.rs @@ -8,8 +8,8 @@ #![stable(feature = "raw_os", since = "1.1.0")] -#[cfg_attr(stage0, doc(include = "os/raw/char.md"))] -#[cfg_attr(not(stage0), doc(include = "char.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/char.md"))] +#[cfg_attr(not(bootstrap), doc(include = "char.md"))] #[cfg(any(all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc", @@ -32,8 +32,8 @@ target_arch = "powerpc")), all(target_os = "fuchsia", target_arch = "aarch64")))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8; -#[cfg_attr(stage0, doc(include = "os/raw/char.md"))] -#[cfg_attr(not(stage0), doc(include = "char.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/char.md"))] +#[cfg_attr(not(bootstrap), doc(include = "char.md"))] #[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc", @@ -56,51 +56,51 @@ target_arch = "powerpc")), all(target_os = "fuchsia", target_arch = "aarch64"))))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8; -#[cfg_attr(stage0, doc(include = "os/raw/schar.md"))] -#[cfg_attr(not(stage0), doc(include = "schar.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/schar.md"))] +#[cfg_attr(not(bootstrap), doc(include = "schar.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8; -#[cfg_attr(stage0, doc(include = "os/raw/uchar.md"))] -#[cfg_attr(not(stage0), doc(include = "uchar.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/uchar.md"))] +#[cfg_attr(not(bootstrap), doc(include = "uchar.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8; -#[cfg_attr(stage0, doc(include = "os/raw/short.md"))] -#[cfg_attr(not(stage0), doc(include = "short.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/short.md"))] +#[cfg_attr(not(bootstrap), doc(include = "short.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_short = i16; -#[cfg_attr(stage0, doc(include = "os/raw/ushort.md"))] -#[cfg_attr(not(stage0), doc(include = "ushort.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/ushort.md"))] +#[cfg_attr(not(bootstrap), doc(include = "ushort.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ushort = u16; -#[cfg_attr(stage0, doc(include = "os/raw/int.md"))] -#[cfg_attr(not(stage0), doc(include = "int.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/int.md"))] +#[cfg_attr(not(bootstrap), doc(include = "int.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_int = i32; -#[cfg_attr(stage0, doc(include = "os/raw/uint.md"))] -#[cfg_attr(not(stage0), doc(include = "uint.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/uint.md"))] +#[cfg_attr(not(bootstrap), doc(include = "uint.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uint = u32; -#[cfg_attr(stage0, doc(include = "os/raw/long.md"))] -#[cfg_attr(not(stage0), doc(include = "long.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/long.md"))] +#[cfg_attr(not(bootstrap), doc(include = "long.md"))] #[cfg(any(target_pointer_width = "32", windows))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i32; -#[cfg_attr(stage0, doc(include = "os/raw/ulong.md"))] -#[cfg_attr(not(stage0), doc(include = "ulong.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/ulong.md"))] +#[cfg_attr(not(bootstrap), doc(include = "ulong.md"))] #[cfg(any(target_pointer_width = "32", windows))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u32; -#[cfg_attr(stage0, doc(include = "os/raw/long.md"))] -#[cfg_attr(not(stage0), doc(include = "long.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/long.md"))] +#[cfg_attr(not(bootstrap), doc(include = "long.md"))] #[cfg(all(target_pointer_width = "64", not(windows)))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i64; -#[cfg_attr(stage0, doc(include = "os/raw/ulong.md"))] -#[cfg_attr(not(stage0), doc(include = "ulong.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/ulong.md"))] +#[cfg_attr(not(bootstrap), doc(include = "ulong.md"))] #[cfg(all(target_pointer_width = "64", not(windows)))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u64; -#[cfg_attr(stage0, doc(include = "os/raw/longlong.md"))] -#[cfg_attr(not(stage0), doc(include = "longlong.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/longlong.md"))] +#[cfg_attr(not(bootstrap), doc(include = "longlong.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_longlong = i64; -#[cfg_attr(stage0, doc(include = "os/raw/ulonglong.md"))] -#[cfg_attr(not(stage0), doc(include = "ulonglong.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/ulonglong.md"))] +#[cfg_attr(not(bootstrap), doc(include = "ulonglong.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulonglong = u64; -#[cfg_attr(stage0, doc(include = "os/raw/float.md"))] -#[cfg_attr(not(stage0), doc(include = "float.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/float.md"))] +#[cfg_attr(not(bootstrap), doc(include = "float.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_float = f32; -#[cfg_attr(stage0, doc(include = "os/raw/double.md"))] -#[cfg_attr(not(stage0), doc(include = "double.md"))] +#[cfg_attr(bootstrap, doc(include = "os/raw/double.md"))] +#[cfg_attr(not(bootstrap), doc(include = "double.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_double = f64; #[stable(feature = "raw_os", since = "1.1.0")] From edb21873cced7a179571aa3a9c25eb1cfc05c2db Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 22 Jun 2019 21:51:51 +0200 Subject: [PATCH 58/79] Make path::resolve a method on ExtCtxt --- src/libsyntax/ext/base.rs | 27 ++++++++++++++++++++++++++- src/libsyntax/ext/expand.rs | 3 +-- src/libsyntax/ext/source_util.rs | 7 +++---- src/libsyntax/lib.rs | 1 - src/libsyntax/util/path.rs | 28 ---------------------------- 5 files changed, 30 insertions(+), 36 deletions(-) delete mode 100644 src/libsyntax/util/path.rs diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 926c9e88efe15..11b7a984aaa00 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,6 +1,6 @@ use crate::ast::{self, Attribute, Name, PatKind}; use crate::attr::{HasAttrs, Stability, Deprecation}; -use crate::source_map::{SourceMap, Spanned, respan}; +use crate::source_map::{SourceMap, Spanned, FileName, respan}; use crate::edition::Edition; use crate::ext::expand::{self, AstFragment, Invocation}; use crate::ext::hygiene::{ExpnId, SyntaxContext, Transparency}; @@ -889,6 +889,31 @@ impl<'a> ExtCtxt<'a> { pub fn check_unused_macros(&self) { self.resolver.check_unused_macros(); } + + /// Resolve a path mentioned inside Rust code. + /// + /// This unifies the logic used for resolving `include_X!`, and `#[doc(include)]` file paths. + /// + /// Returns an absolute path to the file that `path` refers to. + pub fn resolve_path(&self, path: impl Into, span: Span) -> PathBuf { + let path = path.into(); + + // Relative paths are resolved relative to the file in which they are found + // after macro expansion (that is, they are unhygienic). + if !path.is_absolute() { + let callsite = span.source_callsite(); + let mut result = match self.source_map().span_to_unmapped_path(callsite) { + FileName::Real(path) => path, + FileName::DocTest(path, _) => path, + other => panic!("cannot resolve relative path in non-file source `{}`", other), + }; + result.pop(); + result.push(path); + result + } else { + path + } + } } /// Extracts a string literal from the macro expanded version of `expr`, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6cfcfdfbf7d85..ae8b11ff9d50e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -17,7 +17,6 @@ use crate::symbol::{sym, Symbol}; use crate::tokenstream::{TokenStream, TokenTree}; use crate::visit::{self, Visitor}; use crate::util::map_in_place::MapInPlace; -use crate::util::path; use errors::{Applicability, FatalError}; use smallvec::{smallvec, SmallVec}; @@ -1254,7 +1253,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { return noop_visit_attribute(at, self); } - let filename = path::resolve(&*file.as_str(), it.span(), self.cx.source_map()); + let filename = self.cx.resolve_path(&*file.as_str(), it.span()); match fs::read_to_string(&filename) { Ok(src) => { let src_interned = Symbol::intern(&src); diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index aad390f3bf601..ae080c05eec91 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -6,7 +6,6 @@ use crate::print::pprust; use crate::ptr::P; use crate::symbol::Symbol; use crate::tokenstream; -use crate::util::path; use smallvec::SmallVec; use syntax_pos::{self, Pos, Span}; @@ -78,7 +77,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstrea None => return DummyResult::any(sp), }; // The file will be added to the code map by the parser - let file = path::resolve(file, sp, cx.source_map()); + let file = cx.resolve_path(file, sp); let directory_ownership = DirectoryOwnership::Owned { relative: None }; let p = parse::new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp); @@ -115,7 +114,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::To Some(f) => f, None => return DummyResult::expr(sp) }; - let file = path::resolve(file, sp, cx.source_map()); + let file = cx.resolve_path(file, sp); match fs::read_to_string(&file) { Ok(src) => { let interned_src = Symbol::intern(&src); @@ -143,7 +142,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream:: Some(f) => f, None => return DummyResult::expr(sp) }; - let file = path::resolve(file, sp, cx.source_map()); + let file = cx.resolve_path(file, sp); match fs::read(&file) { Ok(bytes) => { // Add the contents to the source map if it contains UTF-8. diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 1b2873b1de7bc..3dea1977c4dac 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -135,7 +135,6 @@ pub mod util { #[cfg(test)] pub mod parser_testing; pub mod map_in_place; - pub mod path; } pub mod json; diff --git a/src/libsyntax/util/path.rs b/src/libsyntax/util/path.rs deleted file mode 100644 index a3511bac8e7d9..0000000000000 --- a/src/libsyntax/util/path.rs +++ /dev/null @@ -1,28 +0,0 @@ -use crate::source_map::SourceMap; -use std::path::PathBuf; -use syntax_pos::{Span, FileName}; - -/// Resolve a path mentioned inside Rust code. -/// -/// This unifies the logic used for resolving `include_X!`, and `#[doc(include)]` file paths. -/// -/// Returns an absolute path to the file that `path` refers to. -pub fn resolve(path: impl Into, span: Span, map: &SourceMap) -> PathBuf { - let path = path.into(); - - // Relative paths are resolved relative to the file in which they are found - // after macro expansion (that is, they are unhygienic). - if !path.is_absolute() { - let callsite = span.source_callsite(); - let mut result = match map.span_to_unmapped_path(callsite) { - FileName::Real(path) => path, - FileName::DocTest(path, _) => path, - other => panic!("cannot resolve relative path in non-file source `{}`", other), - }; - result.pop(); - result.push(path); - result - } else { - path - } -} From 7c42259d03b196839754ef2c55d6e3acb3c9f895 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 17 Jul 2019 22:46:37 +0200 Subject: [PATCH 59/79] Update stdarch submodule --- src/stdarch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdarch b/src/stdarch index b881a2d124cb0..4791ba85e7645 160000 --- a/src/stdarch +++ b/src/stdarch @@ -1 +1 @@ -Subproject commit b881a2d124cb0eea09d137300eb4a35829b517fb +Subproject commit 4791ba85e7645c02146dd416288480943670d1ca From dd5045ed630b7577296087f09f559bb9c08f68e2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 23 Jul 2019 17:48:01 +0200 Subject: [PATCH 60/79] Apply suggestions from code review Co-Authored-By: gnzlbg --- src/libstd/primitive_docs.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index ead1987d04b56..b79cfa3eead23 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -363,12 +363,12 @@ mod prim_unit { } /// *[See also the `std::ptr` module](ptr/index.html).* /// /// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. -/// Raw pointers can be unaligned or [`null`] when unused. However, when a raw pointer is +/// Raw pointers can be unaligned or [`null`]. However, when a raw pointer is /// dereferenced (using the `*` operator), it must be non-null and aligned. /// /// Storing through a raw pointer using `*ptr = data` calls `drop` on the old value, so /// [`write`] must be used if the type has drop glue and memory is not already -/// initialized---otherwise `drop` would be called on the uninitialized memory. +/// initialized - otherwise `drop` would be called on the uninitialized memory. /// /// Use the [`null`] and [`null_mut`] functions to create null pointers, and the /// [`is_null`] method of the `*const T` and `*mut T` types to check for null. @@ -898,7 +898,10 @@ mod prim_usize { } /// operators on a value, or by using a `ref` or `ref mut` pattern. /// /// For those familiar with pointers, a reference is just a pointer that is assumed to be -/// aligned, not null, and pointing to valid (initialized) memory. +/// aligned, not null, and pointing to memory containing a valid value of `T` - for example, +/// `&bool` can only point to an allocation containing the integer values `1` (`true`) or `0` +/// (`false`), but the behavior of creating a `&bool` that points to an allocation containing +/// the value `3` is undefined. /// In fact, `Option<&T>` has the same memory representation as a /// nullable but aligned pointer, and can be passed across FFI boundaries as such. /// From 65cf10d90276e40bd8cc27a79d6c6f0d13e0cc7a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 23 Jul 2019 17:51:52 +0200 Subject: [PATCH 61/79] word things more like we usually do --- src/libstd/primitive_docs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index b79cfa3eead23..d9a3da66a6786 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -900,8 +900,8 @@ mod prim_usize { } /// For those familiar with pointers, a reference is just a pointer that is assumed to be /// aligned, not null, and pointing to memory containing a valid value of `T` - for example, /// `&bool` can only point to an allocation containing the integer values `1` (`true`) or `0` -/// (`false`), but the behavior of creating a `&bool` that points to an allocation containing -/// the value `3` is undefined. +/// (`false`), but creating a `&bool` that points to an allocation containing +/// the value `3` causes undefined behaviour. /// In fact, `Option<&T>` has the same memory representation as a /// nullable but aligned pointer, and can be passed across FFI boundaries as such. /// From 218ab4cd7fdf145a0870c582a23ad5fd85cd80e5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 23 Jul 2019 17:57:54 +0200 Subject: [PATCH 62/79] Update test --- src/test/ui/extern/external-doc-error.rs | 1 - src/test/ui/extern/external-doc-error.stderr | 12 +++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/test/ui/extern/external-doc-error.rs b/src/test/ui/extern/external-doc-error.rs index e17dda65568e9..4e89f7464da49 100644 --- a/src/test/ui/extern/external-doc-error.rs +++ b/src/test/ui/extern/external-doc-error.rs @@ -4,7 +4,6 @@ #[doc(include = "not-a-file.md")] pub struct SomeStruct; //~^ ERROR couldn't read - //~| HELP external doc paths are relative to the crate root #[doc(include = "auxiliary/invalid-utf8.txt")] pub struct InvalidUtf8; //~^ ERROR wasn't a utf-8 file diff --git a/src/test/ui/extern/external-doc-error.stderr b/src/test/ui/extern/external-doc-error.stderr index a3be3277de545..b180cd66c5269 100644 --- a/src/test/ui/extern/external-doc-error.stderr +++ b/src/test/ui/extern/external-doc-error.stderr @@ -3,35 +3,33 @@ error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2) | LL | #[doc(include = "not-a-file.md")] | ^^^^^^^^^^^^^^^ couldn't read file - | - = help: external doc paths are relative to the crate root error: $DIR/auxiliary/invalid-utf8.txt wasn't a utf-8 file - --> $DIR/external-doc-error.rs:9:17 + --> $DIR/external-doc-error.rs:8:17 | LL | #[doc(include = "auxiliary/invalid-utf8.txt")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ contains invalid utf-8 error: expected path to external documentation - --> $DIR/external-doc-error.rs:12:7 + --> $DIR/external-doc-error.rs:11:7 | LL | #[doc(include)] | ^^^^^^^ help: provide a file path with `=`: `include = ""` error: expected path to external documentation - --> $DIR/external-doc-error.rs:17:7 + --> $DIR/external-doc-error.rs:16:7 | LL | #[doc(include("../README.md"))] | ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"` error: expected path to external documentation - --> $DIR/external-doc-error.rs:22:7 + --> $DIR/external-doc-error.rs:21:7 | LL | #[doc(include = 123)] | ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = ""` error: expected path to external documentation - --> $DIR/external-doc-error.rs:27:7 + --> $DIR/external-doc-error.rs:26:7 | LL | #[doc(include(123))] | ^^^^^^^^^^^^ help: provide a file path with `=`: `include = ""` From 614037171bf0140390033cc60f5e99aac079a0e5 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 23 Jul 2019 18:50:47 +0300 Subject: [PATCH 63/79] cleanup: Remove `extern crate serialize as rustc_serialize`s --- src/librustc/Cargo.toml | 2 +- src/librustc/hir/def_id.rs | 17 ++++++------ src/librustc/hir/mod.rs | 6 ++--- src/librustc/hir/ptr.rs | 2 +- src/librustc/infer/canonical/mod.rs | 2 +- src/librustc/lib.rs | 8 ------ src/librustc/lint/context.rs | 2 +- src/librustc/mir/cache.rs | 18 ++++++------- src/librustc/mir/interpret/allocation.rs | 2 +- src/librustc/mir/interpret/mod.rs | 6 ++--- src/librustc/mir/mod.rs | 6 ++--- src/librustc/ty/codec.rs | 4 +-- src/librustc/ty/mod.rs | 16 +++++------ src/librustc/ty/query/on_disk_cache.rs | 2 +- src/librustc/ty/sty.rs | 7 +++-- src/librustc/ty/subst.rs | 4 +-- src/librustc_codegen_ssa/Cargo.toml | 2 +- src/librustc_codegen_ssa/back/linker.rs | 2 +- src/librustc_codegen_ssa/back/wasm.rs | 2 +- src/librustc_data_structures/Cargo.toml | 2 +- src/librustc_data_structures/fingerprint.rs | 11 ++++---- src/librustc_data_structures/indexed_vec.rs | 30 ++++++++------------- src/librustc_data_structures/lib.rs | 2 -- src/librustc_data_structures/svh.rs | 2 +- src/librustc_driver/Cargo.toml | 2 +- src/librustc_driver/lib.rs | 2 +- src/librustc_errors/Cargo.toml | 2 +- src/librustc_errors/lib.rs | 3 --- src/librustc_incremental/Cargo.toml | 2 +- src/librustc_incremental/lib.rs | 3 --- src/librustc_interface/Cargo.toml | 2 +- src/librustc_interface/passes.rs | 2 +- src/librustc_interface/queries.rs | 2 +- src/librustc_metadata/Cargo.toml | 2 +- src/librustc_metadata/lib.rs | 2 -- src/librustc_metadata/schema.rs | 9 +++---- src/librustc_mir/Cargo.toml | 2 +- src/librustc_mir/lib.rs | 8 ++---- src/librustc_target/Cargo.toml | 2 +- src/librustc_target/lib.rs | 3 --- src/librustc_target/spec/mod.rs | 6 ++--- src/libserialize/tests/json.rs | 1 - src/libserialize/tests/opaque.rs | 1 - src/libsyntax/Cargo.toml | 2 +- src/libsyntax/ast.rs | 9 +++---- src/libsyntax/lib.rs | 3 --- src/libsyntax/ptr.rs | 2 +- src/libsyntax/tokenstream.rs | 2 +- src/libsyntax_pos/Cargo.toml | 2 +- src/libsyntax_pos/hygiene.rs | 2 +- src/libsyntax_pos/lib.rs | 9 +++---- src/libsyntax_pos/symbol.rs | 2 +- 52 files changed, 99 insertions(+), 147 deletions(-) diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 1677ef4b6079f..0222a3dde7ab9 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -27,7 +27,7 @@ rustc_target = { path = "../librustc_target" } rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } backtrace = "0.3.3" diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index 057d878a0ab8d..f3edb5f862117 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -1,7 +1,6 @@ use crate::ty::{self, TyCtxt}; use crate::hir::map::definitions::FIRST_FREE_DEF_INDEX; use rustc_data_structures::indexed_vec::Idx; -use serialize; use std::fmt; use std::u32; @@ -93,8 +92,8 @@ impl fmt::Display for CrateNum { } } -impl serialize::UseSpecializedEncodable for CrateNum {} -impl serialize::UseSpecializedDecodable for CrateNum {} +impl rustc_serialize::UseSpecializedEncodable for CrateNum {} +impl rustc_serialize::UseSpecializedDecodable for CrateNum {} newtype_index! { /// A DefIndex is an index into the hir-map for a crate, identifying a @@ -134,8 +133,8 @@ impl DefIndex { } } -impl serialize::UseSpecializedEncodable for DefIndex {} -impl serialize::UseSpecializedDecodable for DefIndex {} +impl rustc_serialize::UseSpecializedEncodable for DefIndex {} +impl rustc_serialize::UseSpecializedDecodable for DefIndex {} /// A `DefId` identifies a particular *definition*, by combining a crate /// index and a def index. @@ -186,8 +185,8 @@ impl DefId { } } -impl serialize::UseSpecializedEncodable for DefId {} -impl serialize::UseSpecializedDecodable for DefId {} +impl rustc_serialize::UseSpecializedEncodable for DefId {} +impl rustc_serialize::UseSpecializedDecodable for DefId {} /// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since /// we encode this information in the type, we can ensure at compile time that @@ -220,5 +219,5 @@ impl fmt::Debug for LocalDefId { } } -impl serialize::UseSpecializedEncodable for LocalDefId {} -impl serialize::UseSpecializedDecodable for LocalDefId {} +impl rustc_serialize::UseSpecializedEncodable for LocalDefId {} +impl rustc_serialize::UseSpecializedDecodable for LocalDefId {} diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index e7b37d40b4b2f..3708a905a4b03 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -34,7 +34,7 @@ use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; use rustc_data_structures::thin_vec::ThinVec; use rustc_macros::HashStable; -use serialize::{self, Encoder, Encodable, Decoder, Decodable}; +use rustc_serialize::{self, Encoder, Encodable, Decoder, Decodable}; use std::collections::{BTreeSet, BTreeMap}; use std::fmt; use smallvec::SmallVec; @@ -92,7 +92,7 @@ impl HirId { } } -impl serialize::UseSpecializedEncodable for HirId { +impl rustc_serialize::UseSpecializedEncodable for HirId { fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { let HirId { owner, @@ -104,7 +104,7 @@ impl serialize::UseSpecializedEncodable for HirId { } } -impl serialize::UseSpecializedDecodable for HirId { +impl rustc_serialize::UseSpecializedDecodable for HirId { fn default_decode(d: &mut D) -> Result { let owner = DefIndex::decode(d)?; let local_id = ItemLocalId::decode(d)?; diff --git a/src/librustc/hir/ptr.rs b/src/librustc/hir/ptr.rs index 3a87b36a1b434..1976b4c9e54ff 100644 --- a/src/librustc/hir/ptr.rs +++ b/src/librustc/hir/ptr.rs @@ -7,7 +7,7 @@ use std::iter::FromIterator; use std::ops::Deref; use std::{slice, vec}; -use serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, HashStable}; diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index b508f91e01ebb..6840611d4be79 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -27,7 +27,7 @@ use crate::infer::region_constraints::MemberConstraint; use crate::mir::interpret::ConstValue; use rustc_data_structures::indexed_vec::IndexVec; use rustc_macros::HashStable; -use serialize::UseSpecializedDecodable; +use rustc_serialize::UseSpecializedDecodable; use smallvec::SmallVec; use std::ops::Index; use syntax::source_map::Span; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 63e0107a4d882..c7d4fa3aec654 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -75,16 +75,8 @@ extern crate getopts; extern crate libc; #[macro_use] extern crate rustc_macros; #[macro_use] extern crate rustc_data_structures; - #[macro_use] extern crate log; #[macro_use] extern crate syntax; - -// FIXME: This import is used by deriving `RustcDecodable` and `RustcEncodable`. Removing this -// results in a bunch of "failed to resolve" errors. Hopefully, the compiler moves to serde or -// something, and we can get rid of this. -#[allow(rust_2018_idioms)] -extern crate serialize as rustc_serialize; - #[macro_use] extern crate smallvec; // Use the test crate here so we depend on getopts through it. This allow tools to link to both diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 2930f7690dd8e..859bc86d3a07d 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -23,7 +23,7 @@ use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; -use crate::rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; +use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use crate::session::{config, early_error, Session}; use crate::ty::{self, print::Printer, subst::Kind, TyCtxt, Ty}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index d2cabb7e10bbf..3d33e249536c7 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -1,27 +1,25 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::{RwLock, MappedReadGuard, ReadGuard}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHasherResult}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; +use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use crate::ich::StableHashingContext; use crate::mir::{Body, BasicBlock}; -use crate::rustc_serialize as serialize; - #[derive(Clone, Debug)] pub struct Cache { predecessors: RwLock>>> } -impl serialize::Encodable for Cache { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - serialize::Encodable::encode(&(), s) +impl rustc_serialize::Encodable for Cache { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&(), s) } } -impl serialize::Decodable for Cache { - fn decode(d: &mut D) -> Result { - serialize::Decodable::decode(d).map(|_v: ()| Self::new()) +impl rustc_serialize::Decodable for Cache { + fn decode(d: &mut D) -> Result { + Decodable::decode(d).map(|_v: ()| Self::new()) } } diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index c8bf250d02b36..51b2d0272a597 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -113,7 +113,7 @@ impl Allocation { } } -impl<'tcx> ::serialize::UseSpecializedDecodable for &'tcx Allocation {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Allocation {} /// Byte accessors impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 1b294250aa3dc..3e9933a24750e 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -27,7 +27,7 @@ use crate::hir::def_id::DefId; use crate::ty::{self, TyCtxt, Instance, subst::UnpackedKind}; use crate::ty::layout::{self, Size}; use std::io; -use crate::rustc_serialize::{Encoder, Decodable, Encodable}; +use rustc_serialize::{Encoder, Decodable, Encodable}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{Lock as Mutex, HashMapExt}; use rustc_data_structures::tiny_list::TinyList; @@ -51,8 +51,8 @@ pub struct GlobalId<'tcx> { #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)] pub struct AllocId(pub u64); -impl crate::rustc_serialize::UseSpecializedEncodable for AllocId {} -impl crate::rustc_serialize::UseSpecializedDecodable for AllocId {} +impl rustc_serialize::UseSpecializedEncodable for AllocId {} +impl rustc_serialize::UseSpecializedDecodable for AllocId {} #[derive(RustcDecodable, RustcEncodable)] enum AllocDiscriminant { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d8b641fbe31f4..571fc56a54e54 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -9,7 +9,6 @@ use crate::hir::def_id::DefId; use crate::hir::{self, InlineAsm as HirInlineAsm}; use crate::mir::interpret::{ConstValue, InterpError, Scalar}; use crate::mir::visit::MirVisitable; -use crate::rustc_serialize as serialize; use crate::ty::adjustment::PointerCast; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::layout::VariantIdx; @@ -28,6 +27,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::MappedReadGuard; use rustc_macros::HashStable; +use rustc_serialize::{Encodable, Decodable}; use smallvec::SmallVec; use std::borrow::Cow; use std::fmt::{self, Debug, Display, Formatter, Write}; @@ -463,8 +463,8 @@ impl ClearCrossCrate { } } -impl serialize::UseSpecializedEncodable for ClearCrossCrate {} -impl serialize::UseSpecializedDecodable for ClearCrossCrate {} +impl rustc_serialize::UseSpecializedEncodable for ClearCrossCrate {} +impl rustc_serialize::UseSpecializedDecodable for ClearCrossCrate {} /// Grouped information about the source code origin of a MIR entity. /// Intended to be inspected by diagnostics and debuginfo. diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index 26e7cc9004d4e..e3c6eca02d554 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -10,7 +10,7 @@ use crate::arena::ArenaAllocatable; use crate::hir::def_id::{DefId, CrateNum}; use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; use rustc_data_structures::fx::FxHashMap; -use crate::rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque}; +use rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque}; use std::hash::Hash; use std::intrinsics; use crate::ty::{self, Ty, TyCtxt}; @@ -333,7 +333,7 @@ macro_rules! implement_ty_decoder { use $crate::ty::codec::*; use $crate::ty::subst::SubstsRef; use $crate::hir::def_id::{CrateNum}; - use crate::rustc_serialize::{Decoder, SpecializedDecoder}; + use rustc_serialize::{Decoder, SpecializedDecoder}; use std::borrow::Cow; impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 538afa6054ff9..44897c8e90376 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -32,7 +32,7 @@ use crate::util::nodemap::{NodeSet, DefIdMap, FxHashMap}; use arena::SyncDroplessArena; use crate::session::DataTypeKind; -use serialize::{self, Encodable, Encoder}; +use rustc_serialize::{self, Encodable, Encoder}; use std::cell::RefCell; use std::cmp::{self, Ordering}; use std::fmt; @@ -588,8 +588,8 @@ impl<'a, 'tcx> HashStable> for ty::TyS<'tcx> { pub type Ty<'tcx> = &'tcx TyS<'tcx>; -impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {} -impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {} pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>; @@ -708,7 +708,7 @@ impl<'a, T> IntoIterator for &'a List { } } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List> {} impl List { #[inline(always)] @@ -1009,8 +1009,8 @@ pub struct GenericPredicates<'tcx> { pub predicates: Vec<(Predicate<'tcx>, Span)>, } -impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {} -impl<'tcx> serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {} impl<'tcx> GenericPredicates<'tcx> { pub fn instantiate( @@ -1985,13 +1985,13 @@ impl Hash for AdtDef { } } -impl<'tcx> serialize::UseSpecializedEncodable for &'tcx AdtDef { +impl<'tcx> rustc_serialize::UseSpecializedEncodable for &'tcx AdtDef { fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { self.did.encode(s) } } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx AdtDef {} impl<'a> HashStable> for AdtDef { diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index a25c1e34cf154..211a28fe9315f 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -5,7 +5,7 @@ use crate::hir::map::definitions::DefPathHash; use crate::ich::{CachingSourceMapView, Fingerprint}; use crate::mir::{self, interpret}; use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; -use crate::rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, SpecializedDecoder, SpecializedEncoder, UseSpecializedDecodable, UseSpecializedEncodable}; use crate::session::{CrateDisambiguator, Session}; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 5d17080a9b2bc..49a0fd827fbd8 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -26,7 +26,6 @@ use rustc_target::spec::abi; use syntax::ast::{self, Ident}; use syntax::symbol::{kw, InternedString}; -use serialize; use self::InferTy::*; use self::TyKind::*; @@ -640,7 +639,7 @@ impl<'tcx> Binder> { } } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List> {} impl<'tcx> List> { /// Returns the "principal def id" of this set of existential predicates. @@ -1324,7 +1323,7 @@ pub enum RegionKind { ReClosureBound(RegionVid), } -impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {} #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, PartialOrd, Ord)] pub struct EarlyBoundRegion { @@ -2333,7 +2332,7 @@ impl<'tcx> Const<'tcx> { } } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {} /// An inference variable for a const, for use in const generics. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 79dcd327f52d4..ea829da783e9b 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -6,7 +6,7 @@ use crate::ty::{self, Lift, List, Ty, TyCtxt, InferConst, ParamConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::mir::interpret::ConstValue; -use serialize::{self, Encodable, Encoder, Decodable, Decoder}; +use rustc_serialize::{self, Encodable, Encoder, Decodable, Decoder}; use syntax_pos::{Span, DUMMY_SP}; use smallvec::SmallVec; use rustc_macros::HashStable; @@ -399,7 +399,7 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { } } -impl<'tcx> serialize::UseSpecializedDecodable for SubstsRef<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for SubstsRef<'tcx> {} /////////////////////////////////////////////////////////////////////////// // Public trait `Subst` diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index e7ee06df7e12d..90d7320987c95 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -20,7 +20,7 @@ jobserver = "0.1.11" parking_lot = "0.7" tempfile = "3.0.5" -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc = { path = "../librustc" } diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 32696d46cd577..882963f9174ec 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -16,7 +16,7 @@ use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, LinkerPluginLto, Lto}; use rustc::ty::TyCtxt; use rustc_target::spec::{LinkerFlavor, LldFlavor}; -use serialize::{json, Encoder}; +use rustc_serialize::{json, Encoder}; /// For all the linkers we support, and information they might /// need out of the shared crate context before we get rid of it. diff --git a/src/librustc_codegen_ssa/back/wasm.rs b/src/librustc_codegen_ssa/back/wasm.rs index f90bb89fbe87d..2a9e81a788e52 100644 --- a/src/librustc_codegen_ssa/back/wasm.rs +++ b/src/librustc_codegen_ssa/back/wasm.rs @@ -2,7 +2,7 @@ use std::fs; use std::path::Path; use std::str; -use serialize::leb128; +use rustc_serialize::leb128; // https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec const WASM_CUSTOM_SECTION_ID: u8 = 0; diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 79cbe26e73e83..288676ce3ff67 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -15,7 +15,7 @@ indexmap = "1" log = "0.4" jobserver_crate = { version = "0.1.13", package = "jobserver" } lazy_static = "1" -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } graphviz = { path = "../libgraphviz" } cfg-if = "0.1.2" crossbeam-utils = { version = "0.6.5", features = ["nightly"] } diff --git a/src/librustc_data_structures/fingerprint.rs b/src/librustc_data_structures/fingerprint.rs index 3bea965ef3041..c8012bb942461 100644 --- a/src/librustc_data_structures/fingerprint.rs +++ b/src/librustc_data_structures/fingerprint.rs @@ -1,7 +1,6 @@ use crate::stable_hasher; use std::mem; -use serialize; -use serialize::opaque::{EncodeResult, Encoder, Decoder}; +use rustc_serialize::opaque::{EncodeResult, Encoder, Decoder}; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] pub struct Fingerprint(u64, u64); @@ -85,17 +84,17 @@ impl stable_hasher::StableHasherResult for Fingerprint { impl_stable_hash_via_hash!(Fingerprint); -impl serialize::UseSpecializedEncodable for Fingerprint { } +impl rustc_serialize::UseSpecializedEncodable for Fingerprint { } -impl serialize::UseSpecializedDecodable for Fingerprint { } +impl rustc_serialize::UseSpecializedDecodable for Fingerprint { } -impl serialize::SpecializedEncoder for serialize::opaque::Encoder { +impl rustc_serialize::SpecializedEncoder for Encoder { fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { f.encode_opaque(self) } } -impl<'a> serialize::SpecializedDecoder for serialize::opaque::Decoder<'a> { +impl<'a> rustc_serialize::SpecializedDecoder for Decoder<'a> { fn specialized_decode(&mut self) -> Result { Fingerprint::decode_opaque(self) } diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index c3c76e8160615..6f40d059be27f 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -1,3 +1,5 @@ +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; + use std::fmt::Debug; use std::iter::{self, FromIterator}; use std::slice; @@ -8,8 +10,6 @@ use std::hash::Hash; use std::vec; use std::u32; -use rustc_serialize as serialize; - /// Represents some newtyped `usize` wrapper. /// /// Purpose: avoid mixing indexes for different bitvector domains. @@ -398,17 +398,9 @@ macro_rules! newtype_index { ); (@decodable $type:ident) => ( - impl $type { - fn __decodable__impl__hack() { - mod __more_hacks_because__self_doesnt_work_in_functions { - extern crate serialize; - use self::serialize::{Decodable, Decoder}; - impl Decodable for super::$type { - fn decode(d: &mut D) -> Result { - d.read_u32().map(Self::from) - } - } - } + impl ::rustc_serialize::Decodable for $type { + fn decode(d: &mut D) -> Result { + d.read_u32().map(Self::from) } } ); @@ -521,15 +513,15 @@ pub struct IndexVec { // not the phantom data. unsafe impl Send for IndexVec where T: Send {} -impl serialize::Encodable for IndexVec { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - serialize::Encodable::encode(&self.raw, s) +impl Encodable for IndexVec { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&self.raw, s) } } -impl serialize::Decodable for IndexVec { - fn decode(d: &mut D) -> Result { - serialize::Decodable::decode(d).map(|v| { +impl Decodable for IndexVec { + fn decode(d: &mut D) -> Result { + Decodable::decode(d).map(|v| { IndexVec { raw: v, _marker: PhantomData } }) } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index a2407681e6d3f..3047119029abc 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -31,8 +31,6 @@ #[macro_use] extern crate log; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving #[cfg(unix)] extern crate libc; #[macro_use] diff --git a/src/librustc_data_structures/svh.rs b/src/librustc_data_structures/svh.rs index df4f61768375e..3123c182b0f4c 100644 --- a/src/librustc_data_structures/svh.rs +++ b/src/librustc_data_structures/svh.rs @@ -7,7 +7,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; -use serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use crate::stable_hasher; diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index d4c30dc6c4507..3162af5086d80 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -34,7 +34,7 @@ rustc_traits = { path = "../librustc_traits" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_typeck = { path = "../librustc_typeck" } rustc_interface = { path = "../librustc_interface" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } syntax_ext = { path = "../libsyntax_ext" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 2bc79e5080f3a..c139be07aa1d3 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -46,7 +46,7 @@ use rustc_interface::interface; use rustc_interface::util::get_codegen_sysroot; use rustc_data_structures::sync::SeqCst; -use serialize::json::ToJson; +use rustc_serialize::json::ToJson; use std::borrow::Cow; use std::cmp::max; diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml index 4df9632cce26b..5a192e472aa85 100644 --- a/src/librustc_errors/Cargo.toml +++ b/src/librustc_errors/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] log = "0.4" -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax_pos = { path = "../libsyntax_pos" } rustc_data_structures = { path = "../librustc_data_structures" } unicode-width = "0.1.4" diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 3269b85d0dd13..0a6c02c0ca68f 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -12,9 +12,6 @@ #![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving - pub use emitter::ColorConfig; use Level::*; diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml index 9678cb4f65545..a931ad3b66e21 100644 --- a/src/librustc_incremental/Cargo.toml +++ b/src/librustc_incremental/Cargo.toml @@ -15,7 +15,7 @@ log = "0.4" rand = "0.6" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc_fs_util = { path = "../librustc_fs_util" } diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 569aa78c9d4b3..55aba7caa9d42 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -12,9 +12,6 @@ #![deny(unused_lifetimes)] #[macro_use] extern crate rustc; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving - #[macro_use] extern crate log; mod assert_dep_graph; diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index a0efec5ee7a7f..a90254e7e185f 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -16,7 +16,7 @@ smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } rustc = { path = "../librustc" } rustc_allocator = { path = "../librustc_allocator" } rustc_ast_borrowck = { path = "../librustc_ast_borrowck" } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 6bf56bf851553..5298f99d54803 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -51,7 +51,7 @@ use syntax::feature_gate::AttributeType; use syntax_pos::{FileName, edition::Edition, hygiene}; use syntax_ext; -use serialize::json; +use rustc_serialize::json; use tempfile::Builder as TempFileBuilder; use std::any::Any; diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 570509ffb2b8c..9b79dc6350ca6 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -15,7 +15,7 @@ use rustc::ty::steal::Steal; use rustc::dep_graph::DepGraph; use rustc_passes::hir_stats; use rustc_plugin::registry::Registry; -use serialize::json; +use rustc_serialize::json; use std::cell::{Ref, RefMut, RefCell}; use std::ops::Deref; use std::rc::Rc; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index e5c9f1bf2057b..a9f054d5e8be8 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -18,7 +18,7 @@ rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_target = { path = "../librustc_target" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } stable_deref_trait = "1.0.0" syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 826349362db25..b0fe06039f4e2 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -18,8 +18,6 @@ #![deny(unused_lifetimes)] extern crate libc; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving extern crate proc_macro; #[macro_use] diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 8d1de4fd6c392..b7dd1d03e44ae 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -13,7 +13,6 @@ use rustc::ty::{self, Ty, ReprOptions}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_data_structures::svh::Svh; -use rustc_serialize as serialize; use syntax::{ast, attr}; use syntax::edition::Edition; use syntax::symbol::Symbol; @@ -85,8 +84,8 @@ impl Clone for Lazy { } } -impl serialize::UseSpecializedEncodable for Lazy {} -impl serialize::UseSpecializedDecodable for Lazy {} +impl rustc_serialize::UseSpecializedEncodable for Lazy {} +impl rustc_serialize::UseSpecializedDecodable for Lazy {} /// A sequence of type T referred to by its absolute position /// in the metadata and length, and which can be decoded lazily. @@ -133,8 +132,8 @@ impl Clone for LazySeq { } } -impl serialize::UseSpecializedEncodable for LazySeq {} -impl serialize::UseSpecializedDecodable for LazySeq {} +impl rustc_serialize::UseSpecializedEncodable for LazySeq {} +impl rustc_serialize::UseSpecializedDecodable for LazySeq {} /// Encoding / decoding state for `Lazy` and `LazySeq`. #[derive(Copy, Clone, PartialEq, Eq, Debug)] diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 2adbd03b24ff1..21008c737289f 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -20,7 +20,7 @@ rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } byteorder = { version = "1.1", features = ["i128"] } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index f5e4661afa6b1..964f04d79b960 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -30,13 +30,9 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![deny(unused_lifetimes)] #[macro_use] extern crate log; -#[macro_use] -extern crate rustc; +#[macro_use] extern crate rustc; #[macro_use] extern crate rustc_data_structures; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving -#[macro_use] -extern crate syntax; +#[macro_use] extern crate syntax; mod error_codes; diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml index f1b21365e4bd4..cab1e0e01371d 100644 --- a/src/librustc_target/Cargo.toml +++ b/src/librustc_target/Cargo.toml @@ -12,5 +12,5 @@ path = "lib.rs" bitflags = "1.0" log = "0.4" rustc_data_structures = { path = "../librustc_data_structures" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index dcd1eb5acdc85..a14bc66cc3833 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -18,8 +18,5 @@ #[macro_use] extern crate log; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving - pub mod abi; pub mod spec; diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1fdc9b015ba39..cda0dbef843b8 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -34,7 +34,7 @@ //! the target's settings, though `target-feature` and `link-args` will *add* //! to the list specified by the target, rather than replace. -use serialize::json::{Json, ToJson}; +use rustc_serialize::json::{Json, ToJson}; use std::collections::BTreeMap; use std::default::Default; use std::{fmt, io}; @@ -306,7 +306,7 @@ macro_rules! supported_targets { #[cfg(test)] mod test_json_encode_decode { - use serialize::json::ToJson; + use rustc_serialize::json::ToJson; use super::Target; $(use super::$module;)+ @@ -1198,7 +1198,7 @@ impl Target { pub fn search(target_triple: &TargetTriple) -> Result { use std::env; use std::fs; - use serialize::json; + use rustc_serialize::json; fn load_file(path: &Path) -> Result { let contents = fs::read(path).map_err(|e| e.to_string())?; diff --git a/src/libserialize/tests/json.rs b/src/libserialize/tests/json.rs index 0fe3d4cfd6297..3fb6bda679bc1 100644 --- a/src/libserialize/tests/json.rs +++ b/src/libserialize/tests/json.rs @@ -1,4 +1,3 @@ -#[allow(unused_extern_crates)] extern crate serialize as rustc_serialize; use rustc_serialize::{Encodable, Decodable}; diff --git a/src/libserialize/tests/opaque.rs b/src/libserialize/tests/opaque.rs index 62a8f25124439..fff6fc69e7842 100644 --- a/src/libserialize/tests/opaque.rs +++ b/src/libserialize/tests/opaque.rs @@ -1,4 +1,3 @@ -#[allow(unused_extern_crates)] extern crate serialize as rustc_serialize; use rustc_serialize::{Encodable, Decodable}; diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 15c685b3b7b50..d4a9acc1569b4 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] bitflags = "1.0" -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" scoped-tls = "1.0" lazy_static = "1.0.0" diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b9b43c89346c7..dbfad3ef7f4de 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -22,7 +22,7 @@ use syntax_pos::{Span, DUMMY_SP}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; -use serialize::{self, Decoder, Encoder}; +use rustc_serialize::{self, Decoder, Encoder}; use std::fmt; pub use rustc_target::abi::FloatTy; @@ -266,13 +266,13 @@ impl fmt::Display for NodeId { } } -impl serialize::UseSpecializedEncodable for NodeId { +impl rustc_serialize::UseSpecializedEncodable for NodeId { fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u32(self.as_u32()) } } -impl serialize::UseSpecializedDecodable for NodeId { +impl rustc_serialize::UseSpecializedDecodable for NodeId { fn default_decode(d: &mut D) -> Result { d.read_u32().map(NodeId::from_u32) } @@ -2414,12 +2414,11 @@ impl ForeignItemKind { #[cfg(test)] mod tests { use super::*; - use serialize; // Are ASTs encodable? #[test] fn check_asts_encodable() { - fn assert_encodable() {} + fn assert_encodable() {} assert_encodable::(); } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 3dea1977c4dac..0507a322a5fb2 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -24,9 +24,6 @@ #![recursion_limit="256"] -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving - pub use errors; use rustc_data_structures::sync::Lock; use rustc_data_structures::bit_set::GrowableBitSet; diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index be580dc2e6a7e..b5eb8ca94c07a 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -31,7 +31,7 @@ use std::iter::FromIterator; use std::ops::{Deref, DerefMut}; use std::{slice, vec}; -use serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, HashStable}; diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 88142344d79e0..34e68944926df 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -23,7 +23,7 @@ use syntax_pos::{BytePos, ExpnId, Span, DUMMY_SP}; #[cfg(target_arch = "x86_64")] use rustc_data_structures::static_assert_size; use rustc_data_structures::sync::Lrc; -use serialize::{Decoder, Decodable, Encoder, Encodable}; +use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use smallvec::{SmallVec, smallvec}; use std::borrow::Cow; diff --git a/src/libsyntax_pos/Cargo.toml b/src/libsyntax_pos/Cargo.toml index eebd25d1fafd8..bc13d2a161132 100644 --- a/src/libsyntax_pos/Cargo.toml +++ b/src/libsyntax_pos/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" doctest = false [dependencies] -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } arena = { path = "../libarena" } diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 944b1da36d038..a96e5ef2323ee 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -30,7 +30,7 @@ use crate::{Span, DUMMY_SP}; use crate::edition::Edition; use crate::symbol::{kw, Symbol}; -use serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use std::fmt; diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index b9a062c0765f0..e5f0892b37be8 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -19,10 +19,7 @@ #![feature(specialization)] #![feature(step_trait)] -use serialize::{Encodable, Decodable, Encoder, Decoder}; - -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; pub mod edition; use edition::Edition; @@ -594,7 +591,7 @@ impl Default for Span { } } -impl serialize::UseSpecializedEncodable for Span { +impl rustc_serialize::UseSpecializedEncodable for Span { fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { let span = self.data(); s.emit_struct("Span", 2, |s| { @@ -609,7 +606,7 @@ impl serialize::UseSpecializedEncodable for Span { } } -impl serialize::UseSpecializedDecodable for Span { +impl rustc_serialize::UseSpecializedDecodable for Span { fn default_decode(d: &mut D) -> Result { d.read_struct("Span", 2, |d| { let lo = d.read_struct_field("lo", 0, Decodable::decode)?; diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index f23ed7371c6dc..308f7d5d4e3fb 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::newtype_index; use rustc_macros::symbols; -use serialize::{Decodable, Decoder, Encodable, Encoder}; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::cmp::{PartialEq, Ordering, PartialOrd, Ord}; use std::fmt; From fe4cdd3078d43fc9d462e27f9dddcdef34ebe98e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 23 Jul 2019 20:30:57 +0200 Subject: [PATCH 64/79] Disable d32 on armv6 hf targets --- src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs | 2 +- src/librustc_target/spec/arm_unknown_linux_musleabihf.rs | 2 +- src/librustc_target/spec/armv6_unknown_freebsd.rs | 2 +- src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs index 8eb19a6518a3f..3c63371d12192 100644 --- a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs @@ -16,7 +16,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+strict-align,+v6,+vfp2".to_string(), + features: "+strict-align,+v6,+vfp2,-d32".to_string(), abi_blacklist: super::arm_base::abi_blacklist(), target_mcount: "\u{1}__gnu_mcount_nc".to_string(), .. base diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs index 496a0c4a43a7e..fb5a16f74c00b 100644 --- a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs @@ -5,7 +5,7 @@ pub fn target() -> TargetResult { // Most of these settings are copied from the arm_unknown_linux_gnueabihf // target. - base.features = "+strict-align,+v6,+vfp2".to_string(); + base.features = "+strict-align,+v6,+vfp2,-d32".to_string(); base.max_atomic_width = Some(64); Ok(Target { // It's important we use "gnueabihf" and not "musleabihf" here. LLVM diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/src/librustc_target/spec/armv6_unknown_freebsd.rs index efbbee959ed95..06233f7caa351 100644 --- a/src/librustc_target/spec/armv6_unknown_freebsd.rs +++ b/src/librustc_target/spec/armv6_unknown_freebsd.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+v6,+vfp2".to_string(), + features: "+v6,+vfp2,-d32".to_string(), max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), target_mcount: "\u{1}__gnu_mcount_nc".to_string(), diff --git a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs index b76c39ac75b8b..40411befcfc2b 100644 --- a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs +++ b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs @@ -16,7 +16,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+v6,+vfp2".to_string(), + features: "+v6,+vfp2,-d32".to_string(), abi_blacklist: super::arm_base::abi_blacklist(), target_mcount: "__mcount".to_string(), .. base From 1aeadcc0d560fd4ce88e2c5dfd98484c2443018b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 23 Jul 2019 12:04:31 -0700 Subject: [PATCH 65/79] Require a value for configure --debuginfo-level In `configure.py`, using the `o` function creates an enable/disable boolean setting, and writes `true` or `false` in `config.toml`. However, rustbuild is expecting to parse a `u32` debuginfo level. We can change to the `v` function to have the options require a value. --- src/bootstrap/configure.py | 10 +++++----- src/ci/run.sh | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 53d3dbf60d1d7..907983d43ade7 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -76,11 +76,11 @@ def v(*args): o("llvm-assertions", "llvm.assertions", "build LLVM with assertions") o("debug-assertions", "rust.debug-assertions", "build with debugging assertions") o("llvm-release-debuginfo", "llvm.release-debuginfo", "build LLVM with debugger metadata") -o("debuginfo-level", "rust.debuginfo-level", "debuginfo level for Rust code") -o("debuginfo-level-rustc", "rust.debuginfo-level-rustc", "debuginfo level for the compiler") -o("debuginfo-level-std", "rust.debuginfo-level-std", "debuginfo level for the standard library") -o("debuginfo-level-tools", "rust.debuginfo-level-tools", "debuginfo level for the tools") -o("debuginfo-level-tests", "rust.debuginfo-level-tests", "debuginfo level for the test suites run with compiletest") +v("debuginfo-level", "rust.debuginfo-level", "debuginfo level for Rust code") +v("debuginfo-level-rustc", "rust.debuginfo-level-rustc", "debuginfo level for the compiler") +v("debuginfo-level-std", "rust.debuginfo-level-std", "debuginfo level for the standard library") +v("debuginfo-level-tools", "rust.debuginfo-level-tools", "debuginfo level for the tools") +v("debuginfo-level-tests", "rust.debuginfo-level-tests", "debuginfo level for the test suites run with compiletest") v("save-toolstates", "rust.save-toolstates", "save build and test status of external tools into this file") v("prefix", "install.prefix", "set installation prefix") diff --git a/src/ci/run.sh b/src/ci/run.sh index 1039343827d87..f1eb417cdf982 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -50,7 +50,7 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.remap-debuginfo" - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.debuginfo-level-std=1" + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level-std=1" if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions" From a4ff823f5d7205a983461063d08902986c11d00d Mon Sep 17 00:00:00 2001 From: Scott Wolchok Date: Tue, 23 Jul 2019 13:37:17 -0700 Subject: [PATCH 66/79] fix check --- src/librustc_target/spec/apple_ios_base.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs index 40cc7f420106b..d400bc62bfd07 100644 --- a/src/librustc_target/spec/apple_ios_base.rs +++ b/src/librustc_target/spec/apple_ios_base.rs @@ -1,5 +1,6 @@ use std::env; use std::io; +use std::path::Path; use std::process::Command; use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; @@ -29,7 +30,7 @@ impl Arch { pub fn get_sdk_root(sdk_name: &str) -> Result { if let Some(sdkroot) = env::var("SDKROOT").ok() { - let sdkroot_path = Path::new(sdkroot); + let sdkroot_path = Path::new(&sdkroot); if sdkroot_path.is_absolute() && sdkroot_path != Path::new("/") && sdkroot_path.exists() { return Ok(sdkroot); } From 71717b951a2f87720d9d8926e9a21353c120f700 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 23 Jul 2019 22:00:25 +0200 Subject: [PATCH 67/79] Initialize the MSP430 AsmParser if available --- src/librustc_llvm/build.rs | 4 ++++ src/librustc_llvm/lib.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 21fa872c8dadb..07d2e6dc28c2c 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -119,6 +119,10 @@ fn main() { println!("cargo:rustc-cfg=llvm_component=\"{}\"", component); } + if major >= 9 { + println!("cargo:rustc-cfg=llvm_has_msp430_asm_parser"); + } + // Link in our own LLVM shims, compiled with the same flags as LLVM let mut cmd = Command::new(&llvm_config); cmd.arg("--cxxflags"); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index bdf6b09185735..dea7e6ae0a2ab 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -76,6 +76,8 @@ pub fn initialize_available_targets() { LLVMInitializeMSP430Target, LLVMInitializeMSP430TargetMC, LLVMInitializeMSP430AsmPrinter); + init_target!(all(llvm_component = "msp430", llvm_has_msp430_asm_parser), + LLVMInitializeMSP430AsmParser); init_target!(llvm_component = "riscv", LLVMInitializeRISCVTargetInfo, LLVMInitializeRISCVTarget, From bd8813e52c5120c40ec3cca096ff4a98fdf56be8 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 24 Jul 2019 01:42:39 +0200 Subject: [PATCH 68/79] Add method disambiguation help for trait implementation Closes #51046 Closes #40471 --- src/librustc_typeck/check/method/suggest.rs | 50 ++++++++++++------- .../method-ambig-two-traits-from-impls.rs | 16 ++++++ .../method-ambig-two-traits-from-impls.stderr | 22 ++++++++ .../method-ambig-two-traits-from-impls2.rs | 16 ++++++ ...method-ambig-two-traits-from-impls2.stderr | 22 ++++++++ 5 files changed, 107 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/methods/method-ambig-two-traits-from-impls.rs create mode 100644 src/test/ui/methods/method-ambig-two-traits-from-impls.stderr create mode 100644 src/test/ui/methods/method-ambig-two-traits-from-impls2.rs create mode 100644 src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 5febc694def0c..cd4c8a28dab28 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -10,7 +10,6 @@ use rustc::hir::{self, ExprKind, Node, QPath}; use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::hir::map as hir_map; -use rustc::hir::print; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::traits::Obligation; use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable}; @@ -78,6 +77,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } + let print_disambiguation_help = | + err: &mut DiagnosticBuilder<'_>, + trait_name: String, + | { + err.help(&format!( + "to disambiguate the method call, write `{}::{}({}{})` instead", + trait_name, + item_name, + if rcvr_ty.is_region_ptr() && args.is_some() { + if rcvr_ty.is_mutable_pointer() { + "&mut " + } else { + "&" + } + } else { + "" + }, + args.map(|arg| arg + .iter() + .map(|arg| self.tcx.sess.source_map().span_to_snippet(arg.span) + .unwrap_or_else(|_| "...".to_owned())) + .collect::>() + .join(", ") + ).unwrap_or_else(|| "...".to_owned()) + )); + }; + let report_candidates = | span: Span, err: &mut DiagnosticBuilder<'_>, @@ -139,6 +165,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.note(¬e_str); } + if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { + print_disambiguation_help(err, self.tcx.def_path_str(trait_ref.def_id)); + } } CandidateSource::TraitSource(trait_did) => { let item = match self.associated_item( @@ -163,24 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "the candidate is defined in the trait `{}`", self.tcx.def_path_str(trait_did)); } - err.help(&format!("to disambiguate the method call, write `{}::{}({}{})` \ - instead", - self.tcx.def_path_str(trait_did), - item_name, - if rcvr_ty.is_region_ptr() && args.is_some() { - if rcvr_ty.is_mutable_pointer() { - "&mut " - } else { - "&" - } - } else { - "" - }, - args.map(|arg| arg.iter() - .map(|arg| print::to_string(print::NO_ANN, - |s| s.print_expr(arg))) - .collect::>() - .join(", ")).unwrap_or_else(|| "...".to_owned()))); + print_disambiguation_help(err, self.tcx.def_path_str(trait_did)); } } } diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls.rs b/src/test/ui/methods/method-ambig-two-traits-from-impls.rs new file mode 100644 index 0000000000000..22bf840660536 --- /dev/null +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls.rs @@ -0,0 +1,16 @@ +trait A { fn foo(self); } +trait B { fn foo(self); } + +struct AB {} + +impl A for AB { + fn foo(self) {} +} + +impl B for AB { + fn foo(self) {} +} + +fn main() { + AB {}.foo(); //~ ERROR E0034 +} diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr new file mode 100644 index 0000000000000..0b3724e030fa4 --- /dev/null +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr @@ -0,0 +1,22 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/method-ambig-two-traits-from-impls.rs:15:11 + | +LL | AB {}.foo(); + | ^^^ multiple `foo` found + | +note: candidate #1 is defined in an impl of the trait `A` for the type `AB` + --> $DIR/method-ambig-two-traits-from-impls.rs:7:5 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^ + = help: to disambiguate the method call, write `A::foo(AB {})` instead +note: candidate #2 is defined in an impl of the trait `B` for the type `AB` + --> $DIR/method-ambig-two-traits-from-impls.rs:11:5 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^ + = help: to disambiguate the method call, write `B::foo(AB {})` instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls2.rs b/src/test/ui/methods/method-ambig-two-traits-from-impls2.rs new file mode 100644 index 0000000000000..0a96c1223da36 --- /dev/null +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls2.rs @@ -0,0 +1,16 @@ +trait A { fn foo(); } +trait B { fn foo(); } + +struct AB {} + +impl A for AB { + fn foo() {} +} + +impl B for AB { + fn foo() {} +} + +fn main() { + AB::foo(); //~ ERROR E0034 +} diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr new file mode 100644 index 0000000000000..81c99b33c813e --- /dev/null +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr @@ -0,0 +1,22 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/method-ambig-two-traits-from-impls2.rs:15:5 + | +LL | AB::foo(); + | ^^^^^^^ multiple `foo` found + | +note: candidate #1 is defined in an impl of the trait `A` for the type `AB` + --> $DIR/method-ambig-two-traits-from-impls2.rs:7:5 + | +LL | fn foo() {} + | ^^^^^^^^ + = help: to disambiguate the method call, write `A::foo(...)` instead +note: candidate #2 is defined in an impl of the trait `B` for the type `AB` + --> $DIR/method-ambig-two-traits-from-impls2.rs:11:5 + | +LL | fn foo() {} + | ^^^^^^^^ + = help: to disambiguate the method call, write `B::foo(...)` instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0034`. From be510dbc35960c9d90f42811787eea2acef8ffe5 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 24 Jul 2019 02:25:01 +0200 Subject: [PATCH 69/79] Adjust tests for method disambiguation help --- .../associated-const/associated-const-ambiguity-report.stderr | 2 ++ src/test/ui/error-codes/E0034.stderr | 2 ++ src/test/ui/inference/inference_unstable_featured.stderr | 2 ++ src/test/ui/issues/issue-3702-2.stderr | 2 ++ src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr | 2 ++ .../methods/method-ambig-two-traits-with-default-method.stderr | 2 ++ ...ethod-deref-to-same-trait-object-with-separate-params.stderr | 2 ++ src/test/ui/traits/trait-alias-ambiguous.stderr | 2 ++ 8 files changed, 16 insertions(+) diff --git a/src/test/ui/associated-const/associated-const-ambiguity-report.stderr b/src/test/ui/associated-const/associated-const-ambiguity-report.stderr index 5f2b9c47e8c2a..bb217bd182db6 100644 --- a/src/test/ui/associated-const/associated-const-ambiguity-report.stderr +++ b/src/test/ui/associated-const/associated-const-ambiguity-report.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `Foo` for the type `i32` | LL | const ID: i32 = 1; | ^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Foo::ID(...)` instead note: candidate #2 is defined in an impl of the trait `Bar` for the type `i32` --> $DIR/associated-const-ambiguity-report.rs:14:5 | LL | const ID: i32 = 3; | ^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Bar::ID(...)` instead error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0034.stderr b/src/test/ui/error-codes/E0034.stderr index 816a48f102dce..a58d16bfafb59 100644 --- a/src/test/ui/error-codes/E0034.stderr +++ b/src/test/ui/error-codes/E0034.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `Trait1` for the type `Tes | LL | fn foo() {} | ^^^^^^^^ + = help: to disambiguate the method call, write `Trait1::foo(...)` instead note: candidate #2 is defined in an impl of the trait `Trait2` for the type `Test` --> $DIR/E0034.rs:16:5 | LL | fn foo() {} | ^^^^^^^^ + = help: to disambiguate the method call, write `Trait2::foo(...)` instead error: aborting due to previous error diff --git a/src/test/ui/inference/inference_unstable_featured.stderr b/src/test/ui/inference/inference_unstable_featured.stderr index 08cdb8cc6883f..b06a6298a571c 100644 --- a/src/test/ui/inference/inference_unstable_featured.stderr +++ b/src/test/ui/inference/inference_unstable_featured.stderr @@ -5,7 +5,9 @@ LL | assert_eq!('x'.ipu_flatten(), 0); | ^^^^^^^^^^^ multiple `ipu_flatten` found | = note: candidate #1 is defined in an impl of the trait `inference_unstable_iterator::IpuIterator` for the type `char` + = help: to disambiguate the method call, write `inference_unstable_iterator::IpuIterator::ipu_flatten('x')` instead = note: candidate #2 is defined in an impl of the trait `inference_unstable_itertools::IpuItertools` for the type `char` + = help: to disambiguate the method call, write `inference_unstable_itertools::IpuItertools::ipu_flatten('x')` instead error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3702-2.stderr b/src/test/ui/issues/issue-3702-2.stderr index 347a19b687fbb..4d0ff750c254c 100644 --- a/src/test/ui/issues/issue-3702-2.stderr +++ b/src/test/ui/issues/issue-3702-2.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `ToPrimitive` for the type | LL | fn to_int(&self) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `ToPrimitive::to_int(&self)` instead note: candidate #2 is defined in an impl of the trait `Add` for the type `isize` --> $DIR/issue-3702-2.rs:14:5 | LL | fn to_int(&self) -> isize { *self } | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Add::to_int(&self)` instead error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr index 2b87ddfdf98e5..9f46a722a508e 100644 --- a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr @@ -9,7 +9,9 @@ note: candidate #1 is defined in an impl of the trait `Me2` for the type `usize` | LL | impl Me2 for usize { fn me(&self) -> usize { *self } } | ^^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Me2::me(1_usize)` instead = note: candidate #2 is defined in an impl of the trait `ambig_impl_2_lib::Me` for the type `usize` + = help: to disambiguate the method call, write `ambig_impl_2_lib::Me::me(1_usize)` instead error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr index 5d508d5702258..dc8aef2503739 100644 --- a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `Foo` for the type `usize` | LL | trait Foo { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Foo::method(1_usize)` instead note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize` --> $DIR/method-ambig-two-traits-with-default-method.rs:6:13 | LL | trait Bar { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Bar::method(1_usize)` instead error: aborting due to previous error diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index d6fac7025a479..283ef8fcba7a4 100644 --- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -27,11 +27,13 @@ note: candidate #1 is defined in an impl of the trait `internal::X` for the type | LL | fn foo(self: Smaht) -> u64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `internal::X::foo(x)` instead note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `_` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:70:9 | LL | fn foo(self) {} | ^^^^^^^^^^^^ + = help: to disambiguate the method call, write `nuisance_foo::NuisanceFoo::foo(x)` instead note: candidate #3 is defined in the trait `FinalFoo` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:57:5 | diff --git a/src/test/ui/traits/trait-alias-ambiguous.stderr b/src/test/ui/traits/trait-alias-ambiguous.stderr index b7443269b882d..cde7dd0824924 100644 --- a/src/test/ui/traits/trait-alias-ambiguous.stderr +++ b/src/test/ui/traits/trait-alias-ambiguous.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `inner::A` for the type `u | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `inner::A::foo(t)` instead note: candidate #2 is defined in an impl of the trait `inner::B` for the type `u8` --> $DIR/trait-alias-ambiguous.rs:11:9 | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `inner::B::foo(t)` instead error: aborting due to previous error From a93fdfedf36dcb909d90cbf963b087c5873bec1d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 16 Jul 2019 21:06:17 +0300 Subject: [PATCH 70/79] Merge `rustc_allocator` into `libsyntax_ext` --- Cargo.lock | 18 ------- src/librustc/lib.rs | 1 - src/librustc/middle/allocator.rs | 16 ------- src/librustc/session/mod.rs | 2 +- src/librustc_allocator/Cargo.toml | 19 -------- src/librustc_codegen_llvm/allocator.rs | 3 +- src/librustc_codegen_llvm/lib.rs | 3 +- src/librustc_codegen_ssa/Cargo.toml | 1 - .../back/symbol_export.rs | 4 +- src/librustc_codegen_ssa/traits/backend.rs | 2 +- src/librustc_driver/Cargo.toml | 2 - src/librustc_interface/Cargo.toml | 1 - src/librustc_interface/passes.rs | 2 +- src/librustc_metadata/creader.rs | 2 +- .../lib.rs => libsyntax/ext/allocator.rs} | 47 +++++++++++-------- src/libsyntax/lib.rs | 1 + .../global_allocator.rs} | 8 ++-- src/libsyntax_ext/lib.rs | 1 + 18 files changed, 41 insertions(+), 92 deletions(-) delete mode 100644 src/librustc/middle/allocator.rs delete mode 100644 src/librustc_allocator/Cargo.toml rename src/{librustc_allocator/lib.rs => libsyntax/ext/allocator.rs} (68%) rename src/{librustc_allocator/expand.rs => libsyntax_ext/global_allocator.rs} (98%) diff --git a/Cargo.lock b/Cargo.lock index bdc746c0bb0e0..8993254627863 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2751,20 +2751,6 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rustc_allocator" -version = "0.0.0" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc 0.0.0", - "rustc_data_structures 0.0.0", - "rustc_errors 0.0.0", - "rustc_target 0.0.0", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syntax 0.0.0", - "syntax_pos 0.0.0", -] - [[package]] name = "rustc_apfloat" version = "0.0.0" @@ -2822,7 +2808,6 @@ dependencies = [ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", - "rustc_allocator 0.0.0", "rustc_apfloat 0.0.0", "rustc_codegen_utils 0.0.0", "rustc_data_structures 0.0.0", @@ -2883,7 +2868,6 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_allocator 0.0.0", "rustc_ast_borrowck 0.0.0", "rustc_codegen_utils 0.0.0", "rustc_data_structures 0.0.0", @@ -2904,7 +2888,6 @@ dependencies = [ "serialize 0.0.0", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", - "syntax_ext 0.0.0", "syntax_pos 0.0.0", ] @@ -2948,7 +2931,6 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_allocator 0.0.0", "rustc_ast_borrowck 0.0.0", "rustc_codegen_ssa 0.0.0", "rustc_codegen_utils 0.0.0", diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 63e0107a4d882..45c6aa63c5581 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -112,7 +112,6 @@ pub mod infer; pub mod lint; pub mod middle { - pub mod allocator; pub mod borrowck; pub mod expr_use_visitor; pub mod cstore; diff --git a/src/librustc/middle/allocator.rs b/src/librustc/middle/allocator.rs deleted file mode 100644 index bb2e3b4ec1971..0000000000000 --- a/src/librustc/middle/allocator.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[derive(Clone, Copy)] -pub enum AllocatorKind { - Global, - DefaultLib, - DefaultExe, -} - -impl AllocatorKind { - pub fn fn_name(&self, base: &str) -> String { - match *self { - AllocatorKind::Global => format!("__rg_{}", base), - AllocatorKind::DefaultLib => format!("__rdl_{}", base), - AllocatorKind::DefaultExe => format!("__rde_{}", base), - } - } -} diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 664926a152f14..d7620817f0448 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -7,7 +7,6 @@ use rustc_data_structures::fingerprint::Fingerprint; use crate::lint; use crate::lint::builtin::BuiltinLintDiagnostics; -use crate::middle::allocator::AllocatorKind; use crate::middle::dependency_format; use crate::session::config::{OutputType, PrintRequest, SwitchWithOptPath}; use crate::session::search_paths::{PathKind, SearchPath}; @@ -27,6 +26,7 @@ use errors::emitter::HumanReadableErrorType; use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter}; use syntax::ast::{self, NodeId}; use syntax::edition::Edition; +use syntax::ext::allocator::AllocatorKind; use syntax::feature_gate::{self, AttributeType}; use syntax::json::JsonEmitter; use syntax::source_map; diff --git a/src/librustc_allocator/Cargo.toml b/src/librustc_allocator/Cargo.toml deleted file mode 100644 index a964f323c9e7d..0000000000000 --- a/src/librustc_allocator/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_allocator" -version = "0.0.0" -edition = "2018" - -[lib] -path = "lib.rs" -test = false - -[dependencies] -rustc = { path = "../librustc" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_target = { path = "../librustc_target" } -syntax = { path = "../libsyntax" } -syntax_pos = { path = "../libsyntax_pos" } -log = "0.4" -smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/librustc_codegen_llvm/allocator.rs b/src/librustc_codegen_llvm/allocator.rs index 02a05fd110200..5d43bf6ae28bf 100644 --- a/src/librustc_codegen_llvm/allocator.rs +++ b/src/librustc_codegen_llvm/allocator.rs @@ -2,9 +2,8 @@ use std::ffi::CString; use crate::attributes; use libc::c_uint; -use rustc::middle::allocator::AllocatorKind; use rustc::ty::TyCtxt; -use rustc_allocator::{ALLOCATOR_METHODS, AllocatorTy}; +use syntax::ext::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use crate::ModuleLlvm; use crate::llvm::{self, False, True}; diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 0f0b9f279175c..8dd241bd81a0a 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -32,7 +32,6 @@ extern crate flate2; #[macro_use] extern crate bitflags; extern crate libc; #[macro_use] extern crate rustc; -extern crate rustc_allocator; extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; extern crate rustc_incremental; @@ -52,13 +51,13 @@ use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinModul use rustc_codegen_ssa::CompiledModule; use errors::{FatalError, Handler}; use rustc::dep_graph::WorkProduct; +use syntax::ext::allocator::AllocatorKind; use syntax_pos::symbol::InternedString; pub use llvm_util::target_features; use std::any::Any; use std::sync::{mpsc, Arc}; use rustc::dep_graph::DepGraph; -use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; use rustc::session::Session; use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index e7ee06df7e12d..3c51c777f53e1 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -24,7 +24,6 @@ serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc = { path = "../librustc" } -rustc_allocator = { path = "../librustc_allocator" } rustc_apfloat = { path = "../librustc_apfloat" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_data_structures = { path = "../librustc_data_structures"} diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index c5553fa93cf67..2d9220f897cff 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -1,3 +1,4 @@ +use std::collections::hash_map::Entry::*; use std::sync::Arc; use rustc::ty::Instance; @@ -12,9 +13,8 @@ use rustc::ty::{TyCtxt, SymbolName}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::util::nodemap::{FxHashMap, DefIdMap}; -use rustc_allocator::ALLOCATOR_METHODS; use rustc_data_structures::indexed_vec::IndexVec; -use std::collections::hash_map::Entry::*; +use syntax::ext::allocator::ALLOCATOR_METHODS; pub type ExportedSymbols = FxHashMap< CrateNum, diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 9d5aaa7655db8..9fbb44dcc9959 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -3,12 +3,12 @@ use rustc::ty::Ty; use super::write::WriteBackendMethods; use super::CodegenObject; -use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::EncodedMetadata; use rustc::session::{Session, config}; use rustc::ty::TyCtxt; use rustc_codegen_utils::codegen_backend::CodegenBackend; use std::sync::Arc; +use syntax::ext::allocator::AllocatorKind; use syntax_pos::symbol::InternedString; pub trait BackendTypes { diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index d4c30dc6c4507..aafc78cf94eff 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -16,7 +16,6 @@ log = "0.4" env_logger = { version = "0.5", default-features = false } rayon = { version = "0.2.0", package = "rustc-rayon" } rustc = { path = "../librustc" } -rustc_allocator = { path = "../librustc_allocator" } rustc_target = { path = "../librustc_target" } rustc_ast_borrowck = { path = "../librustc_ast_borrowck" } rustc_data_structures = { path = "../librustc_data_structures" } @@ -37,5 +36,4 @@ rustc_interface = { path = "../librustc_interface" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } -syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index a0efec5ee7a7f..44fe3ff2c9df8 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -18,7 +18,6 @@ syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } serialize = { path = "../libserialize" } rustc = { path = "../librustc" } -rustc_allocator = { path = "../librustc_allocator" } rustc_ast_borrowck = { path = "../librustc_ast_borrowck" } rustc_incremental = { path = "../librustc_incremental" } rustc_traits = { path = "../librustc_traits" } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 6bf56bf851553..d4a922ddd49e3 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -497,7 +497,7 @@ fn configure_and_expand_inner<'a>( if has_global_allocator { // Expand global allocators, which are treated as an in-tree proc macro time(sess, "creating allocators", || { - allocator::expand::modify( + syntax_ext::global_allocator::modify( &sess.parse_sess, &mut resolver, &mut krate, diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 126cfec157ff3..31f70155b4e37 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -8,7 +8,6 @@ use rustc_data_structures::sync::{Lrc, RwLock, Lock}; use rustc::hir::def_id::CrateNum; use rustc_data_structures::svh::Svh; -use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::DepKind; use rustc::mir::interpret::AllocDecodingState; use rustc::session::{Session, CrateDisambiguator}; @@ -26,6 +25,7 @@ use std::{cmp, fs}; use syntax::ast; use syntax::attr; +use syntax::ext::allocator::AllocatorKind; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use syntax::symbol::{Symbol, sym}; use syntax::visit; diff --git a/src/librustc_allocator/lib.rs b/src/libsyntax/ext/allocator.rs similarity index 68% rename from src/librustc_allocator/lib.rs rename to src/libsyntax/ext/allocator.rs index 8d380c47bc4a3..f2c6bf27cee0c 100644 --- a/src/librustc_allocator/lib.rs +++ b/src/libsyntax/ext/allocator.rs @@ -1,10 +1,33 @@ -#![feature(nll)] -#![feature(rustc_private)] +#[derive(Clone, Copy)] +pub enum AllocatorKind { + Global, + DefaultLib, + DefaultExe, +} -#![deny(rust_2018_idioms)] -#![deny(unused_lifetimes)] +impl AllocatorKind { + pub fn fn_name(&self, base: &str) -> String { + match *self { + AllocatorKind::Global => format!("__rg_{}", base), + AllocatorKind::DefaultLib => format!("__rdl_{}", base), + AllocatorKind::DefaultExe => format!("__rde_{}", base), + } + } +} -pub mod expand; +pub enum AllocatorTy { + Layout, + Ptr, + ResultPtr, + Unit, + Usize, +} + +pub struct AllocatorMethod { + pub name: &'static str, + pub inputs: &'static [AllocatorTy], + pub output: AllocatorTy, +} pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ AllocatorMethod { @@ -28,17 +51,3 @@ pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ output: AllocatorTy::ResultPtr, }, ]; - -pub struct AllocatorMethod { - pub name: &'static str, - pub inputs: &'static [AllocatorTy], - pub output: AllocatorTy, -} - -pub enum AllocatorTy { - Layout, - Ptr, - ResultPtr, - Unit, - Usize, -} diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 3dea1977c4dac..e3bc72335aba0 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -165,6 +165,7 @@ pub mod print { pub mod ext { pub use syntax_pos::hygiene; + pub mod allocator; pub mod base; pub mod build; pub mod derive; diff --git a/src/librustc_allocator/expand.rs b/src/libsyntax_ext/global_allocator.rs similarity index 98% rename from src/librustc_allocator/expand.rs rename to src/libsyntax_ext/global_allocator.rs index af63fffc0f9b4..e8f94bff14470 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -1,5 +1,4 @@ use log::debug; -use rustc::middle::allocator::AllocatorKind; use smallvec::{smallvec, SmallVec}; use syntax::{ ast::{ @@ -11,6 +10,7 @@ use syntax::{ respan, ExpnInfo, ExpnKind, }, ext::{ + allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}, base::{ExtCtxt, MacroKind, Resolver}, build::AstBuilder, expand::ExpansionConfig, @@ -23,14 +23,12 @@ use syntax::{ }; use syntax_pos::Span; -use crate::{AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; - pub fn modify( sess: &ParseSess, resolver: &mut dyn Resolver, krate: &mut Crate, crate_name: String, - handler: &rustc_errors::Handler, + handler: &errors::Handler, ) { ExpandAllocatorDirectives { handler, @@ -44,7 +42,7 @@ pub fn modify( struct ExpandAllocatorDirectives<'a> { found: bool, - handler: &'a rustc_errors::Handler, + handler: &'a errors::Handler, sess: &'a ParseSess, resolver: &'a mut dyn Resolver, crate_name: Option, diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 7de90278ed732..cd7ac5fe2c66c 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -37,6 +37,7 @@ mod test_case; mod trace_macros; pub mod deriving; +pub mod global_allocator; pub mod proc_macro_decls; pub mod proc_macro_impl; From 433024147ae1e9795fe7e94cb1810a17fd37fa51 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 19 Jul 2019 00:24:58 +0300 Subject: [PATCH 71/79] syntax_ext: Turn `#[global_allocator]` into a regular attribute macro --- src/libcore/macros.rs | 7 + src/librustc/middle/dead.rs | 5 - src/librustc_interface/passes.rs | 15 +- src/librustc_metadata/creader.rs | 29 +-- src/librustc_metadata/lib.rs | 5 +- src/librustc_passes/ast_validation.rs | 10 +- src/libsyntax/ext/allocator.rs | 22 ++ src/libsyntax/feature_gate.rs | 1 - src/libsyntax_ext/global_allocator.rs | 223 ++++++------------ src/libsyntax_ext/lib.rs | 8 +- .../run-pass/allocator/custom-in-block.rs | 21 ++ .../run-pass/allocator/custom-in-submodule.rs | 25 ++ src/test/ui/allocator-submodule.rs | 28 --- src/test/ui/allocator-submodule.stderr | 8 - src/test/ui/allocator/allocator-args.rs | 13 + src/test/ui/allocator/allocator-args.stderr | 8 + src/test/ui/allocator/two-allocators.rs | 2 +- src/test/ui/allocator/two-allocators.stderr | 8 +- src/tools/tidy/src/features.rs | 2 +- 19 files changed, 205 insertions(+), 235 deletions(-) create mode 100644 src/test/run-pass/allocator/custom-in-block.rs create mode 100644 src/test/run-pass/allocator/custom-in-submodule.rs delete mode 100644 src/test/ui/allocator-submodule.rs delete mode 100644 src/test/ui/allocator-submodule.stderr create mode 100644 src/test/ui/allocator/allocator-args.rs create mode 100644 src/test/ui/allocator/allocator-args.stderr diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 296bb43f9fad4..17781798946ed 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -1281,6 +1281,13 @@ mod builtin { #[rustc_macro_transparency = "semitransparent"] pub macro test_case($item:item) { /* compiler built-in */ } + /// Attribute macro applied to a static to register it as a global allocator. + #[stable(feature = "global_allocator", since = "1.28.0")] + #[allow_internal_unstable(rustc_attrs)] + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + pub macro global_allocator($item:item) { /* compiler built-in */ } + /// Derive macro generating an impl of the trait `Clone`. #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 4c27318c3e19b..88de77829a6e0 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -320,11 +320,6 @@ fn has_allow_dead_code_or_lang_attr( return true; } - // Don't lint about global allocators - if attr::contains_name(attrs, sym::global_allocator) { - return true; - } - let def_id = tcx.hir().local_def_id(id); let cg_attrs = tcx.codegen_fn_attrs(def_id); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index d4a922ddd49e3..b460a908f1b12 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -468,7 +468,7 @@ fn configure_and_expand_inner<'a>( util::ReplaceBodyWithLoop::new(sess).visit_crate(&mut krate); } - let (has_proc_macro_decls, has_global_allocator) = time(sess, "AST validation", || { + let has_proc_macro_decls = time(sess, "AST validation", || { ast_validation::check_crate(sess, &krate) }); @@ -494,19 +494,6 @@ fn configure_and_expand_inner<'a>( }); } - if has_global_allocator { - // Expand global allocators, which are treated as an in-tree proc macro - time(sess, "creating allocators", || { - syntax_ext::global_allocator::modify( - &sess.parse_sess, - &mut resolver, - &mut krate, - crate_name.to_string(), - sess.diagnostic(), - ) - }); - } - // Done with macro expansion! if sess.opts.debugging_opts.input_stats { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 31f70155b4e37..3404ec5e173bd 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -25,10 +25,9 @@ use std::{cmp, fs}; use syntax::ast; use syntax::attr; -use syntax::ext::allocator::AllocatorKind; +use syntax::ext::allocator::{global_allocator_spans, AllocatorKind}; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use syntax::symbol::{Symbol, sym}; -use syntax::visit; use syntax::{span_err, span_fatal}; use syntax_pos::{Span, DUMMY_SP}; use log::{debug, info, log_enabled}; @@ -888,7 +887,14 @@ impl<'a> CrateLoader<'a> { } fn inject_allocator_crate(&mut self, krate: &ast::Crate) { - let has_global_allocator = has_global_allocator(krate); + let has_global_allocator = match &*global_allocator_spans(krate) { + [span1, span2, ..] => { + self.sess.struct_span_err(*span2, "cannot define multiple global allocators") + .span_note(*span1, "the previous global allocator is defined here").emit(); + true + } + spans => !spans.is_empty() + }; self.sess.has_global_allocator.set(has_global_allocator); // Check to see if we actually need an allocator. This desire comes @@ -975,25 +981,8 @@ impl<'a> CrateLoader<'a> { that implements the GlobalAlloc trait."); } self.sess.allocator_kind.set(Some(AllocatorKind::DefaultLib)); - - fn has_global_allocator(krate: &ast::Crate) -> bool { - struct Finder(bool); - let mut f = Finder(false); - visit::walk_crate(&mut f, krate); - return f.0; - - impl<'ast> visit::Visitor<'ast> for Finder { - fn visit_item(&mut self, i: &'ast ast::Item) { - if attr::contains_name(&i.attrs, sym::global_allocator) { - self.0 = true; - } - visit::walk_item(self, i) - } - } - } } - fn inject_dependency_if(&self, krate: CrateNum, what: &str, diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 826349362db25..30bb37e4680d1 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -1,6 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(box_patterns)] +#![feature(crate_visibility_modifier)] #![feature(drain_filter)] #![feature(in_band_lifetimes)] #![feature(libc)] @@ -8,9 +9,9 @@ #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![feature(rustc_diagnostic_macros)] -#![feature(crate_visibility_modifier)] -#![feature(specialization)] #![feature(rustc_private)] +#![feature(slice_patterns)] +#![feature(specialization)] #![recursion_limit="256"] diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 560635962995c..b550029d9786d 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -51,7 +51,6 @@ impl OuterImplTrait { struct AstValidator<'a> { session: &'a Session, has_proc_macro_decls: bool, - has_global_allocator: bool, /// Used to ban nested `impl Trait`, e.g., `impl Into`. /// Nested `impl Trait` _is_ allowed in associated type position, @@ -539,10 +538,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.has_proc_macro_decls = true; } - if attr::contains_name(&item.attrs, sym::global_allocator) { - self.has_global_allocator = true; - } - match item.node { ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { self.invalid_visibility(&item.vis, None); @@ -848,11 +843,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } -pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) { +pub fn check_crate(session: &Session, krate: &Crate) -> bool { let mut validator = AstValidator { session, has_proc_macro_decls: false, - has_global_allocator: false, outer_impl_trait: None, is_impl_trait_banned: false, is_assoc_ty_bound_banned: false, @@ -861,5 +855,5 @@ pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) { }; visit::walk_crate(&mut validator, krate); - (validator.has_proc_macro_decls, validator.has_global_allocator) + validator.has_proc_macro_decls } diff --git a/src/libsyntax/ext/allocator.rs b/src/libsyntax/ext/allocator.rs index f2c6bf27cee0c..99aeb5414c5d8 100644 --- a/src/libsyntax/ext/allocator.rs +++ b/src/libsyntax/ext/allocator.rs @@ -1,3 +1,7 @@ +use crate::{ast, attr, visit}; +use crate::symbol::{sym, Symbol}; +use syntax_pos::Span; + #[derive(Clone, Copy)] pub enum AllocatorKind { Global, @@ -51,3 +55,21 @@ pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ output: AllocatorTy::ResultPtr, }, ]; + +pub fn global_allocator_spans(krate: &ast::Crate) -> Vec { + struct Finder { name: Symbol, spans: Vec } + impl<'ast> visit::Visitor<'ast> for Finder { + fn visit_item(&mut self, item: &'ast ast::Item) { + if item.ident.name == self.name && + attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) { + self.spans.push(item.span); + } + visit::walk_item(self, item) + } + } + + let name = Symbol::intern(&AllocatorKind::Global.fn_name("alloc")); + let mut f = Finder { name, spans: Vec::new() }; + visit::walk_crate(&mut f, krate); + f.spans +} diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 43f0eaae7c97e..214160f10790d 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1117,7 +1117,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "the `#[rustc_const_unstable]` attribute \ is an internal feature", cfg_fn!(rustc_const_unstable))), - (sym::global_allocator, Normal, template!(Word), Ungated), (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, sym::allocator_internals, "the `#[default_lib_allocator]` \ diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index e8f94bff14470..785636abb121f 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -1,162 +1,95 @@ -use log::debug; -use smallvec::{smallvec, SmallVec}; -use syntax::{ - ast::{ - self, Arg, Attribute, Crate, Expr, FnHeader, Generics, Ident, Item, ItemKind, - Mac, Mod, Mutability, Ty, TyKind, Unsafety, VisibilityKind, - }, - attr, - source_map::{ - respan, ExpnInfo, ExpnKind, - }, - ext::{ - allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}, - base::{ExtCtxt, MacroKind, Resolver}, - build::AstBuilder, - expand::ExpansionConfig, - hygiene::ExpnId, - }, - mut_visit::{self, MutVisitor}, - parse::ParseSess, - ptr::P, - symbol::{kw, sym} -}; +use errors::Applicability; +use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident, Item}; +use syntax::ast::{ItemKind, Mutability, Ty, TyKind, Unsafety, VisibilityKind}; +use syntax::source_map::respan; +use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; +use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::ext::build::AstBuilder; +use syntax::ext::hygiene::SyntaxContext; +use syntax::ptr::P; +use syntax::symbol::{kw, sym}; use syntax_pos::Span; -pub fn modify( - sess: &ParseSess, - resolver: &mut dyn Resolver, - krate: &mut Crate, - crate_name: String, - handler: &errors::Handler, -) { - ExpandAllocatorDirectives { - handler, - sess, - resolver, - found: false, - crate_name: Some(crate_name), - in_submod: -1, // -1 to account for the "root" module - }.visit_crate(krate); -} - -struct ExpandAllocatorDirectives<'a> { - found: bool, - handler: &'a errors::Handler, - sess: &'a ParseSess, - resolver: &'a mut dyn Resolver, - crate_name: Option, - - // For now, we disallow `global_allocator` in submodules because hygiene is hard. Keep track of - // whether we are in a submodule or not. If `in_submod > 0` we are in a submodule. - in_submod: isize, -} - -impl MutVisitor for ExpandAllocatorDirectives<'_> { - fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { - debug!("in submodule {}", self.in_submod); - - if !attr::contains_name(&item.attrs, sym::global_allocator) { - return mut_visit::noop_flat_map_item(item, self); - } - - match item.node { - ItemKind::Static(..) => {} - _ => { - self.handler - .span_err(item.span, "allocators must be statics"); - return smallvec![item]; - } - } - - if self.in_submod > 0 { - self.handler - .span_err(item.span, "`global_allocator` cannot be used in submodules"); - return smallvec![item]; - } +pub fn expand( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + item: Annotatable, +) -> Vec { + if !meta_item.is_word() { + let msg = format!("malformed `{}` attribute input", meta_item.path); + ecx.parse_sess.span_diagnostic.struct_span_err(span, &msg) + .span_suggestion( + span, + "must be of the form", + format!("`#[{}]`", meta_item.path), + Applicability::MachineApplicable + ).emit(); + } - if self.found { - self.handler - .span_err(item.span, "cannot define more than one `#[global_allocator]`"); - return smallvec![item]; + let not_static = |item: Annotatable| { + ecx.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics"); + vec![item] + }; + let item = match item { + Annotatable::Item(item) => match item.node { + ItemKind::Static(..) => item, + _ => return not_static(Annotatable::Item(item)), } - self.found = true; - - // Create a new expansion for the generated allocator code. - let span = item.span.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( - ExpnKind::Macro(MacroKind::Attr, sym::global_allocator), item.span, self.sess.edition, - [sym::rustc_attrs][..].into(), - )); - - // Create an expansion config - let ecfg = ExpansionConfig::default(self.crate_name.take().unwrap()); - - // Generate a bunch of new items using the AllocFnFactory - let mut f = AllocFnFactory { - span, - kind: AllocatorKind::Global, - global: item.ident, - core: Ident::with_empty_ctxt(sym::core), - cx: ExtCtxt::new(self.sess, ecfg, self.resolver), - }; - - // We will generate a new submodule. To `use` the static from that module, we need to get - // the `super::...` path. - let super_path = f.cx.path(f.span, vec![Ident::with_empty_ctxt(kw::Super), f.global]); - - // Generate the items in the submodule - let mut items = vec![ - // import `core` to use allocators - f.cx.item_extern_crate(f.span, f.core), - // `use` the `global_allocator` in `super` - f.cx.item_use_simple( - f.span, - respan(f.span.shrink_to_lo(), VisibilityKind::Inherited), - super_path, - ), - ]; - - // Add the allocator methods to the submodule - items.extend( - ALLOCATOR_METHODS - .iter() - .map(|method| f.allocator_fn(method)), - ); - - // Generate the submodule itself - let name = f.kind.fn_name("allocator_abi"); - let allocator_abi = Ident::from_str(&name).gensym(); - let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items); - let module = f.cx.monotonic_expander().flat_map_item(module).pop().unwrap(); - - // Return the item and new submodule - smallvec![item, module] - } + _ => return not_static(item), + }; + + // Generate a bunch of new items using the AllocFnFactory + let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.mark)); + let f = AllocFnFactory { + span, + kind: AllocatorKind::Global, + global: item.ident, + core: Ident::with_empty_ctxt(sym::core), + cx: ecx, + }; + + // We will generate a new submodule. To `use` the static from that module, we need to get + // the `super::...` path. + let super_path = f.cx.path(f.span, vec![Ident::with_empty_ctxt(kw::Super), f.global]); + + // Generate the items in the submodule + let mut items = vec![ + // import `core` to use allocators + f.cx.item_extern_crate(f.span, f.core), + // `use` the `global_allocator` in `super` + f.cx.item_use_simple( + f.span, + respan(f.span.shrink_to_lo(), VisibilityKind::Inherited), + super_path, + ), + ]; + + // Add the allocator methods to the submodule + items.extend( + ALLOCATOR_METHODS + .iter() + .map(|method| f.allocator_fn(method)), + ); - // If we enter a submodule, take note. - fn visit_mod(&mut self, m: &mut Mod) { - debug!("enter submodule"); - self.in_submod += 1; - mut_visit::noop_visit_mod(m, self); - self.in_submod -= 1; - debug!("exit submodule"); - } + // Generate the submodule itself + let name = f.kind.fn_name("allocator_abi"); + let allocator_abi = Ident::from_str(&name).gensym(); + let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items); - // `visit_mac` is disabled by default. Enable it here. - fn visit_mac(&mut self, mac: &mut Mac) { - mut_visit::noop_visit_mac(mac, self) - } + // Return the item and new submodule + vec![Annotatable::Item(item), Annotatable::Item(module)] } -struct AllocFnFactory<'a> { +struct AllocFnFactory<'a, 'b> { span: Span, kind: AllocatorKind, global: Ident, core: Ident, - cx: ExtCtxt<'a>, + cx: &'b ExtCtxt<'a>, } -impl AllocFnFactory<'_> { +impl AllocFnFactory<'_, '_> { fn allocator_fn(&self, method: &AllocatorMethod) -> P { let mut abi_args = Vec::new(); let mut i = 0; diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index cd7ac5fe2c66c..400bfe796bb07 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -29,6 +29,7 @@ mod concat_idents; mod env; mod format; mod format_foreign; +mod global_allocator; mod global_asm; mod log_syntax; mod proc_macro_server; @@ -37,7 +38,6 @@ mod test_case; mod trace_macros; pub mod deriving; -pub mod global_allocator; pub mod proc_macro_decls; pub mod proc_macro_impl; @@ -152,6 +152,12 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_bench)), edition ) }); + register(sym::global_allocator, SyntaxExtension { + allow_internal_unstable: Some([sym::rustc_attrs][..].into()), + ..SyntaxExtension::default( + SyntaxExtensionKind::LegacyAttr(Box::new(global_allocator::expand)), edition + ) + }); let allow_internal_unstable = Some([sym::fmt_internals][..].into()); register(sym::format_args, SyntaxExtension { diff --git a/src/test/run-pass/allocator/custom-in-block.rs b/src/test/run-pass/allocator/custom-in-block.rs new file mode 100644 index 0000000000000..506154ec601ae --- /dev/null +++ b/src/test/run-pass/allocator/custom-in-block.rs @@ -0,0 +1,21 @@ +// run-pass +// no-prefer-dynamic +// aux-build:custom.rs +// aux-build:helper.rs + +extern crate custom; +extern crate helper; + +use custom::A; +use std::sync::atomic::{AtomicUsize, Ordering}; + +fn main() { + #[global_allocator] + pub static GLOBAL: A = A(AtomicUsize::new(0)); + + let s = Box::new(0); + helper::work_with(&s); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 1); + drop(s); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 2); +} diff --git a/src/test/run-pass/allocator/custom-in-submodule.rs b/src/test/run-pass/allocator/custom-in-submodule.rs new file mode 100644 index 0000000000000..f9c4ad7668b63 --- /dev/null +++ b/src/test/run-pass/allocator/custom-in-submodule.rs @@ -0,0 +1,25 @@ +// run-pass +// no-prefer-dynamic +// aux-build:custom.rs +// aux-build:helper.rs + +extern crate custom; +extern crate helper; + +use custom::A; +use std::sync::atomic::{AtomicUsize, Ordering}; + +mod submodule { + use super::*; + + #[global_allocator] + pub static GLOBAL: A = A(AtomicUsize::new(0)); +} + +fn main() { + let s = Box::new(0); + helper::work_with(&s); + assert_eq!(submodule::GLOBAL.0.load(Ordering::SeqCst), 1); + drop(s); + assert_eq!(submodule::GLOBAL.0.load(Ordering::SeqCst), 2); +} diff --git a/src/test/ui/allocator-submodule.rs b/src/test/ui/allocator-submodule.rs deleted file mode 100644 index 7a8d86b8da18c..0000000000000 --- a/src/test/ui/allocator-submodule.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Tests that it is possible to create a global allocator in a submodule, rather than in the crate -// root. - -extern crate alloc; - -use std::{ - alloc::{GlobalAlloc, Layout}, - ptr, -}; - -struct MyAlloc; - -unsafe impl GlobalAlloc for MyAlloc { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - ptr::null_mut() - } - - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {} -} - -mod submod { - use super::MyAlloc; - - #[global_allocator] - static MY_HEAP: MyAlloc = MyAlloc; //~ ERROR global_allocator -} - -fn main() {} diff --git a/src/test/ui/allocator-submodule.stderr b/src/test/ui/allocator-submodule.stderr deleted file mode 100644 index 91c7c0f6b8e24..0000000000000 --- a/src/test/ui/allocator-submodule.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: `global_allocator` cannot be used in submodules - --> $DIR/allocator-submodule.rs:25:5 - | -LL | static MY_HEAP: MyAlloc = MyAlloc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/allocator/allocator-args.rs b/src/test/ui/allocator/allocator-args.rs new file mode 100644 index 0000000000000..1033f947c5f5b --- /dev/null +++ b/src/test/ui/allocator/allocator-args.rs @@ -0,0 +1,13 @@ +use std::alloc::{GlobalAlloc, Layout}; + +struct A; + +unsafe impl GlobalAlloc for A { + unsafe fn alloc(&self, _: Layout) -> *mut u8 { panic!() } + unsafe fn dealloc(&self, _: *mut u8, _: Layout) { panic!() } +} + +#[global_allocator(malloc)] //~ ERROR malformed `global_allocator` attribute input +static S: A = A; + +fn main() {} diff --git a/src/test/ui/allocator/allocator-args.stderr b/src/test/ui/allocator/allocator-args.stderr new file mode 100644 index 0000000000000..d8ae7130e5d3d --- /dev/null +++ b/src/test/ui/allocator/allocator-args.stderr @@ -0,0 +1,8 @@ +error: malformed `global_allocator` attribute input + --> $DIR/allocator-args.rs:10:1 + | +LL | #[global_allocator(malloc)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: ``#[global_allocator]`` + +error: aborting due to previous error + diff --git a/src/test/ui/allocator/two-allocators.rs b/src/test/ui/allocator/two-allocators.rs index 0f81fc41823ba..aa1291e77aecb 100644 --- a/src/test/ui/allocator/two-allocators.rs +++ b/src/test/ui/allocator/two-allocators.rs @@ -4,6 +4,6 @@ use std::alloc::System; static A: System = System; #[global_allocator] static B: System = System; -//~^ ERROR: cannot define more than one `#[global_allocator]` +//~^ ERROR: cannot define multiple global allocators fn main() {} diff --git a/src/test/ui/allocator/two-allocators.stderr b/src/test/ui/allocator/two-allocators.stderr index 6b0c2b2a25d38..ed0aa13eb8078 100644 --- a/src/test/ui/allocator/two-allocators.stderr +++ b/src/test/ui/allocator/two-allocators.stderr @@ -1,8 +1,14 @@ -error: cannot define more than one `#[global_allocator]` +error: cannot define multiple global allocators --> $DIR/two-allocators.rs:6:1 | LL | static B: System = System; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the previous global allocator is defined here + --> $DIR/two-allocators.rs:4:1 + | +LL | static A: System = System; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 1841beb1fd116..ade61abb7485e 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -344,7 +344,7 @@ fn get_and_check_lib_features(base_src_path: &Path, Ok((name, f)) => { let mut check_features = |f: &Feature, list: &Features, display: &str| { if let Some(ref s) = list.get(name) { - if f.tracking_issue != s.tracking_issue { + if f.tracking_issue != s.tracking_issue && f.level != Status::Stable { tidy_error!(bad, "{}:{}: mismatches the `issue` in {}", file.display(), From 76b1ffaf6c70abd3fa4da2e694dc709116258098 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 19 Jul 2019 02:10:36 +0300 Subject: [PATCH 72/79] syntax_ext: Reuse built-in attribute template checking for macro attributes --- src/librustc_lint/builtin.rs | 4 +- src/libsyntax/attr/builtin.rs | 96 +++++++++++++++++++ src/libsyntax/feature_gate.rs | 90 +---------------- src/libsyntax_ext/global_allocator.rs | 19 +--- src/libsyntax_ext/test.rs | 11 ++- src/libsyntax_ext/test_case.rs | 7 +- src/test/ui/allocator/allocator-args.stderr | 2 +- .../issue-43106-gating-of-bench.stderr | 8 +- .../issue-43106-gating-of-test.stderr | 8 +- 9 files changed, 132 insertions(+), 113 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 4105e030477f1..b63d14ca949ee 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -36,10 +36,10 @@ use syntax::tokenstream::{TokenTree, TokenStream}; use syntax::ast; use syntax::ptr::P; use syntax::ast::Expr; -use syntax::attr::{self, HasAttrs}; +use syntax::attr::{self, HasAttrs, AttributeTemplate}; use syntax::source_map::Spanned; use syntax::edition::Edition; -use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType}; +use syntax::feature_gate::{AttributeGate, AttributeType}; use syntax::feature_gate::{Stability, deprecated_attributes}; use syntax_pos::{BytePos, Span, SyntaxContext}; use syntax::symbol::{Symbol, kw, sym}; diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index b41f1047fcba3..713094416524b 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -1,6 +1,9 @@ //! Parsing and validation of builtin attributes use crate::ast::{self, Attribute, MetaItem, NestedMetaItem}; +use crate::early_buffered_lints::BufferedEarlyLintId; +use crate::ext::base::ExtCtxt; +use crate::ext::build::AstBuilder; use crate::feature_gate::{Features, GatedCfg}; use crate::parse::ParseSess; @@ -19,6 +22,27 @@ enum AttrError { UnsupportedLiteral(&'static str, /* is_bytestr */ bool), } +/// A template that the attribute input must match. +/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now. +#[derive(Clone, Copy)] +pub struct AttributeTemplate { + crate word: bool, + crate list: Option<&'static str>, + crate name_value_str: Option<&'static str>, +} + +impl AttributeTemplate { + /// Checks that the given meta-item is compatible with this template. + fn compatible(&self, meta_item_kind: &ast::MetaItemKind) -> bool { + match meta_item_kind { + ast::MetaItemKind::Word => self.word, + ast::MetaItemKind::List(..) => self.list.is_some(), + ast::MetaItemKind::NameValue(lit) if lit.node.is_str() => self.name_value_str.is_some(), + ast::MetaItemKind::NameValue(..) => false, + } + } +} + fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { let diag = &sess.span_diagnostic; match error { @@ -901,3 +925,75 @@ pub fn find_transparency( let fallback = if is_legacy { Transparency::SemiTransparent } else { Transparency::Opaque }; (transparency.map_or(fallback, |t| t.0), error) } + +pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) { + // All the built-in macro attributes are "words" at the moment. + let template = AttributeTemplate { word: true, list: None, name_value_str: None }; + let attr = ecx.attribute(meta_item.span, meta_item.clone()); + check_builtin_attribute(ecx.parse_sess, &attr, name, template); +} + +crate fn check_builtin_attribute( + sess: &ParseSess, attr: &ast::Attribute, name: Symbol, template: AttributeTemplate +) { + // Some special attributes like `cfg` must be checked + // before the generic check, so we skip them here. + let should_skip = |name| name == sym::cfg; + // Some of previously accepted forms were used in practice, + // report them as warnings for now. + let should_warn = |name| name == sym::doc || name == sym::ignore || + name == sym::inline || name == sym::link; + + match attr.parse_meta(sess) { + Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) { + let error_msg = format!("malformed `{}` attribute input", name); + let mut msg = "attribute must be of the form ".to_owned(); + let mut suggestions = vec![]; + let mut first = true; + if template.word { + first = false; + let code = format!("#[{}]", name); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if let Some(descr) = template.list { + if !first { + msg.push_str(" or "); + } + first = false; + let code = format!("#[{}({})]", name, descr); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if let Some(descr) = template.name_value_str { + if !first { + msg.push_str(" or "); + } + let code = format!("#[{} = \"{}\"]", name, descr); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if should_warn(name) { + sess.buffer_lint( + BufferedEarlyLintId::IllFormedAttributeInput, + meta.span, + ast::CRATE_NODE_ID, + &msg, + ); + } else { + sess.span_diagnostic.struct_span_err(meta.span, &error_msg) + .span_suggestions( + meta.span, + if suggestions.len() == 1 { + "must be of the form" + } else { + "the following are the possible correct uses" + }, + suggestions.into_iter(), + Applicability::HasPlaceholders, + ).emit(); + } + } + Err(mut err) => err.emit(), + } +} diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 214160f10790d..72184b0bd6400 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -19,8 +19,7 @@ use crate::ast::{ self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind, PatKind, RangeEnd, }; -use crate::attr; -use crate::early_buffered_lints::BufferedEarlyLintId; +use crate::attr::{self, check_builtin_attribute, AttributeTemplate}; use crate::source_map::Spanned; use crate::edition::{ALL_EDITIONS, Edition}; use crate::visit::{self, FnKind, Visitor}; @@ -906,27 +905,6 @@ pub enum AttributeGate { Ungated, } -/// A template that the attribute input must match. -/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now. -#[derive(Clone, Copy)] -pub struct AttributeTemplate { - word: bool, - list: Option<&'static str>, - name_value_str: Option<&'static str>, -} - -impl AttributeTemplate { - /// Checks that the given meta-item is compatible with this template. - fn compatible(&self, meta_item_kind: &ast::MetaItemKind) -> bool { - match meta_item_kind { - ast::MetaItemKind::Word => self.word, - ast::MetaItemKind::List(..) => self.list.is_some(), - ast::MetaItemKind::NameValue(lit) if lit.node.is_str() => self.name_value_str.is_some(), - ast::MetaItemKind::NameValue(..) => false, - } - } -} - /// A convenience macro for constructing attribute templates. /// E.g., `template!(Word, List: "description")` means that the attribute /// supports forms `#[attr]` and `#[attr(description)]`. @@ -1901,70 +1879,6 @@ impl<'a> PostExpansionVisitor<'a> { Abi::System => {} } } - - fn check_builtin_attribute(&mut self, attr: &ast::Attribute, name: Symbol, - template: AttributeTemplate) { - // Some special attributes like `cfg` must be checked - // before the generic check, so we skip them here. - let should_skip = |name| name == sym::cfg; - // Some of previously accepted forms were used in practice, - // report them as warnings for now. - let should_warn = |name| name == sym::doc || name == sym::ignore || - name == sym::inline || name == sym::link; - - match attr.parse_meta(self.context.parse_sess) { - Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) { - let error_msg = format!("malformed `{}` attribute input", name); - let mut msg = "attribute must be of the form ".to_owned(); - let mut suggestions = vec![]; - let mut first = true; - if template.word { - first = false; - let code = format!("#[{}]", name); - msg.push_str(&format!("`{}`", &code)); - suggestions.push(code); - } - if let Some(descr) = template.list { - if !first { - msg.push_str(" or "); - } - first = false; - let code = format!("#[{}({})]", name, descr); - msg.push_str(&format!("`{}`", &code)); - suggestions.push(code); - } - if let Some(descr) = template.name_value_str { - if !first { - msg.push_str(" or "); - } - let code = format!("#[{} = \"{}\"]", name, descr); - msg.push_str(&format!("`{}`", &code)); - suggestions.push(code); - } - if should_warn(name) { - self.context.parse_sess.buffer_lint( - BufferedEarlyLintId::IllFormedAttributeInput, - meta.span, - ast::CRATE_NODE_ID, - &msg, - ); - } else { - self.context.parse_sess.span_diagnostic.struct_span_err(meta.span, &error_msg) - .span_suggestions( - meta.span, - if suggestions.len() == 1 { - "must be of the form" - } else { - "the following are the possible correct uses" - }, - suggestions.into_iter(), - Applicability::HasPlaceholders, - ).emit(); - } - } - Err(mut err) => err.emit(), - } - } } impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { @@ -2005,7 +1919,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match attr_info { // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. Some(&(name, _, template, _)) if name != sym::rustc_dummy => - self.check_builtin_attribute(attr, name, template), + check_builtin_attribute(self.context.parse_sess, attr, name, template), _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() { if token == token::Eq { // All key-value attributes are restricted to meta-item syntax. diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index 785636abb121f..196db3d7baa5b 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -1,31 +1,22 @@ -use errors::Applicability; -use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident, Item}; use syntax::ast::{ItemKind, Mutability, Ty, TyKind, Unsafety, VisibilityKind}; -use syntax::source_map::respan; +use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident, Item}; +use syntax::attr::check_builtin_macro_attribute; use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; +use syntax::source_map::respan; use syntax::symbol::{kw, sym}; use syntax_pos::Span; pub fn expand( ecx: &mut ExtCtxt<'_>, - span: Span, + _span: Span, meta_item: &ast::MetaItem, item: Annotatable, ) -> Vec { - if !meta_item.is_word() { - let msg = format!("malformed `{}` attribute input", meta_item.path); - ecx.parse_sess.span_diagnostic.struct_span_err(span, &msg) - .span_suggestion( - span, - "must be of the form", - format!("`#[{}]`", meta_item.path), - Applicability::MachineApplicable - ).emit(); - } + check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator); let not_static = |item: Annotatable| { ecx.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics"); diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index f8755a1d1d791..d381c42f9ce84 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -1,31 +1,34 @@ /// The expansion from a test function to the appropriate test struct for libtest /// Ideally, this code would be in libtest but for efficiency and error messages it lives here. +use syntax::ast; +use syntax::attr::{self, check_builtin_macro_attribute}; use syntax::ext::base::*; use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::SyntaxContext; -use syntax::attr; -use syntax::ast; use syntax::print::pprust; use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; + use std::iter; pub fn expand_test( cx: &mut ExtCtxt<'_>, attr_sp: Span, - _meta_item: &ast::MetaItem, + meta_item: &ast::MetaItem, item: Annotatable, ) -> Vec { + check_builtin_macro_attribute(cx, meta_item, sym::test); expand_test_or_bench(cx, attr_sp, item, false) } pub fn expand_bench( cx: &mut ExtCtxt<'_>, attr_sp: Span, - _meta_item: &ast::MetaItem, + meta_item: &ast::MetaItem, item: Annotatable, ) -> Vec { + check_builtin_macro_attribute(cx, meta_item, sym::bench); expand_test_or_bench(cx, attr_sp, item, true) } diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs index 355f2428e0806..ea4a8d541ab99 100644 --- a/src/libsyntax_ext/test_case.rs +++ b/src/libsyntax_ext/test_case.rs @@ -9,10 +9,11 @@ // We mark item with an inert attribute "rustc_test_marker" which the test generation // logic will pick up on. +use syntax::ast; +use syntax::attr::check_builtin_macro_attribute; use syntax::ext::base::*; use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::SyntaxContext; -use syntax::ast; use syntax::source_map::respan; use syntax::symbol::sym; use syntax_pos::Span; @@ -20,9 +21,11 @@ use syntax_pos::Span; pub fn expand( ecx: &mut ExtCtxt<'_>, attr_sp: Span, - _meta_item: &ast::MetaItem, + meta_item: &ast::MetaItem, anno_item: Annotatable ) -> Vec { + check_builtin_macro_attribute(ecx, meta_item, sym::test_case); + if !ecx.ecfg.should_test { return vec![]; } let sp = attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id)); diff --git a/src/test/ui/allocator/allocator-args.stderr b/src/test/ui/allocator/allocator-args.stderr index d8ae7130e5d3d..dfff2a7e7094d 100644 --- a/src/test/ui/allocator/allocator-args.stderr +++ b/src/test/ui/allocator/allocator-args.stderr @@ -2,7 +2,7 @@ error: malformed `global_allocator` attribute input --> $DIR/allocator-args.rs:10:1 | LL | #[global_allocator(malloc)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: ``#[global_allocator]`` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[global_allocator]` error: aborting due to previous error diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr index 503ef020d9604..e82cb93c6359e 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr @@ -1,7 +1,13 @@ +error: malformed `bench` attribute input + --> $DIR/issue-43106-gating-of-bench.rs:15:1 + | +LL | #![bench = "4100"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[bench]` + error[E0601]: `main` function not found in crate `issue_43106_gating_of_bench` | = note: consider adding a `main` function to `$DIR/issue-43106-gating-of-bench.rs` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr index 2ab35be43c576..9866fa3730ef2 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr @@ -1,7 +1,13 @@ +error: malformed `test` attribute input + --> $DIR/issue-43106-gating-of-test.rs:10:1 + | +LL | #![test = "4200"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[test]` + error[E0601]: `main` function not found in crate `issue_43106_gating_of_test` | = note: consider adding a `main` function to `$DIR/issue-43106-gating-of-test.rs` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0601`. From bf8fc8adfc76f31a8fb6a4cb0dee02f262bd766a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 19 Jul 2019 02:51:07 +0300 Subject: [PATCH 73/79] syntax_ext: Improve and simplify code generated by `#[global_allocator]` Instead of ``` mod allocator_abi { /* methods */ } ``` we now generate ``` const _: () = { /* methods */ } ``` and use `std_path` for paths referring to standard library entities. This way we no longer need to generate `use` and `extern crate` imports, and `#[global_allocator]` starts working inside unnamed blocks. --- src/libsyntax_ext/global_allocator.rs | 85 ++++++------------- .../run-pass/allocator/custom-in-block.rs | 5 +- .../run-pass/allocator/custom-in-submodule.rs | 5 +- 3 files changed, 34 insertions(+), 61 deletions(-) diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index 196db3d7baa5b..71c9e6cd23d44 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -1,13 +1,12 @@ -use syntax::ast::{ItemKind, Mutability, Ty, TyKind, Unsafety, VisibilityKind}; -use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident, Item}; +use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafety}; +use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident}; use syntax::attr::check_builtin_macro_attribute; use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; -use syntax::source_map::respan; -use syntax::symbol::{kw, sym}; +use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; pub fn expand( @@ -36,52 +35,31 @@ pub fn expand( span, kind: AllocatorKind::Global, global: item.ident, - core: Ident::with_empty_ctxt(sym::core), cx: ecx, }; - // We will generate a new submodule. To `use` the static from that module, we need to get - // the `super::...` path. - let super_path = f.cx.path(f.span, vec![Ident::with_empty_ctxt(kw::Super), f.global]); - - // Generate the items in the submodule - let mut items = vec![ - // import `core` to use allocators - f.cx.item_extern_crate(f.span, f.core), - // `use` the `global_allocator` in `super` - f.cx.item_use_simple( - f.span, - respan(f.span.shrink_to_lo(), VisibilityKind::Inherited), - super_path, - ), - ]; - - // Add the allocator methods to the submodule - items.extend( - ALLOCATOR_METHODS - .iter() - .map(|method| f.allocator_fn(method)), - ); + // Generate item statements for the allocator methods. + let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect(); - // Generate the submodule itself - let name = f.kind.fn_name("allocator_abi"); - let allocator_abi = Ident::from_str(&name).gensym(); - let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items); + // Generate anonymous constant serving as container for the allocator methods. + let const_ty = ecx.ty(span, TyKind::Tup(Vec::new())); + let const_body = ecx.expr_block(ecx.block(span, stmts)); + let const_item = + ecx.item_const(span, Ident::with_empty_ctxt(kw::Underscore), const_ty, const_body); - // Return the item and new submodule - vec![Annotatable::Item(item), Annotatable::Item(module)] + // Return the original item and the new methods. + vec![Annotatable::Item(item), Annotatable::Item(const_item)] } struct AllocFnFactory<'a, 'b> { span: Span, kind: AllocatorKind, global: Ident, - core: Ident, cx: &'b ExtCtxt<'a>, } impl AllocFnFactory<'_, '_> { - fn allocator_fn(&self, method: &AllocatorMethod) -> P { + fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt { let mut abi_args = Vec::new(); let mut i = 0; let ref mut mk = || { @@ -105,25 +83,22 @@ impl AllocFnFactory<'_, '_> { Generics::default(), self.cx.block_expr(output_expr), ); - self.cx.item( + let item = self.cx.item( self.span, Ident::from_str(&self.kind.fn_name(method.name)), self.attrs(), kind, - ) + ); + self.cx.stmt_item(self.span, item) } fn call_allocator(&self, method: &str, mut args: Vec>) -> P { - let method = self.cx.path( - self.span, - vec![ - self.core, - Ident::from_str("alloc"), - Ident::from_str("GlobalAlloc"), - Ident::from_str(method), - ], - ); - let method = self.cx.expr_path(method); + let method = self.cx.std_path(&[ + Symbol::intern("alloc"), + Symbol::intern("GlobalAlloc"), + Symbol::intern(method), + ]); + let method = self.cx.expr_path(self.cx.path(self.span, method)); let allocator = self.cx.path_ident(self.span, self.global); let allocator = self.cx.expr_path(allocator); let allocator = self.cx.expr_addr_of(self.span, allocator); @@ -153,16 +128,12 @@ impl AllocFnFactory<'_, '_> { args.push(self.cx.arg(self.span, size, ty_usize.clone())); args.push(self.cx.arg(self.span, align, ty_usize)); - let layout_new = self.cx.path( - self.span, - vec![ - self.core, - Ident::from_str("alloc"), - Ident::from_str("Layout"), - Ident::from_str("from_size_align_unchecked"), - ], - ); - let layout_new = self.cx.expr_path(layout_new); + let layout_new = self.cx.std_path(&[ + Symbol::intern("alloc"), + Symbol::intern("Layout"), + Symbol::intern("from_size_align_unchecked"), + ]); + let layout_new = self.cx.expr_path(self.cx.path(self.span, layout_new)); let size = self.cx.expr_ident(self.span, size); let align = self.cx.expr_ident(self.span, align); let layout = self.cx.expr_call(self.span, layout_new, vec![size, align]); diff --git a/src/test/run-pass/allocator/custom-in-block.rs b/src/test/run-pass/allocator/custom-in-block.rs index 506154ec601ae..12813a1fc8bd4 100644 --- a/src/test/run-pass/allocator/custom-in-block.rs +++ b/src/test/run-pass/allocator/custom-in-block.rs @@ -13,9 +13,10 @@ fn main() { #[global_allocator] pub static GLOBAL: A = A(AtomicUsize::new(0)); + let n = GLOBAL.0.load(Ordering::SeqCst); let s = Box::new(0); helper::work_with(&s); - assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 1); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1); drop(s); - assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 2); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); } diff --git a/src/test/run-pass/allocator/custom-in-submodule.rs b/src/test/run-pass/allocator/custom-in-submodule.rs index f9c4ad7668b63..ea341b1ac14ae 100644 --- a/src/test/run-pass/allocator/custom-in-submodule.rs +++ b/src/test/run-pass/allocator/custom-in-submodule.rs @@ -17,9 +17,10 @@ mod submodule { } fn main() { + let n = submodule::GLOBAL.0.load(Ordering::SeqCst); let s = Box::new(0); helper::work_with(&s); - assert_eq!(submodule::GLOBAL.0.load(Ordering::SeqCst), 1); + assert_eq!(submodule::GLOBAL.0.load(Ordering::SeqCst), n + 1); drop(s); - assert_eq!(submodule::GLOBAL.0.load(Ordering::SeqCst), 2); + assert_eq!(submodule::GLOBAL.0.load(Ordering::SeqCst), n + 2); } From 6e4f16173c331ca3ccae1ffecc5a69f1ad54f30c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 20 Jul 2019 03:14:11 +0300 Subject: [PATCH 74/79] Demote template check error to a lint for `#[test]` and `#[bench]` --- src/libsyntax/attr/builtin.rs | 3 ++- .../ui/feature-gate/issue-43106-gating-of-bench.stderr | 10 +++++++--- .../ui/feature-gate/issue-43106-gating-of-test.stderr | 10 +++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 713094416524b..dbf31ad014832 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -942,7 +942,8 @@ crate fn check_builtin_attribute( // Some of previously accepted forms were used in practice, // report them as warnings for now. let should_warn = |name| name == sym::doc || name == sym::ignore || - name == sym::inline || name == sym::link; + name == sym::inline || name == sym::link || + name == sym::test || name == sym::bench; match attr.parse_meta(sess) { Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) { diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr index e82cb93c6359e..37b5e792dc239 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr @@ -1,13 +1,17 @@ -error: malformed `bench` attribute input +warning: attribute must be of the form `#[bench]` --> $DIR/issue-43106-gating-of-bench.rs:15:1 | LL | #![bench = "4100"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[bench]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(ill_formed_attribute_input)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 error[E0601]: `main` function not found in crate `issue_43106_gating_of_bench` | = note: consider adding a `main` function to `$DIR/issue-43106-gating-of-bench.rs` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr index 9866fa3730ef2..dbffabf3e02f9 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr @@ -1,13 +1,17 @@ -error: malformed `test` attribute input +warning: attribute must be of the form `#[test]` --> $DIR/issue-43106-gating-of-test.rs:10:1 | LL | #![test = "4200"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[test]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(ill_formed_attribute_input)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 error[E0601]: `main` function not found in crate `issue_43106_gating_of_test` | = note: consider adding a `main` function to `$DIR/issue-43106-gating-of-test.rs` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0601`. From a0c2c640d54fa1622c2fea4accae1025bf109c47 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 20 Jul 2019 13:44:11 +0300 Subject: [PATCH 75/79] Fix rebase --- src/libsyntax_ext/global_allocator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index 71c9e6cd23d44..33072487e19f4 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -30,7 +30,7 @@ pub fn expand( }; // Generate a bunch of new items using the AllocFnFactory - let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.mark)); + let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id)); let f = AllocFnFactory { span, kind: AllocatorKind::Global, From eafb42dc94b191fdd9f38b548f624184101182a2 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 10 Jun 2019 10:18:53 -0600 Subject: [PATCH 76/79] Add binary dependencies to dep-info files --- src/librustc_interface/passes.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 6bf56bf851553..469215563ac39 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -9,6 +9,7 @@ use rustc::hir::lowering::lower_crate; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; +use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt}; use rustc::ty::steal::Steal; @@ -657,7 +658,8 @@ fn escape_dep_filename(filename: &FileName) -> String { filename.to_string().replace(" ", "\\ ") } -fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[PathBuf]) { +fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: &[PathBuf]) { + let sess = &compiler.sess; // Write out dependency rules to the dep-info file if requested if !sess.opts.output_types.contains_key(&OutputType::DepInfo) { return; @@ -667,13 +669,28 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa let result = (|| -> io::Result<()> { // Build a list of files used to compile the output and // write Makefile-compatible dependency rules - let files: Vec = sess.source_map() + let mut files: Vec = sess.source_map() .files() .iter() .filter(|fmap| fmap.is_real_file()) .filter(|fmap| !fmap.is_imported()) .map(|fmap| escape_dep_filename(&fmap.name)) .collect(); + + for cnum in compiler.cstore.crates_untracked() { + let metadata = compiler.cstore.crate_data_as_rc_any(cnum); + let metadata = metadata.downcast_ref::().unwrap(); + if let Some((path, _)) = &metadata.source.dylib { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } + if let Some((path, _)) = &metadata.source.rlib { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } + if let Some((path, _)) = &metadata.source.rmeta { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } + } + let mut file = fs::File::create(&deps_filename)?; for path in out_filenames { writeln!(file, "{}: {}\n", path.display(), files.join(" "))?; @@ -750,7 +767,7 @@ pub fn prepare_outputs( } } - write_out_deps(sess, &outputs, &output_paths); + write_out_deps(compiler, &outputs, &output_paths); let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1; From d749b5e2237abdb79494afc9c8d7c8280db9088c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 24 Jul 2019 11:00:09 -0400 Subject: [PATCH 77/79] Gate binary dependency information behind -Zbinary-dep-depinfo --- src/librustc/session/config.rs | 2 ++ src/librustc/session/mod.rs | 3 +++ src/librustc_interface/passes.rs | 24 +++++++++++++----------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 470a08fad23b5..9a8429733d103 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1468,6 +1468,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy, parse_symbol_mangling_version, [TRACKED], "which mangling version to use for symbol names"), + binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], + "include artifacts (sysroot, crate dependencies) used during compilation in dep-info"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 664926a152f14..c88ca132184b2 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -545,6 +545,9 @@ impl Session { pub fn print_llvm_passes(&self) -> bool { self.opts.debugging_opts.print_llvm_passes } + pub fn binary_dep_depinfo(&self) -> bool { + self.opts.debugging_opts.binary_dep_depinfo + } /// Gets the features enabled for the current compilation session. /// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 469215563ac39..772395bca2b37 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -677,17 +677,19 @@ fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: .map(|fmap| escape_dep_filename(&fmap.name)) .collect(); - for cnum in compiler.cstore.crates_untracked() { - let metadata = compiler.cstore.crate_data_as_rc_any(cnum); - let metadata = metadata.downcast_ref::().unwrap(); - if let Some((path, _)) = &metadata.source.dylib { - files.push(escape_dep_filename(&FileName::Real(path.clone()))); - } - if let Some((path, _)) = &metadata.source.rlib { - files.push(escape_dep_filename(&FileName::Real(path.clone()))); - } - if let Some((path, _)) = &metadata.source.rmeta { - files.push(escape_dep_filename(&FileName::Real(path.clone()))); + if sess.binary_dep_depinfo() { + for cnum in compiler.cstore.crates_untracked() { + let metadata = compiler.cstore.crate_data_as_rc_any(cnum); + let metadata = metadata.downcast_ref::().unwrap(); + if let Some((path, _)) = &metadata.source.dylib { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } + if let Some((path, _)) = &metadata.source.rlib { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } + if let Some((path, _)) = &metadata.source.rmeta { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } } } From c0918183a7888ed028e41ca2e2e917a0d377aee8 Mon Sep 17 00:00:00 2001 From: Kevin W Matthews Date: Wed, 24 Jul 2019 08:21:08 -0700 Subject: [PATCH 78/79] Use match ergonomics in Condvar documentation --- src/libstd/sync/condvar.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index ffb9ce1c81a53..aeff57716e86b 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -36,7 +36,7 @@ impl WaitTimeoutResult { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// /// // Let's wait 20 milliseconds before notifying the condvar. /// thread::sleep(Duration::from_millis(20)); @@ -48,7 +48,7 @@ impl WaitTimeoutResult { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// loop { /// // Let's put a timeout on the condvar's wait. @@ -94,7 +94,7 @@ impl WaitTimeoutResult { /// /// // Inside of our lock, spawn a new thread, and then wait for it to start. /// thread::spawn(move|| { -/// let &(ref lock, ref cvar) = &*pair2; +/// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -102,7 +102,7 @@ impl WaitTimeoutResult { /// }); /// /// // Wait for the thread to start up. -/// let &(ref lock, ref cvar) = &*pair; +/// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// while !*started { /// started = cvar.wait(started).unwrap(); @@ -180,7 +180,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -188,7 +188,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { @@ -245,7 +245,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -253,7 +253,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` @@ -301,7 +301,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -309,7 +309,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { @@ -374,7 +374,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -382,7 +382,7 @@ impl Condvar { /// }); /// /// // wait for the thread to start up - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { @@ -449,7 +449,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -457,7 +457,7 @@ impl Condvar { /// }); /// /// // wait for the thread to start up - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let result = cvar.wait_timeout_until( /// lock.lock().unwrap(), /// Duration::from_millis(100), @@ -508,7 +508,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -516,7 +516,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { @@ -548,7 +548,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -556,7 +556,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { From 287db19e9a480decb491d39c3c22357a7a68f102 Mon Sep 17 00:00:00 2001 From: Scott Wolchok Date: Wed, 24 Jul 2019 10:28:14 -0700 Subject: [PATCH 79/79] Add comment --- src/librustc_target/spec/apple_ios_base.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs index d400bc62bfd07..f46ad06ba436a 100644 --- a/src/librustc_target/spec/apple_ios_base.rs +++ b/src/librustc_target/spec/apple_ios_base.rs @@ -29,6 +29,12 @@ impl Arch { } pub fn get_sdk_root(sdk_name: &str) -> Result { + // Following what clang does + // (https://github.com/llvm/llvm-project/blob/ + // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678) + // to allow the SDK path to be set. (For clang, xcrun sets + // SDKROOT; for rustc, the user or build system can set it, or we + // can fall back to checking for xcrun on PATH.) if let Some(sdkroot) = env::var("SDKROOT").ok() { let sdkroot_path = Path::new(&sdkroot); if sdkroot_path.is_absolute() && sdkroot_path != Path::new("/") && sdkroot_path.exists() {