From d74c17ba0c0a60f484dd35c6edb5093bfeeda508 Mon Sep 17 00:00:00 2001 From: Erin Power Date: Tue, 24 Mar 2020 13:24:20 +0100 Subject: [PATCH 01/19] Update RELEASES.md for 1.43.0 --- RELEASES.md | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 9ff0d14b353..44f3390f4df 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,122 @@ +Version 1.43.0 (2020-04-23) +========================== + +Language +-------- +- [Fixed using binary operations with `&{number}` (e.g. `&1.0`) not having + the correctly inferred type.][68129] + +**Syntax only changes** +- [Allow `type Foo: Ord` syntactically.][69361] +- [Unify item parsing & filter illegal item kinds.][69366] +- [Fuse associated and extern items up to defaultness.][69194] +- [Permit attributes on `if` expressions.][69201] +- [Syntactically allow `self` in all `fn` contexts.][68764] +- [Merge `fn` syntax + cleanup item parsing.][68728] + +These are still rejected *semantically*, so you will likely receive an error but +these changes can be seen and parsed by procedural macros and +conditional compilation. + + +Compiler +-------- +- [You can now pass multiple lint flags to rustc to override the previous + flags.][67885] For example; `rustc -D unused -A unused-variables` denies + everything in the `unused` lint group unused except `unused-variables` which + is explicitly allowed. Passing `rustc -A unused-variables -D unused` denies + everything in the `unused` lint group **including** `unused-variables` since + the allow flag is specified before the deny flag (and therefore overridden). +- [rustc will now prefer your system MinGW libraries over its bundled libraries + if they are available on `windows-gnu`.][67429] +- [rustc now buffers errors/warnings printed in JSON.][69227] + +Libraries +--------- +- [`Arc<[T; N]>`, `Box<[T; N]>`, and `Rc<[T; N]>`, now implement + `TryFrom>`,`TryFrom>`, and `TryFrom>` + respectively.][69538] Where `N` is `0..=32`. +- [All `to_be_bytes`, `to_le_bytes`, `to_ne_bytes`, `from_be_bytes`, + `from_le_bytes`, and `from_ne_bytes` methods for integers are + now `const`.][69373] +- [You can now use associated constants on floats and integers directly, rather + than having to import the module.][68952] e.g. You can now write `u32::MAX` or + `f32::NAN` no imports. +- [`u8::is_ascii` is now `const`.][68984] +- [`String` now implements `AsMut`.][68742] +- [Added the `primitive` module to `std` and `core`.][67637] This module + reexports Rust's primitive types. This is mainly useful for use in macros + where you want avoid these types being shadowed. +- [The some of the trait bounds on `HashMap` and `HashSet`.][67642] +- [`string::FromUtf8Error` now implements `Clone + Eq`.][68738] + +Stabilized APIs +--------------- +- [`Once::is_completed`] +- [`f32::LOG10_2`] +- [`f32::LOG2_10`] +- [`f64::LOG10_2`] +- [`f64::LOG2_10`] +- [`iter::once_with`] + +Misc +---- +- [Certain checks in the `const_err` lint were deemed unrelated to const + evaluation][69185], and have been moved to the `unconditional_panic` and + `arithmetic_overflow` lints. + +Internal Only +------------- +These changes provide no direct user facing benefits, but represent significant +improvements to the internals and overall performance of `rustc` and +related tools. + +- [All components are now built with `opt-level=3` instead of `2`.][67878] +- [Improved how rustc generates drop code.][67332] +- [Improved performance from `#[inline]`-ing certain hot functions.][69256] +- [traits: preallocate 2 Vecs of known initial size][69022] +- [Avoid exponential behaviour when relating types][68772] +- [Skip `Drop` terminators for enum variants without drop glue][68943] +- [Improve performance of coherence checks][68966] +- [Deduplicate types in the generator witness][68672] +- [Invert control in struct_lint_level.][68725] + +[67332]: https://github.com/rust-lang/rust/pull/67332/ +[67429]: https://github.com/rust-lang/rust/pull/67429/ +[67637]: https://github.com/rust-lang/rust/pull/67637/ +[67642]: https://github.com/rust-lang/rust/pull/67642/ +[67878]: https://github.com/rust-lang/rust/pull/67878/ +[67885]: https://github.com/rust-lang/rust/pull/67885/ +[68129]: https://github.com/rust-lang/rust/pull/68129/ +[68672]: https://github.com/rust-lang/rust/pull/68672/ +[68725]: https://github.com/rust-lang/rust/pull/68725/ +[68728]: https://github.com/rust-lang/rust/pull/68728/ +[68738]: https://github.com/rust-lang/rust/pull/68738/ +[68742]: https://github.com/rust-lang/rust/pull/68742/ +[68764]: https://github.com/rust-lang/rust/pull/68764/ +[68772]: https://github.com/rust-lang/rust/pull/68772/ +[68943]: https://github.com/rust-lang/rust/pull/68943/ +[68952]: https://github.com/rust-lang/rust/pull/68952/ +[68966]: https://github.com/rust-lang/rust/pull/68966/ +[68984]: https://github.com/rust-lang/rust/pull/68984/ +[69022]: https://github.com/rust-lang/rust/pull/69022/ +[69185]: https://github.com/rust-lang/rust/pull/69185/ +[69194]: https://github.com/rust-lang/rust/pull/69194/ +[69201]: https://github.com/rust-lang/rust/pull/69201/ +[69227]: https://github.com/rust-lang/rust/pull/69227/ +[69256]: https://github.com/rust-lang/rust/pull/69256/ +[69361]: https://github.com/rust-lang/rust/pull/69361/ +[69366]: https://github.com/rust-lang/rust/pull/69366/ +[69373]: https://github.com/rust-lang/rust/pull/69373/ +[69538]: https://github.com/rust-lang/rust/pull/69538/ +[`Once::is_completed`]: https://doc.rust-lang.org/std/sync/struct.Once.html#method.is_completed +[`f32::LOG10_2`]: https://doc.rust-lang.org/std/f32/consts/constant.LOG10_2.html +[`f32::LOG2_10`]: https://doc.rust-lang.org/std/f32/consts/constant.LOG2_10.html +[`f64::LOG10_2`]: https://doc.rust-lang.org/std/f64/consts/constant.LOG10_2.html +[`f64::LOG2_10`]: https://doc.rust-lang.org/std/f64/consts/constant.LOG2_10.html +[`iter::once_with`]: https://doc.rust-lang.org/std/iter/fn.once_with.html + + Version 1.42.0 (2020-03-12) ========================== From f1f91c92a4101f35b8640082970fdbf24a95ccff Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:07:25 +0100 Subject: [PATCH 02/19] Apply suggestions from code review Co-Authored-By: LeSeulArtichaut --- RELEASES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 44f3390f4df..e8205b15a45 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -24,7 +24,7 @@ Compiler - [You can now pass multiple lint flags to rustc to override the previous flags.][67885] For example; `rustc -D unused -A unused-variables` denies everything in the `unused` lint group unused except `unused-variables` which - is explicitly allowed. Passing `rustc -A unused-variables -D unused` denies + is explicitly allowed. However, passing `rustc -A unused-variables -D unused` denies everything in the `unused` lint group **including** `unused-variables` since the allow flag is specified before the deny flag (and therefore overridden). - [rustc will now prefer your system MinGW libraries over its bundled libraries @@ -35,13 +35,13 @@ Libraries --------- - [`Arc<[T; N]>`, `Box<[T; N]>`, and `Rc<[T; N]>`, now implement `TryFrom>`,`TryFrom>`, and `TryFrom>` - respectively.][69538] Where `N` is `0..=32`. + respectively.][69538] These conversions succeed when `N` is `0..=32`. - [All `to_be_bytes`, `to_le_bytes`, `to_ne_bytes`, `from_be_bytes`, `from_le_bytes`, and `from_ne_bytes` methods for integers are now `const`.][69373] - [You can now use associated constants on floats and integers directly, rather than having to import the module.][68952] e.g. You can now write `u32::MAX` or - `f32::NAN` no imports. + `f32::NAN` with no imports. - [`u8::is_ascii` is now `const`.][68984] - [`String` now implements `AsMut`.][68742] - [Added the `primitive` module to `std` and `core`.][67637] This module From 1d2fbbed339bb89175b27d32710d58bdf15f1041 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:08:08 +0100 Subject: [PATCH 03/19] Update RELEASES.md --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index e8205b15a45..4a11fd7760a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -47,7 +47,7 @@ Libraries - [Added the `primitive` module to `std` and `core`.][67637] This module reexports Rust's primitive types. This is mainly useful for use in macros where you want avoid these types being shadowed. -- [The some of the trait bounds on `HashMap` and `HashSet`.][67642] +- [Relaxed some of the trait bounds on `HashMap` and `HashSet`.][67642] - [`string::FromUtf8Error` now implements `Clone + Eq`.][68738] Stabilized APIs From 53790bbd555847c91169fc6da4f65de59d750e6a Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:14:57 +0100 Subject: [PATCH 04/19] Update RELEASES.md Co-Authored-By: LeSeulArtichaut --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 4a11fd7760a..228eb54b9f0 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4,7 +4,7 @@ Version 1.43.0 (2020-04-23) Language -------- - [Fixed using binary operations with `&{number}` (e.g. `&1.0`) not having - the correctly inferred type.][68129] + the type inferred correctly.][68129] **Syntax only changes** - [Allow `type Foo: Ord` syntactically.][69361] From cf06475e3404c6c372600ea6ab51612cf1ebe1e5 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:33:54 +0100 Subject: [PATCH 05/19] Update RELEASES.md --- RELEASES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 228eb54b9f0..ad70c370d56 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -35,7 +35,8 @@ Libraries --------- - [`Arc<[T; N]>`, `Box<[T; N]>`, and `Rc<[T; N]>`, now implement `TryFrom>`,`TryFrom>`, and `TryFrom>` - respectively.][69538] These conversions succeed when `N` is `0..=32`. + respectively.][69538] **Note** These conversions are only available when `N` + is `0..=32`. - [All `to_be_bytes`, `to_le_bytes`, `to_ne_bytes`, `from_be_bytes`, `from_le_bytes`, and `from_ne_bytes` methods for integers are now `const`.][69373] From 5baef9695d94f5fa74317f004fc3543bcc148a68 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Tue, 24 Mar 2020 18:23:46 +0100 Subject: [PATCH 06/19] Update RELEASES.md Co-Authored-By: Mark Rousskov --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index ad70c370d56..711e3217fb4 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -23,7 +23,7 @@ Compiler -------- - [You can now pass multiple lint flags to rustc to override the previous flags.][67885] For example; `rustc -D unused -A unused-variables` denies - everything in the `unused` lint group unused except `unused-variables` which + everything in the `unused` lint group except `unused-variables` which is explicitly allowed. However, passing `rustc -A unused-variables -D unused` denies everything in the `unused` lint group **including** `unused-variables` since the allow flag is specified before the deny flag (and therefore overridden). From f24cc7b633a8207180d87c4a291fcb4d213d1688 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Tue, 24 Mar 2020 18:23:53 +0100 Subject: [PATCH 07/19] Update RELEASES.md Co-Authored-By: Mark Rousskov --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 711e3217fb4..f2f9faf8da0 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -46,7 +46,7 @@ Libraries - [`u8::is_ascii` is now `const`.][68984] - [`String` now implements `AsMut`.][68742] - [Added the `primitive` module to `std` and `core`.][67637] This module - reexports Rust's primitive types. This is mainly useful for use in macros + reexports Rust's primitive types. This is mainly useful in macros where you want avoid these types being shadowed. - [Relaxed some of the trait bounds on `HashMap` and `HashSet`.][67642] - [`string::FromUtf8Error` now implements `Clone + Eq`.][68738] From f4e17cc7c2a1b11ca740db76d8f66bc3ea7904a3 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Tue, 24 Mar 2020 18:35:06 +0100 Subject: [PATCH 08/19] Update RELEASES.md --- RELEASES.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index f2f9faf8da0..4ea24372645 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -60,6 +60,15 @@ Stabilized APIs - [`f64::LOG2_10`] - [`iter::once_with`] +Cargo +----- +- [You can now set config `[profile]`s in your `.cargo/config`, or through + your environment.][cargo/7823] +- [Cargo will now set `CARGO_BIN_EXE_` pointing to a binary's + executable path when running integration tests or benchmarks.][cargo/7697] + `` is the name of your binary as-is e.g. If you wanted the executable + path for a binary named `my-program`you would use `env!("CARGO_BIN_EXE_my-program")`. + Misc ---- - [Certain checks in the `const_err` lint were deemed unrelated to const @@ -110,6 +119,8 @@ related tools. [69366]: https://github.com/rust-lang/rust/pull/69366/ [69373]: https://github.com/rust-lang/rust/pull/69373/ [69538]: https://github.com/rust-lang/rust/pull/69538/ +[cargo/7823]: https://github.com/rust-lang/cargo/pull/7823 +[cargo/7697]: https://github.com/rust-lang/cargo/pull/7697 [`Once::is_completed`]: https://doc.rust-lang.org/std/sync/struct.Once.html#method.is_completed [`f32::LOG10_2`]: https://doc.rust-lang.org/std/f32/consts/constant.LOG10_2.html [`f32::LOG2_10`]: https://doc.rust-lang.org/std/f32/consts/constant.LOG2_10.html From ce3193ff442cab8365960940063a08f546b8fd34 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Wed, 25 Mar 2020 09:23:11 +0100 Subject: [PATCH 09/19] Update RELEASES.md Co-Authored-By: Mazdak Farrokhzad --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 4ea24372645..f0211f6a0e9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -15,7 +15,7 @@ Language - [Merge `fn` syntax + cleanup item parsing.][68728] These are still rejected *semantically*, so you will likely receive an error but -these changes can be seen and parsed by procedural macros and +these changes can be seen and parsed by macros and conditional compilation. From 6364b4dbb4d2393a6bb51562b3f8d2fe2748f657 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Thu, 2 Apr 2020 21:11:29 +0200 Subject: [PATCH 10/19] Update RELEASES.md --- RELEASES.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index f0211f6a0e9..d181b0ece25 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -37,9 +37,6 @@ Libraries `TryFrom>`,`TryFrom>`, and `TryFrom>` respectively.][69538] **Note** These conversions are only available when `N` is `0..=32`. -- [All `to_be_bytes`, `to_le_bytes`, `to_ne_bytes`, `from_be_bytes`, - `from_le_bytes`, and `from_ne_bytes` methods for integers are - now `const`.][69373] - [You can now use associated constants on floats and integers directly, rather than having to import the module.][68952] e.g. You can now write `u32::MAX` or `f32::NAN` with no imports. @@ -74,6 +71,17 @@ Misc - [Certain checks in the `const_err` lint were deemed unrelated to const evaluation][69185], and have been moved to the `unconditional_panic` and `arithmetic_overflow` lints. + +Compatibility Notes +------------------- + +- [Having trailing syntax in the `assert!` macro is now a hard error.][69548] This + has been a warning since 1.36.0. +- [Fixed `Self` not having the correctly inferred type.][69340] This incorrectly + led to some instances being accepted, and now correctly emits a hard error. +- [][] + +[69340]: https://github.com/rust-lang/rust/pull/69340 Internal Only ------------- @@ -114,10 +122,10 @@ related tools. [69194]: https://github.com/rust-lang/rust/pull/69194/ [69201]: https://github.com/rust-lang/rust/pull/69201/ [69227]: https://github.com/rust-lang/rust/pull/69227/ +[69548]: https://github.com/rust-lang/rust/pull/69548/ [69256]: https://github.com/rust-lang/rust/pull/69256/ [69361]: https://github.com/rust-lang/rust/pull/69361/ [69366]: https://github.com/rust-lang/rust/pull/69366/ -[69373]: https://github.com/rust-lang/rust/pull/69373/ [69538]: https://github.com/rust-lang/rust/pull/69538/ [cargo/7823]: https://github.com/rust-lang/cargo/pull/7823 [cargo/7697]: https://github.com/rust-lang/cargo/pull/7697 From 12a95482c10f1ca9123f1685a85f627967157c2b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Apr 2020 16:43:00 +0200 Subject: [PATCH 11/19] Improve rustdoc source code a bit --- src/librustdoc/clean/utils.rs | 44 +++++++++++++---------------- src/librustdoc/html/render/cache.rs | 10 +++---- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 9e96015d306..ace24597288 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -208,10 +208,10 @@ pub fn get_real_types( if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { - if let Some(did) = ty.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - res.insert((ty, kind)); - } + if let Some(kind) = + ty.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) + { + res.insert((ty, kind)); } } } @@ -226,20 +226,18 @@ pub fn get_real_types( if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { - if let Some(did) = ty.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - res.insert((ty.clone(), kind)); - } + if let Some(kind) = + ty.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) + { + res.insert((ty.clone(), kind)); } } } } } } else { - if let Some(did) = arg.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - res.insert((arg.clone(), kind)); - } + if let Some(kind) = arg.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) { + res.insert((arg.clone(), kind)); } if let Some(gens) = arg.generics() { for gen in gens.iter() { @@ -248,10 +246,10 @@ pub fn get_real_types( if !adds.is_empty() { res.extend(adds); } - } else if let Some(did) = gen.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - res.insert((gen.clone(), kind)); - } + } else if let Some(kind) = + gen.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) + { + res.insert((gen.clone(), kind)); } } } @@ -277,10 +275,8 @@ pub fn get_all_types( if !args.is_empty() { all_types.extend(args); } else { - if let Some(did) = arg.type_.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - all_types.insert((arg.type_.clone(), kind)); - } + if let Some(kind) = arg.type_.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) { + all_types.insert((arg.type_.clone(), kind)); } } } @@ -289,10 +285,10 @@ pub fn get_all_types( FnRetTy::Return(ref return_type) => { let mut ret = get_real_types(generics, &return_type, cx, 0); if ret.is_empty() { - if let Some(did) = return_type.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - ret.insert((return_type.clone(), kind)); - } + if let Some(kind) = + return_type.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) + { + ret.insert((return_type.clone(), kind)); } } ret.into_iter().collect() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index d9f6f7b466a..a8efb16a1d3 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -697,11 +697,11 @@ fn get_generics(clean_type: &clean::Type) -> Option> { let r = types .iter() .filter_map(|t| { - if let Some(name) = get_index_type_name(t, false) { - Some(Generic { name: name.to_ascii_lowercase(), defid: t.def_id(), idx: None }) - } else { - None - } + get_index_type_name(t, false).map(|name| Generic { + name: name.to_ascii_lowercase(), + defid: t.def_id(), + idx: None, + }) }) .collect::>(); if r.is_empty() { None } else { Some(r) } From d6b75e0ef11107d699a98bb89dd9f9d688d3e008 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 4 Apr 2020 18:35:20 +0200 Subject: [PATCH 12/19] End cleanup on rustdoc-js tools --- src/bootstrap/test.rs | 7 +- src/tools/compiletest/src/runtest.rs | 2 + src/tools/rustdoc-js-common/lib.js | 319 -------------------- src/tools/rustdoc-js-std/tester.js | 74 ----- src/tools/rustdoc-js/tester.js | 430 +++++++++++++++++++++++++-- 5 files changed, 411 insertions(+), 421 deletions(-) delete mode 100644 src/tools/rustdoc-js-common/lib.js delete mode 100644 src/tools/rustdoc-js-std/tester.js diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 0bf507f9ebb..55480f3f149 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -627,8 +627,13 @@ impl Step for RustdocJSStd { if let Some(ref nodejs) = builder.config.nodejs { let mut command = Command::new(nodejs); command - .arg(builder.src.join("src/tools/rustdoc-js-std/tester.js")) + .arg(builder.src.join("src/tools/rustdoc-js/tester.js")) + .arg("--std") + .arg("--version") + .arg(crate::channel::CFG_RELEASE_NUM) + .arg("--doc-folder") .arg(builder.doc_out(self.target)) + .arg("--test-folder") .arg(builder.src.join("src/test/rustdoc-js-std")); builder.ensure(crate::doc::Std { target: self.target, stage: builder.top_stage }); builder.run(&mut command); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 26a9cd11997..37f8ca1c5e5 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2810,7 +2810,9 @@ impl<'test> TestCx<'test> { let res = self.cmd2procres( Command::new(&nodejs) .arg(root.join("src/tools/rustdoc-js/tester.js")) + .arg("--doc-folder") .arg(out_dir.parent().expect("no parent")) + .arg("--test-file") .arg(self.testpaths.file.with_extension("js")), ); if !res.status.success() { diff --git a/src/tools/rustdoc-js-common/lib.js b/src/tools/rustdoc-js-common/lib.js deleted file mode 100644 index 81e64aec491..00000000000 --- a/src/tools/rustdoc-js-common/lib.js +++ /dev/null @@ -1,319 +0,0 @@ -const fs = require('fs'); - -function getNextStep(content, pos, stop) { - while (pos < content.length && content[pos] !== stop && - (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) { - pos += 1; - } - if (pos >= content.length) { - return null; - } - if (content[pos] !== stop) { - return pos * -1; - } - return pos; -} - -// Stupid function extractor based on indent. Doesn't support block -// comments. If someone puts a ' or an " in a block comment this -// will blow up. Template strings are not tested and might also be -// broken. -function extractFunction(content, functionName) { - var indent = 0; - var splitter = "function " + functionName + "("; - - while (true) { - var start = content.indexOf(splitter); - if (start === -1) { - break; - } - var pos = start; - while (pos < content.length && content[pos] !== ')') { - pos += 1; - } - if (pos >= content.length) { - break; - } - pos = getNextStep(content, pos + 1, '{'); - if (pos === null) { - break; - } else if (pos < 0) { - content = content.slice(-pos); - continue; - } - while (pos < content.length) { - // Eat single-line comments - if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') { - do { - pos += 1; - } while (pos < content.length && content[pos] !== '\n'); - - // Eat quoted strings - } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") { - var stop = content[pos]; - var is_escaped = false; - do { - if (content[pos] === '\\') { - pos += 2; - } else { - pos += 1; - } - } while (pos < content.length && - (content[pos] !== stop || content[pos - 1] === '\\')); - - // Otherwise, check for indent - } else if (content[pos] === '{') { - indent += 1; - } else if (content[pos] === '}') { - indent -= 1; - if (indent === 0) { - return content.slice(start, pos + 1); - } - } - pos += 1; - } - content = content.slice(start + 1); - } - return null; -} - -// Stupid function extractor for array. -function extractArrayVariable(content, arrayName) { - var splitter = "var " + arrayName; - while (true) { - var start = content.indexOf(splitter); - if (start === -1) { - break; - } - var pos = getNextStep(content, start, '='); - if (pos === null) { - break; - } else if (pos < 0) { - content = content.slice(-pos); - continue; - } - pos = getNextStep(content, pos, '['); - if (pos === null) { - break; - } else if (pos < 0) { - content = content.slice(-pos); - continue; - } - while (pos < content.length) { - if (content[pos] === '"' || content[pos] === "'") { - var stop = content[pos]; - do { - if (content[pos] === '\\') { - pos += 2; - } else { - pos += 1; - } - } while (pos < content.length && - (content[pos] !== stop || content[pos - 1] === '\\')); - } else if (content[pos] === ']' && - pos + 1 < content.length && - content[pos + 1] === ';') { - return content.slice(start, pos + 2); - } - pos += 1; - } - content = content.slice(start + 1); - } - return null; -} - -// Stupid function extractor for variable. -function extractVariable(content, varName) { - var splitter = "var " + varName; - while (true) { - var start = content.indexOf(splitter); - if (start === -1) { - break; - } - var pos = getNextStep(content, start, '='); - if (pos === null) { - break; - } else if (pos < 0) { - content = content.slice(-pos); - continue; - } - while (pos < content.length) { - if (content[pos] === '"' || content[pos] === "'") { - var stop = content[pos]; - do { - if (content[pos] === '\\') { - pos += 2; - } else { - pos += 1; - } - } while (pos < content.length && - (content[pos] !== stop || content[pos - 1] === '\\')); - } else if (content[pos] === ';' || content[pos] === ',') { - return content.slice(start, pos + 1); - } - pos += 1; - } - content = content.slice(start + 1); - } - return null; -} - -function loadContent(content) { - var Module = module.constructor; - var m = new Module(); - m._compile(content, "tmp.js"); - m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 || - content.startsWith("// ignore-order\n"); - m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 || - content.startsWith("// exact-check\n"); - m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 || - content.startsWith("// should-fail\n"); - return m.exports; -} - -function readFile(filePath) { - return fs.readFileSync(filePath, 'utf8'); -} - -function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) { - var content = ''; - for (var i = 0; i < thingsToLoad.length; ++i) { - var tmp = funcToCall(fileContent, thingsToLoad[i]); - if (tmp === null) { - console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"'); - process.exit(1); - } - content += tmp; - content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';'; - } - return content; -} - -function lookForEntry(entry, data) { - for (var i = 0; i < data.length; ++i) { - var allGood = true; - for (var key in entry) { - if (!entry.hasOwnProperty(key)) { - continue; - } - var value = data[i][key]; - // To make our life easier, if there is a "parent" type, we add it to the path. - if (key === 'path' && data[i]['parent'] !== undefined) { - if (value.length > 0) { - value += '::' + data[i]['parent']['name']; - } else { - value = data[i]['parent']['name']; - } - } - if (value !== entry[key]) { - allGood = false; - break; - } - } - if (allGood === true) { - return i; - } - } - return null; -} - -function loadMainJsAndIndex(mainJs, aliases, searchIndex, crate) { - if (searchIndex[searchIndex.length - 1].length === 0) { - searchIndex.pop(); - } - searchIndex.pop(); - searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;'); - finalJS = ""; - - var arraysToLoad = ["itemTypes"]; - var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER", - "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA", - "TY_PRIMITIVE", "TY_KEYWORD", - "levenshtein_row2"]; - // execQuery first parameter is built in getQuery (which takes in the search input). - // execQuery last parameter is built in buildIndex. - // buildIndex requires the hashmap from search-index. - var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", - "getQuery", "buildIndex", "execQuery", "execSearch"]; - - finalJS += 'window = { "currentCrate": "' + crate + '" };\n'; - finalJS += 'var rootPath = "../";\n'; - finalJS += aliases; - finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); - finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); - finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs); - - var loaded = loadContent(finalJS); - var index = loaded.buildIndex(searchIndex.searchIndex); - - return [loaded, index]; -} - -function runChecks(testFile, loaded, index) { - var errors = 0; - var loadedFile = loadContent( - readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'); - - const expected = loadedFile.EXPECTED; - const query = loadedFile.QUERY; - const filter_crate = loadedFile.FILTER_CRATE; - const ignore_order = loadedFile.ignore_order; - const exact_check = loadedFile.exact_check; - const should_fail = loadedFile.should_fail; - - var results = loaded.execSearch(loaded.getQuery(query), index); - var error_text = []; - - for (var key in expected) { - if (!expected.hasOwnProperty(key)) { - continue; - } - if (!results.hasOwnProperty(key)) { - error_text.push('==> Unknown key "' + key + '"'); - break; - } - var entry = expected[key]; - var prev_pos = -1; - for (var i = 0; i < entry.length; ++i) { - var entry_pos = lookForEntry(entry[i], results[key]); - if (entry_pos === null) { - error_text.push("==> Result not found in '" + key + "': '" + - JSON.stringify(entry[i]) + "'"); - } else if (exact_check === true && prev_pos + 1 !== entry_pos) { - error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " + - "expected '" + JSON.stringify(entry[i]) + "' but found '" + - JSON.stringify(results[key][i]) + "'"); - } else if (ignore_order === false && entry_pos < prev_pos) { - error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " + - " before '" + JSON.stringify(results[key][entry_pos]) + "'"); - } else { - prev_pos = entry_pos; - } - } - } - if (error_text.length === 0 && should_fail === true) { - errors += 1; - console.error("FAILED"); - console.error("==> Test was supposed to fail but all items were found..."); - } else if (error_text.length !== 0 && should_fail === false) { - errors += 1; - console.error("FAILED"); - console.error(error_text.join("\n")); - } else { - console.log("OK"); - } - return errors; -} - -module.exports = { - 'getNextStep': getNextStep, - 'extractFunction': extractFunction, - 'extractArrayVariable': extractArrayVariable, - 'extractVariable': extractVariable, - 'loadContent': loadContent, - 'readFile': readFile, - 'loadThings': loadThings, - 'lookForEntry': lookForEntry, - 'loadMainJsAndIndex': loadMainJsAndIndex, - 'runChecks': runChecks, -}; diff --git a/src/tools/rustdoc-js-std/tester.js b/src/tools/rustdoc-js-std/tester.js deleted file mode 100644 index 6f730b0fdbb..00000000000 --- a/src/tools/rustdoc-js-std/tester.js +++ /dev/null @@ -1,74 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const tools = require('../rustdoc-js-common/lib.js'); - - -function findFile(dir, name, extension) { - var entries = fs.readdirSync(dir); - var matches = []; - for (var i = 0; i < entries.length; ++i) { - var entry = entries[i]; - var file_type = fs.statSync(dir + entry); - if (file_type.isDirectory()) { - continue; - } - if (entry.startsWith(name) && entry.endsWith(extension)) { - var version = entry.slice(name.length, entry.length - extension.length); - version = version.split(".").map(function(x) { - return parseInt(x); - }); - var total = 0; - var mult = 1; - for (var j = version.length - 1; j >= 0; --j) { - total += version[j] * mult; - mult *= 1000; - } - matches.push([entry, total]); - } - } - if (matches.length === 0) { - return null; - } - // We make a reverse sort to have the "highest" file. Very useful in case you didn't clean up - // you std doc folder... - matches.sort(function(a, b) { - return b[1] - a[1]; - }); - return matches[0][0]; -} - -function readFileMatching(dir, name, extension) { - if (dir.endsWith("/") === false) { - dir += "/"; - } - var f = findFile(dir, name, extension); - if (f === null) { - return ""; - } - return tools.readFile(dir + f); -} - -function main(argv) { - if (argv.length !== 4) { - console.error("USAGE: node tester.js STD_DOCS TEST_FOLDER"); - return 1; - } - var std_docs = argv[2]; - var test_folder = argv[3]; - - var mainJs = readFileMatching(std_docs, "main", ".js"); - var aliases = readFileMatching(std_docs, "aliases", ".js"); - var searchIndex = readFileMatching(std_docs, "search-index", ".js").split("\n"); - - var [loaded, index] = tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, "std"); - - var errors = 0; - - fs.readdirSync(test_folder).forEach(function(file) { - process.stdout.write('Checking "' + file + '" ... '); - errors += tools.runChecks(path.join(test_folder, file), loaded, index); - }); - return errors > 0 ? 1 : 0; -} - -process.exit(main(process.argv)); diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 2e8901d56d0..a871fccfe30 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -1,43 +1,419 @@ const fs = require('fs'); const path = require('path'); -const tools = require('../rustdoc-js-common/lib.js'); -function load_files(out_folder, crate) { - var mainJs = tools.readFile(out_folder + "/main.js"); - var aliases = tools.readFile(out_folder + "/aliases.js"); - var searchIndex = tools.readFile(out_folder + "/search-index.js").split("\n"); +function getNextStep(content, pos, stop) { + while (pos < content.length && content[pos] !== stop && + (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) { + pos += 1; + } + if (pos >= content.length) { + return null; + } + if (content[pos] !== stop) { + return pos * -1; + } + return pos; +} - return tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, crate); +// Stupid function extractor based on indent. Doesn't support block +// comments. If someone puts a ' or an " in a block comment this +// will blow up. Template strings are not tested and might also be +// broken. +function extractFunction(content, functionName) { + var indent = 0; + var splitter = "function " + functionName + "("; + + while (true) { + var start = content.indexOf(splitter); + if (start === -1) { + break; + } + var pos = start; + while (pos < content.length && content[pos] !== ')') { + pos += 1; + } + if (pos >= content.length) { + break; + } + pos = getNextStep(content, pos + 1, '{'); + if (pos === null) { + break; + } else if (pos < 0) { + content = content.slice(-pos); + continue; + } + while (pos < content.length) { + // Eat single-line comments + if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') { + do { + pos += 1; + } while (pos < content.length && content[pos] !== '\n'); + + // Eat quoted strings + } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") { + var stop = content[pos]; + var is_escaped = false; + do { + if (content[pos] === '\\') { + pos += 2; + } else { + pos += 1; + } + } while (pos < content.length && + (content[pos] !== stop || content[pos - 1] === '\\')); + + // Otherwise, check for indent + } else if (content[pos] === '{') { + indent += 1; + } else if (content[pos] === '}') { + indent -= 1; + if (indent === 0) { + return content.slice(start, pos + 1); + } + } + pos += 1; + } + content = content.slice(start + 1); + } + return null; +} + +// Stupid function extractor for array. +function extractArrayVariable(content, arrayName) { + var splitter = "var " + arrayName; + while (true) { + var start = content.indexOf(splitter); + if (start === -1) { + break; + } + var pos = getNextStep(content, start, '='); + if (pos === null) { + break; + } else if (pos < 0) { + content = content.slice(-pos); + continue; + } + pos = getNextStep(content, pos, '['); + if (pos === null) { + break; + } else if (pos < 0) { + content = content.slice(-pos); + continue; + } + while (pos < content.length) { + if (content[pos] === '"' || content[pos] === "'") { + var stop = content[pos]; + do { + if (content[pos] === '\\') { + pos += 2; + } else { + pos += 1; + } + } while (pos < content.length && + (content[pos] !== stop || content[pos - 1] === '\\')); + } else if (content[pos] === ']' && + pos + 1 < content.length && + content[pos + 1] === ';') { + return content.slice(start, pos + 2); + } + pos += 1; + } + content = content.slice(start + 1); + } + return null; +} + +// Stupid function extractor for variable. +function extractVariable(content, varName) { + var splitter = "var " + varName; + while (true) { + var start = content.indexOf(splitter); + if (start === -1) { + break; + } + var pos = getNextStep(content, start, '='); + if (pos === null) { + break; + } else if (pos < 0) { + content = content.slice(-pos); + continue; + } + while (pos < content.length) { + if (content[pos] === '"' || content[pos] === "'") { + var stop = content[pos]; + do { + if (content[pos] === '\\') { + pos += 2; + } else { + pos += 1; + } + } while (pos < content.length && + (content[pos] !== stop || content[pos - 1] === '\\')); + } else if (content[pos] === ';' || content[pos] === ',') { + return content.slice(start, pos + 1); + } + pos += 1; + } + content = content.slice(start + 1); + } + return null; +} + +function loadContent(content) { + var Module = module.constructor; + var m = new Module(); + m._compile(content, "tmp.js"); + m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 || + content.startsWith("// ignore-order\n"); + m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 || + content.startsWith("// exact-check\n"); + m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 || + content.startsWith("// should-fail\n"); + return m.exports; +} + +function readFile(filePath) { + return fs.readFileSync(filePath, 'utf8'); +} + +function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) { + var content = ''; + for (var i = 0; i < thingsToLoad.length; ++i) { + var tmp = funcToCall(fileContent, thingsToLoad[i]); + if (tmp === null) { + console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"'); + process.exit(1); + } + content += tmp; + content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';'; + } + return content; +} + +function lookForEntry(entry, data) { + for (var i = 0; i < data.length; ++i) { + var allGood = true; + for (var key in entry) { + if (!entry.hasOwnProperty(key)) { + continue; + } + var value = data[i][key]; + // To make our life easier, if there is a "parent" type, we add it to the path. + if (key === 'path' && data[i]['parent'] !== undefined) { + if (value.length > 0) { + value += '::' + data[i]['parent']['name']; + } else { + value = data[i]['parent']['name']; + } + } + if (value !== entry[key]) { + allGood = false; + break; + } + } + if (allGood === true) { + return i; + } + } + return null; +} + +function loadMainJsAndIndex(mainJs, aliases, searchIndex, crate) { + if (searchIndex[searchIndex.length - 1].length === 0) { + searchIndex.pop(); + } + searchIndex.pop(); + searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;'); + finalJS = ""; + + var arraysToLoad = ["itemTypes"]; + var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER", + "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA", + "TY_PRIMITIVE", "TY_KEYWORD", + "levenshtein_row2"]; + // execQuery first parameter is built in getQuery (which takes in the search input). + // execQuery last parameter is built in buildIndex. + // buildIndex requires the hashmap from search-index. + var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", + "getQuery", "buildIndex", "execQuery", "execSearch"]; + + finalJS += 'window = { "currentCrate": "' + crate + '" };\n'; + finalJS += 'var rootPath = "../";\n'; + finalJS += aliases; + finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); + finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); + finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs); + + var loaded = loadContent(finalJS); + var index = loaded.buildIndex(searchIndex.searchIndex); + + return [loaded, index]; +} + +function runChecks(testFile, loaded, index) { + var errors = 0; + var loadedFile = loadContent( + readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'); + + const expected = loadedFile.EXPECTED; + const query = loadedFile.QUERY; + const filter_crate = loadedFile.FILTER_CRATE; + const ignore_order = loadedFile.ignore_order; + const exact_check = loadedFile.exact_check; + const should_fail = loadedFile.should_fail; + + var results = loaded.execSearch(loaded.getQuery(query), index); + var error_text = []; + + for (var key in expected) { + if (!expected.hasOwnProperty(key)) { + continue; + } + if (!results.hasOwnProperty(key)) { + error_text.push('==> Unknown key "' + key + '"'); + break; + } + var entry = expected[key]; + var prev_pos = -1; + for (var i = 0; i < entry.length; ++i) { + var entry_pos = lookForEntry(entry[i], results[key]); + if (entry_pos === null) { + error_text.push("==> Result not found in '" + key + "': '" + + JSON.stringify(entry[i]) + "'"); + } else if (exact_check === true && prev_pos + 1 !== entry_pos) { + error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " + + "expected '" + JSON.stringify(entry[i]) + "' but found '" + + JSON.stringify(results[key][i]) + "'"); + } else if (ignore_order === false && entry_pos < prev_pos) { + error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " + + " before '" + JSON.stringify(results[key][entry_pos]) + "'"); + } else { + prev_pos = entry_pos; + } + } + } + if (error_text.length === 0 && should_fail === true) { + errors += 1; + console.error("FAILED"); + console.error("==> Test was supposed to fail but all items were found..."); + } else if (error_text.length !== 0 && should_fail === false) { + errors += 1; + console.error("FAILED"); + console.error(error_text.join("\n")); + } else { + console.log("OK"); + } + return errors; +} + +function load_files(doc_folder, version, crate) { + var mainJs = readFile(doc_folder + "/main" + version + ".js"); + var aliases = readFile(doc_folder + "/aliases" + version + ".js"); + var searchIndex = readFile(doc_folder + "/search-index" + version + ".js").split("\n"); + + return loadMainJsAndIndex(mainJs, aliases, searchIndex, crate); +} + +function showHelp() { + console.log("rustdoc-js options:"); + console.log(" --doc-folder [PATH] : location of the generated doc folder"); + console.log(" --help : show this message then quit"); + console.log(" --std : to run std tests"); + console.log(" --test-file [PATH]: location of the JS test file"); + console.log(" --test-folder [PATH]: location of the JS tests folder"); + console.log(" --version [STRING] : version used when generating docs (used to get js files)"); +} + +function parseOptions(args) { + var opts = { + "is_std": false, + "version": "", + "doc_folder": "", + "test_folder": "", + "test_file": "", + }; + var correspondances = { + "--version": "version", + "--doc-folder": "doc_folder", + "--test-folder": "test_folder", + "--test-file": "test_file", + }; + + for (var i = 0; i < args.length; ++i) { + if (args[i] === "--version" + || args[i] === "--doc-folder" + || args[i] === "--test-folder" + || args[i] === "--test-file") { + i += 1; + if (i >= args.length) { + console.error("Missing argument after `" + args[i - 1] + "` option."); + return null; + } + opts[correspondances[args[i - 1]]] = args[i]; + } else if (args[i] === "--std") { + opts["is_std"] = true; + } else if (args[i] === "--help") { + showHelp(); + process.exit(0); + } else { + console.error("Unknown option `" + args[i] + "`."); + console.error("Use `--help` to see the list of options"); + return null; + } + } + if (opts["doc_folder"].length < 1) { + console.error("Missing `--doc-folder` option."); + return null; + } else if (opts["test_folder"].length < 1 && opts["test_file"].length < 1) { + console.error("At least one of `--test-folder` or `--test-file` option is required."); + return null; + } else if (opts["is_std"] === true && opts["test_file"].length !== 0) { + console.error("`--std` and `--test-file` options can't be used at the same time.") + } + return opts; +} + +function checkFile(test_file, opts, std_loaded, std_index) { + const test_name = path.basename(test_file, ".js"); + + process.stdout.write('Checking "' + test_name + '" ... '); + + var loaded = std_loaded; + var index = std_index; + if (opts["is_std"] !== true) { + var tmp = load_files(path.join(opts["doc_folder"], test_name), opts["version"], test_name); + loaded = tmp[0]; + index = tmp[1]; + } + return runChecks(test_file, loaded, index); } function main(argv) { - if (argv.length < 4) { - console.error("USAGE: node tester.js OUT_FOLDER [TESTS]"); + var opts = parseOptions(argv.slice(2)); + if (opts === null) { return 1; } - if (argv[2].substr(-1) !== "/") { - argv[2] += "/"; + + var std_loaded = null; + var std_index = null; + if (opts["is_std"] === true) { + var tmp = load_files(opts["doc_folder"], opts["version"], "std"); + std_loaded = tmp[0]; + std_index = tmp[1]; } - const out_folder = argv[2]; var errors = 0; - for (var j = 3; j < argv.length; ++j) { - const test_file = argv[j]; - const test_name = path.basename(test_file, ".js"); - - process.stdout.write('Checking "' + test_name + '" ... '); - if (!fs.existsSync(test_file)) { - errors += 1; - console.error("FAILED"); - console.error("==> Missing '" + test_name + ".js' file..."); - continue; - } - - const test_out_folder = out_folder + test_name; - - var [loaded, index] = load_files(test_out_folder, test_name); - errors += tools.runChecks(test_file, loaded, index); + if (opts["test_file"].length !== 0) { + errors += checkFile(opts["test_file"], opts, null, null); + } + if (opts["test_folder"].length !== 0) { + fs.readdirSync(opts["test_folder"]).forEach(function(file) { + if (!file.endsWith(".js")) { + return; + } + errors += checkFile(path.join(opts["test_folder"], file), opts, std_loaded, std_index); + }); } return errors > 0 ? 1 : 0; } From 32047903c78410d47ead0693ec15fc7c6f350229 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Sat, 11 Apr 2020 16:35:19 +0200 Subject: [PATCH 13/19] Update RELEASES.md --- RELEASES.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index d181b0ece25..c1e4fcc4394 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -8,11 +8,22 @@ Language **Syntax only changes** - [Allow `type Foo: Ord` syntactically.][69361] -- [Unify item parsing & filter illegal item kinds.][69366] - [Fuse associated and extern items up to defaultness.][69194] - [Permit attributes on `if` expressions.][69201] - [Syntactically allow `self` in all `fn` contexts.][68764] - [Merge `fn` syntax + cleanup item parsing.][68728] +- [`item` macro fragments can be interpolated into `trait`s, `impl`s, and `extern` blocks.][69366] + For example, you may now write: + ```rust + macro_rules! mac_trait { + ($i:item) => { + trait T { $i } + } + } + mac_trait! { + fn foo() {} + } + ``` These are still rejected *semantically*, so you will likely receive an error but these changes can be seen and parsed by macros and @@ -79,7 +90,6 @@ Compatibility Notes has been a warning since 1.36.0. - [Fixed `Self` not having the correctly inferred type.][69340] This incorrectly led to some instances being accepted, and now correctly emits a hard error. -- [][] [69340]: https://github.com/rust-lang/rust/pull/69340 From dda3445fd51ead62353243928c4376f404b3c182 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Sat, 11 Apr 2020 16:36:29 +0200 Subject: [PATCH 14/19] Update RELEASES.md --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index c1e4fcc4394..36597b1864f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -5,11 +5,11 @@ Language -------- - [Fixed using binary operations with `&{number}` (e.g. `&1.0`) not having the type inferred correctly.][68129] +- [Attributes such as `#[cfg()]` can now be used on `if` expressions.][69201] **Syntax only changes** - [Allow `type Foo: Ord` syntactically.][69361] - [Fuse associated and extern items up to defaultness.][69194] -- [Permit attributes on `if` expressions.][69201] - [Syntactically allow `self` in all `fn` contexts.][68764] - [Merge `fn` syntax + cleanup item parsing.][68728] - [`item` macro fragments can be interpolated into `trait`s, `impl`s, and `extern` blocks.][69366] From 426055cb299017748fcf8368e40afa4259af7a57 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 11 Apr 2020 17:42:47 +0200 Subject: [PATCH 15/19] Improve rustdoc js testers code --- src/bootstrap/test.rs | 5 +- src/tools/compiletest/src/runtest.rs | 6 ++- src/tools/rustdoc-js/tester.js | 73 ++++++++++++---------------- 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 55480f3f149..85c5d28bb89 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -628,8 +628,9 @@ impl Step for RustdocJSStd { let mut command = Command::new(nodejs); command .arg(builder.src.join("src/tools/rustdoc-js/tester.js")) - .arg("--std") - .arg("--version") + .arg("--crate-name") + .arg("std") + .arg("--resource-suffix") .arg(crate::channel::CFG_RELEASE_NUM) .arg("--doc-folder") .arg(builder.doc_out(self.target)) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 37f8ca1c5e5..d7be8c2b6ef 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2807,11 +2807,15 @@ impl<'test> TestCx<'test> { self.document(&out_dir); let root = self.config.find_rust_src_root().unwrap(); + let file_stem = + self.testpaths.file.file_stem().and_then(|f| f.to_str()).expect("no file stem"); let res = self.cmd2procres( Command::new(&nodejs) .arg(root.join("src/tools/rustdoc-js/tester.js")) .arg("--doc-folder") - .arg(out_dir.parent().expect("no parent")) + .arg(out_dir) + .arg("--crate-name") + .arg(file_stem.replace("-", "_")) .arg("--test-file") .arg(self.testpaths.file.with_extension("js")), ); diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index a871fccfe30..03f06fc1c6c 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -224,7 +224,7 @@ function loadMainJsAndIndex(mainJs, aliases, searchIndex, crate) { } searchIndex.pop(); searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;'); - finalJS = ""; + var finalJS = ""; var arraysToLoad = ["itemTypes"]; var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER", @@ -306,52 +306,53 @@ function runChecks(testFile, loaded, index) { return errors; } -function load_files(doc_folder, version, crate) { - var mainJs = readFile(doc_folder + "/main" + version + ".js"); - var aliases = readFile(doc_folder + "/aliases" + version + ".js"); - var searchIndex = readFile(doc_folder + "/search-index" + version + ".js").split("\n"); +function load_files(doc_folder, resource_suffix, crate) { + var mainJs = readFile(path.join(doc_folder, "main" + resource_suffix + ".js")); + var aliases = readFile(path.join(doc_folder, "aliases" + resource_suffix + ".js")); + var searchIndex = readFile( + path.join(doc_folder, "search-index" + resource_suffix + ".js")).split("\n"); return loadMainJsAndIndex(mainJs, aliases, searchIndex, crate); } function showHelp() { console.log("rustdoc-js options:"); - console.log(" --doc-folder [PATH] : location of the generated doc folder"); - console.log(" --help : show this message then quit"); - console.log(" --std : to run std tests"); - console.log(" --test-file [PATH]: location of the JS test file"); - console.log(" --test-folder [PATH]: location of the JS tests folder"); - console.log(" --version [STRING] : version used when generating docs (used to get js files)"); + console.log(" --doc-folder [PATH] : location of the generated doc folder"); + console.log(" --help : show this message then quit"); + console.log(" --crate-name [STRING] : crate name to be used"); + console.log(" --test-file [PATH] : location of the JS test file"); + console.log(" --test-folder [PATH] : location of the JS tests folder"); + console.log(" --resource-suffix [STRING] : suffix to refer to the correct files"); } function parseOptions(args) { var opts = { - "is_std": false, - "version": "", + "crate_name": "", + "resource_suffix": "", "doc_folder": "", "test_folder": "", "test_file": "", }; var correspondances = { - "--version": "version", + "--resource-suffix": "resource_suffix", "--doc-folder": "doc_folder", "--test-folder": "test_folder", "--test-file": "test_file", + "--crate-name": "crate_name", }; for (var i = 0; i < args.length; ++i) { - if (args[i] === "--version" + if (args[i] === "--resource-suffix" || args[i] === "--doc-folder" || args[i] === "--test-folder" - || args[i] === "--test-file") { + || args[i] === "--test-file" + || args[i] === "--crate-name") { i += 1; if (i >= args.length) { console.error("Missing argument after `" + args[i - 1] + "` option."); return null; } opts[correspondances[args[i - 1]]] = args[i]; - } else if (args[i] === "--std") { - opts["is_std"] = true; } else if (args[i] === "--help") { showHelp(); process.exit(0); @@ -363,28 +364,20 @@ function parseOptions(args) { } if (opts["doc_folder"].length < 1) { console.error("Missing `--doc-folder` option."); - return null; + } else if (opts["crate_name"].length < 1) { + console.error("Missing `--crate-name` option."); } else if (opts["test_folder"].length < 1 && opts["test_file"].length < 1) { console.error("At least one of `--test-folder` or `--test-file` option is required."); - return null; - } else if (opts["is_std"] === true && opts["test_file"].length !== 0) { - console.error("`--std` and `--test-file` options can't be used at the same time.") + } else { + return opts; } - return opts; + return null; } -function checkFile(test_file, opts, std_loaded, std_index) { +function checkFile(test_file, opts, loaded, index) { const test_name = path.basename(test_file, ".js"); process.stdout.write('Checking "' + test_name + '" ... '); - - var loaded = std_loaded; - var index = std_index; - if (opts["is_std"] !== true) { - var tmp = load_files(path.join(opts["doc_folder"], test_name), opts["version"], test_name); - loaded = tmp[0]; - index = tmp[1]; - } return runChecks(test_file, loaded, index); } @@ -394,25 +387,21 @@ function main(argv) { return 1; } - var std_loaded = null; - var std_index = null; - if (opts["is_std"] === true) { - var tmp = load_files(opts["doc_folder"], opts["version"], "std"); - std_loaded = tmp[0]; - std_index = tmp[1]; - } - + var [loaded, index] = load_files( + opts["doc_folder"], + opts["resource_suffix"], + opts["crate_name"]); var errors = 0; if (opts["test_file"].length !== 0) { - errors += checkFile(opts["test_file"], opts, null, null); + errors += checkFile(opts["test_file"], opts, loaded, index); } if (opts["test_folder"].length !== 0) { fs.readdirSync(opts["test_folder"]).forEach(function(file) { if (!file.endsWith(".js")) { return; } - errors += checkFile(path.join(opts["test_folder"], file), opts, std_loaded, std_index); + errors += checkFile(path.join(opts["test_folder"], file), opts, loaded, index); }); } return errors > 0 ? 1 : 0; From b77aefb76ebb9e73cf5a26885c131674495f434d Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Mon, 13 Apr 2020 23:37:22 +0000 Subject: [PATCH 16/19] Add illumos triple Co-Authored-By: Jason King Co-Authored-By: Joshua M. Clulow --- Cargo.lock | 8 +- src/librustc_codegen_ssa/Cargo.toml | 2 +- src/librustc_codegen_ssa/back/link.rs | 2 +- src/librustc_target/spec/illumos_base.rs | 48 +++++++ src/librustc_target/spec/mod.rs | 3 + .../spec/x86_64_unknown_illumos.rs | 24 ++++ src/librustdoc/clean/cfg.rs | 1 + src/libstd/build.rs | 8 ++ src/libstd/f64.rs | 2 +- src/libstd/os/illumos/fs.rs | 118 ++++++++++++++++++ src/libstd/os/illumos/mod.rs | 6 + src/libstd/os/illumos/raw.rs | 74 +++++++++++ src/libstd/os/mod.rs | 2 + src/libstd/sys/unix/alloc.rs | 14 ++- src/libstd/sys/unix/args.rs | 1 + src/libstd/sys/unix/env.rs | 11 ++ src/libstd/sys/unix/fd.rs | 2 + src/libstd/sys/unix/fs.rs | 34 ++++- src/libstd/sys/unix/mod.rs | 2 + src/libstd/sys/unix/os.rs | 4 +- src/libstd/sys/unix/stack_overflow.rs | 5 +- src/libstd/sys/unix/thread.rs | 4 +- src/libstd/sys_common/net.rs | 4 +- src/libtest/helpers/concurrency.rs | 1 + src/libunwind/build.rs | 2 + src/tools/build-manifest/src/main.rs | 1 + src/tools/compiletest/src/util.rs | 1 + 27 files changed, 362 insertions(+), 22 deletions(-) create mode 100644 src/librustc_target/spec/illumos_base.rs create mode 100644 src/librustc_target/spec/x86_64_unknown_illumos.rs create mode 100644 src/libstd/os/illumos/fs.rs create mode 100644 src/libstd/os/illumos/mod.rs create mode 100644 src/libstd/os/illumos/raw.rs diff --git a/Cargo.lock b/Cargo.lock index e229448df04..55f986b6008 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1786,9 +1786,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.66" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" +checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" dependencies = [ "rustc-std-workspace-core", ] @@ -4661,9 +4661,9 @@ checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" [[package]] name = "socket2" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" +checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" dependencies = [ "cfg-if", "libc", diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 717e32d4a0d..d9620a21d37 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -15,7 +15,7 @@ cc = "1.0.1" num_cpus = "1.0" memmap = "0.7" log = "0.4.5" -libc = "0.2.44" +libc = "0.2.50" jobserver = "0.1.11" tempfile = "3.1" diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 20e64f0c488..0e45652f951 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -759,7 +759,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { } } LinkerFlavor::Gcc => { - if cfg!(target_os = "solaris") { + if cfg!(any(target_os = "solaris", target_os = "illumos")) { // On historical Solaris systems, "cc" may have // been Sun Studio, which is not flag-compatible // with "gcc". This history casts a long shadow, diff --git a/src/librustc_target/spec/illumos_base.rs b/src/librustc_target/spec/illumos_base.rs new file mode 100644 index 00000000000..35ac346fb3f --- /dev/null +++ b/src/librustc_target/spec/illumos_base.rs @@ -0,0 +1,48 @@ +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use std::default::Default; + +pub fn opts() -> TargetOptions { + let mut late_link_args = LinkArgs::new(); + late_link_args.insert( + LinkerFlavor::Gcc, + vec![ + // LLVM will insert calls to the stack protector functions + // "__stack_chk_fail" and "__stack_chk_guard" into code in native + // object files. Some platforms include these symbols directly in + // libc, but at least historically these have been provided in + // libssp.so on illumos and Solaris systems. + "-lssp".to_string(), + ], + ); + + TargetOptions { + dynamic_linking: true, + executables: true, + has_rpath: true, + target_family: Some("unix".to_string()), + is_like_solaris: true, + limit_rdylib_exports: false, // Linker doesn't support this + eliminate_frame_pointer: false, + late_link_args, + + // While we support ELF TLS, rust requires a way to register + // cleanup handlers (in C, this would be something along the lines of: + // void register_callback(void (*fn)(void *), void *arg); + // (see src/libstd/sys/unix/fast_thread_local.rs) that is currently + // missing in illumos. For now at least, we must fallback to using + // pthread_{get,set}specific. + //has_elf_tls: true, + + // FIXME: Currently, rust is invoking cc to link, which ends up + // causing these to get included twice. We should eventually transition + // to having rustc invoke ld directly, in which case these will need to + // be uncommented. + // + // We want XPG6 behavior from libc and libm. See standards(5) + //pre_link_objects_exe: vec![ + // "/usr/lib/amd64/values-Xc.o".to_string(), + // "/usr/lib/amd64/values-xpg6.o".to_string(), + //], + ..Default::default() + } +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1bc2bf12fad..dbbb1d5b7fd 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -56,6 +56,7 @@ mod fuchsia_base; mod haiku_base; mod hermit_base; mod hermit_kernel_base; +mod illumos_base; mod l4re_base; mod linux_base; mod linux_kernel_base; @@ -447,6 +448,8 @@ supported_targets! { ("x86_64-sun-solaris", "x86_64-pc-solaris", x86_64_sun_solaris), ("sparcv9-sun-solaris", sparcv9_sun_solaris), + ("x86_64-unknown-illumos", x86_64_unknown_illumos), + ("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu), ("i686-pc-windows-gnu", i686_pc_windows_gnu), ("i686-uwp-windows-gnu", i686_uwp_windows_gnu), diff --git a/src/librustc_target/spec/x86_64_unknown_illumos.rs b/src/librustc_target/spec/x86_64_unknown_illumos.rs new file mode 100644 index 00000000000..8d461f67397 --- /dev/null +++ b/src/librustc_target/spec/x86_64_unknown_illumos.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::illumos_base::opts(); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]); + base.cpu = "x86-64".to_string(); + base.max_atomic_width = Some(64); + + Ok(Target { + // LLVM does not currently have a separate illumos target, + // so we still pass Solaris to it + llvm_target: "x86_64-pc-solaris".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + arch: "x86_64".to_string(), + target_os: "illumos".to_string(), + target_env: String::new(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: base, + }) +} diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 775d600fc3d..57d499e38a7 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -360,6 +360,7 @@ impl<'a> fmt::Display for Html<'a> { "fuchsia" => "Fuchsia", "haiku" => "Haiku", "hermit" => "HermitCore", + "illumos" => "illumos", "ios" => "iOS", "l4re" => "L4Re", "linux" => "Linux", diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 8db7bc12cd3..743a1778fbd 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -25,6 +25,14 @@ fn main() { println!("cargo:rustc-link-lib=posix4"); println!("cargo:rustc-link-lib=pthread"); println!("cargo:rustc-link-lib=resolv"); + } else if target.contains("illumos") { + println!("cargo:rustc-link-lib=socket"); + println!("cargo:rustc-link-lib=posix4"); + println!("cargo:rustc-link-lib=pthread"); + println!("cargo:rustc-link-lib=resolv"); + println!("cargo:rustc-link-lib=nsl"); + // Use libumem for the (malloc-compatible) allocator + println!("cargo:rustc-link-lib=umem"); } else if target.contains("apple-darwin") { println!("cargo:rustc-link-lib=System"); diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index ff222fc8539..5cf9cb73d4b 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -919,7 +919,7 @@ impl f64 { // because of their non-standard behavior (e.g., log(-n) returns -Inf instead // of expected NaN). fn log_wrapper f64>(self, log_fn: F) -> f64 { - if !cfg!(target_os = "solaris") { + if !cfg!(any(target_os = "solaris", target_os = "illumos")) { log_fn(self) } else { if self.is_finite() { diff --git a/src/libstd/os/illumos/fs.rs b/src/libstd/os/illumos/fs.rs new file mode 100644 index 00000000000..2abbf1fa9fa --- /dev/null +++ b/src/libstd/os/illumos/fs.rs @@ -0,0 +1,118 @@ +#![stable(feature = "metadata_ext", since = "1.1.0")] + +use libc; + +use crate::fs::Metadata; +use crate::sys_common::AsInner; + +#[allow(deprecated)] +use crate::os::illumos::raw; + +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + /// Gain a reference to the underlying `stat` structure which contains + /// the raw information returned by the OS. + /// + /// The contents of the returned `stat` are **not** consistent across + /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the + /// cross-Unix abstractions contained within the raw stat. + #[stable(feature = "metadata_ext", since = "1.1.0")] + #[rustc_deprecated( + since = "1.8.0", + reason = "deprecated in favor of the accessor methods of this trait" + )] + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat; + + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_dev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ino(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mode(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_nlink(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_uid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_gid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_rdev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_size(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blksize(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blocks(&self) -> u64; +} + +#[stable(feature = "metadata_ext", since = "1.1.0")] +impl MetadataExt for Metadata { + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat { + unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } + } + fn st_dev(&self) -> u64 { + self.as_inner().as_inner().st_dev as u64 + } + fn st_ino(&self) -> u64 { + self.as_inner().as_inner().st_ino as u64 + } + fn st_mode(&self) -> u32 { + self.as_inner().as_inner().st_mode as u32 + } + fn st_nlink(&self) -> u64 { + self.as_inner().as_inner().st_nlink as u64 + } + fn st_uid(&self) -> u32 { + self.as_inner().as_inner().st_uid as u32 + } + fn st_gid(&self) -> u32 { + self.as_inner().as_inner().st_gid as u32 + } + fn st_rdev(&self) -> u64 { + self.as_inner().as_inner().st_rdev as u64 + } + fn st_size(&self) -> u64 { + self.as_inner().as_inner().st_size as u64 + } + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atime as i64 + } + fn st_atime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_atime_nsec as i64 + } + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtime as i64 + } + fn st_mtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_mtime_nsec as i64 + } + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctime as i64 + } + fn st_ctime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_ctime_nsec as i64 + } + fn st_blksize(&self) -> u64 { + self.as_inner().as_inner().st_blksize as u64 + } + fn st_blocks(&self) -> u64 { + self.as_inner().as_inner().st_blocks as u64 + } +} diff --git a/src/libstd/os/illumos/mod.rs b/src/libstd/os/illumos/mod.rs new file mode 100644 index 00000000000..e61926f8935 --- /dev/null +++ b/src/libstd/os/illumos/mod.rs @@ -0,0 +1,6 @@ +//! illumos-specific definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod fs; +pub mod raw; diff --git a/src/libstd/os/illumos/raw.rs b/src/libstd/os/illumos/raw.rs new file mode 100644 index 00000000000..88c832ae7c7 --- /dev/null +++ b/src/libstd/os/illumos/raw.rs @@ -0,0 +1,74 @@ +//! illumos-specific raw type definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] +#![rustc_deprecated( + since = "1.8.0", + reason = "these type aliases are no longer supported by the standard library, the `libc` \ + crate on crates.io should be used instead for the correct definitions" +)] +#![allow(deprecated)] + +use crate::os::raw::c_long; +use crate::os::unix::raw::{gid_t, uid_t}; + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type blkcnt_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type blksize_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type dev_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type fflags_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type ino_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type mode_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type nlink_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type off_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type time_t = i64; + +#[stable(feature = "pthread_t", since = "1.8.0")] +pub type pthread_t = u32; + +#[repr(C)] +#[derive(Clone)] +#[stable(feature = "raw_ext", since = "1.1.0")] +pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ino_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: mode_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: nlink_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: uid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: gid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: off_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __unused: [u8; 16], +} diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index 0fa4a1d2353..fd6ee088e96 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -52,6 +52,8 @@ pub mod freebsd; pub mod fuchsia; #[cfg(target_os = "haiku")] pub mod haiku; +#[cfg(target_os = "illumos")] +pub mod illumos; #[cfg(target_os = "ios")] pub mod ios; #[cfg(target_os = "macos")] diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs index 77417e41331..8e193935460 100644 --- a/src/libstd/sys/unix/alloc.rs +++ b/src/libstd/sys/unix/alloc.rs @@ -52,7 +52,12 @@ unsafe impl GlobalAlloc for System { } } -#[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))] +#[cfg(any( + target_os = "android", + target_os = "illumos", + target_os = "redox", + target_os = "solaris" +))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { // On android we currently target API level 9 which unfortunately @@ -75,7 +80,12 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { libc::memalign(layout.align(), layout.size()) as *mut u8 } -#[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))] +#[cfg(not(any( + target_os = "android", + target_os = "illumos", + target_os = "redox", + target_os = "solaris" +)))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 09acc3f6e3e..4c3e8542d57 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -65,6 +65,7 @@ impl DoubleEndedIterator for Args { target_os = "netbsd", target_os = "openbsd", target_os = "solaris", + target_os = "illumos", target_os = "emscripten", target_os = "haiku", target_os = "l4re", diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs index 984bcfa4509..7f5e9b04dba 100644 --- a/src/libstd/sys/unix/env.rs +++ b/src/libstd/sys/unix/env.rs @@ -97,6 +97,17 @@ pub mod os { pub const EXE_EXTENSION: &str = ""; } +#[cfg(target_os = "illumos")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "illumos"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".so"; + pub const DLL_EXTENSION: &str = "so"; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} + #[cfg(target_os = "haiku")] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 8a99836912a..1bba56e334a 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -153,6 +153,7 @@ impl FileDesc { #[cfg(not(any( target_env = "newlib", target_os = "solaris", + target_os = "illumos", target_os = "emscripten", target_os = "fuchsia", target_os = "l4re", @@ -169,6 +170,7 @@ impl FileDesc { #[cfg(any( target_env = "newlib", target_os = "solaris", + target_os = "illumos", target_os = "emscripten", target_os = "fuchsia", target_os = "l4re", diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index ab2a871b92d..a233aa47dff 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -22,6 +22,7 @@ use libc::fstatat64; target_os = "linux", target_os = "emscripten", target_os = "solaris", + target_os = "illumos", target_os = "l4re", target_os = "fuchsia", target_os = "redox" @@ -200,7 +201,12 @@ pub struct DirEntry { // on Solaris and Fuchsia because a) it uses a zero-length // array to store the name, b) its lifetime between readdir // calls is not guaranteed. - #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] + #[cfg(any( + target_os = "solaris", + target_os = "illumos", + target_os = "fuchsia", + target_os = "redox" + ))] name: Box<[u8]>, } @@ -403,7 +409,12 @@ impl fmt::Debug for ReadDir { impl Iterator for ReadDir { type Item = io::Result; - #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] + #[cfg(any( + target_os = "solaris", + target_os = "fuchsia", + target_os = "redox", + target_os = "illumos" + ))] fn next(&mut self) -> Option> { use crate::slice; @@ -441,7 +452,12 @@ impl Iterator for ReadDir { } } - #[cfg(not(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox")))] + #[cfg(not(any( + target_os = "solaris", + target_os = "fuchsia", + target_os = "redox", + target_os = "illumos" + )))] fn next(&mut self) -> Option> { if self.end_of_stream { return None; @@ -514,12 +530,12 @@ impl DirEntry { lstat(&self.path()) } - #[cfg(any(target_os = "solaris", target_os = "haiku"))] + #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "haiku"))] pub fn file_type(&self) -> io::Result { lstat(&self.path()).map(|m| m.file_type()) } - #[cfg(not(any(target_os = "solaris", target_os = "haiku")))] + #[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "haiku")))] pub fn file_type(&self) -> io::Result { match self.entry.d_type { libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }), @@ -540,6 +556,7 @@ impl DirEntry { target_os = "emscripten", target_os = "android", target_os = "solaris", + target_os = "illumos", target_os = "haiku", target_os = "l4re", target_os = "fuchsia", @@ -586,7 +603,12 @@ impl DirEntry { fn name_bytes(&self) -> &[u8] { unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() } } - #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] + #[cfg(any( + target_os = "solaris", + target_os = "illumos", + target_os = "fuchsia", + target_os = "redox" + ))] fn name_bytes(&self) -> &[u8] { &*self.name } diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index fbcb006ecdf..0154609d939 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -17,6 +17,8 @@ pub use crate::os::freebsd as platform; pub use crate::os::fuchsia as platform; #[cfg(all(not(doc), target_os = "haiku"))] pub use crate::os::haiku as platform; +#[cfg(all(not(doc), target_os = "illumos"))] +pub use crate::os::illumos as platform; #[cfg(all(not(doc), target_os = "ios"))] pub use crate::os::ios as platform; #[cfg(all(not(doc), target_os = "l4re"))] diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 91f7d1524cc..a9cd5094997 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -54,7 +54,7 @@ extern "C" { ), link_name = "__errno" )] - #[cfg_attr(target_os = "solaris", link_name = "___errno")] + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")] #[cfg_attr( any(target_os = "macos", target_os = "ios", target_os = "freebsd"), link_name = "__error" @@ -357,7 +357,7 @@ pub fn current_exe() -> io::Result { } } -#[cfg(any(target_os = "solaris"))] +#[cfg(any(target_os = "solaris", target_os = "illumos"))] pub fn current_exe() -> io::Result { extern "C" { fn getexecname() -> *const c_char; diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 2626ca37cf8..5e103578350 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -33,6 +33,7 @@ impl Drop for Handler { target_os = "dragonfly", target_os = "freebsd", target_os = "solaris", + target_os = "illumos", all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd" ))] @@ -162,7 +163,8 @@ mod imp { target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", - target_os = "solaris" + target_os = "solaris", + target_os = "illumos" ))] unsafe fn get_stack() -> libc::stack_t { libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ } @@ -214,6 +216,7 @@ mod imp { target_os = "dragonfly", target_os = "freebsd", target_os = "solaris", + target_os = "illumos", all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd" )))] diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index aab5a92a7ad..895ea48e2b4 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -132,7 +132,7 @@ impl Thread { } } - #[cfg(target_os = "solaris")] + #[cfg(any(target_os = "solaris", target_os = "illumos"))] pub fn set_name(name: &CStr) { weak! { fn pthread_setname_np( @@ -155,7 +155,7 @@ impl Thread { target_os = "redox" ))] pub fn set_name(_name: &CStr) { - // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name. + // Newlib, Haiku, and Emscripten have no way to set a thread name. } #[cfg(target_os = "fuchsia")] pub fn set_name(_name: &CStr) { diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 135e8308afa..cdd3d2edf1f 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -17,7 +17,7 @@ cfg_if::cfg_if! { if #[cfg(any( target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", - target_os = "openbsd", target_os = "netbsd", + target_os = "openbsd", target_os = "netbsd", target_os = "illumos", target_os = "solaris", target_os = "haiku", target_os = "l4re"))] { use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; @@ -43,7 +43,7 @@ cfg_if::cfg_if! { if #[cfg(any( target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", - target_os = "solaris"))] { + target_os = "solaris", target_os = "illumos"))] { use libc::c_uchar; type IpV4MultiCastType = c_uchar; } else { diff --git a/src/libtest/helpers/concurrency.rs b/src/libtest/helpers/concurrency.rs index 6b0c8a8af32..e8f3820558a 100644 --- a/src/libtest/helpers/concurrency.rs +++ b/src/libtest/helpers/concurrency.rs @@ -77,6 +77,7 @@ pub fn get_concurrency() -> usize { target_os = "linux", target_os = "macos", target_os = "solaris", + target_os = "illumos", ))] fn num_cpus() -> usize { unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index 0628e5d2fc0..c8d2419ab45 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -30,6 +30,8 @@ fn main() { } } else if target.contains("solaris") { println!("cargo:rustc-link-lib=gcc_s"); + } else if target.contains("illumos") { + println!("cargo:rustc-link-lib=gcc_s"); } else if target.contains("dragonfly") { println!("cargo:rustc-link-lib=gcc_pic"); } else if target.contains("pc-windows-gnu") { diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index f075d3e22d6..6de07d3e5cf 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -139,6 +139,7 @@ static TARGETS: &[&str] = &[ "x86_64-pc-solaris", "x86_64-unknown-cloudabi", "x86_64-unknown-freebsd", + "x86_64-unknown-illumos", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnux32", "x86_64-unknown-linux-musl", diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 2663b3d160a..c61bee0f8d9 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -21,6 +21,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("fuchsia", "fuchsia"), ("haiku", "haiku"), ("hermit", "hermit"), + ("illumos", "illumos"), ("ios", "ios"), ("l4re", "l4re"), ("linux", "linux"), From dda5c97675b4f5b1f6fdab64606c8a1f21021b0a Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Wed, 15 Apr 2020 00:44:06 +0000 Subject: [PATCH 17/19] Use fcntl() to set nonblock for solarish sockets The ioctl(FIONBIO) method of setting a file descriptor to be non-blocking does not notify the underlying resource in the same way that fcntl(F_SETFL, O_NONBLOCK) does on illumos and Solaris. --- src/libstd/sys/unix/net.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index b37675e0a0a..d18c22b0573 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -322,11 +322,19 @@ impl Socket { Ok(raw != 0) } + #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking = nonblocking as libc::c_int; cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(drop) } + #[cfg(any(target_os = "solaris", target_os = "illumos"))] + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + // FIONBIO is inadequate for sockets on illumos/Solaris, so use the + // fcntl(F_[GS]ETFL)-based method provided by FileDesc instead. + self.0.set_nonblocking(nonblocking) + } + pub fn take_error(&self) -> io::Result> { let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } From 0fcdefb5592207c328a5d8a5f3496121e170d9c0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Apr 2020 14:20:40 +0200 Subject: [PATCH 18/19] Clean up E0518 explanation --- src/librustc_error_codes/error_codes/E0518.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0518.md b/src/librustc_error_codes/error_codes/E0518.md index 1af9a3735fe..f04329bc4e6 100644 --- a/src/librustc_error_codes/error_codes/E0518.md +++ b/src/librustc_error_codes/error_codes/E0518.md @@ -1,7 +1,7 @@ -This error indicates that an `#[inline(..)]` attribute was incorrectly placed -on something other than a function or method. +An `#[inline(..)]` attribute was incorrectly placed on something other than a +function or method. -Examples of erroneous code: +Example of erroneous code: ```compile_fail,E0518 #[inline(always)] From f47c4ffdfacc783b3fe4bad395a6e16ae296b3d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 10 Mar 2020 16:24:34 -0700 Subject: [PATCH 19/19] Do not ICE in the face of invalid enum discriminant --- src/librustc_middle/ty/mod.rs | 6 +- src/librustc_mir_build/hair/cx/expr.rs | 14 +- ...377-invalid-syntax-in-enum-discriminant.rs | 35 +++++ ...invalid-syntax-in-enum-discriminant.stderr | 123 ++++++++++++++++++ 4 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs create mode 100644 src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 8d50f560a83..430ff67d56b 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -2399,7 +2399,11 @@ impl<'tcx> AdtDef { None } Err(ErrorHandled::TooGeneric) => { - span_bug!(tcx.def_span(expr_did), "enum discriminant depends on generic arguments",) + tcx.sess.delay_span_bug( + tcx.def_span(expr_did), + "enum discriminant depends on generic arguments", + ); + None } } } diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs index 21d632b9f6b..d2d99cf030d 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast, }; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; -use rustc_middle::ty::{self, AdtKind, Ty}; +use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable}; use rustc_span::Span; impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr<'tcx> { @@ -718,8 +718,7 @@ fn convert_path_expr<'a, 'tcx>( Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => { let user_provided_types = cx.tables.user_provided_types(); - let user_provided_type = user_provided_types.get(expr.hir_id).copied(); - debug!("convert_path_expr: user_provided_type={:?}", user_provided_type); + let user_ty = user_provided_types.get(expr.hir_id).copied(); let ty = cx.tables().node_type(expr.hir_id); match ty.kind { // A unit struct/variant which is used as a value. @@ -728,10 +727,17 @@ fn convert_path_expr<'a, 'tcx>( adt_def, variant_index: adt_def.variant_index_with_ctor_id(def_id), substs, - user_ty: user_provided_type, + user_ty, fields: vec![], base: None, }, + _ if ty.references_error() => { + // Handle degenerate input without ICE (#67377). + ExprKind::Literal { + literal: ty::Const::zero_sized(cx.tcx, cx.tcx.types.err), + user_ty: None, + } + } _ => bug!("unexpected ty: {:?}", ty), } } diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs new file mode 100644 index 00000000000..87222ef4b59 --- /dev/null +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs @@ -0,0 +1,35 @@ +mod a { + use std::marker::PhantomData; + + enum Bug { + V = [PhantomData; { [ () ].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + } +} + +mod b { + enum Bug { + V = [Vec::new; { [].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR type annotations needed + } +} + +mod c { + enum Bug { + V = [Vec::new; { [0].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR type annotations needed + } +} + +fn main() {} diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr new file mode 100644 index 00000000000..f20ec755353 --- /dev/null +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -0,0 +1,123 @@ +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error[E0282]: type annotations needed + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | ^^^ cannot infer type for type parameter `T` + +error[E0282]: type annotations needed + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | ^^^^^^^^ cannot infer type for type parameter `T` + +error: aborting due to 14 previous errors + +For more information about this error, try `rustc --explain E0282`.