From ce994b633d9143dd00140c64fe53194a2927dff1 Mon Sep 17 00:00:00 2001 From: Duddino Date: Tue, 14 Apr 2020 17:31:59 +0200 Subject: [PATCH 1/6] Provide better compiler output when using `?` on `Option` in fn returning `Result` and vice-versa --- .../traits/error_reporting/mod.rs | 23 ++++++++++++++- src/test/ui/option-to-result.rs | 13 +++++++++ src/test/ui/option-to-result.stderr | 29 +++++++++++++++++++ src/test/ui/try-on-option.stderr | 4 +++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/option-to-result.rs create mode 100644 src/test/ui/option-to-result.stderr diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index fef7adf02246b..a77ea33bcde09 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -292,7 +292,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { )), Some( "the question mark operation (`?`) implicitly performs a \ - conversion on the error value using the `From` trait" + conversion on the error value using the `From` trait" .to_owned(), ), ) @@ -312,6 +312,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { )) ); + let should_convert_option_to_result = + format!("{}", trait_ref.print_only_trait_path()) + .starts_with("std::convert::From` into a `Result` using `Option::ok_or` or `Option::ok_or_else`", + ".ok_or_else(|_| /* error value */)".to_string(), + Applicability::HasPlaceholders, + ); + } else if is_try && is_from && should_convert_result_to_option { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "consider converting the `Result` into an `Option` using `Result::ok`", + ".ok()".to_string(), + Applicability::HasPlaceholders, + ); + } + let explanation = if obligation.cause.code == ObligationCauseCode::MainFunctionType { "consider using `()`, or a `Result`".to_owned() diff --git a/src/test/ui/option-to-result.rs b/src/test/ui/option-to-result.rs new file mode 100644 index 0000000000000..00e8b5244c54a --- /dev/null +++ b/src/test/ui/option-to-result.rs @@ -0,0 +1,13 @@ +fn main(){ } + +fn test_result() -> Result<(),()> { + let a:Option<()> = Some(()); + a?;//~ ERROR `?` couldn't convert the error + Ok(()) +} + +fn test_option() -> Option{ + let a:Result = Ok(5); + a?;//~ ERROR `?` couldn't convert the error + Some(5) +} diff --git a/src/test/ui/option-to-result.stderr b/src/test/ui/option-to-result.stderr new file mode 100644 index 0000000000000..3c51bcece570b --- /dev/null +++ b/src/test/ui/option-to-result.stderr @@ -0,0 +1,29 @@ +error[E0277]: `?` couldn't convert the error to `()` + --> $DIR/option-to-result.rs:5:6 + | +LL | a?; + | ^ the trait `std::convert::From` is not implemented for `()` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = note: required by `std::convert::From::from` +help: consider converting the `Option` into a `Result` using `Option::ok_or` or `Option::ok_or_else` + | +LL | a.ok_or_else(|_| /* error value */)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `?` couldn't convert the error to `std::option::NoneError` + --> $DIR/option-to-result.rs:11:6 + | +LL | a?; + | ^ the trait `std::convert::From` is not implemented for `std::option::NoneError` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = note: required by `std::convert::From::from` +help: consider converting the `Result` into an `Option` using `Result::ok` + | +LL | a.ok()?; + | ^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/try-on-option.stderr b/src/test/ui/try-on-option.stderr index 07615b52a48a5..d1c0276a67ad2 100644 --- a/src/test/ui/try-on-option.stderr +++ b/src/test/ui/try-on-option.stderr @@ -6,6 +6,10 @@ LL | x?; | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = note: required by `std::convert::From::from` +help: consider converting the `Option` into a `Result` using `Option::ok_or` or `Option::ok_or_else` + | +LL | x.ok_or_else(|_| /* error value */)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`) --> $DIR/try-on-option.rs:13:5 From b77aefb76ebb9e73cf5a26885c131674495f434d Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Mon, 13 Apr 2020 23:37:22 +0000 Subject: [PATCH 2/6] 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 e229448df0477..55f986b60086c 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 717e32d4a0d8a..d9620a21d37cd 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 20e64f0c48851..0e45652f9511d 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 0000000000000..35ac346fb3f6f --- /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 1bc2bf12fad9e..dbbb1d5b7fdeb 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 0000000000000..8d461f67397f2 --- /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 775d600fc3d4b..57d499e38a77b 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 8db7bc12cd308..743a1778fbda3 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 ff222fc8539d0..5cf9cb73d4bf9 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 0000000000000..2abbf1fa9fa16 --- /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 0000000000000..e61926f89356a --- /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 0000000000000..88c832ae7c773 --- /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 0fa4a1d2353ca..fd6ee088e961c 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 77417e4133127..8e193935460eb 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 09acc3f6e3ea8..4c3e8542d576d 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 984bcfa45099b..7f5e9b04dba4b 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 8a99836912a33..1bba56e334a2e 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 ab2a871b92df4..a233aa47dff58 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 fbcb006ecdf11..0154609d939f3 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 91f7d1524ccef..a9cd5094997bd 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 2626ca37cf8b8..5e10357835056 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 aab5a92a7ad2a..895ea48e2b43e 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 135e8308afaea..cdd3d2edf1fa1 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 6b0c8a8af32b4..e8f3820558a6d 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 0628e5d2fc03a..c8d2419ab4514 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 f075d3e22d664..6de07d3e5cfd8 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 2663b3d160a7a..c61bee0f8d9ea 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 3/6] 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 b37675e0a0a00..d18c22b0573f3 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 fbc4168d809dae0408c2520ccfe585f564ad4a0b Mon Sep 17 00:00:00 2001 From: Duddino Date: Wed, 15 Apr 2020 10:57:22 +0200 Subject: [PATCH 4/6] Provide better compiler output when using `?` on `Option` in fn returning `Result` and vice-versa --- src/librustc_trait_selection/traits/error_reporting/mod.rs | 4 ++-- src/test/ui/option-to-result.stderr | 4 ++-- src/test/ui/try-on-option.stderr | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index a77ea33bcde09..904720125d3d7 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -321,7 +321,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_lo(), "consider converting the `Option` into a `Result` using `Option::ok_or` or `Option::ok_or_else`", - ".ok_or_else(|_| /* error value */)".to_string(), + ".ok_or_else(|| /* error value */)".to_string(), Applicability::HasPlaceholders, ); } else if is_try && is_from && should_convert_result_to_option { @@ -329,7 +329,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span.shrink_to_lo(), "consider converting the `Result` into an `Option` using `Result::ok`", ".ok()".to_string(), - Applicability::HasPlaceholders, + Applicability::MachineApplicable, ); } diff --git a/src/test/ui/option-to-result.stderr b/src/test/ui/option-to-result.stderr index 3c51bcece570b..f673ef7fc1e69 100644 --- a/src/test/ui/option-to-result.stderr +++ b/src/test/ui/option-to-result.stderr @@ -8,8 +8,8 @@ LL | a?; = note: required by `std::convert::From::from` help: consider converting the `Option` into a `Result` using `Option::ok_or` or `Option::ok_or_else` | -LL | a.ok_or_else(|_| /* error value */)?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | a.ok_or_else(|| /* error value */)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `?` couldn't convert the error to `std::option::NoneError` --> $DIR/option-to-result.rs:11:6 diff --git a/src/test/ui/try-on-option.stderr b/src/test/ui/try-on-option.stderr index d1c0276a67ad2..7a4bb75967b1f 100644 --- a/src/test/ui/try-on-option.stderr +++ b/src/test/ui/try-on-option.stderr @@ -8,8 +8,8 @@ LL | x?; = note: required by `std::convert::From::from` help: consider converting the `Option` into a `Result` using `Option::ok_or` or `Option::ok_or_else` | -LL | x.ok_or_else(|_| /* error value */)?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | x.ok_or_else(|| /* error value */)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`) --> $DIR/try-on-option.rs:13:5 From 0fcdefb5592207c328a5d8a5f3496121e170d9c0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Apr 2020 14:20:40 +0200 Subject: [PATCH 5/6] 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 1af9a3735fe1a..f04329bc4e618 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 6/6] 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 8d50f560a8370..430ff67d56b68 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 21d632b9f6b83..d2d99cf030d96 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 0000000000000..87222ef4b5924 --- /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 0000000000000..f20ec75535354 --- /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`.