From 187aea7c34adf06b0db39f688d60d3fdac8e7e3e Mon Sep 17 00:00:00 2001 From: Caio Date: Tue, 9 Jun 2020 23:10:55 -0300 Subject: [PATCH 01/17] Impl Default for ranges --- src/libcore/ops/range.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index d86f39c4550c8..7422e5d720b4c 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -39,7 +39,7 @@ use crate::hash::Hash; /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html #[doc(alias = "..")] -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFull; @@ -71,7 +71,7 @@ impl fmt::Debug for RangeFull { /// assert_eq!(arr[1..=3], [ 1,2,3 ]); /// ``` #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { /// The lower bound of the range (inclusive). @@ -179,7 +179,7 @@ impl> Range { /// /// [`Iterator`]: ../iter/trait.IntoIterator.html #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { /// The lower bound of the range (inclusive). @@ -261,7 +261,7 @@ impl> RangeFrom { /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html #[doc(alias = "..")] -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeTo { /// The upper bound of the range (exclusive). @@ -329,7 +329,7 @@ impl> RangeTo { /// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive /// ``` #[doc(alias = "..=")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { // Note that the fields here are not public to allow changing the @@ -556,7 +556,7 @@ impl> RangeInclusive { /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html #[doc(alias = "..=")] -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeToInclusive { /// The upper bound of the range (inclusive) From c3756927478afe8d3a880edc469afd766c2f9e82 Mon Sep 17 00:00:00 2001 From: Caio Date: Fri, 10 Jul 2020 07:44:27 -0300 Subject: [PATCH 02/17] Remove some Default impls --- src/libcore/ops/range.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 7422e5d720b4c..179038d1977c8 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -179,7 +179,7 @@ impl> Range { /// /// [`Iterator`]: ../iter/trait.IntoIterator.html #[doc(alias = "..")] -#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { /// The lower bound of the range (inclusive). @@ -261,7 +261,7 @@ impl> RangeFrom { /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html #[doc(alias = "..")] -#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeTo { /// The upper bound of the range (exclusive). @@ -329,7 +329,7 @@ impl> RangeTo { /// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive /// ``` #[doc(alias = "..=")] -#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { // Note that the fields here are not public to allow changing the @@ -556,7 +556,7 @@ impl> RangeInclusive { /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html #[doc(alias = "..=")] -#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeToInclusive { /// The upper bound of the range (inclusive) From a11024f4f312a49db84d816bf43c7c55d8a21074 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 29 May 2020 08:27:59 +0900 Subject: [PATCH 03/17] Fix debug assertion in typeck --- src/librustc_typeck/collect.rs | 2 +- src/test/ui/traits/issue-72410.rs | 18 ++++++++++++++++++ src/test/ui/traits/issue-72410.stderr | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/traits/issue-72410.rs create mode 100644 src/test/ui/traits/issue-72410.stderr diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ec534aa925d4f..c3b54f1461426 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1927,7 +1927,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat let re_root_empty = tcx.lifetimes.re_root_empty; let predicate = ty::OutlivesPredicate(ty, re_root_empty); predicates.push(( - ty::PredicateKind::TypeOutlives(ty::Binder::dummy(predicate)) + ty::PredicateKind::TypeOutlives(ty::Binder::bind(predicate)) .to_predicate(tcx), span, )); diff --git a/src/test/ui/traits/issue-72410.rs b/src/test/ui/traits/issue-72410.rs new file mode 100644 index 0000000000000..c95f1dfdca53a --- /dev/null +++ b/src/test/ui/traits/issue-72410.rs @@ -0,0 +1,18 @@ +// Regression test for #72410, this should be used with debug assertion enabled. + +// should be fine +pub trait Foo { + fn map() + where + Self: Sized, + for<'a> &'a mut [u8]: ; +} + +// should fail +pub trait Bar { + fn map() + where for<'a> &'a mut [dyn Bar]: ; + //~^ ERROR: the trait `Bar` cannot be made into an object +} + +fn main() {} diff --git a/src/test/ui/traits/issue-72410.stderr b/src/test/ui/traits/issue-72410.stderr new file mode 100644 index 0000000000000..1db2320841ff7 --- /dev/null +++ b/src/test/ui/traits/issue-72410.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/issue-72410.rs:14:19 + | +LL | pub trait Bar { + | --- this trait cannot be made into an object... +LL | fn map() + | --- ...because associated function `map` has no `self` parameter +LL | where for<'a> &'a mut [dyn Bar]: ; + | ^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | +help: consider turning `map` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | where for<'a> &'a mut [dyn Bar]:, Self: Sized ; + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. From e8d16fdf9f95e4110df53650779be842b6749f60 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 18 Jul 2020 19:22:12 +0200 Subject: [PATCH 04/17] add note to `opt_const_param_of` --- src/librustc_middle/query/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 40ff25cf3b134..06136a82e7b46 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -103,9 +103,13 @@ rustc_queries! { /// // ^ While calling `opt_const_param_of` for other bodies returns `None`. /// } /// ``` + // It looks like caching this query on disk actually slightly + // worsened performance in #74376. + // + // Once const generics are more prevalently used, we might want to + // consider only caching calls returning `Some`. query opt_const_param_of(key: LocalDefId) -> Option { desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) } - // FIXME(#74113): consider storing this query on disk. } /// Records the type of every item. From 174abeb6cb9553bae0a59fbf0aba186da300d390 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 19 Jul 2020 04:31:01 +0000 Subject: [PATCH 05/17] Add an border around the Run button --- src/librustdoc/html/static/themes/ayu.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index e0ab7170ea877..09ee9b4b5052f 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -318,6 +318,7 @@ a.test-arrow { font-size: 100%; color: #788797; border-radius: 4px; + box-shadow: 0 0 0 1px #424c57,0 0 0 2px transparent; background-color: rgba(255, 255, 255, 0); } From dec70767e533a4603baafb4c209ac3b90bba79f7 Mon Sep 17 00:00:00 2001 From: Jarek Samic Date: Sun, 19 Jul 2020 02:00:10 -0400 Subject: [PATCH 06/17] Fix search input focus in ayu theme --- src/librustdoc/html/static/themes/ayu.css | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index e0ab7170ea877..c9d46e872f5b5 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -237,16 +237,6 @@ a { #crate-search+.search-input:focus { box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent; - color: #ffffff; - background-color: #141920; - box-shadow: none; - transition: box-shadow 150ms ease-in-out; - border-radius: 4px; - margin-left: 8px; -} - -#crate-search+.search-input:focus { - box-shadow: 0px 6px 20px 0px black; } .search-focus:disabled { From 0eff3d5d886a2290b4557a4438efe8a6aa6cfba7 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 19 Jul 2020 09:09:06 +0000 Subject: [PATCH 07/17] Ayu: use different background color to make Run button easy-to-spot Co-authored-by: Cldfire --- src/librustdoc/html/static/themes/ayu.css | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index 09ee9b4b5052f..6acf4e3e1c080 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -318,13 +318,12 @@ a.test-arrow { font-size: 100%; color: #788797; border-radius: 4px; - box-shadow: 0 0 0 1px #424c57,0 0 0 2px transparent; - background-color: rgba(255, 255, 255, 0); + background-color: rgba(57, 175, 215, 0.09); } a.test-arrow:hover { - background-color: rgba(242, 151, 24, 0.05); - color: #ffb44c; + background-color: rgba(57, 175, 215, 0.368); + color: #c5c5c5; } .toggle-label { From 251878ebc4a86b3f9c94992d89c42d3a0a60cf68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 18 Jul 2020 00:00:00 +0000 Subject: [PATCH 08/17] Remove CC & CFLAGS from MemorySanitizer example They are now unnecessary for projects written in Rust, since backtrace-rs used by the standard library has only Rust dependencies. --- src/doc/unstable-book/src/compiler-flags/sanitizer.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 5e2e04c063bc4..c15f339783f7e 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -196,10 +196,6 @@ fn main() { ```shell $ export \ - CC=clang \ - CXX=clang++ \ - CFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \ - CXXFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \ RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' \ RUSTDOCFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' $ cargo clean From 58b862072c97c17133f3b700b71edf69ce0a7efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 18 Jul 2020 00:00:00 +0000 Subject: [PATCH 09/17] Document AddressSanitizer memory leak detection defaults --- src/doc/unstable-book/src/compiler-flags/sanitizer.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index c15f339783f7e..93908e9190e64 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -26,6 +26,9 @@ of bugs: * Double-free, invalid free * Memory leaks +The memory leak detection is enabled by default on Linux, and can be enabled +with runtime flag `ASAN_OPTIONS=detect_leaks=1` on macOS. + AddressSanitizer is supported on the following targets: * `x86_64-apple-darwin` From 69d5dd6a5023a21ae755381f28f8450227be6daf Mon Sep 17 00:00:00 2001 From: Gabriel Smith Date: Sat, 4 Jul 2020 23:43:48 -0400 Subject: [PATCH 10/17] disallow non-static lifetimes in const generics This has been put in place to patch over an ICE caused when we encounter a non-static lifetime in a const generic during borrow checking. This restriction may be relaxed in the future, but we need more discussion before then, and in the meantime we should still deal with this ICE. Fixes issue #60814 --- src/librustc_error_codes/error_codes.rs | 1 + src/librustc_error_codes/error_codes/E0771.md | 23 +++++++++++++++++++ src/librustc_resolve/late/diagnostics.rs | 18 +++++++++++++++ src/librustc_resolve/late/lifetimes.rs | 11 +++++++++ src/test/ui/error-codes/E0771.rs | 8 +++++++ src/test/ui/error-codes/E0771.stderr | 20 ++++++++++++++++ 6 files changed, 81 insertions(+) create mode 100644 src/librustc_error_codes/error_codes/E0771.md create mode 100644 src/test/ui/error-codes/E0771.rs create mode 100644 src/test/ui/error-codes/E0771.stderr diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index bbbd8359f0126..279c65ce03d2d 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -453,6 +453,7 @@ E0767: include_str!("./error_codes/E0767.md"), E0768: include_str!("./error_codes/E0768.md"), E0769: include_str!("./error_codes/E0769.md"), E0770: include_str!("./error_codes/E0770.md"), +E0771: include_str!("./error_codes/E0771.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0771.md b/src/librustc_error_codes/error_codes/E0771.md new file mode 100644 index 0000000000000..824a955f6b3f4 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0771.md @@ -0,0 +1,23 @@ +A non-`'static` lifetime was used in a const generic. This is currently not +allowed. + +Erroneous code example: + +```compile_fail,E0771 +#![feature(const_generics)] + +fn function_with_str<'a, const STRING: &'a str>() {} // error! +``` + +To fix this issue, the lifetime in the const generic need to be changed to +`'static`: + +``` +#![feature(const_generics)] + +fn function_with_str() {} // ok! +``` + +For more information, see [GitHub issue #74052]. + +[GitHub issue #74052]: https://github.com/rust-lang/rust/issues/74052 diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 9323c15a94109..c86b414184759 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -1141,6 +1141,24 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { err.emit(); } + // FIXME(const_generics): This patches over a ICE caused by non-'static lifetimes in const + // generics. We are disallowing this until we can decide on how we want to handle non-'static + // lifetimes in const generics. See issue #74052 for discussion. + crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &hir::Lifetime) { + let mut err = struct_span_err!( + self.tcx.sess, + lifetime_ref.span, + E0771, + "use of non-static lifetime `{}` in const generic", + lifetime_ref + ); + err.note( + "for more information, see issue #74052 \ + ", + ); + err.emit(); + } + crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res { if [ diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index 567db8edec9af..6009e48a54f5e 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -173,6 +173,8 @@ crate struct LifetimeContext<'a, 'tcx> { /// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax. is_in_fn_syntax: bool, + is_in_const_generic: bool, + /// List of labels in the function/method currently under analysis. labels_in_fn: Vec, @@ -333,6 +335,7 @@ fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap { scope: ROOT_SCOPE, trait_ref_hack: false, is_in_fn_syntax: false, + is_in_const_generic: false, labels_in_fn: vec![], xcrate_object_lifetime_defaults: Default::default(), lifetime_uses: &mut Default::default(), @@ -828,6 +831,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, Region::Static); return; } + if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error { + self.emit_non_static_lt_in_const_generic_error(lifetime_ref); + return; + } self.resolve_lifetime_ref(lifetime_ref); } @@ -860,8 +867,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } GenericParamKind::Const { ref ty, .. } => { + let was_in_const_generic = self.is_in_const_generic; + self.is_in_const_generic = true; walk_list!(self, visit_param_bound, param.bounds); self.visit_ty(&ty); + self.is_in_const_generic = was_in_const_generic; } } } @@ -1317,6 +1327,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope: &wrap_scope, trait_ref_hack: self.trait_ref_hack, is_in_fn_syntax: self.is_in_fn_syntax, + is_in_const_generic: self.is_in_const_generic, labels_in_fn, xcrate_object_lifetime_defaults, lifetime_uses, diff --git a/src/test/ui/error-codes/E0771.rs b/src/test/ui/error-codes/E0771.rs new file mode 100644 index 0000000000000..ba3592719408c --- /dev/null +++ b/src/test/ui/error-codes/E0771.rs @@ -0,0 +1,8 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete + +fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0771 + +fn main() { + function_with_str::<"Hello, world!">() +} diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr new file mode 100644 index 0000000000000..60220be6b57ba --- /dev/null +++ b/src/test/ui/error-codes/E0771.stderr @@ -0,0 +1,20 @@ +warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/E0771.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 for more information + +error[E0771]: use of non-static lifetime `'a` in const generic + --> $DIR/E0771.rs:4:41 + | +LL | fn function_with_str<'a, const STRING: &'a str>() {} + | ^^ + | + = note: for more information, see issue #74052 + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0771`. From c60a0356585d7b0378f50b129e7c7bcfa739f640 Mon Sep 17 00:00:00 2001 From: Gabriel Smith Date: Sun, 19 Jul 2020 12:53:51 -0400 Subject: [PATCH 11/17] Add test for an explicit non-'static lifetime in a const argument --- .../const-argument-non-static-lifetime.rs | 17 +++++++++++++++++ .../const-argument-non-static-lifetime.stderr | 11 +++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/ui/const-generics/const-argument-non-static-lifetime.rs create mode 100644 src/test/ui/const-generics/const-argument-non-static-lifetime.stderr diff --git a/src/test/ui/const-generics/const-argument-non-static-lifetime.rs b/src/test/ui/const-generics/const-argument-non-static-lifetime.rs new file mode 100644 index 0000000000000..bc09ba2ab553b --- /dev/null +++ b/src/test/ui/const-generics/const-argument-non-static-lifetime.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete +#![allow(dead_code)] + +fn test() {} + +fn wow<'a>() -> &'a () { + test::<{ + let _: &'a (); + 3 + }>(); + &() +} + +fn main() {} diff --git a/src/test/ui/const-generics/const-argument-non-static-lifetime.stderr b/src/test/ui/const-generics/const-argument-non-static-lifetime.stderr new file mode 100644 index 0000000000000..53a7550090d44 --- /dev/null +++ b/src/test/ui/const-generics/const-argument-non-static-lifetime.stderr @@ -0,0 +1,11 @@ +warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/const-argument-non-static-lifetime.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 for more information + +warning: 1 warning emitted + From ceac273e60447014038e511e5af43841c359547c Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 13 Jun 2020 19:37:25 +0100 Subject: [PATCH 12/17] wf: check foreign fn decls for well-formedness This commit extends current well-formedness checking to apply to foreign function declarations, re-using the existing machinery for regular functions. In doing this, later parts of the compiler (such as the `improper_ctypes` lint) can rely on being operations not failing as a result of invalid code which would normally be caught earlier. Signed-off-by: David Wood --- src/librustc_typeck/check/wfcheck.rs | 48 ++++++++------- src/test/ui/lint/lint-ctypes.rs | 3 +- src/test/ui/lint/lint-ctypes.stderr | 62 ++++++++++---------- src/test/ui/wf/wf-foreign-fn-decl-ret.rs | 18 ++++++ src/test/ui/wf/wf-foreign-fn-decl-ret.stderr | 18 ++++++ 5 files changed, 97 insertions(+), 52 deletions(-) create mode 100644 src/test/ui/wf/wf-foreign-fn-decl-ret.rs create mode 100644 src/test/ui/wf/wf-foreign-fn-decl-ret.stderr diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 845a4fcafc224..dabae6cbc4137 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; use rustc_session::parse::feature_err; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use rustc_trait_selection::opaque_types::may_define_opaque_type; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -142,8 +142,8 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) { _ => unreachable!(), } } - hir::ItemKind::Fn(..) => { - check_item_fn(tcx, item); + hir::ItemKind::Fn(ref sig, ..) => { + check_item_fn(tcx, item.hir_id, item.ident, item.span, sig.decl); } hir::ItemKind::Static(ref ty, ..) => { check_item_type(tcx, item.hir_id, ty.span, false); @@ -153,8 +153,14 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) { } hir::ItemKind::ForeignMod(ref module) => { for it in module.items.iter() { - if let hir::ForeignItemKind::Static(ref ty, ..) = it.kind { - check_item_type(tcx, it.hir_id, ty.span, true); + match it.kind { + hir::ForeignItemKind::Fn(ref decl, ..) => { + check_item_fn(tcx, it.hir_id, it.ident, it.span, decl) + } + hir::ForeignItemKind::Static(ref ty, ..) => { + check_item_type(tcx, it.hir_id, ty.span, true) + } + hir::ForeignItemKind::Type => (), } } } @@ -303,7 +309,7 @@ fn check_associated_item( fcx, item.ident.span, sig, - hir_sig, + hir_sig.decl, item.def_id, &mut implied_bounds, ); @@ -564,22 +570,24 @@ fn check_associated_type_defaults(fcx: &FnCtxt<'_, '_>, trait_def_id: DefId) { } } -fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { - for_item(tcx, item).with_fcx(|fcx, tcx| { - let def_id = fcx.tcx.hir().local_def_id(item.hir_id); +fn check_item_fn( + tcx: TyCtxt<'_>, + item_id: hir::HirId, + ident: Ident, + span: Span, + decl: &hir::FnDecl<'_>, +) { + for_id(tcx, item_id, span).with_fcx(|fcx, tcx| { + let def_id = fcx.tcx.hir().local_def_id(item_id); let sig = fcx.tcx.fn_sig(def_id); - let sig = fcx.normalize_associated_types_in(item.span, &sig); + let sig = fcx.normalize_associated_types_in(span, &sig); let mut implied_bounds = vec![]; - let hir_sig = match &item.kind { - ItemKind::Fn(sig, ..) => sig, - _ => bug!("expected `ItemKind::Fn`, found `{:?}`", item.kind), - }; check_fn_or_method( tcx, fcx, - item.ident.span, + ident.span, sig, - hir_sig, + decl, def_id.to_def_id(), &mut implied_bounds, ); @@ -835,28 +843,28 @@ fn check_fn_or_method<'fcx, 'tcx>( fcx: &FnCtxt<'fcx, 'tcx>, span: Span, sig: ty::PolyFnSig<'tcx>, - hir_sig: &hir::FnSig<'_>, + hir_decl: &hir::FnDecl<'_>, def_id: DefId, implied_bounds: &mut Vec>, ) { let sig = fcx.normalize_associated_types_in(span, &sig); let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); - for (&input_ty, span) in sig.inputs().iter().zip(hir_sig.decl.inputs.iter().map(|t| t.span)) { + for (&input_ty, span) in sig.inputs().iter().zip(hir_decl.inputs.iter().map(|t| t.span)) { fcx.register_wf_obligation(input_ty.into(), span, ObligationCauseCode::MiscObligation); } implied_bounds.extend(sig.inputs()); fcx.register_wf_obligation( sig.output().into(), - hir_sig.decl.output.span(), + hir_decl.output.span(), ObligationCauseCode::ReturnType, ); // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); - check_where_clauses(tcx, fcx, span, def_id, Some((sig.output(), hir_sig.decl.output.span()))); + check_where_clauses(tcx, fcx, span, def_id, Some((sig.output(), hir_decl.output.span()))); } /// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions diff --git a/src/test/ui/lint/lint-ctypes.rs b/src/test/ui/lint/lint-ctypes.rs index bdf95350c7045..f485766bcd34e 100644 --- a/src/test/ui/lint/lint-ctypes.rs +++ b/src/test/ui/lint/lint-ctypes.rs @@ -7,6 +7,7 @@ extern crate libc; use std::marker::PhantomData; +trait Bar { } trait Mirror { type It: ?Sized; } impl Mirror for T { type It = Self; } #[repr(C)] @@ -53,7 +54,7 @@ extern { pub fn char_type(p: char); //~ ERROR uses type `char` pub fn i128_type(p: i128); //~ ERROR uses type `i128` pub fn u128_type(p: u128); //~ ERROR uses type `u128` - pub fn trait_type(p: &dyn Clone); //~ ERROR uses type `dyn std::clone::Clone` + pub fn trait_type(p: &dyn Bar); //~ ERROR uses type `dyn Bar` pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)` pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)` pub fn zero_size(p: ZeroSize); //~ ERROR uses type `ZeroSize` diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr index 13b9adca3f9f5..a54226a7fc4a2 100644 --- a/src/test/ui/lint/lint-ctypes.stderr +++ b/src/test/ui/lint/lint-ctypes.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `Foo`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:46:28 + --> $DIR/lint-ctypes.rs:47:28 | LL | pub fn ptr_type1(size: *const Foo); | ^^^^^^^^^^ not FFI-safe @@ -12,13 +12,13 @@ LL | #![deny(improper_ctypes)] = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout note: the type is defined here - --> $DIR/lint-ctypes.rs:24:1 + --> $DIR/lint-ctypes.rs:25:1 | LL | pub struct Foo; | ^^^^^^^^^^^^^^^ error: `extern` block uses type `Foo`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:47:28 + --> $DIR/lint-ctypes.rs:48:28 | LL | pub fn ptr_type2(size: *const Foo); | ^^^^^^^^^^ not FFI-safe @@ -26,13 +26,13 @@ LL | pub fn ptr_type2(size: *const Foo); = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout note: the type is defined here - --> $DIR/lint-ctypes.rs:24:1 + --> $DIR/lint-ctypes.rs:25:1 | LL | pub struct Foo; | ^^^^^^^^^^^^^^^ error: `extern` block uses type `[u32]`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:48:26 + --> $DIR/lint-ctypes.rs:49:26 | LL | pub fn slice_type(p: &[u32]); | ^^^^^^ not FFI-safe @@ -41,7 +41,7 @@ LL | pub fn slice_type(p: &[u32]); = note: slices have no C equivalent error: `extern` block uses type `str`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:49:24 + --> $DIR/lint-ctypes.rs:50:24 | LL | pub fn str_type(p: &str); | ^^^^ not FFI-safe @@ -50,7 +50,7 @@ LL | pub fn str_type(p: &str); = note: string slices have no C equivalent error: `extern` block uses type `std::boxed::Box`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:50:24 + --> $DIR/lint-ctypes.rs:51:24 | LL | pub fn box_type(p: Box); | ^^^^^^^^ not FFI-safe @@ -59,7 +59,7 @@ LL | pub fn box_type(p: Box); = note: this struct has unspecified layout error: `extern` block uses type `std::option::Option>`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:51:28 + --> $DIR/lint-ctypes.rs:52:28 | LL | pub fn opt_box_type(p: Option>); | ^^^^^^^^^^^^^^^^ not FFI-safe @@ -68,7 +68,7 @@ LL | pub fn opt_box_type(p: Option>); = note: enum has no representation hint error: `extern` block uses type `char`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:53:25 + --> $DIR/lint-ctypes.rs:54:25 | LL | pub fn char_type(p: char); | ^^^^ not FFI-safe @@ -77,7 +77,7 @@ LL | pub fn char_type(p: char); = note: the `char` type has no C equivalent error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:54:25 + --> $DIR/lint-ctypes.rs:55:25 | LL | pub fn i128_type(p: i128); | ^^^^ not FFI-safe @@ -85,23 +85,23 @@ LL | pub fn i128_type(p: i128); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:55:25 + --> $DIR/lint-ctypes.rs:56:25 | LL | pub fn u128_type(p: u128); | ^^^^ not FFI-safe | = note: 128-bit integers don't currently have a known stable ABI -error: `extern` block uses type `dyn std::clone::Clone`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:56:26 +error: `extern` block uses type `dyn Bar`, which is not FFI-safe + --> $DIR/lint-ctypes.rs:57:26 | -LL | pub fn trait_type(p: &dyn Clone); - | ^^^^^^^^^^ not FFI-safe +LL | pub fn trait_type(p: &dyn Bar); + | ^^^^^^^^ not FFI-safe | = note: trait objects have no C equivalent error: `extern` block uses type `(i32, i32)`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:57:26 + --> $DIR/lint-ctypes.rs:58:26 | LL | pub fn tuple_type(p: (i32, i32)); | ^^^^^^^^^^ not FFI-safe @@ -110,7 +110,7 @@ LL | pub fn tuple_type(p: (i32, i32)); = note: tuples have unspecified layout error: `extern` block uses type `(i32, i32)`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:58:27 + --> $DIR/lint-ctypes.rs:59:27 | LL | pub fn tuple_type2(p: I32Pair); | ^^^^^^^ not FFI-safe @@ -119,7 +119,7 @@ LL | pub fn tuple_type2(p: I32Pair); = note: tuples have unspecified layout error: `extern` block uses type `ZeroSize`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:59:25 + --> $DIR/lint-ctypes.rs:60:25 | LL | pub fn zero_size(p: ZeroSize); | ^^^^^^^^ not FFI-safe @@ -127,26 +127,26 @@ LL | pub fn zero_size(p: ZeroSize); = help: consider adding a member to this struct = note: this struct has no fields note: the type is defined here - --> $DIR/lint-ctypes.rs:20:1 + --> $DIR/lint-ctypes.rs:21:1 | LL | pub struct ZeroSize; | ^^^^^^^^^^^^^^^^^^^^ error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:60:33 + --> $DIR/lint-ctypes.rs:61:33 | LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: composed only of `PhantomData` note: the type is defined here - --> $DIR/lint-ctypes.rs:43:1 + --> $DIR/lint-ctypes.rs:44:1 | LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `extern` block uses type `std::marker::PhantomData`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:63:12 + --> $DIR/lint-ctypes.rs:64:12 | LL | -> ::std::marker::PhantomData; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -154,7 +154,7 @@ LL | -> ::std::marker::PhantomData; = note: composed only of `PhantomData` error: `extern` block uses type `fn()`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:64:23 + --> $DIR/lint-ctypes.rs:65:23 | LL | pub fn fn_type(p: RustFn); | ^^^^^^ not FFI-safe @@ -163,7 +163,7 @@ LL | pub fn fn_type(p: RustFn); = note: this function pointer has Rust-specific calling convention error: `extern` block uses type `fn()`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:65:24 + --> $DIR/lint-ctypes.rs:66:24 | LL | pub fn fn_type2(p: fn()); | ^^^^ not FFI-safe @@ -172,7 +172,7 @@ LL | pub fn fn_type2(p: fn()); = note: this function pointer has Rust-specific calling convention error: `extern` block uses type `std::boxed::Box`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:66:28 + --> $DIR/lint-ctypes.rs:67:28 | LL | pub fn fn_contained(p: RustBadRet); | ^^^^^^^^^^ not FFI-safe @@ -181,7 +181,7 @@ LL | pub fn fn_contained(p: RustBadRet); = note: this struct has unspecified layout error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:67:32 + --> $DIR/lint-ctypes.rs:68:32 | LL | pub fn transparent_i128(p: TransparentI128); | ^^^^^^^^^^^^^^^ not FFI-safe @@ -189,7 +189,7 @@ LL | pub fn transparent_i128(p: TransparentI128); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `str`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:68:31 + --> $DIR/lint-ctypes.rs:69:31 | LL | pub fn transparent_str(p: TransparentStr); | ^^^^^^^^^^^^^^ not FFI-safe @@ -198,7 +198,7 @@ LL | pub fn transparent_str(p: TransparentStr); = note: string slices have no C equivalent error: `extern` block uses type `std::boxed::Box`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:69:30 + --> $DIR/lint-ctypes.rs:70:30 | LL | pub fn transparent_fn(p: TransparentBadFn); | ^^^^^^^^^^^^^^^^ not FFI-safe @@ -207,7 +207,7 @@ LL | pub fn transparent_fn(p: TransparentBadFn); = note: this struct has unspecified layout error: `extern` block uses type `[u8; 8]`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:70:27 + --> $DIR/lint-ctypes.rs:71:27 | LL | pub fn raw_array(arr: [u8; 8]); | ^^^^^^^ not FFI-safe @@ -216,7 +216,7 @@ LL | pub fn raw_array(arr: [u8; 8]); = note: passing raw arrays by value is not FFI-safe error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:72:34 + --> $DIR/lint-ctypes.rs:73:34 | LL | pub static static_u128_type: u128; | ^^^^ not FFI-safe @@ -224,7 +224,7 @@ LL | pub static static_u128_type: u128; = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:73:40 + --> $DIR/lint-ctypes.rs:74:40 | LL | pub static static_u128_array_type: [u128; 16]; | ^^^^^^^^^^ not FFI-safe diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.rs b/src/test/ui/wf/wf-foreign-fn-decl-ret.rs new file mode 100644 index 0000000000000..b9d956c056869 --- /dev/null +++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.rs @@ -0,0 +1,18 @@ +pub trait Unsatisfied {} + +#[repr(transparent)] +pub struct Bar(T); + +pub trait Foo { + type Assoc; +} + +extern "C" { + pub fn lint_me() -> <() as Foo>::Assoc; + //~^ ERROR: the trait bound `(): Foo` is not satisfied [E0277] + + pub fn lint_me_aswell() -> Bar; + //~^ ERROR: the trait bound `u32: Unsatisfied` is not satisfied [E0277] +} + +fn main() {} diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr new file mode 100644 index 0000000000000..9081b7929d935 --- /dev/null +++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/wf-foreign-fn-decl-ret.rs:11:5 + | +LL | pub fn lint_me() -> <() as Foo>::Assoc; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + +error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied + --> $DIR/wf-foreign-fn-decl-ret.rs:14:32 + | +LL | pub struct Bar(T); + | ----------- required by this bound in `Bar` +... +LL | pub fn lint_me_aswell() -> Bar; + | ^^^^^^^^ the trait `Unsatisfied` is not implemented for `u32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From c8cdcc8e517ab5831328ba71f57f00d177913174 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 20 Jul 2020 12:23:47 +0200 Subject: [PATCH 13/17] Fix duplicate maybe_uninit_extra attribute --- src/libstd/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 11b8f953be460..02de3fff29f87 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -224,10 +224,7 @@ all(target_vendor = "fortanix", target_env = "sgx"), feature(slice_index_methods, coerce_unsized, sgx_platform, ptr_wrapping_offset_from) )] -#![cfg_attr( - all(test, target_vendor = "fortanix", target_env = "sgx"), - feature(fixed_size_array, maybe_uninit_extra) -)] +#![cfg_attr(all(test, target_vendor = "fortanix", target_env = "sgx"), feature(fixed_size_array))] // std is implemented with unstable features, many of which are internal // compiler details that will never be stable // NB: the following list is sorted to minimize merge conflicts. From 5d4147a965fdd0c9766cd8ed934b33a836fcd6f6 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 10 Jul 2020 12:08:32 +0200 Subject: [PATCH 14/17] Stabilize TAU constant. Closes #66770. --- src/libcore/num/f32.rs | 2 +- src/libcore/num/f64.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 061d1ea6b1c46..9fb7296ce31cc 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -242,7 +242,7 @@ pub mod consts { /// The full circle constant (τ) /// /// Equal to 2π. - #[unstable(feature = "tau_constant", issue = "66770")] + #[stable(feature = "tau_constant", since = "1.47.0")] pub const TAU: f32 = 6.28318530717958647692528676655900577_f32; /// π/2 diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index b0df4d64f6ee1..bcb6cd4084691 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -242,7 +242,7 @@ pub mod consts { /// The full circle constant (τ) /// /// Equal to 2π. - #[unstable(feature = "tau_constant", issue = "66770")] + #[stable(feature = "tau_constant", since = "1.47.0")] pub const TAU: f64 = 6.28318530717958647692528676655900577_f64; /// π/2 From 995d63ac73ca89486b8a715ecc8296efb6090bf6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 20 Jul 2020 14:37:47 +0200 Subject: [PATCH 15/17] Improve "important traits" popup display on mobile --- src/librustdoc/html/static/rustdoc.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 38709b445efae..850a4b3cbc216 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1511,6 +1511,11 @@ h4 > .important-traits { #main > .line-numbers { margin-top: 0; } + + .important-traits .important-traits-tooltiptext { + left: 0; + top: 100%; + } } @media print { From 4cbd265c119cb1a5eb92e98d2bb93466f05efa46 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 20 Jul 2020 16:44:46 +0200 Subject: [PATCH 16/17] update backtrace-rs --- src/backtrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backtrace b/src/backtrace index 8f89434446f72..5965cf5fc17af 160000 --- a/src/backtrace +++ b/src/backtrace @@ -1 +1 @@ -Subproject commit 8f89434446f72f27f8145d8bbc1a302c6ef29d1e +Subproject commit 5965cf5fc17affc84c11dc9972ae8f4dc2c32db1 From f5e5eb6f46ef2cf0dd45dba4f975305509334fc6 Mon Sep 17 00:00:00 2001 From: Jakub Adam Wieczorek Date: Mon, 20 Jul 2020 15:13:00 +0200 Subject: [PATCH 17/17] Fix an ICE on an invalid `binding @ ...` in a tuple struct pattern --- src/librustc_resolve/late.rs | 8 +++++++- src/test/ui/issues/issue-74539.rs | 12 ++++++++++++ src/test/ui/issues/issue-74539.stderr | 21 +++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-74539.rs create mode 100644 src/test/ui/issues/issue-74539.stderr diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index ed88e54969215..261c2031364f6 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1500,11 +1500,17 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { pat_src: PatternSource, bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet); 1]>, ) { + let is_tuple_struct_pat = matches!(pat.kind, PatKind::TupleStruct(_, _)); + // Visit all direct subpatterns of this pattern. pat.walk(&mut |pat| { debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind); match pat.kind { - PatKind::Ident(bmode, ident, ref sub) => { + // In tuple struct patterns ignore the invalid `ident @ ...`. + // It will be handled as an error by the AST lowering. + PatKind::Ident(bmode, ident, ref sub) + if !(is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some()) => + { // First try to resolve the identifier as some existing entity, // then fall back to a fresh binding. let has_sub = sub.is_some(); diff --git a/src/test/ui/issues/issue-74539.rs b/src/test/ui/issues/issue-74539.rs new file mode 100644 index 0000000000000..75632d11c1df0 --- /dev/null +++ b/src/test/ui/issues/issue-74539.rs @@ -0,0 +1,12 @@ +enum E { + A(u8, u8), +} + +fn main() { + let e = E::A(2, 3); + match e { + E::A(x @ ..) => { //~ ERROR `x @` is not allowed in a tuple + x //~ ERROR cannot find value `x` in this scope + } + }; +} diff --git a/src/test/ui/issues/issue-74539.stderr b/src/test/ui/issues/issue-74539.stderr new file mode 100644 index 0000000000000..94526dcd7cb39 --- /dev/null +++ b/src/test/ui/issues/issue-74539.stderr @@ -0,0 +1,21 @@ +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-74539.rs:9:13 + | +LL | x + | ^ help: a local variable with a similar name exists: `e` + +error: `x @` is not allowed in a tuple struct + --> $DIR/issue-74539.rs:8:14 + | +LL | E::A(x @ ..) => { + | ^^^^^^ this is only allowed in slice patterns + | + = help: remove this and bind each tuple field independently +help: if you don't need to use the contents of x, discard the tuple's remaining fields + | +LL | E::A(..) => { + | ^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`.