From 9755fe80ee88803f2ecf7e86d7ae6d6fb8e25f55 Mon Sep 17 00:00:00 2001 From: Ali Raheem Date: Wed, 7 Aug 2019 15:59:18 +0100 Subject: [PATCH 01/31] Add fs::read_dir() and ReadDir warning about iterator order + example --- src/libstd/fs.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index f7c32a5c20d3d..2a55c79a93ce4 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -114,6 +114,11 @@ pub struct Metadata(fs_imp::FileAttr); /// information like the entry's path and possibly other metadata can be /// learned. /// +/// #### Note: Iteration Order is Implementation-Defined +/// +/// The order in which this iterator returns entries is platform and filesystem +/// dependent. +/// /// # Errors /// /// This [`io::Result`] will be an [`Err`] if there's some sort of intermittent @@ -1959,6 +1964,11 @@ pub fn remove_dir_all>(path: P) -> io::Result<()> { /// /// [changes]: ../io/index.html#platform-specific-behavior /// +/// #### Note: Iteration Order is Implementation-Defined +/// +/// The order in which this iterator returns entries is platform and filesystem +/// dependent. +/// /// # Errors /// /// This function will return an error in the following situations, but is not @@ -1991,6 +2001,28 @@ pub fn remove_dir_all>(path: P) -> io::Result<()> { /// Ok(()) /// } /// ``` +/// +/// ```rust,no_run +/// use std::{fs, io}; +/// +/// fn main() -> io::Result<()> { +/// // The order read_dir returns entries is not guaranteed. If reproducible +/// // ordering is required the entries should be explicitly sorted. +/// let mut entries = fs::read_dir(".")? +/// .map(|res| res.map(|e| e.path())) +/// .collect::, io::Error>>()?; +/// +/// println!( +/// "Entries before sorting (may or may not be sorted already): {:?}", +/// entries +/// ); +/// +/// entries.sort(); +/// +/// println!("Entries after sorting: {:?}", entries); +/// Ok(()) +/// } +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn read_dir>(path: P) -> io::Result { fs_imp::readdir(path.as_ref()).map(ReadDir) From 8068812d042fa1bfb2133332152ee591705fdef7 Mon Sep 17 00:00:00 2001 From: Ali Raheem Date: Thu, 8 Aug 2019 15:33:39 +0100 Subject: [PATCH 02/31] Remove Iteration order heading --- src/libstd/fs.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 2a55c79a93ce4..ad279d7f754a6 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -114,8 +114,6 @@ pub struct Metadata(fs_imp::FileAttr); /// information like the entry's path and possibly other metadata can be /// learned. /// -/// #### Note: Iteration Order is Implementation-Defined -/// /// The order in which this iterator returns entries is platform and filesystem /// dependent. /// @@ -1964,8 +1962,6 @@ pub fn remove_dir_all>(path: P) -> io::Result<()> { /// /// [changes]: ../io/index.html#platform-specific-behavior /// -/// #### Note: Iteration Order is Implementation-Defined -/// /// The order in which this iterator returns entries is platform and filesystem /// dependent. /// From 53c504650dc6e51c45a256f56c92b872082d0642 Mon Sep 17 00:00:00 2001 From: Ali Raheem Date: Thu, 15 Aug 2019 10:53:29 +0100 Subject: [PATCH 03/31] Fix gramitcal error in read_dir example --- src/libstd/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index ad279d7f754a6..42ce044c5abe5 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -2002,7 +2002,7 @@ pub fn remove_dir_all>(path: P) -> io::Result<()> { /// use std::{fs, io}; /// /// fn main() -> io::Result<()> { -/// // The order read_dir returns entries is not guaranteed. If reproducible +/// // The order in which `read_dir` returns entries is not guaranteed. If reproducible /// // ordering is required the entries should be explicitly sorted. /// let mut entries = fs::read_dir(".")? /// .map(|res| res.map(|e| e.path())) From 3c820fef9fafca1f25da37274aea683b9e341339 Mon Sep 17 00:00:00 2001 From: Ali Raheem Date: Mon, 26 Aug 2019 11:24:08 +0100 Subject: [PATCH 04/31] Comment out println in read_dir sorting example --- src/libstd/fs.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 42ce044c5abe5..689c50c6b80fa 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -2008,14 +2008,14 @@ pub fn remove_dir_all>(path: P) -> io::Result<()> { /// .map(|res| res.map(|e| e.path())) /// .collect::, io::Error>>()?; /// -/// println!( -/// "Entries before sorting (may or may not be sorted already): {:?}", -/// entries -/// ); +/// // println!( +/// // "Entries before sorting (may or may not be sorted already): {:?}", +/// // entries +/// // ); /// /// entries.sort(); /// -/// println!("Entries after sorting: {:?}", entries); +/// // println!("Entries after sorting: {:?}", entries); /// Ok(()) /// } /// ``` From 91fd8efd265b60a635aff89d1c2d0a8aea45fdf9 Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Mon, 9 Sep 2019 08:02:26 +1000 Subject: [PATCH 05/31] document the unstable iter_order_by library feature --- src/doc/unstable-book/src/iter-order-by.md | 9 +++++++++ src/libcore/iter/traits/iterator.rs | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 src/doc/unstable-book/src/iter-order-by.md diff --git a/src/doc/unstable-book/src/iter-order-by.md b/src/doc/unstable-book/src/iter-order-by.md new file mode 100644 index 0000000000000..1ed97872c881c --- /dev/null +++ b/src/doc/unstable-book/src/iter-order-by.md @@ -0,0 +1,9 @@ +# `iter_order_by` + +The tracking issue for this feature is: [#64295] + +[#64295]: https://github.com/rust-lang/rust/issues/64295 + +------------------------ + +Add `cmp_by`, `partial_cmp_by` and `eq_by` methods to `Iterator` in the same vein as `max_by` and `min_by`. diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index c09df3f7f22cb..266f1e6a78102 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -2585,7 +2585,7 @@ pub trait Iterator { /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (x * x).cmp(&y)), Ordering::Equal); /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater); /// ``` - #[unstable(feature = "iter_order_by", issue = "0")] + #[unstable(feature = "iter_order_by", issue = "64295")] fn cmp_by(mut self, other: I, mut cmp: F) -> Ordering where Self: Sized, @@ -2668,7 +2668,7 @@ pub trait Iterator { /// Some(Ordering::Greater) /// ); /// ``` - #[unstable(feature = "iter_order_by", issue = "0")] + #[unstable(feature = "iter_order_by", issue = "64295")] fn partial_cmp_by(mut self, other: I, mut partial_cmp: F) -> Option where Self: Sized, @@ -2733,7 +2733,7 @@ pub trait Iterator { /// /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y)); /// ``` - #[unstable(feature = "iter_order_by", issue = "0")] + #[unstable(feature = "iter_order_by", issue = "64295")] fn eq_by(mut self, other: I, mut eq: F) -> bool where Self: Sized, From 1161aeb2b423da744e687315648a49cc4774220b Mon Sep 17 00:00:00 2001 From: Ali Raheem Date: Mon, 9 Sep 2019 20:38:21 +0100 Subject: [PATCH 06/31] Replace println statements with explanatory comments --- src/libstd/fs.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 689c50c6b80fa..246587b4233cd 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -2002,20 +2002,17 @@ pub fn remove_dir_all>(path: P) -> io::Result<()> { /// use std::{fs, io}; /// /// fn main() -> io::Result<()> { -/// // The order in which `read_dir` returns entries is not guaranteed. If reproducible -/// // ordering is required the entries should be explicitly sorted. /// let mut entries = fs::read_dir(".")? /// .map(|res| res.map(|e| e.path())) /// .collect::, io::Error>>()?; /// -/// // println!( -/// // "Entries before sorting (may or may not be sorted already): {:?}", -/// // entries -/// // ); +/// // The order in which `read_dir` returns entries is not guaranteed. If reproducible +/// // ordering is required the entries should be explicitly sorted. /// /// entries.sort(); /// -/// // println!("Entries after sorting: {:?}", entries); +/// // The entries have now been sorted by their path. +/// /// Ok(()) /// } /// ``` From 612ef5f518198448c43959a6416b9da2964f9167 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Sep 2019 17:04:32 -0400 Subject: [PATCH 07/31] add new tests for re_rebalance_coherence --- ...]-foreign[foreign[t],local]-for-foreign.rs | 14 +++++++++++++ ...pl[t]-foreign[local]-for-fundamental[t].rs | 21 +++++++++++++++++++ .../coherence/impl[t]-foreign[local]-for-t.rs | 16 ++++++++++++++ .../impl[t]-foreign[local]-for-t.stderr | 11 ++++++++++ .../coherence/re-rebalance-coherence-rpass.rs | 14 ------------- 5 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr delete mode 100644 src/test/ui/coherence/re-rebalance-coherence-rpass.rs diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs new file mode 100644 index 0000000000000..61f2637c0c297 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs @@ -0,0 +1,14 @@ +#![feature(re_rebalance_coherence)] + +// run-pass +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +impl Remote2, Local> for usize { } + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs new file mode 100644 index 0000000000000..586b8de9e95c9 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs @@ -0,0 +1,21 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// run-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { + // FIXME(#64412) -- this is expected to error +} + +impl Remote1 for &T { + // FIXME(#64412) -- this is expected to error +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs new file mode 100644 index 0000000000000..6f35c6c9dbc88 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr new file mode 100644 index 0000000000000..be7de8cccb467 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[local]-for-t.rs:12:1 + | +LL | impl Remote1 for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/re-rebalance-coherence-rpass.rs b/src/test/ui/coherence/re-rebalance-coherence-rpass.rs deleted file mode 100644 index bacd3b89fad29..0000000000000 --- a/src/test/ui/coherence/re-rebalance-coherence-rpass.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow(dead_code)] -#![feature(re_rebalance_coherence)] - -// run-pass -// aux-build:re_rebalance_coherence_lib.rs - -extern crate re_rebalance_coherence_lib as lib; -use lib::*; - -struct Oracle; -impl Backend for Oracle {} -impl<'a, T:'a, Tab> QueryFragment for BatchInsert<'a, T, Tab> {} - -fn main() {} From e69d1b67b6603e0635c553eff693a0606d282d75 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 13 Sep 2019 14:57:06 -0400 Subject: [PATCH 08/31] change to check-pass --- .../coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs | 2 +- .../ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs index 61f2637c0c297..54d4bf04a583c 100644 --- a/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs +++ b/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs @@ -1,6 +1,6 @@ #![feature(re_rebalance_coherence)] -// run-pass +// check-pass // compile-flags:--crate-name=test // aux-build:coherence_lib.rs diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs index 586b8de9e95c9..db671cb9bcaba 100644 --- a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs @@ -2,7 +2,7 @@ // compile-flags:--crate-name=test // aux-build:coherence_lib.rs -// run-pass +// check-pass extern crate coherence_lib as lib; use lib::*; From df7789c902eb198a107422dd8e4e4c81ec3cb6ad Mon Sep 17 00:00:00 2001 From: Tomas Tauber <2410580+tomtau@users.noreply.github.com> Date: Sat, 14 Sep 2019 10:06:05 +0800 Subject: [PATCH 09/31] Made a thread local storage panic message more explanatory (TLS is usually understood as Transport Layer Security outside rust-std internals) --- src/libstd/thread/local.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index f85b5d632f16b..a2bbe371de788 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -236,8 +236,8 @@ impl LocalKey { #[stable(feature = "rust1", since = "1.0.0")] pub fn with(&'static self, f: F) -> R where F: FnOnce(&T) -> R { - self.try_with(f).expect("cannot access a TLS value during or \ - after it is destroyed") + self.try_with(f).expect("cannot access a Thread Local Storage value \ + during or after it is destroyed") } /// Acquires a reference to the value in this TLS key. From 68c3739f1268e496c096d89ab9e556f196e35974 Mon Sep 17 00:00:00 2001 From: Tomas Tauber <2410580+tomtau@users.noreply.github.com> Date: Mon, 16 Sep 2019 12:13:02 +0800 Subject: [PATCH 10/31] updated the panic message wording --- src/libstd/thread/local.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index a2bbe371de788..e92c0d1c58e41 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -237,7 +237,7 @@ impl LocalKey { pub fn with(&'static self, f: F) -> R where F: FnOnce(&T) -> R { self.try_with(f).expect("cannot access a Thread Local Storage value \ - during or after it is destroyed") + during or after destruction") } /// Acquires a reference to the value in this TLS key. From 3f004a1bc44859857f05a9f692a578124b3f3e01 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Tue, 17 Sep 2019 14:40:36 +0200 Subject: [PATCH 11/31] Fix re-rebalance coherence implementation for fundamental types Fixes #64412 --- src/librustc/traits/coherence.rs | 10 +++++++++- ...pl[t]-foreign[local]-for-fundamental[t].rs | 5 ++--- ...]-foreign[local]-for-fundamental[t].stderr | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index b6f0addd77107..bc6bcb1f76f96 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -378,7 +378,15 @@ fn orphan_check_trait_ref<'tcx>( // Let Ti be the first such type. // - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti) // - for input_ty in trait_ref.input_types() { + fn uncover_fundamental_ty(ty: Ty<'_>) -> Vec> { + if fundamental_ty(ty) { + ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(ty)).collect() + } else { + vec![ty] + } + } + + for input_ty in trait_ref.input_types().flat_map(uncover_fundamental_ty) { debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty); if ty_is_local(tcx, input_ty, in_crate) { debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty); diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs index db671cb9bcaba..54425b6d708aa 100644 --- a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs @@ -2,7 +2,6 @@ // compile-flags:--crate-name=test // aux-build:coherence_lib.rs -// check-pass extern crate coherence_lib as lib; use lib::*; @@ -11,11 +10,11 @@ use std::rc::Rc; struct Local; impl Remote1 for Box { - // FIXME(#64412) -- this is expected to error + //~^ ERROR type parameter `T` must be used as the type parameter for some local type } impl Remote1 for &T { - // FIXME(#64412) -- this is expected to error + //~^ ERROR type parameter `T` must be used as the type parameter for some local type } fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr new file mode 100644 index 0000000000000..7859665a7bb58 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:12:1 + | +LL | impl Remote1 for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:16:1 + | +LL | impl Remote1 for &T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. From a9c38d9d01bd50b5a264cd62fd32cec37f006ab9 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Wed, 18 Sep 2019 22:14:33 +0200 Subject: [PATCH 12/31] Add more tests --- .../impl-foreign[foreign]-for-foreign.rs | 16 +++++++++++++++ .../impl-foreign[foreign]-for-foreign.stderr | 12 +++++++++++ .../impl-foreign[foreign]-for-local.rs | 16 +++++++++++++++ ...[t]-foreign[foreign]-for-fundamental[t].rs | 20 +++++++++++++++++++ ...foreign[foreign]-for-fundamental[t].stderr | 19 ++++++++++++++++++ .../impl[t]-foreign[foreign]-for-t.rs | 16 +++++++++++++++ .../impl[t]-foreign[foreign]-for-t.stderr | 11 ++++++++++ ...reign[fundamental[t],local]-for-foreign.rs | 20 +++++++++++++++++++ ...n[fundamental[t],local]-for-foreign.stderr | 19 ++++++++++++++++++ ...[t]-foreign[fundamental[t]]-for-foreign.rs | 20 +++++++++++++++++++ ...foreign[fundamental[t]]-for-foreign.stderr | 19 ++++++++++++++++++ ...eign[fundamental[t]]-for-fundamental[t].rs | 19 ++++++++++++++++++ ...[fundamental[t]]-for-fundamental[t].stderr | 19 ++++++++++++++++++ ...pl[t]-foreign[fundamental[t]]-for-local.rs | 17 ++++++++++++++++ .../impl[t]-foreign[fundamental[t]]-for-t.rs | 19 ++++++++++++++++++ ...pl[t]-foreign[fundamental[t]]-for-t.stderr | 19 ++++++++++++++++++ ...eign[local, fundamental[t]]-for-foreign.rs | 19 ++++++++++++++++++ .../impl[t]-foreign[local]-for-foreign.rs | 16 +++++++++++++++ .../impl[t]-foreign[local]-for-local.rs | 15 ++++++++++++++ .../impl[t]-foreign[t]-for-foreign.rs | 16 +++++++++++++++ .../impl[t]-foreign[t]-for-foreign.stderr | 11 ++++++++++ .../impl[t]-foreign[t]-for-fundamental.rs | 20 +++++++++++++++++++ .../impl[t]-foreign[t]-for-fundamental.stderr | 19 ++++++++++++++++++ .../coherence/impl[t]-foreign[t]-for-local.rs | 15 ++++++++++++++ .../ui/coherence/impl[t]-foreign[t]-for-t.rs | 16 +++++++++++++++ .../coherence/impl[t]-foreign[t]-for-t.stderr | 11 ++++++++++ 26 files changed, 439 insertions(+) create mode 100644 src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl-foreign[foreign]-for-local.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs new file mode 100644 index 0000000000000..57738c64e3779 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for f64 { + //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr new file mode 100644 index 0000000000000..04e96f29230fb --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr @@ -0,0 +1,12 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign[foreign]-for-foreign.rs:12:1 + | +LL | impl Remote1 for f64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs new file mode 100644 index 0000000000000..33e85c164763e --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local { +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs new file mode 100644 index 0000000000000..66a4d9d273469 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs @@ -0,0 +1,20 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, T> Remote1 for &'a T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr new file mode 100644 index 0000000000000..2467097b1a8b3 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:12:1 + | +LL | impl Remote1 for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:16:1 + | +LL | impl<'a, T> Remote1 for &'a T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs new file mode 100644 index 0000000000000..0a67ebcbba44c --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr new file mode 100644 index 0000000000000..5c28406f113fc --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[foreign]-for-t.rs:12:1 + | +LL | impl Remote1 for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.rs new file mode 100644 index 0000000000000..24e0f309c4555 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.rs @@ -0,0 +1,20 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote2, Local> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, T> Remote2<&'a T, Local> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.stderr new file mode 100644 index 0000000000000..da670bcfc3fc9 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t],local]-for-foreign.rs:12:1 + | +LL | impl Remote2, Local> for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t],local]-for-foreign.rs:16:1 + | +LL | impl<'a, T> Remote2<&'a T, Local> for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs new file mode 100644 index 0000000000000..71598dae96ab3 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs @@ -0,0 +1,20 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, T> Remote1<&'a T> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr new file mode 100644 index 0000000000000..dd9702650795e --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:12:1 + | +LL | impl Remote1> for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:16:1 + | +LL | impl<'a, T> Remote1<&'a T> for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs new file mode 100644 index 0000000000000..7bf0306f29ba4 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs @@ -0,0 +1,19 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<'a, T> Remote1> for &'a T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} +impl<'a, T> Remote1<&'a T> for Box { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr new file mode 100644 index 0000000000000..eec57fccea762 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:12:1 + | +LL | impl<'a, T> Remote1> for &'a T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:15:1 + | +LL | impl<'a, T> Remote1<&'a T> for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs new file mode 100644 index 0000000000000..54d577c749248 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs @@ -0,0 +1,17 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for Local {} + +impl<'a, T> Remote1<&'a T> for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs new file mode 100644 index 0000000000000..7af929006ef7f --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs @@ -0,0 +1,19 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} +impl<'a, T> Remote1<&'a T> for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr new file mode 100644 index 0000000000000..e017c3ffe6c05 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:12:1 + | +LL | impl Remote1> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:15:1 + | +LL | impl<'a, T> Remote1<&'a T> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs new file mode 100644 index 0000000000000..be0875d0110fd --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs @@ -0,0 +1,19 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local2(Rc); + +impl Remote2> for u32 {} +impl<'a, T> Remote2 for u32 {} +impl Remote2, Box> for u32 {} +impl<'a, T> Remote2, &'a T> for u32 {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs new file mode 100644 index 0000000000000..81cf3c3f6eca9 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Rc {} +impl Remote1 for Vec> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs new file mode 100644 index 0000000000000..6b1d93cd94442 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs @@ -0,0 +1,15 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs new file mode 100644 index 0000000000000..5e89c2077330a --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr new file mode 100644 index 0000000000000..5544729b5d640 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[t]-for-foreign.rs:12:1 + | +LL | impl Remote1 for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs new file mode 100644 index 0000000000000..300a2c4d48a9c --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs @@ -0,0 +1,20 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, A, B> Remote1 for &'a B { + //~^ ERROR type parameter `B` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr new file mode 100644 index 0000000000000..be8cc29a6e5b0 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:12:1 + | +LL | impl Remote1 for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `B` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:16:1 + | +LL | impl<'a, A, B> Remote1 for &'a B { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `B` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs new file mode 100644 index 0000000000000..769147ea7eabd --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs @@ -0,0 +1,15 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs new file mode 100644 index 0000000000000..c8513380ff73e --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr new file mode 100644 index 0000000000000..de857afd20b15 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[t]-for-t.rs:12:1 + | +LL | impl Remote1 for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. From 31b301219f534090690674e43e05c3cbfd2d5005 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Wed, 18 Sep 2019 22:36:04 +0200 Subject: [PATCH 13/31] Split line to fix tidy --- src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs index 57738c64e3779..b08fedc5e11c2 100644 --- a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs @@ -10,7 +10,8 @@ use std::rc::Rc; struct Local; impl Remote1 for f64 { - //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types [E0117] + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] } fn main() {} From 983e035b11d90787fe27c5c31203b4e03ea0266a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 13 Sep 2019 15:14:28 +0200 Subject: [PATCH 14/31] add long error explanation for E0524 --- src/librustc_mir/error_codes.rs | 64 ++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs index ba299e9463b8d..196bcf147f8f8 100644 --- a/src/librustc_mir/error_codes.rs +++ b/src/librustc_mir/error_codes.rs @@ -1993,6 +1993,69 @@ fn get_owned_iterator() -> IntoIter { ``` "##, +E0524: r##" +A variable which requires unique access is being used in more than one closure +at the same time. + +Erroneous code example: + +```compile_fail,E0524 +fn set(x: &mut isize) { + *x += 4; +} + +fn dragoooon(x: &mut isize) { + let mut c1 = || set(x); + let mut c2 = || set(x); // error! + + c2(); + c1(); +} +``` + +To solve this issue, multiple solutions are available. First, is it required +for this variable to be used in more than one closure at a time? If it is the +case, use reference counted types such as `Rc` (or `Arc` if it runs +concurrently): + +``` +use std::rc::Rc; +use std::cell::RefCell; + +fn set(x: &mut isize) { + *x += 4; +} + +fn dragoooon(x: &mut isize) { + let x = Rc::new(RefCell::new(x)); + let y = Rc::clone(&x); + let mut c1 = || { let mut x2 = x.borrow_mut(); set(&mut x2); }; + let mut c2 = || { let mut x2 = y.borrow_mut(); set(&mut x2); }; // ok! + + c2(); + c1(); +} +``` + +If not, just run closures one at a time: + +``` +fn set(x: &mut isize) { + *x += 4; +} + +fn dragoooon(x: &mut isize) { + { // This block isn't necessary since non-lexical lifetimes, it's just to + // make it more clear. + let mut c1 = || set(&mut *x); + c1(); + } // `c1` has been dropped here so we're free to use `x` again! + let mut c2 = || set(&mut *x); + c2(); +} +``` +"##, + E0595: r##" #### Note: this error code is no longer emitted by the compiler. @@ -2393,7 +2456,6 @@ There are some known bugs that trigger this message. // E0385, // {} in an aliasable location E0493, // destructors cannot be evaluated at compile-time E0521, // borrowed data escapes outside of closure - E0524, // two closures require unique access to `..` at the same time E0526, // shuffle indices are not constant E0594, // cannot assign to {} // E0598, // lifetime of {} is too short to guarantee its contents can be... From d2b873b06706e97dc54317b8c0ad8f9efa1c3b70 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 13 Sep 2019 15:14:53 +0200 Subject: [PATCH 15/31] update ui tests --- src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs | 4 ---- src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr | 9 +++++---- src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr | 1 + src/test/ui/borrowck/borrowck-closures-unique.stderr | 3 ++- src/test/ui/nll/closures-in-loops.stderr | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs index 24e06e3c4e666..d7e187a2b3958 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs +++ b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs @@ -1,10 +1,6 @@ // Tests that two closures cannot simultaneously have mutable // and immutable access to the variable. Issue #6801. -fn get(x: &isize) -> isize { - *x -} - fn set(x: &mut isize) { *x = 4; } diff --git a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr index 3be7d725eda3a..784b903a5896a 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr +++ b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr @@ -1,17 +1,17 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference - --> $DIR/borrowck-closures-mut-of-imm.rs:13:25 + --> $DIR/borrowck-closures-mut-of-imm.rs:9:25 | LL | let mut c1 = || set(&mut *x); | ^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference - --> $DIR/borrowck-closures-mut-of-imm.rs:15:25 + --> $DIR/borrowck-closures-mut-of-imm.rs:11:25 | LL | let mut c2 = || set(&mut *x); | ^^^^^^^ cannot borrow as mutable error[E0524]: two closures require unique access to `x` at the same time - --> $DIR/borrowck-closures-mut-of-imm.rs:15:18 + --> $DIR/borrowck-closures-mut-of-imm.rs:11:18 | LL | let mut c1 = || set(&mut *x); | -- - first borrow occurs due to use of `x` in closure @@ -28,4 +28,5 @@ LL | c2(); c1(); error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0596`. +Some errors have detailed explanations: E0524, E0596. +For more information about an error, try `rustc --explain E0524`. diff --git a/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr b/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr index a174388712158..471173e595f47 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr @@ -15,3 +15,4 @@ LL | c2(); c1(); error: aborting due to previous error +For more information about this error, try `rustc --explain E0524`. diff --git a/src/test/ui/borrowck/borrowck-closures-unique.stderr b/src/test/ui/borrowck/borrowck-closures-unique.stderr index 9b53af4c01f59..2ed08b83c58b9 100644 --- a/src/test/ui/borrowck/borrowck-closures-unique.stderr +++ b/src/test/ui/borrowck/borrowck-closures-unique.stderr @@ -50,4 +50,5 @@ LL | let c1 = |y: &'static mut isize| x = y; error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0500`. +Some errors have detailed explanations: E0500, E0524. +For more information about an error, try `rustc --explain E0500`. diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr index 7603f9650b54a..0b15d9bcfe68c 100644 --- a/src/test/ui/nll/closures-in-loops.stderr +++ b/src/test/ui/nll/closures-in-loops.stderr @@ -27,5 +27,5 @@ LL | v.push(|| *x = String::new()); error: aborting due to 3 previous errors -Some errors have detailed explanations: E0382, E0499. +Some errors have detailed explanations: E0382, E0499, E0524. For more information about an error, try `rustc --explain E0382`. From 3ee292021d00857586af0d2ef1fa6c31f74181ce Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Sun, 22 Sep 2019 12:59:10 +0200 Subject: [PATCH 16/31] Fix some unused variable warnings --- src/test/ui/coherence/auxiliary/coherence_lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/coherence/auxiliary/coherence_lib.rs b/src/test/ui/coherence/auxiliary/coherence_lib.rs index 9a5ec82430639..c22819831ab24 100644 --- a/src/test/ui/coherence/auxiliary/coherence_lib.rs +++ b/src/test/ui/coherence/auxiliary/coherence_lib.rs @@ -5,11 +5,11 @@ pub trait Remote { } pub trait Remote1 { - fn foo(&self, t: T) { } + fn foo(&self, _t: T) { } } pub trait Remote2 { - fn foo(&self, t: T, u: U) { } + fn foo(&self, _t: T, _u: U) { } } pub struct Pair(T,U); From 645cdca9ba2fd3e47dedeecbb580d490fa9ef85b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Sep 2019 17:42:17 +0300 Subject: [PATCH 17/31] reduce visibility of a bunch of stuff in ext::tt --- src/librustc_resolve/macros.rs | 4 +- src/libsyntax/ext/tt/macro_check.rs | 2 +- src/libsyntax/ext/tt/macro_parser.rs | 16 ++++---- src/libsyntax/ext/tt/macro_rules.rs | 14 ++++--- src/libsyntax/ext/tt/quoted.rs | 57 +++++++++++----------------- src/libsyntax/lib.rs | 13 ++++--- src/libsyntax/tokenstream.rs | 2 +- 7 files changed, 50 insertions(+), 58 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 3900a3dbb3872..73ad0670659b5 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -18,7 +18,7 @@ use syntax::ext::base::{self, InvocationRes, Indeterminate, SpecialDerives}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind}; -use syntax::ext::tt::macro_rules; +use syntax::ext::compile_declarative_macro; use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name}; use syntax::feature_gate::GateIssue; use syntax::symbol::{Symbol, kw, sym}; @@ -843,7 +843,7 @@ impl<'a> Resolver<'a> { /// Compile the macro into a `SyntaxExtension` and possibly replace it with a pre-defined /// extension partially or entirely for built-in macros and legacy plugin macros. crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> SyntaxExtension { - let mut result = macro_rules::compile( + let mut result = compile_declarative_macro( &self.session.parse_sess, self.session.features_untracked(), item, edition ); diff --git a/src/libsyntax/ext/tt/macro_check.rs b/src/libsyntax/ext/tt/macro_check.rs index 5af97199902e6..a1734689595f0 100644 --- a/src/libsyntax/ext/tt/macro_check.rs +++ b/src/libsyntax/ext/tt/macro_check.rs @@ -196,7 +196,7 @@ struct MacroState<'a> { /// - `node_id` is used to emit lints /// - `span` is used when no spans are available /// - `lhses` and `rhses` should have the same length and represent the macro definition -pub fn check_meta_variables( +crate fn check_meta_variables( sess: &ParseSess, node_id: NodeId, span: Span, diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index dbf14daa30e75..a34a0344f2740 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -70,8 +70,8 @@ //! eof: [a $( a )* a b ยท] //! ``` -pub use NamedMatch::*; -pub use ParseResult::*; +crate use NamedMatch::*; +crate use ParseResult::*; use TokenTreeOrTokenTreeSlice::*; use crate::ast::{Ident, Name}; @@ -267,7 +267,7 @@ impl<'root, 'tt> DerefMut for MatcherPosHandle<'root, 'tt> { } /// Represents the possible results of an attempted parse. -pub enum ParseResult { +crate enum ParseResult { /// Parsed successfully. Success(T), /// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected @@ -279,10 +279,10 @@ pub enum ParseResult { /// A `ParseResult` where the `Success` variant contains a mapping of `Ident`s to `NamedMatch`es. /// This represents the mapping of metavars to the token trees they bind to. -pub type NamedParseResult = ParseResult>; +crate type NamedParseResult = ParseResult>; /// Count how many metavars are named in the given matcher `ms`. -pub fn count_names(ms: &[TokenTree]) -> usize { +crate fn count_names(ms: &[TokenTree]) -> usize { ms.iter().fold(0, |count, elt| { count + match *elt { TokenTree::Sequence(_, ref seq) => seq.num_captures, @@ -352,7 +352,7 @@ fn initial_matcher_pos<'root, 'tt>(ms: &'tt [TokenTree], open: Span) -> MatcherP /// only on the nesting depth of `ast::TTSeq`s in the originating /// token tree it was derived from. #[derive(Debug, Clone)] -pub enum NamedMatch { +crate enum NamedMatch { MatchedSeq(Lrc, DelimSpan), MatchedNonterminal(Lrc), } @@ -415,7 +415,7 @@ fn nameize>( /// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For /// other tokens, this is "unexpected token...". -pub fn parse_failure_msg(tok: &Token) -> String { +crate fn parse_failure_msg(tok: &Token) -> String { match tok.kind { token::Eof => "unexpected end of macro invocation".to_string(), _ => format!( @@ -648,7 +648,7 @@ fn inner_parse_loop<'root, 'tt>( /// - `directory`: Information about the file locations (needed for the black-box parser) /// - `recurse_into_modules`: Whether or not to recurse into modules (needed for the black-box /// parser) -pub fn parse( +crate fn parse( sess: &ParseSess, tts: TokenStream, ms: &[TokenTree], diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index b27e9c543377a..90dfa6e7ac8a4 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -35,7 +35,7 @@ const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \ `literal`, `path`, `meta`, `tt`, `item` and `vis`"; -pub struct ParserAnyMacro<'a> { +crate struct ParserAnyMacro<'a> { parser: Parser<'a>, /// Span of the expansion site of the macro this parser is for @@ -45,7 +45,11 @@ pub struct ParserAnyMacro<'a> { arm_span: Span, } -pub fn annotate_err_with_kind(err: &mut DiagnosticBuilder<'_>, kind: AstFragmentKind, span: Span) { +crate fn annotate_err_with_kind( + err: &mut DiagnosticBuilder<'_>, + kind: AstFragmentKind, + span: Span, +) { match kind { AstFragmentKind::Ty => { err.span_label(span, "this macro call doesn't expand to a type"); @@ -58,7 +62,7 @@ pub fn annotate_err_with_kind(err: &mut DiagnosticBuilder<'_>, kind: AstFragment } impl<'a> ParserAnyMacro<'a> { - pub fn make(mut self: Box>, kind: AstFragmentKind) -> AstFragment { + crate fn make(mut self: Box>, kind: AstFragmentKind) -> AstFragment { let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self; let fragment = panictry!(parser.parse_ast_fragment(kind, true).map_err(|mut e| { if parser.token == token::Eof && e.message().ends_with(", found ``") { @@ -284,8 +288,8 @@ fn generic_extension<'cx>( // // Holy self-referential! -/// Converts a `macro_rules!` invocation into a syntax extension. -pub fn compile( +/// Converts a macro item into a syntax extension. +pub fn compile_declarative_macro( sess: &ParseSess, features: &Features, def: &ast::Item, diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index cad94a0e4c120..d161e6638bf75 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -16,14 +16,14 @@ use std::iter::Peekable; /// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note /// that the delimiter itself might be `NoDelim`. #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] -pub struct Delimited { - pub delim: token::DelimToken, - pub tts: Vec, +crate struct Delimited { + crate delim: token::DelimToken, + crate tts: Vec, } impl Delimited { /// Returns a `self::TokenTree` with a `Span` corresponding to the opening delimiter. - pub fn open_tt(&self, span: Span) -> TokenTree { + crate fn open_tt(&self, span: Span) -> TokenTree { let open_span = if span.is_dummy() { span } else { @@ -33,7 +33,7 @@ impl Delimited { } /// Returns a `self::TokenTree` with a `Span` corresponding to the closing delimiter. - pub fn close_tt(&self, span: Span) -> TokenTree { + crate fn close_tt(&self, span: Span) -> TokenTree { let close_span = if span.is_dummy() { span } else { @@ -44,25 +44,25 @@ impl Delimited { } #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] -pub struct SequenceRepetition { +crate struct SequenceRepetition { /// The sequence of token trees - pub tts: Vec, + crate tts: Vec, /// The optional separator - pub separator: Option, + crate separator: Option, /// Whether the sequence can be repeated zero (*), or one or more times (+) - pub kleene: KleeneToken, + crate kleene: KleeneToken, /// The number of `Match`s that appear in the sequence (and subsequences) - pub num_captures: usize, + crate num_captures: usize, } #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] -pub struct KleeneToken { - pub span: Span, - pub op: KleeneOp, +crate struct KleeneToken { + crate span: Span, + crate op: KleeneOp, } impl KleeneToken { - pub fn new(op: KleeneOp, span: Span) -> KleeneToken { + crate fn new(op: KleeneOp, span: Span) -> KleeneToken { KleeneToken { span, op } } } @@ -70,7 +70,7 @@ impl KleeneToken { /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star) /// for token sequences. #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum KleeneOp { +crate enum KleeneOp { /// Kleene star (`*`) for zero or more repetitions ZeroOrMore, /// Kleene plus (`+`) for one or more repetitions @@ -82,7 +82,7 @@ pub enum KleeneOp { /// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)` /// are "first-class" token trees. Useful for parsing macros. #[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)] -pub enum TokenTree { +crate enum TokenTree { Token(Token), Delimited(DelimSpan, Lrc), /// A kleene-style repetition sequence @@ -99,7 +99,7 @@ pub enum TokenTree { impl TokenTree { /// Return the number of tokens in the tree. - pub fn len(&self) -> usize { + crate fn len(&self) -> usize { match *self { TokenTree::Delimited(_, ref delimed) => match delimed.delim { token::NoDelim => delimed.tts.len(), @@ -110,21 +110,8 @@ impl TokenTree { } } - /// Returns `true` if the given token tree contains no other tokens. This is vacuously true for - /// single tokens or metavar/decls, but may be false for delimited trees or sequences. - pub fn is_empty(&self) -> bool { - match *self { - TokenTree::Delimited(_, ref delimed) => match delimed.delim { - token::NoDelim => delimed.tts.is_empty(), - _ => false, - }, - TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(), - _ => true, - } - } - /// Returns `true` if the given token tree is delimited. - pub fn is_delimited(&self) -> bool { + crate fn is_delimited(&self) -> bool { match *self { TokenTree::Delimited(..) => true, _ => false, @@ -132,7 +119,7 @@ impl TokenTree { } /// Returns `true` if the given token tree is a token of the given kind. - pub fn is_token(&self, expected_kind: &TokenKind) -> bool { + crate fn is_token(&self, expected_kind: &TokenKind) -> bool { match self { TokenTree::Token(Token { kind: actual_kind, .. }) => actual_kind == expected_kind, _ => false, @@ -140,7 +127,7 @@ impl TokenTree { } /// Gets the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences. - pub fn get_tt(&self, index: usize) -> TokenTree { + crate fn get_tt(&self, index: usize) -> TokenTree { match (self, index) { (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => { delimed.tts[index].clone() @@ -160,7 +147,7 @@ impl TokenTree { } /// Retrieves the `TokenTree`'s span. - pub fn span(&self) -> Span { + crate fn span(&self) -> Span { match *self { TokenTree::Token(Token { span, .. }) | TokenTree::MetaVar(span, _) @@ -195,7 +182,7 @@ impl TokenTree { /// # Returns /// /// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`. -pub fn parse( +crate fn parse( input: tokenstream::TokenStream, expect_matchers: bool, sess: &ParseSess, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index aaf6f3e537eb6..c06f43021021a 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -162,18 +162,19 @@ pub mod ext { mod proc_macro_server; pub use syntax_pos::hygiene; + pub use tt::macro_rules::compile_declarative_macro; pub mod allocator; pub mod base; pub mod build; pub mod expand; pub mod proc_macro; - pub mod tt { - pub mod transcribe; - pub mod macro_check; - pub mod macro_parser; - pub mod macro_rules; - pub mod quoted; + crate mod tt { + crate mod transcribe; + crate mod macro_check; + crate mod macro_parser; + crate mod macro_rules; + crate mod quoted; } } diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index d702038f54ec3..15fc4b02041b7 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -64,7 +64,7 @@ where impl TokenTree { /// Use this token tree as a matcher to parse given tts. - pub fn parse(cx: &base::ExtCtxt<'_>, mtch: &[quoted::TokenTree], tts: TokenStream) + crate fn parse(cx: &base::ExtCtxt<'_>, mtch: &[quoted::TokenTree], tts: TokenStream) -> macro_parser::NamedParseResult { // `None` is because we're not interpolating let directory = Directory { From 827a5b2ea8dc66bfdf817f52011f470f00bc6fee Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Sep 2019 18:19:51 +0300 Subject: [PATCH 18/31] rename libsyntax::ext::tt to mbe mbe stands for macro-by-example --- src/libsyntax/ext/{tt => mbe}/macro_check.rs | 0 src/libsyntax/ext/{tt => mbe}/macro_parser.rs | 0 src/libsyntax/ext/{tt => mbe}/macro_rules.rs | 0 src/libsyntax/ext/{tt => mbe}/quoted.rs | 0 src/libsyntax/ext/{tt => mbe}/transcribe.rs | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename src/libsyntax/ext/{tt => mbe}/macro_check.rs (100%) rename src/libsyntax/ext/{tt => mbe}/macro_parser.rs (100%) rename src/libsyntax/ext/{tt => mbe}/macro_rules.rs (100%) rename src/libsyntax/ext/{tt => mbe}/quoted.rs (100%) rename src/libsyntax/ext/{tt => mbe}/transcribe.rs (100%) diff --git a/src/libsyntax/ext/tt/macro_check.rs b/src/libsyntax/ext/mbe/macro_check.rs similarity index 100% rename from src/libsyntax/ext/tt/macro_check.rs rename to src/libsyntax/ext/mbe/macro_check.rs diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/mbe/macro_parser.rs similarity index 100% rename from src/libsyntax/ext/tt/macro_parser.rs rename to src/libsyntax/ext/mbe/macro_parser.rs diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/mbe/macro_rules.rs similarity index 100% rename from src/libsyntax/ext/tt/macro_rules.rs rename to src/libsyntax/ext/mbe/macro_rules.rs diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/mbe/quoted.rs similarity index 100% rename from src/libsyntax/ext/tt/quoted.rs rename to src/libsyntax/ext/mbe/quoted.rs diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/mbe/transcribe.rs similarity index 100% rename from src/libsyntax/ext/tt/transcribe.rs rename to src/libsyntax/ext/mbe/transcribe.rs From 49f849cdb7910162f15ac6ac26a98ba22009dc9a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Sep 2019 18:25:29 +0300 Subject: [PATCH 19/31] rename tt -> mbe, part 2 --- src/libsyntax/ext/expand.rs | 6 +++--- src/libsyntax/ext/mbe/macro_check.rs | 2 +- src/libsyntax/ext/mbe/macro_parser.rs | 2 +- src/libsyntax/ext/mbe/macro_rules.rs | 12 ++++++------ src/libsyntax/ext/mbe/quoted.rs | 2 +- src/libsyntax/ext/mbe/transcribe.rs | 4 ++-- src/libsyntax/lib.rs | 4 ++-- src/libsyntax/tokenstream.rs | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b80c530731dfc..2cd802f22d306 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -6,7 +6,7 @@ use crate::config::StripUnconfigured; use crate::ext::base::*; use crate::ext::proc_macro::{collect_derives, MarkAttrs}; use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind}; -use crate::ext::tt::macro_rules::annotate_err_with_kind; +use crate::ext::mbe::macro_rules::annotate_err_with_kind; use crate::ext::placeholders::{placeholder, PlaceholderExpander}; use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; use crate::mut_visit::*; @@ -115,8 +115,8 @@ macro_rules! ast_fragments { } } - impl<'a> MacResult for crate::ext::tt::macro_rules::ParserAnyMacro<'a> { - $(fn $make_ast(self: Box>) + impl<'a> MacResult for crate::ext::mbe::macro_rules::ParserAnyMacro<'a> { + $(fn $make_ast(self: Box>) -> Option<$AstTy> { Some(self.make(AstFragmentKind::$Kind).$make_ast()) })* diff --git a/src/libsyntax/ext/mbe/macro_check.rs b/src/libsyntax/ext/mbe/macro_check.rs index a1734689595f0..aa88d71666eb5 100644 --- a/src/libsyntax/ext/mbe/macro_check.rs +++ b/src/libsyntax/ext/mbe/macro_check.rs @@ -106,7 +106,7 @@ //! bound. use crate::ast::NodeId; use crate::early_buffered_lints::BufferedEarlyLintId; -use crate::ext::tt::quoted::{KleeneToken, TokenTree}; +use crate::ext::mbe::quoted::{KleeneToken, TokenTree}; use crate::parse::token::TokenKind; use crate::parse::token::{DelimToken, Token}; use crate::parse::ParseSess; diff --git a/src/libsyntax/ext/mbe/macro_parser.rs b/src/libsyntax/ext/mbe/macro_parser.rs index a34a0344f2740..88145cd121f14 100644 --- a/src/libsyntax/ext/mbe/macro_parser.rs +++ b/src/libsyntax/ext/mbe/macro_parser.rs @@ -75,7 +75,7 @@ crate use ParseResult::*; use TokenTreeOrTokenTreeSlice::*; use crate::ast::{Ident, Name}; -use crate::ext::tt::quoted::{self, TokenTree}; +use crate::ext::mbe::quoted::{self, TokenTree}; use crate::parse::{Directory, ParseSess}; use crate::parse::parser::{Parser, PathStyle}; use crate::parse::token::{self, DocComment, Nonterminal, Token}; diff --git a/src/libsyntax/ext/mbe/macro_rules.rs b/src/libsyntax/ext/mbe/macro_rules.rs index 90dfa6e7ac8a4..939f5b8f51d57 100644 --- a/src/libsyntax/ext/mbe/macro_rules.rs +++ b/src/libsyntax/ext/mbe/macro_rules.rs @@ -4,12 +4,12 @@ use crate::edition::Edition; use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander}; use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use crate::ext::expand::{AstFragment, AstFragmentKind}; -use crate::ext::tt::macro_check; -use crate::ext::tt::macro_parser::{parse, parse_failure_msg}; -use crate::ext::tt::macro_parser::{Error, Failure, Success}; -use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq}; -use crate::ext::tt::quoted; -use crate::ext::tt::transcribe::transcribe; +use crate::ext::mbe::macro_check; +use crate::ext::mbe::macro_parser::{parse, parse_failure_msg}; +use crate::ext::mbe::macro_parser::{Error, Failure, Success}; +use crate::ext::mbe::macro_parser::{MatchedNonterminal, MatchedSeq}; +use crate::ext::mbe::quoted; +use crate::ext::mbe::transcribe::transcribe; use crate::feature_gate::Features; use crate::parse::parser::Parser; use crate::parse::token::TokenKind::*; diff --git a/src/libsyntax/ext/mbe/quoted.rs b/src/libsyntax/ext/mbe/quoted.rs index d161e6638bf75..8ef2834523112 100644 --- a/src/libsyntax/ext/mbe/quoted.rs +++ b/src/libsyntax/ext/mbe/quoted.rs @@ -1,6 +1,6 @@ use crate::ast; use crate::ast::NodeId; -use crate::ext::tt::macro_parser; +use crate::ext::mbe::macro_parser; use crate::feature_gate::Features; use crate::parse::token::{self, Token, TokenKind}; use crate::parse::ParseSess; diff --git a/src/libsyntax/ext/mbe/transcribe.rs b/src/libsyntax/ext/mbe/transcribe.rs index f9c07e3a2e4ff..94ac1f60c6407 100644 --- a/src/libsyntax/ext/mbe/transcribe.rs +++ b/src/libsyntax/ext/mbe/transcribe.rs @@ -1,7 +1,7 @@ use crate::ast::{Ident, Mac}; use crate::ext::base::ExtCtxt; -use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch}; -use crate::ext::tt::quoted; +use crate::ext::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch}; +use crate::ext::mbe::quoted; use crate::mut_visit::{self, MutVisitor}; use crate::parse::token::{self, NtTT, Token}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index c06f43021021a..045a36931883c 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -162,14 +162,14 @@ pub mod ext { mod proc_macro_server; pub use syntax_pos::hygiene; - pub use tt::macro_rules::compile_declarative_macro; + pub use mbe::macro_rules::compile_declarative_macro; pub mod allocator; pub mod base; pub mod build; pub mod expand; pub mod proc_macro; - crate mod tt { + crate mod mbe { crate mod transcribe; crate mod macro_check; crate mod macro_parser; diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 15fc4b02041b7..d46e38f53d51b 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -14,7 +14,7 @@ //! ownership of the original. use crate::ext::base; -use crate::ext::tt::{macro_parser, quoted}; +use crate::ext::mbe::{macro_parser, quoted}; use crate::parse::Directory; use crate::parse::token::{self, DelimToken, Token, TokenKind}; use crate::print::pprust; From e30c5166db72f9f1ceccc355df25b49df826df02 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Sep 2019 18:28:32 +0300 Subject: [PATCH 20/31] move mbe module to a separate file --- src/libsyntax/ext/mbe.rs | 5 +++++ src/libsyntax/lib.rs | 8 +------- 2 files changed, 6 insertions(+), 7 deletions(-) create mode 100644 src/libsyntax/ext/mbe.rs diff --git a/src/libsyntax/ext/mbe.rs b/src/libsyntax/ext/mbe.rs new file mode 100644 index 0000000000000..b77b59fea7039 --- /dev/null +++ b/src/libsyntax/ext/mbe.rs @@ -0,0 +1,5 @@ +crate mod transcribe; +crate mod macro_check; +crate mod macro_parser; +crate mod macro_rules; +crate mod quoted; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 045a36931883c..402d563010fdc 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -169,13 +169,7 @@ pub mod ext { pub mod expand; pub mod proc_macro; - crate mod mbe { - crate mod transcribe; - crate mod macro_check; - crate mod macro_parser; - crate mod macro_rules; - crate mod quoted; - } + crate mod mbe; } pub mod early_buffered_lints; From 636b3543c27e1eba301605afd2143fc96fd14431 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Sep 2019 20:36:35 +0300 Subject: [PATCH 21/31] docstring for mbe module --- src/libsyntax/ext/mbe.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libsyntax/ext/mbe.rs b/src/libsyntax/ext/mbe.rs index b77b59fea7039..78d96f471fa7f 100644 --- a/src/libsyntax/ext/mbe.rs +++ b/src/libsyntax/ext/mbe.rs @@ -1,3 +1,8 @@ +//! This module implements declarative macros: old `macro_rules` and the newer +//! `macro`. Declarative macros are also known as "macro by example", and that's +//! why we call this module `mbe`. For external documentation, prefer the +//! official terminology: "declarative macros". + crate mod transcribe; crate mod macro_check; crate mod macro_parser; From 9fd75f52877a3e23a7b9a6a9675f37a42340a428 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Sep 2019 19:17:30 +0300 Subject: [PATCH 22/31] pull mbe token tree definition up --- src/libsyntax/ext/mbe.rs | 156 ++++++++++++++++++++++++++ src/libsyntax/ext/mbe/macro_check.rs | 2 +- src/libsyntax/ext/mbe/macro_parser.rs | 10 +- src/libsyntax/ext/mbe/macro_rules.rs | 116 +++++++++---------- src/libsyntax/ext/mbe/quoted.rs | 155 +------------------------ src/libsyntax/ext/mbe/transcribe.rs | 34 +++--- src/libsyntax/tokenstream.rs | 4 +- 7 files changed, 243 insertions(+), 234 deletions(-) diff --git a/src/libsyntax/ext/mbe.rs b/src/libsyntax/ext/mbe.rs index 78d96f471fa7f..c18b8918ff1e3 100644 --- a/src/libsyntax/ext/mbe.rs +++ b/src/libsyntax/ext/mbe.rs @@ -8,3 +8,159 @@ crate mod macro_check; crate mod macro_parser; crate mod macro_rules; crate mod quoted; + +use crate::ast; +use crate::parse::token::{self, Token, TokenKind}; +use crate::tokenstream::{DelimSpan}; + +use syntax_pos::{BytePos, Span}; + +use rustc_data_structures::sync::Lrc; + +/// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note +/// that the delimiter itself might be `NoDelim`. +#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] +crate struct Delimited { + crate delim: token::DelimToken, + crate tts: Vec, +} + +impl Delimited { + /// Returns a `self::TokenTree` with a `Span` corresponding to the opening delimiter. + crate fn open_tt(&self, span: Span) -> TokenTree { + let open_span = if span.is_dummy() { + span + } else { + span.with_hi(span.lo() + BytePos(self.delim.len() as u32)) + }; + TokenTree::token(token::OpenDelim(self.delim), open_span) + } + + /// Returns a `self::TokenTree` with a `Span` corresponding to the closing delimiter. + crate fn close_tt(&self, span: Span) -> TokenTree { + let close_span = if span.is_dummy() { + span + } else { + span.with_lo(span.hi() - BytePos(self.delim.len() as u32)) + }; + TokenTree::token(token::CloseDelim(self.delim), close_span) + } +} + +#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] +crate struct SequenceRepetition { + /// The sequence of token trees + crate tts: Vec, + /// The optional separator + crate separator: Option, + /// Whether the sequence can be repeated zero (*), or one or more times (+) + crate kleene: KleeneToken, + /// The number of `Match`s that appear in the sequence (and subsequences) + crate num_captures: usize, +} + +#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] +crate struct KleeneToken { + crate span: Span, + crate op: KleeneOp, +} + +impl KleeneToken { + crate fn new(op: KleeneOp, span: Span) -> KleeneToken { + KleeneToken { span, op } + } +} + +/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star) +/// for token sequences. +#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +crate enum KleeneOp { + /// Kleene star (`*`) for zero or more repetitions + ZeroOrMore, + /// Kleene plus (`+`) for one or more repetitions + OneOrMore, + /// Kleene optional (`?`) for zero or one reptitions + ZeroOrOne, +} + +/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)` +/// are "first-class" token trees. Useful for parsing macros. +#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)] +crate enum TokenTree { + Token(Token), + Delimited(DelimSpan, Lrc), + /// A kleene-style repetition sequence + Sequence(DelimSpan, Lrc), + /// e.g., `$var` + MetaVar(Span, ast::Ident), + /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros. + MetaVarDecl( + Span, + ast::Ident, /* name to bind */ + ast::Ident, /* kind of nonterminal */ + ), +} + +impl TokenTree { + /// Return the number of tokens in the tree. + crate fn len(&self) -> usize { + match *self { + TokenTree::Delimited(_, ref delimed) => match delimed.delim { + token::NoDelim => delimed.tts.len(), + _ => delimed.tts.len() + 2, + }, + TokenTree::Sequence(_, ref seq) => seq.tts.len(), + _ => 0, + } + } + + /// Returns `true` if the given token tree is delimited. + crate fn is_delimited(&self) -> bool { + match *self { + TokenTree::Delimited(..) => true, + _ => false, + } + } + + /// Returns `true` if the given token tree is a token of the given kind. + crate fn is_token(&self, expected_kind: &TokenKind) -> bool { + match self { + TokenTree::Token(Token { kind: actual_kind, .. }) => actual_kind == expected_kind, + _ => false, + } + } + + /// Gets the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences. + crate fn get_tt(&self, index: usize) -> TokenTree { + match (self, index) { + (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => { + delimed.tts[index].clone() + } + (&TokenTree::Delimited(span, ref delimed), _) => { + if index == 0 { + return delimed.open_tt(span.open); + } + if index == delimed.tts.len() + 1 { + return delimed.close_tt(span.close); + } + delimed.tts[index - 1].clone() + } + (&TokenTree::Sequence(_, ref seq), _) => seq.tts[index].clone(), + _ => panic!("Cannot expand a token tree"), + } + } + + /// Retrieves the `TokenTree`'s span. + crate fn span(&self) -> Span { + match *self { + TokenTree::Token(Token { span, .. }) + | TokenTree::MetaVar(span, _) + | TokenTree::MetaVarDecl(span, _, _) => span, + TokenTree::Delimited(span, _) | TokenTree::Sequence(span, _) => span.entire(), + } + } + + crate fn token(kind: TokenKind, span: Span) -> TokenTree { + TokenTree::Token(Token::new(kind, span)) + } +} diff --git a/src/libsyntax/ext/mbe/macro_check.rs b/src/libsyntax/ext/mbe/macro_check.rs index aa88d71666eb5..a3750e5c46945 100644 --- a/src/libsyntax/ext/mbe/macro_check.rs +++ b/src/libsyntax/ext/mbe/macro_check.rs @@ -106,7 +106,7 @@ //! bound. use crate::ast::NodeId; use crate::early_buffered_lints::BufferedEarlyLintId; -use crate::ext::mbe::quoted::{KleeneToken, TokenTree}; +use crate::ext::mbe::{KleeneToken, TokenTree}; use crate::parse::token::TokenKind; use crate::parse::token::{DelimToken, Token}; use crate::parse::ParseSess; diff --git a/src/libsyntax/ext/mbe/macro_parser.rs b/src/libsyntax/ext/mbe/macro_parser.rs index 88145cd121f14..35fc6cf21b80e 100644 --- a/src/libsyntax/ext/mbe/macro_parser.rs +++ b/src/libsyntax/ext/mbe/macro_parser.rs @@ -75,7 +75,7 @@ crate use ParseResult::*; use TokenTreeOrTokenTreeSlice::*; use crate::ast::{Ident, Name}; -use crate::ext::mbe::quoted::{self, TokenTree}; +use crate::ext::mbe::{self, TokenTree}; use crate::parse::{Directory, ParseSess}; use crate::parse::parser::{Parser, PathStyle}; use crate::parse::token::{self, DocComment, Nonterminal, Token}; @@ -195,7 +195,7 @@ struct MatcherPos<'root, 'tt> { // `None`. /// The KleeneOp of this sequence if we are in a repetition. - seq_op: Option, + seq_op: Option, /// The separator if we are in a repetition. sep: Option, @@ -532,7 +532,7 @@ fn inner_parse_loop<'root, 'tt>( } // We don't need a separator. Move the "dot" back to the beginning of the matcher // and try to match again UNLESS we are only allowed to have _one_ repetition. - else if item.seq_op != Some(quoted::KleeneOp::ZeroOrOne) { + else if item.seq_op != Some(mbe::KleeneOp::ZeroOrOne) { item.match_cur = item.match_lo; item.idx = 0; cur_items.push(item); @@ -555,8 +555,8 @@ fn inner_parse_loop<'root, 'tt>( // implicitly disallowing OneOrMore from having 0 matches here. Thus, that will // result in a "no rules expected token" error by virtue of this matcher not // working. - if seq.kleene.op == quoted::KleeneOp::ZeroOrMore - || seq.kleene.op == quoted::KleeneOp::ZeroOrOne + if seq.kleene.op == mbe::KleeneOp::ZeroOrMore + || seq.kleene.op == mbe::KleeneOp::ZeroOrOne { let mut new_item = item.clone(); new_item.match_cur += seq.num_captures; diff --git a/src/libsyntax/ext/mbe/macro_rules.rs b/src/libsyntax/ext/mbe/macro_rules.rs index 939f5b8f51d57..2ec171a7fb591 100644 --- a/src/libsyntax/ext/mbe/macro_rules.rs +++ b/src/libsyntax/ext/mbe/macro_rules.rs @@ -4,11 +4,11 @@ use crate::edition::Edition; use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander}; use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use crate::ext::expand::{AstFragment, AstFragmentKind}; +use crate::ext::mbe; use crate::ext::mbe::macro_check; use crate::ext::mbe::macro_parser::{parse, parse_failure_msg}; use crate::ext::mbe::macro_parser::{Error, Failure, Success}; use crate::ext::mbe::macro_parser::{MatchedNonterminal, MatchedSeq}; -use crate::ext::mbe::quoted; use crate::ext::mbe::transcribe::transcribe; use crate::feature_gate::Features; use crate::parse::parser::Parser; @@ -135,8 +135,8 @@ struct MacroRulesMacroExpander { name: ast::Ident, span: Span, transparency: Transparency, - lhses: Vec, - rhses: Vec, + lhses: Vec, + rhses: Vec, valid: bool, } @@ -169,8 +169,8 @@ fn generic_extension<'cx>( name: ast::Ident, transparency: Transparency, arg: TokenStream, - lhses: &[quoted::TokenTree], - rhses: &[quoted::TokenTree], + lhses: &[mbe::TokenTree], + rhses: &[mbe::TokenTree], ) -> Box { if cx.trace_macros() { trace_macros_note(cx, sp, format!("expanding `{}! {{ {} }}`", name, arg)); @@ -182,7 +182,7 @@ fn generic_extension<'cx>( for (i, lhs) in lhses.iter().enumerate() { // try each arm's matchers let lhs_tt = match *lhs { - quoted::TokenTree::Delimited(_, ref delim) => &delim.tts[..], + mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..], _ => cx.span_bug(sp, "malformed macro lhs"), }; @@ -190,7 +190,7 @@ fn generic_extension<'cx>( Success(named_matches) => { let rhs = match rhses[i] { // ignore delimiters - quoted::TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(), + mbe::TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(), _ => cx.span_bug(sp, "malformed macro rhs"), }; let arm_span = rhses[i].span(); @@ -258,7 +258,7 @@ fn generic_extension<'cx>( for lhs in lhses { // try each arm's matchers let lhs_tt = match *lhs { - quoted::TokenTree::Delimited(_, ref delim) => &delim.tts[..], + mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..], _ => continue, }; match TokenTree::parse(cx, lhs_tt, arg.clone()) { @@ -312,32 +312,32 @@ pub fn compile_declarative_macro( // ...quasiquoting this would be nice. // These spans won't matter, anyways let argument_gram = vec![ - quoted::TokenTree::Sequence( + mbe::TokenTree::Sequence( DelimSpan::dummy(), - Lrc::new(quoted::SequenceRepetition { + Lrc::new(mbe::SequenceRepetition { tts: vec![ - quoted::TokenTree::MetaVarDecl(def.span, lhs_nm, tt_spec), - quoted::TokenTree::token(token::FatArrow, def.span), - quoted::TokenTree::MetaVarDecl(def.span, rhs_nm, tt_spec), + mbe::TokenTree::MetaVarDecl(def.span, lhs_nm, tt_spec), + mbe::TokenTree::token(token::FatArrow, def.span), + mbe::TokenTree::MetaVarDecl(def.span, rhs_nm, tt_spec), ], separator: Some(Token::new( if body.legacy { token::Semi } else { token::Comma }, def.span, )), - kleene: quoted::KleeneToken::new(quoted::KleeneOp::OneOrMore, def.span), + kleene: mbe::KleeneToken::new(mbe::KleeneOp::OneOrMore, def.span), num_captures: 2, }), ), // to phase into semicolon-termination instead of semicolon-separation - quoted::TokenTree::Sequence( + mbe::TokenTree::Sequence( DelimSpan::dummy(), - Lrc::new(quoted::SequenceRepetition { - tts: vec![quoted::TokenTree::token( + Lrc::new(mbe::SequenceRepetition { + tts: vec![mbe::TokenTree::token( if body.legacy { token::Semi } else { token::Comma }, def.span, )], separator: None, - kleene: quoted::KleeneToken::new(quoted::KleeneOp::ZeroOrMore, def.span), + kleene: mbe::KleeneToken::new(mbe::KleeneOp::ZeroOrMore, def.span), num_captures: 0, }), ), @@ -367,7 +367,7 @@ pub fn compile_declarative_macro( .map(|m| { if let MatchedNonterminal(ref nt) = *m { if let NtTT(ref tt) = **nt { - let tt = quoted::parse( + let tt = mbe::quoted::parse( tt.clone().into(), true, sess, @@ -384,7 +384,7 @@ pub fn compile_declarative_macro( } sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs") }) - .collect::>(), + .collect::>(), _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"), }; @@ -394,7 +394,7 @@ pub fn compile_declarative_macro( .map(|m| { if let MatchedNonterminal(ref nt) = *m { if let NtTT(ref tt) = **nt { - return quoted::parse( + return mbe::quoted::parse( tt.clone().into(), false, sess, @@ -409,7 +409,7 @@ pub fn compile_declarative_macro( } sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs") }) - .collect::>(), + .collect::>(), _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"), }; @@ -454,11 +454,11 @@ fn check_lhs_nt_follows( sess: &ParseSess, features: &Features, attrs: &[ast::Attribute], - lhs: "ed::TokenTree, + lhs: &mbe::TokenTree, ) -> bool { // lhs is going to be like TokenTree::Delimited(...), where the // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens. - if let quoted::TokenTree::Delimited(_, ref tts) = *lhs { + if let mbe::TokenTree::Delimited(_, ref tts) = *lhs { check_matcher(sess, features, attrs, &tts.tts) } else { let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; @@ -471,8 +471,8 @@ fn check_lhs_nt_follows( /// Checks that the lhs contains no repetition which could match an empty token /// tree, because then the matcher would hang indefinitely. -fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { - use quoted::TokenTree; +fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { + use mbe::TokenTree; for tt in tts { match *tt { TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) => (), @@ -486,8 +486,8 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { && seq.tts.iter().all(|seq_tt| match *seq_tt { TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis, TokenTree::Sequence(_, ref sub_seq) => { - sub_seq.kleene.op == quoted::KleeneOp::ZeroOrMore - || sub_seq.kleene.op == quoted::KleeneOp::ZeroOrOne + sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore + || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne } _ => false, }) @@ -506,9 +506,9 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { true } -fn check_rhs(sess: &ParseSess, rhs: "ed::TokenTree) -> bool { +fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool { match *rhs { - quoted::TokenTree::Delimited(..) => return true, + mbe::TokenTree::Delimited(..) => return true, _ => sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited"), } false @@ -518,7 +518,7 @@ fn check_matcher( sess: &ParseSess, features: &Features, attrs: &[ast::Attribute], - matcher: &[quoted::TokenTree], + matcher: &[mbe::TokenTree], ) -> bool { let first_sets = FirstSets::new(matcher); let empty_suffix = TokenSet::empty(); @@ -550,8 +550,8 @@ struct FirstSets { } impl FirstSets { - fn new(tts: &[quoted::TokenTree]) -> FirstSets { - use quoted::TokenTree; + fn new(tts: &[mbe::TokenTree]) -> FirstSets { + use mbe::TokenTree; let mut sets = FirstSets { first: FxHashMap::default() }; build_recur(&mut sets, tts); @@ -598,8 +598,8 @@ impl FirstSets { // Reverse scan: Sequence comes before `first`. if subfirst.maybe_empty - || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore - || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne + || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrMore + || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrOne { // If sequence is potentially empty, then // union them (preserving first emptiness). @@ -619,8 +619,8 @@ impl FirstSets { // walks forward over `tts` until all potential FIRST tokens are // identified. - fn first(&self, tts: &[quoted::TokenTree]) -> TokenSet { - use quoted::TokenTree; + fn first(&self, tts: &[mbe::TokenTree]) -> TokenSet { + use mbe::TokenTree; let mut first = TokenSet::empty(); for tt in tts.iter() { @@ -656,8 +656,8 @@ impl FirstSets { assert!(first.maybe_empty); first.add_all(subfirst); if subfirst.maybe_empty - || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore - || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne + || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrMore + || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrOne { // Continue scanning for more first // tokens, but also make sure we @@ -678,7 +678,7 @@ impl FirstSets { } } -// A set of `quoted::TokenTree`s, which may include `TokenTree::Match`s +// A set of `mbe::TokenTree`s, which may include `TokenTree::Match`s // (for macro-by-example syntactic variables). It also carries the // `maybe_empty` flag; that is true if and only if the matcher can // match an empty token sequence. @@ -690,7 +690,7 @@ impl FirstSets { // (Notably, we must allow for *-op to occur zero times.) #[derive(Clone, Debug)] struct TokenSet { - tokens: Vec, + tokens: Vec, maybe_empty: bool, } @@ -702,13 +702,13 @@ impl TokenSet { // Returns the set `{ tok }` for the single-token (and thus // non-empty) sequence [tok]. - fn singleton(tok: quoted::TokenTree) -> Self { + fn singleton(tok: mbe::TokenTree) -> Self { TokenSet { tokens: vec![tok], maybe_empty: false } } // Changes self to be the set `{ tok }`. // Since `tok` is always present, marks self as non-empty. - fn replace_with(&mut self, tok: quoted::TokenTree) { + fn replace_with(&mut self, tok: mbe::TokenTree) { self.tokens.clear(); self.tokens.push(tok); self.maybe_empty = false; @@ -723,7 +723,7 @@ impl TokenSet { } // Adds `tok` to the set for `self`, marking sequence as non-empy. - fn add_one(&mut self, tok: quoted::TokenTree) { + fn add_one(&mut self, tok: mbe::TokenTree) { if !self.tokens.contains(&tok) { self.tokens.push(tok); } @@ -731,7 +731,7 @@ impl TokenSet { } // Adds `tok` to the set for `self`. (Leaves `maybe_empty` flag alone.) - fn add_one_maybe(&mut self, tok: quoted::TokenTree) { + fn add_one_maybe(&mut self, tok: mbe::TokenTree) { if !self.tokens.contains(&tok) { self.tokens.push(tok); } @@ -772,10 +772,10 @@ fn check_matcher_core( features: &Features, attrs: &[ast::Attribute], first_sets: &FirstSets, - matcher: &[quoted::TokenTree], + matcher: &[mbe::TokenTree], follow: &TokenSet, ) -> TokenSet { - use quoted::TokenTree; + use mbe::TokenTree; let mut last = TokenSet::empty(); @@ -950,8 +950,8 @@ fn check_matcher_core( last } -fn token_can_be_followed_by_any(tok: "ed::TokenTree) -> bool { - if let quoted::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok { +fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool { + if let mbe::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok { frag_can_be_followed_by_any(frag_spec.name) } else { // (Non NT's can always be followed by anthing in matchers.) @@ -997,8 +997,8 @@ enum IsInFollow { /// break macros that were relying on that binary operator as a /// separator. // when changing this do not forget to update doc/book/macros.md! -fn is_in_follow(tok: "ed::TokenTree, frag: Symbol) -> IsInFollow { - use quoted::TokenTree; +fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { + use mbe::TokenTree; if let TokenTree::Token(Token { kind: token::CloseDelim(_), .. }) = *tok { // closing a token tree can never be matched by any fragment; @@ -1116,10 +1116,10 @@ fn has_legal_fragment_specifier( sess: &ParseSess, features: &Features, attrs: &[ast::Attribute], - tok: "ed::TokenTree, + tok: &mbe::TokenTree, ) -> Result<(), String> { debug!("has_legal_fragment_specifier({:?})", tok); - if let quoted::TokenTree::MetaVarDecl(_, _, ref frag_spec) = *tok { + if let mbe::TokenTree::MetaVarDecl(_, _, ref frag_spec) = *tok { let frag_span = tok.span(); if !is_legal_fragment_specifier(sess, features, attrs, frag_spec.name, frag_span) { return Err(frag_spec.to_string()); @@ -1160,13 +1160,13 @@ fn is_legal_fragment_specifier( } } -fn quoted_tt_to_string(tt: "ed::TokenTree) -> String { +fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { match *tt { - quoted::TokenTree::Token(ref token) => crate::print::pprust::token_to_string(&token), - quoted::TokenTree::MetaVar(_, name) => format!("${}", name), - quoted::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), + mbe::TokenTree::Token(ref token) => crate::print::pprust::token_to_string(&token), + mbe::TokenTree::MetaVar(_, name) => format!("${}", name), + mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), _ => panic!( - "unexpected quoted::TokenTree::{{Sequence or Delimited}} \ + "unexpected mbe::TokenTree::{{Sequence or Delimited}} \ in follow set checker" ), } diff --git a/src/libsyntax/ext/mbe/quoted.rs b/src/libsyntax/ext/mbe/quoted.rs index 8ef2834523112..82289d7449d36 100644 --- a/src/libsyntax/ext/mbe/quoted.rs +++ b/src/libsyntax/ext/mbe/quoted.rs @@ -1,166 +1,19 @@ use crate::ast; use crate::ast::NodeId; use crate::ext::mbe::macro_parser; +use crate::ext::mbe::{TokenTree, KleeneOp, KleeneToken, SequenceRepetition, Delimited}; use crate::feature_gate::Features; -use crate::parse::token::{self, Token, TokenKind}; +use crate::parse::token::{self, Token}; use crate::parse::ParseSess; use crate::print::pprust; use crate::symbol::kw; -use crate::tokenstream::{self, DelimSpan}; +use crate::tokenstream; -use syntax_pos::{edition::Edition, BytePos, Span}; +use syntax_pos::{edition::Edition, Span}; use rustc_data_structures::sync::Lrc; use std::iter::Peekable; -/// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note -/// that the delimiter itself might be `NoDelim`. -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] -crate struct Delimited { - crate delim: token::DelimToken, - crate tts: Vec, -} - -impl Delimited { - /// Returns a `self::TokenTree` with a `Span` corresponding to the opening delimiter. - crate fn open_tt(&self, span: Span) -> TokenTree { - let open_span = if span.is_dummy() { - span - } else { - span.with_hi(span.lo() + BytePos(self.delim.len() as u32)) - }; - TokenTree::token(token::OpenDelim(self.delim), open_span) - } - - /// Returns a `self::TokenTree` with a `Span` corresponding to the closing delimiter. - crate fn close_tt(&self, span: Span) -> TokenTree { - let close_span = if span.is_dummy() { - span - } else { - span.with_lo(span.hi() - BytePos(self.delim.len() as u32)) - }; - TokenTree::token(token::CloseDelim(self.delim), close_span) - } -} - -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] -crate struct SequenceRepetition { - /// The sequence of token trees - crate tts: Vec, - /// The optional separator - crate separator: Option, - /// Whether the sequence can be repeated zero (*), or one or more times (+) - crate kleene: KleeneToken, - /// The number of `Match`s that appear in the sequence (and subsequences) - crate num_captures: usize, -} - -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] -crate struct KleeneToken { - crate span: Span, - crate op: KleeneOp, -} - -impl KleeneToken { - crate fn new(op: KleeneOp, span: Span) -> KleeneToken { - KleeneToken { span, op } - } -} - -/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star) -/// for token sequences. -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -crate enum KleeneOp { - /// Kleene star (`*`) for zero or more repetitions - ZeroOrMore, - /// Kleene plus (`+`) for one or more repetitions - OneOrMore, - /// Kleene optional (`?`) for zero or one reptitions - ZeroOrOne, -} - -/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)` -/// are "first-class" token trees. Useful for parsing macros. -#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)] -crate enum TokenTree { - Token(Token), - Delimited(DelimSpan, Lrc), - /// A kleene-style repetition sequence - Sequence(DelimSpan, Lrc), - /// e.g., `$var` - MetaVar(Span, ast::Ident), - /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros. - MetaVarDecl( - Span, - ast::Ident, /* name to bind */ - ast::Ident, /* kind of nonterminal */ - ), -} - -impl TokenTree { - /// Return the number of tokens in the tree. - crate fn len(&self) -> usize { - match *self { - TokenTree::Delimited(_, ref delimed) => match delimed.delim { - token::NoDelim => delimed.tts.len(), - _ => delimed.tts.len() + 2, - }, - TokenTree::Sequence(_, ref seq) => seq.tts.len(), - _ => 0, - } - } - - /// Returns `true` if the given token tree is delimited. - crate fn is_delimited(&self) -> bool { - match *self { - TokenTree::Delimited(..) => true, - _ => false, - } - } - - /// Returns `true` if the given token tree is a token of the given kind. - crate fn is_token(&self, expected_kind: &TokenKind) -> bool { - match self { - TokenTree::Token(Token { kind: actual_kind, .. }) => actual_kind == expected_kind, - _ => false, - } - } - - /// Gets the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences. - crate fn get_tt(&self, index: usize) -> TokenTree { - match (self, index) { - (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => { - delimed.tts[index].clone() - } - (&TokenTree::Delimited(span, ref delimed), _) => { - if index == 0 { - return delimed.open_tt(span.open); - } - if index == delimed.tts.len() + 1 { - return delimed.close_tt(span.close); - } - delimed.tts[index - 1].clone() - } - (&TokenTree::Sequence(_, ref seq), _) => seq.tts[index].clone(), - _ => panic!("Cannot expand a token tree"), - } - } - - /// Retrieves the `TokenTree`'s span. - crate fn span(&self) -> Span { - match *self { - TokenTree::Token(Token { span, .. }) - | TokenTree::MetaVar(span, _) - | TokenTree::MetaVarDecl(span, _, _) => span, - TokenTree::Delimited(span, _) | TokenTree::Sequence(span, _) => span.entire(), - } - } - - crate fn token(kind: TokenKind, span: Span) -> TokenTree { - TokenTree::Token(Token::new(kind, span)) - } -} - /// Takes a `tokenstream::TokenStream` and returns a `Vec`. Specifically, this /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a /// collection of `TokenTree` for use in parsing a macro. diff --git a/src/libsyntax/ext/mbe/transcribe.rs b/src/libsyntax/ext/mbe/transcribe.rs index 94ac1f60c6407..ba818ebd35c7f 100644 --- a/src/libsyntax/ext/mbe/transcribe.rs +++ b/src/libsyntax/ext/mbe/transcribe.rs @@ -1,7 +1,7 @@ use crate::ast::{Ident, Mac}; use crate::ext::base::ExtCtxt; +use crate::ext::mbe; use crate::ext::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch}; -use crate::ext::mbe::quoted; use crate::mut_visit::{self, MutVisitor}; use crate::parse::token::{self, NtTT, Token}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; @@ -38,22 +38,22 @@ impl Marker { /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`). enum Frame { - Delimited { forest: Lrc, idx: usize, span: DelimSpan }, - Sequence { forest: Lrc, idx: usize, sep: Option }, + Delimited { forest: Lrc, idx: usize, span: DelimSpan }, + Sequence { forest: Lrc, idx: usize, sep: Option }, } impl Frame { /// Construct a new frame around the delimited set of tokens. - fn new(tts: Vec) -> Frame { - let forest = Lrc::new(quoted::Delimited { delim: token::NoDelim, tts }); + fn new(tts: Vec) -> Frame { + let forest = Lrc::new(mbe::Delimited { delim: token::NoDelim, tts }); Frame::Delimited { forest, idx: 0, span: DelimSpan::dummy() } } } impl Iterator for Frame { - type Item = quoted::TokenTree; + type Item = mbe::TokenTree; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { match *self { Frame::Delimited { ref forest, ref mut idx, .. } => { *idx += 1; @@ -90,7 +90,7 @@ impl Iterator for Frame { pub(super) fn transcribe( cx: &ExtCtxt<'_>, interp: &FxHashMap, - src: Vec, + src: Vec, transparency: Transparency, ) -> TokenStream { // Nothing for us to transcribe... @@ -178,7 +178,7 @@ pub(super) fn transcribe( // We are descending into a sequence. We first make sure that the matchers in the RHS // and the matches in `interp` have the same shape. Otherwise, either the caller or the // macro writer has made a mistake. - seq @ quoted::TokenTree::Sequence(..) => { + seq @ mbe::TokenTree::Sequence(..) => { match lockstep_iter_size(&seq, interp, &repeats) { LockstepIterSize::Unconstrained => { cx.span_fatal( @@ -199,7 +199,7 @@ pub(super) fn transcribe( LockstepIterSize::Constraint(len, _) => { // We do this to avoid an extra clone above. We know that this is a // sequence already. - let (sp, seq) = if let quoted::TokenTree::Sequence(sp, seq) = seq { + let (sp, seq) = if let mbe::TokenTree::Sequence(sp, seq) = seq { (sp, seq) } else { unreachable!() @@ -207,7 +207,7 @@ pub(super) fn transcribe( // Is the repetition empty? if len == 0 { - if seq.kleene.op == quoted::KleeneOp::OneOrMore { + if seq.kleene.op == mbe::KleeneOp::OneOrMore { // FIXME: this really ought to be caught at macro definition // time... It happens when the Kleene operator in the matcher and // the body for the same meta-variable do not match. @@ -232,7 +232,7 @@ pub(super) fn transcribe( } // Replace the meta-var with the matched token tree from the invocation. - quoted::TokenTree::MetaVar(mut sp, mut ident) => { + mbe::TokenTree::MetaVar(mut sp, mut ident) => { // Find the matched nonterminal from the macro invocation, and use it to replace // the meta-var. if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { @@ -269,7 +269,7 @@ pub(super) fn transcribe( // We will produce all of the results of the inside of the `Delimited` and then we will // jump back out of the Delimited, pop the result_stack and add the new results back to // the previous results (from outside the Delimited). - quoted::TokenTree::Delimited(mut span, delimited) => { + mbe::TokenTree::Delimited(mut span, delimited) => { marker.visit_delim_span(&mut span); stack.push(Frame::Delimited { forest: delimited, idx: 0, span }); result_stack.push(mem::take(&mut result)); @@ -277,14 +277,14 @@ pub(super) fn transcribe( // Nothing much to do here. Just push the token to the result, being careful to // preserve syntax context. - quoted::TokenTree::Token(token) => { + mbe::TokenTree::Token(token) => { let mut tt = TokenTree::Token(token); marker.visit_tt(&mut tt); result.push(tt.into()); } // There should be no meta-var declarations in the invocation of a macro. - quoted::TokenTree::MetaVarDecl(..) => panic!("unexpected `TokenTree::MetaVarDecl"), + mbe::TokenTree::MetaVarDecl(..) => panic!("unexpected `TokenTree::MetaVarDecl"), } } } @@ -368,11 +368,11 @@ impl LockstepIterSize { /// `lookup_cur_matched` will return `None`, which is why this still works even in the presnece of /// multiple nested matcher sequences. fn lockstep_iter_size( - tree: "ed::TokenTree, + tree: &mbe::TokenTree, interpolations: &FxHashMap, repeats: &[(usize, usize)], ) -> LockstepIterSize { - use quoted::TokenTree; + use mbe::TokenTree; match *tree { TokenTree::Delimited(_, ref delimed) => { delimed.tts.iter().fold(LockstepIterSize::Unconstrained, |size, tt| { diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index d46e38f53d51b..fd87f8a1f678a 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -14,7 +14,7 @@ //! ownership of the original. use crate::ext::base; -use crate::ext::mbe::{macro_parser, quoted}; +use crate::ext::mbe::{self, macro_parser}; use crate::parse::Directory; use crate::parse::token::{self, DelimToken, Token, TokenKind}; use crate::print::pprust; @@ -64,7 +64,7 @@ where impl TokenTree { /// Use this token tree as a matcher to parse given tts. - crate fn parse(cx: &base::ExtCtxt<'_>, mtch: &[quoted::TokenTree], tts: TokenStream) + crate fn parse(cx: &base::ExtCtxt<'_>, mtch: &[mbe::TokenTree], tts: TokenStream) -> macro_parser::NamedParseResult { // `None` is because we're not interpolating let directory = Directory { From 983569732d24df434c644dd1764e9c5e4ecfd081 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Sep 2019 19:41:04 +0300 Subject: [PATCH 23/31] push TokenTree::parse down --- src/libsyntax/ext/mbe/macro_rules.rs | 15 ++++++++++++++- src/libsyntax/tokenstream.rs | 15 --------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/libsyntax/ext/mbe/macro_rules.rs b/src/libsyntax/ext/mbe/macro_rules.rs index 2ec171a7fb591..816baadb12fbb 100644 --- a/src/libsyntax/ext/mbe/macro_rules.rs +++ b/src/libsyntax/ext/mbe/macro_rules.rs @@ -8,7 +8,7 @@ use crate::ext::mbe; use crate::ext::mbe::macro_check; use crate::ext::mbe::macro_parser::{parse, parse_failure_msg}; use crate::ext::mbe::macro_parser::{Error, Failure, Success}; -use crate::ext::mbe::macro_parser::{MatchedNonterminal, MatchedSeq}; +use crate::ext::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedParseResult}; use crate::ext::mbe::transcribe::transcribe; use crate::feature_gate::Features; use crate::parse::parser::Parser; @@ -1171,3 +1171,16 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { ), } } + +impl TokenTree { + /// Use this token tree as a matcher to parse given tts. + fn parse(cx: &ExtCtxt<'_>, mtch: &[mbe::TokenTree], tts: TokenStream) + -> NamedParseResult { + // `None` is because we're not interpolating + let directory = Directory { + path: Cow::from(cx.current_expansion.module.directory.as_path()), + ownership: cx.current_expansion.directory_ownership, + }; + parse(cx.parse_sess(), tts, mtch, Some(directory), true) + } +} diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index fd87f8a1f678a..26cae2a8e7c42 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -13,9 +13,6 @@ //! and a borrowed `TokenStream` is sufficient to build an owned `TokenStream` without taking //! ownership of the original. -use crate::ext::base; -use crate::ext::mbe::{self, macro_parser}; -use crate::parse::Directory; use crate::parse::token::{self, DelimToken, Token, TokenKind}; use crate::print::pprust; @@ -26,7 +23,6 @@ use rustc_data_structures::sync::Lrc; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use smallvec::{SmallVec, smallvec}; -use std::borrow::Cow; use std::{fmt, iter, mem}; #[cfg(test)] @@ -63,17 +59,6 @@ where {} impl TokenTree { - /// Use this token tree as a matcher to parse given tts. - crate fn parse(cx: &base::ExtCtxt<'_>, mtch: &[mbe::TokenTree], tts: TokenStream) - -> macro_parser::NamedParseResult { - // `None` is because we're not interpolating - let directory = Directory { - path: Cow::from(cx.current_expansion.module.directory.as_path()), - ownership: cx.current_expansion.directory_ownership, - }; - macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory), true) - } - /// Checks if this TokenTree is equal to the other, regardless of span information. pub fn eq_unspanned(&self, other: &TokenTree) -> bool { match (self, other) { From 81fe85710d7f749c87494c4b968861adc67a9c4a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Sep 2019 19:42:52 +0300 Subject: [PATCH 24/31] make mbe::TokenTree private to module --- src/libsyntax/ext/mbe.rs | 44 +++++++++++++-------------- src/libsyntax/ext/mbe/macro_check.rs | 2 +- src/libsyntax/ext/mbe/macro_parser.rs | 4 +-- src/libsyntax/ext/mbe/quoted.rs | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/libsyntax/ext/mbe.rs b/src/libsyntax/ext/mbe.rs index c18b8918ff1e3..a87da791c9b4f 100644 --- a/src/libsyntax/ext/mbe.rs +++ b/src/libsyntax/ext/mbe.rs @@ -20,14 +20,14 @@ use rustc_data_structures::sync::Lrc; /// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note /// that the delimiter itself might be `NoDelim`. #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] -crate struct Delimited { - crate delim: token::DelimToken, - crate tts: Vec, +struct Delimited { + delim: token::DelimToken, + tts: Vec, } impl Delimited { /// Returns a `self::TokenTree` with a `Span` corresponding to the opening delimiter. - crate fn open_tt(&self, span: Span) -> TokenTree { + fn open_tt(&self, span: Span) -> TokenTree { let open_span = if span.is_dummy() { span } else { @@ -37,7 +37,7 @@ impl Delimited { } /// Returns a `self::TokenTree` with a `Span` corresponding to the closing delimiter. - crate fn close_tt(&self, span: Span) -> TokenTree { + fn close_tt(&self, span: Span) -> TokenTree { let close_span = if span.is_dummy() { span } else { @@ -48,25 +48,25 @@ impl Delimited { } #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] -crate struct SequenceRepetition { +struct SequenceRepetition { /// The sequence of token trees - crate tts: Vec, + tts: Vec, /// The optional separator - crate separator: Option, + separator: Option, /// Whether the sequence can be repeated zero (*), or one or more times (+) - crate kleene: KleeneToken, + kleene: KleeneToken, /// The number of `Match`s that appear in the sequence (and subsequences) - crate num_captures: usize, + num_captures: usize, } #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] -crate struct KleeneToken { - crate span: Span, - crate op: KleeneOp, +struct KleeneToken { + span: Span, + op: KleeneOp, } impl KleeneToken { - crate fn new(op: KleeneOp, span: Span) -> KleeneToken { + fn new(op: KleeneOp, span: Span) -> KleeneToken { KleeneToken { span, op } } } @@ -74,7 +74,7 @@ impl KleeneToken { /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star) /// for token sequences. #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -crate enum KleeneOp { +enum KleeneOp { /// Kleene star (`*`) for zero or more repetitions ZeroOrMore, /// Kleene plus (`+`) for one or more repetitions @@ -86,7 +86,7 @@ crate enum KleeneOp { /// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)` /// are "first-class" token trees. Useful for parsing macros. #[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)] -crate enum TokenTree { +enum TokenTree { Token(Token), Delimited(DelimSpan, Lrc), /// A kleene-style repetition sequence @@ -103,7 +103,7 @@ crate enum TokenTree { impl TokenTree { /// Return the number of tokens in the tree. - crate fn len(&self) -> usize { + fn len(&self) -> usize { match *self { TokenTree::Delimited(_, ref delimed) => match delimed.delim { token::NoDelim => delimed.tts.len(), @@ -115,7 +115,7 @@ impl TokenTree { } /// Returns `true` if the given token tree is delimited. - crate fn is_delimited(&self) -> bool { + fn is_delimited(&self) -> bool { match *self { TokenTree::Delimited(..) => true, _ => false, @@ -123,7 +123,7 @@ impl TokenTree { } /// Returns `true` if the given token tree is a token of the given kind. - crate fn is_token(&self, expected_kind: &TokenKind) -> bool { + fn is_token(&self, expected_kind: &TokenKind) -> bool { match self { TokenTree::Token(Token { kind: actual_kind, .. }) => actual_kind == expected_kind, _ => false, @@ -131,7 +131,7 @@ impl TokenTree { } /// Gets the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences. - crate fn get_tt(&self, index: usize) -> TokenTree { + fn get_tt(&self, index: usize) -> TokenTree { match (self, index) { (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => { delimed.tts[index].clone() @@ -151,7 +151,7 @@ impl TokenTree { } /// Retrieves the `TokenTree`'s span. - crate fn span(&self) -> Span { + fn span(&self) -> Span { match *self { TokenTree::Token(Token { span, .. }) | TokenTree::MetaVar(span, _) @@ -160,7 +160,7 @@ impl TokenTree { } } - crate fn token(kind: TokenKind, span: Span) -> TokenTree { + fn token(kind: TokenKind, span: Span) -> TokenTree { TokenTree::Token(Token::new(kind, span)) } } diff --git a/src/libsyntax/ext/mbe/macro_check.rs b/src/libsyntax/ext/mbe/macro_check.rs index a3750e5c46945..97074f5cbe46c 100644 --- a/src/libsyntax/ext/mbe/macro_check.rs +++ b/src/libsyntax/ext/mbe/macro_check.rs @@ -196,7 +196,7 @@ struct MacroState<'a> { /// - `node_id` is used to emit lints /// - `span` is used when no spans are available /// - `lhses` and `rhses` should have the same length and represent the macro definition -crate fn check_meta_variables( +pub(super) fn check_meta_variables( sess: &ParseSess, node_id: NodeId, span: Span, diff --git a/src/libsyntax/ext/mbe/macro_parser.rs b/src/libsyntax/ext/mbe/macro_parser.rs index 35fc6cf21b80e..b51384d3b15e1 100644 --- a/src/libsyntax/ext/mbe/macro_parser.rs +++ b/src/libsyntax/ext/mbe/macro_parser.rs @@ -282,7 +282,7 @@ crate enum ParseResult { crate type NamedParseResult = ParseResult>; /// Count how many metavars are named in the given matcher `ms`. -crate fn count_names(ms: &[TokenTree]) -> usize { +pub(super) fn count_names(ms: &[TokenTree]) -> usize { ms.iter().fold(0, |count, elt| { count + match *elt { TokenTree::Sequence(_, ref seq) => seq.num_captures, @@ -648,7 +648,7 @@ fn inner_parse_loop<'root, 'tt>( /// - `directory`: Information about the file locations (needed for the black-box parser) /// - `recurse_into_modules`: Whether or not to recurse into modules (needed for the black-box /// parser) -crate fn parse( +pub(super) fn parse( sess: &ParseSess, tts: TokenStream, ms: &[TokenTree], diff --git a/src/libsyntax/ext/mbe/quoted.rs b/src/libsyntax/ext/mbe/quoted.rs index 82289d7449d36..3952e29a5f0d1 100644 --- a/src/libsyntax/ext/mbe/quoted.rs +++ b/src/libsyntax/ext/mbe/quoted.rs @@ -35,7 +35,7 @@ use std::iter::Peekable; /// # Returns /// /// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`. -crate fn parse( +pub(super) fn parse( input: tokenstream::TokenStream, expect_matchers: bool, sess: &ParseSess, From 4ea371e40bfff6254f66c9b35510be09de5db1e6 Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Mon, 23 Sep 2019 11:57:07 +1000 Subject: [PATCH 25/31] Delete iter-order-by.md --- src/doc/unstable-book/src/iter-order-by.md | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 src/doc/unstable-book/src/iter-order-by.md diff --git a/src/doc/unstable-book/src/iter-order-by.md b/src/doc/unstable-book/src/iter-order-by.md deleted file mode 100644 index 1ed97872c881c..0000000000000 --- a/src/doc/unstable-book/src/iter-order-by.md +++ /dev/null @@ -1,9 +0,0 @@ -# `iter_order_by` - -The tracking issue for this feature is: [#64295] - -[#64295]: https://github.com/rust-lang/rust/issues/64295 - ------------------------- - -Add `cmp_by`, `partial_cmp_by` and `eq_by` methods to `Iterator` in the same vein as `max_by` and `min_by`. From 0423c2a7a35ce17b44b4c93c227177fc0fcd7217 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Thu, 19 Sep 2019 22:24:06 +0900 Subject: [PATCH 26/31] Remove unused dependencies --- Cargo.lock | 13 ------------- src/librustc_ast_borrowck/Cargo.toml | 2 -- src/librustc_codegen_ssa/Cargo.toml | 1 - src/librustc_codegen_utils/Cargo.toml | 1 - src/librustc_mir/Cargo.toml | 1 - src/librustc_plugin/Cargo.toml | 1 - src/librustc_resolve/Cargo.toml | 1 - src/librustc_save_analysis/Cargo.toml | 1 - src/librustc_traits/Cargo.toml | 2 -- src/libstd/Cargo.toml | 3 --- src/libsyntax/Cargo.toml | 1 - src/libsyntax_ext/Cargo.toml | 1 - 12 files changed, 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa749e5e3aebe..5b446c517c915 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3325,8 +3325,6 @@ dependencies = [ "log", "rustc", "rustc_data_structures", - "rustc_errors", - "syntax", "syntax_pos", ] @@ -3348,7 +3346,6 @@ dependencies = [ "log", "memmap", "num_cpus", - "parking_lot 0.9.0", "rustc", "rustc_apfloat", "rustc_codegen_utils", @@ -3367,7 +3364,6 @@ dependencies = [ name = "rustc_codegen_utils" version = "0.0.0" dependencies = [ - "flate2", "log", "punycode", "rustc", @@ -3562,7 +3558,6 @@ name = "rustc_mir" version = "0.0.0" dependencies = [ "arena", - "byteorder", "either", "graphviz", "log", @@ -3615,7 +3610,6 @@ name = "rustc_plugin_impl" version = "0.0.0" dependencies = [ "rustc", - "rustc_errors", "rustc_metadata", "syntax", "syntax_pos", @@ -3639,7 +3633,6 @@ version = "0.0.0" dependencies = [ "arena", "bitflags", - "indexmap", "log", "rustc", "rustc_data_structures", @@ -3661,7 +3654,6 @@ dependencies = [ "rustc_codegen_utils", "rustc_data_structures", "rustc_target", - "rustc_typeck", "serde_json", "syntax", "syntax_pos", @@ -3692,9 +3684,7 @@ checksum = "b725dadae9fabc488df69a287f5a99c5eaf5d10853842a8a3dfac52476f544ee" name = "rustc_traits" version = "0.0.0" dependencies = [ - "bitflags", "chalk-engine", - "graphviz", "log", "rustc", "rustc_data_structures", @@ -4057,7 +4047,6 @@ version = "0.0.0" dependencies = [ "alloc", "backtrace", - "cc", "cfg-if", "compiler_builtins", "core", @@ -4242,7 +4231,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_lexer", - "rustc_macros", "rustc_target", "scoped-tls", "serialize", @@ -4258,7 +4246,6 @@ dependencies = [ "log", "rustc_data_structures", "rustc_errors", - "rustc_lexer", "rustc_target", "smallvec", "syntax", diff --git a/src/librustc_ast_borrowck/Cargo.toml b/src/librustc_ast_borrowck/Cargo.toml index 024b2640e1e8e..40c4c1fc3fee6 100644 --- a/src/librustc_ast_borrowck/Cargo.toml +++ b/src/librustc_ast_borrowck/Cargo.toml @@ -12,11 +12,9 @@ doctest = false [dependencies] log = "0.4" -syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } # for "clarity", rename the graphviz crate to dot; graphviz within `borrowck` # refers to the borrowck-specific graphviz adapter traits. dot = { path = "../libgraphviz", package = "graphviz" } rustc = { path = "../librustc" } -errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index bc028d6624279..2e3666e609657 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -17,7 +17,6 @@ memmap = "0.6" log = "0.4.5" libc = "0.2.44" jobserver = "0.1.11" -parking_lot = "0.9" tempfile = "3.1" rustc_serialize = { path = "../libserialize", package = "serialize" } diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml index 89b50c5daccae..c8c219d039a73 100644 --- a/src/librustc_codegen_utils/Cargo.toml +++ b/src/librustc_codegen_utils/Cargo.toml @@ -10,7 +10,6 @@ path = "lib.rs" test = false [dependencies] -flate2 = "1.0" log = "0.4" punycode = "0.4.0" rustc-demangle = "0.1.16" diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 0691390bead4b..f296753a0304c 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -24,6 +24,5 @@ rustc_lexer = { path = "../librustc_lexer" } rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -byteorder = { version = "1.3" } rustc_apfloat = { path = "../librustc_apfloat" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/librustc_plugin/Cargo.toml b/src/librustc_plugin/Cargo.toml index 84a743ed1ad7d..3f11430dc82cb 100644 --- a/src/librustc_plugin/Cargo.toml +++ b/src/librustc_plugin/Cargo.toml @@ -15,4 +15,3 @@ rustc = { path = "../librustc" } rustc_metadata = { path = "../librustc_metadata" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 548f982fe3bf0..936e72ef2c571 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -12,7 +12,6 @@ doctest = false [dependencies] bitflags = "1.0" -indexmap = "1" log = "0.4" syntax = { path = "../libsyntax" } rustc = { path = "../librustc" } diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index 88bb76d2aba3a..b89c83d630b7d 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -14,7 +14,6 @@ rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_target = { path = "../librustc_target" } -rustc_typeck = { path = "../librustc_typeck" } serde_json = "1" syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index bb28ac839a544..b86a3a5e9639b 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -9,8 +9,6 @@ name = "rustc_traits" path = "lib.rs" [dependencies] -bitflags = "1.0" -graphviz = { path = "../libgraphviz" } log = { version = "0.4" } rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index af1d2402f88e7..ee4b367b5c5b9 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -53,9 +53,6 @@ fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] } [target.wasm32-wasi.dependencies] wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] } -[build-dependencies] -cc = "1.0" - [features] default = ["std_detect_file_io", "std_detect_dlsym_getauxval"] diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index d4a9acc1569b4..196cf4d9dfae8 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -19,6 +19,5 @@ syntax_pos = { path = "../libsyntax_pos" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_lexer = { path = "../librustc_lexer" } -rustc_macros = { path = "../librustc_macros" } rustc_target = { path = "../librustc_target" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml index 791ee94b4fa77..73310df305b32 100644 --- a/src/libsyntax_ext/Cargo.toml +++ b/src/libsyntax_ext/Cargo.toml @@ -18,4 +18,3 @@ rustc_target = { path = "../librustc_target" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rustc_lexer = { path = "../librustc_lexer" } From 2666ae5caa1b07d0b611995f5d137e86bdaa31bc Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Mon, 23 Sep 2019 21:29:12 +0200 Subject: [PATCH 27/31] Remove whitespace from testname --- ...gn.rs => impl[t]-foreign[local,fundamental[t]]-for-foreign.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/coherence/{impl[t]-foreign[local, fundamental[t]]-for-foreign.rs => impl[t]-foreign[local,fundamental[t]]-for-foreign.rs} (100%) diff --git a/src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local,fundamental[t]]-for-foreign.rs similarity index 100% rename from src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs rename to src/test/ui/coherence/impl[t]-foreign[local,fundamental[t]]-for-foreign.rs From 8acf95886b6d045a5069b3a0c2c5f0fc29b1dc35 Mon Sep 17 00:00:00 2001 From: Andrew Banchich Date: Mon, 23 Sep 2019 16:09:36 -0400 Subject: [PATCH 28/31] update test Use assert_eq and assert_ne over comparison operators. --- src/libcore/mem/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index 87ec05a243d36..8767625d4ed37 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -818,9 +818,9 @@ impl fmt::Debug for Discriminant { /// /// enum Foo { A(&'static str), B(i32), C(i32) } /// -/// assert!(mem::discriminant(&Foo::A("bar")) == mem::discriminant(&Foo::A("baz"))); -/// assert!(mem::discriminant(&Foo::B(1)) == mem::discriminant(&Foo::B(2))); -/// assert!(mem::discriminant(&Foo::B(3)) != mem::discriminant(&Foo::C(3))); +/// assert_eq!(mem::discriminant(&Foo::A("bar")), mem::discriminant(&Foo::A("baz"))); +/// assert_eq!(mem::discriminant(&Foo::B(1)), mem::discriminant(&Foo::B(2))); +/// assert_ne!(mem::discriminant(&Foo::B(3)), mem::discriminant(&Foo::C(3))); /// ``` #[stable(feature = "discriminant_value", since = "1.21.0")] pub fn discriminant(v: &T) -> Discriminant { From 4fd9b9944f52afa948288c96c9860709c9f82231 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 18 Sep 2019 14:35:56 -0700 Subject: [PATCH 29/31] Add cycle detection for graphs --- .../graph/iterate/mod.rs | 204 +++++++++++++++++- .../graph/iterate/tests.rs | 11 + src/librustc_data_structures/graph/mod.rs | 10 + 3 files changed, 224 insertions(+), 1 deletion(-) diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/src/librustc_data_structures/graph/iterate/mod.rs index c4185fc7cd9c3..cbf6a0a3c03a0 100644 --- a/src/librustc_data_structures/graph/iterate/mod.rs +++ b/src/librustc_data_structures/graph/iterate/mod.rs @@ -1,5 +1,5 @@ use super::super::indexed_vec::IndexVec; -use super::{DirectedGraph, WithNumNodes, WithSuccessors}; +use super::{DirectedGraph, WithNumNodes, WithSuccessors, WithStartNode}; use crate::bit_set::BitSet; #[cfg(test)] @@ -85,3 +85,205 @@ where Some(n) } } + +/// Allows searches to terminate early with a value. +#[derive(Clone, Copy, Debug)] +pub enum ControlFlow { + Break(T), + Continue, +} + +/// The status of a node in the depth-first search. +/// +/// See the documentation of `TriColorDepthFirstSearch` to see how a node's status is updated +/// during DFS. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum NodeStatus { + /// This node has been examined by the depth-first search but is not yet `Settled`. + /// + /// Also referred to as "gray" or "discovered" nodes in [CLR][]. + /// + /// [CLR]: https://en.wikipedia.org/wiki/Introduction_to_Algorithms + Visited, + + /// This node and all nodes reachable from it have been examined by the depth-first search. + /// + /// Also referred to as "black" or "finished" nodes in [CLR][]. + /// + /// [CLR]: https://en.wikipedia.org/wiki/Introduction_to_Algorithms + Settled, +} + +struct Event { + node: N, + becomes: NodeStatus, +} + +/// A depth-first search that also tracks when all successors of a node have been examined. +/// +/// This is based on the DFS described in [Introduction to Algorithms (1st ed.)][CLR], hereby +/// referred to as **CLR**. However, we use the terminology in [`NodeStatus`][] above instead of +/// "discovered"/"finished" or "white"/"grey"/"black". Each node begins the search with no status, +/// becomes `Visited` when it is first examined by the DFS and is `Settled` when all nodes +/// reachable from it have been examined. This allows us to differentiate between "tree", "back" +/// and "forward" edges (see [`TriColorVisitor::node_examined`]). +/// +/// Unlike the pseudocode in [CLR][], this implementation is iterative and does not use timestamps. +/// We accomplish this by storing `Event`s on the stack that result in a (possible) state change +/// for each node. A `Visited` event signifies that we should examine this node if it has not yet +/// been `Visited` or `Settled`. When a node is examined for the first time, we mark it as +/// `Visited` and push a `Settled` event for it on stack followed by `Visited` events for all of +/// its predecessors, scheduling them for examination. Multiple `Visited` events for a single node +/// may exist on the stack simultaneously if a node has multiple predecessors, but only one +/// `Settled` event will ever be created for each node. After all `Visited` events for a node's +/// successors have been popped off the stack (as well as any new events triggered by visiting +/// those successors), we will pop off that node's `Settled` event. +/// +/// [CLR]: https://en.wikipedia.org/wiki/Introduction_to_Algorithms +/// [`NodeStatus`]: ./enum.NodeStatus.html +/// [`TriColorVisitor::node_examined`]: ./trait.TriColorVisitor.html#method.node_examined +pub struct TriColorDepthFirstSearch<'graph, G> +where + G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors, +{ + graph: &'graph G, + stack: Vec>, + visited: BitSet, + settled: BitSet, +} + +impl TriColorDepthFirstSearch<'graph, G> +where + G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors, +{ + pub fn new(graph: &'graph G) -> Self { + TriColorDepthFirstSearch { + graph, + stack: vec![], + visited: BitSet::new_empty(graph.num_nodes()), + settled: BitSet::new_empty(graph.num_nodes()), + } + } + + /// Performs a depth-first search, starting from the given `root`. + /// + /// This won't visit nodes that are not reachable from `root`. + pub fn run_from(mut self, root: G::Node, visitor: &mut V) -> Option + where + V: TriColorVisitor, + { + use NodeStatus::{Visited, Settled}; + + self.stack.push(Event { node: root, becomes: Visited }); + + loop { + match self.stack.pop()? { + Event { node, becomes: Settled } => { + let not_previously_settled = self.settled.insert(node); + assert!(not_previously_settled, "A node should be settled exactly once"); + if let ControlFlow::Break(val) = visitor.node_settled(node) { + return Some(val); + } + } + + Event { node, becomes: Visited } => { + let not_previously_visited = self.visited.insert(node); + let prior_status = if not_previously_visited { + None + } else if self.settled.contains(node) { + Some(Settled) + } else { + Some(Visited) + }; + + if let ControlFlow::Break(val) = visitor.node_examined(node, prior_status) { + return Some(val); + } + + // If this node has already been examined, we are done. + if prior_status.is_some() { + continue; + } + + // Otherwise, push a `Settled` event for this node onto the stack, then + // schedule its successors for examination. + self.stack.push(Event { node, becomes: Settled }); + for succ in self.graph.successors(node) { + self.stack.push(Event { node: succ, becomes: Visited }); + } + } + } + } + } +} + +impl TriColorDepthFirstSearch<'graph, G> +where + G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors + WithStartNode, +{ + /// Performs a depth-first search, starting from `G::start_node()`. + /// + /// This won't visit nodes that are not reachable from the start node. + pub fn run_from_start(self, visitor: &mut V) -> Option + where + V: TriColorVisitor, + { + let root = self.graph.start_node(); + self.run_from(root, visitor) + } +} + +/// What to do when a node is examined or becomes `Settled` during DFS. +pub trait TriColorVisitor +where + G: ?Sized + DirectedGraph, +{ + /// The value returned by this search. + type BreakVal; + + /// Called when a node is examined by the depth-first search. + /// + /// By checking the value of `prior_status`, this visitor can determine whether the edge + /// leading to this node was a tree edge (`None`), forward edge (`Some(Settled)`) or back edge + /// (`Some(Visited)`). For a full explanation of each edge type, see the "Depth-first Search" + /// chapter in [CLR][] or [wikipedia][]. + /// + /// If you want to know *both* nodes linked by each edge, you'll need to modify + /// `TriColorDepthFirstSearch` to store a `source` node for each `Visited` event. + /// + /// [wikipedia]: https://en.wikipedia.org/wiki/Depth-first_search#Output_of_a_depth-first_search + /// [CLR]: https://en.wikipedia.org/wiki/Introduction_to_Algorithms + fn node_examined( + &mut self, + _target: G::Node, + _prior_status: Option, + ) -> ControlFlow { + ControlFlow::Continue + } + + /// Called after all nodes reachable from this one have been examined. + fn node_settled(&mut self, _target: G::Node) -> ControlFlow { + ControlFlow::Continue + } +} + +/// This `TriColorVisitor` looks for back edges in a graph, which indicate that a cycle exists. +pub struct CycleDetector; + +impl TriColorVisitor for CycleDetector +where + G: ?Sized + DirectedGraph, +{ + type BreakVal = (); + + fn node_examined( + &mut self, + _node: G::Node, + prior_status: Option, + ) -> ControlFlow { + match prior_status { + Some(NodeStatus::Visited) => ControlFlow::Break(()), + _ => ControlFlow::Continue, + } + } +} diff --git a/src/librustc_data_structures/graph/iterate/tests.rs b/src/librustc_data_structures/graph/iterate/tests.rs index 6c7cfd6d8a777..0e038e88b221d 100644 --- a/src/librustc_data_structures/graph/iterate/tests.rs +++ b/src/librustc_data_structures/graph/iterate/tests.rs @@ -9,3 +9,14 @@ fn diamond_post_order() { let result = post_order_from(&graph, 0); assert_eq!(result, vec![3, 1, 2, 0]); } + +#[test] +fn is_cyclic() { + use super::super::is_cyclic; + + let diamond_acyclic = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3)]); + let diamond_cyclic = TestGraph::new(0, &[(0, 1), (1, 2), (2, 3), (3, 0)]); + + assert!(!is_cyclic(&diamond_acyclic)); + assert!(is_cyclic(&diamond_cyclic)); +} diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 662581ca1e498..0a607659f3e24 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -81,3 +81,13 @@ where + WithNumNodes, { } + +/// Returns `true` if the graph has a cycle that is reachable from the start node. +pub fn is_cyclic(graph: &G) -> bool +where + G: ?Sized + DirectedGraph + WithStartNode + WithSuccessors + WithNumNodes, +{ + iterate::TriColorDepthFirstSearch::new(graph) + .run_from_start(&mut iterate::CycleDetector) + .is_some() +} From c9e4816fe319b2fde83779ff375037c8079d36a2 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 18 Sep 2019 14:53:55 -0700 Subject: [PATCH 30/31] Add convenience function for detecting cyclic CFGs --- src/librustc/mir/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 0ebc70750a6bb..5206e044f9fa5 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -262,6 +262,12 @@ impl<'tcx> Body<'tcx> { dominators(self) } + /// Returns `true` if a cycle exists in the control-flow graph that is reachable from the + /// `START_BLOCK`. + pub fn is_cfg_cyclic(&self) -> bool { + graph::is_cyclic(self) + } + #[inline] pub fn local_kind(&self, local: Local) -> LocalKind { let index = local.as_usize(); From 5aa5d5780839cda5a7fde2cf434a630b98cd485b Mon Sep 17 00:00:00 2001 From: Guanqun Lu Date: Tue, 24 Sep 2019 10:29:09 +0800 Subject: [PATCH 31/31] fix one typo --- src/librustc_typeck/check/method/suggest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 74e4f28255b16..4c681544978e5 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -232,7 +232,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut err = if !actual.references_error() { // Suggest clamping down the type if the method that is being attempted to - // be used exists at all, and the type is an ambiuous numeric type + // be used exists at all, and the type is an ambiguous numeric type // ({integer}/{float}). let mut candidates = all_traits(self.tcx) .into_iter()