diff options
1410 files changed, 18285 insertions, 21748 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32c18cab099..2d8980fcd1a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,24 +42,20 @@ jobs: TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" CACHE_DOMAIN: ci-caches.rust-lang.org if: "github.event_name == 'pull_request'" - continue-on-error: "${{ matrix.tidy }}" + continue-on-error: "${{ matrix.name == 'mingw-check-tidy' }}" strategy: matrix: include: - name: mingw-check - tidy: false os: ubuntu-20.04-16core-64gb env: {} - name: mingw-check-tidy - tidy: true os: ubuntu-20.04-16core-64gb env: {} - name: x86_64-gnu-llvm-14 - tidy: false os: ubuntu-20.04-16core-64gb env: {} - name: x86_64-gnu-tools - tidy: false os: ubuntu-20.04-16core-64gb env: {} timeout-minutes: 600 @@ -98,9 +94,6 @@ jobs: - name: show the current environment run: src/ci/scripts/dump-environment.sh if: success() && !env.SKIP_JOB - - name: install awscli - run: src/ci/scripts/install-awscli.sh - if: success() && !env.SKIP_JOB - name: install sccache run: src/ci/scripts/install-sccache.sh if: success() && !env.SKIP_JOB @@ -170,6 +163,7 @@ jobs: TOOLSTATE_PUBLISH: 1 CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 + AWS_REGION: us-west-1 CACHE_DOMAIN: ci-caches.rust-lang.org if: "github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" strategy: @@ -260,13 +254,13 @@ jobs: os: ubuntu-20.04-8core-32gb env: {} - name: i686-gnu - os: ubuntu-20.04-16core-64gb + os: ubuntu-20.04-8core-32gb env: {} - name: i686-gnu-nopt - os: ubuntu-20.04-16core-64gb + os: ubuntu-20.04-8core-32gb env: {} - name: mingw-check - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb env: {} - name: test-various os: ubuntu-20.04-8core-32gb @@ -275,16 +269,16 @@ jobs: os: ubuntu-20.04-8core-32gb env: {} - name: x86_64-gnu - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb env: {} - name: x86_64-gnu-stable env: IMAGE: x86_64-gnu RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable CI_ONLY_WHEN_CHANNEL: nightly - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb - name: x86_64-gnu-aux - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb env: {} - name: x86_64-gnu-debug os: ubuntu-20.04-8core-32gb @@ -309,7 +303,7 @@ jobs: RUST_BACKTRACE: 1 os: ubuntu-20.04-8core-32gb - name: x86_64-gnu-nopt - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb env: {} - name: x86_64-gnu-tools env: @@ -521,9 +515,6 @@ jobs: - name: show the current environment run: src/ci/scripts/dump-environment.sh if: success() && !env.SKIP_JOB - - name: install awscli - run: src/ci/scripts/install-awscli.sh - if: success() && !env.SKIP_JOB - name: install sccache run: src/ci/scripts/install-sccache.sh if: success() && !env.SKIP_JOB @@ -593,6 +584,7 @@ jobs: TOOLSTATE_PUBLISH: 1 CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 + AWS_REGION: us-west-1 CACHE_DOMAIN: ci-caches.rust-lang.org if: "github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" strategy: @@ -637,9 +629,6 @@ jobs: - name: show the current environment run: src/ci/scripts/dump-environment.sh if: success() && !env.SKIP_JOB - - name: install awscli - run: src/ci/scripts/install-awscli.sh - if: success() && !env.SKIP_JOB - name: install sccache run: src/ci/scripts/install-sccache.sh if: success() && !env.SKIP_JOB @@ -706,6 +695,7 @@ jobs: TOOLSTATE_PUBLISH: 1 CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 + AWS_REGION: us-west-1 CACHE_DOMAIN: ci-caches.rust-lang.org if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'" steps: diff --git a/Cargo.lock b/Cargo.lock index f6ee8157b40..bab73ff6770 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,6 +297,7 @@ dependencies = [ "sha2", "tar", "toml", + "xz2", ] [[package]] @@ -576,7 +577,7 @@ checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "clippy" -version = "0.1.70" +version = "0.1.71" dependencies = [ "clap 4.2.1", "clippy_lints", @@ -618,7 +619,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.70" +version = "0.1.71" dependencies = [ "arrayvec", "cargo_metadata 0.15.3", @@ -642,7 +643,7 @@ dependencies = [ [[package]] name = "clippy_utils" -version = "0.1.70" +version = "0.1.71" dependencies = [ "arrayvec", "if_chain", @@ -968,7 +969,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69" [[package]] name = "declare_clippy_lint" -version = "0.1.70" +version = "0.1.71" dependencies = [ "itertools", "quote", @@ -1545,9 +1546,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash 0.7.4", - "compiler_builtins", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", ] [[package]] @@ -1557,6 +1555,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" dependencies = [ "ahash 0.8.2", + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", ] [[package]] @@ -1654,9 +1655,9 @@ dependencies = [ [[package]] name = "icu_list" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a65ff0cab77c33c7e165c858eaa6e84a09f1e485dd495d9d0ae61083c6f786" +checksum = "fd7ba7442d9235b689d4fdce17c452ea229934980fd81ba50cc28275752c9f90" dependencies = [ "displaydoc", "icu_provider", @@ -1666,9 +1667,9 @@ dependencies = [ [[package]] name = "icu_locid" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d7a98ecb812760b5f077e55a4763edeefa7ccc30d6eb5680a70841ede81928" +checksum = "3003f85dccfc0e238ff567693248c59153a46f4e6125ba4020b973cef4d1d335" dependencies = [ "displaydoc", "litemap", @@ -1679,9 +1680,9 @@ dependencies = [ [[package]] name = "icu_provider" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a86816c97bc4e613086497f9479f63e120315e056763e8c4435604f98d21d82d" +checksum = "8dc312a7b6148f7dfe098047ae2494d12d4034f48ade58d4f353000db376e305" dependencies = [ "displaydoc", "icu_locid", @@ -1695,9 +1696,9 @@ dependencies = [ [[package]] name = "icu_provider_adapters" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e89bf33962b24bb48a4a21330c20c9ff17949338ea376360dd9eda2c209dca1" +checksum = "f4ae1e2bd0c41728b77e7c46e9afdec5e2127d1eedacc684724667d50c126bd3" dependencies = [ "icu_locid", "icu_provider", @@ -1708,9 +1709,9 @@ dependencies = [ [[package]] name = "icu_provider_macros" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ddb07844c2ffc4c28840e799e9e54ff054393cf090740decf25624e9d94b93a" +checksum = "dd8b728b9421e93eff1d9f8681101b78fa745e0748c95c655c83f337044a7e10" dependencies = [ "proc-macro2", "quote", @@ -2031,9 +2032,9 @@ checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "litemap" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575d8a551c59104b4df91269921e5eab561aa1b77c618dac0414b5d44a4617de" +checksum = "3a04a5b2b6f54acba899926491d0a6c59d98012938ca2ab5befb281c034e8f94" [[package]] name = "lld-wrapper" @@ -2060,9 +2061,9 @@ dependencies = [ [[package]] name = "lzma-sys" -version = "0.1.16" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24f76ec44a8ac23a31915d6e326bca17ce88da03096f1ff194925dc714dac99" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" dependencies = [ "cc", "libc", @@ -2908,9 +2909,9 @@ dependencies = [ [[package]] name = "rustc-build-sysroot" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65b1271cdac365b71b59570ea35d945dea2dd2cc47eba3d33b4bd1e0190ac6d" +checksum = "8ed2a90dfa5232ed5ff21d53d4df655f315ab316ea06fc508f1c74bcedb1ce6c" dependencies = [ "anyhow", "rustc_version", @@ -3164,6 +3165,7 @@ dependencies = [ "rustc_expand", "rustc_feature", "rustc_fluent_macro", + "rustc_index", "rustc_lexer", "rustc_lint_defs", "rustc_macros", @@ -4059,6 +4061,7 @@ dependencies = [ "indexmap", "rustc_macros", "smallvec", + "tempfile", "thin-vec", ] @@ -4090,6 +4093,7 @@ dependencies = [ name = "rustc_smir" version = "0.0.0" dependencies = [ + "rustc_hir", "rustc_middle", "rustc_span", "tracing", @@ -4603,7 +4607,7 @@ dependencies = [ "core", "dlmalloc", "fortanix-sgx-abi", - "hashbrown 0.12.3", + "hashbrown 0.13.1", "hermit-abi 0.3.0", "libc", "miniz_oxide", @@ -4737,6 +4741,15 @@ dependencies = [ ] [[package]] +name = "sysroot" +version = "0.0.0" +dependencies = [ + "proc_macro", + "std", + "test", +] + +[[package]] name = "tar" version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4820,7 +4833,6 @@ dependencies = [ "getopts", "panic_abort", "panic_unwind", - "proc_macro", "std", ] @@ -5100,11 +5112,12 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "ui_test" -version = "0.5.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ddb6f31025943e2f9d59237f433711c461a43d9415974c3eb3a4902edc1c1f" +checksum = "3e10f5f88ce8c331a388deda1e6e2bd533c73ca89cc5f539a3df02ed35c8efba" dependencies = [ "bstr 1.3.0", + "cargo-platform", "cargo_metadata 0.15.3", "color-eyre", "colored", @@ -5113,6 +5126,7 @@ dependencies = [ "lazy_static", "regex", "rustc_version", + "rustfix", "serde", "serde_json", "tempfile", @@ -5656,9 +5670,9 @@ dependencies = [ [[package]] name = "xz2" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" dependencies = [ "lzma-sys", ] @@ -5694,9 +5708,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222180af14a6b54ef2c33493c1eff77ae95a3687a21b243e752624006fb8f26e" +checksum = "1848075a23a28f9773498ee9a0f2cf58fcbad4f8c0ccf84a210ab33c6ae495de" dependencies = [ "serde", "stable_deref_trait", @@ -5739,9 +5753,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "154df60c74c4a844bc04a53cef4fc18a909d3ea07e19f5225eaba86209da3aa6" +checksum = "198f54134cd865f437820aa3b43d0ad518af4e68ee161b444cdd15d8e567c8ea" dependencies = [ "yoke", "zerofrom", diff --git a/Cargo.toml b/Cargo.toml index a497d7321e0..7aaa34a68e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ members = [ "compiler/rustc", "library/std", - "library/test", + "library/sysroot", "src/rustdoc-json-types", "src/tools/build_helper", "src/tools/cargotest", diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index b4597d5bc78..3d97d9b4895 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -729,42 +729,73 @@ pub trait LayoutCalculator { align = align.max(AbiAndPrefAlign::new(repr_align)); } - let optimize = !repr.inhibit_union_abi_opt(); + // If all the non-ZST fields have the same ABI and union ABI optimizations aren't + // disabled, we can use that common ABI for the union as a whole. + struct AbiMismatch; + let mut common_non_zst_abi_and_align = if repr.inhibit_union_abi_opt() { + // Can't optimize + Err(AbiMismatch) + } else { + Ok(None) + }; + let mut size = Size::ZERO; - let mut abi = Abi::Aggregate { sized: true }; let only_variant = &variants[FIRST_VARIANT]; for field in only_variant { assert!(field.0.is_sized()); + align = align.max(field.align()); + size = cmp::max(size, field.size()); - // If all non-ZST fields have the same ABI, forward this ABI - if optimize && !field.0.is_zst() { + if field.0.is_zst() { + // Nothing more to do for ZST fields + continue; + } + + if let Ok(common) = common_non_zst_abi_and_align { // Discard valid range information and allow undef - let field_abi = match field.abi() { - Abi::Scalar(x) => Abi::Scalar(x.to_union()), - Abi::ScalarPair(x, y) => Abi::ScalarPair(x.to_union(), y.to_union()), - Abi::Vector { element: x, count } => { - Abi::Vector { element: x.to_union(), count } - } - Abi::Uninhabited | Abi::Aggregate { .. } => Abi::Aggregate { sized: true }, - }; + let field_abi = field.abi().to_union(); - if size == Size::ZERO { - // first non ZST: initialize 'abi' - abi = field_abi; - } else if abi != field_abi { - // different fields have different ABI: reset to Aggregate - abi = Abi::Aggregate { sized: true }; + if let Some((common_abi, common_align)) = common { + if common_abi != field_abi { + // Different fields have different ABI: disable opt + common_non_zst_abi_and_align = Err(AbiMismatch); + } else { + // Fields with the same non-Aggregate ABI should also + // have the same alignment + if !matches!(common_abi, Abi::Aggregate { .. }) { + assert_eq!( + common_align, + field.align().abi, + "non-Aggregate field with matching ABI but differing alignment" + ); + } + } + } else { + // First non-ZST field: record its ABI and alignment + common_non_zst_abi_and_align = Ok(Some((field_abi, field.align().abi))); } } - - size = cmp::max(size, field.size()); } if let Some(pack) = repr.pack { align = align.min(AbiAndPrefAlign::new(pack)); } + // If all non-ZST fields have the same ABI, we may forward that ABI + // for the union as a whole, unless otherwise inhibited. + let abi = match common_non_zst_abi_and_align { + Err(AbiMismatch) | Ok(None) => Abi::Aggregate { sized: true }, + Ok(Some((abi, _))) => { + if abi.inherent_align(dl).map(|a| a.abi) != Some(align.abi) { + // Mismatched alignment (e.g. union is #[repr(packed)]): disable opt + Abi::Aggregate { sized: true } + } else { + abi + } + } + }; + Some(LayoutS { variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?), diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index d01a9b00304..43db66a3c28 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1272,6 +1272,50 @@ impl Abi { pub fn is_scalar(&self) -> bool { matches!(*self, Abi::Scalar(_)) } + + /// Returns the fixed alignment of this ABI, if any is mandated. + pub fn inherent_align<C: HasDataLayout>(&self, cx: &C) -> Option<AbiAndPrefAlign> { + Some(match *self { + Abi::Scalar(s) => s.align(cx), + Abi::ScalarPair(s1, s2) => s1.align(cx).max(s2.align(cx)), + Abi::Vector { element, count } => { + cx.data_layout().vector_align(element.size(cx) * count) + } + Abi::Uninhabited | Abi::Aggregate { .. } => return None, + }) + } + + /// Returns the fixed size of this ABI, if any is mandated. + pub fn inherent_size<C: HasDataLayout>(&self, cx: &C) -> Option<Size> { + Some(match *self { + Abi::Scalar(s) => { + // No padding in scalars. + s.size(cx) + } + Abi::ScalarPair(s1, s2) => { + // May have some padding between the pair. + let field2_offset = s1.size(cx).align_to(s2.align(cx).abi); + (field2_offset + s2.size(cx)).align_to(self.inherent_align(cx)?.abi) + } + Abi::Vector { element, count } => { + // No padding in vectors, except possibly for trailing padding + // to make the size a multiple of align (e.g. for vectors of size 3). + (element.size(cx) * count).align_to(self.inherent_align(cx)?.abi) + } + Abi::Uninhabited | Abi::Aggregate { .. } => return None, + }) + } + + /// Discard validity range information and allow undef. + pub fn to_union(&self) -> Self { + assert!(self.is_sized()); + match *self { + Abi::Scalar(s) => Abi::Scalar(s.to_union()), + Abi::ScalarPair(s1, s2) => Abi::ScalarPair(s1.to_union(), s2.to_union()), + Abi::Vector { element, count } => Abi::Vector { element: element.to_union(), count }, + Abi::Uninhabited | Abi::Aggregate { .. } => Abi::Aggregate { sized: true }, + } + } } #[derive(PartialEq, Eq, Hash, Clone, Debug)] diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ea04ba4f66e..e3ac8a8784a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -287,12 +287,20 @@ pub enum TraitBoundModifier { /// No modifiers None, + /// `!Trait` + Negative, + /// `?Trait` Maybe, /// `~const Trait` MaybeConst, + /// `~const !Trait` + // + // This parses but will be rejected during AST validation. + MaybeConstNegative, + /// `~const ?Trait` // // This parses but will be rejected during AST validation. @@ -1589,7 +1597,6 @@ pub enum ClosureBinder { pub struct MacCall { pub path: Path, pub args: P<DelimArgs>, - pub prior_type_ascription: Option<(Span, bool)>, } impl MacCall { @@ -1814,6 +1821,8 @@ pub enum LitKind { /// A byte string (`b"foo"`). Not stored as a symbol because it might be /// non-utf8, and symbols only allow utf8 strings. ByteStr(Lrc<[u8]>, StrStyle), + /// A C String (`c"foo"`). Guaranteed to only have `\0` at the end. + CStr(Lrc<[u8]>, StrStyle), /// A byte char (`b'f'`). Byte(u8), /// A character literal (`'a'`). @@ -1868,6 +1877,7 @@ impl LitKind { // unsuffixed variants LitKind::Str(..) | LitKind::ByteStr(..) + | LitKind::CStr(..) | LitKind::Byte(..) | LitKind::Char(..) | LitKind::Int(_, LitIntType::Unsuffixed) @@ -2447,6 +2457,16 @@ impl fmt::Debug for ImplPolarity { } } +#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)] +pub enum BoundPolarity { + /// `Type: Trait` + Positive, + /// `Type: !Trait` + Negative(Span), + /// `Type: ?Trait` + Maybe(Span), +} + #[derive(Clone, Encodable, Decodable, Debug)] pub enum FnRetTy { /// Returns type is not specified. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 68a4d522993..66b94d12a32 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -631,7 +631,7 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { } pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) { - let MacCall { path, args, prior_type_ascription: _ } = mac; + let MacCall { path, args } = mac; vis.visit_path(path); visit_delim_args(args, vis); } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index f947ae4d057..42b843482a3 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -74,6 +74,8 @@ pub enum LitKind { StrRaw(u8), // raw string delimited by `n` hash symbols ByteStr, ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols + CStr, + CStrRaw(u8), Err, } @@ -141,6 +143,10 @@ impl fmt::Display for Lit { delim = "#".repeat(n as usize), string = symbol )?, + CStr => write!(f, "c\"{symbol}\"")?, + CStrRaw(n) => { + write!(f, "cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize))? + } Integer | Float | Bool | Err => write!(f, "{symbol}")?, } @@ -170,6 +176,7 @@ impl LitKind { Float => "float", Str | StrRaw(..) => "string", ByteStr | ByteStrRaw(..) => "byte string", + CStr | CStrRaw(..) => "C string", Err => "error", } } diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 74b842ac96e..15a54fe13d0 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -2,9 +2,13 @@ use crate::ast::{self, LitKind, MetaItemLit, StrStyle}; use crate::token::{self, Token}; -use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode}; +use rustc_lexer::unescape::{ + byte_from_char, unescape_byte, unescape_c_string, unescape_char, unescape_literal, CStrUnit, + Mode, +}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; +use std::ops::Range; use std::{ascii, fmt, str}; // Escapes a string, represented as a symbol. Reuses the original symbol, @@ -35,6 +39,7 @@ pub enum LitError { InvalidFloatSuffix, NonDecimalFloat(u32), IntTooLarge(u32), + NulInCStr(Range<usize>), } impl LitKind { @@ -158,6 +163,52 @@ impl LitKind { LitKind::ByteStr(bytes.into(), StrStyle::Raw(n)) } + token::CStr => { + let s = symbol.as_str(); + let mut buf = Vec::with_capacity(s.len()); + let mut error = Ok(()); + unescape_c_string(s, Mode::CStr, &mut |span, c| match c { + Ok(CStrUnit::Byte(0) | CStrUnit::Char('\0')) => { + error = Err(LitError::NulInCStr(span)); + } + Ok(CStrUnit::Byte(b)) => buf.push(b), + Ok(CStrUnit::Char(c)) if c.len_utf8() == 1 => buf.push(c as u8), + Ok(CStrUnit::Char(c)) => { + buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes()) + } + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); + } + } + }); + error?; + buf.push(0); + LitKind::CStr(buf.into(), StrStyle::Cooked) + } + token::CStrRaw(n) => { + let s = symbol.as_str(); + let mut buf = Vec::with_capacity(s.len()); + let mut error = Ok(()); + unescape_c_string(s, Mode::RawCStr, &mut |span, c| match c { + Ok(CStrUnit::Byte(0) | CStrUnit::Char('\0')) => { + error = Err(LitError::NulInCStr(span)); + } + Ok(CStrUnit::Byte(b)) => buf.push(b), + Ok(CStrUnit::Char(c)) if c.len_utf8() == 1 => buf.push(c as u8), + Ok(CStrUnit::Char(c)) => { + buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes()) + } + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); + } + } + }); + error?; + buf.push(0); + LitKind::CStr(buf.into(), StrStyle::Raw(n)) + } token::Err => LitKind::Err, }) } @@ -191,6 +242,14 @@ impl fmt::Display for LitKind { string = symbol )?; } + LitKind::CStr(ref bytes, StrStyle::Cooked) => { + write!(f, "c\"{}\"", escape_byte_str_symbol(bytes))? + } + LitKind::CStr(ref bytes, StrStyle::Raw(n)) => { + // This can only be valid UTF-8. + let symbol = str::from_utf8(bytes).unwrap(); + write!(f, "cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize),)?; + } LitKind::Int(n, ty) => { write!(f, "{n}")?; match ty { @@ -237,6 +296,8 @@ impl MetaItemLit { LitKind::Str(_, ast::StrStyle::Raw(n)) => token::StrRaw(n), LitKind::ByteStr(_, ast::StrStyle::Cooked) => token::ByteStr, LitKind::ByteStr(_, ast::StrStyle::Raw(n)) => token::ByteStrRaw(n), + LitKind::CStr(_, ast::StrStyle::Cooked) => token::CStr, + LitKind::CStr(_, ast::StrStyle::Raw(n)) => token::CStrRaw(n), LitKind::Byte(_) => token::Byte, LitKind::Char(_) => token::Char, LitKind::Int(..) => token::Integer, diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 64ae904513c..35afd542372 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -53,8 +53,6 @@ pub enum AssocOp { DotDot, /// `..=` range DotDotEq, - /// `:` - Colon, } #[derive(PartialEq, Debug)] @@ -96,7 +94,6 @@ impl AssocOp { token::DotDotEq => Some(DotDotEq), // DotDotDot is no longer supported, but we need some way to display the error token::DotDotDot => Some(DotDotEq), - token::Colon => Some(Colon), // `<-` should probably be `< -` token::LArrow => Some(Less), _ if t.is_keyword(kw::As) => Some(As), @@ -133,7 +130,7 @@ impl AssocOp { pub fn precedence(&self) -> usize { use AssocOp::*; match *self { - As | Colon => 14, + As => 14, Multiply | Divide | Modulus => 13, Add | Subtract => 12, ShiftLeft | ShiftRight => 11, @@ -156,7 +153,7 @@ impl AssocOp { Assign | AssignOp(_) => Fixity::Right, As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual - | LAnd | LOr | Colon => Fixity::Left, + | LAnd | LOr => Fixity::Left, DotDot | DotDotEq => Fixity::None, } } @@ -166,8 +163,9 @@ impl AssocOp { match *self { Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true, Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract - | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq - | Colon => false, + | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq => { + false + } } } @@ -177,7 +175,7 @@ impl AssocOp { Assign | AssignOp(_) => true, Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor - | BitOr | LAnd | LOr | DotDot | DotDotEq | Colon => false, + | BitOr | LAnd | LOr | DotDot | DotDotEq => false, } } @@ -202,7 +200,7 @@ impl AssocOp { BitOr => Some(BinOpKind::BitOr), LAnd => Some(BinOpKind::And), LOr => Some(BinOpKind::Or), - Assign | AssignOp(_) | As | DotDot | DotDotEq | Colon => None, + Assign | AssignOp(_) | As | DotDot | DotDotEq => None, } } @@ -223,10 +221,9 @@ impl AssocOp { Greater | // `{ 42 } > 3` GreaterEqual | // `{ 42 } >= 3` AssignOp(_) | // `{ 42 } +=` - As | // `{ 42 } as usize` // Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect - // NotEqual | // `{ 42 } != { 42 }` struct literals parser recovery. - Colon, // `{ 42 }: usize` + // NotEqual | // `{ 42 } != { 42 } struct literals parser recovery. + As // `{ 42 } as usize` ) } } @@ -254,7 +251,6 @@ pub enum ExprPrecedence { Binary(BinOpKind), Cast, - Type, Assign, AssignOp, @@ -313,7 +309,6 @@ impl ExprPrecedence { // Binop-like expr kinds, handled by `AssocOp`. ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8, ExprPrecedence::Cast => AssocOp::As.precedence() as i8, - ExprPrecedence::Type => AssocOp::Colon.precedence() as i8, ExprPrecedence::Assign | ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b5b28bf8e31..4100efb6eb3 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1368,13 +1368,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound { GenericBound::Trait( ty, - TraitBoundModifier::None | TraitBoundModifier::MaybeConst, + TraitBoundModifier::None + | TraitBoundModifier::MaybeConst + | TraitBoundModifier::Negative, ) => Some(this.lower_poly_trait_ref(ty, itctx)), // `~const ?Bound` will cause an error during AST validation // anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait( _, - TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe, + TraitBoundModifier::Maybe + | TraitBoundModifier::MaybeConstMaybe + | TraitBoundModifier::MaybeConstNegative, ) => None, GenericBound::Outlives(lifetime) => { if lifetime_bound.is_none() { @@ -2421,11 +2425,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TraitBoundModifier::None => hir::TraitBoundModifier::None, TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst, + TraitBoundModifier::Negative => { + if self.tcx.features().negative_bounds { + hir::TraitBoundModifier::Negative + } else { + hir::TraitBoundModifier::None + } + } + // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a // placeholder for compilation to proceed. TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => { hir::TraitBoundModifier::Maybe } + TraitBoundModifier::MaybeConstNegative => hir::TraitBoundModifier::MaybeConst, } } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 8eb84c036a0..441282c05b4 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -136,7 +136,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.diagnostic().span_bug( p.span, - &format!( + format!( "lower_qpath: no final extension segment in {}..{}", proj_start, p.segments.len() diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index ffca37ae9d5..2f413789e77 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -206,7 +206,7 @@ ast_passes_tilde_const_disallowed = `~const` is not allowed here .closure = closures cannot have `~const` trait bounds .function = this function is not `const`, so it cannot have `~const` trait bounds -ast_passes_optional_const_exclusive = `~const` and `?` are mutually exclusive +ast_passes_optional_const_exclusive = `~const` and `{$modifier}` are mutually exclusive ast_passes_const_and_async = functions cannot be both `const` and `async` .const = `const` because of this @@ -235,3 +235,9 @@ ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using t .help = remove one of these features ast_passes_show_span = {$msg} + +ast_passes_negative_bound_not_supported = + negative bounds are not supported + +ast_passes_constraint_on_negative_bound = + associated type constraints not allowed on negative bounds diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index c79626ccd76..bf43bbdbbee 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1168,12 +1168,27 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }); } (_, TraitBoundModifier::MaybeConstMaybe) => { - self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span()}); + self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "?" }); + } + (_, TraitBoundModifier::MaybeConstNegative) => { + self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "!" }); } _ => {} } } + // Negative trait bounds are not allowed to have associated constraints + if let GenericBound::Trait(trait_ref, TraitBoundModifier::Negative) = bound + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(ast::GenericArgs::AngleBracketed(args)) = segment.args.as_deref() + { + for arg in &args.args { + if let ast::AngleBracketedArg::Constraint(constraint) = arg { + self.err_handler().emit_err(errors::ConstraintOnNegativeBound { span: constraint.span }); + } + } + } + visit::walk_param_bound(self, bound) } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 1732865f0bb..82fe2a21d08 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -567,6 +567,7 @@ pub enum TildeConstReason { pub struct OptionalConstExclusive { #[primary_span] pub span: Span, + pub modifier: &'static str, } #[derive(Diagnostic)] @@ -693,3 +694,17 @@ pub struct ShowSpan { pub span: Span, pub msg: &'static str, } + +#[derive(Diagnostic)] +#[diag(ast_passes_negative_bound_not_supported)] +pub struct NegativeBoundUnsupported { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_constraint_on_negative_bound)] +pub struct ConstraintOnNegativeBound { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 17bcd24ee39..b960671bf6e 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -83,7 +83,7 @@ impl<'a> PostExpansionVisitor<'a> { &self, const_extern_fn, span, - &format!("`{}` as a `const fn` ABI is unstable", abi) + format!("`{}` as a `const fn` ABI is unstable", abi) ), } } @@ -104,7 +104,7 @@ impl<'a> PostExpansionVisitor<'a> { if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) { self.sess.parse_sess.span_diagnostic.delay_span_bug( span, - &format!( + format!( "unrecognized ABI not caught in lowering: {}", symbol_unescaped.as_str() ), @@ -572,6 +572,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { } }; } + gate_all!(c_str_literals, "`c\"..\"` literals are experimental"); gate_all!( if_let_guard, "`if let` guards are experimental", @@ -603,6 +604,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { gate_all!(dyn_star, "`dyn*` trait objects are experimental"); gate_all!(const_closures, "const closures are experimental"); + if !visitor.features.negative_bounds { + for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() { + sess.emit_err(errors::NegativeBoundUnsupported { span }); + } + } + // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). // We emit an early future-incompatible warning for these. diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 849336c8669..3f80728a260 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -210,6 +210,10 @@ pub fn literal_to_string(lit: token::Lit) -> String { token::ByteStrRaw(n) => { format!("br{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol) } + token::CStr => format!("c\"{symbol}\""), + token::CStrRaw(n) => { + format!("cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize)) + } token::Integer | token::Float | token::Bool | token::Err => symbol.to_string(), }; @@ -1570,12 +1574,19 @@ impl<'a> State<'a> { GenericBound::Trait(tref, modifier) => { match modifier { TraitBoundModifier::None => {} + TraitBoundModifier::Negative => { + self.word("!"); + } TraitBoundModifier::Maybe => { self.word("?"); } TraitBoundModifier::MaybeConst => { self.word_space("~const"); } + TraitBoundModifier::MaybeConstNegative => { + self.word_space("~const"); + self.word("!"); + } TraitBoundModifier::MaybeConstMaybe => { self.word_space("~const"); self.word("?"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 5511cf851b1..b74c59bca30 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -341,10 +341,16 @@ impl<'a> State<'a> { self.print_type(ty); } ast::ExprKind::Type(expr, ty) => { - let prec = AssocOp::Colon.precedence() as i8; - self.print_expr_maybe_paren(expr, prec); - self.word_space(":"); + self.word("type_ascribe!("); + self.ibox(0); + self.print_expr(expr); + + self.word(","); + self.space_if_not_bol(); self.print_type(ty); + + self.end(); + self.word(")"); } ast::ExprKind::Let(pat, scrutinee, _) => { self.print_let(pat, scrutinee); diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index cb217be6654..2a3092d3c7b 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -5,6 +5,7 @@ use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedM use rustc_ast_pretty::pprust; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_macros::HashStable_Generic; +use rustc_session::config::ExpectedValues; use rustc_session::lint::builtin::UNEXPECTED_CFGS; use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::parse::{feature_err, ParseSess}; @@ -581,32 +582,32 @@ pub fn cfg_matches( ) -> bool { eval_condition(cfg, sess, features, &mut |cfg| { try_gate_cfg(cfg.name, cfg.span, sess, features); - if let Some(names_valid) = &sess.check_config.names_valid { - if !names_valid.contains(&cfg.name) { + match sess.check_config.expecteds.get(&cfg.name) { + Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => { sess.buffer_lint_with_diagnostic( UNEXPECTED_CFGS, cfg.span, lint_node_id, - "unexpected `cfg` condition name", - BuiltinLintDiagnostics::UnexpectedCfg((cfg.name, cfg.name_span), None), + "unexpected `cfg` condition value", + BuiltinLintDiagnostics::UnexpectedCfgValue( + (cfg.name, cfg.name_span), + cfg.value.map(|v| (v, cfg.value_span.unwrap())), + ), ); } - } - if let Some(value) = cfg.value { - if let Some(values) = &sess.check_config.values_valid.get(&cfg.name) { - if !values.contains(&value) { - sess.buffer_lint_with_diagnostic( - UNEXPECTED_CFGS, - cfg.span, - lint_node_id, - "unexpected `cfg` condition value", - BuiltinLintDiagnostics::UnexpectedCfg( - (cfg.name, cfg.name_span), - cfg.value_span.map(|vs| (value, vs)), - ), - ); - } + None if sess.check_config.exhaustive_names => { + sess.buffer_lint_with_diagnostic( + UNEXPECTED_CFGS, + cfg.span, + lint_node_id, + "unexpected `cfg` condition name", + BuiltinLintDiagnostics::UnexpectedCfgName( + (cfg.name, cfg.name_span), + cfg.value.map(|v| (v, cfg.value_span.unwrap())), + ), + ); } + _ => { /* not unexpected */ } } sess.config.contains(&(cfg.name, cfg.value)) }) @@ -623,7 +624,7 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &F let (cfg, feature, has_feature) = gated_cfg; if !has_feature(features) && !cfg_span.allows_unstable(*feature) { let explain = format!("`cfg({cfg})` is experimental and subject to change"); - feature_err(sess, *feature, cfg_span, &explain).emit(); + feature_err(sess, *feature, cfg_span, explain).emit(); } } diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml index 184fea86832..d3a307675ac 100644 --- a/compiler/rustc_baked_icu_data/Cargo.toml +++ b/compiler/rustc_baked_icu_data/Cargo.toml @@ -4,11 +4,11 @@ version = "0.0.0" edition = "2021" [dependencies] -icu_list = "1.1.0" -icu_locid = "1.1.0" -icu_provider = "1.1.0" -icu_provider_adapters = "1.1.0" -zerovec = "0.9.2" +icu_list = "1.2" +icu_locid = "1.2" +icu_provider = "1.2" +icu_provider_adapters = "1.2" +zerovec = "0.9.4" [features] rustc_use_parallel_compiler = ['icu_provider/sync'] diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1/und.rs.data b/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1/und.rs.data index 4fd177834e9..e4aaf50f5d6 100644 --- a/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1/und.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1/und.rs.data @@ -3,223 +3,10 @@ #[allow(unused_unsafe)] ::zerovec::ZeroMap::from_parts_unchecked( unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 97u8, 98u8, 0u8, 97u8, 98u8, 113u8, 97u8, 100u8, 112u8, 97u8, 100u8, 121u8, - 97u8, 101u8, 0u8, 97u8, 101u8, 98u8, 97u8, 104u8, 111u8, 97u8, 106u8, - 116u8, 97u8, 107u8, 107u8, 97u8, 108u8, 116u8, 97u8, 109u8, 0u8, 97u8, - 112u8, 99u8, 97u8, 112u8, 100u8, 97u8, 114u8, 0u8, 97u8, 114u8, 99u8, 97u8, - 114u8, 113u8, 97u8, 114u8, 115u8, 97u8, 114u8, 121u8, 97u8, 114u8, 122u8, - 97u8, 115u8, 0u8, 97u8, 115u8, 101u8, 97u8, 118u8, 0u8, 97u8, 118u8, 108u8, - 97u8, 119u8, 97u8, 98u8, 97u8, 0u8, 98u8, 97u8, 108u8, 98u8, 97u8, 112u8, - 98u8, 97u8, 120u8, 98u8, 99u8, 113u8, 98u8, 101u8, 0u8, 98u8, 101u8, 106u8, - 98u8, 102u8, 113u8, 98u8, 102u8, 116u8, 98u8, 102u8, 121u8, 98u8, 103u8, - 0u8, 98u8, 103u8, 99u8, 98u8, 103u8, 110u8, 98u8, 103u8, 120u8, 98u8, - 104u8, 98u8, 98u8, 104u8, 105u8, 98u8, 104u8, 111u8, 98u8, 106u8, 105u8, - 98u8, 106u8, 106u8, 98u8, 108u8, 116u8, 98u8, 110u8, 0u8, 98u8, 111u8, 0u8, - 98u8, 112u8, 121u8, 98u8, 113u8, 105u8, 98u8, 114u8, 97u8, 98u8, 114u8, - 104u8, 98u8, 114u8, 120u8, 98u8, 115u8, 113u8, 98u8, 115u8, 116u8, 98u8, - 116u8, 118u8, 98u8, 117u8, 97u8, 98u8, 121u8, 110u8, 99u8, 99u8, 112u8, - 99u8, 101u8, 0u8, 99u8, 104u8, 109u8, 99u8, 104u8, 114u8, 99u8, 106u8, - 97u8, 99u8, 106u8, 109u8, 99u8, 107u8, 98u8, 99u8, 109u8, 103u8, 99u8, - 111u8, 112u8, 99u8, 114u8, 0u8, 99u8, 114u8, 104u8, 99u8, 114u8, 107u8, - 99u8, 114u8, 108u8, 99u8, 115u8, 119u8, 99u8, 116u8, 100u8, 99u8, 117u8, - 0u8, 99u8, 118u8, 0u8, 100u8, 97u8, 114u8, 100u8, 99u8, 99u8, 100u8, 103u8, - 108u8, 100u8, 109u8, 102u8, 100u8, 111u8, 105u8, 100u8, 114u8, 104u8, - 100u8, 114u8, 115u8, 100u8, 116u8, 121u8, 100u8, 118u8, 0u8, 100u8, 122u8, - 0u8, 101u8, 103u8, 121u8, 101u8, 107u8, 121u8, 101u8, 108u8, 0u8, 101u8, - 115u8, 103u8, 101u8, 116u8, 116u8, 102u8, 97u8, 0u8, 102u8, 105u8, 97u8, - 102u8, 117u8, 98u8, 103u8, 97u8, 110u8, 103u8, 98u8, 109u8, 103u8, 98u8, - 122u8, 103u8, 101u8, 122u8, 103u8, 103u8, 110u8, 103u8, 106u8, 107u8, - 103u8, 106u8, 117u8, 103u8, 108u8, 107u8, 103u8, 109u8, 118u8, 103u8, - 111u8, 102u8, 103u8, 111u8, 109u8, 103u8, 111u8, 110u8, 103u8, 111u8, - 116u8, 103u8, 114u8, 99u8, 103u8, 114u8, 116u8, 103u8, 117u8, 0u8, 103u8, - 118u8, 114u8, 103u8, 119u8, 99u8, 103u8, 119u8, 116u8, 104u8, 97u8, 107u8, - 104u8, 97u8, 122u8, 104u8, 100u8, 121u8, 104u8, 101u8, 0u8, 104u8, 105u8, - 0u8, 104u8, 108u8, 117u8, 104u8, 109u8, 100u8, 104u8, 110u8, 100u8, 104u8, - 110u8, 101u8, 104u8, 110u8, 106u8, 104u8, 110u8, 111u8, 104u8, 111u8, 99u8, - 104u8, 111u8, 106u8, 104u8, 115u8, 110u8, 104u8, 121u8, 0u8, 105u8, 105u8, - 0u8, 105u8, 110u8, 104u8, 105u8, 117u8, 0u8, 105u8, 119u8, 0u8, 106u8, - 97u8, 0u8, 106u8, 105u8, 0u8, 106u8, 109u8, 108u8, 107u8, 97u8, 0u8, 107u8, - 97u8, 97u8, 107u8, 97u8, 119u8, 107u8, 98u8, 100u8, 107u8, 98u8, 121u8, - 107u8, 100u8, 116u8, 107u8, 102u8, 114u8, 107u8, 102u8, 121u8, 107u8, - 104u8, 98u8, 107u8, 104u8, 110u8, 107u8, 104u8, 116u8, 107u8, 104u8, 119u8, - 107u8, 106u8, 103u8, 107u8, 107u8, 0u8, 107u8, 109u8, 0u8, 107u8, 110u8, - 0u8, 107u8, 111u8, 0u8, 107u8, 111u8, 105u8, 107u8, 111u8, 107u8, 107u8, - 113u8, 121u8, 107u8, 114u8, 99u8, 107u8, 114u8, 117u8, 107u8, 115u8, 0u8, - 107u8, 116u8, 98u8, 107u8, 117u8, 109u8, 107u8, 118u8, 0u8, 107u8, 118u8, - 120u8, 107u8, 120u8, 99u8, 107u8, 120u8, 108u8, 107u8, 120u8, 109u8, 107u8, - 120u8, 112u8, 107u8, 121u8, 0u8, 107u8, 122u8, 104u8, 108u8, 97u8, 98u8, - 108u8, 97u8, 100u8, 108u8, 97u8, 104u8, 108u8, 98u8, 101u8, 108u8, 99u8, - 112u8, 108u8, 101u8, 112u8, 108u8, 101u8, 122u8, 108u8, 105u8, 102u8, - 108u8, 105u8, 115u8, 108u8, 107u8, 105u8, 108u8, 109u8, 110u8, 108u8, - 111u8, 0u8, 108u8, 114u8, 99u8, 108u8, 117u8, 122u8, 108u8, 119u8, 108u8, - 108u8, 122u8, 104u8, 109u8, 97u8, 103u8, 109u8, 97u8, 105u8, 109u8, 100u8, - 101u8, 109u8, 100u8, 102u8, 109u8, 100u8, 120u8, 109u8, 102u8, 97u8, 109u8, - 103u8, 112u8, 109u8, 107u8, 0u8, 109u8, 107u8, 105u8, 109u8, 108u8, 0u8, - 109u8, 110u8, 0u8, 109u8, 110u8, 105u8, 109u8, 110u8, 119u8, 109u8, 114u8, - 0u8, 109u8, 114u8, 100u8, 109u8, 114u8, 106u8, 109u8, 114u8, 111u8, 109u8, - 116u8, 114u8, 109u8, 118u8, 121u8, 109u8, 119u8, 114u8, 109u8, 119u8, - 119u8, 109u8, 121u8, 0u8, 109u8, 121u8, 109u8, 109u8, 121u8, 118u8, 109u8, - 121u8, 122u8, 109u8, 122u8, 110u8, 110u8, 97u8, 110u8, 110u8, 101u8, 0u8, - 110u8, 101u8, 119u8, 110u8, 110u8, 112u8, 110u8, 111u8, 100u8, 110u8, - 111u8, 101u8, 110u8, 111u8, 110u8, 110u8, 113u8, 111u8, 110u8, 115u8, - 107u8, 110u8, 115u8, 116u8, 111u8, 106u8, 0u8, 111u8, 106u8, 115u8, 111u8, - 114u8, 0u8, 111u8, 114u8, 117u8, 111u8, 115u8, 0u8, 111u8, 115u8, 97u8, - 111u8, 116u8, 97u8, 111u8, 116u8, 107u8, 111u8, 117u8, 105u8, 112u8, 97u8, - 0u8, 112u8, 97u8, 108u8, 112u8, 101u8, 111u8, 112u8, 104u8, 108u8, 112u8, - 104u8, 110u8, 112u8, 107u8, 97u8, 112u8, 110u8, 116u8, 112u8, 112u8, 97u8, - 112u8, 114u8, 97u8, 112u8, 114u8, 100u8, 112u8, 115u8, 0u8, 114u8, 97u8, - 106u8, 114u8, 104u8, 103u8, 114u8, 105u8, 102u8, 114u8, 106u8, 115u8, - 114u8, 107u8, 116u8, 114u8, 109u8, 116u8, 114u8, 117u8, 0u8, 114u8, 117u8, - 101u8, 114u8, 121u8, 117u8, 115u8, 97u8, 0u8, 115u8, 97u8, 104u8, 115u8, - 97u8, 116u8, 115u8, 97u8, 122u8, 115u8, 99u8, 107u8, 115u8, 99u8, 108u8, - 115u8, 100u8, 0u8, 115u8, 100u8, 104u8, 115u8, 103u8, 97u8, 115u8, 103u8, - 119u8, 115u8, 104u8, 105u8, 115u8, 104u8, 110u8, 115u8, 104u8, 117u8, - 115u8, 105u8, 0u8, 115u8, 107u8, 114u8, 115u8, 109u8, 112u8, 115u8, 111u8, - 103u8, 115u8, 111u8, 117u8, 115u8, 114u8, 0u8, 115u8, 114u8, 98u8, 115u8, - 114u8, 120u8, 115u8, 119u8, 98u8, 115u8, 119u8, 118u8, 115u8, 121u8, 108u8, - 115u8, 121u8, 114u8, 116u8, 97u8, 0u8, 116u8, 97u8, 106u8, 116u8, 99u8, - 121u8, 116u8, 100u8, 100u8, 116u8, 100u8, 103u8, 116u8, 100u8, 104u8, - 116u8, 101u8, 0u8, 116u8, 103u8, 0u8, 116u8, 104u8, 0u8, 116u8, 104u8, - 108u8, 116u8, 104u8, 113u8, 116u8, 104u8, 114u8, 116u8, 105u8, 0u8, 116u8, - 105u8, 103u8, 116u8, 107u8, 116u8, 116u8, 114u8, 119u8, 116u8, 115u8, - 100u8, 116u8, 115u8, 102u8, 116u8, 115u8, 106u8, 116u8, 116u8, 0u8, 116u8, - 116u8, 115u8, 116u8, 120u8, 103u8, 116u8, 120u8, 111u8, 116u8, 121u8, - 118u8, 117u8, 100u8, 105u8, 117u8, 100u8, 109u8, 117u8, 103u8, 0u8, 117u8, - 103u8, 97u8, 117u8, 107u8, 0u8, 117u8, 110u8, 114u8, 117u8, 110u8, 120u8, - 117u8, 114u8, 0u8, 118u8, 97u8, 105u8, 119u8, 97u8, 108u8, 119u8, 98u8, - 113u8, 119u8, 98u8, 114u8, 119u8, 110u8, 105u8, 119u8, 115u8, 103u8, 119u8, - 116u8, 109u8, 119u8, 117u8, 117u8, 120u8, 99u8, 111u8, 120u8, 99u8, 114u8, - 120u8, 108u8, 99u8, 120u8, 108u8, 100u8, 120u8, 109u8, 102u8, 120u8, 109u8, - 110u8, 120u8, 109u8, 114u8, 120u8, 110u8, 97u8, 120u8, 110u8, 114u8, 120u8, - 112u8, 114u8, 120u8, 115u8, 97u8, 120u8, 115u8, 114u8, 121u8, 105u8, 0u8, - 121u8, 117u8, 101u8, 122u8, 100u8, 106u8, 122u8, 103u8, 104u8, 122u8, - 104u8, 0u8, 122u8, 104u8, 120u8, 122u8, 107u8, 116u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"am\0ar\0as\0be\0bg\0bgcbhobn\0brxchrcv\0doiel\0fa\0gu\0he\0hi\0hy\0ja\0ka\0kk\0km\0kn\0ko\0kokks\0ky\0lo\0maimk\0ml\0mn\0mnimr\0my\0ne\0or\0pa\0ps\0rajru\0sa\0satsd\0si\0sr\0ta\0te\0tg\0th\0ti\0tt\0uk\0ur\0yuezh\0") }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 84u8, 105u8, 98u8, - 116u8, 67u8, 121u8, 114u8, 108u8, 65u8, 118u8, 115u8, 116u8, 65u8, 114u8, - 97u8, 98u8, 65u8, 104u8, 111u8, 109u8, 65u8, 114u8, 97u8, 98u8, 88u8, - 115u8, 117u8, 120u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8, 105u8, - 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, - 65u8, 114u8, 109u8, 105u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, - 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 66u8, 101u8, 110u8, - 103u8, 83u8, 103u8, 110u8, 119u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, - 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 65u8, - 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 66u8, 97u8, 109u8, 117u8, - 69u8, 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, 97u8, - 98u8, 84u8, 97u8, 109u8, 108u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, - 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, 118u8, 97u8, 65u8, - 114u8, 97u8, 98u8, 71u8, 114u8, 101u8, 107u8, 68u8, 101u8, 118u8, 97u8, - 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 69u8, 116u8, 104u8, - 105u8, 68u8, 101u8, 118u8, 97u8, 84u8, 97u8, 118u8, 116u8, 66u8, 101u8, - 110u8, 103u8, 84u8, 105u8, 98u8, 116u8, 66u8, 101u8, 110u8, 103u8, 65u8, - 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 68u8, - 101u8, 118u8, 97u8, 66u8, 97u8, 115u8, 115u8, 69u8, 116u8, 104u8, 105u8, - 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8, - 105u8, 67u8, 97u8, 107u8, 109u8, 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, - 114u8, 108u8, 67u8, 104u8, 101u8, 114u8, 65u8, 114u8, 97u8, 98u8, 67u8, - 104u8, 97u8, 109u8, 65u8, 114u8, 97u8, 98u8, 83u8, 111u8, 121u8, 111u8, - 67u8, 111u8, 112u8, 116u8, 67u8, 97u8, 110u8, 115u8, 67u8, 121u8, 114u8, - 108u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, - 110u8, 115u8, 80u8, 97u8, 117u8, 99u8, 67u8, 121u8, 114u8, 108u8, 67u8, - 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, - 65u8, 114u8, 97u8, 98u8, 77u8, 101u8, 100u8, 102u8, 68u8, 101u8, 118u8, - 97u8, 77u8, 111u8, 110u8, 103u8, 69u8, 116u8, 104u8, 105u8, 68u8, 101u8, - 118u8, 97u8, 84u8, 104u8, 97u8, 97u8, 84u8, 105u8, 98u8, 116u8, 69u8, - 103u8, 121u8, 112u8, 75u8, 97u8, 108u8, 105u8, 71u8, 114u8, 101u8, 107u8, - 71u8, 111u8, 110u8, 109u8, 73u8, 116u8, 97u8, 108u8, 65u8, 114u8, 97u8, - 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, - 115u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 69u8, 116u8, - 104u8, 105u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 65u8, - 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, - 69u8, 116u8, 104u8, 105u8, 68u8, 101u8, 118u8, 97u8, 84u8, 101u8, 108u8, - 117u8, 71u8, 111u8, 116u8, 104u8, 67u8, 112u8, 114u8, 116u8, 66u8, 101u8, - 110u8, 103u8, 71u8, 117u8, 106u8, 114u8, 68u8, 101u8, 118u8, 97u8, 65u8, - 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 65u8, - 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, 72u8, 101u8, 98u8, 114u8, - 68u8, 101u8, 118u8, 97u8, 72u8, 108u8, 117u8, 119u8, 80u8, 108u8, 114u8, - 100u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 109u8, - 110u8, 112u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 68u8, - 101u8, 118u8, 97u8, 72u8, 97u8, 110u8, 115u8, 65u8, 114u8, 109u8, 110u8, - 89u8, 105u8, 105u8, 105u8, 67u8, 121u8, 114u8, 108u8, 67u8, 97u8, 110u8, - 115u8, 72u8, 101u8, 98u8, 114u8, 74u8, 112u8, 97u8, 110u8, 72u8, 101u8, - 98u8, 114u8, 68u8, 101u8, 118u8, 97u8, 71u8, 101u8, 111u8, 114u8, 67u8, - 121u8, 114u8, 108u8, 75u8, 97u8, 119u8, 105u8, 67u8, 121u8, 114u8, 108u8, - 65u8, 114u8, 97u8, 98u8, 84u8, 104u8, 97u8, 105u8, 68u8, 101u8, 118u8, - 97u8, 68u8, 101u8, 118u8, 97u8, 84u8, 97u8, 108u8, 117u8, 68u8, 101u8, - 118u8, 97u8, 77u8, 121u8, 109u8, 114u8, 65u8, 114u8, 97u8, 98u8, 76u8, - 97u8, 111u8, 111u8, 67u8, 121u8, 114u8, 108u8, 75u8, 104u8, 109u8, 114u8, - 75u8, 110u8, 100u8, 97u8, 75u8, 111u8, 114u8, 101u8, 67u8, 121u8, 114u8, - 108u8, 68u8, 101u8, 118u8, 97u8, 69u8, 116u8, 104u8, 105u8, 67u8, 121u8, - 114u8, 108u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 69u8, - 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, - 65u8, 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, 68u8, 101u8, 118u8, - 97u8, 84u8, 104u8, 97u8, 105u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, - 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 76u8, 105u8, 110u8, 97u8, 72u8, - 101u8, 98u8, 114u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, - 84u8, 104u8, 97u8, 105u8, 76u8, 101u8, 112u8, 99u8, 67u8, 121u8, 114u8, - 108u8, 68u8, 101u8, 118u8, 97u8, 76u8, 105u8, 115u8, 117u8, 65u8, 114u8, - 97u8, 98u8, 84u8, 101u8, 108u8, 117u8, 76u8, 97u8, 111u8, 111u8, 65u8, - 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 84u8, 104u8, 97u8, 105u8, 72u8, - 97u8, 110u8, 115u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, - 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8, - 105u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, - 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 77u8, 108u8, 121u8, 109u8, 67u8, - 121u8, 114u8, 108u8, 66u8, 101u8, 110u8, 103u8, 77u8, 121u8, 109u8, 114u8, - 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, - 108u8, 77u8, 114u8, 111u8, 111u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, - 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 109u8, 110u8, 112u8, 77u8, - 121u8, 109u8, 114u8, 69u8, 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, - 77u8, 97u8, 110u8, 100u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, - 115u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 87u8, 99u8, - 104u8, 111u8, 76u8, 97u8, 110u8, 97u8, 68u8, 101u8, 118u8, 97u8, 82u8, - 117u8, 110u8, 114u8, 78u8, 107u8, 111u8, 111u8, 67u8, 97u8, 110u8, 115u8, - 84u8, 110u8, 115u8, 97u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, 110u8, - 115u8, 79u8, 114u8, 121u8, 97u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, - 114u8, 108u8, 79u8, 115u8, 103u8, 101u8, 65u8, 114u8, 97u8, 98u8, 79u8, - 114u8, 107u8, 104u8, 79u8, 117u8, 103u8, 114u8, 71u8, 117u8, 114u8, 117u8, - 80u8, 104u8, 108u8, 105u8, 88u8, 112u8, 101u8, 111u8, 65u8, 114u8, 97u8, - 98u8, 80u8, 104u8, 110u8, 120u8, 66u8, 114u8, 97u8, 104u8, 71u8, 114u8, - 101u8, 107u8, 68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 97u8, 114u8, 65u8, - 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 82u8, - 111u8, 104u8, 103u8, 84u8, 102u8, 110u8, 103u8, 68u8, 101u8, 118u8, 97u8, - 66u8, 101u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, - 108u8, 67u8, 121u8, 114u8, 108u8, 75u8, 97u8, 110u8, 97u8, 68u8, 101u8, - 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 79u8, 108u8, 99u8, 107u8, 83u8, - 97u8, 117u8, 114u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, - 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 79u8, 103u8, 97u8, 109u8, - 69u8, 116u8, 104u8, 105u8, 84u8, 102u8, 110u8, 103u8, 77u8, 121u8, 109u8, - 114u8, 65u8, 114u8, 97u8, 98u8, 83u8, 105u8, 110u8, 104u8, 65u8, 114u8, - 97u8, 98u8, 83u8, 97u8, 109u8, 114u8, 83u8, 111u8, 103u8, 100u8, 84u8, - 104u8, 97u8, 105u8, 67u8, 121u8, 114u8, 108u8, 83u8, 111u8, 114u8, 97u8, - 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, - 97u8, 66u8, 101u8, 110u8, 103u8, 83u8, 121u8, 114u8, 99u8, 84u8, 97u8, - 109u8, 108u8, 68u8, 101u8, 118u8, 97u8, 75u8, 110u8, 100u8, 97u8, 84u8, - 97u8, 108u8, 101u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, - 84u8, 101u8, 108u8, 117u8, 67u8, 121u8, 114u8, 108u8, 84u8, 104u8, 97u8, - 105u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, - 118u8, 97u8, 69u8, 116u8, 104u8, 105u8, 69u8, 116u8, 104u8, 105u8, 68u8, - 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 71u8, 114u8, 101u8, 107u8, - 68u8, 101u8, 118u8, 97u8, 84u8, 105u8, 98u8, 116u8, 67u8, 121u8, 114u8, - 108u8, 84u8, 104u8, 97u8, 105u8, 84u8, 97u8, 110u8, 103u8, 84u8, 111u8, - 116u8, 111u8, 67u8, 121u8, 114u8, 108u8, 65u8, 103u8, 104u8, 98u8, 67u8, - 121u8, 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 85u8, 103u8, 97u8, 114u8, - 67u8, 121u8, 114u8, 108u8, 66u8, 101u8, 110u8, 103u8, 66u8, 101u8, 110u8, - 103u8, 65u8, 114u8, 97u8, 98u8, 86u8, 97u8, 105u8, 105u8, 69u8, 116u8, - 104u8, 105u8, 84u8, 101u8, 108u8, 117u8, 68u8, 101u8, 118u8, 97u8, 65u8, - 114u8, 97u8, 98u8, 71u8, 111u8, 110u8, 103u8, 68u8, 101u8, 118u8, 97u8, - 72u8, 97u8, 110u8, 115u8, 67u8, 104u8, 114u8, 115u8, 67u8, 97u8, 114u8, - 105u8, 76u8, 121u8, 99u8, 105u8, 76u8, 121u8, 100u8, 105u8, 71u8, 101u8, - 111u8, 114u8, 77u8, 97u8, 110u8, 105u8, 77u8, 101u8, 114u8, 99u8, 78u8, - 97u8, 114u8, 98u8, 68u8, 101u8, 118u8, 97u8, 80u8, 114u8, 116u8, 105u8, - 83u8, 97u8, 114u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 101u8, 98u8, - 114u8, 72u8, 97u8, 110u8, 116u8, 65u8, 114u8, 97u8, 98u8, 84u8, 102u8, - 110u8, 103u8, 72u8, 97u8, 110u8, 115u8, 78u8, 115u8, 104u8, 117u8, 75u8, - 105u8, 116u8, 115u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"EthiArabBengCyrlCyrlDevaDevaBengDevaCherCyrlDevaGrekArabGujrHebrDevaArmnJpanGeorCyrlKhmrKndaKoreDevaArabCyrlLaooDevaCyrlMlymCyrlBengDevaMymrDevaOryaGuruArabDevaCyrlDevaOlckArabSinhCyrlTamlTeluCyrlThaiEthiCyrlCyrlArabHantHans") }, ) }, @@ -227,58 +14,18 @@ #[allow(unused_unsafe)] ::zerovec::ZeroMap2d::from_parts_unchecked( unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 97u8, 122u8, 0u8, 104u8, 97u8, 0u8, 107u8, 107u8, 0u8, 107u8, 117u8, 0u8, - 107u8, 121u8, 0u8, 109u8, 97u8, 110u8, 109u8, 110u8, 0u8, 109u8, 115u8, - 0u8, 112u8, 97u8, 0u8, 114u8, 105u8, 102u8, 115u8, 100u8, 0u8, 115u8, - 114u8, 0u8, 116u8, 103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8, - 117u8, 122u8, 0u8, 121u8, 117u8, 101u8, 122u8, 104u8, 0u8, - ]) + ::zerovec::ZeroVec::from_bytes_unchecked( + b"az\0ha\0kk\0ky\0mn\0ms\0pa\0sd\0sr\0tg\0uz\0yuezh\0", + ) }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 3u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 10u8, 0u8, 0u8, - 0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 15u8, - 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, - 0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 26u8, - 0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8, 29u8, 0u8, 0u8, 0u8, 44u8, 0u8, 0u8, - 0u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"\x03\0\0\0\x05\0\0\0\t\0\0\0\x0B\0\0\0\x0C\0\0\0\r\0\0\0\x0E\0\0\0\x0F\0\0\0\x13\0\0\0\x14\0\0\0\x16\0\0\0\x17\0\0\0&\0\0\0") }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 73u8, 81u8, 0u8, 73u8, 82u8, 0u8, 82u8, 85u8, 0u8, 67u8, 77u8, 0u8, 83u8, - 68u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 73u8, 82u8, 0u8, 77u8, 78u8, - 0u8, 76u8, 66u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 71u8, 78u8, 0u8, - 67u8, 78u8, 0u8, 67u8, 67u8, 0u8, 80u8, 75u8, 0u8, 78u8, 76u8, 0u8, 73u8, - 78u8, 0u8, 77u8, 69u8, 0u8, 82u8, 79u8, 0u8, 82u8, 85u8, 0u8, 84u8, 82u8, - 0u8, 80u8, 75u8, 0u8, 75u8, 90u8, 0u8, 77u8, 78u8, 0u8, 78u8, 80u8, 0u8, - 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 67u8, 78u8, 0u8, 65u8, 85u8, 0u8, 66u8, - 78u8, 0u8, 71u8, 66u8, 0u8, 71u8, 70u8, 0u8, 72u8, 75u8, 0u8, 73u8, 68u8, - 0u8, 77u8, 79u8, 0u8, 80u8, 65u8, 0u8, 80u8, 70u8, 0u8, 80u8, 72u8, 0u8, - 83u8, 82u8, 0u8, 84u8, 72u8, 0u8, 84u8, 87u8, 0u8, 85u8, 83u8, 0u8, 86u8, - 78u8, 0u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"IQ\0IR\0RU\0CM\0SD\0AF\0CN\0IR\0MN\0CN\0TR\0CN\0CC\0PK\0IN\0ME\0RO\0RU\0TR\0PK\0AF\0CN\0CN\0AU\0BN\0GB\0GF\0HK\0ID\0MO\0PA\0PF\0PH\0SR\0TH\0TW\0US\0VN\0") }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, - 108u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, - 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, - 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, 116u8, - 110u8, 78u8, 107u8, 111u8, 111u8, 77u8, 111u8, 110u8, 103u8, 65u8, 114u8, - 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, 116u8, 110u8, 68u8, 101u8, - 118u8, 97u8, 76u8, 97u8, 116u8, 110u8, 76u8, 97u8, 116u8, 110u8, 76u8, - 97u8, 116u8, 110u8, 76u8, 97u8, 116u8, 110u8, 65u8, 114u8, 97u8, 98u8, - 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, 118u8, - 97u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 72u8, 97u8, - 110u8, 115u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, - 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, - 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, - 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, - 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, - 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"ArabArabCyrlArabArabArabArabArabArabArabLatnMongArabArabDevaLatnLatnLatnLatnArabArabCyrlHansHantHantHantHantHantHantHantHantHantHantHantHantHantHantHant") }, ) }, @@ -286,392 +33,10 @@ #[allow(unused_unsafe)] ::zerovec::ZeroMap::from_parts_unchecked( unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 97u8, 97u8, 0u8, 97u8, 98u8, 0u8, 97u8, 98u8, 114u8, 97u8, 99u8, 101u8, - 97u8, 99u8, 104u8, 97u8, 100u8, 97u8, 97u8, 100u8, 112u8, 97u8, 100u8, - 121u8, 97u8, 101u8, 0u8, 97u8, 101u8, 98u8, 97u8, 102u8, 0u8, 97u8, 103u8, - 113u8, 97u8, 104u8, 111u8, 97u8, 106u8, 116u8, 97u8, 107u8, 0u8, 97u8, - 107u8, 107u8, 97u8, 108u8, 110u8, 97u8, 108u8, 116u8, 97u8, 109u8, 0u8, - 97u8, 109u8, 111u8, 97u8, 110u8, 0u8, 97u8, 110u8, 110u8, 97u8, 111u8, - 122u8, 97u8, 112u8, 100u8, 97u8, 114u8, 0u8, 97u8, 114u8, 99u8, 97u8, - 114u8, 110u8, 97u8, 114u8, 111u8, 97u8, 114u8, 113u8, 97u8, 114u8, 115u8, - 97u8, 114u8, 121u8, 97u8, 114u8, 122u8, 97u8, 115u8, 0u8, 97u8, 115u8, - 97u8, 97u8, 115u8, 101u8, 97u8, 115u8, 116u8, 97u8, 116u8, 106u8, 97u8, - 118u8, 0u8, 97u8, 119u8, 97u8, 97u8, 121u8, 0u8, 97u8, 122u8, 0u8, 98u8, - 97u8, 0u8, 98u8, 97u8, 108u8, 98u8, 97u8, 110u8, 98u8, 97u8, 112u8, 98u8, - 97u8, 114u8, 98u8, 97u8, 115u8, 98u8, 97u8, 120u8, 98u8, 98u8, 99u8, 98u8, - 98u8, 106u8, 98u8, 99u8, 105u8, 98u8, 101u8, 0u8, 98u8, 101u8, 106u8, 98u8, - 101u8, 109u8, 98u8, 101u8, 119u8, 98u8, 101u8, 122u8, 98u8, 102u8, 100u8, - 98u8, 102u8, 113u8, 98u8, 102u8, 116u8, 98u8, 102u8, 121u8, 98u8, 103u8, - 0u8, 98u8, 103u8, 99u8, 98u8, 103u8, 110u8, 98u8, 103u8, 120u8, 98u8, - 104u8, 98u8, 98u8, 104u8, 105u8, 98u8, 104u8, 111u8, 98u8, 105u8, 0u8, - 98u8, 105u8, 107u8, 98u8, 105u8, 110u8, 98u8, 106u8, 106u8, 98u8, 106u8, - 110u8, 98u8, 106u8, 116u8, 98u8, 107u8, 109u8, 98u8, 107u8, 117u8, 98u8, - 108u8, 97u8, 98u8, 108u8, 103u8, 98u8, 108u8, 116u8, 98u8, 109u8, 0u8, - 98u8, 109u8, 113u8, 98u8, 110u8, 0u8, 98u8, 111u8, 0u8, 98u8, 112u8, 121u8, - 98u8, 113u8, 105u8, 98u8, 113u8, 118u8, 98u8, 114u8, 0u8, 98u8, 114u8, - 97u8, 98u8, 114u8, 104u8, 98u8, 114u8, 120u8, 98u8, 115u8, 0u8, 98u8, - 115u8, 113u8, 98u8, 115u8, 115u8, 98u8, 116u8, 111u8, 98u8, 116u8, 118u8, - 98u8, 117u8, 97u8, 98u8, 117u8, 99u8, 98u8, 117u8, 103u8, 98u8, 117u8, - 109u8, 98u8, 118u8, 98u8, 98u8, 121u8, 110u8, 98u8, 121u8, 118u8, 98u8, - 122u8, 101u8, 99u8, 97u8, 0u8, 99u8, 97u8, 100u8, 99u8, 99u8, 104u8, 99u8, - 99u8, 112u8, 99u8, 101u8, 0u8, 99u8, 101u8, 98u8, 99u8, 103u8, 103u8, 99u8, - 104u8, 0u8, 99u8, 104u8, 107u8, 99u8, 104u8, 109u8, 99u8, 104u8, 111u8, - 99u8, 104u8, 112u8, 99u8, 104u8, 114u8, 99u8, 105u8, 99u8, 99u8, 106u8, - 97u8, 99u8, 106u8, 109u8, 99u8, 107u8, 98u8, 99u8, 108u8, 99u8, 99u8, - 109u8, 103u8, 99u8, 111u8, 0u8, 99u8, 111u8, 112u8, 99u8, 112u8, 115u8, - 99u8, 114u8, 0u8, 99u8, 114u8, 103u8, 99u8, 114u8, 104u8, 99u8, 114u8, - 107u8, 99u8, 114u8, 108u8, 99u8, 114u8, 115u8, 99u8, 115u8, 0u8, 99u8, - 115u8, 98u8, 99u8, 115u8, 119u8, 99u8, 116u8, 100u8, 99u8, 117u8, 0u8, - 99u8, 118u8, 0u8, 99u8, 121u8, 0u8, 100u8, 97u8, 0u8, 100u8, 97u8, 102u8, - 100u8, 97u8, 107u8, 100u8, 97u8, 114u8, 100u8, 97u8, 118u8, 100u8, 99u8, - 99u8, 100u8, 101u8, 0u8, 100u8, 101u8, 110u8, 100u8, 103u8, 114u8, 100u8, - 106u8, 101u8, 100u8, 109u8, 102u8, 100u8, 110u8, 106u8, 100u8, 111u8, - 105u8, 100u8, 114u8, 104u8, 100u8, 115u8, 98u8, 100u8, 116u8, 109u8, 100u8, - 116u8, 112u8, 100u8, 116u8, 121u8, 100u8, 117u8, 97u8, 100u8, 118u8, 0u8, - 100u8, 121u8, 111u8, 100u8, 121u8, 117u8, 100u8, 122u8, 0u8, 101u8, 98u8, - 117u8, 101u8, 101u8, 0u8, 101u8, 102u8, 105u8, 101u8, 103u8, 108u8, 101u8, - 103u8, 121u8, 101u8, 107u8, 121u8, 101u8, 108u8, 0u8, 101u8, 110u8, 0u8, - 101u8, 111u8, 0u8, 101u8, 115u8, 0u8, 101u8, 115u8, 103u8, 101u8, 115u8, - 117u8, 101u8, 116u8, 0u8, 101u8, 116u8, 116u8, 101u8, 117u8, 0u8, 101u8, - 119u8, 111u8, 101u8, 120u8, 116u8, 102u8, 97u8, 0u8, 102u8, 97u8, 110u8, - 102u8, 102u8, 0u8, 102u8, 102u8, 109u8, 102u8, 105u8, 0u8, 102u8, 105u8, - 97u8, 102u8, 105u8, 108u8, 102u8, 105u8, 116u8, 102u8, 106u8, 0u8, 102u8, - 111u8, 0u8, 102u8, 111u8, 110u8, 102u8, 114u8, 0u8, 102u8, 114u8, 99u8, - 102u8, 114u8, 112u8, 102u8, 114u8, 114u8, 102u8, 114u8, 115u8, 102u8, - 117u8, 98u8, 102u8, 117u8, 100u8, 102u8, 117u8, 102u8, 102u8, 117u8, 113u8, - 102u8, 117u8, 114u8, 102u8, 117u8, 118u8, 102u8, 118u8, 114u8, 102u8, - 121u8, 0u8, 103u8, 97u8, 0u8, 103u8, 97u8, 97u8, 103u8, 97u8, 103u8, 103u8, - 97u8, 110u8, 103u8, 97u8, 121u8, 103u8, 98u8, 109u8, 103u8, 98u8, 122u8, - 103u8, 99u8, 114u8, 103u8, 100u8, 0u8, 103u8, 101u8, 122u8, 103u8, 103u8, - 110u8, 103u8, 105u8, 108u8, 103u8, 106u8, 107u8, 103u8, 106u8, 117u8, - 103u8, 108u8, 0u8, 103u8, 108u8, 107u8, 103u8, 110u8, 0u8, 103u8, 111u8, - 109u8, 103u8, 111u8, 110u8, 103u8, 111u8, 114u8, 103u8, 111u8, 115u8, - 103u8, 111u8, 116u8, 103u8, 114u8, 99u8, 103u8, 114u8, 116u8, 103u8, 115u8, - 119u8, 103u8, 117u8, 0u8, 103u8, 117u8, 98u8, 103u8, 117u8, 99u8, 103u8, - 117u8, 114u8, 103u8, 117u8, 122u8, 103u8, 118u8, 0u8, 103u8, 118u8, 114u8, - 103u8, 119u8, 105u8, 104u8, 97u8, 0u8, 104u8, 97u8, 107u8, 104u8, 97u8, - 119u8, 104u8, 97u8, 122u8, 104u8, 101u8, 0u8, 104u8, 105u8, 0u8, 104u8, - 105u8, 102u8, 104u8, 105u8, 108u8, 104u8, 108u8, 117u8, 104u8, 109u8, - 100u8, 104u8, 110u8, 100u8, 104u8, 110u8, 101u8, 104u8, 110u8, 106u8, - 104u8, 110u8, 110u8, 104u8, 110u8, 111u8, 104u8, 111u8, 0u8, 104u8, 111u8, - 99u8, 104u8, 111u8, 106u8, 104u8, 114u8, 0u8, 104u8, 115u8, 98u8, 104u8, - 115u8, 110u8, 104u8, 116u8, 0u8, 104u8, 117u8, 0u8, 104u8, 117u8, 114u8, - 104u8, 121u8, 0u8, 104u8, 122u8, 0u8, 105u8, 97u8, 0u8, 105u8, 98u8, 97u8, - 105u8, 98u8, 98u8, 105u8, 100u8, 0u8, 105u8, 102u8, 101u8, 105u8, 103u8, - 0u8, 105u8, 105u8, 0u8, 105u8, 107u8, 0u8, 105u8, 108u8, 111u8, 105u8, - 110u8, 0u8, 105u8, 110u8, 104u8, 105u8, 111u8, 0u8, 105u8, 115u8, 0u8, - 105u8, 116u8, 0u8, 105u8, 117u8, 0u8, 105u8, 119u8, 0u8, 105u8, 122u8, - 104u8, 106u8, 97u8, 0u8, 106u8, 97u8, 109u8, 106u8, 98u8, 111u8, 106u8, - 103u8, 111u8, 106u8, 105u8, 0u8, 106u8, 109u8, 99u8, 106u8, 109u8, 108u8, - 106u8, 117u8, 116u8, 106u8, 118u8, 0u8, 106u8, 119u8, 0u8, 107u8, 97u8, - 0u8, 107u8, 97u8, 97u8, 107u8, 97u8, 98u8, 107u8, 97u8, 99u8, 107u8, 97u8, - 106u8, 107u8, 97u8, 109u8, 107u8, 97u8, 111u8, 107u8, 97u8, 119u8, 107u8, - 98u8, 100u8, 107u8, 98u8, 121u8, 107u8, 99u8, 103u8, 107u8, 99u8, 107u8, - 107u8, 100u8, 101u8, 107u8, 100u8, 104u8, 107u8, 100u8, 116u8, 107u8, - 101u8, 97u8, 107u8, 101u8, 110u8, 107u8, 102u8, 111u8, 107u8, 102u8, 114u8, - 107u8, 102u8, 121u8, 107u8, 103u8, 0u8, 107u8, 103u8, 101u8, 107u8, 103u8, - 112u8, 107u8, 104u8, 97u8, 107u8, 104u8, 98u8, 107u8, 104u8, 110u8, 107u8, - 104u8, 113u8, 107u8, 104u8, 116u8, 107u8, 104u8, 119u8, 107u8, 105u8, 0u8, - 107u8, 105u8, 117u8, 107u8, 106u8, 0u8, 107u8, 106u8, 103u8, 107u8, 107u8, - 0u8, 107u8, 107u8, 106u8, 107u8, 108u8, 0u8, 107u8, 108u8, 110u8, 107u8, - 109u8, 0u8, 107u8, 109u8, 98u8, 107u8, 110u8, 0u8, 107u8, 110u8, 102u8, - 107u8, 111u8, 0u8, 107u8, 111u8, 105u8, 107u8, 111u8, 107u8, 107u8, 111u8, - 115u8, 107u8, 112u8, 101u8, 107u8, 114u8, 99u8, 107u8, 114u8, 105u8, 107u8, - 114u8, 106u8, 107u8, 114u8, 108u8, 107u8, 114u8, 117u8, 107u8, 115u8, 0u8, - 107u8, 115u8, 98u8, 107u8, 115u8, 102u8, 107u8, 115u8, 104u8, 107u8, 116u8, - 114u8, 107u8, 117u8, 0u8, 107u8, 117u8, 109u8, 107u8, 118u8, 0u8, 107u8, - 118u8, 114u8, 107u8, 118u8, 120u8, 107u8, 119u8, 0u8, 107u8, 119u8, 107u8, - 107u8, 120u8, 108u8, 107u8, 120u8, 109u8, 107u8, 120u8, 112u8, 107u8, - 121u8, 0u8, 107u8, 122u8, 106u8, 107u8, 122u8, 116u8, 108u8, 97u8, 0u8, - 108u8, 97u8, 98u8, 108u8, 97u8, 100u8, 108u8, 97u8, 103u8, 108u8, 97u8, - 104u8, 108u8, 97u8, 106u8, 108u8, 98u8, 0u8, 108u8, 98u8, 101u8, 108u8, - 98u8, 119u8, 108u8, 99u8, 112u8, 108u8, 101u8, 112u8, 108u8, 101u8, 122u8, - 108u8, 103u8, 0u8, 108u8, 105u8, 0u8, 108u8, 105u8, 102u8, 108u8, 105u8, - 106u8, 108u8, 105u8, 108u8, 108u8, 105u8, 115u8, 108u8, 106u8, 112u8, - 108u8, 107u8, 105u8, 108u8, 107u8, 116u8, 108u8, 109u8, 110u8, 108u8, - 109u8, 111u8, 108u8, 110u8, 0u8, 108u8, 111u8, 0u8, 108u8, 111u8, 108u8, - 108u8, 111u8, 122u8, 108u8, 114u8, 99u8, 108u8, 116u8, 0u8, 108u8, 116u8, - 103u8, 108u8, 117u8, 0u8, 108u8, 117u8, 97u8, 108u8, 117u8, 111u8, 108u8, - 117u8, 121u8, 108u8, 117u8, 122u8, 108u8, 118u8, 0u8, 108u8, 119u8, 108u8, - 108u8, 122u8, 104u8, 108u8, 122u8, 122u8, 109u8, 97u8, 100u8, 109u8, 97u8, - 102u8, 109u8, 97u8, 103u8, 109u8, 97u8, 105u8, 109u8, 97u8, 107u8, 109u8, - 97u8, 110u8, 109u8, 97u8, 115u8, 109u8, 97u8, 122u8, 109u8, 100u8, 102u8, - 109u8, 100u8, 104u8, 109u8, 100u8, 114u8, 109u8, 101u8, 110u8, 109u8, - 101u8, 114u8, 109u8, 102u8, 97u8, 109u8, 102u8, 101u8, 109u8, 103u8, 0u8, - 109u8, 103u8, 104u8, 109u8, 103u8, 111u8, 109u8, 103u8, 112u8, 109u8, - 103u8, 121u8, 109u8, 104u8, 0u8, 109u8, 105u8, 0u8, 109u8, 105u8, 99u8, - 109u8, 105u8, 110u8, 109u8, 107u8, 0u8, 109u8, 108u8, 0u8, 109u8, 108u8, - 115u8, 109u8, 110u8, 0u8, 109u8, 110u8, 105u8, 109u8, 110u8, 119u8, 109u8, - 111u8, 0u8, 109u8, 111u8, 101u8, 109u8, 111u8, 104u8, 109u8, 111u8, 115u8, - 109u8, 114u8, 0u8, 109u8, 114u8, 100u8, 109u8, 114u8, 106u8, 109u8, 114u8, - 111u8, 109u8, 115u8, 0u8, 109u8, 116u8, 0u8, 109u8, 116u8, 114u8, 109u8, - 117u8, 97u8, 109u8, 117u8, 115u8, 109u8, 118u8, 121u8, 109u8, 119u8, 107u8, - 109u8, 119u8, 114u8, 109u8, 119u8, 118u8, 109u8, 119u8, 119u8, 109u8, - 120u8, 99u8, 109u8, 121u8, 0u8, 109u8, 121u8, 118u8, 109u8, 121u8, 120u8, - 109u8, 121u8, 122u8, 109u8, 122u8, 110u8, 110u8, 97u8, 0u8, 110u8, 97u8, - 110u8, 110u8, 97u8, 112u8, 110u8, 97u8, 113u8, 110u8, 98u8, 0u8, 110u8, - 99u8, 104u8, 110u8, 100u8, 0u8, 110u8, 100u8, 99u8, 110u8, 100u8, 115u8, - 110u8, 101u8, 0u8, 110u8, 101u8, 119u8, 110u8, 103u8, 0u8, 110u8, 103u8, - 108u8, 110u8, 104u8, 101u8, 110u8, 104u8, 119u8, 110u8, 105u8, 106u8, - 110u8, 105u8, 117u8, 110u8, 106u8, 111u8, 110u8, 108u8, 0u8, 110u8, 109u8, - 103u8, 110u8, 110u8, 0u8, 110u8, 110u8, 104u8, 110u8, 110u8, 112u8, 110u8, - 111u8, 0u8, 110u8, 111u8, 100u8, 110u8, 111u8, 101u8, 110u8, 111u8, 110u8, - 110u8, 113u8, 111u8, 110u8, 114u8, 0u8, 110u8, 115u8, 107u8, 110u8, 115u8, - 111u8, 110u8, 115u8, 116u8, 110u8, 117u8, 115u8, 110u8, 118u8, 0u8, 110u8, - 120u8, 113u8, 110u8, 121u8, 0u8, 110u8, 121u8, 109u8, 110u8, 121u8, 110u8, - 110u8, 122u8, 105u8, 111u8, 99u8, 0u8, 111u8, 106u8, 0u8, 111u8, 106u8, - 115u8, 111u8, 107u8, 97u8, 111u8, 109u8, 0u8, 111u8, 114u8, 0u8, 111u8, - 115u8, 0u8, 111u8, 115u8, 97u8, 111u8, 116u8, 107u8, 111u8, 117u8, 105u8, - 112u8, 97u8, 0u8, 112u8, 97u8, 103u8, 112u8, 97u8, 108u8, 112u8, 97u8, - 109u8, 112u8, 97u8, 112u8, 112u8, 97u8, 117u8, 112u8, 99u8, 100u8, 112u8, - 99u8, 109u8, 112u8, 100u8, 99u8, 112u8, 100u8, 116u8, 112u8, 101u8, 111u8, - 112u8, 102u8, 108u8, 112u8, 104u8, 110u8, 112u8, 105u8, 115u8, 112u8, - 107u8, 97u8, 112u8, 107u8, 111u8, 112u8, 108u8, 0u8, 112u8, 109u8, 115u8, - 112u8, 110u8, 116u8, 112u8, 111u8, 110u8, 112u8, 112u8, 97u8, 112u8, 113u8, - 109u8, 112u8, 114u8, 97u8, 112u8, 114u8, 100u8, 112u8, 114u8, 103u8, 112u8, - 115u8, 0u8, 112u8, 116u8, 0u8, 112u8, 117u8, 117u8, 113u8, 117u8, 0u8, - 113u8, 117u8, 99u8, 113u8, 117u8, 103u8, 114u8, 97u8, 106u8, 114u8, 99u8, - 102u8, 114u8, 101u8, 106u8, 114u8, 103u8, 110u8, 114u8, 104u8, 103u8, - 114u8, 105u8, 97u8, 114u8, 105u8, 102u8, 114u8, 106u8, 115u8, 114u8, 107u8, - 116u8, 114u8, 109u8, 0u8, 114u8, 109u8, 102u8, 114u8, 109u8, 111u8, 114u8, - 109u8, 116u8, 114u8, 109u8, 117u8, 114u8, 110u8, 0u8, 114u8, 110u8, 103u8, - 114u8, 111u8, 0u8, 114u8, 111u8, 98u8, 114u8, 111u8, 102u8, 114u8, 116u8, - 109u8, 114u8, 117u8, 0u8, 114u8, 117u8, 101u8, 114u8, 117u8, 103u8, 114u8, - 119u8, 0u8, 114u8, 119u8, 107u8, 114u8, 121u8, 117u8, 115u8, 97u8, 0u8, - 115u8, 97u8, 102u8, 115u8, 97u8, 104u8, 115u8, 97u8, 113u8, 115u8, 97u8, - 115u8, 115u8, 97u8, 116u8, 115u8, 97u8, 118u8, 115u8, 97u8, 122u8, 115u8, - 98u8, 112u8, 115u8, 99u8, 0u8, 115u8, 99u8, 107u8, 115u8, 99u8, 110u8, - 115u8, 99u8, 111u8, 115u8, 100u8, 0u8, 115u8, 100u8, 99u8, 115u8, 100u8, - 104u8, 115u8, 101u8, 0u8, 115u8, 101u8, 102u8, 115u8, 101u8, 104u8, 115u8, - 101u8, 105u8, 115u8, 101u8, 115u8, 115u8, 103u8, 0u8, 115u8, 103u8, 97u8, - 115u8, 103u8, 115u8, 115u8, 104u8, 105u8, 115u8, 104u8, 110u8, 115u8, - 105u8, 0u8, 115u8, 105u8, 100u8, 115u8, 107u8, 0u8, 115u8, 107u8, 114u8, - 115u8, 108u8, 0u8, 115u8, 108u8, 105u8, 115u8, 108u8, 121u8, 115u8, 109u8, - 0u8, 115u8, 109u8, 97u8, 115u8, 109u8, 100u8, 115u8, 109u8, 106u8, 115u8, - 109u8, 110u8, 115u8, 109u8, 112u8, 115u8, 109u8, 115u8, 115u8, 110u8, 0u8, - 115u8, 110u8, 98u8, 115u8, 110u8, 107u8, 115u8, 111u8, 0u8, 115u8, 111u8, - 103u8, 115u8, 111u8, 117u8, 115u8, 113u8, 0u8, 115u8, 114u8, 0u8, 115u8, - 114u8, 98u8, 115u8, 114u8, 110u8, 115u8, 114u8, 114u8, 115u8, 114u8, 120u8, - 115u8, 115u8, 0u8, 115u8, 115u8, 121u8, 115u8, 116u8, 0u8, 115u8, 116u8, - 113u8, 115u8, 117u8, 0u8, 115u8, 117u8, 107u8, 115u8, 117u8, 115u8, 115u8, - 118u8, 0u8, 115u8, 119u8, 0u8, 115u8, 119u8, 98u8, 115u8, 119u8, 99u8, - 115u8, 119u8, 103u8, 115u8, 119u8, 118u8, 115u8, 120u8, 110u8, 115u8, - 121u8, 108u8, 115u8, 121u8, 114u8, 115u8, 122u8, 108u8, 116u8, 97u8, 0u8, - 116u8, 97u8, 106u8, 116u8, 98u8, 119u8, 116u8, 99u8, 121u8, 116u8, 100u8, - 100u8, 116u8, 100u8, 103u8, 116u8, 100u8, 104u8, 116u8, 100u8, 117u8, - 116u8, 101u8, 0u8, 116u8, 101u8, 109u8, 116u8, 101u8, 111u8, 116u8, 101u8, - 116u8, 116u8, 103u8, 0u8, 116u8, 104u8, 0u8, 116u8, 104u8, 108u8, 116u8, - 104u8, 113u8, 116u8, 104u8, 114u8, 116u8, 105u8, 0u8, 116u8, 105u8, 103u8, - 116u8, 105u8, 118u8, 116u8, 107u8, 0u8, 116u8, 107u8, 108u8, 116u8, 107u8, - 114u8, 116u8, 107u8, 116u8, 116u8, 108u8, 0u8, 116u8, 108u8, 121u8, 116u8, - 109u8, 104u8, 116u8, 110u8, 0u8, 116u8, 111u8, 0u8, 116u8, 111u8, 103u8, - 116u8, 111u8, 107u8, 116u8, 112u8, 105u8, 116u8, 114u8, 0u8, 116u8, 114u8, - 117u8, 116u8, 114u8, 118u8, 116u8, 114u8, 119u8, 116u8, 115u8, 0u8, 116u8, - 115u8, 100u8, 116u8, 115u8, 102u8, 116u8, 115u8, 103u8, 116u8, 115u8, - 106u8, 116u8, 116u8, 0u8, 116u8, 116u8, 106u8, 116u8, 116u8, 115u8, 116u8, - 116u8, 116u8, 116u8, 117u8, 109u8, 116u8, 118u8, 108u8, 116u8, 119u8, - 113u8, 116u8, 120u8, 103u8, 116u8, 120u8, 111u8, 116u8, 121u8, 0u8, 116u8, - 121u8, 118u8, 116u8, 122u8, 109u8, 117u8, 100u8, 105u8, 117u8, 100u8, - 109u8, 117u8, 103u8, 0u8, 117u8, 103u8, 97u8, 117u8, 107u8, 0u8, 117u8, - 108u8, 105u8, 117u8, 109u8, 98u8, 117u8, 110u8, 114u8, 117u8, 110u8, 120u8, - 117u8, 114u8, 0u8, 117u8, 122u8, 0u8, 118u8, 97u8, 105u8, 118u8, 101u8, - 0u8, 118u8, 101u8, 99u8, 118u8, 101u8, 112u8, 118u8, 105u8, 0u8, 118u8, - 105u8, 99u8, 118u8, 108u8, 115u8, 118u8, 109u8, 102u8, 118u8, 109u8, 119u8, - 118u8, 111u8, 0u8, 118u8, 111u8, 116u8, 118u8, 114u8, 111u8, 118u8, 117u8, - 110u8, 119u8, 97u8, 0u8, 119u8, 97u8, 101u8, 119u8, 97u8, 108u8, 119u8, - 97u8, 114u8, 119u8, 98u8, 112u8, 119u8, 98u8, 113u8, 119u8, 98u8, 114u8, - 119u8, 108u8, 115u8, 119u8, 110u8, 105u8, 119u8, 111u8, 0u8, 119u8, 115u8, - 103u8, 119u8, 116u8, 109u8, 119u8, 117u8, 117u8, 120u8, 97u8, 118u8, 120u8, - 99u8, 111u8, 120u8, 99u8, 114u8, 120u8, 104u8, 0u8, 120u8, 108u8, 99u8, - 120u8, 108u8, 100u8, 120u8, 109u8, 102u8, 120u8, 109u8, 110u8, 120u8, - 109u8, 114u8, 120u8, 110u8, 97u8, 120u8, 110u8, 114u8, 120u8, 111u8, 103u8, - 120u8, 112u8, 114u8, 120u8, 115u8, 97u8, 120u8, 115u8, 114u8, 121u8, 97u8, - 111u8, 121u8, 97u8, 112u8, 121u8, 97u8, 118u8, 121u8, 98u8, 98u8, 121u8, - 105u8, 0u8, 121u8, 111u8, 0u8, 121u8, 114u8, 108u8, 121u8, 117u8, 97u8, - 121u8, 117u8, 101u8, 122u8, 97u8, 0u8, 122u8, 97u8, 103u8, 122u8, 100u8, - 106u8, 122u8, 101u8, 97u8, 122u8, 103u8, 104u8, 122u8, 104u8, 0u8, 122u8, - 104u8, 120u8, 122u8, 107u8, 116u8, 122u8, 108u8, 109u8, 122u8, 109u8, - 105u8, 122u8, 117u8, 0u8, 122u8, 122u8, 97u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"af\0am\0ar\0as\0astaz\0be\0bg\0bgcbhobn\0br\0brxbs\0ca\0cebchrcs\0cv\0cy\0da\0de\0doidsbel\0en\0es\0et\0eu\0fa\0ff\0fi\0filfo\0fr\0ga\0gd\0gl\0gu\0ha\0he\0hi\0hr\0hsbhu\0hy\0ia\0id\0ig\0is\0it\0ja\0jv\0ka\0keakgpkk\0km\0kn\0ko\0kokks\0ky\0lo\0lt\0lv\0maimi\0mk\0ml\0mn\0mnimr\0ms\0my\0ne\0nl\0nn\0no\0or\0pa\0pcmpl\0ps\0pt\0qu\0rajrm\0ro\0ru\0sa\0satsc\0sd\0si\0sk\0sl\0so\0sq\0sr\0su\0sv\0sw\0ta\0te\0tg\0th\0ti\0tk\0to\0tr\0tt\0uk\0ur\0uz\0vi\0wo\0xh\0yo\0yrlyuezh\0zu\0") }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 69u8, 84u8, 0u8, 71u8, 69u8, 0u8, 71u8, 72u8, 0u8, 73u8, 68u8, 0u8, 85u8, - 71u8, 0u8, 71u8, 72u8, 0u8, 66u8, 84u8, 0u8, 82u8, 85u8, 0u8, 73u8, 82u8, - 0u8, 84u8, 78u8, 0u8, 90u8, 65u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, - 84u8, 78u8, 0u8, 71u8, 72u8, 0u8, 73u8, 81u8, 0u8, 88u8, 75u8, 0u8, 82u8, - 85u8, 0u8, 69u8, 84u8, 0u8, 78u8, 71u8, 0u8, 69u8, 83u8, 0u8, 78u8, 71u8, - 0u8, 73u8, 68u8, 0u8, 84u8, 71u8, 0u8, 69u8, 71u8, 0u8, 73u8, 82u8, 0u8, - 67u8, 76u8, 0u8, 66u8, 79u8, 0u8, 68u8, 90u8, 0u8, 83u8, 65u8, 0u8, 77u8, - 65u8, 0u8, 69u8, 71u8, 0u8, 73u8, 78u8, 0u8, 84u8, 90u8, 0u8, 85u8, 83u8, - 0u8, 69u8, 83u8, 0u8, 67u8, 65u8, 0u8, 82u8, 85u8, 0u8, 73u8, 78u8, 0u8, - 66u8, 79u8, 0u8, 65u8, 90u8, 0u8, 82u8, 85u8, 0u8, 80u8, 75u8, 0u8, 73u8, - 68u8, 0u8, 78u8, 80u8, 0u8, 65u8, 84u8, 0u8, 67u8, 77u8, 0u8, 67u8, 77u8, - 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 67u8, 73u8, 0u8, 66u8, 89u8, 0u8, - 83u8, 68u8, 0u8, 90u8, 77u8, 0u8, 73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 67u8, - 77u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 66u8, 71u8, - 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8, - 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 86u8, 85u8, 0u8, 80u8, 72u8, 0u8, 78u8, - 71u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8, 83u8, 78u8, 0u8, 67u8, 77u8, - 0u8, 80u8, 72u8, 0u8, 67u8, 65u8, 0u8, 77u8, 89u8, 0u8, 86u8, 78u8, 0u8, - 77u8, 76u8, 0u8, 77u8, 76u8, 0u8, 66u8, 68u8, 0u8, 67u8, 78u8, 0u8, 73u8, - 78u8, 0u8, 73u8, 82u8, 0u8, 67u8, 73u8, 0u8, 70u8, 82u8, 0u8, 73u8, 78u8, - 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 66u8, 65u8, 0u8, 76u8, 82u8, 0u8, - 67u8, 77u8, 0u8, 80u8, 72u8, 0u8, 80u8, 75u8, 0u8, 82u8, 85u8, 0u8, 89u8, - 84u8, 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 71u8, 81u8, 0u8, 69u8, 82u8, - 0u8, 67u8, 77u8, 0u8, 77u8, 76u8, 0u8, 69u8, 83u8, 0u8, 85u8, 83u8, 0u8, - 78u8, 71u8, 0u8, 66u8, 68u8, 0u8, 82u8, 85u8, 0u8, 80u8, 72u8, 0u8, 85u8, - 71u8, 0u8, 71u8, 85u8, 0u8, 70u8, 77u8, 0u8, 82u8, 85u8, 0u8, 85u8, 83u8, - 0u8, 67u8, 65u8, 0u8, 85u8, 83u8, 0u8, 85u8, 83u8, 0u8, 75u8, 72u8, 0u8, - 86u8, 78u8, 0u8, 73u8, 81u8, 0u8, 67u8, 65u8, 0u8, 77u8, 78u8, 0u8, 70u8, - 82u8, 0u8, 69u8, 71u8, 0u8, 80u8, 72u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, - 0u8, 85u8, 65u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 83u8, 67u8, 0u8, - 67u8, 90u8, 0u8, 80u8, 76u8, 0u8, 67u8, 65u8, 0u8, 77u8, 77u8, 0u8, 82u8, - 85u8, 0u8, 82u8, 85u8, 0u8, 71u8, 66u8, 0u8, 68u8, 75u8, 0u8, 67u8, 73u8, - 0u8, 85u8, 83u8, 0u8, 82u8, 85u8, 0u8, 75u8, 69u8, 0u8, 73u8, 78u8, 0u8, - 68u8, 69u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 78u8, 69u8, 0u8, 78u8, - 71u8, 0u8, 67u8, 73u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, 68u8, 69u8, - 0u8, 77u8, 76u8, 0u8, 77u8, 89u8, 0u8, 78u8, 80u8, 0u8, 67u8, 77u8, 0u8, - 77u8, 86u8, 0u8, 83u8, 78u8, 0u8, 66u8, 70u8, 0u8, 66u8, 84u8, 0u8, 75u8, - 69u8, 0u8, 71u8, 72u8, 0u8, 78u8, 71u8, 0u8, 73u8, 84u8, 0u8, 69u8, 71u8, - 0u8, 77u8, 77u8, 0u8, 71u8, 82u8, 0u8, 85u8, 83u8, 0u8, 48u8, 48u8, 49u8, - 69u8, 83u8, 0u8, 73u8, 78u8, 0u8, 85u8, 83u8, 0u8, 69u8, 69u8, 0u8, 73u8, - 84u8, 0u8, 69u8, 83u8, 0u8, 67u8, 77u8, 0u8, 69u8, 83u8, 0u8, 73u8, 82u8, - 0u8, 71u8, 81u8, 0u8, 83u8, 78u8, 0u8, 77u8, 76u8, 0u8, 70u8, 73u8, 0u8, - 83u8, 68u8, 0u8, 80u8, 72u8, 0u8, 83u8, 69u8, 0u8, 70u8, 74u8, 0u8, 70u8, - 79u8, 0u8, 66u8, 74u8, 0u8, 70u8, 82u8, 0u8, 85u8, 83u8, 0u8, 70u8, 82u8, - 0u8, 68u8, 69u8, 0u8, 68u8, 69u8, 0u8, 67u8, 77u8, 0u8, 87u8, 70u8, 0u8, - 71u8, 78u8, 0u8, 78u8, 69u8, 0u8, 73u8, 84u8, 0u8, 78u8, 71u8, 0u8, 83u8, - 68u8, 0u8, 78u8, 76u8, 0u8, 73u8, 69u8, 0u8, 71u8, 72u8, 0u8, 77u8, 68u8, - 0u8, 67u8, 78u8, 0u8, 73u8, 68u8, 0u8, 73u8, 78u8, 0u8, 73u8, 82u8, 0u8, - 71u8, 70u8, 0u8, 71u8, 66u8, 0u8, 69u8, 84u8, 0u8, 78u8, 80u8, 0u8, 75u8, - 73u8, 0u8, 80u8, 75u8, 0u8, 80u8, 75u8, 0u8, 69u8, 83u8, 0u8, 73u8, 82u8, - 0u8, 80u8, 89u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8, - 78u8, 76u8, 0u8, 85u8, 65u8, 0u8, 67u8, 89u8, 0u8, 73u8, 78u8, 0u8, 67u8, - 72u8, 0u8, 73u8, 78u8, 0u8, 66u8, 82u8, 0u8, 67u8, 79u8, 0u8, 71u8, 72u8, - 0u8, 75u8, 69u8, 0u8, 73u8, 77u8, 0u8, 78u8, 80u8, 0u8, 67u8, 65u8, 0u8, - 78u8, 71u8, 0u8, 67u8, 78u8, 0u8, 85u8, 83u8, 0u8, 65u8, 70u8, 0u8, 73u8, - 76u8, 0u8, 73u8, 78u8, 0u8, 70u8, 74u8, 0u8, 80u8, 72u8, 0u8, 84u8, 82u8, - 0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 85u8, 83u8, 0u8, - 80u8, 72u8, 0u8, 80u8, 75u8, 0u8, 80u8, 71u8, 0u8, 73u8, 78u8, 0u8, 73u8, - 78u8, 0u8, 72u8, 82u8, 0u8, 68u8, 69u8, 0u8, 67u8, 78u8, 0u8, 72u8, 84u8, - 0u8, 72u8, 85u8, 0u8, 67u8, 65u8, 0u8, 65u8, 77u8, 0u8, 78u8, 65u8, 0u8, - 48u8, 48u8, 49u8, 77u8, 89u8, 0u8, 78u8, 71u8, 0u8, 73u8, 68u8, 0u8, 84u8, - 71u8, 0u8, 78u8, 71u8, 0u8, 67u8, 78u8, 0u8, 85u8, 83u8, 0u8, 80u8, 72u8, - 0u8, 73u8, 68u8, 0u8, 82u8, 85u8, 0u8, 48u8, 48u8, 49u8, 73u8, 83u8, 0u8, - 73u8, 84u8, 0u8, 67u8, 65u8, 0u8, 73u8, 76u8, 0u8, 82u8, 85u8, 0u8, 74u8, - 80u8, 0u8, 74u8, 77u8, 0u8, 48u8, 48u8, 49u8, 67u8, 77u8, 0u8, 85u8, 65u8, - 0u8, 84u8, 90u8, 0u8, 78u8, 80u8, 0u8, 68u8, 75u8, 0u8, 73u8, 68u8, 0u8, - 73u8, 68u8, 0u8, 71u8, 69u8, 0u8, 85u8, 90u8, 0u8, 68u8, 90u8, 0u8, 77u8, - 77u8, 0u8, 78u8, 71u8, 0u8, 75u8, 69u8, 0u8, 77u8, 76u8, 0u8, 73u8, 68u8, - 0u8, 82u8, 85u8, 0u8, 78u8, 69u8, 0u8, 78u8, 71u8, 0u8, 90u8, 87u8, 0u8, - 84u8, 90u8, 0u8, 84u8, 71u8, 0u8, 84u8, 72u8, 0u8, 67u8, 86u8, 0u8, 67u8, - 77u8, 0u8, 67u8, 73u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 67u8, 68u8, - 0u8, 73u8, 68u8, 0u8, 66u8, 82u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, - 73u8, 78u8, 0u8, 77u8, 76u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8, - 69u8, 0u8, 84u8, 82u8, 0u8, 78u8, 65u8, 0u8, 76u8, 65u8, 0u8, 75u8, 90u8, - 0u8, 67u8, 77u8, 0u8, 71u8, 76u8, 0u8, 75u8, 69u8, 0u8, 75u8, 72u8, 0u8, - 65u8, 79u8, 0u8, 73u8, 78u8, 0u8, 71u8, 87u8, 0u8, 75u8, 82u8, 0u8, 82u8, - 85u8, 0u8, 73u8, 78u8, 0u8, 70u8, 77u8, 0u8, 76u8, 82u8, 0u8, 82u8, 85u8, - 0u8, 83u8, 76u8, 0u8, 80u8, 72u8, 0u8, 82u8, 85u8, 0u8, 73u8, 78u8, 0u8, - 73u8, 78u8, 0u8, 84u8, 90u8, 0u8, 67u8, 77u8, 0u8, 68u8, 69u8, 0u8, 77u8, - 89u8, 0u8, 84u8, 82u8, 0u8, 82u8, 85u8, 0u8, 82u8, 85u8, 0u8, 73u8, 68u8, - 0u8, 80u8, 75u8, 0u8, 71u8, 66u8, 0u8, 67u8, 65u8, 0u8, 73u8, 78u8, 0u8, - 84u8, 72u8, 0u8, 80u8, 75u8, 0u8, 75u8, 71u8, 0u8, 77u8, 89u8, 0u8, 77u8, - 89u8, 0u8, 86u8, 65u8, 0u8, 71u8, 82u8, 0u8, 73u8, 76u8, 0u8, 84u8, 90u8, - 0u8, 80u8, 75u8, 0u8, 85u8, 71u8, 0u8, 76u8, 85u8, 0u8, 82u8, 85u8, 0u8, - 73u8, 68u8, 0u8, 67u8, 78u8, 0u8, 73u8, 78u8, 0u8, 82u8, 85u8, 0u8, 85u8, - 71u8, 0u8, 78u8, 76u8, 0u8, 78u8, 80u8, 0u8, 73u8, 84u8, 0u8, 67u8, 65u8, - 0u8, 67u8, 78u8, 0u8, 73u8, 68u8, 0u8, 73u8, 82u8, 0u8, 85u8, 83u8, 0u8, - 73u8, 78u8, 0u8, 73u8, 84u8, 0u8, 67u8, 68u8, 0u8, 76u8, 65u8, 0u8, 67u8, - 68u8, 0u8, 90u8, 77u8, 0u8, 73u8, 82u8, 0u8, 76u8, 84u8, 0u8, 76u8, 86u8, - 0u8, 67u8, 68u8, 0u8, 67u8, 68u8, 0u8, 75u8, 69u8, 0u8, 75u8, 69u8, 0u8, - 73u8, 82u8, 0u8, 76u8, 86u8, 0u8, 84u8, 72u8, 0u8, 67u8, 78u8, 0u8, 84u8, - 82u8, 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, - 0u8, 73u8, 68u8, 0u8, 71u8, 77u8, 0u8, 75u8, 69u8, 0u8, 77u8, 88u8, 0u8, - 82u8, 85u8, 0u8, 80u8, 72u8, 0u8, 73u8, 68u8, 0u8, 83u8, 76u8, 0u8, 75u8, - 69u8, 0u8, 84u8, 72u8, 0u8, 77u8, 85u8, 0u8, 77u8, 71u8, 0u8, 77u8, 90u8, - 0u8, 67u8, 77u8, 0u8, 78u8, 80u8, 0u8, 84u8, 90u8, 0u8, 77u8, 72u8, 0u8, - 78u8, 90u8, 0u8, 67u8, 65u8, 0u8, 73u8, 68u8, 0u8, 77u8, 75u8, 0u8, 73u8, - 78u8, 0u8, 83u8, 68u8, 0u8, 77u8, 78u8, 0u8, 73u8, 78u8, 0u8, 77u8, 77u8, - 0u8, 82u8, 79u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 66u8, 70u8, 0u8, - 73u8, 78u8, 0u8, 78u8, 80u8, 0u8, 82u8, 85u8, 0u8, 66u8, 68u8, 0u8, 77u8, - 89u8, 0u8, 77u8, 84u8, 0u8, 73u8, 78u8, 0u8, 67u8, 77u8, 0u8, 85u8, 83u8, - 0u8, 80u8, 75u8, 0u8, 77u8, 76u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8, - 85u8, 83u8, 0u8, 90u8, 87u8, 0u8, 77u8, 77u8, 0u8, 82u8, 85u8, 0u8, 85u8, - 71u8, 0u8, 73u8, 82u8, 0u8, 73u8, 82u8, 0u8, 78u8, 82u8, 0u8, 67u8, 78u8, - 0u8, 73u8, 84u8, 0u8, 78u8, 65u8, 0u8, 78u8, 79u8, 0u8, 77u8, 88u8, 0u8, - 90u8, 87u8, 0u8, 77u8, 90u8, 0u8, 68u8, 69u8, 0u8, 78u8, 80u8, 0u8, 78u8, - 80u8, 0u8, 78u8, 65u8, 0u8, 77u8, 90u8, 0u8, 77u8, 88u8, 0u8, 77u8, 88u8, - 0u8, 73u8, 68u8, 0u8, 78u8, 85u8, 0u8, 73u8, 78u8, 0u8, 78u8, 76u8, 0u8, - 67u8, 77u8, 0u8, 78u8, 79u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, 78u8, - 79u8, 0u8, 84u8, 72u8, 0u8, 73u8, 78u8, 0u8, 83u8, 69u8, 0u8, 71u8, 78u8, - 0u8, 90u8, 65u8, 0u8, 67u8, 65u8, 0u8, 90u8, 65u8, 0u8, 73u8, 78u8, 0u8, - 83u8, 83u8, 0u8, 85u8, 83u8, 0u8, 67u8, 78u8, 0u8, 77u8, 87u8, 0u8, 84u8, - 90u8, 0u8, 85u8, 71u8, 0u8, 71u8, 72u8, 0u8, 70u8, 82u8, 0u8, 67u8, 65u8, - 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 69u8, 84u8, 0u8, 73u8, 78u8, 0u8, - 71u8, 69u8, 0u8, 85u8, 83u8, 0u8, 77u8, 78u8, 0u8, 49u8, 52u8, 51u8, 73u8, - 78u8, 0u8, 80u8, 72u8, 0u8, 73u8, 82u8, 0u8, 80u8, 72u8, 0u8, 65u8, 87u8, - 0u8, 80u8, 87u8, 0u8, 70u8, 82u8, 0u8, 78u8, 71u8, 0u8, 85u8, 83u8, 0u8, - 67u8, 65u8, 0u8, 73u8, 82u8, 0u8, 68u8, 69u8, 0u8, 76u8, 66u8, 0u8, 83u8, - 66u8, 0u8, 73u8, 78u8, 0u8, 75u8, 69u8, 0u8, 80u8, 76u8, 0u8, 73u8, 84u8, - 0u8, 71u8, 82u8, 0u8, 70u8, 77u8, 0u8, 73u8, 78u8, 0u8, 67u8, 65u8, 0u8, - 80u8, 75u8, 0u8, 73u8, 82u8, 0u8, 48u8, 48u8, 49u8, 65u8, 70u8, 0u8, 66u8, - 82u8, 0u8, 71u8, 65u8, 0u8, 80u8, 69u8, 0u8, 71u8, 84u8, 0u8, 69u8, 67u8, - 0u8, 73u8, 78u8, 0u8, 82u8, 69u8, 0u8, 73u8, 68u8, 0u8, 73u8, 84u8, 0u8, - 77u8, 77u8, 0u8, 73u8, 78u8, 0u8, 77u8, 65u8, 0u8, 78u8, 80u8, 0u8, 66u8, - 68u8, 0u8, 67u8, 72u8, 0u8, 70u8, 73u8, 0u8, 67u8, 72u8, 0u8, 73u8, 82u8, - 0u8, 83u8, 69u8, 0u8, 66u8, 73u8, 0u8, 77u8, 90u8, 0u8, 82u8, 79u8, 0u8, - 73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 70u8, 74u8, 0u8, 82u8, 85u8, 0u8, 85u8, - 65u8, 0u8, 83u8, 66u8, 0u8, 82u8, 87u8, 0u8, 84u8, 90u8, 0u8, 74u8, 80u8, - 0u8, 73u8, 78u8, 0u8, 71u8, 72u8, 0u8, 82u8, 85u8, 0u8, 75u8, 69u8, 0u8, - 73u8, 68u8, 0u8, 73u8, 78u8, 0u8, 83u8, 78u8, 0u8, 73u8, 78u8, 0u8, 84u8, - 90u8, 0u8, 73u8, 84u8, 0u8, 73u8, 78u8, 0u8, 73u8, 84u8, 0u8, 71u8, 66u8, - 0u8, 80u8, 75u8, 0u8, 73u8, 84u8, 0u8, 73u8, 82u8, 0u8, 78u8, 79u8, 0u8, - 67u8, 73u8, 0u8, 77u8, 90u8, 0u8, 77u8, 88u8, 0u8, 77u8, 76u8, 0u8, 67u8, - 70u8, 0u8, 73u8, 69u8, 0u8, 76u8, 84u8, 0u8, 77u8, 65u8, 0u8, 77u8, 77u8, - 0u8, 76u8, 75u8, 0u8, 69u8, 84u8, 0u8, 83u8, 75u8, 0u8, 80u8, 75u8, 0u8, - 83u8, 73u8, 0u8, 80u8, 76u8, 0u8, 73u8, 68u8, 0u8, 87u8, 83u8, 0u8, 83u8, - 69u8, 0u8, 65u8, 79u8, 0u8, 83u8, 69u8, 0u8, 70u8, 73u8, 0u8, 73u8, 76u8, - 0u8, 70u8, 73u8, 0u8, 90u8, 87u8, 0u8, 77u8, 89u8, 0u8, 77u8, 76u8, 0u8, - 83u8, 79u8, 0u8, 85u8, 90u8, 0u8, 84u8, 72u8, 0u8, 65u8, 76u8, 0u8, 82u8, - 83u8, 0u8, 73u8, 78u8, 0u8, 83u8, 82u8, 0u8, 83u8, 78u8, 0u8, 73u8, 78u8, - 0u8, 90u8, 65u8, 0u8, 69u8, 82u8, 0u8, 90u8, 65u8, 0u8, 68u8, 69u8, 0u8, - 73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 71u8, 78u8, 0u8, 83u8, 69u8, 0u8, 84u8, - 90u8, 0u8, 89u8, 84u8, 0u8, 67u8, 68u8, 0u8, 68u8, 69u8, 0u8, 73u8, 78u8, - 0u8, 73u8, 68u8, 0u8, 66u8, 68u8, 0u8, 73u8, 81u8, 0u8, 80u8, 76u8, 0u8, - 73u8, 78u8, 0u8, 78u8, 80u8, 0u8, 80u8, 72u8, 0u8, 73u8, 78u8, 0u8, 67u8, - 78u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 77u8, 89u8, 0u8, 73u8, 78u8, - 0u8, 83u8, 76u8, 0u8, 85u8, 71u8, 0u8, 84u8, 76u8, 0u8, 84u8, 74u8, 0u8, - 84u8, 72u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 69u8, - 84u8, 0u8, 69u8, 82u8, 0u8, 78u8, 71u8, 0u8, 84u8, 77u8, 0u8, 84u8, 75u8, - 0u8, 65u8, 90u8, 0u8, 78u8, 80u8, 0u8, 80u8, 72u8, 0u8, 65u8, 90u8, 0u8, - 78u8, 69u8, 0u8, 90u8, 65u8, 0u8, 84u8, 79u8, 0u8, 77u8, 87u8, 0u8, 48u8, - 48u8, 49u8, 80u8, 71u8, 0u8, 84u8, 82u8, 0u8, 84u8, 82u8, 0u8, 84u8, 87u8, - 0u8, 80u8, 75u8, 0u8, 90u8, 65u8, 0u8, 71u8, 82u8, 0u8, 78u8, 80u8, 0u8, - 80u8, 72u8, 0u8, 66u8, 84u8, 0u8, 82u8, 85u8, 0u8, 85u8, 71u8, 0u8, 84u8, - 72u8, 0u8, 65u8, 90u8, 0u8, 77u8, 87u8, 0u8, 84u8, 86u8, 0u8, 78u8, 69u8, - 0u8, 67u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 70u8, 0u8, 82u8, 85u8, 0u8, - 77u8, 65u8, 0u8, 82u8, 85u8, 0u8, 82u8, 85u8, 0u8, 67u8, 78u8, 0u8, 83u8, - 89u8, 0u8, 85u8, 65u8, 0u8, 70u8, 77u8, 0u8, 65u8, 79u8, 0u8, 73u8, 78u8, - 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 85u8, 90u8, 0u8, 76u8, 82u8, 0u8, - 90u8, 65u8, 0u8, 73u8, 84u8, 0u8, 82u8, 85u8, 0u8, 86u8, 78u8, 0u8, 83u8, - 88u8, 0u8, 66u8, 69u8, 0u8, 68u8, 69u8, 0u8, 77u8, 90u8, 0u8, 48u8, 48u8, - 49u8, 82u8, 85u8, 0u8, 69u8, 69u8, 0u8, 84u8, 90u8, 0u8, 66u8, 69u8, 0u8, - 67u8, 72u8, 0u8, 69u8, 84u8, 0u8, 80u8, 72u8, 0u8, 65u8, 85u8, 0u8, 73u8, - 78u8, 0u8, 73u8, 78u8, 0u8, 87u8, 70u8, 0u8, 75u8, 77u8, 0u8, 83u8, 78u8, - 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, 66u8, 82u8, 0u8, - 85u8, 90u8, 0u8, 84u8, 82u8, 0u8, 90u8, 65u8, 0u8, 84u8, 82u8, 0u8, 84u8, - 82u8, 0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 83u8, 68u8, 0u8, 83u8, 65u8, - 0u8, 73u8, 78u8, 0u8, 85u8, 71u8, 0u8, 73u8, 82u8, 0u8, 89u8, 69u8, 0u8, - 78u8, 80u8, 0u8, 77u8, 90u8, 0u8, 70u8, 77u8, 0u8, 67u8, 77u8, 0u8, 67u8, - 77u8, 0u8, 48u8, 48u8, 49u8, 78u8, 71u8, 0u8, 66u8, 82u8, 0u8, 77u8, 88u8, - 0u8, 72u8, 75u8, 0u8, 67u8, 78u8, 0u8, 83u8, 68u8, 0u8, 75u8, 77u8, 0u8, - 78u8, 76u8, 0u8, 77u8, 65u8, 0u8, 67u8, 78u8, 0u8, 67u8, 78u8, 0u8, 67u8, - 78u8, 0u8, 84u8, 71u8, 0u8, 77u8, 89u8, 0u8, 90u8, 65u8, 0u8, 84u8, 82u8, - 0u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"ZA\0ET\0EG\0IN\0ES\0AZ\0BY\0BG\0IN\0IN\0BD\0FR\0IN\0BA\0ES\0PH\0US\0CZ\0RU\0GB\0DK\0DE\0IN\0DE\0GR\0US\0ES\0EE\0ES\0IR\0SN\0FI\0PH\0FO\0FR\0IE\0GB\0ES\0IN\0NG\0IL\0IN\0HR\0DE\0HU\0AM\x00001ID\0NG\0IS\0IT\0JP\0ID\0GE\0CV\0BR\0KZ\0KH\0IN\0KR\0IN\0IN\0KG\0LA\0LT\0LV\0IN\0NZ\0MK\0IN\0MN\0IN\0IN\0MY\0MM\0NP\0NL\0NO\0NO\0IN\0IN\0NG\0PL\0AF\0BR\0PE\0IN\0CH\0RO\0RU\0IN\0IN\0IT\0PK\0LK\0SK\0SI\0SO\0AL\0RS\0ID\0SE\0TZ\0IN\0IN\0TJ\0TH\0ET\0TM\0TO\0TR\0RU\0UA\0PK\0UZ\0VN\0SN\0ZA\0NG\0BR\0HK\0CN\0ZA\0") }, ) }, @@ -679,49 +44,22 @@ #[allow(unused_unsafe)] ::zerovec::ZeroMap2d::from_parts_unchecked( unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 97u8, 114u8, 99u8, 97u8, 122u8, 0u8, 99u8, 117u8, 0u8, 101u8, 110u8, 0u8, - 102u8, 102u8, 0u8, 103u8, 114u8, 99u8, 107u8, 107u8, 0u8, 107u8, 117u8, - 0u8, 107u8, 121u8, 0u8, 108u8, 105u8, 102u8, 109u8, 97u8, 110u8, 109u8, - 110u8, 0u8, 112u8, 97u8, 0u8, 112u8, 97u8, 108u8, 115u8, 100u8, 0u8, 116u8, - 103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8, 117u8, 122u8, 0u8, - 121u8, 117u8, 101u8, 122u8, 104u8, 0u8, - ]) + ::zerovec::ZeroVec::from_bytes_unchecked( + b"az\0en\0ff\0kk\0ky\0mn\0pa\0sd\0tg\0uz\0yuezh\0", + ) }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 2u8, 0u8, 0u8, 0u8, 3u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, - 0u8, 6u8, 0u8, 0u8, 0u8, 7u8, 0u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 10u8, 0u8, - 0u8, 0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, - 15u8, 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 20u8, 0u8, - 0u8, 0u8, 21u8, 0u8, 0u8, 0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8, - 24u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"\x01\0\0\0\x02\0\0\0\x03\0\0\0\x04\0\0\0\x06\0\0\0\x07\0\0\0\x08\0\0\0\x0B\0\0\0\x0C\0\0\0\r\0\0\0\x0E\0\0\0\x11\0\0\0") }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 78u8, 98u8, 97u8, 116u8, 80u8, 97u8, 108u8, 109u8, 65u8, 114u8, 97u8, 98u8, - 71u8, 108u8, 97u8, 103u8, 83u8, 104u8, 97u8, 119u8, 65u8, 100u8, 108u8, - 109u8, 76u8, 105u8, 110u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, - 97u8, 98u8, 89u8, 101u8, 122u8, 105u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, - 116u8, 110u8, 76u8, 105u8, 109u8, 98u8, 78u8, 107u8, 111u8, 111u8, 77u8, - 111u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 80u8, 104u8, 108u8, 112u8, - 68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 111u8, 106u8, 83u8, 105u8, 110u8, - 100u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, - 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 66u8, - 111u8, 112u8, 111u8, 72u8, 97u8, 110u8, 98u8, 72u8, 97u8, 110u8, 116u8, - ]) + ::zerovec::ZeroVec::from_bytes_unchecked( + b"ArabShawAdlmArabArabLatnMongArabDevaKhojSindArabArabHansBopoHanbHant", + ) }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 74u8, 79u8, 0u8, 83u8, 89u8, 0u8, 73u8, 82u8, 0u8, 66u8, 71u8, 0u8, 71u8, - 66u8, 0u8, 71u8, 78u8, 0u8, 71u8, 82u8, 0u8, 67u8, 78u8, 0u8, 73u8, 81u8, - 0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8, - 71u8, 78u8, 0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 67u8, 78u8, 0u8, 73u8, - 78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8, 90u8, - 0u8, 78u8, 80u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 84u8, 87u8, 0u8, - 84u8, 87u8, 0u8, 84u8, 87u8, 0u8, - ]) + ::zerovec::ZeroVec::from_bytes_unchecked( + b"IR\0GB\0GN\0CN\0CN\0TR\0CN\0PK\0IN\0IN\0IN\0PK\0AF\0CN\0TW\0TW\0TW\0", + ) }, ) }, diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1/und.rs.data b/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1/und.rs.data index 5ead959083c..a13646a0b92 100644 --- a/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1/und.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1/und.rs.data @@ -3,213 +3,10 @@ #[allow(unused_unsafe)] ::zerovec::ZeroMap::from_parts_unchecked( unsafe { - ::zerovec::VarZeroVec::from_bytes_unchecked(&[ - 131u8, 0u8, 0u8, 0u8, 0u8, 0u8, 6u8, 0u8, 11u8, 0u8, 16u8, 0u8, 21u8, 0u8, - 26u8, 0u8, 31u8, 0u8, 36u8, 0u8, 41u8, 0u8, 46u8, 0u8, 51u8, 0u8, 56u8, - 0u8, 61u8, 0u8, 66u8, 0u8, 71u8, 0u8, 76u8, 0u8, 81u8, 0u8, 86u8, 0u8, - 91u8, 0u8, 96u8, 0u8, 101u8, 0u8, 106u8, 0u8, 111u8, 0u8, 116u8, 0u8, - 121u8, 0u8, 126u8, 0u8, 131u8, 0u8, 136u8, 0u8, 141u8, 0u8, 146u8, 0u8, - 151u8, 0u8, 156u8, 0u8, 161u8, 0u8, 166u8, 0u8, 171u8, 0u8, 176u8, 0u8, - 181u8, 0u8, 186u8, 0u8, 191u8, 0u8, 196u8, 0u8, 201u8, 0u8, 206u8, 0u8, - 211u8, 0u8, 216u8, 0u8, 221u8, 0u8, 226u8, 0u8, 231u8, 0u8, 236u8, 0u8, - 241u8, 0u8, 246u8, 0u8, 251u8, 0u8, 0u8, 1u8, 5u8, 1u8, 10u8, 1u8, 15u8, - 1u8, 20u8, 1u8, 25u8, 1u8, 30u8, 1u8, 35u8, 1u8, 40u8, 1u8, 45u8, 1u8, - 50u8, 1u8, 55u8, 1u8, 60u8, 1u8, 65u8, 1u8, 70u8, 1u8, 75u8, 1u8, 80u8, - 1u8, 85u8, 1u8, 90u8, 1u8, 95u8, 1u8, 100u8, 1u8, 105u8, 1u8, 110u8, 1u8, - 115u8, 1u8, 120u8, 1u8, 125u8, 1u8, 130u8, 1u8, 135u8, 1u8, 140u8, 1u8, - 145u8, 1u8, 150u8, 1u8, 155u8, 1u8, 160u8, 1u8, 165u8, 1u8, 170u8, 1u8, - 175u8, 1u8, 180u8, 1u8, 185u8, 1u8, 190u8, 1u8, 195u8, 1u8, 200u8, 1u8, - 205u8, 1u8, 210u8, 1u8, 215u8, 1u8, 220u8, 1u8, 225u8, 1u8, 230u8, 1u8, - 235u8, 1u8, 240u8, 1u8, 245u8, 1u8, 250u8, 1u8, 255u8, 1u8, 4u8, 2u8, 9u8, - 2u8, 14u8, 2u8, 19u8, 2u8, 24u8, 2u8, 29u8, 2u8, 34u8, 2u8, 39u8, 2u8, - 44u8, 2u8, 49u8, 2u8, 54u8, 2u8, 59u8, 2u8, 64u8, 2u8, 71u8, 2u8, 73u8, - 2u8, 75u8, 2u8, 77u8, 2u8, 82u8, 2u8, 87u8, 2u8, 92u8, 2u8, 97u8, 2u8, - 102u8, 2u8, 107u8, 2u8, 112u8, 2u8, 117u8, 2u8, 122u8, 2u8, 127u8, 2u8, - 132u8, 2u8, 101u8, 110u8, 45u8, 49u8, 53u8, 48u8, 101u8, 110u8, 45u8, 65u8, - 71u8, 101u8, 110u8, 45u8, 65u8, 73u8, 101u8, 110u8, 45u8, 65u8, 84u8, - 101u8, 110u8, 45u8, 65u8, 85u8, 101u8, 110u8, 45u8, 66u8, 66u8, 101u8, - 110u8, 45u8, 66u8, 69u8, 101u8, 110u8, 45u8, 66u8, 77u8, 101u8, 110u8, - 45u8, 66u8, 83u8, 101u8, 110u8, 45u8, 66u8, 87u8, 101u8, 110u8, 45u8, 66u8, - 90u8, 101u8, 110u8, 45u8, 67u8, 67u8, 101u8, 110u8, 45u8, 67u8, 72u8, - 101u8, 110u8, 45u8, 67u8, 75u8, 101u8, 110u8, 45u8, 67u8, 77u8, 101u8, - 110u8, 45u8, 67u8, 88u8, 101u8, 110u8, 45u8, 67u8, 89u8, 101u8, 110u8, - 45u8, 68u8, 69u8, 101u8, 110u8, 45u8, 68u8, 71u8, 101u8, 110u8, 45u8, 68u8, - 75u8, 101u8, 110u8, 45u8, 68u8, 77u8, 101u8, 110u8, 45u8, 69u8, 82u8, - 101u8, 110u8, 45u8, 70u8, 73u8, 101u8, 110u8, 45u8, 70u8, 74u8, 101u8, - 110u8, 45u8, 70u8, 75u8, 101u8, 110u8, 45u8, 70u8, 77u8, 101u8, 110u8, - 45u8, 71u8, 66u8, 101u8, 110u8, 45u8, 71u8, 68u8, 101u8, 110u8, 45u8, 71u8, - 71u8, 101u8, 110u8, 45u8, 71u8, 72u8, 101u8, 110u8, 45u8, 71u8, 73u8, - 101u8, 110u8, 45u8, 71u8, 77u8, 101u8, 110u8, 45u8, 71u8, 89u8, 101u8, - 110u8, 45u8, 72u8, 75u8, 101u8, 110u8, 45u8, 73u8, 69u8, 101u8, 110u8, - 45u8, 73u8, 76u8, 101u8, 110u8, 45u8, 73u8, 77u8, 101u8, 110u8, 45u8, 73u8, - 78u8, 101u8, 110u8, 45u8, 73u8, 79u8, 101u8, 110u8, 45u8, 74u8, 69u8, - 101u8, 110u8, 45u8, 74u8, 77u8, 101u8, 110u8, 45u8, 75u8, 69u8, 101u8, - 110u8, 45u8, 75u8, 73u8, 101u8, 110u8, 45u8, 75u8, 78u8, 101u8, 110u8, - 45u8, 75u8, 89u8, 101u8, 110u8, 45u8, 76u8, 67u8, 101u8, 110u8, 45u8, 76u8, - 82u8, 101u8, 110u8, 45u8, 76u8, 83u8, 101u8, 110u8, 45u8, 77u8, 71u8, - 101u8, 110u8, 45u8, 77u8, 79u8, 101u8, 110u8, 45u8, 77u8, 83u8, 101u8, - 110u8, 45u8, 77u8, 84u8, 101u8, 110u8, 45u8, 77u8, 85u8, 101u8, 110u8, - 45u8, 77u8, 86u8, 101u8, 110u8, 45u8, 77u8, 87u8, 101u8, 110u8, 45u8, 77u8, - 89u8, 101u8, 110u8, 45u8, 78u8, 65u8, 101u8, 110u8, 45u8, 78u8, 70u8, - 101u8, 110u8, 45u8, 78u8, 71u8, 101u8, 110u8, 45u8, 78u8, 76u8, 101u8, - 110u8, 45u8, 78u8, 82u8, 101u8, 110u8, 45u8, 78u8, 85u8, 101u8, 110u8, - 45u8, 78u8, 90u8, 101u8, 110u8, 45u8, 80u8, 71u8, 101u8, 110u8, 45u8, 80u8, - 75u8, 101u8, 110u8, 45u8, 80u8, 78u8, 101u8, 110u8, 45u8, 80u8, 87u8, - 101u8, 110u8, 45u8, 82u8, 87u8, 101u8, 110u8, 45u8, 83u8, 66u8, 101u8, - 110u8, 45u8, 83u8, 67u8, 101u8, 110u8, 45u8, 83u8, 68u8, 101u8, 110u8, - 45u8, 83u8, 69u8, 101u8, 110u8, 45u8, 83u8, 71u8, 101u8, 110u8, 45u8, 83u8, - 72u8, 101u8, 110u8, 45u8, 83u8, 73u8, 101u8, 110u8, 45u8, 83u8, 76u8, - 101u8, 110u8, 45u8, 83u8, 83u8, 101u8, 110u8, 45u8, 83u8, 88u8, 101u8, - 110u8, 45u8, 83u8, 90u8, 101u8, 110u8, 45u8, 84u8, 67u8, 101u8, 110u8, - 45u8, 84u8, 75u8, 101u8, 110u8, 45u8, 84u8, 79u8, 101u8, 110u8, 45u8, 84u8, - 84u8, 101u8, 110u8, 45u8, 84u8, 86u8, 101u8, 110u8, 45u8, 84u8, 90u8, - 101u8, 110u8, 45u8, 85u8, 71u8, 101u8, 110u8, 45u8, 86u8, 67u8, 101u8, - 110u8, 45u8, 86u8, 71u8, 101u8, 110u8, 45u8, 86u8, 85u8, 101u8, 110u8, - 45u8, 87u8, 83u8, 101u8, 110u8, 45u8, 90u8, 65u8, 101u8, 110u8, 45u8, 90u8, - 77u8, 101u8, 110u8, 45u8, 90u8, 87u8, 101u8, 115u8, 45u8, 65u8, 82u8, - 101u8, 115u8, 45u8, 66u8, 79u8, 101u8, 115u8, 45u8, 66u8, 82u8, 101u8, - 115u8, 45u8, 66u8, 90u8, 101u8, 115u8, 45u8, 67u8, 76u8, 101u8, 115u8, - 45u8, 67u8, 79u8, 101u8, 115u8, 45u8, 67u8, 82u8, 101u8, 115u8, 45u8, 67u8, - 85u8, 101u8, 115u8, 45u8, 68u8, 79u8, 101u8, 115u8, 45u8, 69u8, 67u8, - 101u8, 115u8, 45u8, 71u8, 84u8, 101u8, 115u8, 45u8, 72u8, 78u8, 101u8, - 115u8, 45u8, 77u8, 88u8, 101u8, 115u8, 45u8, 78u8, 73u8, 101u8, 115u8, - 45u8, 80u8, 65u8, 101u8, 115u8, 45u8, 80u8, 69u8, 101u8, 115u8, 45u8, 80u8, - 82u8, 101u8, 115u8, 45u8, 80u8, 89u8, 101u8, 115u8, 45u8, 83u8, 86u8, - 101u8, 115u8, 45u8, 85u8, 83u8, 101u8, 115u8, 45u8, 85u8, 89u8, 101u8, - 115u8, 45u8, 86u8, 69u8, 104u8, 105u8, 45u8, 76u8, 97u8, 116u8, 110u8, - 104u8, 116u8, 110u8, 98u8, 110u8, 110u8, 112u8, 116u8, 45u8, 65u8, 79u8, - 112u8, 116u8, 45u8, 67u8, 72u8, 112u8, 116u8, 45u8, 67u8, 86u8, 112u8, - 116u8, 45u8, 70u8, 82u8, 112u8, 116u8, 45u8, 71u8, 81u8, 112u8, 116u8, - 45u8, 71u8, 87u8, 112u8, 116u8, 45u8, 76u8, 85u8, 112u8, 116u8, 45u8, 77u8, - 79u8, 112u8, 116u8, 45u8, 77u8, 90u8, 112u8, 116u8, 45u8, 83u8, 84u8, - 112u8, 116u8, 45u8, 84u8, 76u8, 122u8, 104u8, 45u8, 72u8, 97u8, 110u8, - 116u8, 45u8, 77u8, 79u8, - ]) + :: zerovec :: VarZeroVec :: from_bytes_unchecked (b"\x84\0\0\0\0\0\x06\0\x0B\0\x10\0\x15\0\x1A\0\x1F\0$\0)\0.\x003\08\0=\0B\0G\0L\0Q\0V\0[\0`\0e\0j\0o\0t\0y\0~\0\x83\0\x88\0\x8D\0\x92\0\x97\0\x9C\0\xA1\0\xA6\0\xAB\0\xB0\0\xB5\0\xBA\0\xBF\0\xC4\0\xC9\0\xCE\0\xD3\0\xD8\0\xDD\0\xE2\0\xE7\0\xEC\0\xF1\0\xF6\0\xFB\0\0\x01\x05\x01\n\x01\x0F\x01\x14\x01\x19\x01\x1E\x01#\x01(\x01-\x012\x017\x01<\x01A\x01F\x01K\x01P\x01U\x01Z\x01_\x01d\x01i\x01n\x01s\x01x\x01}\x01\x82\x01\x87\x01\x8C\x01\x91\x01\x96\x01\x9B\x01\xA0\x01\xA5\x01\xAA\x01\xAF\x01\xB4\x01\xB9\x01\xBE\x01\xC3\x01\xC8\x01\xCD\x01\xD2\x01\xD7\x01\xDC\x01\xE1\x01\xE6\x01\xEB\x01\xF0\x01\xF5\x01\xFA\x01\xFF\x01\x04\x02\t\x02\x0E\x02\x13\x02\x18\x02\x1D\x02\"\x02'\x02,\x021\x026\x02;\x02@\x02G\x02I\x02K\x02M\x02R\x02W\x02\\\x02a\x02f\x02k\x02p\x02u\x02z\x02\x7F\x02\x84\x02\x89\x02en-150en-AGen-AIen-ATen-AUen-BBen-BEen-BMen-BSen-BWen-BZen-CCen-CHen-CKen-CMen-CXen-CYen-DEen-DGen-DKen-DMen-ERen-FIen-FJen-FKen-FMen-GBen-GDen-GGen-GHen-GIen-GMen-GYen-HKen-IEen-ILen-IMen-INen-IOen-JEen-JMen-KEen-KIen-KNen-KYen-LCen-LRen-LSen-MGen-MOen-MSen-MTen-MUen-MVen-MWen-MYen-NAen-NFen-NGen-NLen-NRen-NUen-NZen-PGen-PKen-PNen-PWen-RWen-SBen-SCen-SDen-SEen-SGen-SHen-SIen-SLen-SSen-SXen-SZen-TCen-TKen-TOen-TTen-TVen-TZen-UGen-VCen-VGen-VUen-WSen-ZAen-ZMen-ZWes-ARes-BOes-BRes-BZes-CLes-COes-CRes-CUes-DOes-ECes-GTes-HNes-MXes-NIes-PAes-PEes-PRes-PYes-SVes-USes-UYes-VEhi-Latnhtnbnnno-NOpt-AOpt-CHpt-CVpt-FRpt-GQpt-GWpt-LUpt-MOpt-MZpt-STpt-TLzh-Hant-MO") }, unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, - 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, - 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, - 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, - 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, - 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, - 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, - 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, - 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, - 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, - 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, - 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, - 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, - 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, - 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, - 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, - 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, - 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, - 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, - 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, - 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, - 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, - 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, - 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, - 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, - 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, - 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, - 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, - 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, - 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 115u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, - 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, - 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, - 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, - 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, - 49u8, 57u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 73u8, 78u8, - 0u8, 102u8, 114u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 72u8, 84u8, 0u8, - 110u8, 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 110u8, - 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 112u8, 116u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, - 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, - 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, - 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, - 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, - 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 122u8, 104u8, 0u8, 1u8, 72u8, - 97u8, 110u8, 116u8, 1u8, 72u8, 75u8, 0u8, - ]) + :: zerovec :: ZeroVec :: from_bytes_unchecked (b"en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419en\0\0\0\0\0\0\x01IN\0fr\0\0\0\0\0\0\x01HT\0no\0\0\0\0\0\0\0\0\0\0no\0\0\0\0\0\0\0\0\0\0no\0\0\0\0\0\0\0\0\0\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0zh\0\x01Hant\x01HK\0") }, ) }, diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1/und.rs.data b/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1/und.rs.data index 7d70e78c327..647f8f51601 100644 --- a/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1/und.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1/und.rs.data @@ -2,34 +2,20 @@ parents: unsafe { #[allow(unused_unsafe)] ::zerovec::ZeroMap::from_parts_unchecked( - unsafe { - ::zerovec::VarZeroVec::from_bytes_unchecked(&[ - 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 121u8, 117u8, 101u8, - ]) - }, - unsafe { - ::zerovec::ZeroVec::from_bytes_unchecked(&[ - 122u8, 104u8, 0u8, 1u8, 72u8, 97u8, 110u8, 116u8, 0u8, 0u8, 0u8, 0u8, - ]) - }, + unsafe { ::zerovec::VarZeroVec::from_bytes_unchecked(b"\x01\0\0\0\0\0yue") }, + unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(b"zh\0\x01Hant\0\0\0\0") }, ) }, unicode_extension_defaults: unsafe { #[allow(unused_unsafe)] ::zerovec::ZeroMap2d::from_parts_unchecked( - unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[99u8, 111u8]) }, - unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[2u8, 0u8, 0u8, 0u8]) }, + unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(b"co") }, + unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(b"\x02\0\0\0") }, unsafe { - ::zerovec::VarZeroVec::from_bytes_unchecked(&[ - 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 122u8, 104u8, 122u8, 104u8, 45u8, - 72u8, 97u8, 110u8, 116u8, - ]) + ::zerovec::VarZeroVec::from_bytes_unchecked(b"\x02\0\0\0\0\0\x02\0zhzh-Hant") }, unsafe { - ::zerovec::VarZeroVec::from_bytes_unchecked(&[ - 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 6u8, 0u8, 112u8, 105u8, 110u8, 121u8, 105u8, - 110u8, 115u8, 116u8, 114u8, 111u8, 107u8, 101u8, - ]) + ::zerovec::VarZeroVec::from_bytes_unchecked(b"\x02\0\0\0\0\0\x06\0pinyinstroke") }, ) }, diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/en.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/en.rs.data index cb5cbfa87c2..4bf244019ff 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/en.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/en.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", and ", 6u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", and ", 6u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" and ", 5u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", & ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", & ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" & ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" & ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/es.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/es.rs.data index 51f91097518..84de7cd01a7 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/es.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/es.rs.data @@ -1,836 +1,116 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(::icu_list::provider::SpecialCasePattern { condition: unsafe { ::icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked( if cfg!(target_endian = "little") { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, - 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, - 0u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 0u8, 0u8, 254u8, 255u8, 0u8, 0u8, 0u8, 2u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 0u8, 0u8, 1u8, - 40u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 4u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, - 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }, ) }, - pattern: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + pattern: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), }), }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(::icu_list::provider::SpecialCasePattern { condition: unsafe { ::icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked( if cfg!(target_endian = "little") { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, - 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, - 0u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 0u8, 0u8, 254u8, 255u8, 0u8, 0u8, 0u8, 2u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 0u8, 0u8, 1u8, - 40u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 4u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, - 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }, ) }, - pattern: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + pattern: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), }), }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(::icu_list::provider::SpecialCasePattern { condition: unsafe { ::icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked( if cfg!(target_endian = "little") { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, - 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, - 0u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 0u8, 0u8, 254u8, 255u8, 0u8, 0u8, 0u8, 2u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 0u8, 0u8, 1u8, - 40u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 4u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, - 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }, ) }, - pattern: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + pattern: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), }), }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(::icu_list::provider::SpecialCasePattern { condition: unsafe { ::icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked( if cfg!(target_endian = "little") { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, - 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, - 0u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 0u8, 0u8, 254u8, 255u8, 0u8, 0u8, 0u8, 2u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 0u8, 0u8, 1u8, - 40u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 4u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, - 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }, ) }, - pattern: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + pattern: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), }), }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(::icu_list::provider::SpecialCasePattern { condition: unsafe { ::icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked( if cfg!(target_endian = "little") { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, - 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, - 0u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 0u8, 0u8, 254u8, 255u8, 0u8, 0u8, 0u8, 2u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 0u8, 0u8, 1u8, - 40u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 4u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, - 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }, ) }, - pattern: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + pattern: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), }), }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(::icu_list::provider::SpecialCasePattern { condition: unsafe { ::icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked( if cfg!(target_endian = "little") { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, - 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, - 0u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { - &[ - 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, - 120u8, 45u8, 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, - 45u8, 100u8, 102u8, 97u8, 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, - 101u8, 0u8, 0u8, 0u8, 0u8, 254u8, 255u8, 0u8, 0u8, 0u8, 2u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, - 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, - 7u8, 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, - 13u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, - 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, - 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, - 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, - 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, - 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, 21u8, - 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, - 22u8, 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, - 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, 0u8, 0u8, 1u8, - 40u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 5u8, - 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, - 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, - 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, 4u8, 7u8, 9u8, 9u8, - 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, 23u8, - 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, - 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, - 68u8, 0u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, - 221u8, 0u8, 0u8, 0u8, 236u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, 25u8, 1u8, 0u8, 0u8, - 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 68u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, - 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, - 17u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, - 0u8, 15u8, 16u8, 0u8, 0u8, 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, 221u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, - 0u8, 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 4u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, - 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, - 35u8, - ] + b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }, ) }, - pattern: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + pattern: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), }), }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/fr.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/fr.rs.data index 66ec8f600f4..79a97e50f5a 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/fr.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/fr.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" et ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" et ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" et ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" et ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/it.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/it.rs.data index cbccf1120d2..b976b6cb65a 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/it.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/it.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/ja.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/ja.rs.data index 9fd168375cb..d76d567ebf8 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/ja.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/ja.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/pt.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/pt.rs.data index 403975213ef..3d8c89f9072 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/pt.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/pt.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/ru.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/ru.rs.data index 933cb85c8fe..653ce28d615 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/ru.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/ru.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" и ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" и ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" и ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" и ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/tr.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/tr.rs.data index 286eaf69f34..9fa6eb56ade 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/tr.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/tr.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" ve ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" ve ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" ve ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(" ve ", 4u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/und.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/und.rs.data index 2d2c9bcecb1..66b55c25368 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/und.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/und.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/zh-Hant.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/zh-Hant.rs.data index 5d96cc85e8c..38da6ecf815 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/zh-Hant.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/zh-Hant.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1/zh.rs.data b/compiler/rustc_baked_icu_data/src/data/list/and_v1/zh.rs.data index 4a38374caf4..d4dac1c386e 100644 --- a/compiler/rustc_baked_icu_data/src/data/list/and_v1/zh.rs.data +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1/zh.rs.data @@ -1,74 +1,50 @@ ::icu_list::provider::ListFormatterPatternsV1([ ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ::icu_list::provider::ConditionalListJoinerPattern { - default: unsafe { - ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) - }, + default: ::icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None, }, ]) diff --git a/compiler/rustc_baked_icu_data/src/data/mod.rs b/compiler/rustc_baked_icu_data/src/data/mod.rs index ce33339ad99..943187808b8 100644 --- a/compiler/rustc_baked_icu_data/src/data/mod.rs +++ b/compiler/rustc_baked_icu_data/src/data/mod.rs @@ -1,7 +1,10 @@ // @generated +#[clippy::msrv = "1.61"] mod fallback; +#[clippy::msrv = "1.61"] mod list; -use ::icu_provider::prelude::*; +#[clippy::msrv = "1.61"] +use icu_provider::prelude::*; /// Implement [`DataProvider<M>`] on the given struct using the data /// hardcoded in this module. This allows the struct to be used with /// `icu`'s `_unstable` constructors. @@ -17,6 +20,7 @@ use ::icu_provider::prelude::*; #[allow(unused_macros)] macro_rules! impl_data_provider { ($ provider : path) => { + #[clippy::msrv = "1.61"] impl DataProvider<::icu_list::provider::AndListV1Marker> for $provider { fn load(&self, req: DataRequest) -> Result<DataResponse<::icu_list::provider::AndListV1Marker>, DataError> { list::and_v1::lookup(&req.locale) @@ -26,6 +30,7 @@ macro_rules! impl_data_provider { .ok_or_else(|| DataErrorKind::MissingLocale.with_req(::icu_list::provider::AndListV1Marker::KEY, req)) } } + #[clippy::msrv = "1.61"] impl DataProvider<::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker> for $provider { fn load( &self, @@ -41,6 +46,7 @@ macro_rules! impl_data_provider { }) } } + #[clippy::msrv = "1.61"] impl DataProvider<::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker> for $provider { fn load( &self, @@ -56,6 +62,7 @@ macro_rules! impl_data_provider { }) } } + #[clippy::msrv = "1.61"] impl DataProvider<::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker> for $provider { fn load( &self, @@ -87,6 +94,7 @@ macro_rules! impl_data_provider { #[allow(unused_macros)] macro_rules! impl_any_provider { ($ provider : path) => { + #[clippy::msrv = "1.61"] impl AnyProvider for $provider { fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> { const ANDLISTV1MARKER: ::icu_provider::DataKeyHash = ::icu_list::provider::AndListV1Marker::KEY.hashed(); @@ -109,5 +117,6 @@ macro_rules! impl_any_provider { } }; } +#[clippy::msrv = "1.61"] pub struct BakedDataProvider; impl_data_provider!(BakedDataProvider); diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 6259722b694..74e6ce37e97 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -54,7 +54,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> { // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not // contain dangling references. - PlaceContext::NonUse(NonUseContext::PlaceMention) | + PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) | PlaceContext::NonUse(NonUseContext::AscribeUserTy) | PlaceContext::MutatingUse(MutatingUseContext::AddressOf) | diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index ac84188a35f..04b8174079a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -158,7 +158,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else if reinits > 1 { err.span_note( MultiSpan::from_spans(reinit_spans), - &if reinits <= 3 { + if reinits <= 3 { format!("these {reinits} reinitializations might get skipped") } else { format!( @@ -253,7 +253,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // We have a `&mut` ref, we need to reborrow on each iteration (#62112). err.span_suggestion_verbose( span.shrink_to_lo(), - &format!( + format!( "consider creating a fresh reborrow of {} here", self.describe_place(moved_place) .map(|n| format!("`{n}`")) @@ -304,7 +304,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .. } = use_spans { - err.note(&format!( + err.note(format!( "{} occurs due to deref coercion to `{deref_target_ty}`", desired_action.as_noun(), )); @@ -586,7 +586,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // _ => {} // We don't want to point to this. // }; // ``` - err.span_label(sp, &label); + err.span_label(sp, label); shown = true; } } @@ -1139,7 +1139,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } if union_type_name != "" { - err.note(&format!( + err.note(format!( "{} is a field of the union `{}`, so it overlaps the field {}", msg_place, union_type_name, msg_borrow, )); @@ -1238,14 +1238,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } err.span_help( inner_call_span, - &format!( + format!( "try adding a local storing this{}...", if use_span.is_some() { "" } else { " argument" } ), ); err.span_help( outer_call_span, - &format!( + format!( "...and then using that local {}", if use_span.is_some() { "here" } else { "as the argument to this call" } ), @@ -2281,7 +2281,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); err.span_suggestion_verbose( sugg_span, - &format!( + format!( "to force the {} to take ownership of {} (and any \ other referenced variables), use the `move` keyword", kind, captured_var @@ -2293,7 +2293,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { match category { ConstraintCategory::Return(_) | ConstraintCategory::OpaqueType => { let msg = format!("{} is returned here", kind); - err.span_note(constraint_span, &msg); + err.span_note(constraint_span, msg); } ConstraintCategory::CallArgument(_) => { fr_name.highlight_region_name(&mut err); @@ -2304,7 +2304,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } else { let msg = format!("{scope} requires argument type to outlive `{fr_name}`"); - err.span_note(constraint_span, &msg); + err.span_note(constraint_span, msg); } } _ => bug!( @@ -2626,7 +2626,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }); if let Some(Ok(instance)) = deref_target { let deref_target_ty = instance.ty(tcx, self.param_env); - err.note(&format!( + err.note(format!( "borrow occurs due to deref coercion to `{}`", deref_target_ty )); @@ -3180,7 +3180,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { diag.span_label(*return_span, format!("also has lifetime `{}`", region_name,)); - diag.help(&format!( + diag.help(format!( "use data from the highlighted arguments which match the `{}` lifetime of \ the return type", region_name, diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index f995c3165a9..d0cb1126f38 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -90,7 +90,7 @@ impl<'tcx> BorrowExplanation<'tcx> { { err.span_label( pat.span, - &format!("binding `{ident}` declared here"), + format!("binding `{ident}` declared here"), ); } } @@ -323,7 +323,7 @@ impl<'tcx> BorrowExplanation<'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), - &msg, + msg, format!(" + {suggestable_name}"), Applicability::Unspecified, ); diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index a780255725e..7fc8eb161d2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1073,7 +1073,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if !is_loop_move { err.span_suggestion_verbose( move_span.shrink_to_lo(), - &format!( + format!( "consider creating a fresh reborrow of {} here", self.describe_place(moved_place.as_ref()) .map(|n| format!("`{n}`")) @@ -1120,7 +1120,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }); } if let Some(clone_trait) = tcx.lang_items().clone_trait() - && let trait_ref = tcx.mk_trait_ref(clone_trait, [ty]) + && let trait_ref = ty::TraitRef::new(tcx, clone_trait, [ty]) && let o = Obligation::new( tcx, ObligationCause::dummy(), diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 67af96a71e3..8b77477a31a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -533,7 +533,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { suggestions.sort_unstable_by_key(|&(span, _, _)| span); suggestions.dedup_by_key(|&mut (span, _, _)| span); for (span, msg, suggestion) in suggestions { - err.span_suggestion_verbose(span, &msg, suggestion, Applicability::MachineApplicable); + err.span_suggestion_verbose(span, msg, suggestion, Applicability::MachineApplicable); } } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index e3d81194ac8..7558247948f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -573,7 +573,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if !is_trait_sig { err.span_suggestion_verbose( err_help_span, - &format!( + format!( "consider changing this to be a mutable {pointer_desc}" ), suggested_code, @@ -582,7 +582,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else if let Some(x) = local_trait { err.span_suggestion_verbose( x, - &format!( + format!( "consider changing that to be a mutable {pointer_desc}" ), suggested_code, @@ -636,14 +636,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; err.span_suggestion_verbose( span, - &format!("consider {changing} this binding's type"), + format!("consider {changing} this binding's type"), sugg, Applicability::HasPlaceholders, ); } else { err.span_label( err_label_span, - &format!( + format!( "consider changing this binding's type to be: `{message}`" ), ); @@ -679,13 +679,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { match opt_source { Some(BorrowedContentSource::OverloadedDeref(ty)) => { - err.help(&format!( + err.help(format!( "trait `DerefMut` is required to modify through a dereference, \ but it is not implemented for `{ty}`", )); } Some(BorrowedContentSource::OverloadedIndex(ty)) => { - err.help(&format!( + err.help(format!( "trait `IndexMut` is required to modify indexed content, \ but it is not implemented for `{ty}`", )); @@ -736,7 +736,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // val[index] = rv; // ---------- place self.err.multipart_suggestions( - &format!( + format!( "to modify a `{}`, use `.get_mut()`, `.insert()` or the entry API", self.ty, ), @@ -788,7 +788,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { { // val[index].path(args..); self.err.multipart_suggestion( - &format!("to modify a `{}` use `.get_mut()`", self.ty), + format!("to modify a `{}` use `.get_mut()`", self.ty), vec![ ( val.span.shrink_to_hi().with_hi(index.span.lo()), @@ -822,7 +822,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let mut v = V { assign_span, err, ty, suggested: false }; v.visit_body(body); if !v.suggested { - err.help(&format!( + err.help(format!( "to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API", )); } diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index d5ece57437e..ffba6058186 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -171,7 +171,7 @@ impl OutlivesSuggestionBuilder { if let (Some(fr_name), Some(outlived_fr_name)) = (fr_name, outlived_fr_name) && !matches!(outlived_fr_name.source, RegionNameSource::Static) { - diag.help(&format!( + diag.help(format!( "consider adding the following bound: `{fr_name}: {outlived_fr_name}`", )); } @@ -207,7 +207,7 @@ impl OutlivesSuggestionBuilder { // If there is exactly one suggestable constraints, then just suggest it. Otherwise, emit a // list of diagnostics. let mut diag = if suggested.len() == 1 { - mbcx.infcx.tcx.sess.diagnostic().struct_help(&match suggested.last().unwrap() { + mbcx.infcx.tcx.sess.diagnostic().struct_help(match suggested.last().unwrap() { SuggestedConstraint::Outlives(a, bs) => { let bs: SmallVec<[String; 2]> = bs.iter().map(|r| r.to_string()).collect(); format!("add bound `{a}: {}`", bs.join(" + ")) @@ -232,15 +232,15 @@ impl OutlivesSuggestionBuilder { match constraint { SuggestedConstraint::Outlives(a, bs) => { let bs: SmallVec<[String; 2]> = bs.iter().map(|r| r.to_string()).collect(); - diag.help(&format!("add bound `{a}: {}`", bs.join(" + "))); + diag.help(format!("add bound `{a}: {}`", bs.join(" + "))); } SuggestedConstraint::Equal(a, b) => { - diag.help(&format!( + diag.help(format!( "`{a}` and `{b}` must be the same: replace one with the other", )); } SuggestedConstraint::Static(a) => { - diag.help(&format!("replace `{a}` with `'static`")); + diag.help(format!("replace `{a}` with `'static`")); } } } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 9fcebeb0acd..8ec872e2057 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -533,8 +533,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } _ => panic!("Unexpected type {ty:?}"), }; - diag.note(&format!("requirement occurs because of {desc}",)); - diag.note(¬e); + diag.note(format!("requirement occurs because of {desc}",)); + diag.note(note); diag.help("see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance"); } } @@ -845,7 +845,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { return; } - let Some((alias_tys, alias_span)) = self + let Some((alias_tys, alias_span, lt_addition_span)) = self .infcx .tcx .return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id) else { return; }; @@ -858,12 +858,22 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { () } if let TyKind::TraitObject(_, lt, _) = alias_ty.kind { - spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string())); + if lt.ident.name == kw::Empty { + spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string())); + } else { + spans_suggs.push((lt.ident.span, "'a".to_string())); + } } } - spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string())); + + if let Some(lt_addition_span) = lt_addition_span { + spans_suggs.push((lt_addition_span, "'a, ".to_string())); + } else { + spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string())); + } + diag.multipart_suggestion_verbose( - &format!( + format!( "to declare that the trait object {captures}, you can add a lifetime parameter `'a` in the type alias" ), spans_suggs, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index f69c4829ae2..f38e1605fa5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -622,7 +622,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // programs, so we need to use delay_span_bug here. See #82126. self.infcx.tcx.sess.delay_span_bug( hir_arg.span(), - &format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"), + format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"), ); } } diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 06986f848bf..863c92acdf4 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -138,7 +138,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.consume_operand(location, cond); use rustc_middle::mir::AssertKind; - if let AssertKind::BoundsCheck { len, index } = msg { + if let AssertKind::BoundsCheck { len, index } = &**msg { self.consume_operand(location, len); self.consume_operand(location, index); } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 6900729d671..315303b25fe 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -498,11 +498,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { let next_region = self.infcx.next_region_var(origin); let vid = next_region.as_var(); - if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() { + if cfg!(debug_assertions) { debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin); let ctxt = get_ctxt_fn(); let mut var_to_origin = self.reg_var_to_origin.borrow_mut(); - var_to_origin.insert(vid, ctxt); + assert_eq!(var_to_origin.insert(vid, ctxt), None); } next_region @@ -520,11 +520,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { let next_region = self.infcx.next_nll_region_var(origin); let vid = next_region.as_var(); - if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() { + if cfg!(debug_assertions) { debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin); let ctxt = get_ctxt_fn(); let mut var_to_origin = self.reg_var_to_origin.borrow_mut(); - var_to_origin.insert(vid, ctxt); + assert_eq!(var_to_origin.insert(vid, ctxt), None); } next_region @@ -738,7 +738,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.consume_operand(loc, (cond, span), flow_state); use rustc_middle::mir::AssertKind; - if let AssertKind::BoundsCheck { len, index } = msg { + if let AssertKind::BoundsCheck { len, index } = &**msg { self.consume_operand(loc, (len, span), flow_state); self.consume_operand(loc, (index, span), flow_state); } @@ -2022,7 +2022,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // been emitted (#52262). self.infcx.tcx.sess.delay_span_bug( span, - &format!( + format!( "Accessing `{:?}` with the kind `{:?}` shouldn't be possible", place, kind, ), @@ -2383,7 +2383,7 @@ mod error { } for (_, (mut diag, count)) in std::mem::take(&mut self.errors.buffered_mut_errors) { if count > 10 { - diag.note(&format!("...and {} other attempted mutable borrows", count - 10)); + diag.note(format!("...and {} other attempted mutable borrows", count - 10)); } diag.buffer(&mut self.errors.buffered); } diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 5f1bcb27ea7..a4394ddc01c 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -399,7 +399,7 @@ pub(super) fn dump_annotation<'tcx>( regioncx.annotate(tcx, &mut err); - err.note(&format!( + err.note(format!( "number of external vids: {}", closure_region_requirements.num_external_vids )); @@ -421,7 +421,7 @@ pub(super) fn dump_annotation<'tcx>( }; if !opaque_type_values.is_empty() { - err.note(&format!("Inferred opaque type values:\n{:#?}", opaque_type_values)); + err.note(format!("Inferred opaque type values:\n{:#?}", opaque_type_values)); } errors.buffer_non_error_diag(err); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 65573c71f14..8fbe814c856 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -76,7 +76,7 @@ pub struct RegionInferenceContext<'tcx> { /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if /// `B: A`. This is used to compute the universal regions that are required /// to outlive a given SCC. Computed lazily. - rev_scc_graph: Option<Rc<ReverseSccGraph>>, + rev_scc_graph: Option<ReverseSccGraph>, /// The "R0 member of [R1..Rn]" constraints, indexed by SCC. member_constraints: Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>, @@ -813,9 +813,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { // free region that must outlive the member region `R0` (`UB: // R0`). Therefore, we need only keep an option `O` if `UB: O` // for all UB. - let rev_scc_graph = self.reverse_scc_graph(); + self.compute_reverse_scc_graph(); let universal_region_relations = &self.universal_region_relations; - for ub in rev_scc_graph.upper_bounds(scc) { + for ub in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) { debug!(?ub); choice_regions.retain(|&o_r| universal_region_relations.outlives(ub, o_r)); } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 2b16655cf7d..4970ece5e7d 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -399,7 +399,7 @@ fn check_opaque_type_parameter_valid( return Err(tcx .sess .struct_span_err(span, "non-defining opaque type use in defining scope") - .span_note(spans, &format!("{} used multiple times", descr)) + .span_note(spans, format!("{} used multiple times", descr)) .emit()); } } diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index 23a59c12865..fe56bd54a3f 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -8,7 +8,6 @@ use rustc_data_structures::graph::vec_graph::VecGraph; use rustc_data_structures::graph::WithSuccessors; use rustc_middle::ty::RegionVid; use std::ops::Range; -use std::rc::Rc; pub(crate) struct ReverseSccGraph { graph: VecGraph<ConstraintSccIndex>, @@ -40,10 +39,10 @@ impl ReverseSccGraph { } impl RegionInferenceContext<'_> { - /// Compute and return the reverse SCC-based constraint graph (lazily). - pub(super) fn reverse_scc_graph(&mut self) -> Rc<ReverseSccGraph> { - if let Some(g) = &self.rev_scc_graph { - return g.clone(); + /// Compute the reverse SCC-based constraint graph (lazily). + pub(super) fn compute_reverse_scc_graph(&mut self) { + if self.rev_scc_graph.is_some() { + return; } let graph = self.constraint_sccs.reverse(); @@ -63,8 +62,6 @@ impl RegionInferenceContext<'_> { start += group_size; } - let rev_graph = Rc::new(ReverseSccGraph { graph, scc_regions, universal_regions }); - self.rev_scc_graph = Some(rev_graph.clone()); - rev_graph + self.rev_scc_graph = Some(ReverseSccGraph { graph, scc_regions, universal_regions }); } } diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 22de7549e94..4389d2b60bc 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -109,6 +109,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] + fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, location: Location) { + let old_ct = *ct; + *ct = self.renumber_regions(old_ct, || RegionCtxt::Location(location)); + + debug!(?ct); + } + + #[instrument(skip(self), level = "debug")] fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) { let literal = constant.literal; constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(location)); diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 4004966c40a..bd01c0b504c 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -249,7 +249,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { .infcx .tcx .sess - .delay_span_bug(span, &format!("failed to normalize {:?}", ty)); + .delay_span_bug(span, format!("failed to normalize {:?}", ty)); TypeOpOutput { output: self.infcx.tcx.ty_error(guar), constraints: None, diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 9250b8d3eaf..a06d4bcc6c7 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -106,7 +106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() { self.tcx().sess.delay_span_bug( body.span, - &format!( + format!( "Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})", body.yield_ty(), universal_regions.yield_ty, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index d5e50a61b03..dcabeb792be 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -236,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>( if hidden_type.has_non_region_infer() { let reported = infcx.tcx.sess.delay_span_bug( decl.hidden_type.span, - &format!("could not resolve {:#?}", hidden_type.ty.kind()), + format!("could not resolve {:#?}", hidden_type.ty.kind()), ); hidden_type.ty = infcx.tcx.ty_error(reported); } @@ -538,7 +538,8 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { let tcx = self.tcx(); - let trait_ref = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, [place_ty.ty]); + let trait_ref = + ty::TraitRef::from_lang_item(tcx, LangItem::Copy, self.last_span, [place_ty.ty]); // To have a `Copy` operand, the type `T` of the // value must be `Copy`. Note that we prove that `T: Copy`, @@ -771,12 +772,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { match context { PlaceContext::MutatingUse(_) => ty::Invariant, - PlaceContext::NonUse(StorageDead | StorageLive | PlaceMention | VarDebugInfo) => { - ty::Invariant - } + PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant, PlaceContext::NonMutatingUse( - Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf - | Projection, + Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | UniqueBorrow + | AddressOf | Projection, ) => ty::Covariant, PlaceContext::NonUse(AscribeUserTy) => ty::Covariant, } @@ -1237,8 +1236,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_rvalue(body, rv, location); if !self.unsized_feature_enabled() { - let trait_ref = - tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, [place_ty]); + let trait_ref = ty::TraitRef::from_lang_item( + tcx, + LangItem::Sized, + self.last_span, + [place_ty], + ); self.prove_trait_ref( trait_ref, location.to_locations(), @@ -1404,7 +1407,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); } - if let AssertKind::BoundsCheck { len, index } = msg { + if let AssertKind::BoundsCheck { len, index } = &**msg { if len.ty(body, tcx) != tcx.types.usize { span_mirbug!(self, len, "bounds-check length non-usize {:?}", len) } @@ -1798,6 +1801,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::Repeat(operand, len) => { self.check_operand(operand, location); + let array_ty = rvalue.ty(body.local_decls(), tcx); + self.prove_predicate( + ty::PredicateKind::WellFormed(array_ty.into()), + Locations::Single(location), + ConstraintCategory::Boring, + ); + // If the length cannot be evaluated we must assume that the length can be larger // than 1. // If the length is larger than 1, the repeat expression will need to copy the @@ -1810,7 +1820,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Operand::Move(place) => { // Make sure that repeated elements implement `Copy`. let ty = place.ty(body, tcx).ty; - let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, [ty]); + let trait_ref = + ty::TraitRef::from_lang_item(tcx, LangItem::Copy, span, [ty]); self.prove_trait_ref( trait_ref, @@ -1823,7 +1834,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [ty]); + let trait_ref = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, span, [ty]); self.prove_trait_ref( trait_ref, @@ -1835,7 +1846,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::ShallowInitBox(operand, ty) => { self.check_operand(operand, location); - let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [*ty]); + let trait_ref = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, span, [*ty]); self.prove_trait_ref( trait_ref, @@ -1932,9 +1943,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { CastKind::Pointer(PointerCast::Unsize) => { let &ty = ty; - let trait_ref = tcx - .at(span) - .mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]); + let trait_ref = ty::TraitRef::from_lang_item( + tcx, + LangItem::CoerceUnsized, + span, + [op.ty(body, tcx), ty], + ); self.prove_trait_ref( trait_ref, diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 7e6d17ec343..7158c62b548 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -131,9 +131,13 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env), }; - if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() { + if cfg!(debug_assertions) { let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut(); - var_to_origin.insert(reg.as_var(), RegionCtxt::Placeholder(reg_info)); + let new = RegionCtxt::Placeholder(reg_info); + let prev = var_to_origin.insert(reg.as_var(), new); + if let Some(prev) = prev { + assert_eq!(new, prev); + } } reg @@ -146,9 +150,10 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> universe, ); - if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() { + if cfg!(debug_assertions) { let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut(); - var_to_origin.insert(reg.as_var(), RegionCtxt::Existential(None)); + let prev = var_to_origin.insert(reg.as_var(), RegionCtxt::Existential(None)); + assert_eq!(prev, None); } reg diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 3f7f23df8d9..56f078f2da8 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -335,7 +335,7 @@ impl<'tcx> UniversalRegions<'tcx> { pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { match self.defining_ty { DefiningTy::Closure(def_id, substs) => { - err.note(&format!( + err.note(format!( "defining type: {} with closure substs {:#?}", tcx.def_path_str_with_substs(def_id, substs), &substs[tcx.generics_of(def_id).parent_count..], @@ -347,11 +347,11 @@ impl<'tcx> UniversalRegions<'tcx> { // and other things that are not stable across tests! // So we just include the region-vid. Annoying. for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| { - err.note(&format!("late-bound region is {:?}", self.to_region_vid(r))); + err.note(format!("late-bound region is {:?}", self.to_region_vid(r))); }); } DefiningTy::Generator(def_id, substs, _) => { - err.note(&format!( + err.note(format!( "defining type: {} with generator substs {:#?}", tcx.def_path_str_with_substs(def_id, substs), &substs[tcx.generics_of(def_id).parent_count..], @@ -361,23 +361,23 @@ impl<'tcx> UniversalRegions<'tcx> { // `r` but doing so is not stable across architectures // and so forth. for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| { - err.note(&format!("late-bound region is {:?}", self.to_region_vid(r))); + err.note(format!("late-bound region is {:?}", self.to_region_vid(r))); }); } DefiningTy::FnDef(def_id, substs) => { - err.note(&format!( + err.note(format!( "defining type: {}", tcx.def_path_str_with_substs(def_id, substs), )); } DefiningTy::Const(def_id, substs) => { - err.note(&format!( + err.note(format!( "defining constant type: {}", tcx.def_path_str_with_substs(def_id, substs), )); } DefiningTy::InlineConst(def_id, substs) => { - err.note(&format!( + err.note(format!( "defining inline constant type: {}", tcx.def_path_str_with_substs(def_id, substs), )); diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 5f6441660e3..44012e802aa 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -14,6 +14,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } +rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index c066512b09e..bb059a120df 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -2,9 +2,10 @@ use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter}; use rustc_ast::tokenstream::TokenStream; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::PResult; use rustc_expand::base::{self, *}; +use rustc_index::bit_set::GrowableBitSet; use rustc_parse::parser::Parser; use rustc_parse_format as parse; use rustc_session::lint; @@ -20,8 +21,8 @@ use crate::errors; pub struct AsmArgs { pub templates: Vec<P<ast::Expr>>, pub operands: Vec<(ast::InlineAsmOperand, Span)>, - named_args: FxHashMap<Symbol, usize>, - reg_args: FxHashSet<usize>, + named_args: FxIndexMap<Symbol, usize>, + reg_args: GrowableBitSet<usize>, pub clobber_abis: Vec<(Symbol, Span)>, options: ast::InlineAsmOptions, pub options_spans: Vec<Span>, @@ -56,8 +57,8 @@ pub fn parse_asm_args<'a>( let mut args = AsmArgs { templates: vec![first_template], operands: vec![], - named_args: FxHashMap::default(), - reg_args: FxHashSet::default(), + named_args: Default::default(), + reg_args: Default::default(), clobber_abis: Vec::new(), options: ast::InlineAsmOptions::empty(), options_spans: vec![], @@ -68,9 +69,7 @@ pub fn parse_asm_args<'a>( if !p.eat(&token::Comma) { if allow_templates { // After a template string, we always expect *only* a comma... - let mut err = diag.create_err(errors::AsmExpectedComma { span: p.token.span }); - p.maybe_annotate_with_ascription(&mut err, false); - return Err(err); + return Err(diag.create_err(errors::AsmExpectedComma { span: p.token.span })); } else { // ...after that delegate to `expect` to also include the other expected tokens. return Err(p.expect(&token::Comma).err().unwrap()); @@ -215,7 +214,7 @@ pub fn parse_asm_args<'a>( } else { if !args.named_args.is_empty() || !args.reg_args.is_empty() { let named = args.named_args.values().map(|p| args.operands[*p].1).collect(); - let explicit = args.reg_args.iter().map(|p| args.operands[*p].1).collect(); + let explicit = args.reg_args.iter().map(|p| args.operands[p].1).collect(); diag.emit_err(errors::AsmPositionalAfter { span, named, explicit }); } @@ -448,8 +447,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl // Register operands are implicitly used since they are not allowed to be // referenced in the template string. let mut used = vec![false; args.operands.len()]; - for pos in &args.reg_args { - used[*pos] = true; + for pos in args.reg_args.iter() { + used[pos] = true; } let named_pos: FxHashMap<usize, Symbol> = args.named_args.iter().map(|(&sym, &idx)| (idx, sym)).collect(); @@ -555,7 +554,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl let mut e = ecx.struct_span_err(err_sp, msg); e.span_label(err_sp, err.label + " in asm template string"); if let Some(note) = err.note { - e.note(¬e); + e.note(note); } if let Some((label, span)) = err.secondary_label { let err_sp = template_span.from_inner(InnerSpan::new(span.start, span.end)); @@ -583,7 +582,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl parse::ArgumentIs(idx) | parse::ArgumentImplicitlyIs(idx) => { if idx >= args.operands.len() || named_pos.contains_key(&idx) - || args.reg_args.contains(&idx) + || args.reg_args.contains(idx) { let msg = format!("invalid reference to argument at index {}", idx); let mut err = ecx.struct_span_err(span, &msg); @@ -602,7 +601,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl 1 => format!("there is 1 {}argument", positional), x => format!("there are {} {}arguments", x, positional), }; - err.note(&msg); + err.note(msg); if named_pos.contains_key(&idx) { err.span_label(args.operands[idx].1, "named argument"); @@ -610,7 +609,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl args.operands[idx].1, "named arguments cannot be referenced by position", ); - } else if args.reg_args.contains(&idx) { + } else if args.reg_args.contains(idx) { err.span_label( args.operands[idx].1, "explicit register argument", @@ -705,7 +704,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl let (sp, msg) = unused_operands.into_iter().next().unwrap(); let mut err = ecx.struct_span_err(sp, msg); err.span_label(sp, msg); - err.help(&format!( + err.help(format!( "if this argument is intentionally unused, \ consider using it in an asm comment: `\"/*{} */\"`", help_str @@ -720,7 +719,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl for (sp, msg) in unused_operands { err.span_label(sp, msg); } - err.help(&format!( + err.help(format!( "if these arguments are intentionally unused, \ consider using them in an asm comment: `\"/*{} */\"`", help_str diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 0de424be2f1..ab4ea9c8c20 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -61,7 +61,6 @@ pub fn expand_assert<'cx>( delim: MacDelimiter::Parenthesis, tokens, }), - prior_type_ascription: None, })), ); expr_if_not(cx, call_site_span, cond_expr, then, None) diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index bd3f148c9a7..ea830a0ce60 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -182,7 +182,6 @@ impl<'cx, 'a> Context<'cx, 'a> { delim: MacDelimiter::Parenthesis, tokens: initial.into_iter().chain(captures).collect::<TokenStream>(), }), - prior_type_ascription: None, })), ) } diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index b92964d03e9..50e88ae2eee 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -32,6 +32,10 @@ pub fn expand_concat( Ok(ast::LitKind::Bool(b)) => { accumulator.push_str(&b.to_string()); } + Ok(ast::LitKind::CStr(..)) => { + cx.span_err(e.span, "cannot concatenate a C string literal"); + has_errors = true; + } Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => { cx.emit_err(errors::ConcatBytestr { span: e.span }); has_errors = true; diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index ba639c0a9fe..5ef35af0a05 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -18,6 +18,11 @@ fn invalid_type_err( }; let snippet = cx.sess.source_map().span_to_snippet(span).ok(); match ast::LitKind::from_token_lit(token_lit) { + Ok(ast::LitKind::CStr(_, _)) => { + // FIXME(c_str_literals): should concatenation of C string literals + // include the null bytes in the end? + cx.span_err(span, "cannot concatenate C string literals"); + } Ok(ast::LitKind::Char(_)) => { let sugg = snippet.map(|snippet| ConcatBytesInvalidSuggestion::CharLit { span, snippet }); diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs index b2a21611db7..ef0db23ff2f 100644 --- a/compiler/rustc_builtin_macros/src/edition_panic.rs +++ b/compiler/rustc_builtin_macros/src/edition_panic.rs @@ -63,7 +63,6 @@ fn expand<'cx>( delim: MacDelimiter::Parenthesis, tokens: tts, }), - prior_type_ascription: None, })), ), ) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index f17df5b0a83..adc12ec84f5 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -616,14 +616,14 @@ fn report_missing_placeholders( } else { diag.span_note( sp, - &format!("format specifiers use curly braces, and {}", trn), + format!("format specifiers use curly braces, and {}", trn), ); } } else { if success { - diag.help(&format!("`{}` should be written as `{}`", sub, trn)); + diag.help(format!("`{}` should be written as `{}`", sub, trn)); } else { - diag.note(&format!("`{}` should use curly braces, and {}", sub, trn)); + diag.note(format!("`{}` should use curly braces, and {}", sub, trn)); } } } @@ -777,7 +777,7 @@ fn report_invalid_references( has_precision_star = true; e.span_label( *span, - &format!( + format!( "this precision flag adds an extra required argument at position {}, which is why there {} expected", index, if num_placeholders == 1 { diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 8f86ef44aa3..c7da61d72b3 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -1,7 +1,6 @@ //! This crate contains implementations of built-in macros and other code generating facilities //! injecting code into the crate before it is lowered to HIR. -#![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] #![feature(box_patterns)] diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 378d5f39f4a..52b5601bb11 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -194,7 +194,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { }; self.handler - .struct_span_err(attr.span, &msg) + .struct_span_err(attr.span, msg) .span_label(prev_attr.span, "previous attribute here") .emit(); @@ -219,7 +219,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { pprust::path_to_string(&attr.get_normal_item().path), ); - self.handler.span_err(attr.span, &msg); + self.handler.span_err(attr.span, msg); return; } @@ -233,7 +233,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { pprust::path_to_string(&attr.get_normal_item().path), ); - self.handler.span_err(attr.span, &msg); + self.handler.span_err(attr.span, msg); return; } diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 0b17e92efe9..b8a24f1102d 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -150,7 +150,7 @@ pub fn expand_include<'cx>( if self.p.token != token::Eof { let token = pprust::token_to_string(&self.p.token); let msg = format!("expected item, found `{}`", token); - self.p.struct_span_err(self.p.token.span, &msg).emit(); + self.p.struct_span_err(self.p.token.span, msg).emit(); } break; diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index be4ba66c082..9bc1e27b4ec 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -232,7 +232,7 @@ fn generate_test_harness( let expn_id = ext_cx.resolver.expansion_for_ast_pass( DUMMY_SP, AstPass::TestHarness, - &[sym::test, sym::rustc_attrs], + &[sym::test, sym::rustc_attrs, sym::no_coverage], None, ); let def_site = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id()); @@ -313,6 +313,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { // #[rustc_main] let main_attr = ecx.attr_word(sym::rustc_main, sp); + // #[no_coverage] + let no_coverage_attr = ecx.attr_word(sym::no_coverage, sp); // pub fn main() { ... } let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(ThinVec::new())); @@ -342,7 +344,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { let main = P(ast::Item { ident: main_id, - attrs: thin_vec![main_attr], + attrs: thin_vec![main_attr, no_coverage_attr], id: ast::DUMMY_NODE_ID, kind: main, vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None }, diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index e533afcfaa9..73a3e3353f3 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -88,10 +88,10 @@ pub(crate) fn import_function<'tcx>( let sig = get_function_sig(tcx, module.target_config().default_call_conv, inst); match module.declare_function(name, Linkage::Import, &sig) { Ok(func_id) => func_id, - Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!( + Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(format!( "attempt to declare `{name}` as function, but it was already declared as static" )), - Err(ModuleError::IncompatibleSignature(_, prev_sig, new_sig)) => tcx.sess.fatal(&format!( + Err(ModuleError::IncompatibleSignature(_, prev_sig, new_sig)) => tcx.sess.fatal(format!( "attempt to declare `{name}` with signature {new_sig:?}, \ but it was already declared with signature {prev_sig:?}" )), @@ -548,7 +548,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( if !matches!(fn_sig.abi(), Abi::C { .. }) { fx.tcx.sess.span_fatal( source_info.span, - &format!("Variadic call for non-C abi {:?}", fn_sig.abi()), + format!("Variadic call for non-C abi {:?}", fn_sig.abi()), ); } let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); @@ -560,7 +560,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME set %al to upperbound on float args once floats are supported fx.tcx.sess.span_fatal( source_info.span, - &format!("Non int ty {:?} for variadic call", ty), + format!("Non int ty {:?} for variadic call", ty), ); } AbiParam::new(ty) diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index a259a4f30b2..e9dbea1be67 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -220,13 +220,13 @@ pub(crate) fn verify_func( match cranelift_codegen::verify_function(&func, &flags) { Ok(_) => {} Err(err) => { - tcx.sess.err(&format!("{:?}", err)); + tcx.sess.err(format!("{:?}", err)); let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error( &func, Some(Box::new(writer)), err, ); - tcx.sess.fatal(&format!("cranelift verify error:\n{}", pretty_error)); + tcx.sess.fatal(format!("cranelift verify error:\n{}", pretty_error)); } } }); @@ -335,7 +335,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { fx.bcx.switch_to_block(failure); fx.bcx.ins().nop(); - match msg { + match &**msg { AssertKind::BoundsCheck { ref len, ref index } => { let len = codegen_operand(fx, len).load_scalar(fx); let index = codegen_operand(fx, index).load_scalar(fx); diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 30f4cf4473c..ccb3a0c4f27 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -361,7 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { self.instance.subst_mir_and_normalize_erasing_regions( self.tcx, ty::ParamEnv::reveal_all(), - value, + ty::EarlyBinder(value), ) } @@ -481,7 +481,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { if let layout::LayoutError::SizeOverflow(_) = err { - self.0.sess.span_fatal(span, &err.to_string()) + self.0.sess.span_fatal(span, err.to_string()) } else { span_bug!(span, "failed to get layout for `{}`: {}", ty, err) } @@ -499,7 +499,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { - self.0.sess.span_fatal(span, &err.to_string()) + self.0.sess.span_fatal(span, err.to_string()) } else { match fn_abi_request { FnAbiRequest::OfFnPtr { sig, extra_args } => { diff --git a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs index 54df04f8c2c..d2b928db7d4 100644 --- a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs +++ b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs @@ -65,7 +65,7 @@ impl ConcurrencyLimiter { // Make sure to drop the mutex guard first to prevent poisoning the mutex. drop(state); if let Some(err) = err { - handler.fatal(&err).raise(); + handler.fatal(err).raise(); } else { // The error was already emitted, but compilation continued. Raise a silent // fatal error. diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index bf5d29c16f6..77af561a587 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -308,7 +308,7 @@ fn data_id_for_static( attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL), ) { Ok(data_id) => data_id, - Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!( + Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(format!( "attempt to declare `{symbol_name}` as static, but it was already declared as function" )), Err(err) => Err::<_, _>(err).unwrap(), @@ -356,7 +356,7 @@ fn data_id_for_static( attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL), ) { Ok(data_id) => data_id, - Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!( + Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(format!( "attempt to declare `{symbol_name}` as static, but it was already declared as function" )), Err(err) => Err::<_, _>(err).unwrap(), @@ -404,7 +404,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant if let Some(names) = section_name.split_once(',') { names } else { - tcx.sess.fatal(&format!( + tcx.sess.fatal(format!( "#[link_section = \"{}\"] is not valid for macos target: must be segment and section separated by comma", section_name )); @@ -449,7 +449,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant GlobalAlloc::Static(def_id) => { if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { - tcx.sess.fatal(&format!( + tcx.sess.fatal(format!( "Allocation {:?} contains reference to TLS value {:?}", alloc_id, def_id )); diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 0e6c6ad95aa..aad9a9647f8 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -69,7 +69,7 @@ impl OngoingCodegen { let module_codegen_result = match module_codegen_result { Ok(module_codegen_result) => module_codegen_result, - Err(err) => sess.fatal(&err), + Err(err) => sess.fatal(err), }; let ModuleCodegenResult { module_regular, module_global_asm, existing_work_product } = module_codegen_result; @@ -468,7 +468,7 @@ pub(crate) fn run_aot( let obj = create_compressed_metadata_file(tcx.sess, &metadata, &symbol_name); if let Err(err) = std::fs::write(&tmp_file, obj) { - tcx.sess.fatal(&format!("error writing metadata object file: {}", err)); + tcx.sess.fatal(format!("error writing metadata object file: {}", err)); } (metadata_cgu_name, tmp_file) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs index f722e52284f..f67fdb59270 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs @@ -42,7 +42,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( _ => { fx.tcx .sess - .warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic)); + .warn(format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic)); crate::trap::trap_unimplemented(fx, intrinsic); return; } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs index b431158d269..33b2f4702a7 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs @@ -207,7 +207,7 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>( } */ _ => { - fx.tcx.sess.warn(&format!( + fx.tcx.sess.warn(format!( "unsupported AArch64 llvm intrinsic {}; replacing with trap", intrinsic )); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 0f32d1a25ff..56d8f13cec5 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -138,10 +138,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( llvm_add_sub(fx, BinOp::Sub, ret, b_in, a, b); } _ => { - fx.tcx.sess.warn(&format!( - "unsupported x86 llvm intrinsic {}; replacing with trap", - intrinsic - )); + fx.tcx + .sess + .warn(format!("unsupported x86 llvm intrinsic {}; replacing with trap", intrinsic)); crate::trap::trap_unimplemented(fx, intrinsic); return; } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 539f8c103db..0a513b08b74 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -42,7 +42,7 @@ fn report_atomic_type_validation_error<'tcx>( ) { fx.tcx.sess.span_err( span, - &format!( + format!( "`{}` intrinsic: expected basic integer or raw pointer type, found `{:?}`", intrinsic, ty ), @@ -1202,7 +1202,7 @@ fn codegen_regular_intrinsic_call<'tcx>( _ => { fx.tcx .sess - .span_fatal(source_info.span, &format!("unsupported intrinsic {}", intrinsic)); + .span_fatal(source_info.span, format!("unsupported intrinsic {}", intrinsic)); } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 264b578c168..5a038bfca5d 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -13,7 +13,7 @@ fn report_simd_type_validation_error( span: Span, ty: Ty<'_>, ) { - fx.tcx.sess.span_err(span, &format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty)); + fx.tcx.sess.span_err(span, format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty)); // Prevent verifier error fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } @@ -150,7 +150,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( _ => { fx.tcx.sess.span_err( span, - &format!( + format!( "simd_shuffle index must be an array of `u32`, got `{}`", idx_ty, ), @@ -248,7 +248,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( if idx >= lane_count.into() { fx.tcx.sess.span_fatal( fx.mir.span, - &format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count), + format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count), ); } @@ -296,7 +296,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( if idx >= lane_count.into() { fx.tcx.sess.span_fatal( fx.mir.span, - &format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count), + format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count), ); } @@ -699,7 +699,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( _ => { fx.tcx.sess.span_fatal( span, - &format!( + format!( "invalid monomorphization of `simd_bitmask` intrinsic: \ vector argument `{}`'s element type `{}`, expected integer element \ type", @@ -739,7 +739,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( _ => { fx.tcx.sess.span_fatal( span, - &format!( + format!( "invalid monomorphization of `simd_bitmask` intrinsic: \ cannot return `{}`, expected `u{}` or `[u8; {}]`", ret.layout().ty, @@ -875,7 +875,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( } _ => { - fx.tcx.sess.span_err(span, &format!("Unknown SIMD intrinsic {}", intrinsic)); + fx.tcx.sess.span_err(span, format!("Unknown SIMD intrinsic {}", intrinsic)); // Prevent verifier error fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index f0b399ae280..9966cc2ef3c 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -185,7 +185,7 @@ impl CodegenBackend for CraneliftCodegenBackend { let mut config = self.config.borrow_mut(); if config.is_none() { let new_config = BackendConfig::from_opts(&sess.opts.cg.llvm_args) - .unwrap_or_else(|err| sess.fatal(&err)); + .unwrap_or_else(|err| sess.fatal(err)); *config = Some(new_config); } } @@ -245,7 +245,7 @@ impl CodegenBackend for CraneliftCodegenBackend { fn target_triple(sess: &Session) -> target_lexicon::Triple { match sess.target.llvm_target.parse() { Ok(triple) => triple, - Err(err) => sess.fatal(&format!("target not recognized: {}", err)), + Err(err) => sess.fatal(format!("target not recognized: {}", err)), } } @@ -307,7 +307,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar Some(value) => { let mut builder = cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| { - sess.fatal(&format!("can't compile for {}: {}", target_triple, err)); + sess.fatal(format!("can't compile for {}: {}", target_triple, err)); }); if let Err(_) = builder.enable(value) { sess.fatal("the specified target cpu isn't currently supported by Cranelift."); @@ -317,7 +317,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar None => { let mut builder = cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| { - sess.fatal(&format!("can't compile for {}: {}", target_triple, err)); + sess.fatal(format!("can't compile for {}: {}", target_triple, err)); }); if target_triple.architecture == target_lexicon::Architecture::X86_64 { // Don't use "haswell" as the default, as it implies `has_lzcnt`. @@ -330,7 +330,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar match isa_builder.finish(flags) { Ok(target_isa) => target_isa, - Err(err) => sess.fatal(&format!("failed to build TargetIsa: {}", err)), + Err(err) => sess.fatal(format!("failed to build TargetIsa: {}", err)), } } diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 205411e8c27..20ba73f3852 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -75,7 +75,7 @@ pub(crate) fn maybe_create_entry_wrapper( Ok(func_id) => func_id, Err(err) => { tcx.sess - .fatal(&format!("entry symbol `{entry_name}` declared multiple times: {err}")); + .fatal(format!("entry symbol `{entry_name}` declared multiple times: {err}")); } }; @@ -171,7 +171,7 @@ pub(crate) fn maybe_create_entry_wrapper( } if let Err(err) = m.define_function(cmain_func_id, &mut ctx) { - tcx.sess.fatal(&format!("entry symbol `{entry_name}` defined multiple times: {err}")); + tcx.sess.fatal(format!("entry symbol `{entry_name}` defined multiple times: {err}")); } unwind_context.add_function(cmain_func_id, &ctx, m.isa()); diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index c964d1ac5e0..b1fda6ff213 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -344,7 +344,7 @@ impl<'tcx> CPlace<'tcx> { if layout.size.bytes() >= u64::from(u32::MAX - 16) { fx.tcx .sess - .fatal(&format!("values of type {} are too big to store on the stack", layout.ty)); + .fatal(format!("values of type {} are too big to store on the stack", layout.ty)); } let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData { diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 738cdb6f119..250aa79f8d6 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -501,7 +501,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { if options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) }; - self.call(self.type_void(), None, builtin_unreachable, &[], None); + self.call(self.type_void(), None, None, builtin_unreachable, &[], None); } // Write results to outputs. diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index a3c8142bea2..a66ddb6a09f 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -35,6 +35,7 @@ use rustc_codegen_ssa::traits::{ }; use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::layout::{FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_span::Span; @@ -455,12 +456,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } #[cfg(feature="master")] - fn invoke(&mut self, typ: Type<'gcc>, _fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> { + fn invoke(&mut self, typ: Type<'gcc>, fn_attrs: Option<&CodegenFnAttrs>, _fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> { let try_block = self.current_func().new_block("try"); let current_block = self.block.clone(); self.block = try_block; - let call = self.call(typ, None, func, args, None); // TODO(antoyo): use funclet here? + let call = self.call(typ, fn_attrs, None, func, args, None); // TODO(antoyo): use funclet here? self.block = current_block; let return_value = self.current_func() @@ -483,8 +484,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } #[cfg(not(feature="master"))] - fn invoke(&mut self, typ: Type<'gcc>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> { - let call_site = self.call(typ, None, func, args, None); + fn invoke(&mut self, typ: Type<'gcc>, fn_attrs: &CodegenFnAttrs, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> { + let call_site = self.call(typ, fn_attrs, None, func, args, None); let condition = self.context.new_rvalue_from_int(self.bool_type, 1); self.llbb().end_with_conditional(None, condition, then, catch); if let Some(_fn_abi) = fn_abi { @@ -1351,6 +1352,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn call( &mut self, _typ: Type<'gcc>, + _fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 94dc8c9e93b..60176874747 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -113,7 +113,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { _ if simple.is_some() => { // FIXME(antoyo): remove this cast when the API supports function. let func = unsafe { std::mem::transmute(simple.expect("simple")) }; - self.call(self.type_void(), None, func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None) + self.call(self.type_void(), None, None, func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None) }, sym::likely => { self.expect(args[0].immediate(), true) @@ -326,7 +326,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let masked = self.and(addr, mask); self.bitcast(masked, void_ptr_type) }, - + _ if name_str.starts_with("simd_") => { match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { Ok(llval) => llval, @@ -354,7 +354,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { fn abort(&mut self) { let func = self.context.get_builtin_function("abort"); let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; - self.call(self.type_void(), None, func, &[], None); + self.call(self.type_void(), None, None, func, &[], None); } fn assume(&mut self, value: Self::Value) { @@ -1135,7 +1135,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(bx: &'b mut Builder<'a, 'gcc, 'tcx>, try_func: RValue<'gcc>, data: RValue<'gcc>, _catch_func: RValue<'gcc>, dest: RValue<'gcc>) { if bx.sess().panic_strategy() == PanicStrategy::Abort { - bx.call(bx.type_void(), None, try_func, &[data], None); + bx.call(bx.type_void(), None, None, try_func, &[data], None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. let ret_align = bx.tcx.data_layout.i32_align.abi; @@ -1204,21 +1204,21 @@ fn codegen_gnu_try<'gcc>(bx: &mut Builder<'_, 'gcc, '_>, try_func: RValue<'gcc>, let zero = bx.cx.context.new_rvalue_zero(bx.int_type); let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]); let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); - bx.call(catch_ty, None, catch_func, &[data, ptr], None); + bx.call(catch_ty, None, None, catch_func, &[data, ptr], None); bx.ret(bx.const_i32(1)); // NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not // generate a try/catch. // FIXME(antoyo): add a check in the libgccjit API to prevent this. bx.switch_to_block(current_block); - bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None); + bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None); }); let func = unsafe { std::mem::transmute(func) }; // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bx.call(llty, None, func, &[try_func, data, catch_func], None); + let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None); let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index daa661f35c4..521b64ad34d 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -280,16 +280,4 @@ pub fn struct_fields<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout } impl<'gcc, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - fn set_type_metadata(&self, _function: RValue<'gcc>, _typeid: String) { - // Unsupported. - } - - fn typeid_metadata(&self, _typeid: String) -> RValue<'gcc> { - // Unsupported. - self.context.new_rvalue_from_int(self.int_type, 0) - } - - fn set_kcfi_type_metadata(&self, _function: RValue<'gcc>, _kcfi_typeid: u32) { - // Unsupported. - } } diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index b6d7484bcce..d77634741fb 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -24,7 +24,7 @@ codegen_llvm_error_writing_def_file = Error writing .DEF file: {$error} codegen_llvm_error_calling_dlltool = - Error calling dlltool: {$error} + Error calling dlltool '{$dlltool_path}': {$error} codegen_llvm_dlltool_fail_import_library = Dlltool could not create import library: {$stdout} @@ -82,7 +82,7 @@ codegen_llvm_prepare_thin_lto_module_with_llvm_err = failed to prepare thin LTO codegen_llvm_parse_bitcode = failed to parse bitcode for LTO module codegen_llvm_parse_bitcode_with_llvm_err = failed to parse bitcode for LTO module: {$llvm_err} -codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name}: {$message} +codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message} codegen_llvm_from_llvm_diag = {$message} codegen_llvm_write_bytecode = failed to write bytecode to {$path}: {$err} diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 98d5b3599d9..f9af103c9ad 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -443,9 +443,9 @@ pub(crate) fn inline_asm_call<'ll>( ); let call = if let Some((dest, catch, funclet)) = dest_catch_funclet { - bx.invoke(fty, None, v, inputs, dest, catch, funclet) + bx.invoke(fty, None, None, v, inputs, dest, catch, funclet) } else { - bx.call(fty, None, v, inputs, None) + bx.call(fty, None, None, v, inputs, None) }; // Store mark in a metadata node so we can map LLVM errors diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 12da21dc477..a6416e9540c 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -198,7 +198,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { "arm" => ("arm", "--32"), _ => panic!("unsupported arch {}", sess.target.arch), }; - let result = std::process::Command::new(dlltool) + let result = std::process::Command::new(&dlltool) .args([ "-d", def_file_path.to_str().unwrap(), @@ -218,9 +218,13 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { match result { Err(e) => { - sess.emit_fatal(ErrorCallingDllTool { error: e }); + sess.emit_fatal(ErrorCallingDllTool { + dlltool_path: dlltool.to_string_lossy(), + error: e, + }); } - Ok(output) if !output.status.success() => { + // dlltool returns '0' on failure, so check for error output instead. + Ok(output) if !output.stderr.is_empty() => { sess.emit_fatal(DlltoolFailImportLibrary { stdout: String::from_utf8_lossy(&output.stdout), stderr: String::from_utf8_lossy(&output.stderr), @@ -431,7 +435,7 @@ fn string_to_io_error(s: String) -> io::Error { fn find_binutils_dlltool(sess: &Session) -> OsString { assert!(sess.target.options.is_like_windows && !sess.target.options.is_like_msvc); - if let Some(dlltool_path) = &sess.opts.unstable_opts.dlltool { + if let Some(dlltool_path) = &sess.opts.cg.dlltool { return dlltool_path.clone().into_os_string(); } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 7136f750f39..ca2eab28f87 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -31,6 +31,7 @@ use rustc_span::symbol::sym; use rustc_span::InnerSpan; use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo}; +use crate::llvm::diagnostic::OptimizationDiagnosticKind; use libc::{c_char, c_int, c_uint, c_void, size_t}; use std::ffi::CString; use std::fs; @@ -363,6 +364,15 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void line: opt.line, column: opt.column, pass_name: &opt.pass_name, + kind: match opt.kind { + OptimizationDiagnosticKind::OptimizationRemark => "success", + OptimizationDiagnosticKind::OptimizationMissed + | OptimizationDiagnosticKind::OptimizationFailure => "missed", + OptimizationDiagnosticKind::OptimizationAnalysis + | OptimizationDiagnosticKind::OptimizationAnalysisFPCommute + | OptimizationDiagnosticKind::OptimizationAnalysisAliasing => "analysis", + OptimizationDiagnosticKind::OptimizationRemarkOther => "other", + }, message: &opt.message, }); } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 6819a2af09d..2fd6db8cbfe 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -15,14 +15,15 @@ use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::MemFlags; use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::def_id::DefId; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout, }; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -use rustc_symbol_mangling::typeid::kcfi_typeid_for_fnabi; +use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi, TypeIdOptions}; use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange}; -use rustc_target::spec::{HasTargetSpec, Target}; +use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target}; use std::borrow::Cow; use std::ffi::CStr; use std::iter; @@ -216,6 +217,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn invoke( &mut self, llty: &'ll Type, + fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, args: &[&'ll Value], @@ -230,19 +232,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw); let mut bundles = vec![funclet_bundle]; - // Set KCFI operand bundle - let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; - let kcfi_bundle = - if self.tcx.sess.is_sanitizer_kcfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call { - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi); - Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) - } else { - None - }; - if kcfi_bundle.is_some() { - let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw); - bundles.push(kcfi_bundle); - } + // Emit CFI pointer type membership test + self.cfi_type_test(fn_attrs, fn_abi, llfn); + + // Emit KCFI operand bundle + let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn); + let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw); + bundles.push(kcfi_bundle); bundles.retain(|bundle| bundle.is_some()); let invoke = unsafe { @@ -1183,6 +1179,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn call( &mut self, llty: &'ll Type, + fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, args: &[&'ll Value], @@ -1195,19 +1192,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw); let mut bundles = vec![funclet_bundle]; - // Set KCFI operand bundle - let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; - let kcfi_bundle = - if let Some(fn_abi) = fn_abi && self.tcx.sess.is_sanitizer_kcfi_enabled() && is_indirect_call { - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi); - Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) - } else { - None - }; - if kcfi_bundle.is_some() { - let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw); - bundles.push(kcfi_bundle); - } + // Emit CFI pointer type membership test + self.cfi_type_test(fn_attrs, fn_abi, llfn); + + // Emit KCFI operand bundle + let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn); + let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw); + bundles.push(kcfi_bundle); bundles.retain(|bundle| bundle.is_some()); let call = unsafe { @@ -1456,7 +1447,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value { let (ty, f) = self.cx.get_intrinsic(intrinsic); - self.call(ty, None, f, args, None) + self.call(ty, None, None, f, args, None) } fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) { @@ -1518,7 +1509,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width) }; let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty)); - self.call(self.type_func(&[src_ty], dest_ty), None, f, &[val], None) + self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None) } pub(crate) fn landing_pad( @@ -1535,4 +1526,71 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { llvm::LLVMBuildLandingPad(self.llbuilder, ty, None, num_clauses as c_uint, UNNAMED) } } + + // Emits CFI pointer type membership tests. + fn cfi_type_test( + &mut self, + fn_attrs: Option<&CodegenFnAttrs>, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, + llfn: &'ll Value, + ) { + let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; + if is_indirect_call && fn_abi.is_some() && self.tcx.sess.is_sanitizer_cfi_enabled() { + if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::CFI) { + return; + } + + let mut options = TypeIdOptions::empty(); + if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() { + options.insert(TypeIdOptions::GENERALIZE_POINTERS); + } + if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() { + options.insert(TypeIdOptions::NORMALIZE_INTEGERS); + } + + let typeid = typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options); + let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap(); + + // Test whether the function pointer is associated with the type identifier. + let cond = self.type_test(llfn, typeid_metadata); + let bb_pass = self.append_sibling_block("type_test.pass"); + let bb_fail = self.append_sibling_block("type_test.fail"); + self.cond_br(cond, bb_pass, bb_fail); + + self.switch_to_block(bb_fail); + self.abort(); + self.unreachable(); + + self.switch_to_block(bb_pass); + } + } + + // Emits KCFI operand bundles. + fn kcfi_operand_bundle( + &mut self, + fn_attrs: Option<&CodegenFnAttrs>, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, + llfn: &'ll Value, + ) -> Option<llvm::OperandBundleDef<'ll>> { + let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; + let kcfi_bundle = if is_indirect_call && self.tcx.sess.is_sanitizer_kcfi_enabled() { + if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::KCFI) { + return None; + } + + let mut options = TypeIdOptions::empty(); + if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() { + options.insert(TypeIdOptions::GENERALIZE_POINTERS); + } + if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() { + options.insert(TypeIdOptions::NORMALIZE_INTEGERS); + } + + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options); + Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) + } else { + None + }; + kcfi_bundle + } } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index f0d729d4779..83101a85435 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -228,18 +228,29 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1); } - if sess.is_sanitizer_cfi_enabled() { - // FIXME(rcvalle): Add support for non canonical jump tables. + // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.) + if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() { let canonical_jump_tables = "CFI Canonical Jump Tables\0".as_ptr().cast(); - // FIXME(rcvalle): Add it with Override behavior flag. llvm::LLVMRustAddModuleFlag( llmod, - llvm::LLVMModFlagBehavior::Warning, + llvm::LLVMModFlagBehavior::Override, canonical_jump_tables, 1, ); } + // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.) + if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() { + let enable_split_lto_unit = "EnableSplitLTOUnit\0".as_ptr().cast(); + llvm::LLVMRustAddModuleFlag( + llmod, + llvm::LLVMModFlagBehavior::Override, + enable_split_lto_unit, + 1, + ); + } + + // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.) if sess.is_sanitizer_kcfi_enabled() { let kcfi = "kcfi\0".as_ptr().cast(); llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 2f910c37d61..3fff112a020 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -93,7 +93,7 @@ fn make_mir_scope<'ll, 'tcx>( let callee = cx.tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - callee, + ty::EarlyBinder(callee), ); let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty()); cx.dbg_scope_fn(callee, callee_fn_abi, None) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 2e9f89f4196..c3f0a0033b0 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -322,7 +322,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let tcx = self.tcx; let def_id = instance.def_id(); - let containing_scope = get_containing_scope(self, instance); + let (containing_scope, is_method) = get_containing_scope(self, instance); let span = tcx.def_span(def_id); let loc = self.lookup_debug_loc(span.lo()); let file_metadata = file_metadata(self, &loc.file); @@ -378,8 +378,29 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - unsafe { - return llvm::LLVMRustDIBuilderCreateFunction( + // When we're adding a method to a type DIE, we only want a DW_AT_declaration there, because + // LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition. + // When we use this `decl` below, the subprogram definition gets created at the CU level + // with a DW_AT_specification pointing back to the type's declaration. + let decl = is_method.then(|| unsafe { + llvm::LLVMRustDIBuilderCreateMethod( + DIB(self), + containing_scope, + name.as_ptr().cast(), + name.len(), + linkage_name.as_ptr().cast(), + linkage_name.len(), + file_metadata, + loc.line, + function_type_metadata, + flags, + spflags & !DISPFlags::SPFlagDefinition, + template_parameters, + ) + }); + + return unsafe { + llvm::LLVMRustDIBuilderCreateFunction( DIB(self), containing_scope, name.as_ptr().cast(), @@ -394,9 +415,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { spflags, maybe_definition_llfn, template_parameters, - None, - ); - } + decl, + ) + }; fn get_function_signature<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, @@ -493,57 +514,53 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { names } + /// Returns a scope, plus `true` if that's a type scope for "class" methods, + /// otherwise `false` for plain namespace scopes. fn get_containing_scope<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, - ) -> &'ll DIScope { + ) -> (&'ll DIScope, bool) { // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. - let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| { + if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) { // If the method does *not* belong to a trait, proceed if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - cx.tcx.type_of(impl_def_id).skip_binder(), + cx.tcx.type_of(impl_def_id), ); // Only "class" methods are generally understood by LLVM, // so avoid methods on other types (e.g., `<*mut T>::null`). - match impl_self_ty.kind() { - ty::Adt(def, ..) if !def.is_box() => { - // Again, only create type information if full debuginfo is enabled - if cx.sess().opts.debuginfo == DebugInfo::Full - && !impl_self_ty.has_param() - { - Some(type_di_node(cx, impl_self_ty)) - } else { - Some(namespace::item_namespace(cx, def.did())) - } + if let ty::Adt(def, ..) = impl_self_ty.kind() && !def.is_box() { + // Again, only create type information if full debuginfo is enabled + if cx.sess().opts.debuginfo == DebugInfo::Full && !impl_self_ty.has_param() + { + return (type_di_node(cx, impl_self_ty), true); + } else { + return (namespace::item_namespace(cx, def.did()), false); } - _ => None, } } else { // For trait method impls we still use the "parallel namespace" // strategy - None } - }); + } - self_type.unwrap_or_else(|| { - namespace::item_namespace( - cx, - DefId { - krate: instance.def_id().krate, - index: cx - .tcx - .def_key(instance.def_id()) - .parent - .expect("get_containing_scope: missing parent?"), - }, - ) - }) + let scope = namespace::item_namespace( + cx, + DefId { + krate: instance.def_id().krate, + index: cx + .tcx + .def_key(instance.def_id()) + .parent + .expect("get_containing_scope: missing parent?"), + }, + ); + (scope, false) } } diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 6a575095f7e..cc2a5d158be 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -20,7 +20,7 @@ use crate::type_::Type; use crate::value::Value; use rustc_codegen_ssa::traits::TypeMembershipMethods; use rustc_middle::ty::Ty; -use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi}; +use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi, TypeIdOptions}; use smallvec::SmallVec; /// Declare a function. @@ -132,12 +132,31 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { fn_abi.apply_attrs_llfn(self, llfn); if self.tcx.sess.is_sanitizer_cfi_enabled() { - let typeid = typeid_for_fnabi(self.tcx, fn_abi); + let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::empty()); self.set_type_metadata(llfn, typeid); + let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::GENERALIZE_POINTERS); + self.add_type_metadata(llfn, typeid); + let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::NORMALIZE_INTEGERS); + self.add_type_metadata(llfn, typeid); + let typeid = typeid_for_fnabi( + self.tcx, + fn_abi, + TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS, + ); + self.add_type_metadata(llfn, typeid); } if self.tcx.sess.is_sanitizer_kcfi_enabled() { - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi); + // LLVM KCFI does not support multiple !kcfi_type attachments + let mut options = TypeIdOptions::empty(); + if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() { + options.insert(TypeIdOptions::GENERALIZE_POINTERS); + } + if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() { + options.insert(TypeIdOptions::NORMALIZE_INTEGERS); + } + + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options); self.set_kcfi_type_metadata(llfn, kcfi_typeid); } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index bae88d94293..6a9173ab450 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -67,7 +67,8 @@ pub(crate) struct ErrorWritingDEFFile { #[derive(Diagnostic)] #[diag(codegen_llvm_error_calling_dlltool)] -pub(crate) struct ErrorCallingDllTool { +pub(crate) struct ErrorCallingDllTool<'a> { + pub dlltool_path: Cow<'a, str>, pub error: std::io::Error, } @@ -195,6 +196,7 @@ pub(crate) struct FromLlvmOptimizationDiag<'a> { pub line: std::ffi::c_uint, pub column: std::ffi::c_uint, pub pass_name: &'a str, + pub kind: &'a str, pub message: &'a str, } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 012e25884ca..00d1796f210 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -110,6 +110,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.call( simple_ty, None, + None, simple_fn, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None, @@ -444,7 +445,7 @@ fn try_intrinsic<'ll>( ) { if bx.sess().panic_strategy() == PanicStrategy::Abort { let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - bx.call(try_func_ty, None, try_func, &[data], None); + bx.call(try_func_ty, None, None, try_func, &[data], None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. let ret_align = bx.tcx().data_layout.i32_align.abi; @@ -543,7 +544,7 @@ fn codegen_msvc_try<'ll>( let ptr_align = bx.tcx().data_layout.pointer_align.abi; let slot = bx.alloca(bx.type_i8p(), ptr_align); let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - bx.invoke(try_func_ty, None, try_func, &[data], normal, catchswitch, None); + bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None); bx.switch_to_block(normal); bx.ret(bx.const_i32(0)); @@ -587,7 +588,7 @@ fn codegen_msvc_try<'ll>( let funclet = bx.catch_pad(cs, &[tydesc, flags, slot]); let ptr = bx.load(bx.type_i8p(), slot, ptr_align); let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); - bx.call(catch_ty, None, catch_func, &[data, ptr], Some(&funclet)); + bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet)); bx.catch_ret(&funclet, caught); // The flag value of 64 indicates a "catch-all". @@ -595,7 +596,7 @@ fn codegen_msvc_try<'ll>( let flags = bx.const_i32(64); let null = bx.const_null(bx.type_i8p()); let funclet = bx.catch_pad(cs, &[null, flags, null]); - bx.call(catch_ty, None, catch_func, &[data, null], Some(&funclet)); + bx.call(catch_ty, None, None, catch_func, &[data, null], Some(&funclet)); bx.catch_ret(&funclet, caught); bx.switch_to_block(caught); @@ -604,7 +605,7 @@ fn codegen_msvc_try<'ll>( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None); + let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None); let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -647,7 +648,7 @@ fn codegen_gnu_try<'ll>( let data = llvm::get_param(bx.llfn(), 1); let catch_func = llvm::get_param(bx.llfn(), 2); let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None); + bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None); bx.switch_to_block(then); bx.ret(bx.const_i32(0)); @@ -665,13 +666,13 @@ fn codegen_gnu_try<'ll>( bx.add_clause(vals, tydesc); let ptr = bx.extract_value(vals, 0); let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); - bx.call(catch_ty, None, catch_func, &[data, ptr], None); + bx.call(catch_ty, None, None, catch_func, &[data, ptr], None); bx.ret(bx.const_i32(1)); }); // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None); + let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None); let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -711,7 +712,7 @@ fn codegen_emcc_try<'ll>( let data = llvm::get_param(bx.llfn(), 1); let catch_func = llvm::get_param(bx.llfn(), 2); let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None); + bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None); bx.switch_to_block(then); bx.ret(bx.const_i32(0)); @@ -750,13 +751,13 @@ fn codegen_emcc_try<'ll>( let catch_data = bx.bitcast(catch_data, bx.type_i8p()); let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); - bx.call(catch_ty, None, catch_func, &[data, catch_data], None); + bx.call(catch_ty, None, None, catch_func, &[data, catch_data], None); bx.ret(bx.const_i32(1)); }); // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None); + let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None); let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -1205,6 +1206,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let c = bx.call( fn_ty, None, + None, f, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None, @@ -1423,6 +1425,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let v = bx.call( fn_ty, None, + None, f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None, @@ -1564,6 +1567,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let v = bx.call( fn_ty, None, + None, f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None, @@ -2037,7 +2041,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let fn_ty = bx.type_func(&[vec_ty, vec_ty], vec_ty); let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); - let v = bx.call(fn_ty, None, f, &[lhs, rhs], None); + let v = bx.call(fn_ty, None, None, f, &[lhs, rhs], None); return Ok(v); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index c95148013eb..61365e6dc4b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1987,6 +1987,21 @@ extern "C" { Decl: Option<&'a DIDescriptor>, ) -> &'a DISubprogram; + pub fn LLVMRustDIBuilderCreateMethod<'a>( + Builder: &DIBuilder<'a>, + Scope: &'a DIDescriptor, + Name: *const c_char, + NameLen: size_t, + LinkageName: *const c_char, + LinkageNameLen: size_t, + File: &'a DIFile, + LineNo: c_uint, + Ty: &'a DIType, + Flags: DIFlags, + SPFlags: DISPFlags, + TParam: &'a DIArray, + ) -> &'a DISubprogram; + pub fn LLVMRustDIBuilderCreateBasicType<'a>( Builder: &DIBuilder<'a>, Name: *const c_char, @@ -2249,7 +2264,7 @@ extern "C" { pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool; - pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine); + pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine, cpu: *const c_char); pub fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t; pub fn LLVMRustGetTargetFeature( T: &TargetMachine, diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 46692fd5e8b..2fbdab9f8ce 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -329,7 +329,14 @@ pub(crate) fn print(req: PrintRequest, sess: &Session) { require_inited(); let tm = create_informational_target_machine(sess); match req { - PrintRequest::TargetCPUs => unsafe { llvm::LLVMRustPrintTargetCPUs(tm) }, + PrintRequest::TargetCPUs => { + // SAFETY generate a C compatible string from a byte slice to pass + // the target CPU name into LLVM, the lifetime of the reference is + // at least as long as the C function + let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref())) + .unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e)); + unsafe { llvm::LLVMRustPrintTargetCPUs(tm, cpu_cstring.as_ptr()) }; + } PrintRequest::TargetFeatures => print_target_features(sess, tm), _ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req), } diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index bef4647f207..d3fad5699c8 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -291,8 +291,24 @@ impl<'ll, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { } impl<'ll, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'ll, 'tcx> { + fn add_type_metadata(&self, function: &'ll Value, typeid: String) { + let typeid_metadata = self.typeid_metadata(typeid).unwrap(); + let v = [self.const_usize(0), typeid_metadata]; + unsafe { + llvm::LLVMRustGlobalAddMetadata( + function, + llvm::MD_type as c_uint, + llvm::LLVMValueAsMetadata(llvm::LLVMMDNodeInContext( + self.llcx, + v.as_ptr(), + v.len() as c_uint, + )), + ) + } + } + fn set_type_metadata(&self, function: &'ll Value, typeid: String) { - let typeid_metadata = self.typeid_metadata(typeid); + let typeid_metadata = self.typeid_metadata(typeid).unwrap(); let v = [self.const_usize(0), typeid_metadata]; unsafe { llvm::LLVMGlobalSetMetadata( @@ -307,13 +323,28 @@ impl<'ll, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - fn typeid_metadata(&self, typeid: String) -> &'ll Value { - unsafe { + fn typeid_metadata(&self, typeid: String) -> Option<&'ll Value> { + Some(unsafe { llvm::LLVMMDStringInContext( self.llcx, typeid.as_ptr() as *const c_char, typeid.len() as c_uint, ) + }) + } + + fn add_kcfi_type_metadata(&self, function: &'ll Value, kcfi_typeid: u32) { + let kcfi_type_metadata = self.const_u32(kcfi_typeid); + unsafe { + llvm::LLVMRustGlobalAddMetadata( + function, + llvm::MD_kcfi_type as c_uint, + llvm::LLVMMDNodeInContext2( + self.llcx, + &llvm::LLVMValueAsMetadata(kcfi_type_metadata), + 1, + ), + ) } } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c63e156beae..8a7809a1468 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -40,7 +40,6 @@ use regex::Regex; use tempfile::Builder as TempFileBuilder; use itertools::Itertools; -use std::borrow::Borrow; use std::cell::OnceCell; use std::collections::BTreeSet; use std::ffi::OsString; @@ -54,7 +53,7 @@ use std::{env, fmt, fs, io, mem, str}; pub fn ensure_removed(diag_handler: &Handler, path: &Path) { if let Err(e) = fs::remove_file(path) { if e.kind() != io::ErrorKind::NotFound { - diag_handler.err(&format!("failed to remove {}: {}", path.display(), e)); + diag_handler.err(format!("failed to remove {}: {}", path.display(), e)); } } } @@ -576,17 +575,17 @@ fn link_dwarf_object<'a>( impl<Relocations> ThorinSession<Relocations> { fn alloc_mmap(&self, data: Mmap) -> &Mmap { - (*self.arena_mmap.alloc(data)).borrow() + &*self.arena_mmap.alloc(data) } } impl<Relocations> thorin::Session<Relocations> for ThorinSession<Relocations> { fn alloc_data(&self, data: Vec<u8>) -> &[u8] { - (*self.arena_data.alloc(data)).borrow() + &*self.arena_data.alloc(data) } fn alloc_relocation(&self, data: Relocations) -> &Relocations { - (*self.arena_relocations.alloc(data)).borrow() + &*self.arena_relocations.alloc(data) } fn read_input(&self, path: &Path) -> std::io::Result<&[u8]> { @@ -1406,7 +1405,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { sess.emit_note(errors::StaticLibraryNativeArtifacts); // Prefix for greppability // Note: This must not be translated as tools are allowed to depend on this exact string. - sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" "))); + sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" "))); } } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 65dfc325a11..1e57f4248d2 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1631,7 +1631,7 @@ impl<'a> Linker for AixLinker<'a> { } }; if let Err(e) = res { - self.sess.fatal(&format!("failed to write export file: {}", e)); + self.sess.fatal(format!("failed to write export file: {}", e)); } self.cmd.arg(format!("-bE:{}", path.to_str().unwrap())); } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index c80347448cb..c323372bda4 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1821,9 +1821,15 @@ impl SharedEmitterMain { let source = sess .source_map() .new_source_file(FileName::inline_asm_source_code(&buffer), buffer); - let source_span = Span::with_root_ctxt(source.start_pos, source.end_pos); - let spans: Vec<_> = - spans.iter().map(|sp| source_span.from_inner(*sp)).collect(); + let spans: Vec<_> = spans + .iter() + .map(|sp| { + Span::with_root_ctxt( + source.normalized_byte_pos(sp.start as u32), + source.normalized_byte_pos(sp.end as u32), + ) + }) + .collect(); err.span_note(spans, "instantiated into assembly here"); } @@ -1833,7 +1839,7 @@ impl SharedEmitterMain { sess.abort_if_errors(); } Ok(SharedEmitterMessage::Fatal(msg)) => { - sess.fatal(&msg); + sess.fatal(msg); } Err(_) => { break; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index c5ca7936a2b..ae45ae9d802 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -494,7 +494,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (rust_main, start_ty, vec![arg_argc, arg_argv]) }; - let result = bx.call(start_ty, None, start_fn, &args, None); + let result = bx.call(start_ty, None, None, start_fn, &args, None); let cast = bx.intcast(result, cx.type_int(), true); bx.ret(cast); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 5bd42622f2c..8dae5dab429 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -301,7 +301,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if let Some(val) = attr.value_str() { if val.as_str().bytes().any(|b| b == 0) { let msg = format!("illegal null byte in link_section value: `{}`", &val); - tcx.sess.span_err(attr.span, &msg); + tcx.sess.span_err(attr.span, msg); } else { codegen_fn_attrs.link_section = Some(val); } @@ -592,15 +592,6 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> { use rustc_ast::{LitIntType, LitKind, MetaItemLit}; - if !tcx.features().raw_dylib && tcx.sess.target.arch == "x86" { - feature_err( - &tcx.sess.parse_sess, - sym::raw_dylib, - attr.span, - "`#[link_ordinal]` is unstable on x86", - ) - .emit(); - } let meta_item_list = attr.meta_item_list(); let meta_item_list = meta_item_list.as_deref(); let sole_meta_list = match meta_item_list { @@ -631,7 +622,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> { } else { let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal); tcx.sess - .struct_span_err(attr.span, &msg) + .struct_span_err(attr.span, msg) .note("the value may not exceed `u16::MAX`") .emit(); None diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 03f33d8d8aa..6297f91341d 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -94,7 +94,7 @@ fn push_debuginfo_type_name<'tcx>( // Computing the layout can still fail here, e.g. if the target architecture // cannot represent the type. See https://github.com/rust-lang/rust/issues/94961. // FIXME: migrate once `rustc_middle::mir::interpret::InterpError` is translatable. - tcx.sess.fatal(&format!("{}", e)); + tcx.sess.fatal(format!("{}", e)); } } } else { diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 26d55618b49..c3cc17c255b 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -31,7 +31,7 @@ use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_middle::ty::query::{ExternProviders, Providers}; -use rustc_serialize::opaque::{MemDecoder, MemEncoder}; +use rustc_serialize::opaque::{FileEncoder, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT}; use rustc_session::cstore::{self, CrateSource}; @@ -39,6 +39,7 @@ use rustc_session::utils::NativeLibKind; use rustc_span::symbol::Symbol; use rustc_span::DebuggerVisualizerFile; use std::collections::BTreeSet; +use std::io; use std::path::{Path, PathBuf}; pub mod back; @@ -215,8 +216,11 @@ const RLINK_MAGIC: &[u8] = b"rustlink"; const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION"); impl CodegenResults { - pub fn serialize_rlink(codegen_results: &CodegenResults) -> Vec<u8> { - let mut encoder = MemEncoder::new(); + pub fn serialize_rlink( + rlink_file: &Path, + codegen_results: &CodegenResults, + ) -> Result<usize, io::Error> { + let mut encoder = FileEncoder::new(rlink_file)?; encoder.emit_raw_bytes(RLINK_MAGIC); // `emit_raw_bytes` is used to make sure that the version representation does not depend on // Encoder's inner representation of `u32`. diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 81b49afb883..a8b935bd65c 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -28,8 +28,9 @@ impl<'a, 'tcx> VirtualIndex { if bx.cx().sess().opts.unstable_opts.virtual_function_elimination && bx.cx().sess().lto() == Lto::Fat { - let typeid = - bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty))); + let typeid = bx + .typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty))) + .unwrap(); let vtable_byte_offset = self.0 * bx.data_layout().pointer_size.bytes(); let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); bx.pointercast(func, llty) diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 0334c7ff132..569599faa36 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -203,7 +203,9 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> self.assign(local, DefLocation::Body(location)); } - PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {} + PlaceContext::NonUse(_) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) + | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {} PlaceContext::NonMutatingUse( NonMutatingUseContext::Copy | NonMutatingUseContext::Move, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index a0a8246be15..c1613a9640a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -19,7 +19,6 @@ use rustc_middle::ty::{self, Instance, Ty}; use rustc_session::config::OptLevel; use rustc_span::source_map::Span; use rustc_span::{sym, Symbol}; -use rustc_symbol_mangling::typeid::typeid_for_fnabi; use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg}; use rustc_target::abi::{self, HasDataLayout, WrappingRange}; use rustc_target::spec::abi::Abi; @@ -163,6 +162,12 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { // do an invoke, otherwise do a call. let fn_ty = bx.fn_decl_backend_type(&fn_abi); + let fn_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() { + Some(bx.tcx().codegen_fn_attrs(fx.instance.def_id())) + } else { + None + }; + if !fn_abi.can_unwind { unwind = mir::UnwindAction::Unreachable; } @@ -190,6 +195,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { }; let invokeret = bx.invoke( fn_ty, + fn_attrs, Some(&fn_abi), fn_ptr, &llargs, @@ -211,7 +217,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } MergingSucc::False } else { - let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx)); + let llret = bx.call(fn_ty, fn_attrs, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx)); if fx.mir[self.bb].is_cleanup { // Cleanup is always the cold path. Don't inline // drop glue. Also, when there is a deeply-nested @@ -1051,48 +1057,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_argument(bx, location, &mut llargs, last_arg); } - let (is_indirect_call, fn_ptr) = match (llfn, instance) { - (Some(llfn), _) => (true, llfn), - (None, Some(instance)) => (false, bx.get_fn_addr(instance)), - _ => span_bug!(span, "no llfn for call"), + let fn_ptr = match (instance, llfn) { + (Some(instance), None) => bx.get_fn_addr(instance), + (_, Some(llfn)) => llfn, + _ => span_bug!(span, "no instance or llfn for call"), }; - // For backends that support CFI using type membership (i.e., testing whether a given - // pointer is associated with a type identifier). - if bx.tcx().sess.is_sanitizer_cfi_enabled() && is_indirect_call { - // Emit type metadata and checks. - // FIXME(rcvalle): Add support for generalized identifiers. - // FIXME(rcvalle): Create distinct unnamed MDNodes for internal identifiers. - let typeid = typeid_for_fnabi(bx.tcx(), fn_abi); - let typeid_metadata = self.cx.typeid_metadata(typeid); - - // Test whether the function pointer is associated with the type identifier. - let cond = bx.type_test(fn_ptr, typeid_metadata); - let bb_pass = bx.append_sibling_block("type_test.pass"); - let bb_fail = bx.append_sibling_block("type_test.fail"); - bx.cond_br(cond, bb_pass, bb_fail); - - bx.switch_to_block(bb_pass); - let merging_succ = helper.do_call( - self, - bx, - fn_abi, - fn_ptr, - &llargs, - target.as_ref().map(|&target| (ret_dest, target)), - unwind, - &copied_constant_arguments, - false, - ); - assert_eq!(merging_succ, MergingSucc::False); - - bx.switch_to_block(bb_fail); - bx.abort(); - bx.unreachable(); - - return MergingSucc::False; - } - helper.do_call( self, bx, @@ -1640,7 +1610,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicCannotUnwind); let fn_ty = bx.fn_decl_backend_type(&fn_abi); - let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &[], funclet.as_ref()); + let llret = bx.call(fn_ty, None, Some(&fn_abi), fn_ptr, &[], funclet.as_ref()); bx.do_not_inline(llret); bx.unreachable(); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index f706ecea975..1204c99e533 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -111,7 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.instance.subst_mir_and_normalize_erasing_regions( self.cx.tcx(), ty::ParamEnv::reveal_all(), - value, + ty::EarlyBinder(value), ) } } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index b37797fef4c..9efbb34b515 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -2,6 +2,7 @@ use super::place::PlaceRef; use super::{FunctionCx, LocalRef}; use crate::base; +use crate::common::TypeKind; use crate::glue; use crate::traits::*; use crate::MemFlags; @@ -236,19 +237,47 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { }; match (&mut val, field.abi) { - (OperandValue::Immediate(llval), _) => { + ( + OperandValue::Immediate(llval), + Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. }, + ) => { // Bools in union fields needs to be truncated. *llval = bx.to_immediate(*llval, field); // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. - *llval = bx.bitcast(*llval, bx.cx().immediate_backend_type(field)); + let ty = bx.cx().immediate_backend_type(field); + if bx.type_kind(ty) == TypeKind::Pointer { + *llval = bx.pointercast(*llval, ty); + } } (OperandValue::Pair(a, b), Abi::ScalarPair(a_abi, b_abi)) => { // Bools in union fields needs to be truncated. *a = bx.to_immediate_scalar(*a, a_abi); *b = bx.to_immediate_scalar(*b, b_abi); // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. - *a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true)); - *b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true)); + let a_ty = bx.cx().scalar_pair_element_backend_type(field, 0, true); + let b_ty = bx.cx().scalar_pair_element_backend_type(field, 1, true); + if bx.type_kind(a_ty) == TypeKind::Pointer { + *a = bx.pointercast(*a, a_ty); + } + if bx.type_kind(b_ty) == TypeKind::Pointer { + *b = bx.pointercast(*b, b_ty); + } + } + // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]); + (OperandValue::Immediate(llval), Abi::Aggregate { sized: true }) => { + assert!(matches!(self.layout.abi, Abi::Vector { .. })); + + let llty = bx.cx().backend_type(self.layout); + let llfield_ty = bx.cx().backend_type(field); + + // Can't bitcast an aggregate, so round trip through memory. + let lltemp = bx.alloca(llfield_ty, field.align.abi); + let llptr = bx.pointercast(lltemp, bx.cx().type_ptr_to(llty)); + bx.store(*llval, llptr, field.align.abi); + *llval = bx.load(llfield_ty, lltemp, field.align.abi); + } + (OperandValue::Immediate(_), Abi::Uninhabited | Abi::Aggregate { sized: false }) => { + bug!() } (OperandValue::Pair(..), _) => bug!(), (OperandValue::Ref(..), _) => bug!(), diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 64452472eec..6e7065713b8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -697,7 +697,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_ptr = bx.get_fn_addr(instance); let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty()); let fn_ty = bx.fn_decl_backend_type(&fn_abi); - bx.call(fn_ty, Some(fn_abi), fn_ptr, &[], None) + let fn_attrs = if bx.tcx().def_kind(instance.def_id()).has_codegen_attrs() { + Some(bx.tcx().codegen_fn_attrs(instance.def_id())) + } else { + None + }; + bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None) } else { bx.get_static(def_id) }; diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index a936b62dd4e..1cfc4b933a8 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -370,7 +370,7 @@ pub fn from_target_feature( let Some(feature_gate) = supported_target_features.get(feature) else { let msg = format!("the feature named `{}` is not valid for this target", feature); - let mut err = tcx.sess.struct_span_err(item.span(), &msg); + let mut err = tcx.sess.struct_span_err(item.span(), msg); err.span_label( item.span(), format!("`{}` is not valid for this target", feature), @@ -408,7 +408,7 @@ pub fn from_target_feature( &tcx.sess.parse_sess, feature_gate.unwrap(), item.span(), - &format!("the target feature `{}` is currently unstable", feature), + format!("the target feature `{}` is currently unstable", feature), ) .emit(); } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 194768d9466..57de7e9620e 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -14,6 +14,7 @@ use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; use crate::MemFlags; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout}; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -72,6 +73,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn invoke( &mut self, llty: Self::Type, + fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: Self::Value, args: &[Self::Value], @@ -321,6 +323,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn call( &mut self, llty: Self::Type, + fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: Self::Value, args: &[Self::Value], diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 32905b079d3..36d9864221b 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -128,12 +128,16 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> { ) -> Self::Type; } -// For backends that support CFI using type membership (i.e., testing whether a given pointer is +// For backends that support CFI using type membership (i.e., testing whether a given pointer is // associated with a type identifier). pub trait TypeMembershipMethods<'tcx>: Backend<'tcx> { - fn set_type_metadata(&self, function: Self::Function, typeid: String); - fn typeid_metadata(&self, typeid: String) -> Self::Value; - fn set_kcfi_type_metadata(&self, function: Self::Function, typeid: u32); + fn add_type_metadata(&self, _function: Self::Function, _typeid: String) {} + fn set_type_metadata(&self, _function: Self::Function, _typeid: String) {} + fn typeid_metadata(&self, _typeid: String) -> Option<Self::Value> { + None + } + fn add_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {} + fn set_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {} } pub trait ArgAbiMethods<'tcx>: HasCodegen<'tcx> { diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 0579f781535..cdef3fb2339 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -104,13 +104,13 @@ impl<'tcx> ConstEvalErr<'tcx> { // Add spans for the stacktrace. Don't print a single-line backtrace though. if self.stacktrace.len() > 1 { // Helper closure to print duplicated lines. - let mut flush_last_line = |last_frame, times| { + let mut flush_last_line = |last_frame: Option<(String, _)>, times| { if let Some((line, span)) = last_frame { - err.span_note(span, &line); + err.span_note(span, line.clone()); // Don't print [... additional calls ...] if the number of lines is small if times < 3 { for _ in 0..times { - err.span_note(span, &line); + err.span_note(span, line.clone()); } } else { err.span_note( diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 99f180f475d..046d2052968 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -368,7 +368,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( if matches!(err.error, InterpError::UndefinedBehavior(_)) { diag.note(NOTE_ON_UNDEFINED_BEHAVIOR_ERROR); } - diag.note(&format!( + diag.note(format!( "the raw bytes of the constant ({}", display_allocation( *ecx.tcx, diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 3cdf1e6e30c..05be45fef13 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -83,7 +83,7 @@ pub(crate) fn eval_to_valtree<'tcx>( Some(span) => { tcx.sess.create_err(MaxNumNodesInConstErr { span, global_const_id }) } - None => tcx.sess.struct_err(&msg), + None => tcx.sess.struct_err(msg), }; diag.emit(); diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 4d54c01830b..b10f2e9f862 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -337,7 +337,7 @@ fn valtree_into_mplace<'tcx>( match ty.kind() { ty::FnDef(_, _) => { - ecx.write_immediate(Immediate::Uninit, &place.into()).unwrap(); + // Zero-sized type, nothing to do. } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { let scalar_int = valtree.unwrap_leaf(); diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 361ce123c78..b2197a0aabb 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -495,7 +495,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> Result<T, InterpError<'tcx>> { frame .instance - .try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value) + .try_subst_mir_and_normalize_erasing_regions( + *self.tcx, + self.param_env, + ty::EarlyBinder(value), + ) .map_err(|_| err_inval!(TooGeneric)) } diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index b220d21f68b..c2b82ba9b07 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -387,7 +387,7 @@ pub fn intern_const_alloc_recursive< Err(error) => { ecx.tcx.sess.delay_span_bug( ecx.tcx.span, - &format!( + format!( "error during interning should later cause validation failure: {}", error ), diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 5310ef0bb3e..a7f66071fe2 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -245,6 +245,12 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { pub fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { if self.layout.is_unsized() { + if matches!(self.op, Operand::Immediate(Immediate::Uninit)) { + // Uninit unsized places shouldn't occur. In the interpreter we have them + // temporarily for unsized arguments before their value is put in; in ConstProp they + // remain uninit and this code can actually be reached. + throw_inval!(UninitUnsizedLocal); + } // There are no unsized immediates. self.assert_mem_place().len(cx) } else { diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 319b80d66e1..1e60a1e72ea 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -293,7 +293,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME: This should be a span_bug (#80742) self.tcx.sess.delay_span_bug( self.frame().current_span(), - &format!("{null_op:?} MIR operator called for unsized type {ty}"), + format!("{null_op:?} MIR operator called for unsized type {ty}"), ); throw_inval!(SizeOfUnsizedType(ty)); } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index e06b634cdc3..01b77289937 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -38,16 +38,14 @@ macro_rules! throw_validation_failure { msg.push_str(", but expected "); write!(&mut msg, $($expected_fmt)*).unwrap(); )? - let path = rustc_middle::ty::print::with_no_trimmed_paths!({ - let where_ = &$where; - if !where_.is_empty() { - let mut path = String::new(); - write_path(&mut path, where_); - Some(path) - } else { - None - } - }); + let where_ = &$where; + let path = if !where_.is_empty() { + let mut path = String::new(); + write_path(&mut path, where_); + Some(path) + } else { + None + }; throw_ub!(ValidationFailure { path, msg }) }}; } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index e3d39091a74..21f3c2c8917 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -77,7 +77,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp { &ccx.tcx.sess.parse_sess, sym::const_fn_floating_point_arithmetic, span, - &format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()), + format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()), ) } } @@ -211,13 +211,13 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { err.span_note(span, "function defined here, but it is not `const`"); } FnPtr(..) => { - err.note(&format!( + err.note(format!( "function pointers need an RFC before allowed to be called in {}s", ccx.const_kind() )); } Closure(..) => { - err.note(&format!( + err.note(format!( "closures need an RFC before allowed to be called in {}s", ccx.const_kind() )); @@ -289,7 +289,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ccx.const_kind() ); - err.note(&format!("attempting to deref into `{}`", deref_target_ty)); + err.note(format!("attempting to deref into `{}`", deref_target_ty)); // Check first whether the source is accessible (issue #87060) if tcx.sess.source_map().is_span_accessible(deref_target) { @@ -310,14 +310,14 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { }), }; - err.note(&format!( + err.note(format!( "calls in {}s are limited to constant functions, \ tuple structs and tuple variants", ccx.const_kind(), )); if let Some(feature) = feature && ccx.tcx.sess.is_nightly_build() { - err.help(&format!( + err.help(format!( "add `#![feature({})]` to the crate attributes to enable", feature, )); @@ -354,7 +354,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable { err.help("const-stable functions can only call other const-stable functions"); } else if ccx.tcx.sess.is_nightly_build() { if let Some(feature) = feature { - err.help(&format!( + err.help(format!( "add `#![feature({})]` to the crate attributes to enable", feature )); @@ -637,7 +637,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref { &ccx.tcx.sess.parse_sess, sym::const_mut_refs, span, - &format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),), + format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),), ) } } @@ -724,7 +724,7 @@ pub mod ty { &ccx.tcx.sess.parse_sess, sym::const_mut_refs, span, - &format!("mutable references are not allowed in {}s", ccx.const_kind()), + format!("mutable references are not allowed in {}s", ccx.const_kind()), ) } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index bf688f2b34e..1da20579021 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -157,7 +157,7 @@ impl Qualif for NeedsNonConstDrop { cx.tcx, ObligationCause::dummy_with_span(cx.body.span), cx.param_env, - ty::Binder::dummy(cx.tcx.at(cx.body.span).mk_trait_ref(LangItem::Destruct, [ty])) + ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty]) .with_constness(ty::BoundConstness::ConstIfConst), ); diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 03ab2e568df..f46c2d00fe4 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -107,7 +107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // occurred. self.tcx.sess.diagnostic().delay_span_bug( span, - &format!( + format!( "broken MIR in {:?} ({}) at {:?}:\n{}", self.body.source.instance, self.when, @@ -1094,7 +1094,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if self.body.source_scopes.get(scope).is_none() { self.tcx.sess.diagnostic().delay_span_bug( self.body.span, - &format!( + format!( "broken MIR in {:?} ({}):\ninvalid source scope {:?}", self.body.source.instance, self.when, scope, ), diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index 6fa76981408..9995c08345c 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -64,6 +64,11 @@ impl Fingerprint { ) } + #[inline] + pub(crate) fn as_u128(self) -> u128 { + u128::from(self.1) << 64 | u128::from(self.0) + } + // Combines two hashes in an order independent way. Make sure this is what // you want. #[inline] diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 572bd4ac21c..5e13e7c8aaf 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -101,7 +101,7 @@ use parking_lot::RwLock; use smallvec::SmallVec; bitflags::bitflags! { - struct EventFilter: u32 { + struct EventFilter: u16 { const GENERIC_ACTIVITIES = 1 << 0; const QUERY_PROVIDERS = 1 << 1; const QUERY_CACHE_HITS = 1 << 2; diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs index a3d2724fcdb..71679086f16 100644 --- a/compiler/rustc_data_structures/src/svh.rs +++ b/compiler/rustc_data_structures/src/svh.rs @@ -23,18 +23,18 @@ impl Svh { Svh { hash } } - pub fn as_u64(&self) -> u64 { - self.hash.to_smaller_hash().as_u64() + pub fn as_u128(self) -> u128 { + self.hash.as_u128() } - pub fn to_string(&self) -> String { - format!("{:016x}", self.hash.to_smaller_hash()) + pub fn to_hex(self) -> String { + format!("{:032x}", self.hash.as_u128()) } } impl fmt::Display for Svh { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad(&self.to_string()) + f.pad(&self.to_hex()) } } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 5fac485de64..405f3d5b66d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -25,7 +25,7 @@ use rustc_data_structures::profiling::{ use rustc_data_structures::sync::SeqCst; use rustc_errors::registry::{InvalidErrorCode, Registry}; use rustc_errors::{ - DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl, + DiagnosticMessage, ErrorGuaranteed, Handler, PResult, SubdiagnosticMessage, TerminalUrl, }; use rustc_feature::find_gated_cfg; use rustc_fluent_macro::fluent_messages; @@ -55,7 +55,7 @@ use std::panic::{self, catch_unwind}; use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str; -use std::sync::LazyLock; +use std::sync::OnceLock; use std::time::Instant; // This import blocks the use of panicking `print` and `println` in all the code @@ -119,7 +119,7 @@ pub const EXIT_SUCCESS: i32 = 0; /// Exit status code used for compilation failures and invalid flags. pub const EXIT_FAILURE: i32 = 1; -const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/issues/new\ +pub const DEFAULT_BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/issues/new\ ?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md"; const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"]; @@ -1178,6 +1178,7 @@ fn extra_compiler_flags() -> Option<(Vec<String>, bool)> { pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorGuaranteed> { catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| { if value.is::<rustc_errors::FatalErrorMarker>() { + #[allow(deprecated)] ErrorGuaranteed::unchecked_claim_error_was_emitted() } else { panic::resume_unwind(value); @@ -1195,35 +1196,58 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 { } } -static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = - LazyLock::new(|| { - let hook = panic::take_hook(); - panic::set_hook(Box::new(|info| { - // If the error was caused by a broken pipe then this is not a bug. - // Write the error and return immediately. See #98700. - #[cfg(windows)] - if let Some(msg) = info.payload().downcast_ref::<String>() { - if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") - { - early_error_no_abort(ErrorOutputType::default(), &msg); - return; - } - }; +/// Stores the default panic hook, from before [`install_ice_hook`] was called. +static DEFAULT_HOOK: OnceLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = + OnceLock::new(); + +/// Installs a panic hook that will print the ICE message on unexpected panics. +/// +/// The hook is intended to be useable even by external tools. You can pass a custom +/// `bug_report_url`, or report arbitrary info in `extra_info`. Note that `extra_info` is called in +/// a context where *the thread is currently panicking*, so it must not panic or the process will +/// abort. +/// +/// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to +/// extra_info. +/// +/// A custom rustc driver can skip calling this to set up a custom ICE hook. +pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) { + // If the user has not explicitly overridden "RUST_BACKTRACE", then produce + // full backtraces. When a compiler ICE happens, we want to gather + // as much information as possible to present in the issue opened + // by the user. Compiler developers and other rustc users can + // opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE" + // (e.g. `RUST_BACKTRACE=1`) + if std::env::var("RUST_BACKTRACE").is_err() { + std::env::set_var("RUST_BACKTRACE", "full"); + } - // Invoke the default handler, which prints the actual panic message and optionally a backtrace - // Don't do this for delayed bugs, which already emit their own more useful backtrace. - if !info.payload().is::<rustc_errors::DelayedBugPanic>() { - (*DEFAULT_HOOK)(info); + let default_hook = DEFAULT_HOOK.get_or_init(panic::take_hook); - // Separate the output with an empty line - eprintln!(); + panic::set_hook(Box::new(move |info| { + // If the error was caused by a broken pipe then this is not a bug. + // Write the error and return immediately. See #98700. + #[cfg(windows)] + if let Some(msg) = info.payload().downcast_ref::<String>() { + if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") { + early_error_no_abort(ErrorOutputType::default(), &msg); + return; } + }; - // Print the ICE message - report_ice(info, BUG_REPORT_URL); - })); - hook - }); + // Invoke the default handler, which prints the actual panic message and optionally a backtrace + // Don't do this for delayed bugs, which already emit their own more useful backtrace. + if !info.payload().is::<rustc_errors::DelayedBugPanic>() { + (*default_hook)(info); + + // Separate the output with an empty line + eprintln!(); + } + + // Print the ICE message + report_ice(info, bug_report_url, extra_info); + })); +} /// Prints the ICE message, including query stack, but without backtrace. /// @@ -1231,7 +1255,7 @@ static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + /// /// When `install_ice_hook` is called, this function will be called as the panic /// hook. -pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { +pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) { let fallback_bundle = rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( @@ -1276,6 +1300,10 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { interface::try_print_query_stack(&handler, num_frames); + // We don't trust this callback not to panic itself, so run it at the end after we're sure we've + // printed all the relevant info. + extra_info(&handler); + #[cfg(windows)] if env::var("RUSTC_BREAK_ON_ICE").is_ok() { // Trigger a debugger if we crashed during bootstrap @@ -1283,22 +1311,6 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { } } -/// Installs a panic hook that will print the ICE message on unexpected panics. -/// -/// A custom rustc driver can skip calling this to set up a custom ICE hook. -pub fn install_ice_hook() { - // If the user has not explicitly overridden "RUST_BACKTRACE", then produce - // full backtraces. When a compiler ICE happens, we want to gather - // as much information as possible to present in the issue opened - // by the user. Compiler developers and other rustc users can - // opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE" - // (e.g. `RUST_BACKTRACE=1`) - if std::env::var("RUST_BACKTRACE").is_err() { - std::env::set_var("RUST_BACKTRACE", "full"); - } - LazyLock::force(&DEFAULT_HOOK); -} - /// This allows tools to enable rust logging without having to magically match rustc's /// tracing crate version. pub fn init_rustc_env_logger() { @@ -1369,7 +1381,7 @@ pub fn main() -> ! { init_rustc_env_logger(); signal_handler::install(); let mut callbacks = TimePassesCallbacks::default(); - install_ice_hook(); + install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ()); let exit_code = catch_with_exit_code(|| { let args = env::args_os() .enumerate() diff --git a/compiler/rustc_error_codes/src/error_codes/E0726.md b/compiler/rustc_error_codes/src/error_codes/E0726.md index e3794327f2d..a721e746ecd 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0726.md +++ b/compiler/rustc_error_codes/src/error_codes/E0726.md @@ -25,8 +25,8 @@ block_on(future); Specify desired lifetime of parameter `content` or indicate the anonymous lifetime like `content: Content<'_>`. The anonymous lifetime tells the Rust -compiler that `content` is only needed until create function is done with -it's execution. +compiler that `content` is only needed until the `create` function is done with +its execution. The `implicit elision` meaning the omission of suggested lifetime that is `pub async fn create<'a>(content: Content<'a>) {}` is not allowed here as diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml index 481c94266f2..4df5a8d48fd 100644 --- a/compiler/rustc_error_messages/Cargo.toml +++ b/compiler/rustc_error_messages/Cargo.toml @@ -17,9 +17,9 @@ rustc_span = { path = "../rustc_span" } rustc_macros = { path = "../rustc_macros" } tracing = "0.1" unic-langid = { version = "0.9.0", features = ["macros"] } -icu_list = "1.1.0" -icu_locid = "1.1.0" -icu_provider_adapters = "1.1.0" +icu_list = "1.2" +icu_locid = "1.2" +icu_provider_adapters = "1.2" [features] rustc_use_parallel_compiler = ['rustc_baked_icu_data/rustc_use_parallel_compiler'] diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 88d94c93bf5..6c3f677ab8e 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -287,11 +287,19 @@ pub enum SubdiagnosticMessage { FluentAttr(FluentId), } -/// `From` impl that enables existing diagnostic calls to functions which now take -/// `impl Into<SubdiagnosticMessage>` to continue to work as before. -impl<S: Into<String>> From<S> for SubdiagnosticMessage { - fn from(s: S) -> Self { - SubdiagnosticMessage::Str(s.into()) +impl From<String> for SubdiagnosticMessage { + fn from(s: String) -> Self { + SubdiagnosticMessage::Str(s) + } +} +impl<'a> From<&'a str> for SubdiagnosticMessage { + fn from(s: &'a str) -> Self { + SubdiagnosticMessage::Str(s.to_string()) + } +} +impl From<Cow<'static, str>> for SubdiagnosticMessage { + fn from(s: Cow<'static, str>) -> Self { + SubdiagnosticMessage::Str(s.to_string()) } } @@ -352,11 +360,19 @@ impl DiagnosticMessage { } } -/// `From` impl that enables existing diagnostic calls to functions which now take -/// `impl Into<DiagnosticMessage>` to continue to work as before. -impl<S: Into<String>> From<S> for DiagnosticMessage { - fn from(s: S) -> Self { - DiagnosticMessage::Str(s.into()) +impl From<String> for DiagnosticMessage { + fn from(s: String) -> Self { + DiagnosticMessage::Str(s) + } +} +impl<'a> From<&'a str> for DiagnosticMessage { + fn from(s: &'a str) -> Self { + DiagnosticMessage::Str(s.to_string()) + } +} +impl From<Cow<'static, str>> for DiagnosticMessage { + fn from(s: Cow<'static, str>) -> Self { + DiagnosticMessage::Str(s.to_string()) } } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 3064d2bedbe..ef528d87cb2 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -192,6 +192,7 @@ impl EmissionGuarantee for ErrorGuaranteed { became non-error ({:?}), after original `.emit()`", db.inner.diagnostic.level, ); + #[allow(deprecated)] ErrorGuaranteed::unchecked_claim_error_was_emitted() } } @@ -791,7 +792,7 @@ macro_rules! struct_span_err { ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ $session.struct_span_err_with_code( $span, - &format!($($message)*), + format!($($message)*), $crate::error_code!($code), ) }) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 2498ae2b7bc..68e57de5e08 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -601,7 +601,7 @@ impl Emitter for SilentEmitter { if d.level == Level::Fatal { let mut d = d.clone(); if let Some(ref note) = self.fatal_note { - d.note(note); + d.note(note.clone()); } self.fatal_handler.emit_diagnostic(&mut d); } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b65a636d770..fcbd9a53b48 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1069,26 +1069,29 @@ impl Handler { } pub fn has_errors(&self) -> Option<ErrorGuaranteed> { - self.inner.borrow().has_errors().then(ErrorGuaranteed::unchecked_claim_error_was_emitted) + self.inner.borrow().has_errors().then(|| { + #[allow(deprecated)] + ErrorGuaranteed::unchecked_claim_error_was_emitted() + }) } pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> { - self.inner - .borrow() - .has_errors_or_lint_errors() - .then(ErrorGuaranteed::unchecked_claim_error_was_emitted) + self.inner.borrow().has_errors_or_lint_errors().then(|| { + #[allow(deprecated)] + ErrorGuaranteed::unchecked_claim_error_was_emitted() + }) } pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> { - self.inner - .borrow() - .has_errors_or_delayed_span_bugs() - .then(ErrorGuaranteed::unchecked_claim_error_was_emitted) + self.inner.borrow().has_errors_or_delayed_span_bugs().then(|| { + #[allow(deprecated)] + ErrorGuaranteed::unchecked_claim_error_was_emitted() + }) } pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> { - self.inner - .borrow() - .is_compilation_going_to_fail() - .then(ErrorGuaranteed::unchecked_claim_error_was_emitted) + self.inner.borrow().is_compilation_going_to_fail().then(|| { + #[allow(deprecated)] + ErrorGuaranteed::unchecked_claim_error_was_emitted() + }) } pub fn print_error_count(&self, registry: &Registry) { @@ -1333,6 +1336,7 @@ impl HandlerInner { .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace)); if !self.flags.report_delayed_bugs { + #[allow(deprecated)] return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } } @@ -1411,7 +1415,10 @@ impl HandlerInner { self.bump_err_count(); } - guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); + #[allow(deprecated)] + { + guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); + } } else { self.bump_warn_count(); } @@ -1462,10 +1469,10 @@ impl HandlerInner { DiagnosticMessage::Str(warnings), )), (_, 0) => { - let _ = self.fatal(&errors); + let _ = self.fatal(errors); } (_, _) => { - let _ = self.fatal(&format!("{}; {}", &errors, &warnings)); + let _ = self.fatal(format!("{}; {}", &errors, &warnings)); } } @@ -1486,18 +1493,18 @@ impl HandlerInner { error_codes.sort(); if error_codes.len() > 1 { let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() }; - self.failure(&format!( + self.failure(format!( "Some errors have detailed explanations: {}{}", error_codes[..limit].join(", "), if error_codes.len() > 9 { "..." } else { "." } )); - self.failure(&format!( + self.failure(format!( "For more information about an error, try \ `rustc --explain {}`.", &error_codes[0] )); } else { - self.failure(&format!( + self.failure(format!( "For more information about this error, try \ `rustc --explain {}`.", &error_codes[0] @@ -1663,7 +1670,7 @@ impl HandlerInner { if bug.level != Level::DelayedBug { // NOTE(eddyb) not panicking here because we're already producing // an ICE, and the more information the merrier. - bug.note(&format!( + bug.note(format!( "`flushed_delayed` got diagnostic with level {:?}, \ instead of the expected `DelayedBug`", bug.level, @@ -1732,7 +1739,7 @@ impl DelayedDiagnostic { } fn decorate(mut self) -> Diagnostic { - self.inner.note(&format!("delayed at {}", self.note)); + self.inner.note(format!("delayed at {}", self.note)); self.inner } } @@ -1831,7 +1838,7 @@ pub fn add_elided_lifetime_in_path_suggestion( if incl_angl_brckt { format!("<{}>", anon_lts) } else { format!("{}, ", anon_lts) }; diag.span_suggestion_verbose( insertion_span.shrink_to_hi(), - &format!("indicate the anonymous lifetime{}", pluralize!(n)), + format!("indicate the anonymous lifetime{}", pluralize!(n)), suggestion, Applicability::MachineApplicable, ); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index caa2a201c75..c1cca89df8c 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -992,7 +992,6 @@ pub struct ExpansionData { pub depth: usize, pub module: Rc<ModuleData>, pub dir_ownership: DirOwnership, - pub prior_type_ascription: Option<(Span, bool)>, /// Some parent node that is close to this macro call pub lint_node_id: NodeId, pub is_trailing_mac: bool, @@ -1043,7 +1042,6 @@ impl<'a> ExtCtxt<'a> { depth: 0, module: Default::default(), dir_ownership: DirOwnership::Owned { relative: None }, - prior_type_ascription: None, lint_node_id: ast::CRATE_NODE_ID, is_trailing_mac: false, }, @@ -1148,7 +1146,7 @@ impl<'a> ExtCtxt<'a> { for (span, notes) in self.expansions.iter() { let mut db = self.sess.parse_sess.create_note(errors::TraceMacro { span: *span }); for note in notes { - db.note(note); + db.note(note.clone()); } db.emit(); } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index ec40911545f..7c78970345a 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -657,8 +657,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span) } SyntaxExtensionKind::LegacyBang(expander) => { - let prev = self.cx.current_expansion.prior_type_ascription; - self.cx.current_expansion.prior_type_ascription = mac.prior_type_ascription; let tok_result = expander.expand(self.cx, span, mac.args.tokens.clone()); let result = if let Some(result) = fragment_kind.make_from(tok_result) { result @@ -666,7 +664,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.error_wrong_fragment_kind(fragment_kind, &mac, span); fragment_kind.dummy(span) }; - self.cx.current_expansion.prior_type_ascription = prev; result } _ => unreachable!(), @@ -800,7 +797,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { &self.cx.sess.parse_sess, sym::proc_macro_hygiene, span, - &format!("custom attributes cannot be applied to {}", kind), + format!("custom attributes cannot be applied to {}", kind), ) .emit(); } diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 283e68a68b5..1c222fb4a89 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -88,6 +88,7 @@ use rustc_span::Span; use std::borrow::Cow; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::fmt::Display; +use std::rc::Rc; /// A unit within a matcher that a `MatcherPos` can refer to. Similar to (and derived from) /// `mbe::TokenTree`, but designed specifically for fast and easy traversal during matching. @@ -257,10 +258,10 @@ struct MatcherPos { /// against the relevant metavar by the black box parser. An element will be a `MatchedSeq` if /// the corresponding metavar decl is within a sequence. /// - /// It is critical to performance that this is an `Lrc`, because it gets cloned frequently when + /// It is critical to performance that this is an `Rc`, because it gets cloned frequently when /// processing sequences. Mostly for sequence-ending possibilities that must be tried but end /// up failing. - matches: Lrc<Vec<NamedMatch>>, + matches: Rc<Vec<NamedMatch>>, } // This type is used a lot. Make sure it doesn't unintentionally get bigger. @@ -272,7 +273,7 @@ impl MatcherPos { /// and both are hot enough to be always worth inlining. #[inline(always)] fn push_match(&mut self, metavar_idx: usize, seq_depth: usize, m: NamedMatch) { - let matches = Lrc::make_mut(&mut self.matches); + let matches = Rc::make_mut(&mut self.matches); match seq_depth { 0 => { // We are not within a sequence. Just append `m`. @@ -427,7 +428,7 @@ pub struct TtParser { /// Pre-allocate an empty match array, so it can be cloned cheaply for macros with many rules /// that have no metavars. - empty_matches: Lrc<Vec<NamedMatch>>, + empty_matches: Rc<Vec<NamedMatch>>, } impl TtParser { @@ -437,7 +438,7 @@ impl TtParser { cur_mps: vec![], next_mps: vec![], bb_mps: vec![], - empty_matches: Lrc::new(vec![]), + empty_matches: Rc::new(vec![]), } } @@ -507,7 +508,7 @@ impl TtParser { // Try zero matches of this sequence, by skipping over it. self.cur_mps.push(MatcherPos { idx: idx_first_after, - matches: Lrc::clone(&mp.matches), + matches: Rc::clone(&mp.matches), }); } @@ -521,7 +522,7 @@ impl TtParser { // processed next time around the loop. let ending_mp = MatcherPos { idx: mp.idx + 1, // +1 skips the Kleene op - matches: Lrc::clone(&mp.matches), + matches: Rc::clone(&mp.matches), }; self.cur_mps.push(ending_mp); @@ -537,7 +538,7 @@ impl TtParser { // will fail quietly when it is processed next time around the loop. let ending_mp = MatcherPos { idx: mp.idx + 2, // +2 skips the separator and the Kleene op - matches: Lrc::clone(&mp.matches), + matches: Rc::clone(&mp.matches), }; self.cur_mps.push(ending_mp); @@ -587,9 +588,9 @@ impl TtParser { if *token == token::Eof { Some(match eof_mps { EofMatcherPositions::One(mut eof_mp) => { - // Need to take ownership of the matches from within the `Lrc`. - Lrc::make_mut(&mut eof_mp.matches); - let matches = Lrc::try_unwrap(eof_mp.matches).unwrap().into_iter(); + // Need to take ownership of the matches from within the `Rc`. + Rc::make_mut(&mut eof_mp.matches); + let matches = Rc::try_unwrap(eof_mp.matches).unwrap().into_iter(); self.nameize(matcher, matches) } EofMatcherPositions::Multiple => { diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 3aeb2edb54c..e4c65a2049b 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -250,8 +250,7 @@ fn expand_macro<'cx>( trace_macros_note(&mut cx.expansions, sp, msg); } - let mut p = Parser::new(sess, tts, false, None); - p.last_type_ascription = cx.current_expansion.prior_type_ascription; + let p = Parser::new(sess, tts, false, None); if is_local { cx.resolver.record_macro_rule_usage(node_id, i); @@ -475,7 +474,7 @@ pub fn compile_declarative_macro( let s = parse_failure_msg(&token); let sp = token.span.substitute_dummy(def.span); - let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s); + let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, s); err.span_label(sp, msg); annotate_doc_comment(&mut err, sess.source_map(), sp); err.emit(); @@ -484,7 +483,7 @@ pub fn compile_declarative_macro( Error(sp, msg) => { sess.parse_sess .span_diagnostic - .struct_span_err(sp.substitute_dummy(def.span), &msg) + .struct_span_err(sp.substitute_dummy(def.span), msg) .emit(); return dummy_syn_ext(); } @@ -556,7 +555,7 @@ pub fn compile_declarative_macro( let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules); match transparency_error { Some(TransparencyError::UnknownTransparency(value, span)) => { - diag.span_err(span, &format!("unknown macro transparency: `{}`", value)); + diag.span_err(span, format!("unknown macro transparency: `{}`", value)); } Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => { diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes"); @@ -1165,7 +1164,7 @@ fn check_matcher_core<'tt>( let sp = next_token.span(); let mut err = sess.span_diagnostic.struct_span_err( sp, - &format!( + format!( "`${name}:{frag}` {may_be} followed by `{next}`, which \ is not allowed for `{frag}` fragments", name = name, @@ -1197,13 +1196,13 @@ fn check_matcher_core<'tt>( match possible { &[] => {} &[t] => { - err.note(&format!( + err.note(format!( "only {} is allowed after `{}` fragments", t, kind, )); } ts => { - err.note(&format!( + err.note(format!( "{}{} or {}", msg, ts[..ts.len() - 1].to_vec().join(", "), diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index fb3a00d86d4..6e919615019 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -78,7 +78,7 @@ fn check_trailing_token<'sess>( if let Some(tt) = iter.next() { let mut diag = sess .span_diagnostic - .struct_span_err(tt.span(), &format!("unexpected token: {}", pprust::tt_to_string(tt))); + .struct_span_err(tt.span(), format!("unexpected token: {}", pprust::tt_to_string(tt))); diag.span_note(tt.span(), "meta-variable expression must not have trailing tokens"); Err(diag) } else { @@ -137,11 +137,11 @@ fn parse_ident<'sess>( let token_str = pprust::token_to_string(token); let mut err = sess.span_diagnostic.struct_span_err( span, - &format!("expected identifier, found `{}`", &token_str) + format!("expected identifier, found `{}`", &token_str) ); err.span_suggestion( token.span, - &format!("try removing `{}`", &token_str), + format!("try removing `{}`", &token_str), "", Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index bc298b0ad2b..b2bdf9c7e6d 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -85,7 +85,7 @@ pub(super) fn parse( frag.name ); sess.span_diagnostic - .struct_span_err(span, &msg) + .struct_span_err(span, msg) .help(VALID_FRAGMENT_NAMES_MSG) .emit(); token::NonterminalKind::Ident @@ -195,7 +195,7 @@ fn parse_tree( _ => { let tok = pprust::token_kind_to_string(&token::OpenDelim(delim)); let msg = format!("expected `(` or `{{`, found `{}`", tok); - sess.span_diagnostic.span_err(delim_span.entire(), &msg); + sess.span_diagnostic.span_err(delim_span.entire(), msg); } } } @@ -246,7 +246,7 @@ fn parse_tree( "expected identifier, found `{}`", pprust::token_to_string(&token), ); - sess.span_diagnostic.span_err(token.span, &msg); + sess.span_diagnostic.span_err(token.span, msg); TokenTree::MetaVar(token.span, Ident::empty()) } @@ -358,7 +358,7 @@ fn parse_sep_and_kleene_op( // For example, `macro_rules! foo { ( ${length()} ) => {} }` fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &ParseSess, token: &Token) { sess.span_diagnostic - .span_err(token.span, &format!("unexpected token: {}", pprust::token_to_string(token))); + .span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token))); sess.span_diagnostic.span_note_without_error( token.span, "`$$` and meta-variable expressions are not allowed inside macro parameter definitions", diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 03bb5c1dfe4..e9af688ee2b 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -21,7 +21,6 @@ pub fn placeholder( delim: ast::MacDelimiter::Parenthesis, tokens: ast::tokenstream::TokenStream::new(Vec::new()), }), - prior_type_ascription: None, }) } diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 26bc216f678..41b24407fa0 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -95,7 +95,7 @@ impl base::AttrProcMacro for AttrProcMacro { |e| { let mut err = ecx.struct_span_err(span, "custom attribute panicked"); if let Some(s) = e.as_str() { - err.help(&format!("message: {}", s)); + err.help(format!("message: {}", s)); } err.emit() }, @@ -148,7 +148,7 @@ impl MultiItemModifier for DeriveProcMacro { Err(e) => { let mut err = ecx.struct_span_err(span, "proc-macro derive panicked"); if let Some(s) = e.as_str() { - err.help(&format!("message: {}", s)); + err.help(format!("message: {}", s)); } err.emit(); return ExpandResult::Ready(vec![]); diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 1e7d07bc22d..891e84a2f30 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -61,6 +61,8 @@ impl FromInternal<token::LitKind> for LitKind { token::StrRaw(n) => LitKind::StrRaw(n), token::ByteStr => LitKind::ByteStr, token::ByteStrRaw(n) => LitKind::ByteStrRaw(n), + token::CStr => LitKind::CStr, + token::CStrRaw(n) => LitKind::CStrRaw(n), token::Err => LitKind::Err, token::Bool => unreachable!(), } @@ -78,6 +80,8 @@ impl ToInternal<token::LitKind> for LitKind { LitKind::StrRaw(n) => token::StrRaw(n), LitKind::ByteStr => token::ByteStr, LitKind::ByteStrRaw(n) => token::ByteStrRaw(n), + LitKind::CStr => token::CStr, + LitKind::CStrRaw(n) => token::CStrRaw(n), LitKind::Err => token::Err, } } @@ -436,6 +440,8 @@ impl server::FreeFunctions for Rustc<'_, '_> { | token::LitKind::StrRaw(_) | token::LitKind::ByteStr | token::LitKind::ByteStrRaw(_) + | token::LitKind::CStr + | token::LitKind::CStrRaw(_) | token::LitKind::Err => return Err(()), token::LitKind::Integer | token::LitKind::Float => {} } diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 3b9fc5e9a51..5b2e4d15dfe 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -130,6 +130,8 @@ declare_features! ( (accepted, copy_closures, "1.26.0", Some(44490), None), /// Allows `crate` in paths. (accepted, crate_in_paths, "1.30.0", Some(45477), None), + /// Allows using `#[debugger_visualizer]` attribute. + (accepted, debugger_visualizer, "CURRENT_RUSTC_VERSION", Some(95939), None), /// Allows rustc to inject a default alloc_error_handler (accepted, default_alloc_error_handler, "1.68.0", Some(66741), None), /// Allows using assigning a default type to type parameters in algebraic data type definitions. @@ -278,6 +280,8 @@ declare_features! ( (accepted, pub_restricted, "1.18.0", Some(32409), None), /// Allows use of the postfix `?` operator in expressions. (accepted, question_mark, "1.13.0", Some(31436), None), + /// Allows the use of raw-dylibs (RFC 2627). + (accepted, raw_dylib, "CURRENT_RUSTC_VERSION", Some(58713), None), /// Allows keywords to be escaped for use as identifiers. (accepted, raw_identifiers, "1.30.0", Some(48589), None), /// Allows relaxing the coherence rules such that diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 052d312d9a0..27d30c315af 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -164,6 +164,8 @@ declare_features! ( (active, link_cfg, "1.14.0", None, None), /// Allows the `multiple_supertrait_upcastable` lint. (active, multiple_supertrait_upcastable, "1.69.0", None, None), + /// Allow negative trait bounds. This is an internal-only feature for testing the trait solver! + (incomplete, negative_bounds, "CURRENT_RUSTC_VERSION", None, None), /// Allows using `#[omit_gdb_pretty_printer_section]`. (active, omit_gdb_pretty_printer_section, "1.5.0", None, None), /// Allows using `#[prelude_import]` on glob `use` items. @@ -310,8 +312,10 @@ declare_features! ( /// Allows `async || body` closures. (active, async_closure, "1.37.0", Some(62290), None), /// Allows async functions to be declared, implemented, and used in traits. - (incomplete, async_fn_in_trait, "1.66.0", Some(91611), None), - /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries. + (active, async_fn_in_trait, "1.66.0", Some(91611), None), + /// Allows `c"foo"` literals. + (active, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None), + /// Treat `extern "C"` function as nounwind. (active, c_unwind, "1.52.0", Some(74990), None), /// Allows using C-variadics. (active, c_variadic, "1.34.0", Some(44930), None), @@ -329,6 +333,8 @@ declare_features! ( (active, cfg_target_thread_local, "1.7.0", Some(29594), None), /// Allow conditional compilation depending on rust version (active, cfg_version, "1.45.0", Some(64796), None), + /// Allows to use the `#[cfi_encoding = ""]` attribute. + (active, cfi_encoding, "1.69.0", Some(89653), None), /// Allows `for<...>` on closures and generators. (active, closure_lifetime_binder, "1.64.0", Some(97362), None), /// Allows `#[track_caller]` on closures and generators. @@ -363,8 +369,6 @@ declare_features! ( (active, custom_inner_attributes, "1.30.0", Some(54726), None), /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. (active, custom_test_frameworks, "1.30.0", Some(50297), None), - /// Allows using `#[debugger_visualizer]`. - (active, debugger_visualizer, "1.62.0", Some(95939), None), /// Allows declarative macros 2.0 (`macro`). (active, decl_macro, "1.17.0", Some(39412), None), /// Allows default type parameters to influence type inference. @@ -485,8 +489,6 @@ declare_features! ( (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), /// Allows macro attributes on expressions, statements and non-inline modules. (active, proc_macro_hygiene, "1.30.0", Some(54727), None), - /// Allows the use of raw-dylibs (RFC 2627). - (active, raw_dylib, "1.65.0", Some(58713), None), /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. (active, raw_ref_op, "1.41.0", Some(64490), None), /// Allows using the `#[register_tool]` attribute. @@ -496,7 +498,7 @@ declare_features! ( /// Allows `repr(simd)` and importing the various simd intrinsics. (active, repr_simd, "1.4.0", Some(27731), None), /// Allows return-position `impl Trait` in traits. - (incomplete, return_position_impl_trait_in_trait, "1.65.0", Some(91611), None), + (active, return_position_impl_trait_in_trait, "1.65.0", Some(91611), None), /// Allows bounding the return type of AFIT/RPITIT. (incomplete, return_type_notation, "1.70.0", Some(109417), None), /// Allows `extern "rust-cold"`. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index c77292fdd16..fe05d4590e7 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -403,16 +403,16 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string"), DuplicatesOk ), + // Debugging + ungated!( + debugger_visualizer, Normal, + template!(List: r#"natvis_file = "...", gdb_script_file = "...""#), DuplicatesOk + ), + // ========================================================================== // Unstable attributes: // ========================================================================== - // RFC #3191: #[debugger_visualizer] support - gated!( - debugger_visualizer, Normal, template!(List: r#"natvis_file = "...", gdb_script_file = "...""#), - DuplicatesOk, experimental!(debugger_visualizer) - ), - // Linking: gated!( naked, Normal, template!(Word), WarnFollowing, @only_local: true, @@ -494,6 +494,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // RFC 2397 gated!(do_not_recommend, Normal, template!(Word), WarnFollowing, experimental!(do_not_recommend)), + // `#[cfi_encoding = ""]` + gated!( + cfi_encoding, Normal, template!(NameValueStr: "encoding"), ErrorPreceding, + experimental!(cfi_encoding) + ), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e220a029339..38cd5865cc3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -435,6 +435,7 @@ pub enum GenericArgsParentheses { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum TraitBoundModifier { None, + Negative, Maybe, MaybeConst, } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 8f91a96f964..1f08befb180 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -226,6 +226,7 @@ language_item_table! { PartialEq, sym::eq, eq_trait, Target::Trait, GenericRequirement::Exact(1); PartialOrd, sym::partial_ord, partial_ord_trait, Target::Trait, GenericRequirement::Exact(1); + CVoid, sym::c_void, c_void, Target::Enum, GenericRequirement::None; // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays. @@ -293,6 +294,8 @@ language_item_table! { PointerLike, sym::pointer_like, pointer_like, Target::Trait, GenericRequirement::Exact(0); + ConstParamTy, sym::const_param_ty, const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0); + Poll, sym::Poll, poll, Target::Enum, GenericRequirement::None; PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None; PollPending, sym::Pending, poll_pending_variant, Target::Variant, GenericRequirement::None; @@ -330,6 +333,7 @@ language_item_table! { RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None; String, sym::String, string, Target::Struct, GenericRequirement::None; + CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None; } pub enum GenericRequirement { diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 5d45d09797b..3b42b0fe246 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -35,6 +35,10 @@ hir_analysis_field_already_declared = hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` +hir_analysis_const_param_ty_impl_on_non_adt = + the trait `ConstParamTy` may not be implemented for this type + .label = type is not a structure or enumeration + hir_analysis_ambiguous_lifetime_bound = ambiguous lifetime bound, explicit lifetime bound required @@ -188,7 +192,11 @@ hir_analysis_return_type_notation_equality_bound = return type notation is not allowed to use type equality hir_analysis_return_type_notation_missing_method = - cannot find associated function `{$assoc_name}` in trait `{$trait_name}` + cannot find associated function `{$assoc_name}` for `{$ty_name}` + +hir_analysis_return_type_notation_conflicting_bound = + ambiguous associated function `{$assoc_name}` for `{$ty_name}` + .note = `{$assoc_name}` is declared in two supertraits: `{$first_bound}` and `{$second_bound}` hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind} .label = not allowed in type signatures @@ -276,3 +284,7 @@ hir_analysis_const_specialize = cannot specialize on const impl with non-const i hir_analysis_static_specialize = cannot specialize on `'static` lifetime hir_analysis_missing_tilde_const = missing `~const` qualifier for specialization + +hir_analysis_drop_impl_negative = negative `Drop` impls are not supported + +hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index 113c3f08ab9..7b922f5d525 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -243,13 +243,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let note = format!("{title} is defined in an impl for the type `{impl_ty}`"); if let Some(span) = note_span { - err.span_note(span, ¬e); + err.span_note(span, note); } else { - err.note(¬e); + err.note(note); } } if candidates.len() > limit { - err.note(&format!("and {} others", candidates.len() - limit)); + err.note(format!("and {} others", candidates.len() - limit)); } } @@ -303,7 +303,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "associated type `{name}` not found for `{self_ty}` in the current scope" ); err.span_label(name.span, format!("associated item not found in `{self_ty}`")); - err.note(&format!( + err.note(format!( "the associated type was found for\n{type_candidates}{additional_types}", )); add_def_label(&mut err); @@ -390,10 +390,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut err = tcx.sess.struct_span_err( name.span, - &format!("the associated type `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied") + format!("the associated type `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied") ); if !bounds.is_empty() { - err.note(&format!( + err.note(format!( "the following trait bounds were not satisfied:\n{}", bounds.join("\n") )); @@ -409,7 +409,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if !tcx.sess.source_map().is_span_accessible(span) { continue; } - err.span_label(span, &msg); + err.span_label(span, msg); } add_def_label(&mut err); err.emit() @@ -589,7 +589,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } if !suggestions.is_empty() { err.multipart_suggestion( - &format!("specify the associated type{}", pluralize!(types_count)), + format!("specify the associated type{}", pluralize!(types_count)), suggestions, Applicability::HasPlaceholders, ); diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index 3b5c67de239..ed011b9086a 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -112,7 +112,7 @@ fn generic_arg_mismatch_err( if let rustc_hir::ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) = body.value.kind { if let Res::Def(DefKind::Fn { .. }, id) = path.res { - err.help(&format!("`{}` is a function item, not a type", tcx.item_name(id))); + err.help(format!("`{}` is a function item, not a type", tcx.item_name(id))); err.help("function item types cannot be named directly"); } } @@ -130,7 +130,7 @@ fn generic_arg_mismatch_err( } else { (arg.descr(), param.kind.descr()) }; - err.note(&format!("{} arguments must be provided before {} arguments", first, last)); + err.note(format!("{} arguments must be provided before {} arguments", first, last)); if let Some(help) = help { err.help(help); } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 709dea43d84..5ee0cf94360 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -56,6 +56,9 @@ use std::slice; #[derive(Debug)] pub struct PathSeg(pub DefId, pub usize); +#[derive(Copy, Clone, Debug)] +pub struct OnlySelfBounds(pub bool); + pub trait AstConv<'tcx> { fn tcx(&self) -> TyCtxt<'tcx>; @@ -662,6 +665,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span: Span, binding_span: Option<Span>, constness: ty::BoundConstness, + polarity: ty::ImplPolarity, bounds: &mut Bounds<'tcx>, speculative: bool, trait_ref_span: Span, @@ -670,6 +674,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { args: &GenericArgs<'_>, infer_args: bool, self_ty: Ty<'tcx>, + only_self_bounds: OnlySelfBounds, ) -> GenericArgCountResult { let (substs, arg_count) = self.create_substs_for_ast_path( trait_ref_span, @@ -689,13 +694,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let assoc_bindings = self.create_assoc_bindings_for_generic_args(args); let poly_trait_ref = - ty::Binder::bind_with_vars(tcx.mk_trait_ref(trait_def_id, substs), bound_vars); + ty::Binder::bind_with_vars(ty::TraitRef::new(tcx, trait_def_id, substs), bound_vars); debug!(?poly_trait_ref, ?assoc_bindings); - bounds.push_trait_bound(tcx, poly_trait_ref, span, constness); + bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity); let mut dup_bindings = FxHashMap::default(); for binding in &assoc_bindings { + // Don't register additional associated type bounds for negative bounds, + // since we should have emitten an error for them earlier, and they will + // not be well-formed! + if polarity == ty::ImplPolarity::Negative { + self.tcx() + .sess + .delay_span_bug(binding.span, "negative trait bounds should not have bindings"); + continue; + } + // Specify type to assert that error was already reported in `Err` case. let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding( hir_id, @@ -706,6 +721,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &mut dup_bindings, binding_span.unwrap_or(binding.span), constness, + only_self_bounds, + polarity, ); // Okay to ignore `Err` because of `ErrorGuaranteed` (see above). } @@ -738,9 +755,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_ref: &hir::TraitRef<'_>, span: Span, constness: ty::BoundConstness, + polarity: ty::ImplPolarity, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, speculative: bool, + only_self_bounds: OnlySelfBounds, ) -> GenericArgCountResult { let hir_id = trait_ref.hir_ref_id; let binding_span = None; @@ -758,6 +777,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, binding_span, constness, + polarity, bounds, speculative, trait_ref_span, @@ -766,6 +786,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { args, infer_args, self_ty, + only_self_bounds, ) } @@ -777,6 +798,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { args: &GenericArgs<'_>, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, + only_self_bounds: OnlySelfBounds, ) { let binding_span = Some(span); let constness = ty::BoundConstness::NotConst; @@ -791,6 +813,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, binding_span, constness, + ty::ImplPolarity::Positive, bounds, speculative, trait_ref_span, @@ -799,6 +822,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { args, infer_args, self_ty, + only_self_bounds, ); } @@ -822,7 +846,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(b) = trait_segment.args().bindings.first() { prohibit_assoc_ty_binding(self.tcx(), b.span, Some((trait_segment, span))); } - self.tcx().mk_trait_ref(trait_def_id, substs) + ty::TraitRef::new(self.tcx(), trait_def_id, substs) } #[instrument(level = "debug", skip(self, span))] @@ -947,28 +971,43 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ast_bounds: I, bounds: &mut Bounds<'tcx>, bound_vars: &'tcx ty::List<ty::BoundVariableKind>, + only_self_bounds: OnlySelfBounds, ) { for ast_bound in ast_bounds { match ast_bound { hir::GenericBound::Trait(poly_trait_ref, modifier) => { - let constness = match modifier { - hir::TraitBoundModifier::MaybeConst => ty::BoundConstness::ConstIfConst, - hir::TraitBoundModifier::None => ty::BoundConstness::NotConst, + let (constness, polarity) = match modifier { + hir::TraitBoundModifier::MaybeConst => { + (ty::BoundConstness::ConstIfConst, ty::ImplPolarity::Positive) + } + hir::TraitBoundModifier::None => { + (ty::BoundConstness::NotConst, ty::ImplPolarity::Positive) + } + hir::TraitBoundModifier::Negative => { + (ty::BoundConstness::NotConst, ty::ImplPolarity::Negative) + } hir::TraitBoundModifier::Maybe => continue, }; - let _ = self.instantiate_poly_trait_ref( &poly_trait_ref.trait_ref, poly_trait_ref.span, constness, + polarity, param_ty, bounds, false, + only_self_bounds, ); } &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => { self.instantiate_lang_item_trait_ref( - lang_item, span, hir_id, args, param_ty, bounds, + lang_item, + span, + hir_id, + args, + param_ty, + bounds, + only_self_bounds, ); } hir::GenericBound::Outlives(lifetime) => { @@ -1006,13 +1045,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, param_ty: Ty<'tcx>, ast_bounds: &[hir::GenericBound<'_>], + only_self_bounds: OnlySelfBounds, ) -> Bounds<'tcx> { - self.compute_bounds_inner(param_ty, ast_bounds) + let mut bounds = Bounds::default(); + self.add_bounds( + param_ty, + ast_bounds.iter(), + &mut bounds, + ty::List::empty(), + only_self_bounds, + ); + debug!(?bounds); + + bounds } /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type /// named `assoc_name` into ty::Bounds. Ignore the rest. - pub(crate) fn compute_bounds_that_match_assoc_type( + pub(crate) fn compute_bounds_that_match_assoc_item( &self, param_ty: Ty<'tcx>, ast_bounds: &[hir::GenericBound<'_>], @@ -1023,23 +1073,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { for ast_bound in ast_bounds { if let Some(trait_ref) = ast_bound.trait_ref() && let Some(trait_did) = trait_ref.trait_def_id() - && self.tcx().trait_may_define_assoc_type(trait_did, assoc_name) + && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name) { result.push(ast_bound.clone()); } } - self.compute_bounds_inner(param_ty, &result) - } - - fn compute_bounds_inner( - &self, - param_ty: Ty<'tcx>, - ast_bounds: &[hir::GenericBound<'_>], - ) -> Bounds<'tcx> { let mut bounds = Bounds::default(); - - self.add_bounds(param_ty, ast_bounds.iter(), &mut bounds, ty::List::empty()); + self.add_bounds( + param_ty, + result.iter(), + &mut bounds, + ty::List::empty(), + OnlySelfBounds(true), + ); debug!(?bounds); bounds @@ -1062,6 +1109,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { dup_bindings: &mut FxHashMap<DefId, Span>, path_span: Span, constness: ty::BoundConstness, + only_self_bounds: OnlySelfBounds, + polarity: ty::ImplPolarity, ) -> Result<(), ErrorGuaranteed> { // Given something like `U: SomeTrait<T = X>`, we want to produce a // predicate like `<U as SomeTrait>::T = X`. This is somewhat @@ -1092,11 +1141,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) { trait_ref } else { - return Err(tcx.sess.emit_err(crate::errors::ReturnTypeNotationMissingMethod { - span: binding.span, - trait_name: tcx.item_name(trait_ref.def_id()), - assoc_name: binding.item_name.name, - })); + self.one_bound_for_assoc_method( + traits::supertraits(tcx, trait_ref), + trait_ref.print_only_trait_path(), + binding.item_name, + path_span, + )? } } else if self.trait_defines_associated_item_named( trait_ref.def_id(), @@ -1142,9 +1192,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.sess .struct_span_err( binding.span, - &format!("{} `{}` is private", assoc_item.kind, binding.item_name), + format!("{} `{}` is private", assoc_item.kind, binding.item_name), ) - .span_label(binding.span, &format!("private {}", assoc_item.kind)) + .span_label(binding.span, format!("private {}", assoc_item.kind)) .emit(); } tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None); @@ -1316,11 +1366,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let expected = tcx.def_descr(assoc_item_def_id); let mut err = tcx.sess.struct_span_err( binding.span, - &format!("expected {expected} bound, found {got}"), + format!("expected {expected} bound, found {got}"), ); err.span_note( tcx.def_span(assoc_item_def_id), - &format!("{expected} defined here"), + format!("{expected} defined here"), ); if let hir::def::DefKind::AssocConst = def_kind @@ -1361,8 +1411,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty` // parameter to have a skipped binder. - let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder()); - self.add_bounds(param_ty, ast_bounds.iter(), bounds, projection_ty.bound_vars()); + // + // NOTE: If `only_self_bounds` is true, do NOT expand this associated + // type bound into a trait predicate, since we only want to add predicates + // for the `Self` type. + if !only_self_bounds.0 { + let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder()); + self.add_bounds( + param_ty, + ast_bounds.iter(), + bounds, + projection_ty.bound_vars(), + only_self_bounds, + ); + } } } Ok(()) @@ -1400,9 +1462,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &trait_bound.trait_ref, trait_bound.span, ty::BoundConstness::NotConst, + ty::ImplPolarity::Positive, dummy_self, &mut bounds, false, + // FIXME: This should be `true`, but we don't really handle + // associated type bounds or type aliases in objects in a way + // that makes this meaningful, I think. + OnlySelfBounds(false), ) { potential_assoc_types.extend(cur_potential_assoc_types); } @@ -1466,7 +1533,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "additional use", ); first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use"); - err.help(&format!( + err.help(format!( "consider creating a new trait with all of these as supertraits and using that \ trait here instead: `trait NewTrait: {} {{}}`", regular_traits @@ -1776,7 +1843,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ([], []) => { err.span_suggestion_verbose( span, - &format!( + format!( "if there were a type named `Type` that implements a trait named \ `Trait` with associated type `{name}`, you could use the \ fully-qualified path", @@ -1788,7 +1855,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ([], [trait_str]) => { err.span_suggestion_verbose( span, - &format!( + format!( "if there were a type named `Example` that implemented `{trait_str}`, \ you could use the fully-qualified path", ), @@ -1799,7 +1866,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ([], traits) => { err.span_suggestions( span, - &format!( + format!( "if there were a type named `Example` that implemented one of the \ traits with associated type `{name}`, you could use the \ fully-qualified path", @@ -1814,7 +1881,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ([type_str], []) => { err.span_suggestion_verbose( span, - &format!( + format!( "if there were a trait named `Example` with associated type `{name}` \ implemented for `{type_str}`, you could use the fully-qualified path", ), @@ -1825,7 +1892,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (types, []) => { err.span_suggestions( span, - &format!( + format!( "if there were a trait named `Example` with associated type `{name}` \ implemented for one of the types, you could use the fully-qualified \ path", @@ -1880,7 +1947,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let param_name = tcx.hir().ty_param_name(ty_param_def_id); self.one_bound_for_assoc_type( || { - traits::transitive_bounds_that_define_assoc_type( + traits::transitive_bounds_that_define_assoc_item( tcx, predicates.iter().filter_map(|(p, _)| { Some(p.to_opt_poly_trait_pred()?.map_bound(|t| t.trait_ref)) @@ -1991,7 +2058,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); } } else { - err.note(&format!( + err.note(format!( "associated type `{}` could derive from `{}`", ty_param_name, bound.print_only_trait_path(), @@ -1999,7 +2066,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } if !where_bounds.is_empty() { - err.help(&format!( + err.help(format!( "consider introducing a new type parameter `T` and adding `where` constraints:\ \n where\n T: {},\n{}", ty_param_name, @@ -2015,6 +2082,46 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Ok(bound) } + #[instrument(level = "debug", skip(self, all_candidates, ty_name), ret)] + fn one_bound_for_assoc_method( + &self, + all_candidates: impl Iterator<Item = ty::PolyTraitRef<'tcx>>, + ty_name: impl Display, + assoc_name: Ident, + span: Span, + ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> { + let mut matching_candidates = all_candidates.filter(|r| { + self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Fn, assoc_name) + }); + + let candidate = match matching_candidates.next() { + Some(candidate) => candidate, + None => { + return Err(self.tcx().sess.emit_err( + crate::errors::ReturnTypeNotationMissingMethod { + span, + ty_name: ty_name.to_string(), + assoc_name: assoc_name.name, + }, + )); + } + }; + + if let Some(conflicting_candidate) = matching_candidates.next() { + return Err(self.tcx().sess.emit_err( + crate::errors::ReturnTypeNotationConflictingBound { + span, + ty_name: ty_name.to_string(), + assoc_name: assoc_name.name, + first_bound: candidate.print_only_trait_path(), + second_bound: conflicting_candidate.print_only_trait_path(), + }, + )); + } + + Ok(candidate) + } + // Create a type from a path to an associated type or to an enum variant. // For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C` // and item_segment is the path segment for `D`. We return a type and a def for @@ -2067,14 +2174,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // work for the `enum`, instead of just looking if it takes *any*. err.span_suggestion_verbose( args_span, - &format!("{type_name} doesn't have generic parameters"), + format!("{type_name} doesn't have generic parameters"), "", Applicability::MachineApplicable, ); return; } let Ok(snippet) = tcx.sess.source_map().span_to_snippet(args_span) else { - err.note(&msg); + err.note(msg); return; }; let (qself_sugg_span, is_self) = if let hir::TyKind::Path( @@ -2108,12 +2215,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { kw::SelfUpper == segment.ident.name, ), _ => { - err.note(&msg); + err.note(msg); return; } } } else { - err.note(&msg); + err.note(msg); return; }; let suggestion = vec![ @@ -2128,7 +2235,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (args_span, String::new()), ]; err.multipart_suggestion_verbose( - &msg, + msg, suggestion, Applicability::MaybeIncorrect, ); @@ -2180,7 +2287,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let reported = if variant_resolution.is_some() { // Variant in type position let msg = format!("expected type, found variant `{}`", assoc_ident); - tcx.sess.span_err(span, &msg) + tcx.sess.span_err(span, msg) } else if qself_ty.is_enum() { let mut err = struct_span_err!( tcx.sess, @@ -2251,7 +2358,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Assume that if it's not matched, there must be a const defined with the same name // but it was used in a type position. let msg = format!("found associated const `{assoc_ident}` when type was expected"); - let guar = tcx.sess.struct_span_err(span, &msg).emit(); + let guar = tcx.sess.struct_span_err(span, msg).emit(); return Err(guar); }; @@ -2271,7 +2378,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { also, tcx.def_kind_descr(kind, def_id) ); - lint.span_note(tcx.def_span(def_id), ¬e_msg); + lint.span_note(tcx.def_span(def_id), note_msg); }; could_refer_to(DefKind::Variant, variant_def_id, ""); @@ -2468,9 +2575,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let msg = format!("{kind} `{name}` is private"); let def_span = tcx.def_span(item); tcx.sess - .struct_span_err_with_code(span, &msg, rustc_errors::error_code!(E0624)) - .span_label(span, &format!("private {kind}")) - .span_label(def_span, &format!("{kind} defined here")) + .struct_span_err_with_code(span, msg, rustc_errors::error_code!(E0624)) + .span_label(span, format!("private {kind}")) + .span_label(def_span, format!("{kind} defined here")) .emit(); } tcx.check_stability(item, Some(block), span, None); @@ -2918,7 +3025,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.prohibit_generics(path.segments.iter(), |err| { if let Some(span) = tcx.def_ident_span(def_id) { let name = tcx.item_name(def_id); - err.span_note(span, &format!("type parameter `{name}` defined here")); + err.span_note(span, format!("type parameter `{name}` defined here")); } }); @@ -2979,7 +3086,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut span: MultiSpan = vec![t_sp].into(); span.push_span_label( i_sp, - &format!("`Self` is on type `{type_name}` in this `impl`"), + format!("`Self` is on type `{type_name}` in this `impl`"), ); let mut postfix = ""; if generics == 0 { @@ -2987,11 +3094,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } span.push_span_label( t_sp, - &format!("`Self` corresponds to this type{postfix}"), + format!("`Self` corresponds to this type{postfix}"), ); - err.span_note(span, &msg); + err.span_note(span, msg); } else { - err.note(&msg); + err.note(msg); } for segment in path.segments { if let Some(args) = segment.args && segment.ident.name == kw::SelfUpper { @@ -3082,7 +3189,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(args) = segment.args { err.span_suggestion_verbose( segment.ident.span.shrink_to_hi().to(args.span_ext), - &format!("primitive type `{name}` doesn't have generic parameters"), + format!("primitive type `{name}` doesn't have generic parameters"), "", Applicability::MaybeIncorrect, ); @@ -3373,7 +3480,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if !infer_replacements.is_empty() { diag.multipart_suggestion( - &format!( + format!( "try replacing `_` with the type{} in the corresponding trait method signature", rustc_errors::pluralize!(infer_replacements.len()), ), diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index ba2d4319af6..1cf93c86f4f 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -123,7 +123,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let tcx = self.infcx.tcx; // <ty as Deref> - let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]); + let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]); let cause = traits::ObligationCause::misc(self.span, self.body_id); diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 284b099e7bc..686066abbf0 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -42,8 +42,14 @@ impl<'tcx> Bounds<'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, span: Span, constness: ty::BoundConstness, + polarity: ty::ImplPolarity, ) { - self.predicates.push((trait_ref.with_constness(constness).to_predicate(tcx), span)); + self.predicates.push(( + trait_ref + .map_bound(|trait_ref| ty::TraitPredicate { trait_ref, constness, polarity }) + .to_predicate(tcx), + span, + )); } pub fn push_projection_bound( @@ -57,7 +63,7 @@ impl<'tcx> Bounds<'tcx> { pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); - let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized_def_id, [ty])); + let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]); // Preferable to put this obligation first, since we report better errors for sized ambiguity. self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span)); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 68e957f9d8e..c4d4e0d6d78 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -175,7 +175,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { } // Generic statics are rejected, but we still reach this case. Err(e) => { - tcx.sess.delay_span_bug(span, &e.to_string()); + tcx.sess.delay_span_bug(span, e.to_string()); return; } }; @@ -334,7 +334,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( &tcx.sess.parse_sess, sym::impl_trait_projections, span, - &format!( + format!( "`{}` return type cannot contain a projection or `Self` that references \ lifetimes from a parent scope", if is_async { "async fn" } else { "impl Trait" }, @@ -428,7 +428,7 @@ fn check_opaque_meets_bounds<'tcx>( let ty_err = ty_err.to_string(tcx); tcx.sess.delay_span_bug( span, - &format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"), + format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"), ); } } @@ -536,7 +536,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { tcx, assoc_item, assoc_item, - tcx.mk_trait_ref(id.owner_id.to_def_id(), trait_substs), + ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_substs), ); } _ => {} @@ -618,11 +618,11 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { E0044, "foreign items may not have {kinds} parameters", ) - .span_label(item.span, &format!("can't have {kinds} parameters")) + .span_label(item.span, format!("can't have {kinds} parameters")) .help( // FIXME: once we start storing spans for type arguments, turn this // into a suggestion. - &format!( + format!( "replace the {} parameters with concrete {}{}", kinds, kinds_pl, @@ -985,10 +985,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { err.span_note( tcx.def_span(def_spans[0].0), - &format!( - "`{}` has a `#[repr(align)]` attribute", - tcx.item_name(def_spans[0].0) - ), + format!("`{}` has a `#[repr(align)]` attribute", tcx.item_name(def_spans[0].0)), ); if def_spans.len() > 2 { @@ -997,7 +994,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { let ident = tcx.item_name(*adt_def); err.span_note( *span, - &if first { + if first { format!( "`{}` contains a field of type `{}`", tcx.type_of(def.did()).subst_identity(), @@ -1466,10 +1463,10 @@ fn opaque_type_cycle_error( let ty_span = tcx.def_span(def_id); if !seen.contains(&ty_span) { let descr = if ty.is_impl_trait() { "opaque " } else { "" }; - err.span_label(ty_span, &format!("returning this {descr}type `{ty}`")); + err.span_label(ty_span, format!("returning this {descr}type `{ty}`")); seen.insert(ty_span); } - err.span_label(sp, &format!("returning here with type `{ty}`")); + err.span_label(sp, format!("returning here with type `{ty}`")); } for closure_def_id in visitor.closures { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 48214b899a4..7384eb25f2e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1273,7 +1273,7 @@ fn compare_number_of_generics<'tcx>( let mut err = tcx.sess.struct_span_err_with_code( spans, - &format!( + format!( "{} `{}` has {} {kind} parameter{} but its trait \ declaration has {} {kind} parameter{}", item_kind, diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 111bf5e5455..5ba1ca1c807 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -1,13 +1,17 @@ // FIXME(@lcnr): Move this module out of `rustc_hir_analysis`. // // We don't do any drop checking during hir typeck. -use crate::hir::def_id::{DefId, LocalDefId}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{struct_span_err, ErrorGuaranteed}; -use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; +use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::IgnoreRegions; -use rustc_middle::ty::{self, Predicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; +use rustc_trait_selection::traits::{self, ObligationCtxt}; + +use crate::errors; +use crate::hir::def_id::{DefId, LocalDefId}; /// This function confirms that the `Drop` implementation identified by /// `drop_impl_did` is not any more specialized than the type it is @@ -27,22 +31,34 @@ use rustc_middle::ty::{self, Predicate, Ty, TyCtxt}; /// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`). /// pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorGuaranteed> { + match tcx.impl_polarity(drop_impl_did) { + ty::ImplPolarity::Positive => {} + ty::ImplPolarity::Negative => { + return Err(tcx.sess.emit_err(errors::DropImplPolarity::Negative { + span: tcx.def_span(drop_impl_did), + })); + } + ty::ImplPolarity::Reservation => { + return Err(tcx.sess.emit_err(errors::DropImplPolarity::Reservation { + span: tcx.def_span(drop_impl_did), + })); + } + } let dtor_self_type = tcx.type_of(drop_impl_did).subst_identity(); - let dtor_predicates = tcx.predicates_of(drop_impl_did); match dtor_self_type.kind() { - ty::Adt(adt_def, self_to_impl_substs) => { + ty::Adt(adt_def, adt_to_impl_substs) => { ensure_drop_params_and_item_params_correspond( tcx, drop_impl_did.expect_local(), adt_def.did(), - self_to_impl_substs, + adt_to_impl_substs, )?; ensure_drop_predicates_are_implied_by_item_defn( tcx, - dtor_predicates, + drop_impl_did.expect_local(), adt_def.did().expect_local(), - self_to_impl_substs, + adt_to_impl_substs, ) } _ => { @@ -52,7 +68,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro let span = tcx.def_span(drop_impl_did); let reported = tcx.sess.delay_span_bug( span, - &format!("should have been rejected by coherence check: {dtor_self_type}"), + format!("should have been rejected by coherence check: {dtor_self_type}"), ); Err(reported) } @@ -63,9 +79,9 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( tcx: TyCtxt<'tcx>, drop_impl_did: LocalDefId, self_type_did: DefId, - drop_impl_substs: SubstsRef<'tcx>, + adt_to_impl_substs: SubstsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let Err(arg) = tcx.uses_unique_generic_params(drop_impl_substs, IgnoreRegions::No) else { + let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, IgnoreRegions::No) else { return Ok(()) }; @@ -76,15 +92,15 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( struct_span_err!(tcx.sess, drop_impl_span, E0366, "`Drop` impls cannot be specialized"); match arg { ty::util::NotUniqueParam::DuplicateParam(arg) => { - err.note(&format!("`{arg}` is mentioned multiple times")) + err.note(format!("`{arg}` is mentioned multiple times")) } ty::util::NotUniqueParam::NotParam(arg) => { - err.note(&format!("`{arg}` is not a generic parameter")) + err.note(format!("`{arg}` is not a generic parameter")) } }; err.span_note( item_span, - &format!( + format!( "use the same sequence of generic lifetime, type and const parameters \ as the {self_descr} definition", ), @@ -96,237 +112,94 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( /// implied by assuming the predicates attached to self_type_did. fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( tcx: TyCtxt<'tcx>, - dtor_predicates: ty::GenericPredicates<'tcx>, - self_type_did: LocalDefId, - self_to_impl_substs: SubstsRef<'tcx>, + drop_impl_def_id: LocalDefId, + adt_def_id: LocalDefId, + adt_to_impl_substs: SubstsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let mut result = Ok(()); - - // Here is an example, analogous to that from - // `compare_impl_method`. - // - // Consider a struct type: - // - // struct Type<'c, 'b:'c, 'a> { - // x: &'a Contents // (contents are irrelevant; - // y: &'c Cell<&'b Contents>, // only the bounds matter for our purposes.) - // } - // - // and a Drop impl: - // - // impl<'z, 'y:'z, 'x:'y> Drop for P<'z, 'y, 'x> { - // fn drop(&mut self) { self.y.set(self.x); } // (only legal if 'x: 'y) - // } - // - // We start out with self_to_impl_substs, that maps the generic - // parameters of Type to that of the Drop impl. - // - // self_to_impl_substs = {'c => 'z, 'b => 'y, 'a => 'x} - // - // Applying this to the predicates (i.e., assumptions) provided by the item - // definition yields the instantiated assumptions: - // - // ['y : 'z] + let infcx = tcx.infer_ctxt().build(); + let ocx = ObligationCtxt::new(&infcx); + + // Take the param-env of the adt and substitute the substs that show up in + // the implementation's self type. This gives us the assumptions that the + // self ty of the implementation is allowed to know just from it being a + // well-formed adt, since that's all we're allowed to assume while proving + // the Drop implementation is not specialized. // - // We then check all of the predicates of the Drop impl: - // - // ['y:'z, 'x:'y] - // - // and ensure each is in the list of instantiated - // assumptions. Here, `'y:'z` is present, but `'x:'y` is - // absent. So we report an error that the Drop impl injected a - // predicate that is not present on the struct definition. - - // We can assume the predicates attached to struct/enum definition - // hold. - let generic_assumptions = tcx.predicates_of(self_type_did); - - let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs); - let assumptions_in_impl_context = assumptions_in_impl_context.predicates; - - debug!(?assumptions_in_impl_context, ?dtor_predicates.predicates); - - let self_param_env = tcx.param_env(self_type_did); - - // An earlier version of this code attempted to do this checking - // via the traits::fulfill machinery. However, it ran into trouble - // since the fulfill machinery merely turns outlives-predicates - // 'a:'b and T:'b into region inference constraints. It is simpler - // just to look for all the predicates directly. - - assert_eq!(dtor_predicates.parent, None); - for &(predicate, predicate_sp) in dtor_predicates.predicates { - // (We do not need to worry about deep analysis of type - // expressions etc because the Drop impls are already forced - // to take on a structure that is roughly an alpha-renaming of - // the generic parameters of the item definition.) - - // This path now just checks *all* predicates via an instantiation of - // the `SimpleEqRelation`, which simply forwards to the `relate` machinery - // after taking care of anonymizing late bound regions. - // - // However, it may be more efficient in the future to batch - // the analysis together via the fulfill (see comment above regarding - // the usage of the fulfill machinery), rather than the - // repeated `.iter().any(..)` calls. + // We don't need to normalize this param-env or anything, since we're only + // substituting it with free params, so no additional param-env normalization + // can occur on top of what has been done in the param_env query itself. + let param_env = ty::EarlyBinder(tcx.param_env(adt_def_id)) + .subst(tcx, adt_to_impl_substs) + .with_constness(tcx.constness(drop_impl_def_id)); + + for (pred, span) in tcx.predicates_of(drop_impl_def_id).instantiate_identity(tcx) { + let normalize_cause = traits::ObligationCause::misc(span, adt_def_id); + let pred = ocx.normalize(&normalize_cause, param_env, pred); + let cause = traits::ObligationCause::new(span, adt_def_id, traits::DropImpl); + ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, pred)); + } - // This closure is a more robust way to check `Predicate` equality - // than simple `==` checks (which were the previous implementation). - // It relies on `ty::relate` for `TraitPredicate`, `ProjectionPredicate`, - // `ConstEvaluatable` and `TypeOutlives` (which implement the Relate trait), - // while delegating on simple equality for the other `Predicate`. - // This implementation solves (Issue #59497) and (Issue #58311). - // It is unclear to me at the moment whether the approach based on `relate` - // could be extended easily also to the other `Predicate`. - let predicate_matches_closure = |p: Predicate<'tcx>| { - let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env); - let predicate = predicate.kind(); - let p = p.kind(); - match (predicate.skip_binder(), p.skip_binder()) { - ( - ty::PredicateKind::Clause(ty::Clause::Trait(a)), - ty::PredicateKind::Clause(ty::Clause::Trait(b)), - ) => relator.relate(predicate.rebind(a), p.rebind(b)).is_ok(), - ( - ty::PredicateKind::Clause(ty::Clause::Projection(a)), - ty::PredicateKind::Clause(ty::Clause::Projection(b)), - ) => relator.relate(predicate.rebind(a), p.rebind(b)).is_ok(), - ( - ty::PredicateKind::ConstEvaluatable(a), - ty::PredicateKind::ConstEvaluatable(b), - ) => relator.relate(predicate.rebind(a), predicate.rebind(b)).is_ok(), - ( - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate( - ty_a, - lt_a, - ))), - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate( - ty_b, - lt_b, - ))), - ) => { - relator.relate(predicate.rebind(ty_a), p.rebind(ty_b)).is_ok() - && relator.relate(predicate.rebind(lt_a), p.rebind(lt_b)).is_ok() - } - (ty::PredicateKind::WellFormed(arg_a), ty::PredicateKind::WellFormed(arg_b)) => { - relator.relate(predicate.rebind(arg_a), p.rebind(arg_b)).is_ok() - } - _ => predicate == p, + // All of the custom error reporting logic is to preserve parity with the old + // error messages. + // + // They can probably get removed with better treatment of the new `DropImpl` + // obligation cause code, and perhaps some custom logic in `report_region_errors`. + + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + let mut guar = None; + let mut root_predicates = FxHashSet::default(); + for error in errors { + let root_predicate = error.root_obligation.predicate; + if root_predicates.insert(root_predicate) { + let item_span = tcx.def_span(adt_def_id); + let self_descr = tcx.def_descr(adt_def_id.to_def_id()); + guar = Some( + struct_span_err!( + tcx.sess, + error.root_obligation.cause.span, + E0367, + "`Drop` impl requires `{root_predicate}` \ + but the {self_descr} it is implemented for does not", + ) + .span_note(item_span, "the implementor must specify the same requirement") + .emit(), + ); } - }; - - if !assumptions_in_impl_context.iter().copied().any(predicate_matches_closure) { - let item_span = tcx.def_span(self_type_did); - let self_descr = tcx.def_descr(self_type_did.to_def_id()); - let reported = struct_span_err!( - tcx.sess, - predicate_sp, - E0367, - "`Drop` impl requires `{predicate}` but the {self_descr} it is implemented for does not", - ) - .span_note(item_span, "the implementor must specify the same requirement") - .emit(); - result = Err(reported); } + return Err(guar.unwrap()); } - result -} - -/// This is an implementation of the [`TypeRelation`] trait with the -/// aim of simply comparing for equality (without side-effects). -/// -/// It is not intended to be used anywhere else other than here. -pub(crate) struct SimpleEqRelation<'tcx> { - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, -} - -impl<'tcx> SimpleEqRelation<'tcx> { - fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> SimpleEqRelation<'tcx> { - SimpleEqRelation { tcx, param_env } - } -} - -impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env - } - - fn tag(&self) -> &'static str { - "dropck::SimpleEqRelation" - } - - fn a_is_expected(&self) -> bool { - true - } - - fn relate_with_variance<T: Relate<'tcx>>( - &mut self, - _: ty::Variance, - _info: ty::VarianceDiagInfo<'tcx>, - a: T, - b: T, - ) -> RelateResult<'tcx, T> { - // Here we ignore variance because we require drop impl's types - // to be *exactly* the same as to the ones in the struct definition. - self.relate(a, b) - } - - fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - debug!("SimpleEqRelation::tys(a={:?}, b={:?})", a, b); - ty::relate::super_relate_tys(self, a, b) - } - - fn regions( - &mut self, - a: ty::Region<'tcx>, - b: ty::Region<'tcx>, - ) -> RelateResult<'tcx, ty::Region<'tcx>> { - debug!("SimpleEqRelation::regions(a={:?}, b={:?})", a, b); - - // We can just equate the regions because LBRs have been - // already anonymized. - if a == b { - Ok(a) - } else { - // I'm not sure is this `TypeError` is the right one, but - // it should not matter as it won't be checked (the dropck - // will emit its own, more informative and higher-level errors - // in case anything goes wrong). - Err(TypeError::RegionsPlaceholderMismatch) + let errors = ocx.infcx.resolve_regions(&OutlivesEnvironment::new(param_env)); + if !errors.is_empty() { + let mut guar = None; + for error in errors { + let item_span = tcx.def_span(adt_def_id); + let self_descr = tcx.def_descr(adt_def_id.to_def_id()); + let outlives = match error { + RegionResolutionError::ConcreteFailure(_, a, b) => format!("{b}: {a}"), + RegionResolutionError::GenericBoundFailure(_, generic, r) => { + format!("{generic}: {r}") + } + RegionResolutionError::SubSupConflict(_, _, _, a, _, b, _) => format!("{b}: {a}"), + RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => { + format!("{b}: {a}", a = tcx.mk_re_var(a)) + } + }; + guar = Some( + struct_span_err!( + tcx.sess, + error.origin().span(), + E0367, + "`Drop` impl requires `{outlives}` \ + but the {self_descr} it is implemented for does not", + ) + .span_note(item_span, "the implementor must specify the same requirement") + .emit(), + ); } + return Err(guar.unwrap()); } - fn consts( - &mut self, - a: ty::Const<'tcx>, - b: ty::Const<'tcx>, - ) -> RelateResult<'tcx, ty::Const<'tcx>> { - debug!("SimpleEqRelation::consts(a={:?}, b={:?})", a, b); - ty::relate::super_relate_consts(self, a, b) - } - - fn binders<T>( - &mut self, - a: ty::Binder<'tcx, T>, - b: ty::Binder<'tcx, T>, - ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> - where - T: Relate<'tcx>, - { - debug!("SimpleEqRelation::binders({:?}: {:?}", a, b); - - // Anonymizing the LBRs is necessary to solve (Issue #59497). - // After we do so, it should be totally fine to skip the binders. - let anon_a = self.tcx.anonymize_bound_vars(a); - let anon_b = self.tcx.anonymize_bound_vars(b); - self.relate(anon_a.skip_binder(), anon_b.skip_binder())?; - - Ok(a) - } + Ok(()) } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index d505d8b8e0b..e8785235c83 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -381,6 +381,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool), sym::read_via_copy => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)), + sym::write_via_move => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), sym::discriminant_value => { let assoc_items = tcx.associated_item_def_ids( @@ -546,14 +547,14 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) Err(_) => { let msg = format!("unrecognized platform-specific intrinsic function: `{name}`"); - tcx.sess.struct_span_err(it.span, &msg).emit(); + tcx.sess.struct_span_err(it.span, msg).emit(); return; } } } _ => { let msg = format!("unrecognized platform-specific intrinsic function: `{name}`"); - tcx.sess.struct_span_err(it.span, &msg).emit(); + tcx.sess.struct_span_err(it.span, msg).emit(); return; } }; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index a28814681db..0bb1467ef31 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -130,7 +130,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { _ => None, }; let Some(asm_ty) = asm_ty else { - let msg = &format!("cannot use value of type `{ty}` for inline assembly"); + let msg = format!("cannot use value of type `{ty}` for inline assembly"); let mut err = self.tcx.sess.struct_span_err(expr.span, msg); err.note( "only integers, floats, SIMD vectors, pointers and function pointers \ @@ -145,7 +145,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if !ty.is_copy_modulo_regions(self.tcx, self.param_env) { let msg = "arguments for inline assembly must be copyable"; let mut err = self.tcx.sess.struct_span_err(expr.span, msg); - err.note(&format!("`{ty}` does not implement the Copy trait")); + err.note(format!("`{ty}` does not implement the Copy trait")); err.emit(); } @@ -164,8 +164,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg); let in_expr_ty = (self.get_operand_ty)(in_expr); - err.span_label(in_expr.span, &format!("type `{in_expr_ty}`")); - err.span_label(expr.span, &format!("type `{ty}`")); + err.span_label(in_expr.span, format!("type `{in_expr_ty}`")); + err.span_label(expr.span, format!("type `{ty}`")); err.note( "asm inout arguments must have the same type, \ unless they are both pointers or integers of the same size", @@ -184,17 +184,17 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let reg_class = reg.reg_class(); let supported_tys = reg_class.supported_types(asm_arch); let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else { - let msg = &format!("type `{ty}` cannot be used with this register class"); + let msg = format!("type `{ty}` cannot be used with this register class"); let mut err = self.tcx.sess.struct_span_err(expr.span, msg); let supported_tys: Vec<_> = supported_tys.iter().map(|(t, _)| t.to_string()).collect(); - err.note(&format!( + err.note(format!( "register class `{}` supports these types: {}", reg_class.name(), supported_tys.join(", "), )); if let Some(suggest) = reg_class.suggest_class(asm_arch, asm_ty) { - err.help(&format!( + err.help(format!( "consider using the `{}` register class instead", suggest.name() )); @@ -215,9 +215,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // register class is usable at all. if let Some(feature) = feature { if !target_features.contains(feature) { - let msg = &format!("`{}` target feature is not enabled", feature); + let msg = format!("`{}` target feature is not enabled", feature); let mut err = self.tcx.sess.struct_span_err(expr.span, msg); - err.note(&format!( + err.note(format!( "this is required to use type `{}` with register class `{}`", ty, reg_class.name(), @@ -252,10 +252,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { "formatting may not be suitable for sub-register argument", |lint| { lint.span_label(expr.span, "for this argument"); - lint.help(&format!( + lint.help(format!( "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}`", )); - lint.help(&format!( + lint.help(format!( "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`", )); lint @@ -301,7 +301,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { op.is_clobber(), ) { let msg = format!("cannot use register `{}`: {}", reg.name(), msg); - self.tcx.sess.struct_span_err(*op_sp, &msg).emit(); + self.tcx.sess.struct_span_err(*op_sp, msg).emit(); continue; } } @@ -340,7 +340,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { reg_class.name(), feature ); - self.tcx.sess.struct_span_err(*op_sp, &msg).emit(); + self.tcx.sess.struct_span_err(*op_sp, msg).emit(); // register isn't enabled, don't do more checks continue; } @@ -354,7 +354,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { .intersperse(", ") .collect::<String>(), ); - self.tcx.sess.struct_span_err(*op_sp, &msg).emit(); + self.tcx.sess.struct_span_err(*op_sp, msg).emit(); // register isn't enabled, don't do more checks continue; } @@ -436,7 +436,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { self.tcx.sess.struct_span_err(*op_sp, "invalid `sym` operand"); err.span_label( self.tcx.def_span(anon_const.def_id), - &format!("is {} `{}`", ty.kind().article(), ty), + format!("is {} `{}`", ty.kind().article(), ty), ); err.help("`sym` operands must refer to either a function or a static"); err.emit(); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c066c396766..862f0a9b0e2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -445,7 +445,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe let plural = pluralize!(unsatisfied_bounds.len()); let mut err = tcx.sess.struct_span_err( gat_item_hir.span, - &format!("missing required bound{} on `{}`", plural, gat_item_hir.ident), + format!("missing required bound{} on `{}`", plural, gat_item_hir.ident), ); let suggestion = format!( @@ -455,14 +455,14 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe ); err.span_suggestion( gat_item_hir.generics.tail_span_for_predicate_suggestion(), - &format!("add the required where clause{plural}"), + format!("add the required where clause{plural}"), suggestion, Applicability::MachineApplicable, ); let bound = if unsatisfied_bounds.len() > 1 { "these bounds are" } else { "this bound is" }; - err.note(&format!( + err.note(format!( "{} currently required to ensure that impls have maximum flexibility", bound )); @@ -916,14 +916,14 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { if is_ptr { tcx.sess.span_err( hir_ty.span, - &format!( + format!( "using {unsupported_type} as const generic parameters is forbidden", ), ); } else { let mut err = tcx.sess.struct_span_err( hir_ty.span, - &format!( + format!( "{unsupported_type} is forbidden as the type of a const generic parameter", ), ); @@ -1029,7 +1029,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b let ty = tcx.erase_regions(ty); if ty.has_infer() { tcx.sess - .delay_span_bug(item.span, &format!("inference variables in {:?}", ty)); + .delay_span_bug(item.span, format!("inference variables in {:?}", ty)); // Just treat unresolved type expression as if it needs drop. true } else { @@ -1651,7 +1651,7 @@ fn check_method_receiver<'tcx>( &tcx.sess.parse_sess, sym::arbitrary_self_types, span, - &format!( + format!( "`{receiver_ty}` cannot be used as the type of `self` without \ the `arbitrary_self_types` feature", ), @@ -1779,7 +1779,7 @@ fn receiver_is_implemented<'tcx>( receiver_ty: Ty<'tcx>, ) -> bool { let tcx = wfcx.tcx(); - let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(receiver_trait_def_id, [receiver_ty])); + let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]); let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref); @@ -1874,10 +1874,10 @@ fn report_bivariance( } else { format!("consider removing `{param_name}` or referring to it in a field") }; - err.help(&msg); + err.help(msg); if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds { - err.help(&format!( + err.help(format!( "if you intended `{0}` to be a const parameter, use `const {0}: usize` instead", param_name )); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 611ce13b739..d05d8508408 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -1,9 +1,11 @@ //! Check properties that are required by built-in traits and set //! up data structures required by type-checking/codegen. -use crate::errors::{CopyImplOnNonAdt, CopyImplOnTypeWithDtor, DropImplOnWrongItem}; +use crate::errors::{ + ConstParamTyImplOnNonAdt, CopyImplOnNonAdt, CopyImplOnTypeWithDtor, DropImplOnWrongItem, +}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, MultiSpan}; +use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; @@ -14,9 +16,11 @@ use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt}; +use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::misc::{ - type_allowed_to_implement_copy, CopyImplementationError, InfringingFieldsReason, + type_allowed_to_implement_const_param_ty, type_allowed_to_implement_copy, + ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason, }; use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCause}; @@ -27,6 +31,7 @@ pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) { Checker { tcx, trait_def_id } .check(lang_items.drop_trait(), visit_implementation_of_drop) .check(lang_items.copy_trait(), visit_implementation_of_copy) + .check(lang_items.const_param_ty_trait(), visit_implementation_of_const_param_ty) .check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized) .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn); } @@ -83,110 +88,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { match type_allowed_to_implement_copy(tcx, param_env, self_type, cause) { Ok(()) => {} Err(CopyImplementationError::InfringingFields(fields)) => { - let mut err = struct_span_err!( - tcx.sess, - span, - E0204, - "the trait `Copy` cannot be implemented for this type" - ); - - // We'll try to suggest constraining type parameters to fulfill the requirements of - // their `Copy` implementation. - let mut errors: BTreeMap<_, Vec<_>> = Default::default(); - let mut bounds = vec![]; - - let mut seen_tys = FxHashSet::default(); - - for (field, ty, reason) in fields { - // Only report an error once per type. - if !seen_tys.insert(ty) { - continue; - } - - let field_span = tcx.def_span(field.did); - err.span_label(field_span, "this field does not implement `Copy`"); - - match reason { - InfringingFieldsReason::Fulfill(fulfillment_errors) => { - for error in fulfillment_errors { - let error_predicate = error.obligation.predicate; - // Only note if it's not the root obligation, otherwise it's trivial and - // should be self-explanatory (i.e. a field literally doesn't implement Copy). - - // FIXME: This error could be more descriptive, especially if the error_predicate - // contains a foreign type or if it's a deeply nested type... - if error_predicate != error.root_obligation.predicate { - errors - .entry((ty.to_string(), error_predicate.to_string())) - .or_default() - .push(error.obligation.cause.span); - } - if let ty::PredicateKind::Clause(ty::Clause::Trait( - ty::TraitPredicate { - trait_ref, - polarity: ty::ImplPolarity::Positive, - .. - }, - )) = error_predicate.kind().skip_binder() - { - let ty = trait_ref.self_ty(); - if let ty::Param(_) = ty.kind() { - bounds.push(( - format!("{ty}"), - trait_ref.print_only_trait_path().to_string(), - Some(trait_ref.def_id), - )); - } - } - } - } - InfringingFieldsReason::Regions(region_errors) => { - for error in region_errors { - let ty = ty.to_string(); - match error { - RegionResolutionError::ConcreteFailure(origin, a, b) => { - let predicate = format!("{b}: {a}"); - errors - .entry((ty.clone(), predicate.clone())) - .or_default() - .push(origin.span()); - if let ty::RegionKind::ReEarlyBound(ebr) = *b && ebr.has_name() { - bounds.push((b.to_string(), a.to_string(), None)); - } - } - RegionResolutionError::GenericBoundFailure(origin, a, b) => { - let predicate = format!("{a}: {b}"); - errors - .entry((ty.clone(), predicate.clone())) - .or_default() - .push(origin.span()); - if let infer::region_constraints::GenericKind::Param(_) = a { - bounds.push((a.to_string(), b.to_string(), None)); - } - } - _ => continue, - } - } - } - } - } - for ((ty, error_predicate), spans) in errors { - let span: MultiSpan = spans.into(); - err.span_note( - span, - &format!("the `Copy` impl for `{}` requires that `{}`", ty, error_predicate), - ); - } - suggest_constraining_type_params( - tcx, - tcx.hir().get_generics(impl_did).expect("impls always have generics"), - &mut err, - bounds.iter().map(|(param, constraint, def_id)| { - (param.as_str(), constraint.as_str(), *def_id) - }), - None, - ); - err.emit(); + infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span); } Err(CopyImplementationError::NotAnAdt) => { tcx.sess.emit_err(CopyImplOnNonAdt { span }); @@ -197,6 +99,29 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { } } +fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) { + let self_type = tcx.type_of(impl_did).subst_identity(); + assert!(!self_type.has_escaping_bound_vars()); + + let param_env = tcx.param_env(impl_did); + + let span = match tcx.hir().expect_item(impl_did).expect_impl() { + hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return, + impl_ => impl_.self_ty.span, + }; + + let cause = traits::ObligationCause::misc(span, impl_did); + match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) { + Ok(()) => {} + Err(ConstParamTyImplementationError::InfrigingFields(fields)) => { + infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span); + } + Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => { + tcx.sess.emit_err(ConstParamTyImplOnNonAdt { span }); + } + } +} + fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'_>, impl_did: LocalDefId) { debug!("visit_implementation_of_coerce_unsized: impl_did={:?}", impl_did); @@ -288,7 +213,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef for structs containing the field being coerced, \ ZST fields with 1 byte alignment, and nothing else", ) - .note(&format!( + .note(format!( "extra field `{}` of type `{}` is not allowed", field.name, ty_a, )) @@ -316,7 +241,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef for a coercion between structures with a single field \ being coerced", ) - .note(&format!( + .note(format!( "currently, {} fields need coercions: {}", coerced_fields.len(), coerced_fields @@ -340,10 +265,11 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef tcx, cause.clone(), param_env, - ty::Binder::dummy(tcx.mk_trait_ref( + ty::TraitRef::new( + tcx, dispatch_from_dyn_trait, [field.ty(tcx, substs_a), field.ty(tcx, substs_b)], - )), + ), )); } let errors = ocx.select_all_or_error(); @@ -373,7 +299,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)); let unsize_trait = tcx.lang_items().require(LangItem::Unsize).unwrap_or_else(|err| { - tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err.to_string())); + tcx.sess.fatal(format!("`CoerceUnsized` implementation {}", err.to_string())); }); let source = tcx.type_of(impl_did).subst_identity(); @@ -544,7 +470,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe "`CoerceUnsized` may only be implemented for \ a coercion between structures with one field being coerced", ) - .note(&format!( + .note(format!( "currently, {} fields need coercions: {}", diff_fields.len(), diff_fields @@ -579,8 +505,12 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe // Register an obligation for `A: Trait<B>`. let ocx = ObligationCtxt::new(&infcx); let cause = traits::ObligationCause::misc(span, impl_did); - let obligation = - Obligation::new(tcx, cause, param_env, tcx.mk_trait_ref(trait_def_id, [source, target])); + let obligation = Obligation::new( + tcx, + cause, + param_env, + ty::TraitRef::new(tcx, trait_def_id, [source, target]), + ); ocx.register_obligation(obligation); let errors = ocx.select_all_or_error(); if !errors.is_empty() { @@ -593,3 +523,119 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe CoerceUnsizedInfo { custom_kind: kind } } + +fn infringing_fields_error( + tcx: TyCtxt<'_>, + fields: Vec<(&ty::FieldDef, Ty<'_>, InfringingFieldsReason<'_>)>, + lang_item: LangItem, + impl_did: LocalDefId, + impl_span: Span, +) -> ErrorGuaranteed { + let trait_did = tcx.require_lang_item(lang_item, Some(impl_span)); + + let trait_name = tcx.def_path_str(trait_did); + + let mut err = struct_span_err!( + tcx.sess, + impl_span, + E0204, + "the trait `{trait_name}` cannot be implemented for this type" + ); + + // We'll try to suggest constraining type parameters to fulfill the requirements of + // their `Copy` implementation. + let mut errors: BTreeMap<_, Vec<_>> = Default::default(); + let mut bounds = vec![]; + + let mut seen_tys = FxHashSet::default(); + + for (field, ty, reason) in fields { + // Only report an error once per type. + if !seen_tys.insert(ty) { + continue; + } + + let field_span = tcx.def_span(field.did); + err.span_label(field_span, format!("this field does not implement `{trait_name}`")); + + match reason { + InfringingFieldsReason::Fulfill(fulfillment_errors) => { + for error in fulfillment_errors { + let error_predicate = error.obligation.predicate; + // Only note if it's not the root obligation, otherwise it's trivial and + // should be self-explanatory (i.e. a field literally doesn't implement Copy). + + // FIXME: This error could be more descriptive, especially if the error_predicate + // contains a foreign type or if it's a deeply nested type... + if error_predicate != error.root_obligation.predicate { + errors + .entry((ty.to_string(), error_predicate.to_string())) + .or_default() + .push(error.obligation.cause.span); + } + if let ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate { + trait_ref, + polarity: ty::ImplPolarity::Positive, + .. + })) = error_predicate.kind().skip_binder() + { + let ty = trait_ref.self_ty(); + if let ty::Param(_) = ty.kind() { + bounds.push(( + format!("{ty}"), + trait_ref.print_only_trait_path().to_string(), + Some(trait_ref.def_id), + )); + } + } + } + } + InfringingFieldsReason::Regions(region_errors) => { + for error in region_errors { + let ty = ty.to_string(); + match error { + RegionResolutionError::ConcreteFailure(origin, a, b) => { + let predicate = format!("{b}: {a}"); + errors + .entry((ty.clone(), predicate.clone())) + .or_default() + .push(origin.span()); + if let ty::RegionKind::ReEarlyBound(ebr) = *b && ebr.has_name() { + bounds.push((b.to_string(), a.to_string(), None)); + } + } + RegionResolutionError::GenericBoundFailure(origin, a, b) => { + let predicate = format!("{a}: {b}"); + errors + .entry((ty.clone(), predicate.clone())) + .or_default() + .push(origin.span()); + if let infer::region_constraints::GenericKind::Param(_) = a { + bounds.push((a.to_string(), b.to_string(), None)); + } + } + _ => continue, + } + } + } + } + } + for ((ty, error_predicate), spans) in errors { + let span: MultiSpan = spans.into(); + err.span_note( + span, + format!("the `{trait_name}` impl for `{ty}` requires that `{error_predicate}`"), + ); + } + suggest_constraining_type_params( + tcx, + tcx.hir().get_generics(impl_did).expect("impls always have generics"), + &mut err, + bounds + .iter() + .map(|(param, constraint, def_id)| (param.as_str(), constraint.as_str(), *def_id)), + None, + ); + + err.emit() +} diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 3d37e0ce0c6..33559020692 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -146,7 +146,7 @@ impl<'tcx> InherentCollect<'tcx> { ); err.help("consider using an extension trait instead"); if let ty::Ref(_, subty, _) = ty.kind() { - err.note(&format!( + err.note(format!( "you could also try moving the reference to \ uses of `{}` (such as `self`) within the implementation", subty diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 89175c0ef74..5ce8a83aad7 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -372,10 +372,10 @@ fn emit_orphan_check_error<'tcx>( if is_target_ty { // Point at `D<A>` in `impl<A, B> for C<B> in D<A>` - err.span_label(self_ty_span, &msg); + err.span_label(self_ty_span, msg); } else { // Point at `C<B>` in `impl<A, B> for C<B> in D<A>` - err.span_label(trait_span, &msg); + err.span_label(trait_span, msg); } } err.note("define and implement a trait or new type instead"); @@ -531,15 +531,15 @@ fn lint_auto_trait_impl<'tcx>( let self_descr = tcx.def_descr(self_type_did); match arg { ty::util::NotUniqueParam::DuplicateParam(arg) => { - lint.note(&format!("`{}` is mentioned multiple times", arg)); + lint.note(format!("`{}` is mentioned multiple times", arg)); } ty::util::NotUniqueParam::NotParam(arg) => { - lint.note(&format!("`{}` is not a generic parameter", arg)); + lint.note(format!("`{}` is not a generic parameter", arg)); } } lint.span_note( item_span, - &format!( + format!( "try using the same sequence of generic parameters as the {} definition", self_descr, ), diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 41547dd2a75..b65817ee95e 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -64,8 +64,8 @@ pub fn provide(providers: &mut Providers) { explicit_predicates_of: predicates_of::explicit_predicates_of, super_predicates_of: predicates_of::super_predicates_of, implied_predicates_of: predicates_of::implied_predicates_of, - super_predicates_that_define_assoc_type: - predicates_of::super_predicates_that_define_assoc_type, + super_predicates_that_define_assoc_item: + predicates_of::super_predicates_that_define_assoc_item, trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds, type_param_predicates: predicates_of::type_param_predicates, trait_def, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 80d6bc7db9e..948b903e509 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -1,5 +1,5 @@ use super::ItemCtxt; -use crate::astconv::AstConv; +use crate::astconv::{AstConv, OnlySelfBounds}; use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::subst::InternalSubsts; @@ -26,7 +26,7 @@ fn associated_type_bounds<'tcx>( ); let icx = ItemCtxt::new(tcx, assoc_item_def_id); - let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds); + let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false)); // Associated types are implicitly sized unless a `?Sized` bound is found icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span); @@ -67,7 +67,7 @@ fn opaque_type_bounds<'tcx>( ) -> &'tcx [(ty::Predicate<'tcx>, Span)] { ty::print::with_no_queries!({ let icx = ItemCtxt::new(tcx, opaque_def_id); - let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds); + let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false)); // Opaque types are implicitly sized unless a `?Sized` bound is found icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span); debug!(?bounds); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 8c414521b76..6c06957d1ee 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -1,4 +1,4 @@ -use crate::astconv::AstConv; +use crate::astconv::{AstConv, OnlySelfBounds}; use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; @@ -14,9 +14,6 @@ use rustc_middle::ty::{GenericPredicates, ToPredicate}; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; -#[derive(Debug)] -struct OnlySelfBounds(bool); - /// Returns a list of all type predicates (explicit and implicit) for the definition with /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus /// `Self: Trait` predicates for traits. @@ -99,8 +96,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen | ItemKind::Struct(_, generics) | ItemKind::Union(_, generics) => generics, - ItemKind::Trait(_, _, generics, ..) | ItemKind::TraitAlias(generics, _) => { - is_trait = Some(ty::TraitRef::identity(tcx, def_id.to_def_id())); + ItemKind::Trait(_, _, generics, self_bounds, ..) + | ItemKind::TraitAlias(generics, self_bounds) => { + is_trait = Some(self_bounds); generics } ItemKind::OpaqueTy(OpaqueTy { generics, .. }) => generics, @@ -122,10 +120,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // Below we'll consider the bounds on the type parameters (including `Self`) // and the explicit where-clauses, but to get the full set of predicates - // on a trait we need to add in the supertrait bounds and bounds found on - // associated types. - if let Some(_trait_ref) = is_trait { - predicates.extend(tcx.implied_predicates_of(def_id).predicates.iter().cloned()); + // on a trait we must also consider the bounds that follow the trait's name, + // like `trait Foo: A + B + C`. + if let Some(self_bounds) = is_trait { + predicates.extend( + icx.astconv() + .compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false)) + .predicates(), + ); } // In default impls, we can assume that the self type implements @@ -225,7 +227,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } let mut bounds = Bounds::default(); - icx.astconv().add_bounds(ty, bound_pred.bounds.iter(), &mut bounds, bound_vars); + icx.astconv().add_bounds( + ty, + bound_pred.bounds.iter(), + &mut bounds, + bound_vars, + OnlySelfBounds(false), + ); predicates.extend(bounds.predicates()); } @@ -557,7 +565,7 @@ pub(super) fn super_predicates_of( implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::SelfOnly) } -pub(super) fn super_predicates_that_define_assoc_type( +pub(super) fn super_predicates_that_define_assoc_item( tcx: TyCtxt<'_>, (trait_def_id, assoc_name): (DefId, Ident), ) -> ty::GenericPredicates<'_> { @@ -608,7 +616,7 @@ pub(super) fn implied_predicates_with_filter( let (superbounds, where_bounds_that_match) = match filter { PredicateFilter::All => ( // Convert the bounds that follow the colon (or equal in trait aliases) - icx.astconv().compute_bounds(self_param_ty, bounds), + icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(false)), // Also include all where clause bounds icx.type_parameter_bounds_in_generics( generics, @@ -620,7 +628,7 @@ pub(super) fn implied_predicates_with_filter( ), PredicateFilter::SelfOnly => ( // Convert the bounds that follow the colon (or equal in trait aliases) - icx.astconv().compute_bounds(self_param_ty, bounds), + icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(true)), // Include where clause bounds for `Self` icx.type_parameter_bounds_in_generics( generics, @@ -632,7 +640,7 @@ pub(super) fn implied_predicates_with_filter( ), PredicateFilter::SelfThatDefines(assoc_name) => ( // Convert the bounds that follow the colon (or equal) that reference the associated name - icx.astconv().compute_bounds_that_match_assoc_type(self_param_ty, bounds, assoc_name), + icx.astconv().compute_bounds_that_match_assoc_item(self_param_ty, bounds, assoc_name), // Include where clause bounds for `Self` that reference the associated name icx.type_parameter_bounds_in_generics( generics, @@ -774,32 +782,35 @@ impl<'tcx> ItemCtxt<'tcx> { only_self_bounds: OnlySelfBounds, assoc_name: Option<Ident>, ) -> Vec<(ty::Predicate<'tcx>, Span)> { - ast_generics - .predicates - .iter() - .filter_map(|wp| match wp { - hir::WherePredicate::BoundPredicate(bp) => Some(bp), - _ => None, - }) - .flat_map(|bp| { - let bt = if bp.is_param_bound(param_def_id.to_def_id()) { - Some(ty) - } else if !only_self_bounds.0 { - Some(self.to_ty(bp.bounded_ty)) - } else { - None - }; - let bvars = self.tcx.late_bound_vars(bp.hir_id); - - bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter( - |(_, b, _)| match assoc_name { - Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name), - None => true, - }, - ) - }) - .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars)) - .collect() + let mut bounds = Bounds::default(); + + for predicate in ast_generics.predicates { + let hir::WherePredicate::BoundPredicate(predicate) = predicate else { + continue; + }; + + let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) { + ty + } else if !only_self_bounds.0 { + self.to_ty(predicate.bounded_ty) + } else { + continue; + }; + + let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); + self.astconv().add_bounds( + bound_ty, + predicate.bounds.iter().filter(|bound| { + assoc_name + .map_or(true, |assoc_name| self.bound_defines_assoc_item(bound, assoc_name)) + }), + &mut bounds, + bound_vars, + only_self_bounds, + ); + } + + bounds.predicates().collect() } #[instrument(level = "trace", skip(self))] @@ -808,7 +819,7 @@ impl<'tcx> ItemCtxt<'tcx> { hir::GenericBound::Trait(poly_trait_ref, _) => { let trait_ref = &poly_trait_ref.trait_ref; if let Some(trait_did) = trait_ref.trait_def_id() { - self.tcx.trait_may_define_assoc_type(trait_did, assoc_name) + self.tcx.trait_may_define_assoc_item(trait_did, assoc_name) } else { false } @@ -817,19 +828,3 @@ impl<'tcx> ItemCtxt<'tcx> { } } } - -/// Converts a specific `GenericBound` from the AST into a set of -/// predicates that apply to the self type. A vector is returned -/// because this can be anywhere from zero predicates (`T: ?Sized` adds no -/// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar` -/// and `<T as Bar>::X == i32`). -fn predicates_from_bound<'tcx>( - astconv: &dyn AstConv<'tcx>, - param_ty: Ty<'tcx>, - bound: &'tcx hir::GenericBound<'tcx>, - bound_vars: &'tcx ty::List<ty::BoundVariableKind>, -) -> Vec<(ty::Predicate<'tcx>, Span)> { - let mut bounds = Bounds::default(); - astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars); - bounds.predicates().collect() -} diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 1c496f867a0..ab0dd01ce3a 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -987,7 +987,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { lifetime.ident ), |lint| { - let help = &format!( + let help = format!( "you can use the `'static` lifetime directly, in place of `{}`", lifetime.ident, ); @@ -1365,7 +1365,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { self.tcx.sess.delay_span_bug( lifetime_ref.ident.span, - &format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,), + format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,), ); } @@ -1652,17 +1652,16 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation { let bound_vars = if let Some(type_def_id) = type_def_id && self.tcx.def_kind(type_def_id) == DefKind::Trait - // FIXME(return_type_notation): We could bound supertrait methods. - && let Some(assoc_fn) = self - .tcx - .associated_items(type_def_id) - .find_by_name_and_kind(self.tcx, binding.ident, ty::AssocKind::Fn, type_def_id) + && let Some((mut bound_vars, assoc_fn)) = + BoundVarContext::supertrait_hrtb_vars( + self.tcx, + type_def_id, + binding.ident, + ty::AssocKind::Fn, + ) { - self.tcx - .generics_of(assoc_fn.def_id) - .params - .iter() - .map(|param| match param.kind { + bound_vars.extend(self.tcx.generics_of(assoc_fn.def_id).params.iter().map( + |param| match param.kind { ty::GenericParamDefKind::Lifetime => ty::BoundVariableKind::Region( ty::BoundRegionKind::BrNamed(param.def_id, param.name), ), @@ -1670,9 +1669,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { ty::BoundTyKind::Param(param.def_id, param.name), ), ty::GenericParamDefKind::Const { .. } => ty::BoundVariableKind::Const, - }) - .chain(self.tcx.fn_sig(assoc_fn.def_id).subst_identity().bound_vars()) - .collect() + }, + )); + bound_vars + .extend(self.tcx.fn_sig(assoc_fn.def_id).subst_identity().bound_vars()); + bound_vars } else { self.tcx.sess.delay_span_bug( binding.ident.span, @@ -1689,8 +1690,13 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { }); }); } else if let Some(type_def_id) = type_def_id { - let bound_vars = - BoundVarContext::supertrait_hrtb_vars(self.tcx, type_def_id, binding.ident); + let bound_vars = BoundVarContext::supertrait_hrtb_vars( + self.tcx, + type_def_id, + binding.ident, + ty::AssocKind::Type, + ) + .map(|(bound_vars, _)| bound_vars); self.with(scope, |this| { let scope = Scope::Supertrait { bound_vars: bound_vars.unwrap_or_default(), @@ -1720,11 +1726,15 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, def_id: DefId, assoc_name: Ident, - ) -> Option<Vec<ty::BoundVariableKind>> { - let trait_defines_associated_type_named = |trait_def_id: DefId| { - tcx.associated_items(trait_def_id) - .find_by_name_and_kind(tcx, assoc_name, ty::AssocKind::Type, trait_def_id) - .is_some() + assoc_kind: ty::AssocKind, + ) -> Option<(Vec<ty::BoundVariableKind>, &'tcx ty::AssocItem)> { + let trait_defines_associated_item_named = |trait_def_id: DefId| { + tcx.associated_items(trait_def_id).find_by_name_and_kind( + tcx, + assoc_name, + assoc_kind, + trait_def_id, + ) }; use smallvec::{smallvec, SmallVec}; @@ -1742,10 +1752,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { _ => break None, } - if trait_defines_associated_type_named(def_id) { - break Some(bound_vars.into_iter().collect()); + if let Some(assoc_item) = trait_defines_associated_item_named(def_id) { + break Some((bound_vars.into_iter().collect(), assoc_item)); } - let predicates = tcx.super_predicates_that_define_assoc_type((def_id, assoc_name)); + let predicates = tcx.super_predicates_that_define_assoc_item((def_id, assoc_name)); let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| { let bound_predicate = pred.kind(); match bound_predicate.skip_binder() { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index d7d509e5394..c20fbfd1e40 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -828,14 +828,14 @@ fn infer_placeholder_type<'a>( if let Some(ty) = ty.make_suggestable(tcx, false) { err.span_suggestion( span, - &format!("provide a type for the {item}", item = kind), + format!("provide a type for the {item}", item = kind), format!("{colon} {ty}"), Applicability::MachineApplicable, ); } else { with_forced_trimmed_paths!(err.span_note( tcx.hir().body(body_id).value.span, - &format!("however, the inferred type `{ty}` cannot be named"), + format!("however, the inferred type `{ty}` cannot be named"), )); } } @@ -856,7 +856,7 @@ fn infer_placeholder_type<'a>( } else { with_forced_trimmed_paths!(diag.span_note( tcx.hir().body(body_id).value.span, - &format!("however, the inferred type `{ty}` cannot be named"), + format!("however, the inferred type `{ty}` cannot be named"), )); } } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index f82169dee98..379a88538a9 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -6,7 +6,7 @@ use rustc_errors::{ MultiSpan, }; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, print::TraitRefPrintOnlyTraitPath, Ty}; use rustc_span::{symbol::Ident, Span, Symbol}; #[derive(Diagnostic)] @@ -108,6 +108,14 @@ pub struct CopyImplOnNonAdt { } #[derive(Diagnostic)] +#[diag(hir_analysis_const_param_ty_impl_on_non_adt)] +pub struct ConstParamTyImplOnNonAdt { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] #[diag(hir_analysis_trait_object_declared_with_no_traits, code = "E0224")] pub struct TraitObjectDeclaredWithNoTraits { #[primary_span] @@ -504,11 +512,23 @@ pub(crate) struct ReturnTypeNotationEqualityBound { pub(crate) struct ReturnTypeNotationMissingMethod { #[primary_span] pub span: Span, - pub trait_name: Symbol, + pub ty_name: String, pub assoc_name: Symbol, } #[derive(Diagnostic)] +#[diag(hir_analysis_return_type_notation_conflicting_bound)] +#[note] +pub(crate) struct ReturnTypeNotationConflictingBound<'tcx> { + #[primary_span] + pub span: Span, + pub ty_name: String, + pub assoc_name: Symbol, + pub first_bound: ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, + pub second_bound: ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, +} + +#[derive(Diagnostic)] #[diag(hir_analysis_placeholder_not_allowed_item_signatures, code = "E0121")] pub(crate) struct PlaceholderNotAllowedItemSignatures { #[primary_span] @@ -649,7 +669,6 @@ pub enum ImplNotMarkedDefault { #[note] Err { #[primary_span] - #[label] span: Span, cname: Symbol, ident: Symbol, @@ -815,3 +834,17 @@ pub(crate) struct MissingTildeConst { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +pub(crate) enum DropImplPolarity { + #[diag(hir_analysis_drop_impl_negative)] + Negative { + #[primary_span] + span: Span, + }, + #[diag(hir_analysis_drop_impl_reservation)] + Reservation { + #[primary_span] + span: Span, + }, +} diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 82a96f8e674..f070b4f9bae 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -76,7 +76,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) // (#36836) tcx.sess.delay_span_bug( tcx.def_span(impl_def_id), - &format!( + format!( "potentially unconstrained type parameters weren't evaluated: {:?}", impl_self_ty, ), diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index c09457e1d65..5cca2dacb5c 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -272,7 +272,7 @@ fn check_duplicate_params<'tcx>( if let (_, [duplicate, ..]) = base_params.partition_dedup() { let param = impl1_substs[duplicate.0 as usize]; tcx.sess - .struct_span_err(span, &format!("specializing impl repeats parameter `{}`", param)) + .struct_span_err(span, format!("specializing impl repeats parameter `{}`", param)) .emit(); } } @@ -464,7 +464,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc tcx.sess .struct_span_err( span, - &format!( + format!( "cannot specialize on trait `{}`", tcx.def_path_str(trait_ref.def_id), ), @@ -479,7 +479,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc tcx.sess .struct_span_err( span, - &format!("cannot specialize on associated type `{projection_ty} == {term}`",), + format!("cannot specialize on associated type `{projection_ty} == {term}`",), ) .emit(); } @@ -495,7 +495,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc } _ => { tcx.sess - .struct_span_err(span, &format!("cannot specialize on predicate `{}`", predicate)) + .struct_span_err(span, format!("cannot specialize on predicate `{}`", predicate)) .emit(); } } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index a4b797f77f7..3fe34f23aef 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -116,7 +116,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, use std::ops::Not; -use astconv::AstConv; +use astconv::{AstConv, OnlySelfBounds}; use bounds::Bounds; fluent_messages! { "../messages.ftl" } @@ -528,9 +528,11 @@ pub fn hir_trait_to_predicates<'tcx>( hir_trait, DUMMY_SP, ty::BoundConstness::NotConst, + ty::ImplPolarity::Positive, self_ty, &mut bounds, true, + OnlySelfBounds(false), ); bounds diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index da72d2584e3..42612eed750 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -61,7 +61,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau let span = tcx.def_span(item_def_id); let mut err = tcx.sess.struct_span_err(span, "rustc_outlives"); - for p in &pred { + for p in pred { err.note(p); } err.emit(); diff --git a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs index 0bfbf99cb0b..c37dff61b72 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs @@ -48,7 +48,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx, '_> { &self, mut err: DiagnosticBuilder<'tcx, ErrorGuaranteed>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - err.note(&format!( + err.note(format!( "certain types, like `{}`, must be casted before passing them to a \ variadic function, because of arcane ABI rules dictated by the C \ standard", diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 8f4d81ec3a9..6d1a1634ab4 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -480,7 +480,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let span = self.path_segment.ident.span; let msg = self.create_error_message(); - self.tcx.sess.struct_span_err_with_code(span, &msg, self.code()) + self.tcx.sess.struct_span_err_with_code(span, msg, self.code()) } /// Builds the `expected 1 type argument / supplied 2 type arguments` message. @@ -602,7 +602,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), - &msg, + msg, sugg, Applicability::HasPlaceholders, ); @@ -625,7 +625,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let sugg = format!("{}{}{}", sugg_prefix, suggested_args, sugg_suffix); debug!("sugg: {:?}", sugg); - err.span_suggestion_verbose(sugg_span, &msg, sugg, Applicability::HasPlaceholders); + err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders); } AngleBrackets::Implied => { // We never encounter missing lifetimes in situations in which lifetimes are elided @@ -652,7 +652,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), - &msg, + msg, sugg, Applicability::HasPlaceholders, ); @@ -683,7 +683,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let sugg = format!("{}{}{}", sugg_prefix, suggested_args, sugg_suffix); debug!("sugg: {:?}", sugg); - err.span_suggestion_verbose(sugg_span, &msg, sugg, Applicability::HasPlaceholders); + err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders); } } } @@ -885,7 +885,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { err.span_suggestion( span_redundant_lt_args, - &msg_lifetimes, + msg_lifetimes, "", Applicability::MaybeIncorrect, ); @@ -927,7 +927,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { err.span_suggestion( span_redundant_type_or_const_args, - &msg_types_or_consts, + msg_types_or_consts, "", Applicability::MaybeIncorrect, ); @@ -943,7 +943,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { if !suggestions.is_empty() { err.multipart_suggestion_verbose( - &format!( + format!( "replace the generic bound{s} with the associated type{s}", s = pluralize!(unbound_types.len()) ), @@ -969,7 +969,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { }, ); - err.span_suggestion(span, &msg, "", Applicability::MaybeIncorrect); + err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect); } else if redundant_lifetime_args && redundant_type_or_const_args { remove_lifetime_args(err); remove_type_or_const_args(err); @@ -1029,7 +1029,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { ) }; - err.span_note(spans, &msg); + err.span_note(spans, msg); } /// Add note if `impl Trait` is explicitly specified. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2db4f1e50d4..d93e8efc1b5 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1407,10 +1407,16 @@ impl<'a> State<'a> { self.print_type(ty); } hir::ExprKind::Type(expr, ty) => { - let prec = AssocOp::Colon.precedence() as i8; - self.print_expr_maybe_paren(expr, prec); - self.word_space(":"); + self.word("type_ascribe!("); + self.ibox(0); + self.print_expr(expr); + + self.word(","); + self.space_if_not_bol(); self.print_type(ty); + + self.end(); + self.word(")"); } hir::ExprKind::DropTemps(init) => { // Print `{`: diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index aefde8109a0..7d2f7e87608 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -271,7 +271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &cause, &mut |err| { if let Some((span, msg)) = &ret_reason { - err.span_label(*span, msg); + err.span_label(*span, msg.clone()); } else if let ExprKind::Block(block, _) = &then_expr.kind && let Some(expr) = &block.expr { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 5235710a266..655ab94eb48 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -397,7 +397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .sess .struct_span_err( callee_expr.span, - &format!("evaluate({:?}) = {:?}", predicate, result), + format!("evaluate({:?}) = {:?}", predicate, result), ) .span_label(predicate_span, "predicate") .emit(); @@ -630,7 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some((removal_span, kind, path)) = &unit_variant { err.span_suggestion_verbose( *removal_span, - &format!( + format!( "`{path}` is a unit {kind}, and does not take parentheses to be constructed", ), "", diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 1481c038cfe..a92f368e083 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -146,7 +146,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let reported = self .tcx .sess - .delay_span_bug(span, &format!("`{:?}` should be sized but is not?", t)); + .delay_span_bug(span, format!("`{:?}` should be sized but is not?", t)); return Err(reported); } }) @@ -270,7 +270,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { fcx, ); if self.cast_ty.is_integral() { - err.help(&format!( + err.help(format!( "cast through {} first", match e { CastError::NeedViaPtr => "a raw pointer", @@ -292,7 +292,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.cast_ty, fcx, ) - .help(&format!( + .help(format!( "cast through {} first", match e { CastError::NeedViaInt => "an integer", @@ -651,13 +651,13 @@ impl<'a, 'tcx> CastCheck<'tcx> { ); } Err(_) => { - let msg = &format!("did you mean `&{}{}`?", mtstr, tstr); + let msg = format!("did you mean `&{}{}`?", mtstr, tstr); err.span_help(self.cast_span, msg); } } } else { let msg = - &format!("consider using an implicit coercion to `&{mtstr}{tstr}` instead"); + format!("consider using an implicit coercion to `&{mtstr}{tstr}` instead"); err.span_help(self.span, msg); } } @@ -674,7 +674,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { Err(_) => { err.span_help( self.cast_span, - &format!("you might have meant `Box<{tstr}>`"), + format!("you might have meant `Box<{tstr}>`"), ); } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 507c24d540c..cfe8d59f737 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -601,7 +601,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { self.tcx, cause, self.fcx.param_env, - self.tcx.mk_trait_ref(coerce_unsized_did, [coerce_source, coerce_target]) + ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target]) )]; let mut has_unsized_tuple_coercion = false; @@ -707,9 +707,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { &self.tcx.sess.parse_sess, sym::trait_upcasting, self.cause.span, - &format!("cannot cast `{sub}` to `{sup}`, trait upcasting coercion is experimental"), + format!("cannot cast `{sub}` to `{sup}`, trait upcasting coercion is experimental"), ); - err.note(&format!("required when coercing `{source}` into `{target}`")); + err.note(format!("required when coercing `{source}` into `{target}`")); err.emit(); } @@ -764,8 +764,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { self.tcx, self.cause.clone(), self.param_env, - ty::Binder::dummy( - self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerLike, [a]), + ty::TraitRef::from_lang_item( + self.tcx, + hir::LangItem::PointerLike, + self.cause.span, + [a], ), )); @@ -1657,7 +1660,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { "the function expects a value to always be returned, but loops might run zero times", ); if MAXITER < ret_exprs.len() { - err.note(&format!( + err.note(format!( "if the loop doesn't execute, {} other values would never get returned", ret_exprs.len() - MAXITER )); @@ -1767,7 +1770,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { { err.span_note( sp, - &format!( + format!( "return type inferred to be `{}` here", expected ), @@ -1864,7 +1867,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { Applicability::MaybeIncorrect, ); } else { - err.help(&format!( + err.help(format!( "if the trait `{}` were object safe, you could return a boxed trait object", &snippet[5..] )); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index cfeb7f25533..9d59cdcbc60 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -543,13 +543,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We are pointing at the binding's type or initializer value, but it's pattern // is in a different line, so we point at both. err.span_label(secondary_span, "expected due to the type of this binding"); - err.span_label(primary_span, &format!("expected due to this{post_message}")); + err.span_label(primary_span, format!("expected due to this{post_message}")); } else if post_message == "" { // We are pointing at either the assignment lhs or the binding def pattern. err.span_label(primary_span, "expected due to the type of this binding"); } else { // We are pointing at the binding's type or initializer value. - err.span_label(primary_span, &format!("expected due to this{post_message}")); + err.span_label(primary_span, format!("expected due to this{post_message}")); } if !lhs.is_syntactic_place_expr() { @@ -566,7 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) if rhs.hir_id == expr.hir_id && self.typeck_results.borrow().expr_ty_adjusted_opt(lhs) == Some(expected) => { - err.span_label(lhs.span, &format!("expected because this is `{expected}`")); + err.span_label(lhs.span, format!("expected because this is `{expected}`")); } _ => {} } @@ -704,19 +704,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); err.span_note( path_span, - &format!( + format!( "the `{}` call is resolved to the method in `{container}`, shadowing {tail}", path.ident, ), ); if suggestions.len() > other_methods_in_scope.len() { - err.note(&format!( + err.note(format!( "additionally, there are {} other available methods that aren't in scope", suggestions.len() - other_methods_in_scope.len() )); } err.multipart_suggestions( - &format!( + format!( "you might have meant to call {}; you can use the fully-qualified path to call {} \ explicitly", if suggestions.len() == 1 { @@ -941,7 +941,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [(variant, ctor_kind, field_name, note)] => { // Just a single matching variant. err.multipart_suggestion_verbose( - &format!( + format!( "try wrapping the expression in `{variant}`{note}", note = note.as_deref().unwrap_or("") ), @@ -953,7 +953,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { // More than one matching variant. err.multipart_suggestions( - &format!( + format!( "try wrapping the expression in a variant of `{}`", self.tcx.def_path_str(expected_adt.did()) ), @@ -1726,7 +1726,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ]; (msg, suggestion) } else { - let msg = format!("{msg} and panic if the converted value doesn't fit"); + let msg = + format!("{} and panic if the converted value doesn't fit", msg.clone()); let mut suggestion = sugg.clone(); suggestion.push(( expr.span.shrink_to_hi(), @@ -1734,11 +1735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); (msg, suggestion) }; - err.multipart_suggestion_verbose( - &msg, - suggestion, - Applicability::MachineApplicable, - ); + err.multipart_suggestion_verbose(msg, suggestion, Applicability::MachineApplicable); }; let suggest_to_change_suffix_or_into = @@ -1755,13 +1752,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let always_fallible = found_to_exp_is_fallible && (exp_to_found_is_fallible || expected_ty_expr.is_none()); let msg = if literal_is_ty_suffixed(expr) { - &lit_msg + lit_msg.clone() } else if always_fallible && (is_negative_int(expr) && is_uint(expected_ty)) { // We now know that converting either the lhs or rhs is fallible. Before we // suggest a fallible conversion, check if the value can never fit in the // expected type. let msg = format!("`{src}` cannot fit into type `{expected_ty}`"); - err.note(&msg); + err.note(msg); return; } else if in_const_context { // Do not recommend `into` or `try_into` in const contexts. @@ -1769,7 +1766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if found_to_exp_is_fallible { return suggest_fallible_into_or_lhs_from(err, exp_to_found_is_fallible); } else { - &msg + msg.clone() }; let suggestion = if literal_is_ty_suffixed(expr) { suffix_suggestion.clone() @@ -1831,14 +1828,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { suggest_to_change_suffix_or_into(err, false, true); } else if literal_is_ty_suffixed(expr) { err.multipart_suggestion_verbose( - &lit_msg, + lit_msg, suffix_suggestion, Applicability::MachineApplicable, ); } else if can_cast { // Missing try_into implementation for `f64` to `f32` err.multipart_suggestion_verbose( - &format!("{cast_msg}, producing the closest possible value"), + format!("{cast_msg}, producing the closest possible value"), cast_suggestion, Applicability::MaybeIncorrect, // lossy conversion ); @@ -1848,14 +1845,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (&ty::Uint(_) | &ty::Int(_), &ty::Float(_)) => { if literal_is_ty_suffixed(expr) { err.multipart_suggestion_verbose( - &lit_msg, + lit_msg, suffix_suggestion, Applicability::MachineApplicable, ); } else if can_cast { // Missing try_into implementation for `{float}` to `{integer}` err.multipart_suggestion_verbose( - &format!("{msg}, rounding the float towards zero"), + format!("{msg}, rounding the float towards zero"), cast_suggestion, Applicability::MaybeIncorrect, // lossy conversion ); @@ -1866,7 +1863,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // if `found` is `None` (meaning found is `usize`), don't suggest `.into()` if exp.bit_width() > found.bit_width().unwrap_or(256) { err.multipart_suggestion_verbose( - &format!( + format!( "{msg}, producing the floating point representation of the integer", ), into_suggestion, @@ -1874,14 +1871,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } else if literal_is_ty_suffixed(expr) { err.multipart_suggestion_verbose( - &lit_msg, + lit_msg, suffix_suggestion, Applicability::MachineApplicable, ); } else { // Missing try_into implementation for `{integer}` to `{float}` err.multipart_suggestion_verbose( - &format!( + format!( "{cast_msg}, producing the floating point representation of the integer, \ rounded if necessary", ), @@ -1895,23 +1892,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // if `found` is `None` (meaning found is `isize`), don't suggest `.into()` if exp.bit_width() > found.bit_width().unwrap_or(256) { err.multipart_suggestion_verbose( - &format!( + format!( "{}, producing the floating point representation of the integer", - &msg, + msg.clone(), ), into_suggestion, Applicability::MachineApplicable, ); } else if literal_is_ty_suffixed(expr) { err.multipart_suggestion_verbose( - &lit_msg, + lit_msg, suffix_suggestion, Applicability::MachineApplicable, ); } else { // Missing try_into implementation for `{integer}` to `{float}` err.multipart_suggestion_verbose( - &format!( + format!( "{}, producing the floating point representation of the integer, \ rounded if necessary", &msg, @@ -1928,7 +1925,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &ty::Char, ) => { err.multipart_suggestion_verbose( - &format!("{cast_msg}, since a `char` always occupies 4 bytes"), + format!("{cast_msg}, since a `char` always occupies 4 bytes"), cast_suggestion, Applicability::MachineApplicable, ); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 3ffc583d43f..bba049c3819 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1426,6 +1426,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_repeat_element_needs_copy_bound(element, count, element_ty); + self.register_wf_obligation( + tcx.mk_array_with_const_len(t, count).into(), + expr.span, + traits::WellFormed(None), + ); + tcx.mk_array_with_const_len(t, count) } @@ -1944,12 +1950,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { private_fields: Vec<&ty::FieldDef>, used_fields: &'tcx [hir::ExprField<'tcx>], ) { - let mut err = self.tcx.sess.struct_span_err( - span, - &format!( - "cannot construct `{adt_ty}` with struct literal syntax due to private fields", - ), - ); + let mut err = + self.tcx.sess.struct_span_err( + span, + format!( + "cannot construct `{adt_ty}` with struct literal syntax due to private fields", + ), + ); let (used_private_fields, remaining_private_fields): ( Vec<(Symbol, Span, bool)>, Vec<(Symbol, Span, bool)>, @@ -2045,7 +2052,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(field.ident.span, "field does not exist"); err.span_suggestion_verbose( expr_span, - &format!( + format!( "`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax", adt = ty, variant = variant.name, @@ -2063,7 +2070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(field.ident.span, "field does not exist"); err.span_suggestion_verbose( expr_span, - &format!( + format!( "`{adt}` is a tuple {kind_name}, use the appropriate syntax", adt = ty, kind_name = kind_name, @@ -2105,7 +2112,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let available_field_names = self.available_field_names(variant, expr_span); if !available_field_names.is_empty() { - err.note(&format!( + err.note(format!( "available fields are: {}", self.name_series_display(available_field_names) )); @@ -2384,7 +2391,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } if add_label { - err.span_label(field_ident.span, &format!("field not found in `{ty}`")); + err.span_label(field_ident.span, format!("field not found in `{ty}`")); } } @@ -2565,7 +2572,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let param_span = self.tcx.hir().span(param_hir_id); let param_name = self.tcx.hir().ty_param_name(param_def_id.expect_local()); - err.span_label(param_span, &format!("type parameter '{param_name}' declared here")); + err.span_label(param_span, format!("type parameter '{param_name}' declared here")); } fn suggest_fields_on_recordish( @@ -2589,7 +2596,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let struct_variant_def = def.non_enum_variant(); let field_names = self.available_field_names(struct_variant_def, access_span); if !field_names.is_empty() { - err.note(&format!( + err.note(format!( "available fields are: {}", self.name_series_display(field_names), )); @@ -2630,7 +2637,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { let msg = format!("`{base}` is a raw pointer; try dereferencing it"); let suggestion = format!("(*{base}).{field}"); - err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect); + err.span_suggestion(expr.span, msg, suggestion, Applicability::MaybeIncorrect); } } @@ -2821,7 +2828,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // but has nested obligations which are unsatisfied. for (base_t, _) in self.autoderef(base.span, base_t).silence_errors() { if let Some((_, index_ty, element_ty)) = - self.find_and_report_unsatisfied_index_impl(expr.hir_id, base, base_t) + self.find_and_report_unsatisfied_index_impl(base, base_t) { self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No); return element_ty; @@ -2880,7 +2887,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// predicates cause this to be, so that the user can add them to fix their code. fn find_and_report_unsatisfied_index_impl( &self, - index_expr_hir_id: HirId, base_expr: &hir::Expr<'_>, base_ty: Ty<'tcx>, ) -> Option<(ErrorGuaranteed, Ty<'tcx>, Ty<'tcx>)> { @@ -2913,13 +2919,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // in the first place. ocx.register_obligations(traits::predicates_for_generics( |idx, span| { - traits::ObligationCause::new( - base_expr.span, - self.body_id, - if span.is_dummy() { - traits::ExprItemObligation(impl_def_id, index_expr_hir_id, idx) - } else { - traits::ExprBindingObligation(impl_def_id, span, index_expr_hir_id, idx) + cause.clone().derived_cause( + ty::Binder::dummy(ty::TraitPredicate { + trait_ref: impl_trait_ref, + polarity: ty::ImplPolarity::Positive, + constness: ty::BoundConstness::NotConst, + }), + |derived| { + traits::ImplDerivedObligation(Box::new( + traits::ImplDerivedObligationCause { + derived, + impl_or_alias_def_id: impl_def_id, + impl_def_predicate_index: Some(idx), + span, + }, + )) }, ) }, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2b5af4bc81b..9e78e6acba5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -63,9 +63,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::UNREACHABLE_CODE, id, span, - &msg, + msg.clone(), |lint| { - lint.span_label(span, &msg).span_label( + lint.span_label(span, msg).span_label( orig_span, custom_note .unwrap_or("any code following this expression is unreachable"), @@ -275,7 +275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { self.tcx.sess.delay_span_bug( expr.span, - &format!( + format!( "while adjusting {:?}, can't compose {:?} and {:?}", expr, entry.get(), @@ -854,9 +854,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = self .resolve_fully_qualified_call(span, item_name, ty.normalized, qself.span, hir_id) .or_else(|error| { + let guar = self + .tcx + .sess + .delay_span_bug(span, "method resolution should've emitted an error"); let result = match error { method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)), - _ => Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()), + _ => Err(guar), }; // If we have a path like `MyTrait::missing_method`, then don't register @@ -1034,15 +1038,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr.span, "you probably want to use this value after calling the method...", ); - err.span_note(sp, &modifies_rcvr_note); - err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident)); + err.span_note(sp, modifies_rcvr_note); + err.note(format!("...instead of the `()` output of method `{}`", path_segment.ident)); } else if let ExprKind::MethodCall(..) = rcvr.kind { err.span_note( sp, modifies_rcvr_note.clone() + ", it is not meant to be used in method chains.", ); } else { - err.span_note(sp, &modifies_rcvr_note); + err.span_note(sp, modifies_rcvr_note); } } @@ -1374,7 +1378,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(_) => { self.tcx.sess.delay_span_bug( span, - &format!( + format!( "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?", self_ty, impl_ty, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 56c94505727..70ce45e21ea 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -481,7 +481,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // For the purposes of this function, we hope that it is a `struct` type, and that our current `expr` is a literal of // that struct type. let impl_trait_self_ref = if self.tcx.is_trait_alias(obligation.impl_or_alias_def_id) { - self.tcx.mk_trait_ref( + ty::TraitRef::new( + self.tcx, obligation.impl_or_alias_def_id, ty::InternalSubsts::identity_for_item(self.tcx, obligation.impl_or_alias_def_id), ) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index e620aa6a291..c7011b23a7d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -685,7 +685,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err = tcx.sess.struct_span_err_with_code( full_call_span, - &format!( + format!( "{call_name} takes {}{} but {} {} supplied", if c_variadic { "at least " } else { "" }, potentially_plural_count( @@ -828,7 +828,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { tcx.sess.struct_span_err_with_code( full_call_span, - &format!( + format!( "this {} takes {}{} but {} {} supplied", call_name, if c_variadic { "at least " } else { "" }, @@ -1203,7 +1203,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } SuggestionText::Remove(plural) => { err.multipart_suggestion( - &format!("remove the extra argument{}", if plural { "s" } else { "" }), + format!("remove the extra argument{}", if plural { "s" } else { "" }), suggestions, Applicability::HasPlaceholders, ); @@ -1253,7 +1253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { suggestion += ")"; err.span_suggestion_verbose( suggestion_span, - &suggestion_text, + suggestion_text, suggestion, Applicability::HasPlaceholders, ); @@ -1300,6 +1300,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { opt_ty.unwrap_or_else(|| self.next_float_var()) } ast::LitKind::Bool(_) => tcx.types.bool, + ast::LitKind::CStr(_, _) => tcx.mk_imm_ref( + tcx.lifetimes.re_static, + tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, Some(lit.span))) + .skip_binder(), + ), ast::LitKind::Err => tcx.ty_error_misc(), } } @@ -1903,7 +1908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { // Look for a user-provided impl of a `Fn` trait, and point to it. let new_def_id = self.probe(|_| { - let trait_ref = self.tcx.mk_trait_ref( + let trait_ref = ty::TraitRef::new(self.tcx, call_kind.to_def_id(self.tcx), [ callee_ty, @@ -1955,7 +1960,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { spans.push_span_label(param.span, ""); } - err.span_note(spans, &format!("{} defined here", self.tcx.def_descr(def_id))); + err.span_note(spans, format!("{} defined here", self.tcx.def_descr(def_id))); } else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id) && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind { @@ -1966,11 +1971,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { ("closure", self.tcx.def_span(def_id)) }; - err.span_note(span, &format!("{} defined here", kind)); + err.span_note(span, format!("{} defined here", kind)); } else { err.span_note( self.tcx.def_span(def_id), - &format!("{} defined here", self.tcx.def_descr(def_id)), + format!("{} defined here", self.tcx.def_descr(def_id)), ); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 3f95027d3b8..2867fcc8ecd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -279,9 +279,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_ref(expr, found, expected) { if verbose { - err.span_suggestion_verbose(sp, &msg, suggestion, applicability); + err.span_suggestion_verbose(sp, msg, suggestion, applicability); } else { - err.span_suggestion(sp, &msg, suggestion, applicability); + err.span_suggestion(sp, msg, suggestion, applicability); } if annotation { let suggest_annotation = match expr.peel_drop_temps().kind { @@ -1096,10 +1096,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx, self.misc(expr.span), self.param_env, - ty::Binder::dummy(self.tcx.mk_trait_ref( + ty::TraitRef::new(self.tcx, into_def_id, [expr_ty, expected_ty] - )), + ), )) { let sugg = if expr.precedence().order() >= PREC_POSTFIX { @@ -1438,7 +1438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && !results.expr_adjustments(callee_expr).iter().any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(..))) // Check that we're in fact trying to clone into the expected type && self.can_coerce(*pointee_ty, expected_ty) - && let trait_ref = ty::Binder::dummy(self.tcx.mk_trait_ref(clone_trait_did, [expected_ty])) + && let trait_ref = ty::TraitRef::new(self.tcx, clone_trait_did, [expected_ty]) // And the expected type doesn't implement `Clone` && !self.predicate_must_hold_considering_regions(&traits::Obligation::new( self.tcx, @@ -1449,7 +1449,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { diag.span_note( callee_expr.span, - &format!( + format!( "`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead" ), ); diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs index 5136d895f22..8ab0bd535d6 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -205,7 +205,7 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { if ty.has_infer() { self.tcx.sess.delay_span_bug( self.tcx.hir().span(assignee_place.hir_id), - &format!("inference variables in {ty}"), + format!("inference variables in {ty}"), ); } else if ty.needs_drop(self.tcx, self.param_env) { self.places diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 915280a5bea..019fb86f55c 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -112,7 +112,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { self.fcx .tcx .sess - .delay_span_bug(span, &format!("Encountered var {:?}", unresolved_term)); + .delay_span_bug(span, format!("Encountered var {:?}", unresolved_term)); } else { let note = format!( "the type is part of the {} because of this {}", @@ -464,7 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { self.fcx .tcx .sess - .delay_span_bug(expr.span, &format!("inference variables in {ty}")); + .delay_span_bug(expr.span, format!("inference variables in {ty}")); true } else { ty.needs_drop(self.fcx.tcx, self.fcx.param_env) diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 2ad79cd85b1..3c5eafd9484 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -72,8 +72,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let from = unpack_option_like(tcx, from); if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer(dl.instruction_address_space).size(&tcx) { struct_span_err!(tcx.sess, span, E0591, "can't transmute zero-sized type") - .note(&format!("source type: {from}")) - .note(&format!("target type: {to}")) + .note(format!("source type: {from}")) + .note(format!("target type: {to}")) .help("cast with `as` to a pointer instead") .emit(); return; @@ -109,10 +109,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { or dependently-sized types" ); if from == to { - err.note(&format!("`{from}` does not have a fixed size")); + err.note(format!("`{from}` does not have a fixed size")); } else { - err.note(&format!("source type: `{}` ({})", from, skeleton_string(from, sk_from))) - .note(&format!("target type: `{}` ({})", to, skeleton_string(to, sk_to))); + err.note(format!("source type: `{}` ({})", from, skeleton_string(from, sk_from))) + .note(format!("target type: `{}` ({})", to, skeleton_string(to, sk_to))); let mut should_delay_as_bug = false; if let Err(LayoutError::Unknown(bad_from)) = sk_from && bad_from.references_error() { should_delay_as_bug = true; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index d50be47c915..a2a4362e2f5 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -448,7 +448,7 @@ fn fatally_break_rust(sess: &Session) { "we would appreciate a joke overview: \ https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675", ); - handler.note_without_error(&format!( + handler.note_without_error(format!( "rustc {} running on {}", option_env!("CFG_VERSION").unwrap_or("unknown_version"), config::host_triple(), diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index fab9a8a5f4f..5963a1632c5 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -316,7 +316,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.var_for_def(cause.span, param) }); - let trait_ref = self.tcx.mk_trait_ref(trait_def_id, substs); + let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, substs); // Construct an obligation let poly_trait_ref = ty::Binder::dummy(trait_ref); diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 3d6c2119bea..ec4e7f7f88a 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; lint.span_help( sp, - &format!("disambiguate the method call with `({})`", self_adjusted,), + format!("disambiguate the method call with `({})`", self_adjusted,), ); } @@ -180,7 +180,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { lint.span_help( sp, - &format!( + format!( "disambiguate the associated function with `{}::{}(...)`", trait_name, segment.ident, ), diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 1a429142e01..483e17460b3 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -954,7 +954,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ) { debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id); let trait_substs = self.fresh_item_substs(trait_def_id); - let trait_ref = self.tcx.mk_trait_ref(trait_def_id, trait_substs); + let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, trait_substs); if self.tcx.is_trait_alias(trait_def_id) { // For trait aliases, recursively assume all explicitly named traits are relevant @@ -1396,7 +1396,7 @@ impl<'tcx> Pick<'tcx> { // However `self.span` only // highlights the method name, so we can't use it. Also consider reusing // the code from `report_method_error()`. - lint.help(&format!( + lint.help(format!( "call with fully qualified syntax `{}(...)` to keep using the current \ method", tcx.def_path_str(self.item.def_id), @@ -1420,7 +1420,7 @@ impl<'tcx> Pick<'tcx> { } if tcx.sess.is_nightly_build() { for (candidate, feature) in &self.unstable_candidates { - lint.help(&format!( + lint.help(format!( "add `#![feature({})]` to the crate attributes to enable `{}`", feature, tcx.def_path_str(candidate.item.def_id), diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 43f40ada5ac..30f0978d190 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -72,7 +72,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.autoderef(span, ty).any(|(ty, _)| { info!("check deref {:?} impl FnOnce", ty); self.probe(|_| { - let trait_ref = tcx.mk_trait_ref( + let trait_ref = ty::TraitRef::new( + tcx, fn_once, [ ty, @@ -169,13 +170,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind, item_name ); - err.span_label(item_name.span, &format!("private {}", kind)); + err.span_label(item_name.span, format!("private {}", kind)); let sp = self .tcx .hir() .span_if_local(def_id) .unwrap_or_else(|| self.tcx.def_span(def_id)); - err.span_label(sp, &format!("private {} defined here", kind)); + err.span_label(sp, format!("private {} defined here", kind)); self.suggest_valid_traits(&mut err, out_of_scope_traits); err.emit(); } @@ -188,7 +189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { format!("the `{item_name}` method cannot be invoked on a trait object") }; - let mut err = self.sess().struct_span_err(span, &msg); + let mut err = self.sess().struct_span_err(span, msg); if !needs_mut { err.span_label(bound_span, "this has a `Sized` requirement"); } @@ -228,12 +229,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.span_suggestion_verbose( mut_ty.ty.span.shrink_to_lo(), - &msg, + msg, "mut ", Applicability::MachineApplicable, ); } else { - err.help(&msg); + err.help(msg); } } } @@ -374,14 +375,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty_str }; if let Some(file) = ty_file { - err.note(&format!("the full type name has been written to '{}'", file.display(),)); + err.note(format!("the full type name has been written to '{}'", file.display(),)); } if rcvr_ty.references_error() { err.downgrade_to_delayed_bug(); } if tcx.ty_is_opaque_future(rcvr_ty) && item_name.name == sym::poll { - err.help(&format!( + err.help(format!( "method `poll` found on `Pin<&mut {ty_str}>`, \ see documentation for `std::pin::Pin`" )); @@ -510,7 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) { let iterator_trait = self.tcx.def_path_str(iterator_trait); - err.note(&format!( + err.note(format!( "`count` is defined on `{iterator_trait}`, which `{rcvr_ty}` does not implement" )); } @@ -810,7 +811,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (sp, label) in span_labels { span.push_span_label(sp, label); } - err.span_note(span, &msg); + err.span_note(span, msg); unsatisfied_bounds = true; } @@ -867,7 +868,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { obligations.sort(); err.span_suggestion_verbose( span, - &format!( + format!( "consider restricting the type parameter{s} to satisfy the \ trait bound{s}", s = pluralize!(obligations.len()) @@ -912,13 +913,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { but its trait bounds were not satisfied" ) }); - err.set_primary_message(&primary_message); + err.set_primary_message(primary_message); if let Some(label) = label { custom_span_label = true; err.span_label(span, label); } if !bound_list.is_empty() { - err.note(&format!( + err.note(format!( "the following trait bounds were not satisfied:\n{bound_list}" )); } @@ -1002,7 +1003,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { "".to_string() }; - err.note(&format!( + err.note(format!( "the {item_kind} was found for\n{}{}", type_candidates, additional_types )); @@ -1049,7 +1050,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bound_spans.sort(); bound_spans.dedup(); for (span, msg) in bound_spans.into_iter() { - err.span_label(span, &msg); + err.span_label(span, msg); } if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params { @@ -1119,7 +1120,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.span_suggestion( span, - &format!( + format!( "there is {} {} with a similar name", self.tcx.def_kind_descr_article(def_kind, similar_candidate.def_id), self.tcx.def_kind_descr(def_kind, similar_candidate.def_id) @@ -1203,9 +1204,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if let Some(note_span) = note_span { // We have a span pointing to the method. Show note with snippet. - err.span_note(note_span, ¬e_str); + err.span_note(note_span, note_str); } else { - err.note(¬e_str); + err.note(note_str); } if let Some(sugg_span) = sugg_span && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { @@ -1243,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let Some(item) = self.associated_value(trait_did, item_name) else { continue }; let item_span = self.tcx.def_span(item.def_id); let idx = if sources.len() > 1 { - let msg = &format!( + let msg = format!( "candidate #{} is defined in the trait `{}`", idx + 1, self.tcx.def_path_str(trait_did) @@ -1251,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_note(item_span, msg); Some(idx + 1) } else { - let msg = &format!( + let msg = format!( "the candidate is defined in the trait `{}`", self.tcx.def_path_str(trait_did) ); @@ -1278,7 +1279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } if sources.len() > limit { - err.note(&format!("and {} others", sources.len() - limit)); + err.note(format!("and {} others", sources.len() - limit)); } } @@ -1402,7 +1403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { applicability, ); } else { - err.help(&format!("try with `{}::{}`", ty_str, item_name,)); + err.help(format!("try with `{}::{}`", ty_str, item_name,)); } } @@ -1436,7 +1437,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.is_fn_ty(field_ty, span) { let expr_span = expr.span.to(item_name.span); err.multipart_suggestion( - &format!( + format!( "to call the function stored in `{}`, \ surround the field access with parentheses", item_name, @@ -1612,7 +1613,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let snippet = snippet.strip_suffix('.').unwrap_or(&snippet); err.span_suggestion( lit.span, - &format!( + format!( "you must specify a concrete type for this numeric value, \ like `{}`", concrete_type @@ -1648,7 +1649,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // account for `let x: _ = 42;` // ^^^ type_span, - &msg, + msg, format!(": {concrete_type}"), Applicability::MaybeIncorrect, ); @@ -1861,7 +1862,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let self_ty = field.ty(tcx, substs); err.span_note( tcx.def_span(pick.item.def_id), - &format!("the method `{item_name}` exists on the type `{self_ty}`"), + format!("the method `{item_name}` exists on the type `{self_ty}`"), ); let (article, kind, variant, question) = if tcx.is_diagnostic_item(sym::Result, kind.did()) { @@ -1975,7 +1976,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_note( tcx.def_span(pick.item.def_id), - &format!("the method `{item_name}` exists on the type `{ty}`"), + format!("the method `{item_name}` exists on the type `{ty}`"), ); } } @@ -2046,7 +2047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pluralize!(preds.len()), ) }; - err.span_note(spans, &msg); + err.span_note(spans, msg); } let preds: Vec<_> = errors @@ -2160,14 +2161,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } err.span_note( span, - &format!("the trait{} {} must be implemented", pluralize!(len), names), + format!("the trait{} {} must be implemented", pluralize!(len), names), ); } for (self_name, self_span, traits) in &derives_grouped { err.span_suggestion_verbose( self_span.shrink_to_lo(), - &format!("consider annotating `{}` with `#[derive({})]`", self_name, traits), + format!("consider annotating `{}` with `#[derive({})]`", self_name, traits), format!("#[derive({})]\n", traits), Applicability::MaybeIncorrect, ); @@ -2313,7 +2314,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestions( span, - &msg, + msg, path_strings.chain(glob_path_strings), Applicability::MaybeIncorrect, ); @@ -2345,7 +2346,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.suggest_use_candidates(err, msg, candidates); if let Some(did) = edition_fix { - err.note(&format!( + err.note(format!( "'{}' is included in the prelude starting in Edition 2021", with_crate_prefix!(self.tcx.def_path_str(did)) )); @@ -2413,7 +2414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if pick.autoderefs == 0 && !skip { err.span_label( pick.item.ident(self.tcx).span, - &format!("the method is available for `{}` here", rcvr_ty), + format!("the method is available for `{}` here", rcvr_ty), ); } break; @@ -2459,7 +2460,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if pick.autoderefs == 0 && !skip { err.span_label( pick.item.ident(self.tcx).span, - &format!("the method is available for `{}` here", new_rcvr_t), + format!("the method is available for `{}` here", new_rcvr_t), ); err.multipart_suggestion( "consider wrapping the receiver expression with the \ @@ -2655,7 +2656,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) { err.span_suggestions( sp, - &message(format!( + message(format!( "restrict type parameter `{}` with", param.name.ident(), )), @@ -2687,7 +2688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; err.span_suggestions( sp, - &message(format!("add {} supertrait for", article)), + message(format!("add {} supertrait for", article)), candidates.iter().map(|t| { format!("{} {}", sep, self.tcx.def_path_str(t.def_id),) }), @@ -2746,7 +2747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [trait_info] if trait_info.def_id.is_local() => { err.span_note( self.tcx.def_span(trait_info.def_id), - &format!( + format!( "`{}` defines an item `{}`, perhaps you need to {} it", self.tcx.def_path_str(trait_info.def_id), item_name, @@ -2763,7 +2764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.def_path_str(trait_info.def_id), )); } - err.note(&msg); + err.note(msg); } } match &explicitly_negative[..] { @@ -2774,7 +2775,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.def_path_str(trait_info.def_id), item_name ); - err.note(&msg); + err.note(msg); } trait_infos => { let mut msg = format!( @@ -2784,7 +2785,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for trait_info in trait_infos { msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id))); } - err.note(&msg); + err.note(msg); } } } @@ -2836,7 +2837,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_args.len() == args.len() + 1 { err.span_suggestion_verbose( method_name.span.shrink_to_hi(), - &format!("try calling `{}` instead", new_name.name.as_str()), + format!("try calling `{}` instead", new_name.name.as_str()), "_else", Applicability::MaybeIncorrect, ); @@ -2956,7 +2957,7 @@ fn print_disambiguation_help<'tcx>( }; err.span_suggestion_verbose( span, - &format!( + format!( "disambiguate the {} for {}", def_kind_descr, if let Some(candidate) = candidate { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index e91ae4466eb..af351a3fa10 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -390,7 +390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) .is_ok() { - let msg = &format!( + let msg = format!( "`{}{}` can be used on `{}` if you dereference the left-hand side", op.node.as_str(), match is_assign { @@ -515,7 +515,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // When we know that a missing bound is responsible, we don't show // this note as it is redundant. - err.note(&format!( + err.note(format!( "the trait `{missing_trait}` is not implemented for `{lhs_ty}`" )); } @@ -690,7 +690,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.span_suggestion( ex.span, - &format!( + format!( "you may have meant the maximum value of `{actual}`", ), format!("{actual}::MAX"), diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index d69a16d45ae..5af955d3134 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -517,7 +517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn endpoint_has_type(&self, err: &mut Diagnostic, span: Span, ty: Ty<'_>) { if !ty.references_error() { - err.span_label(span, &format!("this is of type `{}`", ty)); + err.span_label(span, format!("this is of type `{}`", ty)); } } @@ -544,7 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("this is of type `{}` but it should be `char` or numeric", ty) }; let mut one_side_err = |first_span, first_ty, second: Option<(bool, Ty<'tcx>, Span)>| { - err.span_label(first_span, &msg(first_ty)); + err.span_label(first_span, msg(first_ty)); if let Some((_, ty, sp)) = second { let ty = self.resolve_vars_if_possible(ty); self.endpoint_has_type(&mut err, sp, ty); @@ -552,8 +552,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; match (lhs, rhs) { (Some((true, lhs_ty, lhs_sp)), Some((true, rhs_ty, rhs_sp))) => { - err.span_label(lhs_sp, &msg(lhs_ty)); - err.span_label(rhs_sp, &msg(rhs_ty)); + err.span_label(lhs_sp, msg(lhs_ty)); + err.span_label(rhs_sp, msg(rhs_ty)); } (Some((true, lhs_ty, lhs_sp)), rhs) => one_side_err(lhs_sp, lhs_ty, rhs), (lhs, Some((true, rhs_ty, rhs_sp))) => one_side_err(rhs_sp, rhs_ty, lhs), @@ -651,7 +651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }); let pre = if in_match { "in the same arm, " } else { "" }; - err.note(&format!("{}a binding must have the same type in all alternatives", pre)); + err.note(format!("{}a binding must have the same type in all alternatives", pre)); self.suggest_adding_missing_ref_or_removing_ref( &mut err, span, @@ -958,11 +958,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let pat_span = pat.span; if let Some(span) = self.tcx.hir().res_span(pat_res) { - e.span_label(span, &format!("{} defined here", res.descr())); + e.span_label(span, format!("{} defined here", res.descr())); if let [hir::PathSegment { ident, .. }] = &*segments { e.span_label( pat_span, - &format!( + format!( "`{}` is interpreted as {} {}, not a new binding", ident, res.article(), @@ -1158,7 +1158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.span_label( last_subpat_span, - &format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len()), + format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len()), ); if self.tcx.sess.source_map().is_multiline(qpath.span().between(last_subpat_span)) { err.span_label(qpath.span(), ""); @@ -1171,7 +1171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } err.span_label( last_field_def_span, - &format!("{} has {} field{}", res.descr(), fields.len(), fields_ending), + format!("{} has {} field{}", res.descr(), fields.len(), fields_ending), ); // Identify the case `Some(x, y)` where the expected type is e.g. `Option<(T, U)>`. @@ -1641,7 +1641,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let unmentioned_field = unmentioned_fields[0].1.name; err.span_suggestion_short( pat_field.ident.span, - &format!( + format!( "`{}` has a field named `{}`", tcx.def_path_str(variant.def_id), unmentioned_field @@ -1831,7 +1831,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint.help( "ensure that all fields are mentioned explicitly by adding the suggested fields", ); - lint.note(&format!( + lint.note(format!( "the pattern is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found", ty, )); @@ -1895,7 +1895,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; err.span_suggestion( sp, - &format!( + format!( "include the missing field{} in the pattern{}", pluralize!(len), if have_inaccessible_fields { " and ignore the inaccessible fields" } else { "" } @@ -1922,7 +1922,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.span_suggestion( sp, - &format!( + format!( "if you don't care about {these} missing field{s}, you can explicitly ignore {them}", these = pluralize!("this", len), s = pluralize!(len), diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 1f7e7ba9f5b..f217c5c1e1c 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -73,16 +73,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.resolve_vars_if_possible(ty); let mut err = self.tcx.sess.struct_span_err( span, - &format!("negative integers cannot be used to index on a `{ty}`"), + format!("negative integers cannot be used to index on a `{ty}`"), ); - err.span_label(span, &format!("cannot use a negative integer for indexing on `{ty}`")); + err.span_label(span, format!("cannot use a negative integer for indexing on `{ty}`")); if let (hir::ExprKind::Path(..), Ok(snippet)) = (&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span)) { // `foo[-1]` to `foo[foo.len() - 1]` err.span_suggestion_verbose( span.shrink_to_lo(), - &format!( + format!( "to access an element starting from the end of the `{ty}`, compute the index", ), format!("{snippet}.len() "), diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 147b3e74d0f..543194ac9d6 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -713,7 +713,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.sess.delay_span_bug( closure_span, - &format!( + format!( "two identical projections: ({:?}, {:?})", capture1.place.projections, capture2.place.projections ), @@ -863,7 +863,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let indent = line2.split_once(|c: char| !c.is_whitespace()).unwrap_or_default().0; lint.span_suggestion( closure_body_span.with_lo(closure_body_span.lo() + BytePos::from_usize(line1.len())).shrink_to_lo(), - &diagnostic_msg, + diagnostic_msg, format!("\n{indent}{migration_string};"), Applicability::MachineApplicable, ); @@ -874,7 +874,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // directly after the `{`. lint.span_suggestion( closure_body_span.with_lo(closure_body_span.lo() + BytePos(1)).shrink_to_lo(), - &diagnostic_msg, + diagnostic_msg, format!(" {migration_string};"), Applicability::MachineApplicable, ); @@ -882,7 +882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This is a closure without braces around the body. // We add braces to add the `let` before the body. lint.multipart_suggestion( - &diagnostic_msg, + diagnostic_msg, vec![ (closure_body_span.shrink_to_lo(), format!("{{ {migration_string}; ")), (closure_body_span.shrink_to_hi(), " }".to_string()), @@ -893,7 +893,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { lint.span_suggestion( closure_span, - &diagnostic_msg, + diagnostic_msg, migration_string, Applicability::HasPlaceholders ); @@ -1519,7 +1519,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let span = capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir().span(e)); - diag.span_note(span, &output_str); + diag.span_note(span, output_str); } diag.emit(); } @@ -1560,13 +1560,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { multi_span.push_span_label(path_span, path_label); multi_span.push_span_label(capture_kind_span, capture_kind_label); - diag.span_note(multi_span, &output_str); + diag.span_note(multi_span, output_str); } else { let span = capture_info .path_expr_id .map_or(closure_span, |e| self.tcx.hir().span(e)); - diag.span_note(span, &output_str); + diag.span_note(span, output_str); }; } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 817918257be..cf95d4f04bb 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -227,7 +227,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // When encountering `return [0][0]` outside of a `fn` body we can encounter a base // that isn't in the type table. We assume more relevant errors have already been // emitted, so we delay an ICE if none have. (#64638) - self.tcx().sess.delay_span_bug(e.span, &format!("bad base: `{:?}`", base)); + self.tcx().sess.delay_span_bug(e.span, format!("bad base: `{:?}`", base)); } if let Some(ty::Ref(_, base_ty, _)) = base_ty { let index_ty = typeck_results.expr_ty_adjusted_opt(index).unwrap_or_else(|| { @@ -491,7 +491,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let err = self .tcx() .sess - .struct_span_err(span, &format!("user substs: {:?}", user_substs)); + .struct_span_err(span, format!("user substs: {:?}", user_substs)); err.buffer(&mut errors_buffer); } } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index ec6d61f9e5f..e3c688b3e98 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -346,7 +346,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) { let mut new_sub_dir_name = String::from(&old_sub_dir_name[..=dash_indices[2]]); // Append the svh - base_n::push_str(svh.as_u64() as u128, INT_ENCODE_BASE, &mut new_sub_dir_name); + base_n::push_str(svh.as_u128(), INT_ENCODE_BASE, &mut new_sub_dir_name); // Create the full path let new_path = incr_comp_session_dir.parent().unwrap().join(new_sub_dir_name); diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index d240d8e491f..0c8854e962a 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -30,8 +30,6 @@ use super::*; use rustc_middle::ty::relate::{Relate, TypeRelation}; use rustc_middle::ty::{Const, ImplSubject}; -use std::cell::Cell; - /// Whether we should define opaque types or just treat them opaquely. /// /// Currently only used to prevent predicate matching from matching anything @@ -84,7 +82,6 @@ impl<'tcx> InferCtxt<'tcx> { in_snapshot: self.in_snapshot.clone(), universe: self.universe.clone(), intercrate: self.intercrate, - inside_canonicalization_ctxt: Cell::new(self.inside_canonicalization_ctxt()), } } } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index c29f652034f..427d05c8b4d 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -205,7 +205,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { // `delay_span_bug` to allow type error over an ICE. canonicalizer.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, - &format!("unexpected region in query response: `{:?}`", r), + format!("unexpected region in query response: `{:?}`", r), ); r } @@ -561,8 +561,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { where V: TypeFoldable<TyCtxt<'tcx>>, { - let _inside_canonical_ctxt_guard = infcx.set_canonicalization_ctxt(); - let needs_canonical_flags = if canonicalize_region_mode.any() { TypeFlags::HAS_INFER | TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS` diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 9b670c76a18..2a51439b0a9 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -73,6 +73,8 @@ impl<'tcx> InferCtxt<'tcx> { R: ObligationEmittingRelation<'tcx>, { let a_is_expected = relation.a_is_expected(); + debug_assert!(!a.has_escaping_bound_vars()); + debug_assert!(!b.has_escaping_bound_vars()); match (a.kind(), b.kind()) { // Relate integral variables to other types @@ -163,6 +165,8 @@ impl<'tcx> InferCtxt<'tcx> { R: ObligationEmittingRelation<'tcx>, { debug!("{}.consts({:?}, {:?})", relation.tag(), a, b); + debug_assert!(!a.has_escaping_bound_vars()); + debug_assert!(!b.has_escaping_bound_vars()); if a == b { return Ok(a); } @@ -192,7 +196,7 @@ impl<'tcx> InferCtxt<'tcx> { self.tcx.check_tys_might_be_eq(canonical).map_err(|_| { self.tcx.sess.delay_span_bug( DUMMY_SP, - &format!("cannot relate consts of different types (a={:?}, b={:?})", a, b,), + format!("cannot relate consts of different types (a={:?}, b={:?})", a, b,), ) }) }); @@ -238,22 +242,12 @@ impl<'tcx> InferCtxt<'tcx> { (_, ty::ConstKind::Infer(InferConst::Var(vid))) => { return self.unify_const_variable(vid, a); } - (ty::ConstKind::Unevaluated(..), _) if self.tcx.lazy_normalization() => { - // FIXME(#59490): Need to remove the leak check to accommodate - // escaping bound variables here. - if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { - relation.register_const_equate_obligation(a, b); - } + (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..)) + if self.tcx.lazy_normalization() => + { + relation.register_const_equate_obligation(a, b); return Ok(b); } - (_, ty::ConstKind::Unevaluated(..)) if self.tcx.lazy_normalization() => { - // FIXME(#59490): Need to remove the leak check to accommodate - // escaping bound variables here. - if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { - relation.register_const_equate_obligation(a, b); - } - return Ok(a); - } _ => {} } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 547f851526f..98da5ba65b7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -282,9 +282,9 @@ fn emit_msg_span( let message = format!("{}{}{}", prefix, description, suffix); if let Some(span) = span { - err.span_note(span, &message); + err.span_note(span, message); } else { - err.note(&message); + err.note(message); } } @@ -298,9 +298,9 @@ fn label_msg_span( let message = format!("{}{}{}", prefix, description, suffix); if let Some(span) = span { - err.span_label(span, &message); + err.span_label(span, message); } else { - err.note(&message); + err.note(message); } } @@ -2395,7 +2395,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); } else { let consider = format!("{} `{}: {}`...", msg, bound_kind, sub); - err.help(&consider); + err.help(consider); } } @@ -2625,7 +2625,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); err.span_note( sup_trace.cause.span, - &format!("...so that the {}", sup_trace.cause.as_requirement_str()), + format!("...so that the {}", sup_trace.cause.as_requirement_str()), ); err.note_expected_found(&"", sup_expected, &"", sup_found); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index c1ea0a0d95e..c9c1f0aeaac 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -261,11 +261,16 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { (false, None, None, Some(span), String::new()) }; - let expected_trait_ref = self - .cx - .resolve_vars_if_possible(self.cx.tcx.mk_trait_ref(trait_def_id, expected_substs)); - let actual_trait_ref = - self.cx.resolve_vars_if_possible(self.cx.tcx.mk_trait_ref(trait_def_id, actual_substs)); + let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new( + self.cx.tcx, + trait_def_id, + expected_substs, + )); + let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new( + self.cx.tcx, + trait_def_id, + actual_substs, + )); // Search the expected and actual trait references to see (a) // whether the sub/sup placeholders appear in them (sometimes diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 27c3b796d14..aad9885827d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -299,7 +299,7 @@ pub fn suggest_new_region_bound( if let Some(explicit_static) = &explicit_static { err.span_suggestion_verbose( span, - &format!("{consider} `{ty}`'s {explicit_static}"), + format!("{consider} `{ty}`'s {explicit_static}"), &lifetime_name, Applicability::MaybeIncorrect, ); @@ -367,7 +367,7 @@ pub fn suggest_new_region_bound( spans_suggs .push((fn_return.span.shrink_to_hi(), format!(" + {name} "))); err.multipart_suggestion_verbose( - &format!( + format!( "{declare} `{ty}` {captures}, {use_lt}", ), spans_suggs, @@ -376,7 +376,7 @@ pub fn suggest_new_region_bound( } else { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), - &format!("{declare} `{ty}` {captures}, {explicit}",), + format!("{declare} `{ty}` {captures}, {explicit}",), &plus_lt, Applicability::MaybeIncorrect, ); @@ -387,7 +387,7 @@ pub fn suggest_new_region_bound( if let LifetimeName::ImplicitObjectLifetimeDefault = lt.res { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), - &format!( + format!( "{declare} the trait object {captures}, {explicit}", declare = declare, captures = captures, @@ -404,7 +404,7 @@ pub fn suggest_new_region_bound( if let Some(explicit_static) = &explicit_static { err.span_suggestion_verbose( lt.ident.span, - &format!("{} the trait object's {}", consider, explicit_static), + format!("{} the trait object's {}", consider, explicit_static), &lifetime_name, Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index e410172c8c8..a3116351940 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -209,7 +209,7 @@ impl<T> Trait<T> for X { if !sp.contains(p_span) { diag.span_label(p_span, "this type parameter"); } - diag.help(&format!( + diag.help(format!( "every closure has a distinct type and so could not always match the \ caller-chosen type of parameter `{}`", p @@ -248,7 +248,7 @@ impl<T> Trait<T> for X { proj_ty, values.expected, )) { - diag.help(&msg); + diag.help(msg); diag.note( "for more information, visit \ https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", @@ -415,12 +415,12 @@ impl<T> Trait<T> for X { if !impl_comparison { // Generic suggestion when we can't be more specific. if callable_scope { - diag.help(&format!( + diag.help(format!( "{} or calling a method that returns `{}`", msg, values.expected )); } else { - diag.help(&msg); + diag.help(msg); } diag.note( "for more information, visit \ @@ -536,7 +536,7 @@ fn foo(&self) -> Self::T { String::new() } for (sp, label) in methods.into_iter() { span.push_span_label(sp, label); } - diag.span_help(span, &msg); + diag.span_help(span, msg); return true; } false diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index bd1bfed3a0c..8482ae2aa38 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -102,6 +102,17 @@ pub enum RegionResolutionError<'tcx> { ), } +impl<'tcx> RegionResolutionError<'tcx> { + pub fn origin(&self) -> &SubregionOrigin<'tcx> { + match self { + RegionResolutionError::ConcreteFailure(origin, _, _) + | RegionResolutionError::GenericBoundFailure(origin, _, _) + | RegionResolutionError::SubSupConflict(_, _, origin, _, _, _, _) + | RegionResolutionError::UpperBoundUniverseConflict(_, _, _, origin, _) => origin, + } + } +} + struct RegionAndOrigin<'tcx> { region: Region<'tcx>, origin: SubregionOrigin<'tcx>, @@ -824,7 +835,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // resolution errors here; delay ICE in favor of those errors. self.tcx().sess.delay_span_bug( self.var_infos[node_idx].origin.span(), - &format!( + format!( "collect_error_for_expanding_node() could not find \ error for var {:?} in universe {:?}, lower_bounds={:#?}, \ upper_bounds={:#?}", diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 1cfdb791cd6..a89b9931599 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -39,7 +39,6 @@ use rustc_span::Span; use std::cell::{Cell, RefCell}; use std::fmt; -use std::ops::Drop; use self::combine::CombineFields; use self::error_reporting::TypeErrCtxt; @@ -342,11 +341,6 @@ pub struct InferCtxt<'tcx> { /// there is no type that the user could *actually name* that /// would satisfy it. This avoids crippling inference, basically. pub intercrate: bool, - - /// Flag that is set when we enter canonicalization. Used for debugging to ensure - /// that we only collect region information for `BorrowckInferCtxt::reg_var_to_origin` - /// inside non-canonicalization contexts. - inside_canonicalization_ctxt: Cell<bool>, } /// See the `error_reporting` module for more details. @@ -638,7 +632,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> { skip_leak_check: Cell::new(false), universe: Cell::new(ty::UniverseIndex::ROOT), intercrate, - inside_canonicalization_ctxt: Cell::new(false), } } } @@ -1636,31 +1629,6 @@ impl<'tcx> InferCtxt<'tcx> { } } } - - pub fn inside_canonicalization_ctxt(&self) -> bool { - self.inside_canonicalization_ctxt.get() - } - - pub fn set_canonicalization_ctxt(&self) -> CanonicalizationCtxtGuard<'_, 'tcx> { - let prev_ctxt = self.inside_canonicalization_ctxt(); - self.inside_canonicalization_ctxt.set(true); - CanonicalizationCtxtGuard { prev_ctxt, infcx: self } - } - - fn set_canonicalization_ctxt_to(&self, ctxt: bool) { - self.inside_canonicalization_ctxt.set(ctxt); - } -} - -pub struct CanonicalizationCtxtGuard<'cx, 'tcx> { - prev_ctxt: bool, - infcx: &'cx InferCtxt<'tcx>, -} - -impl<'cx, 'tcx> Drop for CanonicalizationCtxtGuard<'cx, 'tcx> { - fn drop(&mut self) { - self.infcx.set_canonicalization_ctxt_to(self.prev_ctxt) - } } impl<'tcx> TypeErrCtxt<'_, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 9f7b26b87f4..88a0a81e276 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -30,11 +30,10 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt}; use rustc_span::{Span, Symbol}; use std::fmt::Debug; -use std::ops::ControlFlow; use super::combine::ObligationEmittingRelation; @@ -115,11 +114,6 @@ pub trait TypeRelatingDelegate<'tcx> { fn forbid_inference_vars() -> bool; } -#[derive(Clone, Debug, Default)] -struct BoundRegionScope<'tcx> { - map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>, -} - #[derive(Copy, Clone)] struct UniversallyQuantified(bool); @@ -230,10 +224,13 @@ where ) -> RelateResult<'tcx, T> { let universe = self.infcx.probe_ty_var(for_vid).unwrap_err(); + if value.has_escaping_bound_vars() { + bug!("trying to instantiate {for_vid:?} with escaping bound vars: {value:?}"); + } + let mut generalizer = TypeGeneralizer { infcx: self.infcx, delegate: &mut self.delegate, - first_free_index: ty::INNERMOST, ambient_variance: self.ambient_variance, for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid), universe, @@ -488,13 +485,7 @@ where } if a == b { - // Subtle: if a or b has a bound variable that we are lazily - // substituting, then even if a == b, it could be that the values we - // will substitute for those bound variables are *not* the same, and - // hence returning `Ok(a)` is incorrect. - if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { - return Ok(a); - } + return Ok(a); } match (a.kind(), b.kind()) { @@ -726,47 +717,6 @@ where } } -/// When we encounter a binder like `for<..> fn(..)`, we actually have -/// to walk the `fn` value to find all the values bound by the `for` -/// (these are not explicitly present in the ty representation right -/// now). This visitor handles that: it descends the type, tracking -/// binder depth, and finds late-bound regions targeting the -/// `for<..`>. For each of those, it creates an entry in -/// `bound_region_scope`. -struct ScopeInstantiator<'me, 'tcx> { - next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>, - // The debruijn index of the scope we are instantiating. - target_index: ty::DebruijnIndex, - bound_region_scope: &'me mut BoundRegionScope<'tcx>, -} - -impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> { - fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( - &mut self, - t: &ty::Binder<'tcx, T>, - ) -> ControlFlow<Self::BreakTy> { - self.target_index.shift_in(1); - t.super_visit_with(self); - self.target_index.shift_out(1); - - ControlFlow::Continue(()) - } - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - let ScopeInstantiator { bound_region_scope, next_region, .. } = self; - - match *r { - ty::ReLateBound(debruijn, br) if debruijn == self.target_index => { - bound_region_scope.map.entry(br).or_insert_with(|| next_region(br)); - } - - _ => {} - } - - ControlFlow::Continue(()) - } -} - /// The "type generalizer" is used when handling inference variables. /// /// The basic strategy for handling a constraint like `?A <: B` is to @@ -780,11 +730,6 @@ impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> { /// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which /// establishes `'0: 'x` as a constraint. /// -/// As a side-effect of this generalization procedure, we also replace -/// all the bound regions that we have traversed with concrete values, -/// so that the resulting generalized type is independent from the -/// scopes. -/// /// [blog post]: https://is.gd/0hKvIr struct TypeGeneralizer<'me, 'tcx, D> where @@ -798,8 +743,6 @@ where /// some other type. What will be the variance at this point? ambient_variance: ty::Variance, - first_free_index: ty::DebruijnIndex, - /// The vid of the type variable that is in the process of being /// instantiated. If we find this within the value we are folding, /// that means we would have created a cyclic value. @@ -939,7 +882,7 @@ where ) -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("TypeGeneralizer::regions(a={:?})", a); - if let ty::ReLateBound(debruijn, _) = *a && debruijn < self.first_free_index { + if let ty::ReLateBound(..) = *a { return Ok(a); } @@ -958,7 +901,6 @@ where // FIXME(#54105) -- if the ambient variance is bivariant, // though, we may however need to check well-formedness or // risk a problem like #41677 again. - let replacement_region_vid = self.delegate.generalize_existential(self.universe); Ok(replacement_region_vid) @@ -1002,10 +944,7 @@ where T: Relate<'tcx>, { debug!("TypeGeneralizer::binders(a={:?})", a); - - self.first_free_index.shift_in(1); let result = self.relate(a.skip_binder(), a.skip_binder())?; - self.first_free_index.shift_out(1); Ok(a.rebind(result)) } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index ae4b85c8799..a0f6d7ecab7 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -42,7 +42,7 @@ impl<'tcx> Drop for OpaqueTypeStorage<'tcx> { fn drop(&mut self) { if !self.opaque_types.is_empty() { ty::tls::with(|tcx| { - tcx.sess.delay_span_bug(DUMMY_SP, &format!("{:?}", self.opaque_types)) + tcx.sess.delay_span_bug(DUMMY_SP, format!("{:?}", self.opaque_types)) }); } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index d3f7eeff997..9c20c814b69 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -256,7 +256,7 @@ where // this point it never will be self.tcx.sess.delay_span_bug( origin.span(), - &format!("unresolved inference variable in outlives: {:?}", v), + format!("unresolved inference variable in outlives: {:?}", v), ); } } diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index e1cb53bc71d..c86da22526b 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -179,7 +179,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // this point it never will be self.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, - &format!("unresolved inference variable in outlives: {:?}", v), + format!("unresolved inference variable in outlives: {:?}", v), ); // add a bound that never holds VerifyBound::AnyBound(vec![]) diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index b8940e2f045..11f43469400 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -18,7 +18,7 @@ pub trait TraitEngine<'tcx>: 'tcx { def_id: DefId, cause: ObligationCause<'tcx>, ) { - let trait_ref = infcx.tcx.mk_trait_ref(def_id, [ty]); + let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]); self.register_predicate_obligation( infcx, Obligation { diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 4d53519581b..b5a7d0326a8 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -73,7 +73,7 @@ pub fn report_object_safety_error<'tcx>( format!("...because {}", violation.error_msg()) }; if spans.is_empty() { - err.note(&msg); + err.note(msg); } else { for span in spans { multi_span.push(span); diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index ef01d5d513b..74a78f38024 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -200,6 +200,10 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { let bound_predicate = elaboratable.predicate().kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(data)) => { + // Negative trait bounds do not imply any supertrait bounds + if data.polarity == ty::ImplPolarity::Negative { + return; + } // Get predicates implied by the trait, or only super predicates if we only care about self predicates. let predicates = if self.only_self { tcx.super_predicates_of(data.def_id()) @@ -376,11 +380,11 @@ pub fn transitive_bounds<'tcx>( } /// A specialized variant of `elaborate` that only elaborates trait references that may -/// define the given associated type `assoc_name`. It uses the -/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that +/// define the given associated item with the name `assoc_name`. It uses the +/// `super_predicates_that_define_assoc_item` query to avoid enumerating super-predicates that /// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or /// `T::Item` and helps to avoid cycle errors (see e.g. #35237). -pub fn transitive_bounds_that_define_assoc_type<'tcx>( +pub fn transitive_bounds_that_define_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>, assoc_name: Ident, @@ -393,7 +397,7 @@ pub fn transitive_bounds_that_define_assoc_type<'tcx>( let anon_trait_ref = tcx.anonymize_bound_vars(trait_ref); if visited.insert(anon_trait_ref) { let super_predicates = - tcx.super_predicates_that_define_assoc_type((trait_ref.def_id(), assoc_name)); + tcx.super_predicates_that_define_assoc_item((trait_ref.def_id(), assoc_name)); for (super_predicate, _) in super_predicates.predicates { let subst_predicate = super_predicate.subst_supertrait(tcx, &trait_ref); if let Some(binder) = subst_predicate.to_opt_poly_trait_pred() { diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 8e9150ba8ad..9d9f4ee13f4 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -9,11 +9,12 @@ use rustc_data_structures::OnDrop; use rustc_errors::registry::Registry; use rustc_errors::{ErrorGuaranteed, Handler}; use rustc_lint::LintStore; -use rustc_middle::ty; +use rustc_middle::{bug, ty}; use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; -use rustc_session::config::{self, CheckCfg, ErrorOutputType, Input, OutputFilenames}; +use rustc_session::config::{self, ErrorOutputType, Input, OutputFilenames}; +use rustc_session::config::{CheckCfg, ExpectedValues}; use rustc_session::lint; use rustc_session::parse::{CrateConfig, ParseSess}; use rustc_session::Session; @@ -121,9 +122,9 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String /// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`. pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg { rustc_span::create_default_session_if_not_set_then(move |_| { - let mut cfg = CheckCfg::default(); + let mut check_cfg = CheckCfg::default(); - 'specs: for s in specs { + for s in specs { let sess = ParseSess::with_silent_emitter(Some(format!( "this error occurred on the command line: `--check-cfg={s}`" ))); @@ -137,40 +138,54 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg { concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), s ), - ); + ) }; } + let expected_error = || { + error!( + "expected `names(name1, name2, ... nameN)` or \ + `values(name, \"value1\", \"value2\", ... \"valueN\")`" + ) + }; + match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) { Ok(mut parser) => match parser.parse_meta_item() { Ok(meta_item) if parser.token == token::Eof => { if let Some(args) = meta_item.meta_item_list() { if meta_item.has_name(sym::names) { - let names_valid = - cfg.names_valid.get_or_insert_with(|| FxHashSet::default()); + check_cfg.exhaustive_names = true; for arg in args { if arg.is_word() && arg.ident().is_some() { let ident = arg.ident().expect("multi-segment cfg key"); - names_valid.insert(ident.name.to_string()); + check_cfg + .expecteds + .entry(ident.name.to_string()) + .or_insert(ExpectedValues::Any); } else { error!("`names()` arguments must be simple identifiers"); } } - continue 'specs; } else if meta_item.has_name(sym::values) { if let Some((name, values)) = args.split_first() { if name.is_word() && name.ident().is_some() { let ident = name.ident().expect("multi-segment cfg key"); - let ident_values = cfg - .values_valid + let expected_values = check_cfg + .expecteds .entry(ident.name.to_string()) - .or_insert_with(|| FxHashSet::default()); + .or_insert_with(|| { + ExpectedValues::Some(FxHashSet::default()) + }); + + let ExpectedValues::Some(expected_values) = expected_values else { + bug!("shoudn't be possible") + }; for val in values { if let Some(LitKind::Str(s, _)) = val.lit().map(|lit| &lit.kind) { - ident_values.insert(s.to_string()); + expected_values.insert(Some(s.to_string())); } else { error!( "`values()` arguments must be string literals" @@ -178,35 +193,40 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg { } } - continue 'specs; + if values.is_empty() { + expected_values.insert(None); + } } else { error!( "`values()` first argument must be a simple identifier" ); } } else if args.is_empty() { - cfg.well_known_values = true; - continue 'specs; + check_cfg.exhaustive_values = true; + } else { + expected_error(); } + } else { + expected_error(); } + } else { + expected_error(); } } - Ok(..) => {} - Err(err) => err.cancel(), + Ok(..) => expected_error(), + Err(err) => { + err.cancel(); + expected_error(); + } }, - Err(errs) => drop(errs), + Err(errs) => { + drop(errs); + expected_error(); + } } - - error!( - "expected `names(name1, name2, ... nameN)` or \ - `values(name, \"value1\", \"value2\", ... \"valueN\")`" - ); } - if let Some(names_valid) = &mut cfg.names_valid { - names_valid.extend(cfg.values_valid.keys().cloned()); - } - cfg + check_cfg }) } diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 77fbbf64a0a..6483d51a0b9 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -368,9 +368,8 @@ impl Linker { } if sess.opts.unstable_opts.no_link { - let encoded = CodegenResults::serialize_rlink(&codegen_results); let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT); - std::fs::write(&rlink_file, encoded) + CodegenResults::serialize_rlink(&rlink_file, &codegen_results) .map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?; return Ok(()); } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 7b0b5102c2d..1bae771e373 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -69,6 +69,7 @@ where is_private_dep: false, add_prelude: true, nounused_dep: false, + force: false, } } @@ -547,6 +548,7 @@ fn test_codegen_options_tracking_hash() { untracked!(ar, String::from("abc")); untracked!(codegen_units, Some(42)); untracked!(default_linker_libraries, true); + untracked!(dlltool, Some(PathBuf::from("custom_dlltool.exe"))); untracked!(extra_filename, String::from("extra-filename")); untracked!(incremental, Some(String::from("abc"))); // `link_arg` is omitted because it just forwards to `link_args`. @@ -651,7 +653,6 @@ fn test_unstable_options_tracking_hash() { untracked!(assert_incr_state, Some(String::from("loaded"))); untracked!(deduplicate_diagnostics, false); untracked!(dep_tasks, true); - untracked!(dlltool, Some(PathBuf::from("custom_dlltool.exe"))); untracked!(dont_buffer_diagnostics, true); untracked!(dump_dep_graph, true); untracked!(dump_drop_tracking_cfg, Some("cfg.dot".to_string())); @@ -795,12 +796,16 @@ fn test_unstable_options_tracking_hash() { tracked!(remap_cwd_prefix, Some(PathBuf::from("abc"))); tracked!(report_delayed_bugs, true); tracked!(sanitizer, SanitizerSet::ADDRESS); + tracked!(sanitizer_cfi_canonical_jump_tables, None); + tracked!(sanitizer_cfi_generalize_pointers, Some(true)); + tracked!(sanitizer_cfi_normalize_integers, Some(true)); tracked!(sanitizer_memory_track_origins, 2); tracked!(sanitizer_recover, SanitizerSet::ADDRESS); tracked!(saturating_float_casts, Some(true)); tracked!(share_generics, Some(true)); tracked!(show_span, Some(String::from("abc"))); tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc"))); + tracked!(split_lto_unit, Some(true)); tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1)); tracked!(stack_protector, StackProtector::All); tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index b3f4b5cd5e5..c07dc19a0ac 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -186,12 +186,16 @@ pub enum LiteralKind { Str { terminated: bool }, /// "b"abc"", "b"abc" ByteStr { terminated: bool }, + /// `c"abc"`, `c"abc` + CStr { terminated: bool }, /// "r"abc"", "r#"abc"#", "r####"ab"###"c"####", "r#"a". `None` indicates /// an invalid literal. RawStr { n_hashes: Option<u8> }, /// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a". `None` /// indicates an invalid literal. RawByteStr { n_hashes: Option<u8> }, + /// `cr"abc"`, "cr#"abc"#", `cr#"a`. `None` indicates an invalid literal. + RawCStr { n_hashes: Option<u8> }, } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -357,39 +361,18 @@ impl Cursor<'_> { }, // Byte literal, byte string literal, raw byte string literal or identifier. - 'b' => match (self.first(), self.second()) { - ('\'', _) => { - self.bump(); - let terminated = self.single_quoted_string(); - let suffix_start = self.pos_within_token(); - if terminated { - self.eat_literal_suffix(); - } - let kind = Byte { terminated }; - Literal { kind, suffix_start } - } - ('"', _) => { - self.bump(); - let terminated = self.double_quoted_string(); - let suffix_start = self.pos_within_token(); - if terminated { - self.eat_literal_suffix(); - } - let kind = ByteStr { terminated }; - Literal { kind, suffix_start } - } - ('r', '"') | ('r', '#') => { - self.bump(); - let res = self.raw_double_quoted_string(2); - let suffix_start = self.pos_within_token(); - if res.is_ok() { - self.eat_literal_suffix(); - } - let kind = RawByteStr { n_hashes: res.ok() }; - Literal { kind, suffix_start } - } - _ => self.ident_or_unknown_prefix(), - }, + 'b' => self.c_or_byte_string( + |terminated| ByteStr { terminated }, + |n_hashes| RawByteStr { n_hashes }, + Some(|terminated| Byte { terminated }), + ), + + // c-string literal, raw c-string literal or identifier. + 'c' => self.c_or_byte_string( + |terminated| CStr { terminated }, + |n_hashes| RawCStr { n_hashes }, + None, + ), // Identifier (this should be checked after other variant that can // start as identifier). @@ -553,6 +536,47 @@ impl Cursor<'_> { } } + fn c_or_byte_string( + &mut self, + mk_kind: impl FnOnce(bool) -> LiteralKind, + mk_kind_raw: impl FnOnce(Option<u8>) -> LiteralKind, + single_quoted: Option<fn(bool) -> LiteralKind>, + ) -> TokenKind { + match (self.first(), self.second(), single_quoted) { + ('\'', _, Some(mk_kind)) => { + self.bump(); + let terminated = self.single_quoted_string(); + let suffix_start = self.pos_within_token(); + if terminated { + self.eat_literal_suffix(); + } + let kind = mk_kind(terminated); + Literal { kind, suffix_start } + } + ('"', _, _) => { + self.bump(); + let terminated = self.double_quoted_string(); + let suffix_start = self.pos_within_token(); + if terminated { + self.eat_literal_suffix(); + } + let kind = mk_kind(terminated); + Literal { kind, suffix_start } + } + ('r', '"', _) | ('r', '#', _) => { + self.bump(); + let res = self.raw_double_quoted_string(2); + let suffix_start = self.pos_within_token(); + if res.is_ok() { + self.eat_literal_suffix(); + } + let kind = mk_kind_raw(res.ok()); + Literal { kind, suffix_start } + } + _ => self.ident_or_unknown_prefix(), + } + } + fn number(&mut self, first_digit: char) -> LiteralKind { debug_assert!('0' <= self.prev() && self.prev() <= '9'); let mut base = Base::Decimal; diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index bb4d91247b8..c9ad54d8d98 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -86,10 +86,45 @@ where let res = unescape_char_or_byte(&mut chars, mode == Mode::Byte); callback(0..(src.len() - chars.as_str().len()), res); } - Mode::Str | Mode::ByteStr => unescape_str_or_byte_str(src, mode == Mode::ByteStr, callback), + Mode::Str | Mode::ByteStr => unescape_str_common(src, mode, callback), + Mode::RawStr | Mode::RawByteStr => { unescape_raw_str_or_raw_byte_str(src, mode == Mode::RawByteStr, callback) } + Mode::CStr | Mode::RawCStr => unreachable!(), + } +} + +/// A unit within CStr. Must not be a nul character. +pub enum CStrUnit { + Byte(u8), + Char(char), +} + +impl From<u8> for CStrUnit { + fn from(value: u8) -> Self { + CStrUnit::Byte(value) + } +} + +impl From<char> for CStrUnit { + fn from(value: char) -> Self { + CStrUnit::Char(value) + } +} + +pub fn unescape_c_string<F>(src: &str, mode: Mode, callback: &mut F) +where + F: FnMut(Range<usize>, Result<CStrUnit, EscapeError>), +{ + if mode == Mode::RawCStr { + unescape_raw_str_or_raw_byte_str( + src, + mode.characters_should_be_ascii(), + &mut |r, result| callback(r, result.map(CStrUnit::Char)), + ); + } else { + unescape_str_common(src, mode, callback); } } @@ -114,34 +149,69 @@ pub enum Mode { ByteStr, RawStr, RawByteStr, + CStr, + RawCStr, } impl Mode { pub fn in_double_quotes(self) -> bool { match self { - Mode::Str | Mode::ByteStr | Mode::RawStr | Mode::RawByteStr => true, + Mode::Str + | Mode::ByteStr + | Mode::RawStr + | Mode::RawByteStr + | Mode::CStr + | Mode::RawCStr => true, Mode::Char | Mode::Byte => false, } } - pub fn is_byte(self) -> bool { + /// Non-byte literals should have `\xXX` escapes that are within the ASCII range. + pub fn ascii_escapes_should_be_ascii(self) -> bool { + match self { + Mode::Char | Mode::Str | Mode::RawStr => true, + Mode::Byte | Mode::ByteStr | Mode::RawByteStr | Mode::CStr | Mode::RawCStr => false, + } + } + + /// Whether characters within the literal must be within the ASCII range + pub fn characters_should_be_ascii(self) -> bool { + match self { + Mode::Byte | Mode::ByteStr | Mode::RawByteStr => true, + Mode::Char | Mode::Str | Mode::RawStr | Mode::CStr | Mode::RawCStr => false, + } + } + + /// Byte literals do not allow unicode escape. + pub fn is_unicode_escape_disallowed(self) -> bool { match self { Mode::Byte | Mode::ByteStr | Mode::RawByteStr => true, - Mode::Char | Mode::Str | Mode::RawStr => false, + Mode::Char | Mode::Str | Mode::RawStr | Mode::CStr | Mode::RawCStr => false, + } + } + + pub fn prefix_noraw(self) -> &'static str { + match self { + Mode::Byte | Mode::ByteStr | Mode::RawByteStr => "b", + Mode::CStr | Mode::RawCStr => "c", + Mode::Char | Mode::Str | Mode::RawStr => "", } } } -fn scan_escape(chars: &mut Chars<'_>, is_byte: bool) -> Result<char, EscapeError> { +fn scan_escape<T: From<u8> + From<char>>( + chars: &mut Chars<'_>, + mode: Mode, +) -> Result<T, EscapeError> { // Previous character was '\\', unescape what follows. let res = match chars.next().ok_or(EscapeError::LoneSlash)? { - '"' => '"', - 'n' => '\n', - 'r' => '\r', - 't' => '\t', - '\\' => '\\', - '\'' => '\'', - '0' => '\0', + '"' => b'"', + 'n' => b'\n', + 'r' => b'\r', + 't' => b'\t', + '\\' => b'\\', + '\'' => b'\'', + '0' => b'\0', 'x' => { // Parse hexadecimal character code. @@ -154,76 +224,78 @@ fn scan_escape(chars: &mut Chars<'_>, is_byte: bool) -> Result<char, EscapeError let value = hi * 16 + lo; - // For a non-byte literal verify that it is within ASCII range. - if !is_byte && !is_ascii(value) { + if mode.ascii_escapes_should_be_ascii() && !is_ascii(value) { return Err(EscapeError::OutOfRangeHexEscape); } - let value = value as u8; - value as char + value as u8 } - 'u' => { - // We've parsed '\u', now we have to parse '{..}'. + 'u' => return scan_unicode(chars, mode.is_unicode_escape_disallowed()).map(Into::into), + _ => return Err(EscapeError::InvalidEscape), + }; + Ok(res.into()) +} + +fn scan_unicode( + chars: &mut Chars<'_>, + is_unicode_escape_disallowed: bool, +) -> Result<char, EscapeError> { + // We've parsed '\u', now we have to parse '{..}'. - if chars.next() != Some('{') { - return Err(EscapeError::NoBraceInUnicodeEscape); - } + if chars.next() != Some('{') { + return Err(EscapeError::NoBraceInUnicodeEscape); + } - // First character must be a hexadecimal digit. - let mut n_digits = 1; - let mut value: u32 = match chars.next().ok_or(EscapeError::UnclosedUnicodeEscape)? { - '_' => return Err(EscapeError::LeadingUnderscoreUnicodeEscape), - '}' => return Err(EscapeError::EmptyUnicodeEscape), - c => c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?, - }; - - // First character is valid, now parse the rest of the number - // and closing brace. - loop { - match chars.next() { - None => return Err(EscapeError::UnclosedUnicodeEscape), - Some('_') => continue, - Some('}') => { - if n_digits > 6 { - return Err(EscapeError::OverlongUnicodeEscape); - } - - // Incorrect syntax has higher priority for error reporting - // than unallowed value for a literal. - if is_byte { - return Err(EscapeError::UnicodeEscapeInByte); - } - - break std::char::from_u32(value).ok_or_else(|| { - if value > 0x10FFFF { - EscapeError::OutOfRangeUnicodeEscape - } else { - EscapeError::LoneSurrogateUnicodeEscape - } - })?; - } - Some(c) => { - let digit: u32 = - c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?; - n_digits += 1; - if n_digits > 6 { - // Stop updating value since we're sure that it's incorrect already. - continue; - } - value = value * 16 + digit; + // First character must be a hexadecimal digit. + let mut n_digits = 1; + let mut value: u32 = match chars.next().ok_or(EscapeError::UnclosedUnicodeEscape)? { + '_' => return Err(EscapeError::LeadingUnderscoreUnicodeEscape), + '}' => return Err(EscapeError::EmptyUnicodeEscape), + c => c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?, + }; + + // First character is valid, now parse the rest of the number + // and closing brace. + loop { + match chars.next() { + None => return Err(EscapeError::UnclosedUnicodeEscape), + Some('_') => continue, + Some('}') => { + if n_digits > 6 { + return Err(EscapeError::OverlongUnicodeEscape); + } + + // Incorrect syntax has higher priority for error reporting + // than unallowed value for a literal. + if is_unicode_escape_disallowed { + return Err(EscapeError::UnicodeEscapeInByte); + } + + break std::char::from_u32(value).ok_or_else(|| { + if value > 0x10FFFF { + EscapeError::OutOfRangeUnicodeEscape + } else { + EscapeError::LoneSurrogateUnicodeEscape } - }; + }); } - } - _ => return Err(EscapeError::InvalidEscape), - }; - Ok(res) + Some(c) => { + let digit: u32 = c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?; + n_digits += 1; + if n_digits > 6 { + // Stop updating value since we're sure that it's incorrect already. + continue; + } + value = value * 16 + digit; + } + }; + } } #[inline] -fn ascii_check(c: char, is_byte: bool) -> Result<char, EscapeError> { - if is_byte && !c.is_ascii() { +fn ascii_check(c: char, characters_should_be_ascii: bool) -> Result<char, EscapeError> { + if characters_should_be_ascii && !c.is_ascii() { // Byte literal can't be a non-ascii character. Err(EscapeError::NonAsciiCharInByte) } else { @@ -234,7 +306,7 @@ fn ascii_check(c: char, is_byte: bool) -> Result<char, EscapeError> { fn unescape_char_or_byte(chars: &mut Chars<'_>, is_byte: bool) -> Result<char, EscapeError> { let c = chars.next().ok_or(EscapeError::ZeroChars)?; let res = match c { - '\\' => scan_escape(chars, is_byte), + '\\' => scan_escape(chars, if is_byte { Mode::Byte } else { Mode::Char }), '\n' | '\t' | '\'' => Err(EscapeError::EscapeOnlyChar), '\r' => Err(EscapeError::BareCarriageReturn), _ => ascii_check(c, is_byte), @@ -247,9 +319,9 @@ fn unescape_char_or_byte(chars: &mut Chars<'_>, is_byte: bool) -> Result<char, E /// Takes a contents of a string literal (without quotes) and produces a /// sequence of escaped characters or errors. -fn unescape_str_or_byte_str<F>(src: &str, is_byte: bool, callback: &mut F) +fn unescape_str_common<F, T: From<u8> + From<char>>(src: &str, mode: Mode, callback: &mut F) where - F: FnMut(Range<usize>, Result<char, EscapeError>), + F: FnMut(Range<usize>, Result<T, EscapeError>), { let mut chars = src.chars(); @@ -266,47 +338,49 @@ where // if unescaped '\' character is followed by '\n'. // For details see [Rust language reference] // (https://doc.rust-lang.org/reference/tokens.html#string-literals). - skip_ascii_whitespace(&mut chars, start, callback); + skip_ascii_whitespace(&mut chars, start, &mut |range, err| { + callback(range, Err(err)) + }); continue; } - _ => scan_escape(&mut chars, is_byte), + _ => scan_escape::<T>(&mut chars, mode), } } - '\n' => Ok('\n'), - '\t' => Ok('\t'), + '\n' => Ok(b'\n'.into()), + '\t' => Ok(b'\t'.into()), '"' => Err(EscapeError::EscapeOnlyChar), '\r' => Err(EscapeError::BareCarriageReturn), - _ => ascii_check(c, is_byte), + _ => ascii_check(c, mode.characters_should_be_ascii()).map(Into::into), }; let end = src.len() - chars.as_str().len(); - callback(start..end, res); + callback(start..end, res.map(Into::into)); } +} - fn skip_ascii_whitespace<F>(chars: &mut Chars<'_>, start: usize, callback: &mut F) - where - F: FnMut(Range<usize>, Result<char, EscapeError>), - { - let tail = chars.as_str(); - let first_non_space = tail - .bytes() - .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r') - .unwrap_or(tail.len()); - if tail[1..first_non_space].contains('\n') { - // The +1 accounts for the escaping slash. - let end = start + first_non_space + 1; - callback(start..end, Err(EscapeError::MultipleSkippedLinesWarning)); - } - let tail = &tail[first_non_space..]; - if let Some(c) = tail.chars().nth(0) { - if c.is_whitespace() { - // For error reporting, we would like the span to contain the character that was not - // skipped. The +1 is necessary to account for the leading \ that started the escape. - let end = start + first_non_space + c.len_utf8() + 1; - callback(start..end, Err(EscapeError::UnskippedWhitespaceWarning)); - } +fn skip_ascii_whitespace<F>(chars: &mut Chars<'_>, start: usize, callback: &mut F) +where + F: FnMut(Range<usize>, EscapeError), +{ + let tail = chars.as_str(); + let first_non_space = tail + .bytes() + .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r') + .unwrap_or(tail.len()); + if tail[1..first_non_space].contains('\n') { + // The +1 accounts for the escaping slash. + let end = start + first_non_space + 1; + callback(start..end, EscapeError::MultipleSkippedLinesWarning); + } + let tail = &tail[first_non_space..]; + if let Some(c) = tail.chars().nth(0) { + if c.is_whitespace() { + // For error reporting, we would like the span to contain the character that was not + // skipped. The +1 is necessary to account for the leading \ that started the escape. + let end = start + first_non_space + c.len_utf8() + 1; + callback(start..end, EscapeError::UnskippedWhitespaceWarning); } - *chars = tail.chars(); } + *chars = tail.chars(); } /// Takes a contents of a string literal (without quotes) and produces a diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 3c6dbb466db..71cf644eb50 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -50,6 +50,14 @@ lint_deprecated_lint_name = lint_renamed_or_removed_lint = {$msg} .suggestion = use the new name +lint_suspicious_double_ref_op = + using `.{$call}()` on a double reference, which returns `{$ty}` instead of {$op -> + *[should_not_happen] [{$op}] + [deref] dereferencing + [borrow] borrowing + [clone] cloning + } the inner type + lint_unknown_lint = unknown lint: `{$name}` .suggestion = did you mean diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index aeb791901bd..0b7a704eb57 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -63,6 +63,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef}; +use rustc_session::config::ExpectedValues; use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; @@ -116,8 +117,7 @@ impl EarlyLintPass for WhileTrue { #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { if let ast::ExprKind::While(cond, _, label) = &e.kind - && let cond = pierce_parens(cond) - && let ast::ExprKind::Lit(token_lit) = cond.kind + && let ast::ExprKind::Lit(token_lit) = pierce_parens(cond).kind && let token::Lit { kind: token::Bool, symbol: kw::True, .. } = token_lit && !cond.span.from_expansion() { @@ -546,32 +546,13 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - match it.kind { - hir::ItemKind::Trait(..) => { - // Issue #11592: traits are always considered exported, even when private. - if cx.tcx.visibility(it.owner_id) - == ty::Visibility::Restricted( - cx.tcx.parent_module_from_def_id(it.owner_id.def_id).to_def_id(), - ) - { - return; - } - } - hir::ItemKind::TyAlias(..) - | hir::ItemKind::Fn(..) - | hir::ItemKind::Macro(..) - | hir::ItemKind::Mod(..) - | hir::ItemKind::Enum(..) - | hir::ItemKind::Struct(..) - | hir::ItemKind::Union(..) - | hir::ItemKind::Const(..) - | hir::ItemKind::Static(..) => {} - - _ => return, - }; + // Previously the Impl and Use types have been excluded from missing docs, + // so we will continue to exclude them for compatibility + if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) = it.kind { + return; + } let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id()); - self.check_missing_docs_attrs(cx, it.owner_id.def_id, article, desc); } @@ -3306,16 +3287,15 @@ impl EarlyLintPass for UnexpectedCfgs { let cfg = &cx.sess().parse_sess.config; let check_cfg = &cx.sess().parse_sess.check_config; for &(name, value) in cfg { - if let Some(names_valid) = &check_cfg.names_valid && !names_valid.contains(&name){ - cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigName { - name, - }); - } - if let Some(value) = value && let Some(values) = check_cfg.values_valid.get(&name) && !values.contains(&value) { - cx.emit_lint( - UNEXPECTED_CFGS, - BuiltinUnexpectedCliConfigValue { name, value }, - ); + match check_cfg.expecteds.get(&name) { + Some(ExpectedValues::Some(values)) if !values.contains(&value) => { + let value = value.unwrap_or(kw::Empty); + cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigValue { name, value }); + } + None if check_cfg.exhaustive_names => { + cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigName { name }); + } + _ => { /* expected */ } } } } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 626c09fea07..53d7cf74cde 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -36,6 +36,7 @@ use rustc_middle::middle::stability; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt}; +use rustc_session::config::ExpectedValues; use rustc_session::lint::{BuiltinLintDiagnostics, LintExpectationId}; use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use rustc_session::Session; @@ -616,7 +617,7 @@ pub trait LintContext: Sized { 1 => ("an ", ""), _ => ("", "s"), }; - db.span_label(span, &format!( + db.span_label(span, format!( "this comment contains {}invisible unicode text flow control codepoint{}", an, s, @@ -680,12 +681,12 @@ pub trait LintContext: Sized { ); } BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => { - db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect); + db.span_suggestion(span, note, sugg, Applicability::MaybeIncorrect); } BuiltinLintDiagnostics::UnusedImports(message, replaces, in_test_module) => { if !replaces.is_empty() { db.tool_only_multipart_suggestion( - &message, + message, replaces, Applicability::MachineApplicable, ); @@ -720,13 +721,13 @@ pub trait LintContext: Sized { } BuiltinLintDiagnostics::MissingAbi(span, default_abi) => { db.span_label(span, "ABI should be specified here"); - db.help(&format!("the default ABI is {}", default_abi.name())); + db.help(format!("the default ABI is {}", default_abi.name())); } BuiltinLintDiagnostics::LegacyDeriveHelpers(span) => { db.span_label(span, "the attribute is introduced here"); } BuiltinLintDiagnostics::ProcMacroBackCompat(note) => { - db.note(¬e); + db.note(note); } BuiltinLintDiagnostics::OrPatternsBackCompat(span,suggestion) => { db.span_suggestion(span, "use pat_param to preserve semantics", suggestion, Applicability::MachineApplicable); @@ -747,13 +748,13 @@ pub trait LintContext: Sized { } => { db.span_note( invoc_span, - &format!("the built-in attribute `{attr_name}` will be ignored, since it's applied to the macro invocation `{macro_name}`") + format!("the built-in attribute `{attr_name}` will be ignored, since it's applied to the macro invocation `{macro_name}`") ); } BuiltinLintDiagnostics::TrailingMacro(is_trailing, name) => { if is_trailing { db.note("macro invocations at the end of a block are treated as expressions"); - db.note(&format!("to ignore the value produced by the macro, add a semicolon after the invocation of `{name}`")); + db.note(format!("to ignore the value produced by the macro, add a semicolon after the invocation of `{name}`")); } } BuiltinLintDiagnostics::BreakWithLabelAndLoop(span) => { @@ -765,25 +766,55 @@ pub trait LintContext: Sized { ); } BuiltinLintDiagnostics::NamedAsmLabel(help) => { - db.help(&help); + db.help(help); db.note("see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information"); }, - BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), None) => { - let Some(names_valid) = &sess.parse_sess.check_config.names_valid else { - bug!("it shouldn't be possible to have a diagnostic on a name if name checking is not enabled"); - }; - let possibilities: Vec<Symbol> = names_valid.iter().map(|s| *s).collect(); + BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => { + let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().map(|s| *s).collect(); // Suggest the most probable if we found one if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) { - db.span_suggestion(name_span, "did you mean", best_match, Applicability::MaybeIncorrect); + if let Some(ExpectedValues::Some(best_match_values)) = + sess.parse_sess.check_config.expecteds.get(&best_match) { + let mut possibilities = best_match_values.iter() + .flatten() + .map(Symbol::as_str) + .collect::<Vec<_>>(); + possibilities.sort(); + + if let Some((value, value_span)) = value { + if best_match_values.contains(&Some(value)) { + db.span_suggestion(name_span, "there is a config with a similar name and value", best_match, Applicability::MaybeIncorrect); + } else if best_match_values.contains(&None) { + db.span_suggestion(name_span.to(value_span), "there is a config with a similar name and no value", best_match, Applicability::MaybeIncorrect); + } else if let Some(first_value) = possibilities.first() { + db.span_suggestion(name_span.to(value_span), "there is a config with a similar name and different values", format!("{best_match} = \"{first_value}\""), Applicability::MaybeIncorrect); + } else { + db.span_suggestion(name_span.to(value_span), "there is a config with a similar name and different values", best_match, Applicability::MaybeIncorrect); + }; + } else { + db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect); + } + + if !possibilities.is_empty() { + let possibilities = possibilities.join("`, `"); + db.help(format!("expected values for `{best_match}` are: `{possibilities}`")); + } + } else { + db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect); + } } }, - BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), Some((value, value_span))) => { - let Some(values) = &sess.parse_sess.check_config.values_valid.get(&name) else { + BuiltinLintDiagnostics::UnexpectedCfgValue((name, name_span), value) => { + let Some(ExpectedValues::Some(values)) = &sess.parse_sess.check_config.expecteds.get(&name) else { bug!("it shouldn't be possible to have a diagnostic on a value whose name is not in values"); }; - let possibilities: Vec<Symbol> = values.iter().map(|&s| s).collect(); + let mut have_none_possibility = false; + let possibilities: Vec<Symbol> = values.iter() + .inspect(|a| have_none_possibility |= a.is_none()) + .copied() + .flatten() + .collect(); // Show the full list if all possible values for a given name, but don't do it // for names as the possibilities could be very long @@ -792,17 +823,24 @@ pub trait LintContext: Sized { let mut possibilities = possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>(); possibilities.sort(); - let possibilities = possibilities.join(", "); - db.note(&format!("expected values for `{name}` are: {possibilities}")); + let possibilities = possibilities.join("`, `"); + let none = if have_none_possibility { "(none), " } else { "" }; + + db.note(format!("expected values for `{name}` are: {none}`{possibilities}`")); } - // Suggest the most probable if we found one - if let Some(best_match) = find_best_match_for_name(&possibilities, value, None) { - db.span_suggestion(value_span, "did you mean", format!("\"{best_match}\""), Applicability::MaybeIncorrect); + if let Some((value, value_span)) = value { + // Suggest the most probable if we found one + if let Some(best_match) = find_best_match_for_name(&possibilities, value, None) { + db.span_suggestion(value_span, "there is a expected value with a similar name", format!("\"{best_match}\""), Applicability::MaybeIncorrect); + + } + } else if let &[first_possibility] = &possibilities[..] { + db.span_suggestion(name_span.shrink_to_hi(), "specify a config value", format!(" = \"{first_possibility}\""), Applicability::MaybeIncorrect); } - } else { - db.note(&format!("no expected value for `{name}`")); - if name != sym::feature { + } else if have_none_possibility { + db.note(format!("no expected value for `{name}`")); + if let Some((_value, value_span)) = value { db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect); } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 65607d71805..9f1f5a26ee5 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -428,7 +428,7 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>( for early_lint in lints { sess.delay_span_bug( early_lint.span, - &format!( + format!( "failed to process buffered lint here (dummy = {})", id == ast::DUMMY_NODE_ID ), diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 595b50c4063..0082aaa4a38 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -478,8 +478,10 @@ impl EarlyLintPass for Diagnostics { } if !segments.iter().all(|(name, args)| { let arg = match name.as_str() { - "struct_span_err" | "span_note" | "span_label" | "span_help" => &args[1], - "note" | "help" => &args[0], + "struct_span_err" | "span_note" | "span_label" | "span_help" if args.len() == 2 => { + &args[1] + } + "note" | "help" if args.len() == 1 => &args[0], _ => { return false; } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 848f6a9ecb5..d7bacc6485f 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1150,6 +1150,14 @@ pub struct NoopMethodCallDiag<'a> { pub label: Span, } +#[derive(LintDiagnostic)] +#[diag(lint_suspicious_double_ref_op)] +pub struct SuspiciousDoubleRefDiag<'a> { + pub call: Symbol, + pub ty: Ty<'a>, + pub op: &'static str, +} + // pass_by_value.rs #[derive(LintDiagnostic)] #[diag(lint_pass_by_value)] diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index d67a00619dd..d054966459d 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -1,10 +1,11 @@ use crate::context::LintContext; -use crate::lints::NoopMethodCallDiag; +use crate::lints::{NoopMethodCallDiag, SuspiciousDoubleRefDiag}; use crate::LateContext; use crate::LateLintPass; use rustc_hir::def::DefKind; use rustc_hir::{Expr, ExprKind}; use rustc_middle::ty; +use rustc_middle::ty::adjustment::Adjust; use rustc_span::symbol::sym; declare_lint! { @@ -35,14 +36,44 @@ declare_lint! { "detects the use of well-known noop methods" } -declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL]); +declare_lint! { + /// The `suspicious_double_ref_op` lint checks for usage of `.clone()`/`.borrow()`/`.deref()` + /// on an `&&T` when `T: !Deref/Borrow/Clone`, which means the call will return the inner `&T`, + /// instead of performing the operation on the underlying `T` and can be confusing. + /// + /// ### Example + /// + /// ```rust + /// # #![allow(unused)] + /// struct Foo; + /// let foo = &&Foo; + /// let clone: &Foo = foo.clone(); + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Since `Foo` doesn't implement `Clone`, running `.clone()` only dereferences the double + /// reference, instead of cloning the inner type which should be what was intended. + pub SUSPICIOUS_DOUBLE_REF_OP, + Warn, + "suspicious call of trait method on `&&T`" +} + +declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL, SUSPICIOUS_DOUBLE_REF_OP]); impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // We only care about method calls. - let ExprKind::MethodCall(call, receiver, ..) = &expr.kind else { - return + let ExprKind::MethodCall(call, receiver, _, call_span) = &expr.kind else { + return; }; + + if call_span.from_expansion() { + return; + } + // We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow` // traits and ignore any other method call. let did = match cx.typeck_results().type_dependent_def(expr.hir_id) { @@ -70,25 +101,39 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { }; // (Re)check that it implements the noop diagnostic. let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return }; - if !matches!( - name, - sym::noop_method_borrow | sym::noop_method_clone | sym::noop_method_deref - ) { - return; - } + + let op = match name { + sym::noop_method_borrow => "borrow", + sym::noop_method_clone => "clone", + sym::noop_method_deref => "deref", + _ => return, + }; + let receiver_ty = cx.typeck_results().expr_ty(receiver); let expr_ty = cx.typeck_results().expr_ty_adjusted(expr); - if receiver_ty != expr_ty { - // This lint will only trigger if the receiver type and resulting expression \ - // type are the same, implying that the method call is unnecessary. + let arg_adjustments = cx.typeck_results().expr_adjustments(receiver); + + // If there is any user defined auto-deref step, then we don't want to warn. + // https://github.com/rust-lang/rust-clippy/issues/9272 + if arg_adjustments.iter().any(|adj| matches!(adj.kind, Adjust::Deref(Some(_)))) { return; } + let expr_span = expr.span; let span = expr_span.with_lo(receiver.span.hi()); - cx.emit_spanned_lint( - NOOP_METHOD_CALL, - span, - NoopMethodCallDiag { method: call.ident.name, receiver_ty, label: span }, - ); + + if receiver_ty == expr_ty { + cx.emit_spanned_lint( + NOOP_METHOD_CALL, + span, + NoopMethodCallDiag { method: call.ident.name, receiver_ty, label: span }, + ); + } else { + cx.emit_spanned_lint( + SUSPICIOUS_DOUBLE_REF_OP, + span, + SuspiciousDoubleRefDiag { call: call.ident.name, ty: expr_ty, op }, + ) + } } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a3d7bd3ef59..6fe15e21d94 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4014,7 +4014,6 @@ declare_lint! { /// ### Example /// /// ```rust - /// #![feature(c_unwind)] /// #![warn(ffi_unwind_calls)] /// /// extern "C-unwind" { @@ -4037,8 +4036,7 @@ declare_lint! { /// that desire this ability it is therefore necessary to avoid such calls. pub FFI_UNWIND_CALLS, Allow, - "call to foreign functions or function pointers with FFI-unwind ABI", - @feature_gate = sym::c_unwind; + "call to foreign functions or function pointers with FFI-unwind ABI" } declare_lint! { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7ea472ed504..e27e322db88 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -496,7 +496,8 @@ pub enum BuiltinLintDiagnostics { BreakWithLabelAndLoop(Span), NamedAsmLabel(String), UnicodeTextFlow(Span, String), - UnexpectedCfg((Symbol, Span), Option<(Symbol, Span)>), + UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), + UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), DeprecatedWhereclauseLocation(Span, String), SingleUseLifetime { /// Span of the parameter which declares this lifetime. diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 1acdc95ca8d..5ec3b95225d 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -297,7 +297,6 @@ static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) { report_fatal_error("Bad RelocModel."); } -#ifdef LLVM_RUSTLLVM /// getLongestEntryLength - Return the length of the longest entry in the table. template<typename KV> static size_t getLongestEntryLength(ArrayRef<KV> Table) { @@ -307,56 +306,68 @@ static size_t getLongestEntryLength(ArrayRef<KV> Table) { return MaxLen; } -extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) { +extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, const char* TargetCPU) { const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch(); const Triple::ArchType TargetArch = Target->getTargetTriple().getArch(); + +#if LLVM_VERSION_GE(17, 0) + const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getAllProcessorDescriptions(); +#elif defined(LLVM_RUSTLLVM) const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable(); +#else + printf("Full target CPU help is not supported by this LLVM version.\n\n"); + SubtargetSubTypeKV TargetCPUKV = { TargetCPU, {{}}, {{}} }; + const ArrayRef<SubtargetSubTypeKV> CPUTable = TargetCPUKV; +#endif unsigned MaxCPULen = getLongestEntryLength(CPUTable); printf("Available CPUs for this target:\n"); // Don't print the "native" entry when the user specifies --target with a // different arch since that could be wrong or misleading. if (HostArch == TargetArch) { + MaxCPULen = std::max(MaxCPULen, (unsigned) std::strlen("native")); const StringRef HostCPU = sys::getHostCPUName(); printf(" %-*s - Select the CPU of the current host (currently %.*s).\n", MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data()); } - for (auto &CPU : CPUTable) - printf(" %-*s\n", MaxCPULen, CPU.Key); - printf("\n"); + for (auto &CPU : CPUTable) { + // Compare cpu against current target to label the default + if (strcmp(CPU.Key, TargetCPU) == 0) { + printf(" %-*s - This is the default target CPU" + " for the current build target (currently %s).", + MaxCPULen, CPU.Key, Target->getTargetTriple().str().c_str()); + } + else { + printf(" %-*s", MaxCPULen, CPU.Key); + } + printf("\n"); + } } extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) { +#ifdef LLVM_RUSTLLVM const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable(); return FeatTable.size(); +#else + return 0; +#endif } extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index, const char** Feature, const char** Desc) { +#ifdef LLVM_RUSTLLVM const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable(); const SubtargetFeatureKV Feat = FeatTable[Index]; *Feature = Feat.Key; *Desc = Feat.Desc; -} - -#else - -extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) { - printf("Target CPU help is not supported by this LLVM version.\n\n"); -} - -extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef) { - return 0; -} - -extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef, const char**, const char**) {} #endif +} extern "C" const char* LLVMRustGetHostCPUName(size_t *len) { StringRef Name = sys::getHostCPUName(); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index cadb6b1e23f..49acd71b3e1 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -831,6 +831,28 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( return wrap(Sub); } +extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod( + LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, + const char *Name, size_t NameLen, + const char *LinkageName, size_t LinkageNameLen, + LLVMMetadataRef File, unsigned LineNo, + LLVMMetadataRef Ty, LLVMRustDIFlags Flags, + LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) { + DITemplateParameterArray TParams = + DITemplateParameterArray(unwrap<MDTuple>(TParam)); + DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags); + DINode::DIFlags llvmFlags = fromRust(Flags); + DISubprogram *Sub = Builder->createMethod( + unwrapDI<DIScope>(Scope), + StringRef(Name, NameLen), + StringRef(LinkageName, LinkageNameLen), + unwrapDI<DIFile>(File), LineNo, + unwrapDI<DISubroutineType>(Ty), + 0, 0, nullptr, // VTable params aren't used + llvmFlags, llvmSPFlags, TParams); + return wrap(Sub); +} + extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType( LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, uint64_t SizeInBits, unsigned Encoding) { diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 01b69966ca9..e6e7d25773e 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -865,6 +865,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } } + fn inject_forced_externs(&mut self) { + for (name, entry) in self.sess.opts.externs.iter() { + if entry.force { + let name_interned = Symbol::intern(name); + if !self.used_extern_options.contains(&name_interned) { + self.resolve_crate(name_interned, DUMMY_SP, CrateDepKind::Explicit); + } + } + } + } + fn inject_dependency_if( &self, krate: CrateNum, @@ -913,7 +924,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // Don't worry about pathless `--extern foo` sysroot references continue; } - if entry.nounused_dep { + if entry.nounused_dep || entry.force { // We're not worried about this one continue; } @@ -942,6 +953,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } pub fn postprocess(&mut self, krate: &ast::Crate) { + self.inject_forced_externs(); self.inject_profiler_runtime(krate); self.inject_allocator_crate(krate); self.inject_panic_runtime(krate); diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 51b41b5f6a2..a44c1dd582e 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -498,7 +498,7 @@ impl IntoDiagnostic<'_> for MultipleCandidates { diag.code(error_code!(E0464)); diag.set_span(self.span); for (i, candidate) in self.candidates.iter().enumerate() { - diag.note(&format!("candidate #{}: {}", i + 1, candidate.display())); + diag.note(format!("candidate #{}: {}", i + 1, candidate.display())); } diag } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index b855c8e4332..c83c47e722b 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -161,14 +161,6 @@ impl<'tcx> Collector<'tcx> { "raw-dylib" => { if !sess.target.is_like_windows { sess.emit_err(errors::FrameworkOnlyWindows { span }); - } else if !features.raw_dylib && sess.target.arch == "x86" { - feature_err( - &sess.parse_sess, - sym::raw_dylib, - span, - "link kind `raw-dylib` is unstable on x86", - ) - .emit(); } NativeLibKind::RawDylib } @@ -251,16 +243,6 @@ impl<'tcx> Collector<'tcx> { continue; } }; - if !features.raw_dylib { - let span = item.name_value_literal_span().unwrap(); - feature_err( - &sess.parse_sess, - sym::raw_dylib, - span, - "import name type is unstable", - ) - .emit(); - } import_name_type = Some((link_import_name_type, item.span())); } _ => { @@ -287,7 +269,7 @@ impl<'tcx> Collector<'tcx> { &sess.parse_sess, sym::$feature, span, - &format!("linking modifier `{modifier}` is unstable"), + format!("linking modifier `{modifier}` is unstable"), ) .emit(); } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index f5ffdd27cae..82c66b9dfb9 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -108,11 +108,7 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> { emit_i64(i64); emit_i32(i32); emit_i16(i16); - emit_i8(i8); - emit_bool(bool); - emit_char(char); - emit_str(&str); emit_raw_bytes(&[u8]); } } @@ -837,11 +833,12 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::AnonConst | DefKind::InlineConst | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder | DefKind::Field | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator => true, - DefKind::ForeignMod | DefKind::ImplTraitPlaceholder | DefKind::GlobalAsm => false, + DefKind::ForeignMod | DefKind::GlobalAsm => false, } } @@ -1364,9 +1361,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.params_in_repr[def_id] <- params_in_repr); if adt_def.is_enum() { - let module_children = tcx.module_children_non_reexports(local_def_id); + let module_children = tcx.module_children_local(local_def_id); record_array!(self.tables.module_children_non_reexports[def_id] <- - module_children.iter().map(|def_id| def_id.local_def_index)); + module_children.iter().map(|child| child.res.def_id().index)); } else { // For non-enum, there is only one variant, and its def_id is the adt's. debug_assert_eq!(adt_def.variants().len(), 1); @@ -1412,12 +1409,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Encode this here because we don't do it in encode_def_ids. record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); } else { - let non_reexports = tcx.module_children_non_reexports(local_def_id); + let module_children = tcx.module_children_local(local_def_id); + record_array!(self.tables.module_children_non_reexports[def_id] <- - non_reexports.iter().map(|def_id| def_id.local_def_index)); + module_children.iter().filter(|child| child.reexport_chain.is_empty()) + .map(|child| child.res.def_id().index)); record_defaulted_array!(self.tables.module_children_reexports[def_id] <- - tcx.module_children_reexports(local_def_id)); + module_children.iter().filter(|child| !child.reexport_chain.is_empty())); } } @@ -1676,9 +1675,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemKind::Trait(..) => { record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); - let module_children = tcx.module_children_non_reexports(item.owner_id.def_id); + let module_children = tcx.module_children_local(item.owner_id.def_id); record_array!(self.tables.module_children_non_reexports[def_id] <- - module_children.iter().map(|def_id| def_id.local_def_index)); + module_children.iter().map(|child| child.res.def_id().index)); let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); record_associated_item_def_ids(self, associated_item_def_ids); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index dd02463e16a..84f6b7f934d 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -357,10 +357,16 @@ define_tables! { associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>, opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>, unused_generic_params: Table<DefIndex, UnusedGenericParams>, + // Reexported names are not associated with individual `DefId`s, + // e.g. a glob import can introduce a lot of names, all with the same `DefId`. + // That's why the encoded list needs to contain `ModChild` structures describing all the names + // individually instead of `DefId`s. module_children_reexports: Table<DefIndex, LazyArray<ModChild>>, - optional: attributes: Table<DefIndex, LazyArray<ast::Attribute>>, + // For non-reexported names in a module every name is associated with a separate `DefId`, + // so we can take their names, visibilities etc from other encoded tables. module_children_non_reexports: Table<DefIndex, LazyArray<DefIndex>>, associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>, opt_def_kind: Table<DefIndex, DefKind>, diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index bd9d89deee1..c6bbf2ef0cd 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -32,6 +32,9 @@ middle_values_too_big = middle_cannot_be_normalized = unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized +middle_cycle = + a cycle occurred during layout computation + middle_strict_coherence_needs_negative_coherence = to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled .label = due to this attribute diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index c61de97d532..c266584ac28 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -231,19 +231,19 @@ pub fn explain_lint_level_source( let name = lint.name_lower(); match src { LintLevelSource::Default => { - err.note_once(&format!("`#[{}({})]` on by default", level.as_str(), name)); + err.note_once(format!("`#[{}({})]` on by default", level.as_str(), name)); } LintLevelSource::CommandLine(lint_flag_val, orig_level) => { let flag = orig_level.to_cmd_flag(); let hyphen_case_lint_name = name.replace('_', "-"); if lint_flag_val.as_str() == name { - err.note_once(&format!( + err.note_once(format!( "requested on the command line with `{} {}`", flag, hyphen_case_lint_name )); } else { let hyphen_case_flag_val = lint_flag_val.as_str().replace('_', "-"); - err.note_once(&format!( + err.note_once(format!( "`{} {}` implied by `{} {}`", flag, hyphen_case_lint_name, flag, hyphen_case_flag_val )); @@ -256,7 +256,7 @@ pub fn explain_lint_level_source( err.span_note_once(span, "the lint level is defined here"); if lint_attr_name.as_str() != name { let level_str = level.as_str(); - err.note_once(&format!( + err.note_once(format!( "`#[{}({})]` implied by `#[{}({})]`", level_str, name, level_str, lint_attr_name )); @@ -444,12 +444,12 @@ pub fn struct_lint_level( }; if future_incompatible.explain_reason { - err.warn(&explanation); + err.warn(explanation); } if !future_incompatible.reference.is_empty() { let citation = format!("for more information, see {}", future_incompatible.reference); - err.note(&citation); + err.note(citation); } } diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 967fed687b6..aeb6a1601fc 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -64,7 +64,7 @@ impl EffectiveVisibility { self.at_level(level).is_public() } - pub fn from_vis(vis: Visibility) -> EffectiveVisibility { + pub const fn from_vis(vis: Visibility) -> EffectiveVisibility { EffectiveVisibility { direct: vis, reexported: vis, @@ -72,6 +72,18 @@ impl EffectiveVisibility { reachable_through_impl_trait: vis, } } + + #[must_use] + pub fn min(mut self, lhs: EffectiveVisibility, tcx: TyCtxt<'_>) -> Self { + for l in Level::all_levels() { + let rhs_vis = self.at_level_mut(l); + let lhs_vis = *lhs.at_level(l); + if rhs_vis.is_at_least(lhs_vis, tcx) { + *rhs_vis = lhs_vis; + }; + } + self + } } /// Holds a map of effective visibilities for reachable HIR nodes. @@ -137,24 +149,6 @@ impl EffectiveVisibilities { }; } - pub fn set_public_at_level( - &mut self, - id: LocalDefId, - lazy_private_vis: impl FnOnce() -> Visibility, - level: Level, - ) { - let mut effective_vis = self - .effective_vis(id) - .copied() - .unwrap_or_else(|| EffectiveVisibility::from_vis(lazy_private_vis())); - for l in Level::all_levels() { - if l <= level { - *effective_vis.at_level_mut(l) = Visibility::Public; - } - } - self.map.insert(id, effective_vis); - } - pub fn check_invariants(&self, tcx: TyCtxt<'_>, early: bool) { if !cfg!(debug_assertions) { return; @@ -219,7 +213,7 @@ impl<Id: Eq + Hash> EffectiveVisibilities<Id> { pub fn update( &mut self, id: Id, - nominal_vis: Visibility, + nominal_vis: Option<Visibility>, lazy_private_vis: impl FnOnce() -> Visibility, inherited_effective_vis: EffectiveVisibility, level: Level, @@ -243,12 +237,11 @@ impl<Id: Eq + Hash> EffectiveVisibilities<Id> { if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level && level != l) { - calculated_effective_vis = - if nominal_vis.is_at_least(inherited_effective_vis_at_level, tcx) { - inherited_effective_vis_at_level - } else { - nominal_vis - }; + calculated_effective_vis = if let Some(nominal_vis) = nominal_vis && !nominal_vis.is_at_least(inherited_effective_vis_at_level, tcx) { + nominal_vis + } else { + inherited_effective_vis_at_level + } } // effective visibility can't be decreased at next update call for the // same id diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index b61f7806b7a..89fc864319d 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -115,8 +115,8 @@ pub fn report_unstable( soft_handler(SOFT_UNSTABLE, span, &msg) } else { let mut err = - feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg); - if let Some((inner_types, ref msg, sugg, applicability)) = suggestion { + feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), msg); + if let Some((inner_types, msg, sugg, applicability)) = suggestion { err.span_suggestion(inner_types, msg, sugg, applicability); } err.emit(); @@ -170,7 +170,7 @@ pub fn deprecation_suggestion( if let Some(suggestion) = suggestion { diag.span_suggestion_verbose( span, - &format!("replace the use of the deprecated {}", kind), + format!("replace the use of the deprecated {}", kind), suggestion, Applicability::MachineApplicable, ); @@ -599,7 +599,7 @@ impl<'tcx> TyCtxt<'tcx> { |span, def_id| { // The API could be uncallable for other reasons, for example when a private module // was referenced. - self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id)); + self.sess.delay_span_bug(span, format!("encountered unmarked API: {:?}", def_id)); }, ) } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index c5137cf0666..e45284ca506 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -134,6 +134,9 @@ pub enum InvalidProgramInfo<'tcx> { FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), /// SizeOf of unsized type was requested. SizeOfUnsizedType(Ty<'tcx>), + /// An unsized local was accessed without having been initialized. + /// This is not meaningful as we can't even have backing memory for such locals. + UninitUnsizedLocal, } impl fmt::Display for InvalidProgramInfo<'_> { @@ -150,6 +153,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { Layout(ref err) => write!(f, "{err}"), FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"), SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{ty}`"), + UninitUnsizedLocal => write!(f, "unsized local is used while uninitialized"), } } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 2490b17aac0..858a3d266ea 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -3073,13 +3073,13 @@ mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // tidy-alphabetical-start - static_assert_size!(BasicBlockData<'_>, 144); + static_assert_size!(BasicBlockData<'_>, 136); static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(SourceScopeData<'_>, 72); static_assert_size!(Statement<'_>, 32); static_assert_size!(StatementKind<'_>, 16); - static_assert_size!(Terminator<'_>, 112); - static_assert_size!(TerminatorKind<'_>, 96); + static_assert_size!(Terminator<'_>, 104); + static_assert_size!(TerminatorKind<'_>, 88); static_assert_size!(VarDebugInfo<'_>, 80); // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index a8293ba1819..33b7fe0c2dc 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -651,7 +651,7 @@ pub enum TerminatorKind<'tcx> { Assert { cond: Operand<'tcx>, expected: bool, - msg: AssertMessage<'tcx>, + msg: Box<AssertMessage<'tcx>>, target: BasicBlock, unwind: UnwindAction, }, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 0a9fcd898b9..6718605ed0b 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -192,6 +192,14 @@ macro_rules! make_mir_visitor { self.super_constant(constant, location); } + fn visit_ty_const( + &mut self, + ct: $( & $mutability)? ty::Const<'tcx>, + location: Location, + ) { + self.super_ty_const(ct, location); + } + fn visit_span( &mut self, span: $(& $mutability)? Span, @@ -410,7 +418,7 @@ macro_rules! make_mir_visitor { StatementKind::PlaceMention(place) => { self.visit_place( place, - PlaceContext::NonUse(NonUseContext::PlaceMention), + PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention), location ); } @@ -625,8 +633,9 @@ macro_rules! make_mir_visitor { self.visit_operand(operand, location); } - Rvalue::Repeat(value, _) => { + Rvalue::Repeat(value, ct) => { self.visit_operand(value, location); + self.visit_ty_const($(&$mutability)? *ct, location); } Rvalue::ThreadLocalRef(_) => {} @@ -878,12 +887,20 @@ macro_rules! make_mir_visitor { self.visit_span($(& $mutability)? *span); drop(user_ty); // no visit method for this match literal { - ConstantKind::Ty(_) => {} + ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location), ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), } } + fn super_ty_const( + &mut self, + _ct: $(& $mutability)? ty::Const<'tcx>, + _location: Location, + ) { + + } + fn super_span(&mut self, _span: $(& $mutability)? Span) { } @@ -1251,6 +1268,11 @@ pub enum NonMutatingUseContext { UniqueBorrow, /// AddressOf for *const pointer. AddressOf, + /// PlaceMention statement. + /// + /// This statement is executed as a check that the `Place` is live without reading from it, + /// so it must be considered as a non-mutating use. + PlaceMention, /// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place. /// For example, the projection `x.y` is not marked as a mutation in these cases: /// ```ignore (illustrative) @@ -1301,8 +1323,6 @@ pub enum NonUseContext { AscribeUserTy, /// The data of a user variable, for debug info. VarDebugInfo, - /// PlaceMention statement. - PlaceMention, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 6443c30e822..b425c7600ac 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -569,7 +569,7 @@ rustc_queries! { /// returns the full set of predicates. If `Some<Ident>`, then the query returns only the /// subset of super-predicates that reference traits that define the given associated type. /// This is used to avoid cycles in resolving types like `T::Item`. - query super_predicates_that_define_assoc_type(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { + query super_predicates_that_define_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing the super traits of `{}` with associated type name `{}`", tcx.def_path_str(key.0), key.1 @@ -617,13 +617,11 @@ rustc_queries! { /// `is_const_fn` function. Consider using `is_const_fn` or `is_const_fn_raw` instead. query constness(key: DefId) -> hir::Constness { desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } separate_provide_extern } query asyncness(key: DefId) -> hir::IsAsync { desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -641,14 +639,12 @@ rustc_queries! { /// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`). query is_foreign_item(key: DefId) -> bool { desc { |tcx| "checking if `{}` is a foreign item", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } separate_provide_extern } /// Returns `Some(generator_kind)` if the node pointed to by `def_id` is a generator. query generator_kind(def_id: DefId) -> Option<hir::GeneratorKind> { desc { |tcx| "looking up generator kind of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } separate_provide_extern } @@ -747,7 +743,6 @@ rustc_queries! { } query impl_polarity(impl_id: DefId) -> ty::ImplPolarity { desc { |tcx| "computing implementation polarity of `{}`", tcx.def_path_str(impl_id) } - cache_on_disk_if { impl_id.is_local() } separate_provide_extern } @@ -875,11 +870,10 @@ rustc_queries! { query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } + cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) } } query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> { @@ -1144,7 +1138,6 @@ rustc_queries! { query fn_arg_names(def_id: DefId) -> &'tcx [rustc_span::symbol::Ident] { desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } separate_provide_extern } /// Gets the rendered value of the specified constant or associated constant. @@ -1152,12 +1145,10 @@ rustc_queries! { query rendered_const(def_id: DefId) -> &'tcx String { arena_cache desc { |tcx| "rendering constant initializer of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } separate_provide_extern } query impl_parent(def_id: DefId) -> Option<DefId> { desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } separate_provide_extern } @@ -1410,7 +1401,6 @@ rustc_queries! { query impl_defaultness(def_id: DefId) -> hir::Defaultness { desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } separate_provide_extern feedable } diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index e56faff5ed4..220118ae5cc 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -1026,11 +1026,7 @@ impl<'a, 'tcx> Encoder for CacheEncoder<'a, 'tcx> { emit_i64(i64); emit_i32(i32); emit_i16(i16); - emit_i8(i8); - emit_bool(bool); - emit_char(char); - emit_str(&str); emit_raw_bytes(&[u8]); } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index d69d42bb5d3..8366567c2c3 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -444,6 +444,10 @@ pub enum ObligationCauseCode<'tcx> { AscribeUserTypeProvePredicate(Span), RustCall, + + /// Obligations to prove that a `std::ops::Drop` impl is not stronger than + /// the ADT it's being implemented for. + DropImpl, } /// The 'location' at which we try to perform HIR-based wf checking. @@ -1010,10 +1014,7 @@ impl ObjectSafetyViolation { ) => { err.span_suggestion( *span, - &format!( - "consider changing method `{}`'s `self` parameter to be `&self`", - name - ), + format!("consider changing method `{}`'s `self` parameter to be `&self`", name), "&Self", Applicability::MachineApplicable, ); @@ -1021,7 +1022,7 @@ impl ObjectSafetyViolation { ObjectSafetyViolation::AssocConst(name, _) | ObjectSafetyViolation::GAT(name, _) | ObjectSafetyViolation::Method(name, ..) => { - err.help(&format!("consider moving `{}` to another trait", name)); + err.help(format!("consider moving `{}` to another trait", name)); } } } diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 029cf793ad8..bfb740ab356 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -63,7 +63,8 @@ impl<'tcx> TyCtxt<'tcx> { Err(e) => self.tcx.const_error_with_guaranteed(c.ty(), e), Ok(Some(bac)) => { let substs = self.tcx.erase_regions(uv.substs); - bac.subst(self.tcx, substs) + let bac = bac.subst(self.tcx, substs); + return bac.fold_with(self); } Ok(None) => c, }, diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 6187fc43cf8..ad9891a5dca 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -26,7 +26,7 @@ use super::{Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, Var bitflags! { #[derive(HashStable, TyEncodable, TyDecodable)] - pub struct AdtFlags: u32 { + pub struct AdtFlags: u16 { const NO_ADT_FLAGS = 0; /// Indicates whether the ADT is an enum. const IS_ENUM = 1 << 0; diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 7536903ef96..7fc75674da5 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -506,23 +506,18 @@ macro_rules! implement_ty_decoder { impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> { $crate::__impl_decoder_methods! { + read_usize -> usize; read_u128 -> u128; read_u64 -> u64; read_u32 -> u32; read_u16 -> u16; read_u8 -> u8; - read_usize -> usize; + read_isize -> isize; read_i128 -> i128; read_i64 -> i64; read_i32 -> i32; read_i16 -> i16; - read_i8 -> i8; - read_isize -> isize; - - read_bool -> bool; - read_char -> char; - read_str -> &str; } #[inline] @@ -531,13 +526,13 @@ macro_rules! implement_ty_decoder { } #[inline] - fn position(&self) -> usize { - self.opaque.position() + fn peek_byte(&self) -> u8 { + self.opaque.peek_byte() } #[inline] - fn peek_byte(&self) -> u8 { - self.opaque.peek_byte() + fn position(&self) -> usize { + self.opaque.position() } } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 0a191ff7626..e7107c28bf4 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -114,7 +114,7 @@ impl<'tcx> Const<'tcx> { Err(e) => { tcx.sess.delay_span_bug( expr.span, - &format!("Const::from_anon_const: couldn't lit_to_const {:?}", e), + format!("Const::from_anon_const: couldn't lit_to_const {:?}", e), ); } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a309eaf048d..c2550572879 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1093,11 +1093,13 @@ impl<'tcx> TyCtxt<'tcx> { v.0 } - /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type and associated alias span when type alias is used + /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in + /// its return type, and the associated alias span when type alias is used, + /// along with a span for lifetime suggestion (if there are existing generics). pub fn return_type_impl_or_dyn_traits_with_type_alias( self, scope_def_id: LocalDefId, - ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span)> { + ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> { let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); let mut v = TraitObjectVisitor(vec![], self.hir()); // when the return type is a type alias @@ -1111,7 +1113,7 @@ impl<'tcx> TyCtxt<'tcx> { { v.visit_ty(alias_ty); if !v.0.is_empty() { - return Some((v.0, alias_generics.span)); + return Some((v.0, alias_generics.span, alias_generics.span_for_lifetime_suggestion())); } } return None; @@ -1567,11 +1569,11 @@ impl<'tcx> TyCtxt<'tcx> { /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name` /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`. - pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool { + pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool { self.super_traits_of(trait_def_id).any(|trait_did| { self.associated_items(trait_did) - .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did) - .is_some() + .filter_by_name_unhygienic(assoc_name.name) + .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did)) }) } @@ -1838,7 +1840,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline(always)] - fn check_and_mk_substs( + pub(crate) fn check_and_mk_substs( self, _def_id: DefId, substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, @@ -2238,15 +2240,6 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_substs_from_iter(iter::once(self_ty.into()).chain(rest)) } - pub fn mk_trait_ref( - self, - trait_def_id: DefId, - substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, - ) -> ty::TraitRef<'tcx> { - let substs = self.check_and_mk_substs(trait_def_id, substs); - ty::TraitRef { def_id: trait_def_id, substs, _use_mk_trait_ref_instead: () } - } - pub fn mk_alias_ty( self, def_id: DefId, @@ -2414,26 +2407,17 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// Named module children from all items except `use` and `extern crate` imports. - /// - /// In addition to regular items this list also includes struct or variant constructors, and + /// Named module children from all kinds of items, including imports. + /// In addition to regular items this list also includes struct and variant constructors, and /// items inside `extern {}` blocks because all of them introduce names into parent module. - /// For non-reexported children every such name is associated with a separate `DefId`. /// /// Module here is understood in name resolution sense - it can be a `mod` item, /// or a crate root, or an enum, or a trait. - pub fn module_children_non_reexports(self, def_id: LocalDefId) -> &'tcx [LocalDefId] { - self.resolutions(()).module_children_non_reexports.get(&def_id).map_or(&[], |v| &v[..]) - } - - /// Named module children from `use` and `extern crate` imports. /// - /// Reexported names are not associated with individual `DefId`s, - /// e.g. a glob import can introduce a lot of names, all with the same `DefId`. - /// That's why the list needs to contain `ModChild` structures describing all the names - /// individually instead of `DefId`s. - pub fn module_children_reexports(self, def_id: LocalDefId) -> &'tcx [ModChild] { - self.resolutions(()).module_children_reexports.get(&def_id).map_or(&[], |v| &v[..]) + /// This is not a query, making it a query causes perf regressions + /// (probably due to hashing spans in `ModChild`ren). + pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] { + self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..]) } } @@ -2450,15 +2434,6 @@ impl<'tcx> TyCtxtAt<'tcx> { pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> { self.tcx.ty_error_with_message(self.span, msg) } - - pub fn mk_trait_ref( - self, - trait_lang_item: LangItem, - substs: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>, - ) -> ty::TraitRef<'tcx> { - let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span)); - self.tcx.mk_trait_ref(trait_def_id, substs) - } } /// Parameter attributes that can only be determined by examining the body of a function instead diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index ae0bb4949c7..6a29063b80d 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -139,7 +139,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>( // Suggest a where clause bound for a non-type parameter. err.span_suggestion_verbose( generics.tail_span_for_predicate_suggestion(), - &format!( + format!( "consider {} `where` clause, but there might be an alternative better way to express \ this requirement", if generics.where_clause_span.is_empty() { "introducing a" } else { "extending the" }, @@ -242,7 +242,7 @@ pub fn suggest_constraining_type_params<'a>( err.span_label( param.span, - &format!("this type parameter needs to be `{}`", constraint), + format!("this type parameter needs to be `{}`", constraint), ); suggest_removing_unsized_bound(generics, &mut suggestions, param, def_id); } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index cc86cba6fda..8c69894f5ba 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -115,7 +115,7 @@ impl<'tcx> Instance<'tcx> { /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization. pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { let ty = tcx.type_of(self.def.def_id()); - tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty.skip_binder()) + tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty) } /// Finds a crate that contains a monomorphization of this instance that @@ -385,7 +385,7 @@ impl<'tcx> Instance<'tcx> { /// couldn't complete due to errors elsewhere - this is distinct /// from `Ok(None)` to avoid misleading diagnostics when an error /// has already been/will be emitted, for the original cause - #[instrument(level = "debug", skip(tcx))] + #[instrument(level = "debug", skip(tcx), ret)] pub fn resolve( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -578,14 +578,15 @@ impl<'tcx> Instance<'tcx> { self.def.has_polymorphic_mir_body().then_some(self.substs) } - pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T + pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T where T: TypeFoldable<TyCtxt<'tcx>> + Copy, { + let v = v.map_bound(|v| *v); if let Some(substs) = self.substs_for_mir_body() { - EarlyBinder(*v).subst(tcx, substs) + v.subst(tcx, substs) } else { - *v + v.skip_binder() } } @@ -594,7 +595,7 @@ impl<'tcx> Instance<'tcx> { &self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - v: T, + v: EarlyBinder<T>, ) -> T where T: TypeFoldable<TyCtxt<'tcx>> + Clone, @@ -602,7 +603,7 @@ impl<'tcx> Instance<'tcx> { if let Some(substs) = self.substs_for_mir_body() { tcx.subst_and_normalize_erasing_regions(substs, param_env, v) } else { - tcx.normalize_erasing_regions(param_env, v) + tcx.normalize_erasing_regions(param_env, v.skip_binder()) } } @@ -611,7 +612,7 @@ impl<'tcx> Instance<'tcx> { &self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - v: T, + v: EarlyBinder<T>, ) -> Result<T, NormalizationError<'tcx>> where T: TypeFoldable<TyCtxt<'tcx>> + Clone, @@ -619,7 +620,7 @@ impl<'tcx> Instance<'tcx> { if let Some(substs) = self.substs_for_mir_body() { tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v) } else { - tcx.try_normalize_erasing_regions(param_env, v) + tcx.try_normalize_erasing_regions(param_env, v.skip_binder()) } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 6e6b7c39ecb..f2a2e67cf82 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -210,6 +210,7 @@ pub enum LayoutError<'tcx> { Unknown(Ty<'tcx>), SizeOverflow(Ty<'tcx>), NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>), + Cycle, } impl IntoDiagnostic<'_, !> for LayoutError<'_> { @@ -230,6 +231,9 @@ impl IntoDiagnostic<'_, !> for LayoutError<'_> { diag.set_arg("failure_ty", e.get_type_for_failure()); diag.set_primary_message(fluent::middle_cannot_be_normalized); } + LayoutError::Cycle => { + diag.set_primary_message(fluent::middle_cycle); + } } diag } @@ -250,6 +254,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { t, e.get_type_for_failure() ), + LayoutError::Cycle => write!(f, "a cycle occurred during layout computation"), } } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index db6b35026a8..88b084bbccb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -165,8 +165,7 @@ pub struct ResolverGlobalCtxt { pub effective_visibilities: EffectiveVisibilities, pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>, pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>, - pub module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>, - pub module_children_reexports: LocalDefIdMap<Vec<ModChild>>, + pub module_children: LocalDefIdMap<Vec<ModChild>>, pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>, pub main_def: Option<MainDefinition>, pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>, @@ -1211,6 +1210,18 @@ impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef } } +impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for TraitRef<'tcx> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> { + ty::Binder::dummy(self).to_predicate(tcx) + } +} + +impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for TraitPredicate<'tcx> { + fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> { + ty::Binder::dummy(self) + } +} + impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.map_bound(|p| PredicateKind::Clause(Clause::Trait(p))).to_predicate(tcx) @@ -1235,6 +1246,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { } } +impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { + PredicateKind::Clause(Clause::Trait(self)).to_predicate(tcx) + } +} + impl<'tcx> Predicate<'tcx> { pub fn to_opt_poly_trait_pred(self) -> Option<PolyTraitPredicate<'tcx>> { let predicate = self.kind(); @@ -1722,7 +1739,7 @@ pub struct Destructor { bitflags! { #[derive(HashStable, TyEncodable, TyDecodable)] - pub struct VariantFlags: u32 { + pub struct VariantFlags: u8 { const NO_VARIANT_FLAGS = 0; /// Indicates whether the field list of this variant is `#[non_exhaustive]`. const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0; @@ -2109,10 +2126,9 @@ impl<'tcx> TyCtxt<'tcx> { /// See [`item_name`][Self::item_name] for more information. pub fn opt_item_ident(self, def_id: DefId) -> Option<Ident> { let def = self.opt_item_name(def_id)?; - let span = def_id - .as_local() - .and_then(|id| self.def_ident_span(id)) - .unwrap_or(rustc_span::DUMMY_SP); + let span = self + .def_ident_span(def_id) + .unwrap_or_else(|| bug!("missing ident span for {def_id:?}")); Some(Ident::new(def, span)) } diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 7c59879a187..9332b0430ff 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -139,7 +139,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: T, + value: EarlyBinder<T>, ) -> T where T: TypeFoldable<TyCtxt<'tcx>>, @@ -151,7 +151,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env={:?})", param_substs, value, param_env, ); - let substituted = EarlyBinder(value).subst(self, param_substs); + let substituted = value.subst(self, param_substs); self.normalize_erasing_regions(param_env, substituted) } @@ -163,7 +163,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: T, + value: EarlyBinder<T>, ) -> Result<T, NormalizationError<'tcx>> where T: TypeFoldable<TyCtxt<'tcx>>, @@ -175,7 +175,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env={:?})", param_substs, value, param_env, ); - let substituted = EarlyBinder(value).subst(self, param_substs); + let substituted = value.subst(self, param_substs); self.try_normalize_erasing_regions(param_env, substituted) } } diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 751f3066c9c..72710b78c93 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -177,7 +177,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> { .sess .struct_span_err( self.span, - &format!( + format!( "type parameter `{}` is part of concrete type but not \ used in parameter list for the `impl Trait` type alias", ty diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 5ce32c7aaaa..64e7480e626 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -169,8 +169,11 @@ pub trait Printer<'tcx>: Sized { self.path_append( |cx: Self| { if trait_qualify_parent { - let trait_ref = - cx.tcx().mk_trait_ref(parent_def_id, parent_substs.iter().copied()); + let trait_ref = ty::TraitRef::new( + cx.tcx(), + parent_def_id, + parent_substs.iter().copied(), + ); cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) } else { cx.print_def_path(parent_def_id, parent_substs) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2aced27f7bb..b7e780b94ef 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2633,6 +2633,12 @@ macro_rules! define_print_and_forward_display { #[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>); +impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintOnlyTraitPath<'tcx> { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + self.to_string().into_diagnostic_arg() + } +} + impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self, f) @@ -2816,6 +2822,9 @@ define_print_and_forward_display! { if let ty::BoundConstness::ConstIfConst = self.constness && cx.tcx().features().const_trait_impl { p!("~const "); } + if let ty::ImplPolarity::Negative = self.polarity { + p!("!"); + } p!(print(self.trait_ref.print_only_trait_path())) } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index c6d10f4741a..7f28ed6c263 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -315,7 +315,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> { Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id))) } else { let substs = relate_substs(relation, a.substs, b.substs)?; - Ok(relation.tcx().mk_trait_ref(a.def_id, substs)) + Ok(ty::TraitRef::new(relation.tcx(), a.def_id, substs)) } } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 7bda20ffe9a..646384eebc8 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -727,13 +727,13 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { ExistentialPredicate::AutoTrait(did) => { let generics = tcx.generics_of(did); let trait_ref = if generics.params.len() == 1 { - tcx.mk_trait_ref(did, [self_ty]) + ty::TraitRef::new(tcx, did, [self_ty]) } else { // If this is an ill-formed auto trait, then synthesize // new error substs for the missing generics. let err_substs = ty::InternalSubsts::extend_with_error(tcx, did, &[self_ty.into()]); - tcx.mk_trait_ref(did, err_substs) + ty::TraitRef::new(tcx, did, err_substs) }; self.rebind(trait_ref).without_const().to_predicate(tcx) } @@ -820,36 +820,68 @@ pub struct TraitRef<'tcx> { pub def_id: DefId, pub substs: SubstsRef<'tcx>, /// This field exists to prevent the creation of `TraitRef` without - /// calling [TyCtxt::mk_trait_ref]. - pub(super) _use_mk_trait_ref_instead: (), + /// calling [`TraitRef::new`]. + pub(super) _use_trait_ref_new_instead: (), } impl<'tcx> TraitRef<'tcx> { + pub fn new( + tcx: TyCtxt<'tcx>, + trait_def_id: DefId, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, + ) -> Self { + let substs = tcx.check_and_mk_substs(trait_def_id, substs); + Self { def_id: trait_def_id, substs, _use_trait_ref_new_instead: () } + } + + pub fn from_lang_item( + tcx: TyCtxt<'tcx>, + trait_lang_item: LangItem, + span: Span, + substs: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>, + ) -> Self { + let trait_def_id = tcx.require_lang_item(trait_lang_item, Some(span)); + Self::new(tcx, trait_def_id, substs) + } + + pub fn from_method( + tcx: TyCtxt<'tcx>, + trait_id: DefId, + substs: SubstsRef<'tcx>, + ) -> ty::TraitRef<'tcx> { + let defs = tcx.generics_of(trait_id); + ty::TraitRef::new(tcx, trait_id, tcx.mk_substs(&substs[..defs.params.len()])) + } + + /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi` + /// are the parameters defined on trait. + pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> { + ty::TraitRef::new(tcx, def_id, InternalSubsts::identity_for_item(tcx, def_id)) + } + pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { - tcx.mk_trait_ref( + ty::TraitRef::new( + tcx, self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)), ) } - /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi` - /// are the parameters defined on trait. - pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> { - ty::Binder::dummy(tcx.mk_trait_ref(def_id, InternalSubsts::identity_for_item(tcx, def_id))) + /// Converts this trait ref to a trait predicate with a given `constness` and a positive polarity. + #[inline] + pub fn with_constness(self, constness: ty::BoundConstness) -> ty::TraitPredicate<'tcx> { + ty::TraitPredicate { trait_ref: self, constness, polarity: ty::ImplPolarity::Positive } } + /// Converts this trait ref to a trait predicate without `const` and a positive polarity. #[inline] - pub fn self_ty(&self) -> Ty<'tcx> { - self.substs.type_at(0) + pub fn without_const(self) -> ty::TraitPredicate<'tcx> { + self.with_constness(ty::BoundConstness::NotConst) } - pub fn from_method( - tcx: TyCtxt<'tcx>, - trait_id: DefId, - substs: SubstsRef<'tcx>, - ) -> ty::TraitRef<'tcx> { - let defs = tcx.generics_of(trait_id); - tcx.mk_trait_ref(trait_id, tcx.mk_substs(&substs[..defs.params.len()])) + #[inline] + pub fn self_ty(&self) -> Ty<'tcx> { + self.substs.type_at(0) } } @@ -907,7 +939,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); - tcx.mk_trait_ref(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter())) + ty::TraitRef::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter())) } } @@ -1226,7 +1258,7 @@ impl<'tcx> AliasTy<'tcx> { let trait_def_id = self.trait_def_id(tcx); let trait_generics = tcx.generics_of(trait_def_id); ( - tcx.mk_trait_ref(trait_def_id, self.substs.truncate_to(tcx, trait_generics)), + ty::TraitRef::new(tcx, trait_def_id, self.substs.truncate_to(tcx, trait_generics)), &self.substs[trait_generics.count()..], ) } @@ -1240,7 +1272,7 @@ impl<'tcx> AliasTy<'tcx> { /// as well. pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { let def_id = self.trait_def_id(tcx); - tcx.mk_trait_ref(def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id))) + ty::TraitRef::new(tcx, def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id))) } pub fn self_ty(self) -> Ty<'tcx> { @@ -2400,6 +2432,13 @@ impl<'tcx> Ty<'tcx> { _ => None, } } + + pub fn is_c_void(self, tcx: TyCtxt<'_>) -> bool { + match self.kind() { + ty::Adt(adt, _) => tcx.lang_items().get(LangItem::CVoid) == Some(adt.did()), + _ => false, + } + } } /// Extra information about why we ended up with a particular variance. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c77985c6bd6..e5b2d342452 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -360,16 +360,16 @@ impl<'tcx> TyCtxt<'tcx> { let ty = self.type_of(adt_did).subst_identity(); let mut dtor_candidate = None; self.for_each_relevant_impl(drop_trait, ty, |impl_did| { - let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { - self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function"); - return; - }; - if validate(self, impl_did).is_err() { // Already `ErrorGuaranteed`, no need to delay a span bug here. return; } + let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { + self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function"); + return; + }; + if let Some((old_item_id, _)) = dtor_candidate { self.sess .struct_span_err(self.def_span(item_id), "multiple drop impls found") diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index b73ae593905..3dfd0824f98 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -31,8 +31,8 @@ fn opt_span_bug_fmt<S: Into<MultiSpan>>( tls::with_opt(move |tcx| { let msg = format!("{}: {}", location, args); match (tcx, span) { - (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg), - (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg), + (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, msg), + (Some(tcx), None) => tcx.sess.diagnostic().bug(msg), (None, _) => panic_any(msg), } }) diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 5c38c0acc7f..c62c33d4dfc 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -106,6 +106,12 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<ty::Binder<'_, ty::F } } +impl<'tcx, T> Value<TyCtxt<'tcx>, DepKind> for Result<T, ty::layout::LayoutError<'_>> { + fn from_cycle_error(_tcx: TyCtxt<'tcx>, _cycle: &[QueryInfo<DepKind>]) -> Self { + Err(ty::layout::LayoutError::Cycle) + } +} + // item_and_field_ids should form a cycle where each field contains the // type in the next element in the list pub fn recursive_type_error( diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index fbcfd433724..59549435233 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -146,6 +146,12 @@ pub(crate) fn lit_to_mir_constant<'tcx>( let id = tcx.allocate_bytes(data); ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx)) } + (ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) => + { + let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); + let allocation = tcx.mk_const_alloc(allocation); + ConstValue::Slice { data: allocation, start: 0, end: data.len() } + } (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) } diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 4c66c5b8eae..56c87c402fe 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -1172,7 +1172,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TerminatorKind::Assert { cond, expected, - msg, + msg: Box::new(msg), target: success_block, unwind: UnwindAction::Continue, }, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 66d29931400..8cb3b00c9ad 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -672,7 +672,7 @@ fn non_exhaustive_match<'p, 'tcx>( ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local()); adt_defined_here(cx, &mut err, scrut_ty, &witnesses); - err.note(&format!( + err.note(format!( "the matched value is of type `{}`{}", scrut_ty, if is_variant_list_non_exhaustive { ", which is marked as non-exhaustive" } else { "" } @@ -682,13 +682,13 @@ fn non_exhaustive_match<'p, 'tcx>( && witnesses.len() == 1 && matches!(witnesses[0].ctor(), Constructor::NonExhaustive) { - err.note(&format!( + err.note(format!( "`{}` does not have a fixed maximum value, so a wildcard `_` is necessary to match \ exhaustively", scrut_ty, )); if cx.tcx.sess.is_nightly_build() { - err.help(&format!( + err.help(format!( "add `#![feature(precise_pointer_size_matching)]` to the crate attributes to \ enable precise `{}` matching", scrut_ty, @@ -793,9 +793,9 @@ fn non_exhaustive_match<'p, 'tcx>( }, ); if let Some((span, sugg)) = suggestion { - err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders); + err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders); } else { - err.help(&msg); + err.help(msg); } err.emit(); } @@ -857,7 +857,7 @@ fn adt_defined_here<'p, 'tcx>( for pat in spans { span.push_span_label(pat, "not covered"); } - err.span_note(span, &format!("`{}` defined here", ty)); + err.span_note(span, format!("`{}` defined here", ty)); } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 6a7a9a92279..c73f8284ca5 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -191,7 +191,7 @@ impl<'tcx> ConstToPat<'tcx> { self.tcx(), ObligationCause::dummy(), self.param_env, - self.tcx().mk_trait_ref(partial_eq_trait_id, [ty, ty]), + ty::TraitRef::new(self.tcx(), partial_eq_trait_id, [ty, ty]), ); // FIXME: should this call a `predicate_must_hold` variant instead? diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 0a3423bdd37..1cf2f7ec0ff 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -229,7 +229,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { self.lower_pattern_range(ty, lc, hc, end, lo_span, lo_expr, hi_expr) } None => { - let msg = &format!( + let msg = format!( "found bad range pattern `{:?}` outside of error recovery", (&lo, &hi), ); diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index d8f66a1755b..f229b10c447 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -685,10 +685,9 @@ enum ArmType { /// For example, if we are constructing a witness for the match against /// /// ```compile_fail,E0004 -/// # #![feature(type_ascription)] /// struct Pair(Option<(u32, u32)>, bool); /// # fn foo(p: Pair) { -/// match (p: Pair) { +/// match p { /// Pair(None, _) => {} /// Pair(_, false) => {} /// } diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index bc67aa476f1..aeca0073304 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -197,6 +197,7 @@ impl DefUse { | NonMutatingUseContext::Copy | NonMutatingUseContext::Inspect | NonMutatingUseContext::Move + | NonMutatingUseContext::PlaceMention | NonMutatingUseContext::ShallowBorrow | NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::UniqueBorrow, diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index e99712eeef8..d60184e0ebe 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -224,10 +224,10 @@ fn insert_alignment_check<'tcx>( cond: Operand::Copy(is_ok), expected: true, target: new_block, - msg: AssertKind::MisalignedPointerDereference { + msg: Box::new(AssertKind::MisalignedPointerDereference { required: Operand::Copy(alignment), found: Operand::Copy(addr), - }, + }), unwind: UnwindAction::Terminate, }, }); diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 880745b8f0e..7f995c69a48 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -21,9 +21,9 @@ use rustc_target::spec::abi::Abi as CallAbi; use crate::MirPass; use rustc_const_eval::interpret::{ - self, compile_time_machine, AllocId, ConstAllocation, ConstValue, CtfeValidationMode, Frame, - ImmTy, Immediate, InterpCx, InterpResult, LocalValue, MemoryKind, OpTy, PlaceTy, Pointer, - Scalar, StackPopCleanup, + self, compile_time_machine, AllocId, ConstAllocation, ConstValue, Frame, ImmTy, Immediate, + InterpCx, InterpResult, LocalValue, MemoryKind, OpTy, PlaceTy, Pointer, Scalar, + StackPopCleanup, }; /// The maximum number of bytes that we'll allocate space for a local or the return value. @@ -464,16 +464,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - // Do not try creating references, nor any types with potentially-complex - // invariants. This avoids an issue where checking validity would do a - // bunch of work generating a nice message about the invariant violation, - // only to not show it to anyone (since this isn't the lint). - Rvalue::Cast(CastKind::Transmute, op, dst_ty) if !dst_ty.is_primitive() => { - trace!("skipping Transmute of {:?} to {:?}", op, dst_ty); - - return None; - } - // There's no other checking to do at this time. Rvalue::Aggregate(..) | Rvalue::Use(..) @@ -591,18 +581,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } trace!("attempting to replace {:?} with {:?}", rval, value); - if let Err(e) = self.ecx.const_validate_operand( - value, - vec![], - // FIXME: is ref tracking too expensive? - // FIXME: what is the point of ref tracking if we do not even check the tracked refs? - &mut interpret::RefTracking::empty(), - CtfeValidationMode::Regular, - ) { - trace!("validation error, attempt failed: {:?}", e); - return; - } - // FIXME> figure out what to do when read_immediate_raw fails let imm = self.ecx.read_immediate_raw(value).ok(); @@ -736,13 +714,22 @@ impl CanConstProp { } } -impl Visitor<'_> for CanConstProp { +impl<'tcx> Visitor<'tcx> for CanConstProp { + fn visit_place(&mut self, place: &Place<'tcx>, mut context: PlaceContext, loc: Location) { + use rustc_middle::mir::visit::PlaceContext::*; + + // Dereferencing just read the addess of `place.local`. + if place.projection.first() == Some(&PlaceElem::Deref) { + context = NonMutatingUse(NonMutatingUseContext::Copy); + } + + self.visit_local(place.local, context, loc); + self.visit_projection(place.as_ref(), context, loc); + } + fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) { use rustc_middle::mir::visit::PlaceContext::*; match context { - // Projections are fine, because `&mut foo.x` will be caught by - // `MutatingUseContext::Borrow` elsewhere. - MutatingUse(MutatingUseContext::Projection) // These are just stores, where the storing is not propagatable, but there may be later // mutations of the same local via `Store` | MutatingUse(MutatingUseContext::Call) @@ -773,7 +760,7 @@ impl Visitor<'_> for CanConstProp { NonMutatingUse(NonMutatingUseContext::Copy) | NonMutatingUse(NonMutatingUseContext::Move) | NonMutatingUse(NonMutatingUseContext::Inspect) - | NonMutatingUse(NonMutatingUseContext::Projection) + | NonMutatingUse(NonMutatingUseContext::PlaceMention) | NonUse(_) => {} // These could be propagated with a smarter analysis or just some careful thinking about @@ -792,6 +779,8 @@ impl Visitor<'_> for CanConstProp { trace!("local {:?} can't be propagated because it's used: {:?}", local, context); self.can_const_prop[local] = ConstPropMode::NoPropagation; } + MutatingUse(MutatingUseContext::Projection) + | NonMutatingUse(NonMutatingUseContext::Projection) => bug!("visit_place should not pass {context:?} for {local:?}"), } } } diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 443f469ce52..98e7a519c20 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -366,7 +366,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { if maybe_dead { self.tcx.sess.delay_span_bug( terminator.source_info.span, - &format!( + format!( "drop of untracked, uninitialized value {:?}, place {:?} ({:?})", bb, place, path ), @@ -440,7 +440,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { ) { self.tcx.sess.delay_span_bug( terminator.source_info.span, - &format!("drop of untracked value {:?}", bb), + format!("drop of untracked value {:?}", bb), ); } // A drop and replace behind a pointer/array/whatever. diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index e44dd084b2d..9e16c400f14 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -865,7 +865,7 @@ fn sanitize_witness<'tcx>( _ => { tcx.sess.delay_span_bug( body.span, - &format!("unexpected generator witness type {:?}", witness.kind()), + format!("unexpected generator witness type {:?}", witness.kind()), ); return; } @@ -1150,7 +1150,7 @@ fn insert_panic_block<'tcx>( literal: ConstantKind::from_bool(tcx, false), })), expected: true, - msg: message, + msg: Box::new(message), target: assert_block, unwind: UnwindAction::Continue, }; @@ -1451,8 +1451,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { ) } _ => { - tcx.sess - .delay_span_bug(body.span, &format!("unexpected generator type {}", gen_ty)); + tcx.sess.delay_span_bug(body.span, format!("unexpected generator type {}", gen_ty)); return; } }; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 71bdfd5aae1..ece20d8d3e6 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -180,7 +180,7 @@ impl<'tcx> Inliner<'tcx> { let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions( self.tcx, self.param_env, - callee_body.clone(), + ty::EarlyBinder(callee_body.clone()), ) else { return Err("failed to normalize callee body"); }; @@ -444,7 +444,9 @@ impl<'tcx> Inliner<'tcx> { work_list.push(target); // If the place doesn't actually need dropping, treat it like a regular goto. - let ty = callsite.callee.subst_mir(self.tcx, &place.ty(callee_body, tcx).ty); + let ty = callsite + .callee + .subst_mir(self.tcx, ty::EarlyBinder(&place.ty(callee_body, tcx).ty)); if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind { work_list.push(unwind); } @@ -788,7 +790,9 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { match terminator.kind { TerminatorKind::Drop { ref place, unwind, .. } => { // If the place doesn't actually need dropping, treat it like a regular goto. - let ty = self.instance.subst_mir(tcx, &place.ty(self.callee_body, tcx).ty); + let ty = self + .instance + .subst_mir(tcx, ty::EarlyBinder(&place.ty(self.callee_body, tcx).ty)); if ty.needs_drop(tcx, self.param_env) { self.cost += CALL_PENALTY; if let UnwindAction::Cleanup(_) = unwind { @@ -799,7 +803,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } } TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => { - let fn_ty = self.instance.subst_mir(tcx, &f.literal.ty()); + let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder(&f.literal.ty())); self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) { // Don't give intrinsics the extra penalty for calls INSTR_COST diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 6046c3876be..1ccf06f6153 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -44,7 +44,11 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( ) -> bool { trace!(%caller); for &(callee, substs) in tcx.mir_inliner_callees(caller.def) { - let Ok(substs) = caller.try_subst_mir_and_normalize_erasing_regions(tcx, param_env, substs) else { + let Ok(substs) = caller.try_subst_mir_and_normalize_erasing_regions( + tcx, + param_env, + ty::EarlyBinder(substs), + ) else { trace!(?caller, ?param_env, ?substs, "cannot normalize, skipping"); continue; }; diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 432852a1fdd..6bff535586a 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -1,6 +1,6 @@ //! Performs various peephole optimizations. -use crate::simplify::combine_duplicate_switch_targets; +use crate::simplify::simplify_duplicate_switch_targets; use crate::MirPass; use rustc_hir::Mutability; use rustc_middle::mir::*; @@ -10,15 +10,15 @@ use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; use rustc_span::symbol::Symbol; use rustc_target::abi::FieldIdx; -pub struct InstCombine; +pub struct InstSimplify; -impl<'tcx> MirPass<'tcx> for InstCombine { +impl<'tcx> MirPass<'tcx> for InstSimplify { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { sess.mir_opt_level() > 0 } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let ctx = InstCombineContext { + let ctx = InstSimplifyContext { tcx, local_decls: &body.local_decls, param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()), @@ -27,43 +27,43 @@ impl<'tcx> MirPass<'tcx> for InstCombine { for statement in block.statements.iter_mut() { match statement.kind { StatementKind::Assign(box (_place, ref mut rvalue)) => { - ctx.combine_bool_cmp(&statement.source_info, rvalue); - ctx.combine_ref_deref(&statement.source_info, rvalue); - ctx.combine_len(&statement.source_info, rvalue); - ctx.combine_cast(&statement.source_info, rvalue); + ctx.simplify_bool_cmp(&statement.source_info, rvalue); + ctx.simplify_ref_deref(&statement.source_info, rvalue); + ctx.simplify_len(&statement.source_info, rvalue); + ctx.simplify_cast(&statement.source_info, rvalue); } _ => {} } } - ctx.combine_primitive_clone( + ctx.simplify_primitive_clone( &mut block.terminator.as_mut().unwrap(), &mut block.statements, ); - ctx.combine_intrinsic_assert( + ctx.simplify_intrinsic_assert( &mut block.terminator.as_mut().unwrap(), &mut block.statements, ); - combine_duplicate_switch_targets(block.terminator.as_mut().unwrap()); + simplify_duplicate_switch_targets(block.terminator.as_mut().unwrap()); } } } -struct InstCombineContext<'tcx, 'a> { +struct InstSimplifyContext<'tcx, 'a> { tcx: TyCtxt<'tcx>, local_decls: &'a LocalDecls<'tcx>, param_env: ParamEnv<'tcx>, } -impl<'tcx> InstCombineContext<'tcx, '_> { - fn should_combine(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool { +impl<'tcx> InstSimplifyContext<'tcx, '_> { + fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool { self.tcx.consider_optimizing(|| { - format!("InstCombine - Rvalue: {:?} SourceInfo: {:?}", rvalue, source_info) + format!("InstSimplify - Rvalue: {:?} SourceInfo: {:?}", rvalue, source_info) }) } /// Transform boolean comparisons into logical operations. - fn combine_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { match rvalue { Rvalue::BinaryOp(op @ (BinOp::Eq | BinOp::Ne), box (a, b)) => { let new = match (op, self.try_eval_bool(a), self.try_eval_bool(b)) { @@ -94,7 +94,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { _ => None, }; - if let Some(new) = new && self.should_combine(source_info, rvalue) { + if let Some(new) = new && self.should_simplify(source_info, rvalue) { *rvalue = new; } } @@ -109,14 +109,14 @@ impl<'tcx> InstCombineContext<'tcx, '_> { } /// Transform "&(*a)" ==> "a". - fn combine_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Ref(_, _, place) = rvalue { if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() { if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty { return; } - if !self.should_combine(source_info, rvalue) { + if !self.should_simplify(source_info, rvalue) { return; } @@ -129,11 +129,11 @@ impl<'tcx> InstCombineContext<'tcx, '_> { } /// Transform "Len([_; N])" ==> "N". - fn combine_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Len(ref place) = *rvalue { let place_ty = place.ty(self.local_decls, self.tcx).ty; if let ty::Array(_, len) = *place_ty.kind() { - if !self.should_combine(source_info, rvalue) { + if !self.should_simplify(source_info, rvalue) { return; } @@ -144,7 +144,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { } } - fn combine_cast(&self, _source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_cast(&self, _source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Cast(kind, operand, cast_ty) = rvalue { let operand_ty = operand.ty(self.local_decls, self.tcx); if operand_ty == *cast_ty { @@ -196,7 +196,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { } } - fn combine_primitive_clone( + fn simplify_primitive_clone( &self, terminator: &mut Terminator<'tcx>, statements: &mut Vec<Statement<'tcx>>, @@ -239,7 +239,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { if !self.tcx.consider_optimizing(|| { format!( - "InstCombine - Call: {:?} SourceInfo: {:?}", + "InstSimplify - Call: {:?} SourceInfo: {:?}", (fn_def_id, fn_substs), terminator.source_info ) @@ -262,7 +262,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { terminator.kind = TerminatorKind::Goto { target: destination_block }; } - fn combine_intrinsic_assert( + fn simplify_intrinsic_assert( &self, terminator: &mut Terminator<'tcx>, _statements: &mut Vec<Statement<'tcx>>, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 25d7db0ee60..f25a9f042c4 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -73,7 +73,7 @@ mod ffi_unwind_calls; mod function_item_references; mod generator; mod inline; -mod instcombine; +mod instsimplify; mod large_enums; mod lower_intrinsics; mod lower_slice_len; @@ -547,7 +547,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &match_branches::MatchBranchSimplification, // inst combine is after MatchBranchSimplification to clean up Ne(_1, false) &multiple_return_terminators::MultipleReturnTerminators, - &instcombine::InstCombine, + &instsimplify::InstSimplify, &separate_const_switch::SeparateConstSwitch, &simplify::SimplifyLocals::BeforeConstProp, ©_prop::CopyProp, @@ -616,13 +616,10 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_ return tcx.arena.alloc(IndexVec::new()); } - let tainted_by_errors = tcx.mir_borrowck(def).tainted_by_errors; + tcx.ensure_with_value().mir_borrowck(def); let mut promoted = tcx.mir_promoted(def).1.steal(); for body in &mut promoted { - if let Some(error_reported) = tainted_by_errors { - body.tainted_by_errors = Some(error_reported); - } run_analysis_to_runtime_passes(tcx, body); } diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 62b727674c5..69ba4840146 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -179,6 +179,29 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } } } + sym::write_via_move => { + let target = target.unwrap(); + let Ok([ptr, val]) = <[_; 2]>::try_from(std::mem::take(args)) else { + span_bug!( + terminator.source_info.span, + "Wrong number of arguments for write_via_move intrinsic", + ); + }; + let derefed_place = + if let Some(place) = ptr.place() && let Some(local) = place.as_local() { + tcx.mk_place_deref(local.into()) + } else { + span_bug!(terminator.source_info.span, "Only passing a local is supported"); + }; + block.statements.push(Statement { + source_info: terminator.source_info, + kind: StatementKind::Assign(Box::new(( + derefed_place, + Rvalue::Use(val), + ))), + }); + terminator.kind = TerminatorKind::Goto { target }; + } sym::discriminant_value => { if let (Some(target), Some(arg)) = (*target, args[0].place()) { let arg = tcx.mk_place_deref(arg); diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 7e0cef025f7..1b96df3aed5 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -278,7 +278,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } -pub fn combine_duplicate_switch_targets(terminator: &mut Terminator<'_>) { +pub fn simplify_duplicate_switch_targets(terminator: &mut Terminator<'_>) { if let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind { let otherwise = targets.otherwise(); if targets.iter().any(|t| t.1 == otherwise) { @@ -310,7 +310,7 @@ pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut B } } - combine_duplicate_switch_targets(terminator); + simplify_duplicate_switch_targets(terminator); self.super_terminator(terminator, location); } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 5ac9c8e2073..55c937b305a 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -677,7 +677,7 @@ impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> { self.instance.subst_mir_and_normalize_erasing_regions( self.tcx, ty::ParamEnv::reveal_all(), - value, + ty::EarlyBinder(value), ) } } @@ -843,7 +843,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { } } mir::TerminatorKind::Assert { ref msg, .. } => { - let lang_item = match msg { + let lang_item = match &**msg { mir::AssertKind::BoundsCheck { .. } => LangItem::PanicBoundsCheck, _ => LangItem::Panic, }; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index aea9f719027..7253acf61e6 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -30,8 +30,12 @@ fn custom_coerce_unsize_info<'tcx>( source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> CustomCoerceUnsized { - let trait_ref = - ty::Binder::dummy(tcx.mk_trait_ref(LangItem::CoerceUnsized, [source_ty, target_ty])); + let trait_ref = ty::Binder::dummy(ty::TraitRef::from_lang_item( + tcx.tcx, + LangItem::CoerceUnsized, + tcx.span, + [source_ty, target_ty], + )); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 03183a40660..37b7f6bf8a8 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -310,7 +310,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( let impl_self_ty = tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - tcx.type_of(impl_def_id).skip_binder(), + tcx.type_of(impl_def_id), ); if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) { return Some(def_id); diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs index 33e1f6ce342..d12bfc6f6bb 100644 --- a/compiler/rustc_monomorphize/src/util.rs +++ b/compiler/rustc_monomorphize/src/util.rs @@ -29,12 +29,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In let before_feature_tys = tcx.subst_and_normalize_erasing_regions( closure_instance.substs, param_env, - before_feature_tys, + ty::EarlyBinder(before_feature_tys), ); let after_feature_tys = tcx.subst_and_normalize_erasing_regions( closure_instance.substs, param_env, - after_feature_tys, + ty::EarlyBinder(after_feature_tys), ); let new_size = tcx diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 9c4fac84fc2..cd296dca133 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -420,6 +420,15 @@ parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of parse_expected_fn_path_found_fn_keyword = expected identifier, found keyword `fn` .suggestion = use `Fn` to refer to the trait +parse_path_single_colon = path separator must be a double colon + .suggestion = use a double colon instead + +parse_colon_as_semi = statements are terminated with a semicolon + .suggestion = use a semicolon instead + +parse_type_ascription_removed = + if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> + parse_where_clause_before_tuple_struct_body = where clauses are not allowed before tuple struct bodies .label = unexpected where clause .name_label = while parsing this tuple struct @@ -606,13 +615,6 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword .help = `dyn` is only needed at the start of a trait `+`-separated list .suggestion = remove this keyword -parse_negative_bounds_not_supported = negative bounds are not supported - .label = negative bounds are not supported - .suggestion = {$num_bounds -> - [one] remove the bound - *[other] remove the bounds - } - parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` parse_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide @@ -763,7 +765,8 @@ parse_assoc_lifetime = associated lifetimes are not supported parse_tilde_const_lifetime = `~const` may only modify trait bounds, not lifetime bounds -parse_maybe_lifetime = `?` may only modify trait bounds, not lifetime bounds +parse_modifier_lifetime = `{$sigil}` may only modify trait bounds, not lifetime bounds + .suggestion = remove the `{$sigil}` parse_parenthesized_lifetime = parenthesized lifetime bounds are not supported .suggestion = remove the parentheses diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index f286707a9c0..010a13aefa4 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1341,6 +1341,28 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword { } #[derive(Diagnostic)] +#[diag(parse_path_single_colon)] +pub(crate) struct PathSingleColon { + #[primary_span] + #[suggestion(applicability = "machine-applicable", code = "::")] + pub span: Span, + + #[note(parse_type_ascription_removed)] + pub type_ascription: Option<()>, +} + +#[derive(Diagnostic)] +#[diag(parse_colon_as_semi)] +pub(crate) struct ColonAsSemi { + #[primary_span] + #[suggestion(applicability = "machine-applicable", code = ";")] + pub span: Span, + + #[note(parse_type_ascription_removed)] + pub type_ascription: Option<()>, +} + +#[derive(Diagnostic)] #[diag(parse_where_clause_before_tuple_struct_body)] pub(crate) struct WhereClauseBeforeTupleStructBody { #[primary_span] @@ -2258,31 +2280,6 @@ pub(crate) struct InvalidDynKeyword { pub span: Span, } -#[derive(Diagnostic)] -#[diag(parse_negative_bounds_not_supported)] -pub(crate) struct NegativeBoundsNotSupported { - #[primary_span] - pub negative_bounds: Vec<Span>, - #[label] - pub last_span: Span, - #[subdiagnostic] - pub sub: Option<NegativeBoundsNotSupportedSugg>, -} - -#[derive(Subdiagnostic)] -#[suggestion( - parse_suggestion, - style = "tool-only", - code = "{fixed}", - applicability = "machine-applicable" -)] -pub(crate) struct NegativeBoundsNotSupportedSugg { - #[primary_span] - pub bound_list: Span, - pub num_bounds: usize, - pub fixed: String, -} - #[derive(Subdiagnostic)] pub enum HelpUseLatestEdition { #[help(parse_help_set_edition_cargo)] @@ -2390,10 +2387,12 @@ pub(crate) struct TildeConstLifetime { } #[derive(Diagnostic)] -#[diag(parse_maybe_lifetime)] -pub(crate) struct MaybeLifetime { +#[diag(parse_modifier_lifetime)] +pub(crate) struct ModifierLifetime { #[primary_span] + #[suggestion(style = "tool-only", applicability = "maybe-incorrect", code = "")] pub span: Span, + pub sigil: &'static str, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index a4a75fcb969..51e90489002 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -1,3 +1,5 @@ +use std::ops::Range; + use crate::errors; use crate::lexer::unicode_chars::UNICODE_ARRAY; use crate::make_unclosed_delims_error; @@ -6,7 +8,7 @@ use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::util::unicode::contains_text_flow_control_chars; use rustc_errors::{error_code, Applicability, Diagnostic, DiagnosticBuilder, StashKey}; -use rustc_lexer::unescape::{self, Mode}; +use rustc_lexer::unescape::{self, EscapeError, Mode}; use rustc_lexer::Cursor; use rustc_lexer::{Base, DocStyle, RawStrError}; use rustc_session::lint::builtin::{ @@ -204,6 +206,9 @@ impl<'a> StringReader<'a> { rustc_lexer::TokenKind::Literal { kind, suffix_start } => { let suffix_start = start + BytePos(suffix_start); let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind); + if let token::LitKind::CStr | token::LitKind::CStrRaw(_) = kind { + self.sess.gated_spans.gate(sym::c_str_literals, self.mk_sp(start, self.pos)); + } let suffix = if suffix_start < self.pos { let string = self.str_from(suffix_start); if string == "_" { @@ -321,7 +326,7 @@ impl<'a> StringReader<'a> { ) -> DiagnosticBuilder<'a, !> { self.sess .span_diagnostic - .struct_span_fatal(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c))) + .struct_span_fatal(self.mk_sp(from_pos, to_pos), format!("{}: {}", m, escaped_char(c))) } /// Detect usages of Unicode codepoints changing the direction of the text on screen and loudly @@ -415,6 +420,16 @@ impl<'a> StringReader<'a> { } self.cook_quoted(token::ByteStr, Mode::ByteStr, start, end, 2, 1) // b" " } + rustc_lexer::LiteralKind::CStr { terminated } => { + if !terminated { + self.sess.span_diagnostic.span_fatal_with_code( + self.mk_sp(start + BytePos(1), end), + "unterminated C string", + error_code!(E0767), + ) + } + self.cook_c_string(token::CStr, Mode::CStr, start, end, 2, 1) // c" " + } rustc_lexer::LiteralKind::RawStr { n_hashes } => { if let Some(n_hashes) = n_hashes { let n = u32::from(n_hashes); @@ -433,6 +448,15 @@ impl<'a> StringReader<'a> { self.report_raw_str_error(start, 2); } } + rustc_lexer::LiteralKind::RawCStr { n_hashes } => { + if let Some(n_hashes) = n_hashes { + let n = u32::from(n_hashes); + let kind = token::CStrRaw(n_hashes); + self.cook_c_string(kind, Mode::RawCStr, start, end, 3 + n, 1 + n) // cr##" "## + } else { + self.report_raw_str_error(start, 2); + } + } rustc_lexer::LiteralKind::Int { base, empty_int } => { if empty_int { let span = self.mk_sp(start, end); @@ -542,7 +566,7 @@ impl<'a> StringReader<'a> { err.span_label(self.mk_sp(start, start), "unterminated raw string"); if n_hashes > 0 { - err.note(&format!( + err.note(format!( "this raw string should be terminated with `\"{}`", "#".repeat(n_hashes as usize) )); @@ -648,7 +672,7 @@ impl<'a> StringReader<'a> { self.sess.emit_fatal(errors::TooManyHashes { span: self.mk_sp(start, self.pos), num }); } - fn cook_quoted( + fn cook_common( &self, kind: token::LitKind, mode: Mode, @@ -656,12 +680,13 @@ impl<'a> StringReader<'a> { end: BytePos, prefix_len: u32, postfix_len: u32, + unescape: fn(&str, Mode, &mut dyn FnMut(Range<usize>, Result<(), EscapeError>)), ) -> (token::LitKind, Symbol) { let mut has_fatal_err = false; let content_start = start + BytePos(prefix_len); let content_end = end - BytePos(postfix_len); let lit_content = self.str_from_to(content_start, content_end); - unescape::unescape_literal(lit_content, mode, &mut |range, result| { + unescape(lit_content, mode, &mut |range, result| { // Here we only check for errors. The actual unescaping is done later. if let Err(err) = result { let span_with_quotes = self.mk_sp(start, end); @@ -692,6 +717,38 @@ impl<'a> StringReader<'a> { (token::Err, self.symbol_from_to(start, end)) } } + + fn cook_quoted( + &self, + kind: token::LitKind, + mode: Mode, + start: BytePos, + end: BytePos, + prefix_len: u32, + postfix_len: u32, + ) -> (token::LitKind, Symbol) { + self.cook_common(kind, mode, start, end, prefix_len, postfix_len, |src, mode, callback| { + unescape::unescape_literal(src, mode, &mut |span, result| { + callback(span, result.map(drop)) + }) + }) + } + + fn cook_c_string( + &self, + kind: token::LitKind, + mode: Mode, + start: BytePos, + end: BytePos, + prefix_len: u32, + postfix_len: u32, + ) -> (token::LitKind, Symbol) { + self.cook_common(kind, mode, start, end, prefix_len, postfix_len, |src, mode, callback| { + unescape::unescape_c_string(src, mode, &mut |span, result| { + callback(span, result.map(drop)) + }) + }) + } } pub fn nfc_normalize(string: &str) -> Symbol { diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 7c2c0895193..318a2998509 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -199,8 +199,7 @@ impl<'a> TokenTreesReader<'a> { // matching opening delimiter). let token_str = token_to_string(&self.token); let msg = format!("unexpected closing delimiter: `{}`", token_str); - let mut err = - self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, &msg); + let mut err = self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, msg); report_suspicious_mismatch_block( &mut err, diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 0d12ec6081d..eb9625f923a 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -78,8 +78,7 @@ pub(crate) fn emit_unescape_error( } }; let sugg = sugg.unwrap_or_else(|| { - let is_byte = mode.is_byte(); - let prefix = if is_byte { "b" } else { "" }; + let prefix = mode.prefix_noraw(); let mut escaped = String::with_capacity(lit.len()); let mut chrs = lit.chars().peekable(); while let Some(first) = chrs.next() { @@ -97,7 +96,11 @@ pub(crate) fn emit_unescape_error( }; } let sugg = format!("{prefix}\"{escaped}\""); - MoreThanOneCharSugg::Quotes { span: span_with_quotes, is_byte, sugg } + MoreThanOneCharSugg::Quotes { + span: span_with_quotes, + is_byte: mode == Mode::Byte, + sugg, + } }); handler.emit_err(UnescapeError::MoreThanOneChar { span: span_with_quotes, @@ -112,7 +115,7 @@ pub(crate) fn emit_unescape_error( char_span, escaped_sugg: c.escape_default().to_string(), escaped_msg: escaped_char(c), - byte: mode.is_byte(), + byte: mode == Mode::Byte, }); } EscapeError::BareCarriageReturn => { @@ -126,12 +129,15 @@ pub(crate) fn emit_unescape_error( EscapeError::InvalidEscape => { let (c, span) = last_char(); - let label = - if mode.is_byte() { "unknown byte escape" } else { "unknown character escape" }; + let label = if mode == Mode::Byte || mode == Mode::ByteStr { + "unknown byte escape" + } else { + "unknown character escape" + }; let ec = escaped_char(c); - let mut diag = handler.struct_span_err(span, &format!("{}: `{}`", label, ec)); + let mut diag = handler.struct_span_err(span, format!("{}: `{}`", label, ec)); diag.span_label(span, label); - if c == '{' || c == '}' && !mode.is_byte() { + if c == '{' || c == '}' && matches!(mode, Mode::Str | Mode::RawStr) { diag.help( "if used in a formatting string, curly braces are escaped with `{{` and `}}`", ); @@ -141,7 +147,7 @@ pub(crate) fn emit_unescape_error( version control settings", ); } else { - if !mode.is_byte() { + if mode == Mode::Str || mode == Mode::Char { diag.span_suggestion( span_with_quotes, "if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal", @@ -180,13 +186,13 @@ pub(crate) fn emit_unescape_error( } else { String::new() }; - err.span_label(span, &format!("must be ASCII{}", postfix)); + err.span_label(span, format!("must be ASCII{}", postfix)); // Note: the \\xHH suggestions are not given for raw byte string // literals, because they are araw and so cannot use any escapes. if (c as u32) <= 0xFF && mode != Mode::RawByteStr { err.span_suggestion( span, - &format!( + format!( "if you meant to use the unicode code point for {:?}, use a \\xHH escape", c ), @@ -200,10 +206,7 @@ pub(crate) fn emit_unescape_error( utf8.push(c); err.span_suggestion( span, - &format!( - "if you meant to use the UTF-8 encoding of {:?}, use \\xHH escapes", - c - ), + format!("if you meant to use the UTF-8 encoding of {:?}, use \\xHH escapes", c), utf8.as_bytes() .iter() .map(|b: &u8| format!("\\x{:X}", *b)) diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index 1f027c08fc3..829d9693e55 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -350,7 +350,7 @@ pub(super) fn check_for_substitution( let Some((_, ascii_name, token)) = ASCII_ARRAY.iter().find(|&&(s, _, _)| s == ascii_str) else { let msg = format!("substitution character not found for '{}'", ch); - reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); + reader.sess.span_diagnostic.span_bug_no_panic(span, msg); return (None, None); }; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 61a1cdeb540..25de7808532 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -153,7 +153,7 @@ fn try_file_to_source_file( ) -> Result<Lrc<SourceFile>, Diagnostic> { sess.source_map().load_file(path).map_err(|e| { let msg = format!("couldn't read {}: {}", path.display(), e); - let mut diag = Diagnostic::new(Level::Fatal, &msg); + let mut diag = Diagnostic::new(Level::Fatal, msg); if let Some(sp) = spanopt { diag.set_span(sp); } @@ -190,7 +190,7 @@ pub fn maybe_file_to_stream( override_span: Option<Span>, ) -> Result<TokenStream, Vec<Diagnostic>> { let src = source_file.src.as_ref().unwrap_or_else(|| { - sess.span_diagnostic.bug(&format!( + sess.span_diagnostic.bug(format!( "cannot lex `source_file` without source: {}", sess.source_map().filename_for_diagnostics(&source_file.name) )); @@ -247,7 +247,7 @@ pub fn parse_cfg_attr( match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) { Ok(r) => return Some(r), Err(mut e) => { - e.help(&format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP)) + e.help(format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP)) .note(CFG_ATTR_NOTE_REF) .emit(); } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 0e041df898c..36883bd2172 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -4,7 +4,7 @@ use super::{ TokenExpectType, TokenType, }; use crate::errors::{ - AmbiguousPlus, AttributeOnParamType, BadQPathStage2, BadTypePlus, BadTypePlusSub, + AmbiguousPlus, AttributeOnParamType, BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi, ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg, ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentDoesNotDocumentAnything, DocCommentOnParamType, DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, @@ -84,6 +84,7 @@ impl RecoverQPath for Ty { } impl RecoverQPath for Pat { + const PATH_STYLE: PathStyle = PathStyle::Pat; fn to_ty(&self) -> Option<P<Ty>> { self.to_ty() } @@ -206,11 +207,11 @@ struct MultiSugg { impl MultiSugg { fn emit(self, err: &mut Diagnostic) { - err.multipart_suggestion(&self.msg, self.patches, self.applicability); + err.multipart_suggestion(self.msg, self.patches, self.applicability); } fn emit_verbose(self, err: &mut Diagnostic) { - err.multipart_suggestion_verbose(&self.msg, self.patches, self.applicability); + err.multipart_suggestion_verbose(self.msg, self.patches, self.applicability); } } @@ -590,13 +591,13 @@ impl<'a> Parser<'a> { }; self.last_unexpected_token_span = Some(self.token.span); // FIXME: translation requires list formatting (for `expect`) - let mut err = self.struct_span_err(self.token.span, &msg_exp); + let mut err = self.struct_span_err(self.token.span, msg_exp); if let TokenKind::Ident(symbol, _) = &self.prev_token.kind { if ["def", "fun", "func", "function"].contains(&symbol.as_str()) { err.span_suggestion_short( self.prev_token.span, - &format!("write `fn` instead of `{symbol}` to declare a function"), + format!("write `fn` instead of `{symbol}` to declare a function"), "fn", Applicability::MachineApplicable, ); @@ -663,7 +664,6 @@ impl<'a> Parser<'a> { err.span_label(sp, label_exp); err.span_label(self.token.span, "unexpected token"); } - self.maybe_annotate_with_ascription(&mut err, false); Err(err) } @@ -695,13 +695,13 @@ impl<'a> Parser<'a> { err.set_span(span); err.span_suggestion( span, - &format!("remove the extra `#`{}", pluralize!(count)), + format!("remove the extra `#`{}", pluralize!(count)), "", Applicability::MachineApplicable, ); err.span_label( str_span, - &format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)), + format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)), ); true } @@ -788,59 +788,6 @@ impl<'a> Parser<'a> { None } - pub fn maybe_annotate_with_ascription( - &mut self, - err: &mut Diagnostic, - maybe_expected_semicolon: bool, - ) { - if let Some((sp, likely_path)) = self.last_type_ascription.take() { - let sm = self.sess.source_map(); - let next_pos = sm.lookup_char_pos(self.token.span.lo()); - let op_pos = sm.lookup_char_pos(sp.hi()); - - let allow_unstable = self.sess.unstable_features.is_nightly_build(); - - if likely_path { - err.span_suggestion( - sp, - "maybe write a path separator here", - "::", - if allow_unstable { - Applicability::MaybeIncorrect - } else { - Applicability::MachineApplicable - }, - ); - self.sess.type_ascription_path_suggestions.borrow_mut().insert(sp); - } else if op_pos.line != next_pos.line && maybe_expected_semicolon { - err.span_suggestion( - sp, - "try using a semicolon", - ";", - Applicability::MaybeIncorrect, - ); - } else if allow_unstable { - err.span_label(sp, "tried to parse a type due to this type ascription"); - } else { - err.span_label(sp, "tried to parse a type due to this"); - } - if allow_unstable { - // Give extra information about type ascription only if it's a nightly compiler. - err.note( - "`#![feature(type_ascription)]` lets you annotate an expression with a type: \ - `<expr>: <type>`", - ); - if !likely_path { - // Avoid giving too much info when it was likely an unrelated typo. - err.note( - "see issue #23416 <https://github.com/rust-lang/rust/issues/23416> \ - for more information", - ); - } - } - } - } - /// Eats and discards tokens until one of `kets` is encountered. Respects token trees, /// passes through any errors encountered. Used for error recovery. pub(super) fn eat_to_tokens(&mut self, kets: &[&TokenKind]) { @@ -1337,7 +1284,7 @@ impl<'a> Parser<'a> { } self.bump(); // `+` - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds()?; let sum_span = ty.span.to(self.prev_token.span); let sub = match &ty.kind { @@ -1413,12 +1360,12 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P<Expr>> { let mut err = self.struct_span_err( op_span, - &format!("Rust has no {} {} operator", kind.fixity, kind.op.name()), + format!("Rust has no {} {} operator", kind.fixity, kind.op.name()), ); - err.span_label(op_span, &format!("not a valid {} operator", kind.fixity)); + err.span_label(op_span, format!("not a valid {} operator", kind.fixity)); let help_base_case = |mut err: DiagnosticBuilder<'_, _>, base| { - err.help(&format!("use `{}= 1` instead", kind.op.chr())); + err.help(format!("use `{}= 1` instead", kind.op.chr())); err.emit(); Ok(base) }; @@ -1607,7 +1554,7 @@ impl<'a> Parser<'a> { _ => this_token_str, }, ); - let mut err = self.struct_span_err(sp, &msg); + let mut err = self.struct_span_err(sp, msg); let label_exp = format!("expected `{token_str}`"); let sm = self.sess.source_map(); if !sm.is_multiline(prev_sp.until(sp)) { @@ -1622,12 +1569,36 @@ impl<'a> Parser<'a> { } pub(super) fn expect_semi(&mut self) -> PResult<'a, ()> { - if self.eat(&token::Semi) { + if self.eat(&token::Semi) || self.recover_colon_as_semi() { return Ok(()); } self.expect(&token::Semi).map(drop) // Error unconditionally } + pub(super) fn recover_colon_as_semi(&mut self) -> bool { + let line_idx = |span: Span| { + self.sess + .source_map() + .span_to_lines(span) + .ok() + .and_then(|lines| Some(lines.lines.get(0)?.line_index)) + }; + + if self.may_recover() + && self.token == token::Colon + && self.look_ahead(1, |next| line_idx(self.token.span) < line_idx(next.span)) + { + self.sess.emit_err(ColonAsSemi { + span: self.token.span, + type_ascription: self.sess.unstable_features.is_nightly_build().then_some(()), + }); + self.bump(); + return true; + } + + false + } + /// Consumes alternative await syntaxes like `await!(<expr>)`, `await <expr>`, /// `await? <expr>`, `await(<expr>)`, and `await { <expr> }`. pub(super) fn recover_incorrect_await_syntax( @@ -1734,7 +1705,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } - err.span_suggestion(lo.shrink_to_lo(), &format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); + err.span_suggestion(lo.shrink_to_lo(), format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); err.emit(); Ok(self.mk_expr_err(lo.to(hi))) } else { @@ -1790,24 +1761,6 @@ impl<'a> Parser<'a> { } } - pub(super) fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool { - (self.token == token::Lt && // `foo:<bar`, likely a typoed turbofish. - self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())) - || self.token.is_ident() && - matches!(node, ast::ExprKind::Path(..) | ast::ExprKind::Field(..)) && - !self.token.is_reserved_ident() && // v `foo:bar(baz)` - self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Parenthesis)) - || self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace)) // `foo:bar {` - || self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar::<baz` - self.look_ahead(2, |t| t == &token::Lt) && - self.look_ahead(3, |t| t.is_ident()) - || self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar:baz` - self.look_ahead(2, |t| t.is_ident()) - || self.look_ahead(1, |t| t == &token::ModSep) - && (self.look_ahead(2, |t| t.is_ident()) || // `foo:bar::baz` - self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>` - } - pub(super) fn recover_seq_parse_error( &mut self, delim: Delimiter, @@ -1902,7 +1855,6 @@ impl<'a> Parser<'a> { && brace_depth == 0 && bracket_depth == 0 => { - debug!("recover_stmt_ return - Semi"); break; } _ => self.bump(), @@ -2108,7 +2060,7 @@ impl<'a> Parser<'a> { format!("expected expression, found {}", super::token_descr(&self.token),), ), }; - let mut err = self.struct_span_err(span, &msg); + let mut err = self.struct_span_err(span, msg); let sp = self.sess.source_map().start_point(self.token.span); if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); @@ -2179,7 +2131,7 @@ impl<'a> Parser<'a> { // arguments after a comma. let mut err = self.struct_span_err( self.token.span, - &format!("expected one of `,` or `>`, found {}", super::token_descr(&self.token)), + format!("expected one of `,` or `>`, found {}", super::token_descr(&self.token)), ); err.span_label(self.token.span, "expected one of `,` or `>`"); match self.recover_const_arg(arg.span(), err) { @@ -2606,7 +2558,7 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern"); if let Ok(seq_snippet) = self.span_to_snippet(seq_span) { err.multipart_suggestion( - &format!( + format!( "try adding parentheses to match on a tuple{}", if let CommaRecoveryMode::LikelyTuple = rt { "" } else { "..." }, ), diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index bff9de5c652..018eddea4b0 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -174,10 +174,8 @@ impl<'a> Parser<'a> { self.parse_expr_prefix(attrs)? } }; - let last_type_ascription_set = self.last_type_ascription.is_some(); if !self.should_continue_as_assoc_expr(&lhs) { - self.last_type_ascription = None; return Ok(lhs); } @@ -301,9 +299,6 @@ impl<'a> Parser<'a> { if op == AssocOp::As { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; continue; - } else if op == AssocOp::Colon { - lhs = self.parse_assoc_op_ascribe(lhs, lhs_span)?; - continue; } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq { // If we didn't have to handle `x..`/`x..=`, it would be pretty easy to // generalise it to the Fixity::None code. @@ -364,7 +359,7 @@ impl<'a> Parser<'a> { let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(span, aopexpr) } - AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => { + AssocOp::As | AssocOp::DotDot | AssocOp::DotDotEq => { self.span_bug(span, "AssocOp should have been handled by special case") } }; @@ -373,9 +368,7 @@ impl<'a> Parser<'a> { break; } } - if last_type_ascription_set { - self.last_type_ascription = None; - } + Ok(lhs) } @@ -743,7 +736,7 @@ impl<'a> Parser<'a> { ( // `foo: ` ExprKind::Path(None, ast::Path { segments, .. }), - TokenKind::Ident(kw::For | kw::Loop | kw::While, false), + token::Ident(kw::For | kw::Loop | kw::While, false), ) if segments.len() == 1 => { let snapshot = self.create_snapshot_for_diagnostic(); let label = Label { @@ -838,21 +831,19 @@ impl<'a> Parser<'a> { &mut self, cast_expr: P<Expr>, ) -> PResult<'a, P<Expr>> { + if let ExprKind::Type(_, _) = cast_expr.kind { + panic!("ExprKind::Type must not be parsed"); + } + let span = cast_expr.span; - let (cast_kind, maybe_ascription_span) = - if let ExprKind::Type(ascripted_expr, _) = &cast_expr.kind { - ("type ascription", Some(ascripted_expr.span.shrink_to_hi().with_hi(span.hi()))) - } else { - ("cast", None) - }; let with_postfix = self.parse_expr_dot_or_call_with_(cast_expr, span)?; // Check if an illegal postfix operator has been added after the cast. // If the resulting expression is not a cast, it is an illegal postfix operator. - if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) { + if !matches!(with_postfix.kind, ExprKind::Cast(_, _)) { let msg = format!( - "{cast_kind} cannot be followed by {}", + "cast cannot be followed by {}", match with_postfix.kind { ExprKind::Index(_, _) => "indexing", ExprKind::Try(_) => "`?`", @@ -864,7 +855,7 @@ impl<'a> Parser<'a> { _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"), } ); - let mut err = self.struct_span_err(span, &msg); + let mut err = self.struct_span_err(span, msg); let suggest_parens = |err: &mut Diagnostic| { let suggestions = vec![ @@ -878,44 +869,13 @@ impl<'a> Parser<'a> { ); }; - // If type ascription is "likely an error", the user will already be getting a useful - // help message, and doesn't need a second. - if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) { - self.maybe_annotate_with_ascription(&mut err, false); - } else if let Some(ascription_span) = maybe_ascription_span { - let is_nightly = self.sess.unstable_features.is_nightly_build(); - if is_nightly { - suggest_parens(&mut err); - } - err.span_suggestion( - ascription_span, - &format!( - "{}remove the type ascription", - if is_nightly { "alternatively, " } else { "" } - ), - "", - if is_nightly { - Applicability::MaybeIncorrect - } else { - Applicability::MachineApplicable - }, - ); - } else { - suggest_parens(&mut err); - } + suggest_parens(&mut err); + err.emit(); }; Ok(with_postfix) } - fn parse_assoc_op_ascribe(&mut self, lhs: P<Expr>, lhs_span: Span) -> PResult<'a, P<Expr>> { - let maybe_path = self.could_ascription_be_path(&lhs.kind); - self.last_type_ascription = Some((self.prev_token.span, maybe_path)); - let lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?; - self.sess.gated_spans.gate(sym::type_ascription, lhs.span); - Ok(lhs) - } - /// Parse `& mut? <expr>` or `& raw [ const | mut ] <expr>`. fn parse_expr_borrow(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { self.expect_and()?; @@ -1010,7 +970,7 @@ impl<'a> Parser<'a> { }; if has_dot { // expr.f - e = self.parse_expr_dot_suffix(lo, e)?; + e = self.parse_dot_suffix_expr(lo, e)?; continue; } if self.expr_is_complete(&e) { @@ -1024,13 +984,7 @@ impl<'a> Parser<'a> { } } - fn look_ahead_type_ascription_as_field(&mut self) -> bool { - self.look_ahead(1, |t| t.is_ident()) - && self.look_ahead(2, |t| t == &token::Colon) - && self.look_ahead(3, |t| t.can_begin_expr()) - } - - fn parse_expr_dot_suffix(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> { + fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> { match self.token.uninterpolate().kind { token::Ident(..) => self.parse_dot_suffix(base, lo), token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => { @@ -1183,9 +1137,7 @@ impl<'a> Parser<'a> { /// Parse a function call expression, `expr(...)`. fn parse_expr_fn_call(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> { - let snapshot = if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) - && self.look_ahead_type_ascription_as_field() - { + let snapshot = if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) { Some((self.create_snapshot_for_diagnostic(), fun.kind.clone())) } else { None @@ -1216,7 +1168,6 @@ impl<'a> Parser<'a> { if !self.may_recover() { return None; } - match (seq.as_mut(), snapshot) { (Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => { snapshot.bump(); // `(` @@ -1260,9 +1211,7 @@ impl<'a> Parser<'a> { return Some(self.mk_expr_err(span)); } Ok(_) => {} - Err(mut err) => { - err.emit(); - } + Err(err) => err.cancel(), } } _ => {} @@ -1499,8 +1448,19 @@ impl<'a> Parser<'a> { } fn parse_expr_path_start(&mut self) -> PResult<'a, P<Expr>> { + let maybe_eq_tok = self.prev_token.clone(); let (qself, path) = if self.eat_lt() { - let (qself, path) = self.parse_qpath(PathStyle::Expr)?; + let lt_span = self.prev_token.span; + let (qself, path) = self.parse_qpath(PathStyle::Expr).map_err(|mut err| { + // Suggests using '<=' if there is an error parsing qpath when the previous token + // is an '=' token. Only emits suggestion if the '<' token and '=' token are + // directly adjacent (i.e. '=<') + if maybe_eq_tok.kind == TokenKind::Eq && maybe_eq_tok.span.hi() == lt_span.lo() { + let eq_lt = maybe_eq_tok.span.to(lt_span); + err.span_suggestion(eq_lt, "did you mean", "<=", Applicability::Unspecified); + } + err + })?; (Some(qself), path) } else { (None, self.parse_path(PathStyle::Expr)?) @@ -1516,7 +1476,6 @@ impl<'a> Parser<'a> { let mac = P(MacCall { path, args: self.parse_delim_args()?, - prior_type_ascription: self.last_type_ascription, }); (lo.to(self.prev_token.span), ExprKind::MacCall(mac)) } else if self.check(&token::OpenDelim(Delimiter::Brace)) @@ -1535,7 +1494,7 @@ impl<'a> Parser<'a> { } /// Parse `'label: $expr`. The label is already parsed. - fn parse_expr_labeled( + pub(super) fn parse_expr_labeled( &mut self, label_: Label, mut consume_colon: bool, @@ -1855,7 +1814,7 @@ impl<'a> Parser<'a> { let token = self.token.clone(); let err = |self_: &Self| { let msg = format!("unexpected token: {}", super::token_descr(&token)); - self_.struct_span_err(token.span, &msg) + self_.struct_span_err(token.span, msg) }; // On an error path, eagerly consider a lifetime to be an unclosed character lit if self.token.is_lifetime() { @@ -1922,6 +1881,7 @@ impl<'a> Parser<'a> { let recovered = self.recover_after_dot(); let token = recovered.as_ref().unwrap_or(&self.token); let span = token.span; + token::Lit::from_token(token).map(|token_lit| { self.bump(); (token_lit, span) @@ -3013,6 +2973,11 @@ impl<'a> Parser<'a> { } else { e.span_label(pth.span, "while parsing this struct"); } + + if !recover { + return Err(e); + } + e.emit(); // If the next token is a comma, then try to parse @@ -3024,6 +2989,7 @@ impl<'a> Parser<'a> { break; } } + None } }; diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 61a7ae93bfa..e6d0f9fbc76 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -78,7 +78,7 @@ impl<'a> Parser<'a> { } self.restore_snapshot(snapshot); } - self.parse_generic_bounds(colon_span)? + self.parse_generic_bounds()? } else { Vec::new() }; @@ -419,7 +419,7 @@ impl<'a> Parser<'a> { // or with mandatory equality sign and the second type. let ty = self.parse_ty_for_where_clause()?; if self.eat(&token::Colon) { - let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?; + let bounds = self.parse_generic_bounds()?; Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { span: lo.to(self.prev_token.span), bound_generic_params: lifetime_defs, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 9e003bfc097..6ca88200dc5 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -71,7 +71,7 @@ impl<'a> Parser<'a> { if !self.eat(term) { let token_str = super::token_descr(&self.token); if !self.maybe_consume_incorrect_semicolon(&items) { - let msg = &format!("expected item, found {token_str}"); + let msg = format!("expected item, found {token_str}"); let mut err = self.struct_span_err(self.token.span, msg); let label = if self.is_kw_followed_by_ident(kw::Let) { "consider using `const` or `static` instead of `let` for global variables" @@ -443,7 +443,7 @@ impl<'a> Parser<'a> { Ok(args) => { self.eat_semi_for_macro_if_needed(&args); self.complain_if_pub_macro(vis, false); - Ok(MacCall { path, args, prior_type_ascription: self.last_type_ascription }) + Ok(MacCall { path, args }) } Err(mut err) => { @@ -788,11 +788,7 @@ impl<'a> Parser<'a> { // Parse optional colon and supertrait bounds. let had_colon = self.eat(&token::Colon); let span_at_colon = self.prev_token.span; - let bounds = if had_colon { - self.parse_generic_bounds(Some(self.prev_token.span))? - } else { - Vec::new() - }; + let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() }; let span_before_eq = self.prev_token.span; if self.eat(&token::Eq) { @@ -802,7 +798,7 @@ impl<'a> Parser<'a> { self.sess.emit_err(errors::BoundsNotAllowedOnTraitAliases { span }); } - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds()?; generics.where_clause = self.parse_where_clause()?; self.expect_semi()?; @@ -883,7 +879,7 @@ impl<'a> Parser<'a> { // Parse optional colon and param bounds. let bounds = - if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() }; + if self.eat(&token::Colon) { self.parse_generic_bounds()? } else { Vec::new() }; let before_where_clause = self.parse_where_clause()?; let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None }; @@ -1429,7 +1425,7 @@ impl<'a> Parser<'a> { VariantData::Struct(fields, recovered) } else { let token_str = super::token_descr(&self.token); - let msg = &format!("expected `where` or `{{` after union name, found {token_str}"); + let msg = format!("expected `where` or `{{` after union name, found {token_str}"); let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `where` or `{` after union name"); return Err(err); @@ -1465,7 +1461,7 @@ impl<'a> Parser<'a> { self.eat(&token::CloseDelim(Delimiter::Brace)); } else { let token_str = super::token_descr(&self.token); - let msg = &format!( + let msg = format!( "expected {}`{{` after struct name, found {}", if parsed_where { "" } else { "`where`, or " }, token_str @@ -1602,7 +1598,7 @@ impl<'a> Parser<'a> { let sp = self.prev_token.span.shrink_to_hi(); let mut err = self.struct_span_err( sp, - &format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)), + format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)), ); // Try to recover extra trailing angle brackets @@ -1740,7 +1736,7 @@ impl<'a> Parser<'a> { Ok(_) => { let mut err = self.struct_span_err( lo.to(self.prev_token.span), - &format!("functions are not allowed in {adt_ty} definitions"), + format!("functions are not allowed in {adt_ty} definitions"), ); err.help( "unlike in C++, Java, and C#, functions are declared in `impl` blocks", @@ -1759,7 +1755,7 @@ impl<'a> Parser<'a> { Ok((ident, _)) => { let mut err = self.struct_span_err( lo.with_hi(ident.span.hi()), - &format!("structs are not allowed in {adt_ty} definitions"), + format!("structs are not allowed in {adt_ty} definitions"), ); err.help("consider creating a new `struct` definition instead of nesting"); err @@ -2228,11 +2224,11 @@ impl<'a> Parser<'a> { err.span_suggestion( self.token.uninterpolated_span(), - &format!("`{original_kw}` already used earlier, remove this one"), + format!("`{original_kw}` already used earlier, remove this one"), "", Applicability::MachineApplicable, ) - .span_note(original_sp, &format!("`{original_kw}` first seen here")); + .span_note(original_sp, format!("`{original_kw}` first seen here")); } // The keyword has not been seen yet, suggest correct placement in the function front matter else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw { @@ -2243,7 +2239,7 @@ impl<'a> Parser<'a> { err.span_suggestion( correct_pos_sp.to(misplaced_qual_sp), - &format!("`{misplaced_qual}` must come before `{current_qual}`"), + format!("`{misplaced_qual}` must come before `{current_qual}`"), format!("{misplaced_qual} {current_qual}"), Applicability::MachineApplicable, ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`"); @@ -2267,7 +2263,7 @@ impl<'a> Parser<'a> { if matches!(orig_vis.kind, VisibilityKind::Inherited) { err.span_suggestion( sp_start.to(self.prev_token.span), - &format!("visibility `{vs}` must come before `{snippet}`"), + format!("visibility `{vs}` must come before `{snippet}`"), format!("{vs} {snippet}"), Applicability::MachineApplicable, ); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 1c34e491f21..0c265d7af0e 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -148,9 +148,6 @@ pub struct Parser<'a> { max_angle_bracket_count: u32, last_unexpected_token_span: Option<Span>, - /// Span pointing at the `:` for the last type ascription the parser has seen, and whether it - /// looked like it could have been a mistyped path or literal `Option:Some(42)`). - pub last_type_ascription: Option<(Span, bool /* likely path typo */)>, /// If present, this `Parser` is not parsing Rust code but rather a macro call. subparser_name: Option<&'static str>, capture_state: CaptureState, @@ -165,7 +162,7 @@ pub struct Parser<'a> { // This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure // it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Parser<'_>, 288); +rustc_data_structures::static_assert_size!(Parser<'_>, 272); /// Stores span information about a closure. #[derive(Clone)] @@ -470,7 +467,6 @@ impl<'a> Parser<'a> { unmatched_angle_bracket_count: 0, max_angle_bracket_count: 0, last_unexpected_token_span: None, - last_type_ascription: None, subparser_name, capture_state: CaptureState { capturing: Capturing::No, @@ -909,7 +905,7 @@ impl<'a> Parser<'a> { expect_err .span_suggestion_verbose( self.prev_token.span.shrink_to_hi().until(self.token.span), - &msg, + msg, " @ ", Applicability::MaybeIncorrect, ) @@ -925,7 +921,7 @@ impl<'a> Parser<'a> { expect_err .span_suggestion_short( sp, - &format!("missing `{}`", token_str), + format!("missing `{}`", token_str), token_str, Applicability::MaybeIncorrect, ) @@ -941,10 +937,14 @@ impl<'a> Parser<'a> { // propagate the help message from sub error 'e' to main error 'expect_err; expect_err.children.push(xx.clone()); } - expect_err.emit(); - e.cancel(); - break; + if self.token == token::Colon { + // we will try to recover in `maybe_recover_struct_lit_bad_delims` + return Err(expect_err); + } else { + expect_err.emit(); + break; + } } } } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index f2422fe307c..c317d96368e 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -406,11 +406,11 @@ impl<'a> Parser<'a> { // Parse pattern starting with a path let (qself, path) = if self.eat_lt() { // Parse a qualified path - let (qself, path) = self.parse_qpath(PathStyle::Expr)?; + let (qself, path) = self.parse_qpath(PathStyle::Pat)?; (Some(qself), path) } else { // Parse an unqualified path - (None, self.parse_path(PathStyle::Expr)?) + (None, self.parse_path(PathStyle::Pat)?) }; let span = lo.to(self.prev_token.span); @@ -444,7 +444,7 @@ impl<'a> Parser<'a> { super::token_descr(&self_.token) ); - let mut err = self_.struct_span_err(self_.token.span, &msg); + let mut err = self_.struct_span_err(self_.token.span, msg); err.span_label(self_.token.span, format!("expected {}", expected)); err }); @@ -666,7 +666,7 @@ impl<'a> Parser<'a> { fn parse_pat_mac_invoc(&mut self, path: Path) -> PResult<'a, PatKind> { self.bump(); let args = self.parse_delim_args()?; - let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription }); + let mac = P(MacCall { path, args }); Ok(PatKind::MacCall(mac)) } @@ -680,7 +680,7 @@ impl<'a> Parser<'a> { let expected = Expected::to_string_or_fallback(expected); let msg = format!("expected {}, found {}", expected, super::token_descr(&self.token)); - let mut err = self.struct_span_err(self.token.span, &msg); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, format!("expected {}", expected)); let sp = self.sess.source_map().start_point(self.token.span); @@ -789,11 +789,11 @@ impl<'a> Parser<'a> { let lo = self.token.span; let (qself, path) = if self.eat_lt() { // Parse a qualified path - let (qself, path) = self.parse_qpath(PathStyle::Expr)?; + let (qself, path) = self.parse_qpath(PathStyle::Pat)?; (Some(qself), path) } else { // Parse an unqualified path - (None, self.parse_path(PathStyle::Expr)?) + (None, self.parse_path(PathStyle::Pat)?) }; let hi = self.prev_token.span; Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path))) @@ -978,7 +978,7 @@ impl<'a> Parser<'a> { break; } let token_str = super::token_descr(&self.token); - let msg = &format!("expected `}}`, found {}", token_str); + let msg = format!("expected `}}`, found {}", token_str); let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `}`"); diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index ae73760bd8c..feb7e829caf 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -1,5 +1,6 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; +use crate::errors::PathSingleColon; use crate::{errors, maybe_whole}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; @@ -8,7 +9,7 @@ use rustc_ast::{ AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs, Path, PathSegment, QSelf, }; -use rustc_errors::{Applicability, PResult}; +use rustc_errors::{Applicability, IntoDiagnostic, PResult}; use rustc_span::source_map::{BytePos, Span}; use rustc_span::symbol::{kw, sym, Ident}; use std::mem; @@ -24,7 +25,19 @@ pub enum PathStyle { /// In all such contexts the non-path interpretation is preferred by default for practical /// reasons, but the path interpretation can be forced by the disambiguator `::`, e.g. /// `x<y>` - comparisons, `x::<y>` - unambiguously a path. + /// + /// Also, a path may never be followed by a `:`. This means that we can eagerly recover if + /// we encounter it. Expr, + /// The same as `Expr`, but may be followed by a `:`. + /// For example, this code: + /// ```rust + /// struct S; + /// + /// let S: S; + /// // ^ Followed by a `:` + /// ``` + Pat, /// In other contexts, notably in types, no ambiguity exists and paths can be written /// without the disambiguator, e.g., `x<y>` - unambiguously a path. /// Paths with disambiguators are still accepted, `x::<Y>` - unambiguously a path too. @@ -38,6 +51,12 @@ pub enum PathStyle { Mod, } +impl PathStyle { + fn has_generic_ambiguity(&self) -> bool { + matches!(self, Self::Expr | Self::Pat) + } +} + impl<'a> Parser<'a> { /// Parses a qualified path. /// Assumes that the leading `<` has been parsed already. @@ -183,7 +202,6 @@ impl<'a> Parser<'a> { segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); } self.parse_path_segments(&mut segments, style, ty_generics)?; - Ok(Path { segments, span: lo.to(self.prev_token.span), tokens: None }) } @@ -195,7 +213,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, ()> { loop { let segment = self.parse_path_segment(style, ty_generics)?; - if style == PathStyle::Expr { + if style.has_generic_ambiguity() { // In order to check for trailing angle brackets, we must have finished // recursing (`parse_path_segment` can indirectly call this function), // that is, the next token must be the highlighted part of the below example: @@ -217,6 +235,29 @@ impl<'a> Parser<'a> { segments.push(segment); if self.is_import_coupler() || !self.eat(&token::ModSep) { + if style == PathStyle::Expr + && self.may_recover() + && self.token == token::Colon + && self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident()) + { + // Emit a special error message for `a::b:c` to help users + // otherwise, `a: c` might have meant to introduce a new binding + if self.token.span.lo() == self.prev_token.span.hi() + && self.look_ahead(1, |token| self.token.span.hi() == token.span.lo()) + { + self.bump(); // bump past the colon + self.sess.emit_err(PathSingleColon { + span: self.prev_token.span, + type_ascription: self + .sess + .unstable_features + .is_nightly_build() + .then_some(()), + }); + } + continue; + } + return Ok(()); } } @@ -270,8 +311,25 @@ impl<'a> Parser<'a> { ty_generics, )?; self.expect_gt().map_err(|mut err| { + // Try to recover a `:` into a `::` + if self.token == token::Colon + && self.look_ahead(1, |token| { + token.is_ident() && !token.is_reserved_ident() + }) + { + err.cancel(); + err = PathSingleColon { + span: self.token.span, + type_ascription: self + .sess + .unstable_features + .is_nightly_build() + .then_some(()), + } + .into_diagnostic(self.diagnostic()); + } // Attempt to find places where a missing `>` might belong. - if let Some(arg) = args + else if let Some(arg) = args .iter() .rev() .find(|arg| !matches!(arg, AngleBracketedArg::Constraint(_))) @@ -548,7 +606,7 @@ impl<'a> Parser<'a> { let kind = if self.eat(&token::Colon) { // Parse associated type constraint bound. - let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?; + let bounds = self.parse_generic_bounds()?; AssocConstraintKind::Bound { bounds } } else if self.eat(&token::Eq) { self.parse_assoc_equality_term(ident, self.prev_token.span)? @@ -621,14 +679,14 @@ impl<'a> Parser<'a> { ); err.span_suggestion( eq.to(before_next), - &format!("remove the `=` if `{}` is a type", ident), + format!("remove the `=` if `{}` is a type", ident), "", Applicability::MaybeIncorrect, ) } else { err.span_label( self.token.span, - &format!("expected type, found {}", super::token_descr(&self.token)), + format!("expected type, found {}", super::token_descr(&self.token)), ) }; return Err(err); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index fbe5b88c49e..1c17de337e8 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -10,6 +10,8 @@ use super::{ use crate::errors; use crate::maybe_whole; +use crate::errors::MalformedLoopLabel; +use ast::Label; use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, TokenKind}; @@ -19,7 +21,8 @@ use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, HasAttrs, Local, Stmt}; use rustc_ast::{StmtKind, DUMMY_NODE_ID}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; use rustc_span::source_map::{BytePos, Span}; -use rustc_span::symbol::{kw, sym}; +use rustc_span::symbol::{kw, sym, Ident}; + use std::mem; use thin_vec::{thin_vec, ThinVec}; @@ -186,7 +189,7 @@ impl<'a> Parser<'a> { _ => MacStmtStyle::NoBraces, }; - let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription }); + let mac = P(MacCall { path, args }); let kind = if (style == MacStmtStyle::Braces && self.token != token::Dot @@ -546,10 +549,36 @@ impl<'a> Parser<'a> { } let stmt = match self.parse_full_stmt(recover) { Err(mut err) if recover.yes() => { - self.maybe_annotate_with_ascription(&mut err, false); if let Some(ref mut snapshot) = snapshot { snapshot.recover_diff_marker(); } + if self.token == token::Colon { + // if next token is following a colon, it's likely a path + // and we can suggest a path separator + let ident_span = self.prev_token.span; + self.bump(); + if self.token.span.lo() == self.prev_token.span.hi() { + err.span_suggestion_verbose( + self.prev_token.span, + "maybe write a path separator here", + "::", + Applicability::MaybeIncorrect, + ); + } + if self.look_ahead(1, |token| token == &token::Eq) { + err.span_suggestion_verbose( + ident_span.shrink_to_lo(), + "you might have meant to introduce a new binding", + "let ", + Applicability::MaybeIncorrect, + ); + } + if self.sess.unstable_features.is_nightly_build() { + // FIXME(Nilstrieb): Remove this again after a few months. + err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>"); + } + } + err.emit(); self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore); Some(self.mk_stmt_err(self.token.span)) @@ -580,47 +609,104 @@ impl<'a> Parser<'a> { }; let mut eat_semi = true; + let mut add_semi_to_stmt = false; + match &mut stmt.kind { // Expression without semicolon. StmtKind::Expr(expr) if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => { // Just check for errors and recover; do not eat semicolon yet. // `expect_one_of` returns PResult<'a, bool /* recovered */> - let replace_with_err = - match self.expect_one_of(&[], &[token::Semi, token::CloseDelim(Delimiter::Brace)]) { + + let expect_result = self.expect_one_of(&[], &[token::Semi, token::CloseDelim(Delimiter::Brace)]); + + let replace_with_err = 'break_recover: { + match expect_result { // Recover from parser, skip type error to avoid extra errors. - Ok(true) => true, - Err(mut e) => { - if let TokenKind::DocComment(..) = self.token.kind && - let Ok(snippet) = self.span_to_snippet(self.token.span) { + Ok(true) => true, + Err(mut e) => { + if let TokenKind::DocComment(..) = self.token.kind + && let Ok(snippet) = self.span_to_snippet(self.token.span) + { let sp = self.token.span; let marker = &snippet[..3]; let (comment_marker, doc_comment_marker) = marker.split_at(2); e.span_suggestion( sp.with_hi(sp.lo() + BytePos(marker.len() as u32)), - &format!( + format!( "add a space before `{}` to use a regular comment", doc_comment_marker, ), format!("{} {}", comment_marker, doc_comment_marker), Applicability::MaybeIncorrect, ); - } + } + + if self.recover_colon_as_semi() { + // recover_colon_as_semi has already emitted a nicer error. + e.delay_as_bug(); + add_semi_to_stmt = true; + eat_semi = false; + + break 'break_recover false; + } + + match &expr.kind { + ExprKind::Path(None, ast::Path { segments, .. }) if segments.len() == 1 => { + if self.token == token::Colon + && self.look_ahead(1, |token| { + token.is_whole_block() || matches!( + token.kind, + token::Ident(kw::For | kw::Loop | kw::While, false) + | token::OpenDelim(Delimiter::Brace) + ) + }) + { + let snapshot = self.create_snapshot_for_diagnostic(); + let label = Label { + ident: Ident::from_str_and_span( + &format!("'{}", segments[0].ident), + segments[0].ident.span, + ), + }; + match self.parse_expr_labeled(label, false) { + Ok(labeled_expr) => { + e.delay_as_bug(); + self.sess.emit_err(MalformedLoopLabel { + span: label.ident.span, + correct_label: label.ident, + }); + *expr = labeled_expr; + break 'break_recover false; + } + Err(err) => { + err.cancel(); + self.restore_snapshot(snapshot); + } + } + } + } + _ => {} + } - if let Err(mut e) = - self.check_mistyped_turbofish_with_multiple_type_params(e, expr) - { - if recover.no() { - return Err(e); + if let Err(mut e) = + self.check_mistyped_turbofish_with_multiple_type_params(e, expr) + { + if recover.no() { + return Err(e); + } + e.emit(); + self.recover_stmt(); } - e.emit(); - self.recover_stmt(); + + true + } - true + Ok(false) => false } - _ => false }; + if replace_with_err { // We already emitted an error, so don't emit another type error let sp = expr.span.to(self.prev_token.span); @@ -643,9 +729,10 @@ impl<'a> Parser<'a> { StmtKind::Empty | StmtKind::Item(_) | StmtKind::Local(_) | StmtKind::Semi(_) => eat_semi = false, } - if eat_semi && self.eat(&token::Semi) { + if add_semi_to_stmt || (eat_semi && self.eat(&token::Semi)) { stmt = stmt.add_trailing_semicolon(); } + stmt.span = stmt.span.to(self.prev_token.span); Ok(Some(stmt)) } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 3ceb3a2bef1..a29b696aea8 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -3,8 +3,7 @@ use super::{Parser, PathStyle, TokenType}; use crate::errors::{ self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType, FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg, - InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, - NegativeBoundsNotSupported, NegativeBoundsNotSupportedSugg, NestedCVariadicType, + InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, ReturnTypesUseThinArrow, }; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; @@ -14,8 +13,9 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, BareFnTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, - MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind, + self as ast, BareFnTy, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, + Generics, Lifetime, MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, + TraitObjectSyntax, Ty, TyKind, }; use rustc_errors::{Applicability, PResult}; use rustc_span::source_map::Span; @@ -23,10 +23,10 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; use thin_vec::{thin_vec, ThinVec}; -/// Any `?` or `~const` modifiers that appear at the start of a bound. +/// Any `?`, `!`, or `~const` modifiers that appear at the start of a bound. struct BoundModifiers { /// `?Trait`. - maybe: Option<Span>, + bound_polarity: BoundPolarity, /// `~const Trait`. maybe_const: Option<Span>, @@ -34,11 +34,13 @@ struct BoundModifiers { impl BoundModifiers { fn to_trait_bound_modifier(&self) -> TraitBoundModifier { - match (self.maybe, self.maybe_const) { - (None, None) => TraitBoundModifier::None, - (Some(_), None) => TraitBoundModifier::Maybe, - (None, Some(_)) => TraitBoundModifier::MaybeConst, - (Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe, + match (self.bound_polarity, self.maybe_const) { + (BoundPolarity::Positive, None) => TraitBoundModifier::None, + (BoundPolarity::Negative(_), None) => TraitBoundModifier::Negative, + (BoundPolarity::Maybe(_), None) => TraitBoundModifier::Maybe, + (BoundPolarity::Positive, Some(_)) => TraitBoundModifier::MaybeConst, + (BoundPolarity::Negative(_), Some(_)) => TraitBoundModifier::MaybeConstNegative, + (BoundPolarity::Maybe(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe, } } } @@ -315,9 +317,8 @@ impl<'a> Parser<'a> { } } else { let msg = format!("expected type, found {}", super::token_descr(&self.token)); - let mut err = self.struct_span_err(self.token.span, &msg); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected type"); - self.maybe_annotate_with_ascription(&mut err, true); return Err(err); }; @@ -369,7 +370,7 @@ impl<'a> Parser<'a> { fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()); - let bounds = self.parse_generic_bounds_common(allow_plus, None)?; + let bounds = self.parse_generic_bounds_common(allow_plus)?; if lt_no_plus { self.sess.emit_err(NeedPlusAfterTraitObjectLifetime { span: lo }); } @@ -396,7 +397,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, TyKind> { if plus { self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded - bounds.append(&mut self.parse_generic_bounds(Some(self.prev_token.span))?); + bounds.append(&mut self.parse_generic_bounds()?); } Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) } @@ -599,7 +600,7 @@ impl<'a> Parser<'a> { } }) } - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds()?; *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus); Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)) } @@ -630,7 +631,7 @@ impl<'a> Parser<'a> { }; // Always parse bounds greedily for better error recovery. - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds()?; *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus); Ok(TyKind::TraitObject(bounds, syntax)) } @@ -651,11 +652,7 @@ impl<'a> Parser<'a> { let path = self.parse_path_inner(PathStyle::Type, ty_generics)?; if self.eat(&token::Not) { // Macro invocation in type position - Ok(TyKind::MacCall(P(MacCall { - path, - args: self.parse_delim_args()?, - prior_type_ascription: self.last_type_ascription, - }))) + Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? }))) } else if allow_plus == AllowPlus::Yes && self.check_plus() { // `Trait1 + Trait2 + 'a` self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true) @@ -665,23 +662,15 @@ impl<'a> Parser<'a> { } } - pub(super) fn parse_generic_bounds( - &mut self, - colon_span: Option<Span>, - ) -> PResult<'a, GenericBounds> { - self.parse_generic_bounds_common(AllowPlus::Yes, colon_span) + pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> { + self.parse_generic_bounds_common(AllowPlus::Yes) } /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`. /// /// See `parse_generic_bound` for the `BOUND` grammar. - fn parse_generic_bounds_common( - &mut self, - allow_plus: AllowPlus, - colon_span: Option<Span>, - ) -> PResult<'a, GenericBounds> { + fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> { let mut bounds = Vec::new(); - let mut negative_bounds = Vec::new(); // In addition to looping while we find generic bounds: // We continue even if we find a keyword. This is necessary for error recovery on, @@ -698,19 +687,12 @@ impl<'a> Parser<'a> { self.sess.emit_err(InvalidDynKeyword { span: self.token.span }); self.bump(); } - match self.parse_generic_bound()? { - Ok(bound) => bounds.push(bound), - Err(neg_sp) => negative_bounds.push(neg_sp), - } + bounds.push(self.parse_generic_bound()?); if allow_plus == AllowPlus::No || !self.eat_plus() { break; } } - if !negative_bounds.is_empty() { - self.error_negative_bounds(colon_span, &bounds, negative_bounds); - } - Ok(bounds) } @@ -718,55 +700,22 @@ impl<'a> Parser<'a> { fn can_begin_bound(&mut self) -> bool { // This needs to be synchronized with `TokenKind::can_begin_bound`. self.check_path() - || self.check_lifetime() - || self.check(&token::Not) // Used for error reporting only. - || self.check(&token::Question) - || self.check(&token::Tilde) - || self.check_keyword(kw::For) - || self.check(&token::OpenDelim(Delimiter::Parenthesis)) - } - - fn error_negative_bounds( - &self, - colon_span: Option<Span>, - bounds: &[GenericBound], - negative_bounds: Vec<Span>, - ) { - let sub = if let Some(bound_list) = colon_span { - let bound_list = bound_list.to(self.prev_token.span); - let mut new_bound_list = String::new(); - if !bounds.is_empty() { - let mut snippets = bounds.iter().map(|bound| self.span_to_snippet(bound.span())); - while let Some(Ok(snippet)) = snippets.next() { - new_bound_list.push_str(" + "); - new_bound_list.push_str(&snippet); - } - new_bound_list = new_bound_list.replacen(" +", ":", 1); - } - - Some(NegativeBoundsNotSupportedSugg { - bound_list, - num_bounds: negative_bounds.len(), - fixed: new_bound_list, - }) - } else { - None - }; - - let last_span = *negative_bounds.last().expect("no negative bounds, but still error?"); - self.sess.emit_err(NegativeBoundsNotSupported { negative_bounds, last_span, sub }); + || self.check_lifetime() + || self.check(&token::Not) + || self.check(&token::Question) + || self.check(&token::Tilde) + || self.check_keyword(kw::For) + || self.check(&token::OpenDelim(Delimiter::Parenthesis)) } /// Parses a bound according to the grammar: /// ```ebnf /// BOUND = TY_BOUND | LT_BOUND /// ``` - fn parse_generic_bound(&mut self) -> PResult<'a, Result<GenericBound, Span>> { - let anchor_lo = self.prev_token.span; + fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> { let lo = self.token.span; let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis)); let inner_lo = self.token.span; - let is_negative = self.eat(&token::Not); let modifiers = self.parse_ty_bound_modifiers()?; let bound = if self.token.is_lifetime() { @@ -776,7 +725,7 @@ impl<'a> Parser<'a> { self.parse_generic_ty_bound(lo, has_parens, modifiers)? }; - Ok(if is_negative { Err(anchor_lo.to(self.prev_token.span)) } else { Ok(bound) }) + Ok(bound) } /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to: @@ -804,8 +753,14 @@ impl<'a> Parser<'a> { self.sess.emit_err(errors::TildeConstLifetime { span }); } - if let Some(span) = modifiers.maybe { - self.sess.emit_err(errors::MaybeLifetime { span }); + match modifiers.bound_polarity { + BoundPolarity::Positive => {} + BoundPolarity::Negative(span) => { + self.sess.emit_err(errors::ModifierLifetime { span, sigil: "!" }); + } + BoundPolarity::Maybe(span) => { + self.sess.emit_err(errors::ModifierLifetime { span, sigil: "?" }); + } } } @@ -848,9 +803,16 @@ impl<'a> Parser<'a> { None }; - let maybe = self.eat(&token::Question).then_some(self.prev_token.span); + let bound_polarity = if self.eat(&token::Question) { + BoundPolarity::Maybe(self.prev_token.span) + } else if self.eat(&token::Not) { + self.sess.gated_spans.gate(sym::negative_bounds, self.prev_token.span); + BoundPolarity::Negative(self.prev_token.span) + } else { + BoundPolarity::Positive + }; - Ok(BoundModifiers { maybe, maybe_const }) + Ok(BoundModifiers { bound_polarity, maybe_const }) } /// Parses a type bound according to: diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 815b7c85679..982c4615aff 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -189,7 +189,7 @@ fn emit_malformed_attribute( sess.buffer_lint(&ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, &msg); } else { sess.span_diagnostic - .struct_span_err(span, &error_msg) + .struct_span_err(span, error_msg) .span_suggestions( span, if suggestions.len() == 1 { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3f28ac26f86..06aa2737915 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -101,12 +101,11 @@ impl CheckAttrVisitor<'_> { item: Option<ItemLike<'_>>, ) { let mut doc_aliases = FxHashMap::default(); - let mut is_valid = true; let mut specified_inline = None; let mut seen = FxHashMap::default(); let attrs = self.tcx.hir().attrs(hir_id); for attr in attrs { - let attr_is_valid = match attr.name_or_empty() { + match attr.name_or_empty() { sym::do_not_recommend => self.check_do_not_recommend(attr.span, target), sym::inline => self.check_inline(hir_id, attr, span, target), sym::no_coverage => self.check_no_coverage(hir_id, attr, span, target), @@ -188,7 +187,6 @@ impl CheckAttrVisitor<'_> { sym::link_ordinal => self.check_link_ordinal(&attr, span, target), _ => true, }; - is_valid &= attr_is_valid; // lint-only checks match attr.name_or_empty() { @@ -255,10 +253,6 @@ impl CheckAttrVisitor<'_> { self.check_unused_attribute(hir_id, attr) } - if !is_valid { - return; - } - self.check_repr(attrs, span, target, item, hir_id); self.check_used(attrs, target); } diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 30dd3e4d016..6742722ce52 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -148,7 +148,7 @@ impl<'tcx> CheckConstVisitor<'tcx> { [missing_primary, ref missing_secondary @ ..] => { let msg = format!("{} is not allowed in a `{}`", expr.name(), const_kind.keyword_name()); - let mut err = feature_err(&tcx.sess.parse_sess, *missing_primary, span, &msg); + let mut err = feature_err(&tcx.sess.parse_sess, *missing_primary, span, msg); // If multiple feature gates would be required to enable this expression, include // them as help messages. Don't emit a separate error for each missing feature gate. @@ -161,7 +161,7 @@ impl<'tcx> CheckConstVisitor<'tcx> { "add `#![feature({})]` to the crate attributes to enable", gate, ); - err.help(¬e); + err.help(note); } } diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 9dd39a5c9fe..72371b9950b 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -2,6 +2,7 @@ use hir::CRATE_HIR_ID; use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::sync::Lrc; use rustc_expand::base::resolve_path; use rustc_hir as hir; use rustc_hir::HirId; @@ -9,8 +10,6 @@ use rustc_middle::ty::TyCtxt; use rustc_middle::{query::LocalCrate, ty::query::Providers}; use rustc_span::{sym, DebuggerVisualizerFile, DebuggerVisualizerType}; -use std::sync::Arc; - use crate::errors::DebugVisualizerUnreadable; fn check_for_debugger_visualizer( @@ -52,7 +51,7 @@ fn check_for_debugger_visualizer( match std::fs::read(&file) { Ok(contents) => { debugger_visualizers - .insert(DebuggerVisualizerFile::new(Arc::from(contents), visualizer_type)); + .insert(DebuggerVisualizerFile::new(Lrc::from(contents), visualizer_type)); } Err(error) => { tcx.sess.emit_err(DebugVisualizerUnreadable { diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 3942a73befd..363e1743677 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -31,7 +31,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { if !errors.is_empty() { let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2); - tcx.sess.delay_span_bug(rustc_span::DUMMY_SP, &message); + tcx.sess.delay_span_bug(rustc_span::DUMMY_SP, message); } } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index c607c7fd5f4..b738ce35ada 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -25,7 +25,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; -use rustc_middle::middle::privacy::{EffectiveVisibilities, Level}; +use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; use rustc_middle::span_bug; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; @@ -38,7 +38,7 @@ use rustc_span::Span; use std::marker::PhantomData; use std::ops::ControlFlow; -use std::{cmp, fmt, mem}; +use std::{fmt, mem}; use errors::{ FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, @@ -127,18 +127,19 @@ where fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> { let tcx = self.def_id_visitor.tcx(); - let (trait_ref, assoc_substs) = - if tcx.def_kind(projection.def_id) != DefKind::ImplTraitPlaceholder { - projection.trait_ref_and_own_substs(tcx) - } else { - // HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys - let def_id = tcx.impl_trait_in_trait_parent_fn(projection.def_id); - let trait_generics = tcx.generics_of(def_id); - ( - tcx.mk_trait_ref(def_id, projection.substs.truncate_to(tcx, trait_generics)), - &projection.substs[trait_generics.count()..], - ) - }; + let (trait_ref, assoc_substs) = if tcx.def_kind(projection.def_id) + != DefKind::ImplTraitPlaceholder + { + projection.trait_ref_and_own_substs(tcx) + } else { + // HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys + let def_id = tcx.impl_trait_in_trait_parent_fn(projection.def_id); + let trait_generics = tcx.generics_of(def_id); + ( + ty::TraitRef::new(tcx, def_id, projection.substs.truncate_to(tcx, trait_generics)), + &projection.substs[trait_generics.count()..], + ) + }; self.visit_trait(trait_ref)?; if self.def_id_visitor.shallow() { ControlFlow::Continue(()) @@ -374,8 +375,9 @@ impl VisibilityLike for ty::Visibility { min(find.tcx.local_visibility(def_id), find.min, find.tcx) } } -impl VisibilityLike for Option<Level> { - const MAX: Self = Some(Level::Direct); + +impl VisibilityLike for Option<EffectiveVisibility> { + const MAX: Self = Some(EffectiveVisibility::from_vis(ty::Visibility::Public)); // Type inference is very smart sometimes. // It can make an impl reachable even some components of its type or trait are unreachable. // E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }` @@ -387,7 +389,13 @@ impl VisibilityLike for Option<Level> { // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { - cmp::min(find.effective_visibilities.public_at_level(def_id), find.min) + if let Some(min) = find.min { + return find + .effective_visibilities + .effective_vis(def_id) + .map(|eff_vis| min.min(*eff_vis, find.tcx)); + } + None } } @@ -413,49 +421,79 @@ struct EmbargoVisitor<'tcx> { /// n::p::f() /// } macro_reachable: FxHashSet<(LocalDefId, LocalDefId)>, - /// Previous visibility level; `None` means unreachable. - prev_level: Option<Level>, /// Has something changed in the level map? changed: bool, } struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> { - level: Option<Level>, + effective_vis: Option<EffectiveVisibility>, item_def_id: LocalDefId, ev: &'a mut EmbargoVisitor<'tcx>, + level: Level, } impl<'tcx> EmbargoVisitor<'tcx> { - fn get(&self, def_id: LocalDefId) -> Option<Level> { - self.effective_visibilities.public_at_level(def_id) - } - - /// Updates node level and returns the updated level. - fn update(&mut self, def_id: LocalDefId, level: Option<Level>) -> Option<Level> { - let old_level = self.get(def_id); - // Visibility levels can only grow. - if level > old_level { - self.effective_visibilities.set_public_at_level( - def_id, - || ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id)), - level.unwrap(), - ); - self.changed = true; - level - } else { - old_level + fn get(&self, def_id: LocalDefId) -> Option<EffectiveVisibility> { + self.effective_visibilities.effective_vis(def_id).copied() + } + + // Updates node effective visibility. + fn update( + &mut self, + def_id: LocalDefId, + inherited_effective_vis: Option<EffectiveVisibility>, + level: Level, + ) { + let nominal_vis = self.tcx.local_visibility(def_id); + self.update_eff_vis(def_id, inherited_effective_vis, Some(nominal_vis), level); + } + + fn update_eff_vis( + &mut self, + def_id: LocalDefId, + inherited_effective_vis: Option<EffectiveVisibility>, + nominal_vis: Option<ty::Visibility>, + level: Level, + ) { + if let Some(inherited_effective_vis) = inherited_effective_vis { + let private_vis = + ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id)); + if Some(private_vis) != nominal_vis { + self.changed |= self.effective_visibilities.update( + def_id, + nominal_vis, + || private_vis, + inherited_effective_vis, + level, + self.tcx, + ); + } } } fn reach( &mut self, def_id: LocalDefId, - level: Option<Level>, + effective_vis: Option<EffectiveVisibility>, + ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { + ReachEverythingInTheInterfaceVisitor { + effective_vis, + item_def_id: def_id, + ev: self, + level: Level::Reachable, + } + } + + fn reach_through_impl_trait( + &mut self, + def_id: LocalDefId, + effective_vis: Option<EffectiveVisibility>, ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { ReachEverythingInTheInterfaceVisitor { - level: cmp::min(level, Some(Level::Reachable)), + effective_vis, item_def_id: def_id, ev: self, + level: Level::ReachableThroughImplTrait, } } @@ -476,16 +514,18 @@ impl<'tcx> EmbargoVisitor<'tcx> { return; } - if self.get(local_def_id).is_none() { + if self.effective_visibilities.public_at_level(local_def_id).is_none() { return; } // Since we are starting from an externally visible module, // all the parents in the loop below are also guaranteed to be modules. let mut module_def_id = macro_module_def_id; + let macro_ev = self.get(local_def_id); + assert!(macro_ev.is_some()); loop { let changed_reachability = - self.update_macro_reachable(module_def_id, macro_module_def_id); + self.update_macro_reachable(module_def_id, macro_module_def_id, macro_ev); if changed_reachability || module_def_id == CRATE_DEF_ID { break; } @@ -499,28 +539,42 @@ impl<'tcx> EmbargoVisitor<'tcx> { &mut self, module_def_id: LocalDefId, defining_mod: LocalDefId, + macro_ev: Option<EffectiveVisibility>, ) -> bool { if self.macro_reachable.insert((module_def_id, defining_mod)) { - self.update_macro_reachable_mod(module_def_id, defining_mod); + self.update_macro_reachable_mod(module_def_id, defining_mod, macro_ev); true } else { false } } - fn update_macro_reachable_mod(&mut self, module_def_id: LocalDefId, defining_mod: LocalDefId) { + fn update_macro_reachable_mod( + &mut self, + module_def_id: LocalDefId, + defining_mod: LocalDefId, + macro_ev: Option<EffectiveVisibility>, + ) { let module = self.tcx.hir().get_module(module_def_id).0; for item_id in module.item_ids { let def_kind = self.tcx.def_kind(item_id.owner_id); let vis = self.tcx.local_visibility(item_id.owner_id.def_id); - self.update_macro_reachable_def(item_id.owner_id.def_id, def_kind, vis, defining_mod); + self.update_macro_reachable_def( + item_id.owner_id.def_id, + def_kind, + vis, + defining_mod, + macro_ev, + ); } - for export in self.tcx.module_children_reexports(module_def_id) { - if export.vis.is_accessible_from(defining_mod, self.tcx) - && let Res::Def(def_kind, def_id) = export.res + for child in self.tcx.module_children_local(module_def_id) { + // FIXME: Use module children for the logic above too. + if !child.reexport_chain.is_empty() + && child.vis.is_accessible_from(defining_mod, self.tcx) + && let Res::Def(def_kind, def_id) = child.res && let Some(def_id) = def_id.as_local() { let vis = self.tcx.local_visibility(def_id); - self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod); + self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod, macro_ev); } } } @@ -531,16 +585,14 @@ impl<'tcx> EmbargoVisitor<'tcx> { def_kind: DefKind, vis: ty::Visibility, module: LocalDefId, + macro_ev: Option<EffectiveVisibility>, ) { - let level = Some(Level::Reachable); - if vis.is_public() { - self.update(def_id, level); - } + self.update(def_id, macro_ev, Level::Reachable); match def_kind { // No type privacy, so can be directly marked as reachable. DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => { if vis.is_accessible_from(module, self.tcx) { - self.update(def_id, level); + self.update(def_id, macro_ev, Level::Reachable); } } @@ -552,7 +604,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { let item = self.tcx.hir().expect_item(def_id); if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { if vis.is_accessible_from(module, self.tcx) { - self.update(def_id, level); + self.update(def_id, macro_ev, Level::Reachable); } } } @@ -563,26 +615,24 @@ impl<'tcx> EmbargoVisitor<'tcx> { // the module, however may be reachable. DefKind::Mod => { if vis.is_accessible_from(module, self.tcx) { - self.update_macro_reachable(def_id, module); + self.update_macro_reachable(def_id, module, macro_ev); } } DefKind::Struct | DefKind::Union => { // While structs and unions have type privacy, their fields do not. - if vis.is_public() { - let item = self.tcx.hir().expect_item(def_id); - if let hir::ItemKind::Struct(ref struct_def, _) - | hir::ItemKind::Union(ref struct_def, _) = item.kind - { - for field in struct_def.fields() { - let field_vis = self.tcx.local_visibility(field.def_id); - if field_vis.is_accessible_from(module, self.tcx) { - self.reach(field.def_id, level).ty(); - } + let item = self.tcx.hir().expect_item(def_id); + if let hir::ItemKind::Struct(ref struct_def, _) + | hir::ItemKind::Union(ref struct_def, _) = item.kind + { + for field in struct_def.fields() { + let field_vis = self.tcx.local_visibility(field.def_id); + if field_vis.is_accessible_from(module, self.tcx) { + self.reach(field.def_id, macro_ev).ty(); } - } else { - bug!("item {:?} with DefKind {:?}", item, def_kind); } + } else { + bug!("item {:?} with DefKind {:?}", item, def_kind); } } @@ -626,14 +676,16 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - let item_level = match item.kind { + let item_ev = match item.kind { hir::ItemKind::Impl { .. } => { - let impl_level = Option::<Level>::of_impl( + let impl_ev = Option::<EffectiveVisibility>::of_impl( item.owner_id.def_id, self.tcx, &self.effective_visibilities, ); - self.update(item.owner_id.def_id, impl_level) + + self.update_eff_vis(item.owner_id.def_id, impl_ev, None, Level::Direct); + impl_ev } _ => self.get(item.owner_id.def_id), }; @@ -642,38 +694,32 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { match item.kind { hir::ItemKind::Enum(ref def, _) => { for variant in def.variants { - let variant_level = self.update(variant.def_id, item_level); + self.update(variant.def_id, item_ev, Level::Reachable); + let variant_ev = self.get(variant.def_id); if let Some(ctor_def_id) = variant.data.ctor_def_id() { - self.update(ctor_def_id, item_level); + self.update(ctor_def_id, variant_ev, Level::Reachable); } for field in variant.data.fields() { - self.update(field.def_id, variant_level); + self.update(field.def_id, variant_ev, Level::Reachable); } } } hir::ItemKind::Impl(ref impl_) => { for impl_item_ref in impl_.items { - if impl_.of_trait.is_some() - || self.tcx.visibility(impl_item_ref.id.owner_id).is_public() - { - self.update(impl_item_ref.id.owner_id.def_id, item_level); - } + self.update(impl_item_ref.id.owner_id.def_id, item_ev, Level::Direct); } } hir::ItemKind::Trait(.., trait_item_refs) => { for trait_item_ref in trait_item_refs { - self.update(trait_item_ref.id.owner_id.def_id, item_level); + self.update(trait_item_ref.id.owner_id.def_id, item_ev, Level::Reachable); } } hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => { if let Some(ctor_def_id) = def.ctor_def_id() { - self.update(ctor_def_id, item_level); + self.update(ctor_def_id, item_ev, Level::Reachable); } for field in def.fields() { - let vis = self.tcx.visibility(field.def_id); - if vis.is_public() { - self.update(field.def_id, item_level); - } + self.update(field.def_id, item_ev, Level::Reachable); } } hir::ItemKind::Macro(ref macro_def, _) => { @@ -681,9 +727,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { - if self.tcx.visibility(foreign_item.id.owner_id).is_public() { - self.update(foreign_item.id.owner_id.def_id, item_level); - } + self.update(foreign_item.id.owner_id.def_id, item_ev, Level::Reachable); } } @@ -718,8 +762,11 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // FIXME: This is some serious pessimization intended to workaround deficiencies // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time // reachable if they are returned via `impl Trait`, even from private functions. - let exist_level = cmp::max(item_level, Some(Level::ReachableThroughImplTrait)); - self.reach(item.owner_id.def_id, exist_level).generics().predicates().ty(); + let exist_ev = Some(EffectiveVisibility::from_vis(ty::Visibility::Public)); + self.reach_through_impl_trait(item.owner_id.def_id, exist_ev) + .generics() + .predicates() + .ty(); } } // Visit everything. @@ -727,17 +774,18 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { | hir::ItemKind::Static(..) | hir::ItemKind::Fn(..) | hir::ItemKind::TyAlias(..) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates().ty(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty(); } } hir::ItemKind::Trait(.., trait_item_refs) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates(); for trait_item_ref in trait_item_refs { let tcx = self.tcx; - let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_level); + let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_ev); + reach.generics().predicates(); if trait_item_ref.kind == AssocItemKind::Type @@ -751,23 +799,24 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } } hir::ItemKind::TraitAlias(..) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates(); } } // Visit everything except for private impl items. hir::ItemKind::Impl(ref impl_) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level) + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev) .generics() .predicates() .ty() .trait_ref(); for impl_item_ref in impl_.items { - let impl_item_level = self.get(impl_item_ref.id.owner_id.def_id); - if impl_item_level.is_some() { - self.reach(impl_item_ref.id.owner_id.def_id, impl_item_level) + let impl_item_ev = self.get(impl_item_ref.id.owner_id.def_id); + + if impl_item_ev.is_some() { + self.reach(impl_item_ref.id.owner_id.def_id, impl_item_ev) .generics() .predicates() .ty(); @@ -778,23 +827,23 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // Visit everything, but enum variants have their own levels. hir::ItemKind::Enum(ref def, _) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates(); } for variant in def.variants { - let variant_level = self.get(variant.def_id); - if variant_level.is_some() { + let variant_ev = self.get(variant.def_id); + if variant_ev.is_some() { for field in variant.data.fields() { - self.reach(field.def_id, variant_level).ty(); + self.reach(field.def_id, variant_ev).ty(); } // Corner case: if the variant is reachable, but its // enum is not, make the enum reachable as well. - self.reach(item.owner_id.def_id, variant_level).ty(); + self.reach(item.owner_id.def_id, variant_ev).ty(); } if let Some(ctor_def_id) = variant.data.ctor_def_id() { - let ctor_level = self.get(ctor_def_id); - if ctor_level.is_some() { - self.reach(item.owner_id.def_id, ctor_level).ty(); + let ctor_ev = self.get(ctor_def_id); + if ctor_ev.is_some() { + self.reach(item.owner_id.def_id, ctor_ev).ty(); } } } @@ -802,9 +851,9 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // Visit everything, but foreign items have their own levels. hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { - let foreign_item_level = self.get(foreign_item.id.owner_id.def_id); - if foreign_item_level.is_some() { - self.reach(foreign_item.id.owner_id.def_id, foreign_item_level) + let foreign_item_ev = self.get(foreign_item.id.owner_id.def_id); + if foreign_item_ev.is_some() { + self.reach(foreign_item.id.owner_id.def_id, foreign_item_ev) .generics() .predicates() .ty(); @@ -813,36 +862,32 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } // Visit everything except for private fields. hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates(); for field in struct_def.fields() { - let field_level = self.get(field.def_id); - if field_level.is_some() { - self.reach(field.def_id, field_level).ty(); + let field_ev = self.get(field.def_id); + if field_ev.is_some() { + self.reach(field.def_id, field_ev).ty(); } } } if let Some(ctor_def_id) = struct_def.ctor_def_id() { - let ctor_level = self.get(ctor_def_id); - if ctor_level.is_some() { - self.reach(item.owner_id.def_id, ctor_level).ty(); + let ctor_ev = self.get(ctor_def_id); + if ctor_ev.is_some() { + self.reach(item.owner_id.def_id, ctor_ev).ty(); } } } } - let orig_level = mem::replace(&mut self.prev_level, item_level); intravisit::walk_item(self, item); - self.prev_level = orig_level; } fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) { // Blocks can have public items, for example impls, but they always // start as completely private regardless of publicity of a function, // constant, type, field, etc., in which this block resides. - let orig_level = mem::replace(&mut self.prev_level, None); intravisit::walk_block(self, b); - self.prev_level = orig_level; } } @@ -896,11 +941,7 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> _descr: &dyn fmt::Display, ) -> ControlFlow<Self::BreakTy> { if let Some(def_id) = def_id.as_local() { - if let (ty::Visibility::Public, _) | (_, Some(Level::ReachableThroughImplTrait)) = - (self.tcx().visibility(def_id.to_def_id()), self.level) - { - self.ev.update(def_id, self.level); - } + self.ev.update_eff_vis(def_id, self.effective_vis, None, self.level); } ControlFlow::Continue(()) } @@ -2128,7 +2169,6 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { tcx, effective_visibilities: tcx.resolutions(()).effective_visibilities.clone(), macro_reachable: Default::default(), - prev_level: Some(Level::Direct), changed: false, }; diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index a534b54070c..5f2ec656d1d 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -633,7 +633,7 @@ pub fn print_query_stack<Qcx: QueryContext>( }; let mut diag = Diagnostic::new( Level::FailureNote, - &format!("#{} [{:?}] {}", i, query_info.query.dep_kind, query_info.query.description), + format!("#{} [{:?}] {}", i, query_info.query.dep_kind, query_info.query.description), ); diag.span = query_info.job.span.into(); handler.force_print_diagnostic(diag); diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 3799679cb1e..2438b3a38ed 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1002,7 +1002,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { let msg = format!("`{}` is already in scope", name); let note = "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)"; - self.r.tcx.sess.struct_span_err(span, &msg).note(note).emit(); + self.r.tcx.sess.struct_span_err(span, msg).note(note).emit(); } } diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index ae3fd0ede6c..17c4a6be049 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -418,7 +418,7 @@ impl Resolver<'_, '_> { UNUSED_IMPORTS, unused.use_tree_id, ms, - &msg, + msg, BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes, test_module_span), ); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 4b7048eac04..fae7d549592 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -238,7 +238,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }, }; - err.note(&format!( + err.note(format!( "`{}` must be defined only once in the {} namespace of this {}", name, ns.descr(), @@ -550,7 +550,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let sm = self.tcx.sess.source_map(); let def_id = match outer_res { - Res::SelfTyParam { .. } => { + Res::SelfTyParam { .. } | Res::SelfCtor(_) => { err.span_label(span, "can't use `Self` here"); return err; } @@ -683,7 +683,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { making the path in the pattern qualified: `path::to::ModOrType::{}`", name, ); - err.span_help(span, &help_msg); + err.span_help(span, help_msg); } show_candidates( self.tcx, @@ -783,10 +783,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some((suggestions, msg, applicability)) = suggestion { if suggestions.is_empty() { - err.help(&msg); + err.help(msg); return err; } - err.multipart_suggestion(&msg, suggestions, applicability); + err.multipart_suggestion(msg, suggestions, applicability); } err @@ -930,7 +930,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } => { let mut err = self.tcx.sess.struct_span_err_with_code( span, - &format!( + format!( "item `{}` is an associated {}, which doesn't match its trait `{}`", name, kind, trait_path, ), @@ -1359,7 +1359,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) { let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident); - err.span_note(ident.span, &msg); + err.span_note(ident.span, msg); return; } if self.macro_names.contains(&ident.normalize_to_macros_2_0()) { @@ -1419,7 +1419,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !import.span.is_dummy() { err.span_note( import.span, - &format!("`{}` is imported here, but it is {}", ident, desc), + format!("`{}` is imported here, but it is {}", ident, desc), ); // Silence the 'unused import' warning we might get, // since this diagnostic already covers that import. @@ -1427,7 +1427,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return; } } - err.note(&format!("`{}` is in scope, but it is {}", ident, desc)); + err.note(format!("`{}` is in scope, but it is {}", ident, desc)); return; } } @@ -1474,7 +1474,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { err.span_label( self.tcx.sess.source_map().guess_head_span(def_span), - &format!( + format!( "{}{} `{}` defined here", prefix, suggestion.res.descr(), @@ -1492,7 +1492,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { format!("maybe you meant this {}", suggestion.res.descr()) } }; - err.span_suggestion(span, &msg, suggestion.candidate, Applicability::MaybeIncorrect); + err.span_suggestion(span, msg, suggestion.candidate, Applicability::MaybeIncorrect); true } @@ -1534,7 +1534,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut err = struct_span_err!(self.tcx.sess, ident.span, E0659, "`{ident}` is ambiguous"); err.span_label(ident.span, "ambiguous name"); - err.note(&format!("ambiguous because of {}", kind.descr())); + err.note(format!("ambiguous because of {}", kind.descr())); let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| { let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude); @@ -1562,10 +1562,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { AmbiguityErrorMisc::FromPrelude | AmbiguityErrorMisc::None => {} } - err.span_note(b.span, ¬e_msg); + err.span_note(b.span, note_msg); for (i, help_msg) in help_msgs.iter().enumerate() { let or = if i == 0 { "" } else { "or " }; - err.help(&format!("{}{}", or, help_msg)); + err.help(format!("{}{}", or, help_msg)); } }; @@ -1608,7 +1608,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let descr = get_descr(binding); let mut err = struct_span_err!(self.tcx.sess, ident.span, E0603, "{} `{}` is private", descr, ident); - err.span_label(ident.span, &format!("private {}", descr)); + err.span_label(ident.span, format!("private {}", descr)); let mut non_exhaustive = None; // If an ADT is foreign and marked as `non_exhaustive`, then that's @@ -1623,7 +1623,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { err.span_label(span, "a constructor is private if any of the fields is private"); if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) { err.multipart_suggestion_verbose( - &format!( + format!( "consider making the field{} publicly accessible", pluralize!(fields.len()) ), @@ -1676,7 +1676,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { format!("cannot be constructed because it is `#[non_exhaustive]`"), ); } - err.span_note(note_span, &msg); + err.span_note(note_span, msg); } err.emit(); @@ -2444,7 +2444,7 @@ fn show_candidates( }; for note in accessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) { - err.note(note); + err.note(note.clone()); } if let Some(span) = use_placement_span { @@ -2452,7 +2452,7 @@ fn show_candidates( DiagnosticMode::Pattern => { err.span_suggestions( span, - &msg, + msg, accessible_path_strings.into_iter().map(|a| a.0), Applicability::MaybeIncorrect, ); @@ -2471,7 +2471,7 @@ fn show_candidates( err.span_suggestions_with_style( span, - &msg, + msg, accessible_path_strings.into_iter().map(|a| a.0), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways, @@ -2481,7 +2481,7 @@ fn show_candidates( if sp.can_be_used_for_suggestions() { err.span_suggestion_verbose( sp, - &format!("if you import `{}`, refer to it directly", last.ident), + format!("if you import `{}`, refer to it directly", last.ident), "", Applicability::Unspecified, ); @@ -2495,7 +2495,7 @@ fn show_candidates( msg.push_str(&candidate.0); } - err.help(&msg); + err.help(msg); } } else if !matches!(mode, DiagnosticMode::Import) { assert!(!inaccessible_path_strings.is_empty()); @@ -2520,9 +2520,9 @@ fn show_candidates( let span = tcx.sess.source_map().guess_head_span(span); let mut multi_span = MultiSpan::from_span(span); multi_span.push_span_label(span, "not accessible"); - err.span_note(multi_span, &msg); + err.span_note(multi_span, msg); } else { - err.note(&msg); + err.note(msg); } if let Some(note) = (*note).as_deref() { err.note(note); @@ -2566,10 +2566,10 @@ fn show_candidates( } for note in inaccessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) { - err.note(note); + err.note(note.clone()); } - err.span_note(multi_span, &msg); + err.span_note(multi_span, msg); } } } diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 87067189a77..7393bdb388a 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -199,7 +199,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { let tcx = self.r.tcx; self.changed |= self.import_effective_visibilities.update( binding, - nominal_vis, + Some(nominal_vis), || cheap_private_vis.unwrap_or_else(|| self.r.private_vis_import(binding)), inherited_eff_vis, parent_id.level(), @@ -213,7 +213,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { let tcx = self.r.tcx; self.changed |= self.def_effective_visibilities.update( def_id, - nominal_vis, + Some(nominal_vis), || cheap_private_vis.unwrap_or_else(|| self.r.private_vis_def(def_id)), inherited_eff_vis, parent_id.level(), diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 5a56d7b99a9..2db1d83d4fd 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -24,7 +24,6 @@ use crate::{ResolutionError, Resolver, Scope, ScopeSet, Segment, ToNameBinding, use Determinacy::*; use Namespace::*; -use RibKind::*; type Visibility = ty::Visibility<LocalDefId>; @@ -324,8 +323,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } module = match ribs[i].kind { - ModuleRibKind(module) => module, - MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => { + RibKind::Module(module) => module, + RibKind::MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => { // If an invocation of this macro created `ident`, give up on `ident` // and switch to `ident`'s source from the macro definition. ident.span.remove_mark(); @@ -527,7 +526,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, lint_id, orig_ident.span, - &format!( + format!( "cannot find {} `{}` in this scope", ns.descr(), ident @@ -1084,7 +1083,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let ribs = &all_ribs[rib_index + 1..]; // An invalid forward use of a generic parameter from a previous default. - if let ForwardGenericParamBanRibKind = all_ribs[rib_index].kind { + if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind { if let Some(span) = finalize { let res_error = if rib_ident.name == kw::SelfUpper { ResolutionError::SelfInGenericParamDefault @@ -1104,14 +1103,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { for rib in ribs { match rib.kind { - NormalRibKind - | ClosureOrAsyncRibKind - | ModuleRibKind(..) - | MacroDefinition(..) - | ForwardGenericParamBanRibKind => { + RibKind::Normal + | RibKind::ClosureOrAsync + | RibKind::Module(..) + | RibKind::MacroDefinition(..) + | RibKind::ForwardGenericParamBan => { // Nothing to do. Continue. } - ItemRibKind(_) | AssocItemRibKind => { + RibKind::Item(_) | RibKind::AssocItem => { // This was an attempt to access an upvar inside a // named function item. This is not allowed, so we // report an error. @@ -1123,7 +1122,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem)); } } - ConstantItemRibKind(_, item) => { + RibKind::ConstantItem(_, item) => { // Still doesn't deal with upvars if let Some(span) = finalize { let (span, resolution_error) = @@ -1152,13 +1151,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } return Res::Err; } - ConstParamTyRibKind => { + RibKind::ConstParamTy => { if let Some(span) = finalize { self.report_error(span, ParamInTyOfConstParam(rib_ident.name)); } return Res::Err; } - InlineAsmSymRibKind => { + RibKind::InlineAsmSym => { if let Some(span) = finalize { self.report_error(span, InvalidAsmSym); } @@ -1171,21 +1170,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return Res::Err; } } - Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => { + Res::Def(DefKind::TyParam, _) + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } + | Res::SelfCtor(_) => { for rib in ribs { let has_generic_params: HasGenericParams = match rib.kind { - NormalRibKind - | ClosureOrAsyncRibKind - | ModuleRibKind(..) - | MacroDefinition(..) - | InlineAsmSymRibKind - | AssocItemRibKind - | ForwardGenericParamBanRibKind => { + RibKind::Normal + | RibKind::ClosureOrAsync + | RibKind::Module(..) + | RibKind::MacroDefinition(..) + | RibKind::InlineAsmSym + | RibKind::AssocItem + | RibKind::ForwardGenericParamBan => { // Nothing to do. Continue. continue; } - ConstantItemRibKind(trivial, _) => { + RibKind::ConstantItem(trivial, _) => { let features = self.tcx.sess.features_untracked(); // HACK(min_const_generics): We currently only allow `N` or `{ N }`. if !(trivial == ConstantHasGenerics::Yes @@ -1226,8 +1228,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } // This was an attempt to use a type parameter outside its scope. - ItemRibKind(has_generic_params) => has_generic_params, - ConstParamTyRibKind => { + RibKind::Item(has_generic_params) => has_generic_params, + RibKind::ConstParamTy => { if let Some(span) = finalize { self.report_error( span, @@ -1253,15 +1255,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Res::Def(DefKind::ConstParam, _) => { for rib in ribs { let has_generic_params = match rib.kind { - NormalRibKind - | ClosureOrAsyncRibKind - | ModuleRibKind(..) - | MacroDefinition(..) - | InlineAsmSymRibKind - | AssocItemRibKind - | ForwardGenericParamBanRibKind => continue, - - ConstantItemRibKind(trivial, _) => { + RibKind::Normal + | RibKind::ClosureOrAsync + | RibKind::Module(..) + | RibKind::MacroDefinition(..) + | RibKind::InlineAsmSym + | RibKind::AssocItem + | RibKind::ForwardGenericParamBan => continue, + + RibKind::ConstantItem(trivial, _) => { let features = self.tcx.sess.features_untracked(); // HACK(min_const_generics): We currently only allow `N` or `{ N }`. if !(trivial == ConstantHasGenerics::Yes @@ -1284,8 +1286,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { continue; } - ItemRibKind(has_generic_params) => has_generic_params, - ConstParamTyRibKind => { + RibKind::Item(has_generic_params) => has_generic_params, + RibKind::ConstParamTy => { if let Some(span) = finalize { self.report_error( span, @@ -1345,7 +1347,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ribs: Option<&PerNS<Vec<Rib<'a>>>>, ignore_binding: Option<&'a NameBinding<'a>>, ) -> PathResult<'a> { - debug!("resolve_path(path={:?}, opt_ns={:?}, finalize={:?})", path, opt_ns, finalize); + debug!( + "resolve_path(path={:?}, opt_ns={:?}, finalize={:?}) path_len: {}", + path, + opt_ns, + finalize, + path.len() + ); let mut module = None; let mut allow_super = true; diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index d7c518fbdd0..9e4429507b1 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -578,7 +578,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg); if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() { - diag.note(note); + diag.note(note.clone()); } for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) { @@ -588,10 +588,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some((suggestions, msg, applicability)) = err.suggestion { if suggestions.is_empty() { - diag.help(&msg); + diag.help(msg); continue; } - diag.multipart_suggestion(&msg, suggestions, applicability); + diag.multipart_suggestion(msg, suggestions, applicability); } if let Some(candidates) = &err.candidates { @@ -1063,7 +1063,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { PUB_USE_OF_PRIVATE_EXTERN_CRATE, import_id, import.span, - &msg, + msg, ); } else { let error_msg = if crate_private_reexport { @@ -1084,7 +1084,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg) .span_label(import.span, label_msg) - .note(&format!("consider declaring type or module `{}` with `pub`", ident)) + .note(format!("consider declaring type or module `{}` with `pub`", ident)) .emit(); } else { let mut err = @@ -1102,7 +1102,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { _ => { err.span_note( import.span, - &format!( + format!( "consider marking `{ident}` as `pub` in the imported module" ), ); @@ -1200,7 +1200,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { UNUSED_IMPORTS, id, import.span, - &format!("the item `{}` is imported redundantly", ident), + format!("the item `{}` is imported redundantly", ident), BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident), ); } @@ -1261,14 +1261,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { *module.globs.borrow_mut() = Vec::new(); if let Some(def_id) = module.opt_def_id() { - let mut non_reexports = Vec::new(); - let mut reexports = Vec::new(); + let mut children = Vec::new(); module.for_each_child(self, |this, ident, _, binding| { let res = binding.res().expect_non_local(); - if !binding.is_import() { - non_reexports.push(res.def_id().expect_local()); - } else if res != def::Res::Err && !binding.is_ambiguity() { + if res != def::Res::Err && !binding.is_ambiguity() { let mut reexport_chain = SmallVec::new(); let mut next_binding = binding; while let NameBindingKind::Import { binding, import, .. } = next_binding.kind { @@ -1276,17 +1273,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { next_binding = binding; } - reexports.push(ModChild { ident, res, vis: binding.vis, reexport_chain }); + children.push(ModChild { ident, res, vis: binding.vis, reexport_chain }); } }); - // Should be fine because this code is only called for local modules. - let def_id = def_id.expect_local(); - if !non_reexports.is_empty() { - self.module_children_non_reexports.insert(def_id, non_reexports); - } - if !reexports.is_empty() { - self.module_children_reexports.insert(def_id, reexports); + if !children.is_empty() { + // Should be fine because this code is only called for local modules. + self.module_children.insert(def_id.expect_local(), children); } } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 511ae8516a8..6f5d54bcf87 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -6,8 +6,6 @@ //! If you wonder why there's no `early.rs`, that's because it's split into three files - //! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`. -use RibKind::*; - use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding}; use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult}; use crate::{ResolutionError, Resolver, Segment, UseError}; @@ -133,28 +131,28 @@ enum RecordPartialRes { #[derive(Copy, Clone, Debug)] pub(crate) enum RibKind<'a> { /// No restriction needs to be applied. - NormalRibKind, + Normal, /// We passed through an impl or trait and are now in one of its /// methods or associated types. Allow references to ty params that impl or trait /// binds. Disallow any other upvars (including other ty params that are /// upvars). - AssocItemRibKind, + AssocItem, /// We passed through a closure. Disallow labels. - ClosureOrAsyncRibKind, + ClosureOrAsync, /// We passed through an item scope. Disallow upvars. - ItemRibKind(HasGenericParams), + Item(HasGenericParams), /// We're in a constant item. Can't refer to dynamic stuff. /// /// The item may reference generic parameters in trivial constant expressions. /// All other constants aren't allowed to use generic params at all. - ConstantItemRibKind(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>), + ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>), /// We passed through a module. - ModuleRibKind(Module<'a>), + Module(Module<'a>), /// We passed through a `macro_rules!` statement MacroDefinition(DefId), @@ -162,15 +160,15 @@ pub(crate) enum RibKind<'a> { /// All bindings in this rib are generic parameters that can't be used /// from the default of a generic parameter because they're not declared /// before said generic parameter. Also see the `visit_generics` override. - ForwardGenericParamBanRibKind, + ForwardGenericParamBan, /// We are inside of the type of a const parameter. Can't refer to any /// parameters. - ConstParamTyRibKind, + ConstParamTy, /// We are inside a `sym` inline assembly operand. Can only refer to /// globals. - InlineAsmSymRibKind, + InlineAsmSym, } impl RibKind<'_> { @@ -178,30 +176,30 @@ impl RibKind<'_> { /// variables. pub(crate) fn contains_params(&self) -> bool { match self { - NormalRibKind - | ClosureOrAsyncRibKind - | ConstantItemRibKind(..) - | ModuleRibKind(_) - | MacroDefinition(_) - | ConstParamTyRibKind - | InlineAsmSymRibKind => false, - AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true, + RibKind::Normal + | RibKind::ClosureOrAsync + | RibKind::ConstantItem(..) + | RibKind::Module(_) + | RibKind::MacroDefinition(_) + | RibKind::ConstParamTy + | RibKind::InlineAsmSym => false, + RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true, } } /// This rib forbids referring to labels defined in upwards ribs. fn is_label_barrier(self) -> bool { match self { - NormalRibKind | MacroDefinition(..) => false, - - AssocItemRibKind - | ClosureOrAsyncRibKind - | ItemRibKind(..) - | ConstantItemRibKind(..) - | ModuleRibKind(..) - | ForwardGenericParamBanRibKind - | ConstParamTyRibKind - | InlineAsmSymRibKind => true, + RibKind::Normal | RibKind::MacroDefinition(..) => false, + + RibKind::AssocItem + | RibKind::ClosureOrAsync + | RibKind::Item(..) + | RibKind::ConstantItem(..) + | RibKind::Module(..) + | RibKind::ForwardGenericParamBan + | RibKind::ConstParamTy + | RibKind::InlineAsmSym => true, } } } @@ -548,9 +546,6 @@ struct DiagnosticMetadata<'ast> { /// they are used (in a `break` or `continue` statement) unused_labels: FxHashMap<NodeId, Span>, - /// Only used for better errors on `fn(): fn()`. - current_type_ascription: Vec<Span>, - /// Only used for better errors on `let x = { foo: bar };`. /// In the case of a parse error with `let x = { foo: bar, };`, this isn't needed, it's only /// needed for cases where this parses as a correct type ascription. @@ -705,7 +700,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, let span = ty.span.shrink_to_lo().to(path.span.shrink_to_lo()); self.with_generic_param_rib( &[], - NormalRibKind, + RibKind::Normal, LifetimeRibKind::Generics { binder: ty.id, kind: LifetimeBinderKind::PolyTrait, @@ -743,7 +738,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo()); self.with_generic_param_rib( &bare_fn.generic_params, - NormalRibKind, + RibKind::Normal, LifetimeRibKind::Generics { binder: ty.id, kind: LifetimeBinderKind::BareFnType, @@ -783,7 +778,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo()); self.with_generic_param_rib( &tref.bound_generic_params, - NormalRibKind, + RibKind::Normal, LifetimeRibKind::Generics { binder: tref.trait_ref.ref_id, kind: LifetimeBinderKind::PolyTrait, @@ -807,7 +802,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => { self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes(generics.span)), + RibKind::Item(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: foreign_item.id, kind: LifetimeBinderKind::Item, @@ -819,7 +814,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, ForeignItemKind::Fn(box Fn { ref generics, .. }) => { self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes(generics.span)), + RibKind::Item(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: foreign_item.id, kind: LifetimeBinderKind::Function, @@ -873,9 +868,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, debug!("(resolving function) entering function"); // Create a value rib for the function. - self.with_rib(ValueNS, ClosureOrAsyncRibKind, |this| { + self.with_rib(ValueNS, RibKind::ClosureOrAsync, |this| { // Create a label rib for the function. - this.with_label_rib(ClosureOrAsyncRibKind, |this| { + this.with_label_rib(RibKind::ClosureOrAsync, |this| { match fn_kind { FnKind::Fn(_, _, sig, _, generics, body) => { this.visit_generics(generics); @@ -1132,7 +1127,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, let span = predicate_span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo()); this.with_generic_param_rib( &bound_generic_params, - NormalRibKind, + RibKind::Normal, LifetimeRibKind::Generics { binder: bounded_ty.id, kind: LifetimeBinderKind::WhereBound, @@ -1178,9 +1173,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) { // This is similar to the code for AnonConst. - self.with_rib(ValueNS, InlineAsmSymRibKind, |this| { - this.with_rib(TypeNS, InlineAsmSymRibKind, |this| { - this.with_label_rib(InlineAsmSymRibKind, |this| { + self.with_rib(ValueNS, RibKind::InlineAsmSym, |this| { + this.with_rib(TypeNS, RibKind::InlineAsmSym, |this| { + this.with_label_rib(RibKind::InlineAsmSym, |this| { this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None)); visit::walk_inline_asm_sym(this, sym); }); @@ -1205,7 +1200,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // although it may be useful to track other components as well for diagnostics. let graph_root = resolver.graph_root; let parent_scope = ParentScope::module(graph_root, resolver); - let start_rib_kind = ModuleRibKind(graph_root); + let start_rib_kind = RibKind::Module(graph_root); LateResolutionVisitor { r: resolver, parent_scope, @@ -1309,8 +1304,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { if let Some(module) = self.r.get_module(self.r.local_def_id(id).to_def_id()) { // Move down in the graph. let orig_module = replace(&mut self.parent_scope.module, module); - self.with_rib(ValueNS, ModuleRibKind(module), |this| { - this.with_rib(TypeNS, ModuleRibKind(module), |this| { + self.with_rib(ValueNS, RibKind::Module(module), |this| { + this.with_rib(TypeNS, RibKind::Module(module), |this| { let ret = f(this); this.parent_scope.module = orig_module; ret @@ -1327,8 +1322,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // provide previous type parameters as they're built. We // put all the parameters on the ban list and then remove // them one by one as they are processed and become available. - let mut forward_ty_ban_rib = Rib::new(ForwardGenericParamBanRibKind); - let mut forward_const_ban_rib = Rib::new(ForwardGenericParamBanRibKind); + let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan); + let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan); for param in params.iter() { match param.kind { GenericParamKind::Type { .. } => { @@ -1389,8 +1384,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // Const parameters can't have param bounds. assert!(param.bounds.is_empty()); - this.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind)); - this.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind)); + this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy)); + this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy)); this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { this.visit_ty(ty) }); @@ -2075,6 +2070,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } visit::walk_ty(self, ty) } + + // A type may have an expression as a const generic argument. + // We do not want to recurse into those. + fn visit_expr(&mut self, _: &'a Expr) {} } let impl_self = self @@ -2112,7 +2111,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { for i in (0..self.label_ribs.len()).rev() { let rib = &self.label_ribs[i]; - if let MacroDefinition(def) = rib.kind { + if let RibKind::MacroDefinition(def) = rib.kind { // If an invocation of this macro created `ident`, give up on `ident` // and switch to `ident`'s source from the macro definition. if def == self.r.macro_def(label.span.ctxt()) { @@ -2160,7 +2159,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { self.with_current_self_item(item, |this| { this.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes(generics.span)), + RibKind::Item(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Item, @@ -2201,7 +2200,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { this.r .tcx .sess - .span_err(ident.span, &format!("imports cannot refer to {}", what)); + .span_err(ident.span, format!("imports cannot refer to {}", what)); } }; @@ -2241,7 +2240,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ItemKind::TyAlias(box TyAlias { ref generics, .. }) => { self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes(generics.span)), + RibKind::Item(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Item, @@ -2254,7 +2253,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ItemKind::Fn(box Fn { ref generics, .. }) => { self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes(generics.span)), + RibKind::Item(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Function, @@ -2293,7 +2292,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // Create a new rib for the trait-wide type parameters. self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes(generics.span)), + RibKind::Item(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Item, @@ -2314,7 +2313,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // Create a new rib for the trait-wide type parameters. self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes(generics.span)), + RibKind::Item(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::Item, @@ -2417,11 +2416,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let mut seen_lifetimes = FxHashSet::default(); // We also can't shadow bindings from the parent item - if let AssocItemRibKind = kind { + if let RibKind::AssocItem = kind { let mut add_bindings_for_ns = |ns| { let parent_rib = self.ribs[ns] .iter() - .rfind(|r| matches!(r.kind, ItemRibKind(_))) + .rfind(|r| matches!(r.kind, RibKind::Item(_))) .expect("associated item outside of an item"); seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span))); }; @@ -2510,8 +2509,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { }; let res = match kind { - ItemRibKind(..) | AssocItemRibKind => Res::Def(def_kind, def_id.to_def_id()), - NormalRibKind => { + RibKind::Item(..) | RibKind::AssocItem => Res::Def(def_kind, def_id.to_def_id()), + RibKind::Normal => { if self.r.tcx.sess.features_untracked().non_lifetime_binders { Res::Def(def_kind, def_id.to_def_id()) } else { @@ -2557,7 +2556,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) { - let kind = ItemRibKind(HasGenericParams::No); + let kind = RibKind::Item(HasGenericParams::No); self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f)) } @@ -2577,15 +2576,15 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { item: Option<(Ident, ConstantItemKind)>, f: impl FnOnce(&mut Self), ) { - self.with_rib(ValueNS, ConstantItemRibKind(may_use_generics, item), |this| { + self.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| { this.with_rib( TypeNS, - ConstantItemRibKind( + RibKind::ConstantItem( may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes), item, ), |this| { - this.with_label_rib(ConstantItemRibKind(may_use_generics, item), f); + this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f); }, ) }); @@ -2617,7 +2616,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { |this: &mut Self, generics: &Generics, kind, item: &'ast AssocItem| { this.with_generic_param_rib( &generics.params, - AssocItemRibKind, + RibKind::AssocItem, LifetimeRibKind::Generics { binder: item.id, span: generics.span, kind }, |this| visit::walk_assoc_item(this, item, AssocCtxt::Trait), ); @@ -2698,7 +2697,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } fn with_self_rib_ns(&mut self, ns: Namespace, self_res: Res, f: impl FnOnce(&mut Self)) { - let mut self_type_rib = Rib::new(NormalRibKind); + let mut self_type_rib = Rib::new(RibKind::Normal); // Plain insert (no renaming, since types are not currently hygienic) self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res); @@ -2724,7 +2723,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // If applicable, create a rib for the type parameters. self.with_generic_param_rib( &generics.params, - ItemRibKind(HasGenericParams::Yes(generics.span)), + RibKind::Item(HasGenericParams::Yes(generics.span)), LifetimeRibKind::Generics { span: generics.span, binder: item_id, @@ -2838,7 +2837,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // We also need a new scope for the impl item type parameters. self.with_generic_param_rib( &generics.params, - AssocItemRibKind, + RibKind::AssocItem, LifetimeRibKind::Generics { binder: item.id, span: generics.span, @@ -2866,7 +2865,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // We also need a new scope for the impl item type parameters. self.with_generic_param_rib( &generics.params, - AssocItemRibKind, + RibKind::AssocItem, LifetimeRibKind::Generics { binder: item.id, span: generics.span, @@ -3138,7 +3137,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } fn resolve_arm(&mut self, arm: &'ast Arm) { - self.with_rib(ValueNS, NormalRibKind, |this| { + self.with_rib(ValueNS, RibKind::Normal, |this| { this.resolve_pattern_top(&arm.pat, PatternSource::Match); walk_list!(this, visit_expr, &arm.guard); this.visit_expr(&arm.body); @@ -3860,7 +3859,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { diagnostics::signal_label_shadowing(self.r.tcx.sess, orig_span, label.ident) } - self.with_label_rib(NormalRibKind, |this| { + self.with_label_rib(RibKind::Normal, |this| { let ident = label.ident.normalize_to_macro_rules(); this.label_ribs.last_mut().unwrap().bindings.insert(ident, id); f(this); @@ -3883,11 +3882,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let mut num_macro_definition_ribs = 0; if let Some(anonymous_module) = anonymous_module { debug!("(resolving block) found anonymous module, moving down"); - self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module))); - self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module))); + self.ribs[ValueNS].push(Rib::new(RibKind::Module(anonymous_module))); + self.ribs[TypeNS].push(Rib::new(RibKind::Module(anonymous_module))); self.parent_scope.module = anonymous_module; } else { - self.ribs[ValueNS].push(Rib::new(NormalRibKind)); + self.ribs[ValueNS].push(Rib::new(RibKind::Normal)); } let prev = self.diagnostic_metadata.current_block_could_be_bare_struct_literal.take(); @@ -3904,8 +3903,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { && let ItemKind::MacroDef(..) = item.kind { num_macro_definition_ribs += 1; let res = self.r.local_def_id(item.id).to_def_id(); - self.ribs[ValueNS].push(Rib::new(MacroDefinition(res))); - self.label_ribs.push(Rib::new(MacroDefinition(res))); + self.ribs[ValueNS].push(Rib::new(RibKind::MacroDefinition(res))); + self.label_ribs.push(Rib::new(RibKind::MacroDefinition(res))); } self.visit_stmt(stmt); @@ -3992,7 +3991,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } ExprKind::If(ref cond, ref then, ref opt_else) => { - self.with_rib(ValueNS, NormalRibKind, |this| { + self.with_rib(ValueNS, RibKind::Normal, |this| { let old = this.diagnostic_metadata.in_if_condition.replace(cond); this.visit_expr(cond); this.diagnostic_metadata.in_if_condition = old; @@ -4009,7 +4008,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ExprKind::While(ref cond, ref block, label) => { self.with_resolved_label(label, expr.id, |this| { - this.with_rib(ValueNS, NormalRibKind, |this| { + this.with_rib(ValueNS, RibKind::Normal, |this| { let old = this.diagnostic_metadata.in_if_condition.replace(cond); this.visit_expr(cond); this.diagnostic_metadata.in_if_condition = old; @@ -4020,7 +4019,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ExprKind::ForLoop(ref pat, ref iter_expr, ref block, label) => { self.visit_expr(iter_expr); - self.with_rib(ValueNS, NormalRibKind, |this| { + self.with_rib(ValueNS, RibKind::Normal, |this| { this.resolve_pattern_top(pat, PatternSource::For); this.resolve_labeled_block(label, expr.id, block); }); @@ -4064,17 +4063,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } } } - ExprKind::Type(ref type_expr, ref ty) => { - // `ParseSess::type_ascription_path_suggestions` keeps spans of colon tokens in - // type ascription. Here we are trying to retrieve the span of the colon token as - // well, but only if it's written without spaces `expr:Ty` and therefore confusable - // with `expr::Ty`, only in this case it will match the span from - // `type_ascription_path_suggestions`. - self.diagnostic_metadata - .current_type_ascription - .push(type_expr.span.between(ty.span)); + ExprKind::Type(ref _type_expr, ref _ty) => { visit::walk_expr(self, expr); - self.diagnostic_metadata.current_type_ascription.pop(); } // `async |x| ...` gets desugared to `|x| async {...}`, so we need to // resolve the arguments within the proper scopes so that usages of them inside the @@ -4085,8 +4075,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ref body, .. }) => { - self.with_rib(ValueNS, NormalRibKind, |this| { - this.with_label_rib(ClosureOrAsyncRibKind, |this| { + self.with_rib(ValueNS, RibKind::Normal, |this| { + this.with_label_rib(RibKind::ClosureOrAsync, |this| { // Resolve arguments: this.resolve_params(&fn_decl.inputs); // No need to resolve return type -- @@ -4110,7 +4100,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { }) => { self.with_generic_param_rib( &generic_params, - NormalRibKind, + RibKind::Normal, LifetimeRibKind::Generics { binder: expr.id, kind: LifetimeBinderKind::Closure, @@ -4121,7 +4111,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } ExprKind::Closure(..) => visit::walk_expr(self, expr), ExprKind::Async(..) => { - self.with_label_rib(ClosureOrAsyncRibKind, |this| visit::walk_expr(this, expr)); + self.with_label_rib(RibKind::ClosureOrAsync, |this| visit::walk_expr(this, expr)); } ExprKind::Repeat(ref elem, ref ct) => { self.visit_expr(elem); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index e824a6ddc07..42d498c7ee0 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -28,7 +28,7 @@ use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{BytePos, Span}; +use rustc_span::Span; use std::iter; use std::ops::Deref; @@ -315,8 +315,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { debug!(?res, ?source); let base_error = self.make_base_error(path, span, source, res); let code = source.error_code(res.is_some()); - let mut err = - self.r.tcx.sess.struct_span_err_with_code(base_error.span, &base_error.msg, code); + let mut err = self.r.tcx.sess.struct_span_err_with_code( + base_error.span, + base_error.msg.clone(), + code, + ); self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); @@ -332,7 +335,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if self.suggest_pattern_match_with_let(&mut err, source, span) { // Fallback label. - err.span_label(base_error.span, &base_error.fallback_label); + err.span_label(base_error.span, base_error.fallback_label); return (err, Vec::new()); } @@ -350,18 +353,15 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { return (err, candidates); } - if !self.type_ascription_suggestion(&mut err, base_error.span) { - let mut fallback = - self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error); + let mut fallback = self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error); - // if we have suggested using pattern matching, then don't add needless suggestions - // for typos. - fallback |= self.suggest_typo(&mut err, source, path, span, &base_error); + // if we have suggested using pattern matching, then don't add needless suggestions + // for typos. + fallback |= self.suggest_typo(&mut err, source, path, span, &base_error); - if fallback { - // Fallback label. - err.span_label(base_error.span, &base_error.fallback_label); - } + if fallback { + // Fallback label. + err.span_label(base_error.span, base_error.fallback_label); } self.err_code_special_cases(&mut err, source, path, span); @@ -494,24 +494,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { .filter(|(_, enum_ty_path)| !enum_ty_path.starts_with("std::prelude::")) .collect(); if !enum_candidates.is_empty() { - if let (PathSource::Type, Some(span)) = - (source, self.diagnostic_metadata.current_type_ascription.last()) - { - if self - .r - .tcx - .sess - .parse_sess - .type_ascription_path_suggestions - .borrow() - .contains(span) - { - // Already reported this issue on the lhs of the type ascription. - err.downgrade_to_delayed_bug(); - return (true, candidates); - } - } - enum_candidates.sort(); // Contextualize for E0412 "cannot find type", but don't belabor the point @@ -530,7 +512,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { err.span_suggestions( span, - &msg, + msg, enum_candidates.into_iter().map(|(_variant_path, enum_ty_path)| enum_ty_path), Applicability::MachineApplicable, ); @@ -577,7 +559,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { | AssocSuggestion::AssocType => { err.span_suggestion( span, - &format!("you might have meant to {}", candidate.action()), + format!("you might have meant to {}", candidate.action()), format!("Self::{path_str}"), Applicability::MachineApplicable, ); @@ -598,7 +580,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { err.span_suggestion( call_span, - &format!("try calling `{ident}` as a method"), + format!("try calling `{ident}` as a method"), format!("self.{path_str}({args_snippet})"), Applicability::MachineApplicable, ); @@ -623,14 +605,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } // Try to find in last block rib - if let Some(rib) = &self.last_block_rib && let RibKind::NormalRibKind = rib.kind { + if let Some(rib) = &self.last_block_rib && let RibKind::Normal = rib.kind { for (ident, &res) in &rib.bindings { if let Res::Local(_) = res && path.len() == 1 && ident.span.eq_ctxt(path[0].ident.span) && ident.name == path[0].ident.name { err.span_help( ident.span, - &format!("the binding `{}` is available in a different scope in the same function", path_str), + format!("the binding `{}` is available in a different scope in the same function", path_str), ); return (true, candidates); } @@ -911,7 +893,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if let Some(ident) = fn_kind.ident() { err.span_label( ident.span, - &format!("this function {} have a `self` parameter", doesnt), + format!("this function {} have a `self` parameter", doesnt), ); } } @@ -1087,7 +1069,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if ident.span == span { err.span_suggestion_verbose( *where_span, - &format!("constrain the associated type to `{}`", ident), + format!("constrain the associated type to `{}`", ident), format!( "{}: {}<{} = {}>", self.r @@ -1288,7 +1270,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } PathSource::Expr(_) | PathSource::TupleStruct(..) | PathSource::Pat => { let span = find_span(&source, err); - err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here")); + err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here")); let (tail, descr, applicability, old_fields) = match source { PathSource::Pat => ("", "pattern", Applicability::MachineApplicable, None), @@ -1332,7 +1314,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }; err.span_suggestion( span, - &format!("use struct {} syntax instead", descr), + format!("use struct {} syntax instead", descr), format!("{path_str} {{{pad}{fields}{pad}}}"), applicability, ); @@ -1393,26 +1375,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { Res::Def(DefKind::Enum, def_id), PathSource::TupleStruct(..) | PathSource::Expr(..), ) => { - if self - .diagnostic_metadata - .current_type_ascription - .last() - .map(|sp| { - self.r - .tcx - .sess - .parse_sess - .type_ascription_path_suggestions - .borrow() - .contains(&sp) - }) - .unwrap_or(false) - { - err.downgrade_to_delayed_bug(); - // We already suggested changing `:` into `::` during parsing. - return false; - } - self.suggest_using_enum_variant(err, source, def_id, span); } (Res::Def(DefKind::Struct, def_id), source) if ns == ValueNS => { @@ -1494,7 +1456,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if non_visible_spans.len() > 0 { if let Some(fields) = self.r.field_visibility_spans.get(&def_id) { err.multipart_suggestion_verbose( - &format!( + format!( "consider making the field{} publicly accessible", pluralize!(fields.len()) ), @@ -1524,7 +1486,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let span = find_span(&source, err); err.span_label( self.r.def_span(def_id), - &format!("`{path_str}` defined here"), + format!("`{path_str}` defined here"), ); err.span_suggestion( span, @@ -1538,7 +1500,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } (Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_def_id), _) if ns == ValueNS => { let def_id = self.r.tcx.parent(ctor_def_id); - err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here")); + err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here")); let fields = self.r.field_def_ids(def_id).map_or_else( || "/* fields */".to_string(), |field_ids| vec!["_"; field_ids.len()].join(", "), @@ -1728,7 +1690,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } // Items in scope - if let RibKind::ModuleRibKind(module) = rib.kind { + if let RibKind::Module(module) = rib.kind { // Items from this module self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt)); @@ -1817,80 +1779,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }) } - /// Only used in a specific case of type ascription suggestions - fn get_colon_suggestion_span(&self, start: Span) -> Span { - let sm = self.r.tcx.sess.source_map(); - start.to(sm.next_point(start)) - } - - fn type_ascription_suggestion(&self, err: &mut Diagnostic, base_span: Span) -> bool { - let sm = self.r.tcx.sess.source_map(); - let base_snippet = sm.span_to_snippet(base_span); - if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() { - if let Ok(snippet) = sm.span_to_snippet(sp) { - let len = snippet.trim_end().len() as u32; - if snippet.trim() == ":" { - let colon_sp = - sp.with_lo(sp.lo() + BytePos(len - 1)).with_hi(sp.lo() + BytePos(len)); - let mut show_label = true; - if sm.is_multiline(sp) { - err.span_suggestion_short( - colon_sp, - "maybe you meant to write `;` here", - ";", - Applicability::MaybeIncorrect, - ); - } else { - let after_colon_sp = - self.get_colon_suggestion_span(colon_sp.shrink_to_hi()); - if snippet.len() == 1 { - // `foo:bar` - err.span_suggestion( - colon_sp, - "maybe you meant to write a path separator here", - "::", - Applicability::MaybeIncorrect, - ); - show_label = false; - if !self - .r - .tcx - .sess - .parse_sess - .type_ascription_path_suggestions - .borrow_mut() - .insert(colon_sp) - { - err.downgrade_to_delayed_bug(); - } - } - if let Ok(base_snippet) = base_snippet { - // Try to find an assignment - let eq_span = sm.span_look_ahead(after_colon_sp, Some("="), Some(50)); - if let Ok(ref snippet) = sm.span_to_snippet(eq_span) && snippet == "=" { - err.span_suggestion( - base_span, - "maybe you meant to write an assignment here", - format!("let {}", base_snippet), - Applicability::MaybeIncorrect, - ); - show_label = false; - } - } - } - if show_label { - err.span_label( - base_span, - "expecting a type here because of type ascription", - ); - } - return show_label; - } - } - } - false - } - // try to give a suggestion for this pattern: `name = blah`, which is common in other languages // suggest `let name = blah` to introduce a new binding fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool { @@ -2014,7 +1902,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { err.span_suggestions( span, - &msg, + msg, suggestable_variants, Applicability::MaybeIncorrect, ); @@ -2022,17 +1910,17 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { // If the enum has no tuple variants.. if non_suggestable_variant_count == variants.len() { - err.help(&format!("the enum has no tuple variants {}", source_msg)); + err.help(format!("the enum has no tuple variants {}", source_msg)); } // If there are also non-tuple variants.. if non_suggestable_variant_count == 1 { - err.help(&format!( + err.help(format!( "you might have meant {} the enum's non-tuple variant", source_msg )); } else if non_suggestable_variant_count >= 1 { - err.help(&format!( + err.help(format!( "you might have meant {} one of the enum's non-tuple variants", source_msg )); @@ -2282,7 +2170,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { lint::builtin::SINGLE_USE_LIFETIMES, param.id, param.ident.span, - &format!("lifetime parameter `{}` only used once", param.ident), + format!("lifetime parameter `{}` only used once", param.ident), lint::BuiltinLintDiagnostics::SingleUseLifetime { param_span: param.ident.span, use_span: Some((use_span, elidable)), @@ -2301,7 +2189,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { lint::builtin::UNUSED_LIFETIMES, param.id, param.ident.span, - &format!("lifetime parameter `{}` never used", param.ident), + format!("lifetime parameter `{}` never used", param.ident), lint::BuiltinLintDiagnostics::SingleUseLifetime { param_span: param.ident.span, use_span: None, @@ -2367,7 +2255,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { suggest_note = false; // Avoid displaying the same help multiple times. err.span_label( span, - &format!( + format!( "lifetime `{}` is missing in item created through this procedural macro", name, ), @@ -2573,13 +2461,13 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { )]; } } else if num_params == 1 { - err.help(&format!( + err.help(format!( "this function's return type contains a borrowed value, \ but the signature does not say which {} it is borrowed from", m )); } else { - err.help(&format!( + err.help(format!( "this function's return type contains a borrowed value, \ but the signature does not say whether it is borrowed from {}", m @@ -2648,7 +2536,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } 1 => { err.multipart_suggestion_verbose( - &format!("consider using the `{}` lifetime", existing_name), + format!("consider using the `{}` lifetime", existing_name), spans_suggs, Applicability::MaybeIncorrect, ); @@ -2699,7 +2587,7 @@ pub(super) fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident let shadower = shadower.span; let mut err = sess.struct_span_warn( shadower, - &format!("label name `{}` shadows a label name that is already in scope", name), + format!("label name `{}` shadows a label name that is already in scope", name), ); err.span_label(orig, "first declared here"); err.span_label(shadower, format!("label `{}` already in scope", name)); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 125f5ce7611..e46463579fe 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -909,8 +909,7 @@ pub struct Resolver<'a, 'tcx> { /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: FxHashMap<LocalDefId, CrateNum>, - module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>, - module_children_reexports: LocalDefIdMap<Vec<ModChild>>, + module_children: LocalDefIdMap<Vec<ModChild>>, trait_map: NodeMap<Vec<TraitCandidate>>, /// A map from nodes to anonymous modules. @@ -1260,8 +1259,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { lifetimes_res_map: Default::default(), extra_lifetime_params_map: Default::default(), extern_crate_map: Default::default(), - module_children_non_reexports: Default::default(), - module_children_reexports: Default::default(), + module_children: Default::default(), trait_map: NodeMap::default(), underscore_disambiguator: 0, empty_module, @@ -1399,8 +1397,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { has_pub_restricted, effective_visibilities, extern_crate_map, - module_children_non_reexports: self.module_children_non_reexports, - module_children_reexports: self.module_children_reexports, + module_children: self.module_children, glob_map, maybe_unused_trait_imports, main_def, diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index b30c1cd226c..4da43c6a9a2 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -121,7 +121,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools { if let Some(old_ident) = registered_tools.replace(ident) { let msg = format!("{} `{}` was already registered", "tool", ident); tcx.sess - .struct_span_err(ident.span, &msg) + .struct_span_err(ident.span, msg) .span_label(old_ident.span, "already registered here") .emit(); } @@ -130,7 +130,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools { let msg = format!("`{}` only accepts identifiers", sym::register_tool); let span = nested_meta.span(); tcx.sess - .struct_span_err(span, &msg) + .struct_span_err(span, msg) .span_label(span, "not an identifier") .emit(); } @@ -202,7 +202,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { self.tcx .sess .diagnostic() - .bug(&format!("built-in macro `{}` was already registered", name)); + .bug(format!("built-in macro `{}` was already registered", name)); } } @@ -315,7 +315,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { UNUSED_MACROS, node_id, ident.span, - &format!("unused macro definition: `{}`", ident.name), + format!("unused macro definition: `{}`", ident.name), ); } for (&(def_id, arm_i), &(ident, rule_span)) in self.unused_macro_rules.iter() { @@ -328,7 +328,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { UNUSED_MACRO_RULES, node_id, rule_span, - &format!( + format!( "{} rule of macro `{}` is never used", crate::diagnostics::ordinalize(arm_i + 1), ident.name @@ -698,7 +698,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Segment::names_to_string(path) ); let msg_note = "import resolution is stuck, try simplifying macro imports"; - this.tcx.sess.struct_span_err(span, &msg).note(msg_note).emit(); + this.tcx.sess.struct_span_err(span, msg).note(msg_note).emit(); } } }; @@ -788,7 +788,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Err(..) => { let expected = kind.descr_expected(); let msg = format!("cannot find {} `{}` in this scope", expected, ident); - let mut err = self.tcx.sess.struct_span_err(ident.span, &msg); + let mut err = self.tcx.sess.struct_span_err(ident.span, msg); self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident); err.emit(); } @@ -866,9 +866,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) { let msg = format!("cannot use {} {} through an import", kind.article(), kind.descr()); - let mut err = self.tcx.sess.struct_span_err(span, &msg); + let mut err = self.tcx.sess.struct_span_err(span, msg); if let Some(binding) = binding { - err.span_note(binding.span, &format!("the {} imported here", kind.descr())); + err.span_note(binding.span, format!("the {} imported here", kind.descr())); } err.emit(); } @@ -883,7 +883,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) { self.tcx.sess.span_err( ident.span, - &format!("name `{}` is reserved in attribute namespace", ident), + format!("name `{}` is reserved in attribute namespace", ident), ); } } @@ -927,7 +927,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } else { let msg = format!("cannot find a built-in macro with name `{}`", item.ident); - self.tcx.sess.span_err(item.span, &msg); + self.tcx.sess.span_err(item.span, msg); } } diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index e4dbb8a637c..6046780685a 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -10,3 +10,4 @@ thin-vec = "0.2.12" [dev-dependencies] rustc_macros = { path = "../rustc_macros" } +tempfile = "3.2" diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 0f6e4b329b8..6b559cb5b2f 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -12,118 +12,14 @@ use std::ptr; // Encoder // ----------------------------------------------------------------------------- -pub struct MemEncoder { - pub data: Vec<u8>, -} - -impl MemEncoder { - pub fn new() -> MemEncoder { - MemEncoder { data: vec![] } - } - - #[inline] - pub fn position(&self) -> usize { - self.data.len() - } - - pub fn finish(self) -> Vec<u8> { - self.data - } -} - -macro_rules! write_leb128 { - ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{ - const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>(); - let old_len = $enc.data.len(); - - if MAX_ENCODED_LEN > $enc.data.capacity() - old_len { - $enc.data.reserve(MAX_ENCODED_LEN); - } - - // SAFETY: The above check and `reserve` ensures that there is enough - // room to write the encoded value to the vector's internal buffer. - unsafe { - let buf = &mut *($enc.data.as_mut_ptr().add(old_len) - as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN]); - let encoded = leb128::$fun(buf, $value); - $enc.data.set_len(old_len + encoded.len()); - } - }}; -} - -impl Encoder for MemEncoder { - #[inline] - fn emit_usize(&mut self, v: usize) { - write_leb128!(self, v, usize, write_usize_leb128) - } - - #[inline] - fn emit_u128(&mut self, v: u128) { - write_leb128!(self, v, u128, write_u128_leb128); - } - - #[inline] - fn emit_u64(&mut self, v: u64) { - write_leb128!(self, v, u64, write_u64_leb128); - } - - #[inline] - fn emit_u32(&mut self, v: u32) { - write_leb128!(self, v, u32, write_u32_leb128); - } - - #[inline] - fn emit_u16(&mut self, v: u16) { - self.data.extend_from_slice(&v.to_le_bytes()); - } - - #[inline] - fn emit_u8(&mut self, v: u8) { - self.data.push(v); - } - - #[inline] - fn emit_isize(&mut self, v: isize) { - write_leb128!(self, v, isize, write_isize_leb128) - } - - #[inline] - fn emit_i128(&mut self, v: i128) { - write_leb128!(self, v, i128, write_i128_leb128) - } - - #[inline] - fn emit_i64(&mut self, v: i64) { - write_leb128!(self, v, i64, write_i64_leb128) - } - - #[inline] - fn emit_i32(&mut self, v: i32) { - write_leb128!(self, v, i32, write_i32_leb128) - } - - #[inline] - fn emit_i16(&mut self, v: i16) { - self.data.extend_from_slice(&v.to_le_bytes()); - } - - #[inline] - fn emit_raw_bytes(&mut self, s: &[u8]) { - self.data.extend_from_slice(s); - } -} - pub type FileEncodeResult = Result<usize, io::Error>; /// `FileEncoder` encodes data to file via fixed-size buffer. /// -/// When encoding large amounts of data to a file, using `FileEncoder` may be -/// preferred over using `MemEncoder` to encode to a `Vec`, and then writing the -/// `Vec` to file, as the latter uses as much memory as there is encoded data, -/// while the former uses the fixed amount of memory allocated to the buffer. -/// `FileEncoder` also has the advantage of not needing to reallocate as data -/// is appended to it, but the disadvantage of requiring more error handling, -/// which has some runtime overhead. +/// There used to be a `MemEncoder` type that encoded all the data into a +/// `Vec`. `FileEncoder` is better because its memory use is determined by the +/// size of the buffer, rather than the full length of the encoded data, and +/// because it doesn't need to reallocate memory along the way. pub struct FileEncoder { /// The input buffer. For adequate performance, we need more control over /// buffering than `BufWriter` offers. If `BufWriter` ever offers a raw @@ -369,52 +265,41 @@ impl Drop for FileEncoder { } } -macro_rules! file_encoder_write_leb128 { - ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{ - const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>(); +macro_rules! write_leb128 { + ($this_fn:ident, $int_ty:ty, $write_leb_fn:ident) => { + #[inline] + fn $this_fn(&mut self, v: $int_ty) { + const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>(); - // We ensure this during `FileEncoder` construction. - debug_assert!($enc.capacity() >= MAX_ENCODED_LEN); + // We ensure this during `FileEncoder` construction. + debug_assert!(self.capacity() >= MAX_ENCODED_LEN); - let mut buffered = $enc.buffered; + let mut buffered = self.buffered; - // This can't overflow. See assertion in `FileEncoder::with_capacity`. - if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > $enc.capacity()) { - $enc.flush(); - buffered = 0; - } + // This can't overflow. See assertion in `FileEncoder::with_capacity`. + if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > self.capacity()) { + self.flush(); + buffered = 0; + } - // SAFETY: The above check and flush ensures that there is enough - // room to write the encoded value to the buffer. - let buf = unsafe { - &mut *($enc.buf.as_mut_ptr().add(buffered) as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN]) - }; + // SAFETY: The above check and flush ensures that there is enough + // room to write the encoded value to the buffer. + let buf = unsafe { + &mut *(self.buf.as_mut_ptr().add(buffered) + as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN]) + }; - let encoded = leb128::$fun(buf, $value); - $enc.buffered = buffered + encoded.len(); - }}; + let encoded = leb128::$write_leb_fn(buf, v); + self.buffered = buffered + encoded.len(); + } + }; } impl Encoder for FileEncoder { - #[inline] - fn emit_usize(&mut self, v: usize) { - file_encoder_write_leb128!(self, v, usize, write_usize_leb128) - } - - #[inline] - fn emit_u128(&mut self, v: u128) { - file_encoder_write_leb128!(self, v, u128, write_u128_leb128) - } - - #[inline] - fn emit_u64(&mut self, v: u64) { - file_encoder_write_leb128!(self, v, u64, write_u64_leb128) - } - - #[inline] - fn emit_u32(&mut self, v: u32) { - file_encoder_write_leb128!(self, v, u32, write_u32_leb128) - } + write_leb128!(emit_usize, usize, write_usize_leb128); + write_leb128!(emit_u128, u128, write_u128_leb128); + write_leb128!(emit_u64, u64, write_u64_leb128); + write_leb128!(emit_u32, u32, write_u32_leb128); #[inline] fn emit_u16(&mut self, v: u16) { @@ -426,25 +311,10 @@ impl Encoder for FileEncoder { self.write_one(v); } - #[inline] - fn emit_isize(&mut self, v: isize) { - file_encoder_write_leb128!(self, v, isize, write_isize_leb128) - } - - #[inline] - fn emit_i128(&mut self, v: i128) { - file_encoder_write_leb128!(self, v, i128, write_i128_leb128) - } - - #[inline] - fn emit_i64(&mut self, v: i64) { - file_encoder_write_leb128!(self, v, i64, write_i64_leb128) - } - - #[inline] - fn emit_i32(&mut self, v: i32) { - file_encoder_write_leb128!(self, v, i32, write_i32_leb128) - } + write_leb128!(emit_isize, isize, write_isize_leb128); + write_leb128!(emit_i128, i128, write_i128_leb128); + write_leb128!(emit_i64, i64, write_i64_leb128); + write_leb128!(emit_i32, i32, write_i32_leb128); #[inline] fn emit_i16(&mut self, v: i16) { @@ -541,30 +411,19 @@ impl<'a> MemDecoder<'a> { } macro_rules! read_leb128 { - ($dec:expr, $fun:ident) => {{ leb128::$fun($dec) }}; + ($this_fn:ident, $int_ty:ty, $read_leb_fn:ident) => { + #[inline] + fn $this_fn(&mut self) -> $int_ty { + leb128::$read_leb_fn(self) + } + }; } impl<'a> Decoder for MemDecoder<'a> { - #[inline] - fn position(&self) -> usize { - // SAFETY: This type guarantees start <= current - unsafe { self.current.sub_ptr(self.start) } - } - - #[inline] - fn read_u128(&mut self) -> u128 { - read_leb128!(self, read_u128_leb128) - } - - #[inline] - fn read_u64(&mut self) -> u64 { - read_leb128!(self, read_u64_leb128) - } - - #[inline] - fn read_u32(&mut self) -> u32 { - read_leb128!(self, read_u32_leb128) - } + read_leb128!(read_usize, usize, read_usize_leb128); + read_leb128!(read_u128, u128, read_u128_leb128); + read_leb128!(read_u64, u64, read_u64_leb128); + read_leb128!(read_u32, u32, read_u32_leb128); #[inline] fn read_u16(&mut self) -> u16 { @@ -584,25 +443,10 @@ impl<'a> Decoder for MemDecoder<'a> { } } - #[inline] - fn read_usize(&mut self) -> usize { - read_leb128!(self, read_usize_leb128) - } - - #[inline] - fn read_i128(&mut self) -> i128 { - read_leb128!(self, read_i128_leb128) - } - - #[inline] - fn read_i64(&mut self) -> i64 { - read_leb128!(self, read_i64_leb128) - } - - #[inline] - fn read_i32(&mut self) -> i32 { - read_leb128!(self, read_i32_leb128) - } + read_leb128!(read_isize, isize, read_isize_leb128); + read_leb128!(read_i128, i128, read_i128_leb128); + read_leb128!(read_i64, i64, read_i64_leb128); + read_leb128!(read_i32, i32, read_i32_leb128); #[inline] fn read_i16(&mut self) -> i16 { @@ -610,11 +454,6 @@ impl<'a> Decoder for MemDecoder<'a> { } #[inline] - fn read_isize(&mut self) -> isize { - read_leb128!(self, read_isize_leb128) - } - - #[inline] fn read_raw_bytes(&mut self, bytes: usize) -> &'a [u8] { if bytes > self.remaining() { Self::decoder_exhausted(); @@ -636,6 +475,12 @@ impl<'a> Decoder for MemDecoder<'a> { // Since we just checked current == end, the current pointer must be inbounds. unsafe { *self.current } } + + #[inline] + fn position(&self) -> usize { + // SAFETY: This type guarantees start <= current + unsafe { self.current.sub_ptr(self.start) } + } } // Specializations for contiguous byte sequences follow. The default implementations for slices @@ -645,13 +490,6 @@ impl<'a> Decoder for MemDecoder<'a> { // Specialize encoding byte slices. This specialization also applies to encoding `Vec<u8>`s, etc., // since the default implementations call `encode` on their slices internally. -impl Encodable<MemEncoder> for [u8] { - fn encode(&self, e: &mut MemEncoder) { - Encoder::emit_usize(e, self.len()); - e.emit_raw_bytes(self); - } -} - impl Encodable<FileEncoder> for [u8] { fn encode(&self, e: &mut FileEncoder) { Encoder::emit_usize(e, self.len()); @@ -675,16 +513,6 @@ impl IntEncodedWithFixedSize { pub const ENCODED_SIZE: usize = 8; } -impl Encodable<MemEncoder> for IntEncodedWithFixedSize { - #[inline] - fn encode(&self, e: &mut MemEncoder) { - let _start_pos = e.position(); - e.emit_raw_bytes(&self.0.to_le_bytes()); - let _end_pos = e.position(); - debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE); - } -} - impl Encodable<FileEncoder> for IntEncodedWithFixedSize { #[inline] fn encode(&self, e: &mut FileEncoder) { diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index e1bc598736f..06166cabc18 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -1,9 +1,5 @@ //! Support code for encoding and decoding types. -/* -Core encoding and decoding interfaces. -*/ - use std::alloc::Allocator; use std::borrow::Cow; use std::cell::{Cell, RefCell}; @@ -35,13 +31,13 @@ const STR_SENTINEL: u8 = 0xC1; /// really makes sense to store floating-point values at all. /// (If you need it, revert <https://github.com/rust-lang/rust/pull/109984>.) pub trait Encoder { - // Primitive types: fn emit_usize(&mut self, v: usize); fn emit_u128(&mut self, v: u128); fn emit_u64(&mut self, v: u64); fn emit_u32(&mut self, v: u32); fn emit_u16(&mut self, v: u16); fn emit_u8(&mut self, v: u8); + fn emit_isize(&mut self, v: isize); fn emit_i128(&mut self, v: i128); fn emit_i64(&mut self, v: i64); @@ -93,13 +89,13 @@ pub trait Encoder { /// really makes sense to store floating-point values at all. /// (If you need it, revert <https://github.com/rust-lang/rust/pull/109984>.) pub trait Decoder { - // Primitive types: fn read_usize(&mut self) -> usize; fn read_u128(&mut self) -> u128; fn read_u64(&mut self) -> u64; fn read_u32(&mut self) -> u32; fn read_u16(&mut self) -> u16; fn read_u8(&mut self) -> u8; + fn read_isize(&mut self) -> isize; fn read_i128(&mut self) -> i128; fn read_i64(&mut self) -> i64; diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs index 5e7dd18aa84..861091688bb 100644 --- a/compiler/rustc_serialize/tests/opaque.rs +++ b/compiler/rustc_serialize/tests/opaque.rs @@ -1,9 +1,10 @@ #![allow(rustc::internal)] use rustc_macros::{Decodable, Encodable}; -use rustc_serialize::opaque::{MemDecoder, MemEncoder}; +use rustc_serialize::opaque::{MemDecoder, FileEncoder}; use rustc_serialize::{Decodable, Encodable}; use std::fmt::Debug; +use std::fs; #[derive(PartialEq, Clone, Debug, Encodable, Decodable)] struct Struct { @@ -27,18 +28,21 @@ struct Struct { } fn check_round_trip< - T: Encodable<MemEncoder> + for<'a> Decodable<MemDecoder<'a>> + PartialEq + Debug, + T: Encodable<FileEncoder> + for<'a> Decodable<MemDecoder<'a>> + PartialEq + Debug, >( values: Vec<T>, ) { - let mut encoder = MemEncoder::new(); + let tmpfile = tempfile::NamedTempFile::new().unwrap(); + let tmpfile = tmpfile.path(); + + let mut encoder = FileEncoder::new(&tmpfile).unwrap(); for value in &values { Encodable::encode(value, &mut encoder); } + encoder.finish().unwrap(); - let data = encoder.finish(); + let data = fs::read(&tmpfile).unwrap(); let mut decoder = MemDecoder::new(&data[..], 0); - for value in values { let decoded = Decodable::decode(&mut decoder); assert_eq!(value, decoded); @@ -61,7 +65,7 @@ fn test_u8() { #[test] fn test_u16() { - for i in u16::MIN..u16::MAX { + for i in [u16::MIN, 111, 3333, 55555, u16::MAX] { check_round_trip(vec![1, 2, 3, i, i, i]); } } @@ -92,7 +96,7 @@ fn test_i8() { #[test] fn test_i16() { - for i in i16::MIN..i16::MAX { + for i in [i16::MIN, -100, 0, 101, i16::MAX] { check_round_trip(vec![-1, 2, -3, i, i, i, 2]); } } @@ -251,3 +255,41 @@ fn test_tuples() { check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]); check_round_trip(vec![(String::new(), "some string".to_string())]); } + +#[test] +fn test_unit_like_struct() { + #[derive(Encodable, Decodable, PartialEq, Debug)] + struct UnitLikeStruct; + + check_round_trip(vec![UnitLikeStruct]); +} + +#[test] +fn test_box() { + #[derive(Encodable, Decodable, PartialEq, Debug)] + struct A { + foo: Box<[bool]>, + } + + let obj = A { foo: Box::new([true, false]) }; + check_round_trip(vec![obj]); +} + +#[test] +fn test_cell() { + use std::cell::{Cell, RefCell}; + + #[derive(Encodable, Decodable, PartialEq, Debug)] + struct A { + baz: isize, + } + + #[derive(Encodable, Decodable, PartialEq, Debug)] + struct B { + foo: Cell<bool>, + bar: RefCell<A>, + } + + let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) }; + check_round_trip(vec![obj]); +} diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index ff53f22d43f..a8fe560d1a7 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -35,7 +35,15 @@ session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static` -session_sanitizer_cfi_enabled = `-Zsanitizer=cfi` requires `-Clto` +session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` + +session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi` + +session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` + +session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` + +session_split_lto_unit_requires_lto = `-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto` @@ -93,3 +101,5 @@ session_invalid_int_literal_width = invalid width `{$width}` for integer literal .help = valid widths are 8, 16, 32, 64 and 128 session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg} + +session_nul_in_c_str = null characters in C string literals are not supported diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 51418c01eed..d80cc0aa043 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -518,6 +518,12 @@ pub struct ExternEntry { /// `--extern nounused:std=/path/to/lib/libstd.rlib`. This is used to /// suppress `unused-crate-dependencies` warnings. pub nounused_dep: bool, + /// If the extern entry is not referenced in the crate, force it to be resolved anyway. + /// + /// Allows a dependency satisfying, for instance, a missing panic handler to be injected + /// without modifying source: + /// `--extern force:extras=/path/to/lib/libstd.rlib` + pub force: bool, } #[derive(Clone, Debug)] @@ -556,7 +562,13 @@ impl Externs { impl ExternEntry { fn new(location: ExternLocation) -> ExternEntry { - ExternEntry { location, is_private_dep: false, add_prelude: false, nounused_dep: false } + ExternEntry { + location, + is_private_dep: false, + add_prelude: false, + nounused_dep: false, + force: false, + } } pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> { @@ -1036,6 +1048,14 @@ fn default_configuration(sess: &Session) -> CrateConfig { ret.insert((sym::sanitize, Some(symbol))); } + if sess.is_sanitizer_cfi_generalize_pointers_enabled() { + ret.insert((sym::sanitizer_cfi_generalize_pointers, None)); + } + + if sess.is_sanitizer_cfi_normalize_integers_enabled() { + ret.insert((sym::sanitizer_cfi_normalize_integers, None)); + } + if sess.opts.debug_assertions { ret.insert((sym::debug_assertions, None)); } @@ -1056,37 +1076,76 @@ pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig /// The parsed `--check-cfg` options pub struct CheckCfg<T = String> { - /// The set of all `names()`, if None no name checking is performed - pub names_valid: Option<FxHashSet<T>>, + /// Is well known names activated + pub exhaustive_names: bool, /// Is well known values activated - pub well_known_values: bool, - /// The set of all `values()` - pub values_valid: FxHashMap<T, FxHashSet<T>>, + pub exhaustive_values: bool, + /// All the expected values for a config name + pub expecteds: FxHashMap<T, ExpectedValues<T>>, } impl<T> Default for CheckCfg<T> { fn default() -> Self { CheckCfg { - names_valid: Default::default(), - values_valid: Default::default(), - well_known_values: false, + exhaustive_names: false, + exhaustive_values: false, + expecteds: FxHashMap::default(), } } } impl<T> CheckCfg<T> { - fn map_data<O: Eq + Hash>(&self, f: impl Fn(&T) -> O) -> CheckCfg<O> { + fn map_data<O: Eq + Hash>(self, f: impl Fn(T) -> O) -> CheckCfg<O> { CheckCfg { - names_valid: self - .names_valid - .as_ref() - .map(|names_valid| names_valid.iter().map(|a| f(a)).collect()), - values_valid: self - .values_valid - .iter() - .map(|(a, b)| (f(a), b.iter().map(|b| f(b)).collect())) + exhaustive_names: self.exhaustive_names, + exhaustive_values: self.exhaustive_values, + expecteds: self + .expecteds + .into_iter() + .map(|(name, values)| { + ( + f(name), + match values { + ExpectedValues::Some(values) => ExpectedValues::Some( + values.into_iter().map(|b| b.map(|b| f(b))).collect(), + ), + ExpectedValues::Any => ExpectedValues::Any, + }, + ) + }) .collect(), - well_known_values: self.well_known_values, + } + } +} + +pub enum ExpectedValues<T> { + Some(FxHashSet<Option<T>>), + Any, +} + +impl<T: Eq + Hash> ExpectedValues<T> { + fn insert(&mut self, value: T) -> bool { + match self { + ExpectedValues::Some(expecteds) => expecteds.insert(Some(value)), + ExpectedValues::Any => false, + } + } +} + +impl<T: Eq + Hash> Extend<T> for ExpectedValues<T> { + fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { + match self { + ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(Some)), + ExpectedValues::Any => {} + } + } +} + +impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> { + fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { + match self { + ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(|a| Some(*a))), + ExpectedValues::Any => {} } } } @@ -1095,58 +1154,27 @@ impl<T> CheckCfg<T> { /// `rustc_interface::interface::Config` accepts this in the compiler configuration, /// but the symbol interner is not yet set up then, so we must convert it later. pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig { - cfg.map_data(|s| Symbol::intern(s)) + cfg.map_data(|s| Symbol::intern(&s)) } impl CrateCheckConfig { - /// Fills a `CrateCheckConfig` with well-known configuration names. - fn fill_well_known_names(&mut self) { - // NOTE: This should be kept in sync with `default_configuration` and - // `fill_well_known_values` - const WELL_KNOWN_NAMES: &[Symbol] = &[ - // rustc - sym::unix, - sym::windows, - sym::target_os, - sym::target_family, - sym::target_arch, - sym::target_endian, - sym::target_pointer_width, - sym::target_env, - sym::target_abi, - sym::target_vendor, - sym::target_thread_local, - sym::target_has_atomic_load_store, - sym::target_has_atomic, - sym::target_has_atomic_equal_alignment, - sym::target_feature, - sym::panic, - sym::sanitize, - sym::debug_assertions, - sym::proc_macro, - sym::test, - sym::feature, - // rustdoc - sym::doc, - sym::doctest, - // miri - sym::miri, - ]; - - // We only insert well-known names if `names()` was activated - if let Some(names_valid) = &mut self.names_valid { - names_valid.extend(WELL_KNOWN_NAMES); - } - } - - /// Fills a `CrateCheckConfig` with well-known configuration values. - fn fill_well_known_values(&mut self, current_target: &Target) { - if !self.well_known_values { + pub fn fill_well_known(&mut self, current_target: &Target) { + if !self.exhaustive_values && !self.exhaustive_names { return; } - // NOTE: This should be kept in sync with `default_configuration` and - // `fill_well_known_names` + let no_values = || { + let mut values = FxHashSet::default(); + values.insert(None); + ExpectedValues::Some(values) + }; + + let empty_values = || { + let values = FxHashSet::default(); + ExpectedValues::Some(values) + }; + + // NOTE: This should be kept in sync with `default_configuration` let panic_values = &PanicStrategy::all(); @@ -1166,6 +1194,9 @@ impl CrateCheckConfig { // Unknown possible values: // - `feature` // - `target_feature` + for name in [sym::feature, sym::target_feature] { + self.expecteds.entry(name).or_insert(ExpectedValues::Any); + } // No-values for name in [ @@ -1179,20 +1210,23 @@ impl CrateCheckConfig { sym::debug_assertions, sym::target_thread_local, ] { - self.values_valid.entry(name).or_default(); + self.expecteds.entry(name).or_insert_with(no_values); } // Pre-defined values - self.values_valid.entry(sym::panic).or_default().extend(panic_values); - self.values_valid.entry(sym::sanitize).or_default().extend(sanitize_values); - self.values_valid.entry(sym::target_has_atomic).or_default().extend(atomic_values); - self.values_valid + self.expecteds.entry(sym::panic).or_insert_with(empty_values).extend(panic_values); + self.expecteds.entry(sym::sanitize).or_insert_with(empty_values).extend(sanitize_values); + self.expecteds + .entry(sym::target_has_atomic) + .or_insert_with(no_values) + .extend(atomic_values); + self.expecteds .entry(sym::target_has_atomic_load_store) - .or_default() + .or_insert_with(no_values) .extend(atomic_values); - self.values_valid + self.expecteds .entry(sym::target_has_atomic_equal_alignment) - .or_default() + .or_insert_with(no_values) .extend(atomic_values); // Target specific values @@ -1210,47 +1244,50 @@ impl CrateCheckConfig { // Initialize (if not already initialized) for &e in VALUES { - self.values_valid.entry(e).or_default(); + let entry = self.expecteds.entry(e); + if !self.exhaustive_values { + entry.or_insert(ExpectedValues::Any); + } else { + entry.or_insert_with(empty_values); + } } - // Get all values map at once otherwise it would be costly. - // (8 values * 220 targets ~= 1760 times, at the time of writing this comment). - let [ - values_target_os, - values_target_family, - values_target_arch, - values_target_endian, - values_target_env, - values_target_abi, - values_target_vendor, - values_target_pointer_width, - ] = self - .values_valid - .get_many_mut(VALUES) - .expect("unable to get all the check-cfg values buckets"); - - for target in TARGETS - .iter() - .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target))) - .chain(iter::once(current_target.clone())) - { - values_target_os.insert(Symbol::intern(&target.options.os)); - values_target_family - .extend(target.options.families.iter().map(|family| Symbol::intern(family))); - values_target_arch.insert(Symbol::intern(&target.arch)); - values_target_endian.insert(Symbol::intern(target.options.endian.as_str())); - values_target_env.insert(Symbol::intern(&target.options.env)); - values_target_abi.insert(Symbol::intern(&target.options.abi)); - values_target_vendor.insert(Symbol::intern(&target.options.vendor)); - values_target_pointer_width.insert(sym::integer(target.pointer_width)); + if self.exhaustive_values { + // Get all values map at once otherwise it would be costly. + // (8 values * 220 targets ~= 1760 times, at the time of writing this comment). + let [ + values_target_os, + values_target_family, + values_target_arch, + values_target_endian, + values_target_env, + values_target_abi, + values_target_vendor, + values_target_pointer_width, + ] = self + .expecteds + .get_many_mut(VALUES) + .expect("unable to get all the check-cfg values buckets"); + + for target in TARGETS + .iter() + .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target))) + .chain(iter::once(current_target.clone())) + { + values_target_os.insert(Symbol::intern(&target.options.os)); + values_target_family.extend( + target.options.families.iter().map(|family| Symbol::intern(family)), + ); + values_target_arch.insert(Symbol::intern(&target.arch)); + values_target_endian.insert(Symbol::intern(target.options.endian.as_str())); + values_target_env.insert(Symbol::intern(&target.options.env)); + values_target_abi.insert(Symbol::intern(&target.options.abi)); + values_target_vendor.insert(Symbol::intern(&target.options.vendor)); + values_target_pointer_width.insert(sym::integer(target.pointer_width)); + } } } } - - pub fn fill_well_known(&mut self, current_target: &Target) { - self.fill_well_known_names(); - self.fill_well_known_values(current_target); - } } pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig { @@ -2236,6 +2273,7 @@ pub fn parse_externs( let mut is_private_dep = false; let mut add_prelude = true; let mut nounused_dep = false; + let mut force = false; if let Some(opts) = options { if !is_unstable_enabled { early_error( @@ -2258,6 +2296,7 @@ pub fn parse_externs( } } "nounused" => nounused_dep = true, + "force" => force = true, _ => early_error(error_format, &format!("unknown --extern option `{opt}`")), } } @@ -2268,6 +2307,8 @@ pub fn parse_externs( entry.is_private_dep |= is_private_dep; // likewise `nounused` entry.nounused_dep |= nounused_dep; + // and `force` + entry.force |= force; // If any flag is missing `noprelude`, then add to the prelude. entry.add_prelude |= add_prelude; } diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index bd32adbbdbb..546c0fa8e03 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -6,7 +6,7 @@ use rustc_ast::token; use rustc_ast::util::literal::LitError; use rustc_errors::{error_code, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, MultiSpan}; use rustc_macros::Diagnostic; -use rustc_span::{Span, Symbol}; +use rustc_span::{BytePos, Span, Symbol}; use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple}; #[derive(Diagnostic)] @@ -111,8 +111,24 @@ pub struct CannotMixAndMatchSanitizers { pub struct CannotEnableCrtStaticLinux; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_enabled)] -pub struct SanitizerCfiEnabled; +#[diag(session_sanitizer_cfi_requires_lto)] +pub struct SanitizerCfiRequiresLto; + +#[derive(Diagnostic)] +#[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)] +pub struct SanitizerCfiCanonicalJumpTablesRequiresCfi; + +#[derive(Diagnostic)] +#[diag(session_sanitizer_cfi_generalize_pointers_requires_cfi)] +pub struct SanitizerCfiGeneralizePointersRequiresCfi; + +#[derive(Diagnostic)] +#[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)] +pub struct SanitizerCfiNormalizeIntegersRequiresCfi; + +#[derive(Diagnostic)] +#[diag(session_split_lto_unit_requires_lto)] +pub struct SplitLtoUnitRequiresLto; #[derive(Diagnostic)] #[diag(session_unstable_virtual_function_elimination)] @@ -307,6 +323,13 @@ pub(crate) struct BinaryFloatLiteralNotSupported { pub span: Span, } +#[derive(Diagnostic)] +#[diag(session_nul_in_c_str)] +pub(crate) struct NulInCStr { + #[primary_span] + pub span: Span, +} + pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: Span) { // Checks if `s` looks like i32 or u1234 etc. fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool { @@ -385,6 +408,12 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: }; sess.emit_err(IntLiteralTooLarge { span, limit }); } + LitError::NulInCStr(range) => { + let lo = BytePos(span.lo().0 + range.start as u32 + 2); + let hi = BytePos(span.lo().0 + range.end as u32 + 2); + let span = span.with_lo(lo).with_hi(hi); + sess.emit_err(NulInCStr { span }); + } } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 775fad1a365..5cbd7f98b6b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1235,6 +1235,8 @@ options! { line-tables-only, limited, or full; default: 0)"), default_linker_libraries: bool = (false, parse_bool, [UNTRACKED], "allow the linker to link its default libraries (default: no)"), + dlltool: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED], + "import library generation tool (ignored except when targeting windows-gnu)"), embed_bitcode: bool = (true, parse_bool, [TRACKED], "emit bitcode in rlibs (default: yes)"), extra_filename: String = (String::new(), parse_string, [UNTRACKED], @@ -1391,8 +1393,6 @@ options! { (default: no)"), diagnostic_width: Option<usize> = (None, parse_opt_number, [UNTRACKED], "set the current output width for diagnostic truncation"), - dlltool: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED], - "import library generation tool (windows-gnu only)"), dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED], "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \ (default: no)"), @@ -1555,7 +1555,7 @@ options! { "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ (default: no)"), mir_enable_passes: Vec<(String, bool)> = (Vec::new(), parse_list_with_polarity, [TRACKED], - "use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be \ + "use like `-Zmir-enable-passes=+DestinationPropagation,-InstSimplify`. Forces the specified passes to be \ enabled, overriding all other checks. Passes that are not specified are enabled or \ disabled by other flags as usual."), mir_keep_place_mention: bool = (false, parse_bool, [TRACKED], @@ -1662,6 +1662,12 @@ options! { "immediately print bugs registered with `delay_span_bug` (default: no)"), sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], "use a sanitizer"), + sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED], + "enable canonical jump tables (default: yes)"), + sanitizer_cfi_generalize_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED], + "enable generalizing pointer types (default: no)"), + sanitizer_cfi_normalize_integers: Option<bool> = (None, parse_opt_bool, [TRACKED], + "enable normalizing integer types (default: no)"), sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED], "enable origins tracking in MemorySanitizer"), sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], @@ -1707,6 +1713,8 @@ options! { file which is ignored by the linker `single`: sections which do not require relocation are written into object file but ignored by the linker"), + split_lto_unit: Option<bool> = (None, parse_opt_bool, [TRACKED], + "enable LTO unit splitting (default: no)"), src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED], "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 15e27952cf5..5cc9c62617d 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -214,8 +214,6 @@ pub struct ParseSess { pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>, /// File paths accessed during the build. pub file_depinfo: Lock<FxHashSet<Symbol>>, - /// All the type ascriptions expressions that have had a suggestion for likely path typo. - pub type_ascription_path_suggestions: Lock<FxHashSet<Span>>, /// Whether cfg(version) should treat the current release as incomplete pub assume_incomplete_release: bool, /// Spans passed to `proc_macro::quote_span`. Each span has a numerical @@ -258,7 +256,6 @@ impl ParseSess { reached_eof: AtomicBool::new(false), env_depinfo: Default::default(), file_depinfo: Default::default(), - type_ascription_path_suggestions: Default::default(), assume_incomplete_release: false, proc_macro_quoted_spans: Default::default(), attr_id_generator: AttrIdGenerator::new(), diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index aa22140c99d..a988d7f28e6 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -766,10 +766,30 @@ impl Session { self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI) } + pub fn is_sanitizer_cfi_canonical_jump_tables_disabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_canonical_jump_tables == Some(false) + } + + pub fn is_sanitizer_cfi_canonical_jump_tables_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_canonical_jump_tables == Some(true) + } + + pub fn is_sanitizer_cfi_generalize_pointers_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_generalize_pointers == Some(true) + } + + pub fn is_sanitizer_cfi_normalize_integers_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_normalize_integers == Some(true) + } + pub fn is_sanitizer_kcfi_enabled(&self) -> bool { self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) } + pub fn is_split_lto_unit_enabled(&self) -> bool { + self.opts.unstable_opts.split_lto_unit == Some(true) + } + /// Check whether this compile session and crate type use static crt. pub fn crt_static(&self, crate_type: Option<CrateType>) -> bool { if !self.target.crt_static_respected { @@ -1582,17 +1602,16 @@ fn validate_commandline_args_with_session_available(sess: &Session) { sess.emit_err(errors::CannotEnableCrtStaticLinux); } - // LLVM CFI and VFE both require LTO. - if sess.lto() != config::Lto::Fat { - if sess.is_sanitizer_cfi_enabled() { - sess.emit_err(errors::SanitizerCfiEnabled); - } - if sess.opts.unstable_opts.virtual_function_elimination { - sess.emit_err(errors::UnstableVirtualFunctionElimination); - } + // LLVM CFI requires LTO. + if sess.is_sanitizer_cfi_enabled() + && !(sess.lto() == config::Lto::Fat + || sess.lto() == config::Lto::Thin + || sess.opts.cg.linker_plugin_lto.enabled()) + { + sess.emit_err(errors::SanitizerCfiRequiresLto); } - // LLVM CFI and KCFI are mutually exclusive + // LLVM CFI is incompatible with LLVM KCFI. if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() { sess.emit_err(errors::CannotMixAndMatchSanitizers { first: "cfi".to_string(), @@ -1600,6 +1619,43 @@ fn validate_commandline_args_with_session_available(sess: &Session) { }); } + // Canonical jump tables requires CFI. + if sess.is_sanitizer_cfi_canonical_jump_tables_disabled() { + if !sess.is_sanitizer_cfi_enabled() { + sess.emit_err(errors::SanitizerCfiCanonicalJumpTablesRequiresCfi); + } + } + + // LLVM CFI pointer generalization requires CFI or KCFI. + if sess.is_sanitizer_cfi_generalize_pointers_enabled() { + if !(sess.is_sanitizer_cfi_enabled() || sess.is_sanitizer_kcfi_enabled()) { + sess.emit_err(errors::SanitizerCfiGeneralizePointersRequiresCfi); + } + } + + // LLVM CFI integer normalization requires CFI or KCFI. + if sess.is_sanitizer_cfi_normalize_integers_enabled() { + if !(sess.is_sanitizer_cfi_enabled() || sess.is_sanitizer_kcfi_enabled()) { + sess.emit_err(errors::SanitizerCfiNormalizeIntegersRequiresCfi); + } + } + + // LTO unit splitting requires LTO. + if sess.is_split_lto_unit_enabled() + && !(sess.lto() == config::Lto::Fat + || sess.lto() == config::Lto::Thin + || sess.opts.cg.linker_plugin_lto.enabled()) + { + sess.emit_err(errors::SplitLtoUnitRequiresLto); + } + + // VFE requires LTO. + if sess.lto() != config::Lto::Fat { + if sess.opts.unstable_opts.virtual_function_elimination { + sess.emit_err(errors::UnstableVirtualFunctionElimination); + } + } + if sess.opts.unstable_opts.stack_protector != StackProtector::None { if !sess.target.options.supports_stack_protector { sess.emit_warning(errors::StackProtectorNotSupportedForTarget { diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index fb97ee5bebe..80360a3c73f 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.0" edition = "2021" [dependencies] +rustc_hir = { path = "../rustc_hir" } rustc_middle = { path = "../rustc_middle", optional = true } rustc_span = { path = "../rustc_span", optional = true } tracing = "0.1" diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 09cb6fd22d5..241cd182059 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -93,10 +93,10 @@ fn rustc_statement_to_statement( } } -fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Operand { +fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Rvalue { use rustc_middle::mir::Rvalue::*; match rvalue { - Use(op) => rustc_op_to_op(op), + Use(op) => stable_mir::mir::Rvalue::Use(rustc_op_to_op(op)), Repeat(_, _) => todo!(), Ref(_, _, _) => todo!(), ThreadLocalRef(_) => todo!(), @@ -104,9 +104,15 @@ fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir: Len(_) => todo!(), Cast(_, _, _) => todo!(), BinaryOp(_, _) => todo!(), - CheckedBinaryOp(_, _) => todo!(), + CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp( + rustc_bin_op_to_bin_op(bin_op), + rustc_op_to_op(&ops.0), + rustc_op_to_op(&ops.1), + ), NullaryOp(_, _) => todo!(), - UnaryOp(_, _) => todo!(), + UnaryOp(un_op, op) => { + stable_mir::mir::Rvalue::UnaryOp(rustc_un_op_to_un_op(un_op), rustc_op_to_op(op)) + } Discriminant(_) => todo!(), Aggregate(_, _) => todo!(), ShallowInitBox(_, _) => todo!(), @@ -124,8 +130,10 @@ fn rustc_op_to_op(op: &rustc_middle::mir::Operand<'_>) -> stable_mir::mir::Opera } fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir::Place { - assert_eq!(&place.projection[..], &[]); - stable_mir::mir::Place { local: place.local.as_usize() } + stable_mir::mir::Place { + local: place.local.as_usize(), + projection: format!("{:?}", place.projection), + } } fn rustc_unwind_to_unwind( @@ -140,6 +148,96 @@ fn rustc_unwind_to_unwind( } } +fn rustc_assert_msg_to_msg<'tcx>( + assert_message: &rustc_middle::mir::AssertMessage<'tcx>, +) -> stable_mir::mir::AssertMessage { + use rustc_middle::mir::AssertKind; + match assert_message { + AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck { + len: rustc_op_to_op(len), + index: rustc_op_to_op(index), + }, + AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow( + rustc_bin_op_to_bin_op(bin_op), + rustc_op_to_op(op1), + rustc_op_to_op(op2), + ), + AssertKind::OverflowNeg(op) => { + stable_mir::mir::AssertMessage::OverflowNeg(rustc_op_to_op(op)) + } + AssertKind::DivisionByZero(op) => { + stable_mir::mir::AssertMessage::DivisionByZero(rustc_op_to_op(op)) + } + AssertKind::RemainderByZero(op) => { + stable_mir::mir::AssertMessage::RemainderByZero(rustc_op_to_op(op)) + } + AssertKind::ResumedAfterReturn(generator) => { + stable_mir::mir::AssertMessage::ResumedAfterReturn(rustc_generator_to_generator( + generator, + )) + } + AssertKind::ResumedAfterPanic(generator) => { + stable_mir::mir::AssertMessage::ResumedAfterPanic(rustc_generator_to_generator( + generator, + )) + } + AssertKind::MisalignedPointerDereference { required, found } => { + stable_mir::mir::AssertMessage::MisalignedPointerDereference { + required: rustc_op_to_op(required), + found: rustc_op_to_op(found), + } + } + } +} + +fn rustc_bin_op_to_bin_op(bin_op: &rustc_middle::mir::BinOp) -> stable_mir::mir::BinOp { + use rustc_middle::mir::BinOp; + match bin_op { + BinOp::Add => stable_mir::mir::BinOp::Add, + BinOp::Sub => stable_mir::mir::BinOp::Sub, + BinOp::Mul => stable_mir::mir::BinOp::Mul, + BinOp::Div => stable_mir::mir::BinOp::Div, + BinOp::Rem => stable_mir::mir::BinOp::Rem, + BinOp::BitXor => stable_mir::mir::BinOp::BitXor, + BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, + BinOp::BitOr => stable_mir::mir::BinOp::BitOr, + BinOp::Shl => stable_mir::mir::BinOp::Shl, + BinOp::Shr => stable_mir::mir::BinOp::Shr, + BinOp::Eq => stable_mir::mir::BinOp::Eq, + BinOp::Lt => stable_mir::mir::BinOp::Lt, + BinOp::Le => stable_mir::mir::BinOp::Le, + BinOp::Ne => stable_mir::mir::BinOp::Ne, + BinOp::Ge => stable_mir::mir::BinOp::Ge, + BinOp::Gt => stable_mir::mir::BinOp::Gt, + BinOp::Offset => stable_mir::mir::BinOp::Offset, + } +} + +fn rustc_un_op_to_un_op(unary_op: &rustc_middle::mir::UnOp) -> stable_mir::mir::UnOp { + use rustc_middle::mir::UnOp; + match unary_op { + UnOp::Not => stable_mir::mir::UnOp::Not, + UnOp::Neg => stable_mir::mir::UnOp::Neg, + } +} + +fn rustc_generator_to_generator( + generator: &rustc_hir::GeneratorKind, +) -> stable_mir::mir::GeneratorKind { + use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; + match generator { + GeneratorKind::Async(async_gen) => { + let async_gen = match async_gen { + AsyncGeneratorKind::Block => stable_mir::mir::AsyncGeneratorKind::Block, + AsyncGeneratorKind::Closure => stable_mir::mir::AsyncGeneratorKind::Closure, + AsyncGeneratorKind::Fn => stable_mir::mir::AsyncGeneratorKind::Fn, + }; + stable_mir::mir::GeneratorKind::Async(async_gen) + } + GeneratorKind::Gen => stable_mir::mir::GeneratorKind::Gen, + } +} + fn rustc_terminator_to_terminator( terminator: &rustc_middle::mir::Terminator<'_>, ) -> stable_mir::mir::Terminator { @@ -162,7 +260,11 @@ fn rustc_terminator_to_terminator( Terminate => Terminator::Abort, Return => Terminator::Return, Unreachable => Terminator::Unreachable, - Drop { .. } => todo!(), + Drop { place, target, unwind } => Terminator::Drop { + place: rustc_place_to_place(place), + target: target.as_usize(), + unwind: rustc_unwind_to_unwind(unwind), + }, Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => { Terminator::Call { func: rustc_op_to_op(func), @@ -172,9 +274,15 @@ fn rustc_terminator_to_terminator( unwind: rustc_unwind_to_unwind(unwind), } } - Assert { .. } => todo!(), + Assert { cond, expected, msg, target, unwind } => Terminator::Assert { + cond: rustc_op_to_op(cond), + expected: *expected, + msg: rustc_assert_msg_to_msg(msg), + target: target.as_usize(), + unwind: rustc_unwind_to_unwind(unwind), + }, Yield { .. } => todo!(), - GeneratorDrop => todo!(), + GeneratorDrop => Terminator::GeneratorDrop, FalseEdge { .. } => todo!(), FalseUnwind { .. } => todo!(), InlineAsm { .. } => todo!(), diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index bd5e6b68a12..4baf3f1f75e 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -26,7 +26,7 @@ pub enum Terminator { Drop { place: Place, target: usize, - unwind: Option<usize>, + unwind: UnwindAction, }, Call { func: Operand, @@ -38,10 +38,11 @@ pub enum Terminator { Assert { cond: Operand, expected: bool, - msg: String, + msg: AssertMessage, target: usize, - cleanup: Option<usize>, + unwind: UnwindAction, }, + GeneratorDrop, } #[derive(Clone, Debug)] @@ -53,11 +54,71 @@ pub enum UnwindAction { } #[derive(Clone, Debug)] +pub enum AssertMessage { + BoundsCheck { len: Operand, index: Operand }, + Overflow(BinOp, Operand, Operand), + OverflowNeg(Operand), + DivisionByZero(Operand), + RemainderByZero(Operand), + ResumedAfterReturn(GeneratorKind), + ResumedAfterPanic(GeneratorKind), + MisalignedPointerDereference { required: Operand, found: Operand }, +} + +#[derive(Clone, Debug)] +pub enum BinOp { + Add, + Sub, + Mul, + Div, + Rem, + BitXor, + BitAnd, + BitOr, + Shl, + Shr, + Eq, + Lt, + Le, + Ne, + Ge, + Gt, + Offset, +} + +#[derive(Clone, Debug)] +pub enum UnOp { + Not, + Neg, +} + +#[derive(Clone, Debug)] +pub enum GeneratorKind { + Async(AsyncGeneratorKind), + Gen, +} + +#[derive(Clone, Debug)] +pub enum AsyncGeneratorKind { + Block, + Closure, + Fn, +} + +#[derive(Clone, Debug)] pub enum Statement { - Assign(Place, Operand), + Assign(Place, Rvalue), Nop, } +// FIXME this is incomplete +#[derive(Clone, Debug)] +pub enum Rvalue { + Use(Operand), + CheckedBinaryOp(BinOp, Operand, Operand), + UnaryOp(UnOp, Operand), +} + #[derive(Clone, Debug)] pub enum Operand { Copy(Place), @@ -68,6 +129,7 @@ pub enum Operand { #[derive(Clone, Debug)] pub struct Place { pub local: usize, + pub projection: String, } #[derive(Clone, Debug)] diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 8a900ca427e..7bbab34c69a 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -69,7 +69,6 @@ use std::hash::Hash; use std::ops::{Add, Range, Sub}; use std::path::{Path, PathBuf}; use std::str::FromStr; -use std::sync::Arc; use md5::Digest; use md5::Md5; @@ -1269,13 +1268,13 @@ pub enum DebuggerVisualizerType { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable)] pub struct DebuggerVisualizerFile { /// The complete debugger visualizer source. - pub src: Arc<[u8]>, + pub src: Lrc<[u8]>, /// Indicates which visualizer type this targets. pub visualizer_type: DebuggerVisualizerType, } impl DebuggerVisualizerFile { - pub fn new(src: Arc<[u8]>, visualizer_type: DebuggerVisualizerType) -> Self { + pub fn new(src: Lrc<[u8]>, visualizer_type: DebuggerVisualizerType) -> Self { DebuggerVisualizerFile { src, visualizer_type } } } @@ -1745,6 +1744,28 @@ impl SourceFile { BytePos::from_u32(pos.0 - self.start_pos.0 + diff) } + /// Calculates a normalized byte position from a byte offset relative to the + /// start of the file. + /// + /// When we get an inline assembler error from LLVM during codegen, we + /// import the expanded assembly code as a new `SourceFile`, which can then + /// be used for error reporting with spans. However the byte offsets given + /// to us by LLVM are relative to the start of the original buffer, not the + /// normalized one. Hence we need to convert those offsets to the normalized + /// form when constructing spans. + pub fn normalized_byte_pos(&self, offset: u32) -> BytePos { + let diff = match self + .normalized_pos + .binary_search_by(|np| (np.pos.0 + np.diff).cmp(&(self.start_pos.0 + offset))) + { + Ok(i) => self.normalized_pos[i].diff, + Err(i) if i == 0 => 0, + Err(i) => self.normalized_pos[i - 1].diff, + }; + + BytePos::from_u32(self.start_pos.0 + offset - diff) + } + /// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`. pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos { // The number of extra bytes due to multibyte chars in the `SourceFile`. @@ -2200,6 +2221,7 @@ pub struct ErrorGuaranteed(()); impl ErrorGuaranteed { /// To be used only if you really know what you are doing... ideally, we would find a way to /// eliminate all calls to this method. + #[deprecated = "`Session::delay_span_bug` should be preferred over this function"] pub fn unchecked_claim_error_was_emitted() -> Self { ErrorGuaranteed(()) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 5bfbff76b4f..b97ec6c684b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -441,8 +441,10 @@ symbols! { bridge, bswap, c_str, + c_str_literals, c_unwind, c_variadic, + c_void, call, call_mut, call_once, @@ -470,6 +472,7 @@ symbols! { cfg_target_vendor, cfg_version, cfi, + cfi_encoding, char, client, clippy, @@ -531,6 +534,7 @@ symbols! { const_mut_refs, const_panic, const_panic_fmt, + const_param_ty, const_precise_live_drops, const_raw_ptr_deref, const_raw_ptr_to_usize_cast, @@ -983,6 +987,7 @@ symbols! { needs_panic_runtime, neg, negate_unsigned, + negative_bounds, negative_impls, neon, never, @@ -1202,6 +1207,7 @@ symbols! { require, residual, result, + resume, return_position_impl_trait_in_trait, return_type_notation, rhs, @@ -1321,6 +1327,8 @@ symbols! { s, safety, sanitize, + sanitizer_cfi_generalize_pointers, + sanitizer_cfi_normalize_integers, sanitizer_runtime, saturating_add, saturating_sub, @@ -1636,6 +1644,7 @@ symbols! { write_bytes, write_macro, write_str, + write_via_move, writeln_macro, x87_reg, xer, diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs index 53983bed718..81dbff9ea4e 100644 --- a/compiler/rustc_symbol_mangling/src/typeid.rs +++ b/compiler/rustc_symbol_mangling/src/typeid.rs @@ -1,42 +1,65 @@ -// For more information about type metadata and type metadata identifiers for cross-language LLVM -// CFI support, see Type metadata in the design document in the tracking issue #89653. - +/// Type metadata identifiers for LLVM Control Flow Integrity (CFI) and cross-language LLVM CFI +/// support. +/// +/// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler, +/// see design document in the tracking issue #89653. +use bitflags::bitflags; use rustc_middle::ty::{FnSig, Ty, TyCtxt}; use rustc_target::abi::call::FnAbi; use std::hash::Hasher; use twox_hash::XxHash64; +bitflags! { + /// Options for typeid_for_fnabi and typeid_for_fnsig. + pub struct TypeIdOptions: u32 { + const GENERALIZE_POINTERS = 1; + const GENERALIZE_REPR_C = 2; + const NORMALIZE_INTEGERS = 4; + } +} + mod typeid_itanium_cxx_abi; -use typeid_itanium_cxx_abi::TypeIdOptions; /// Returns a type metadata identifier for the specified FnAbi. -pub fn typeid_for_fnabi<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> String { - typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, TypeIdOptions::NO_OPTIONS) +pub fn typeid_for_fnabi<'tcx>( + tcx: TyCtxt<'tcx>, + fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + options: TypeIdOptions, +) -> String { + typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, options) } /// Returns a type metadata identifier for the specified FnSig. -pub fn typeid_for_fnsig<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: &FnSig<'tcx>) -> String { - typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, TypeIdOptions::NO_OPTIONS) +pub fn typeid_for_fnsig<'tcx>( + tcx: TyCtxt<'tcx>, + fn_sig: &FnSig<'tcx>, + options: TypeIdOptions, +) -> String { + typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options) } -/// Returns an LLVM KCFI type metadata identifier for the specified FnAbi. -pub fn kcfi_typeid_for_fnabi<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> u32 { - // An LLVM KCFI type metadata identifier is a 32-bit constant produced by taking the lower half - // of the xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) +/// Returns a KCFI type metadata identifier for the specified FnAbi. +pub fn kcfi_typeid_for_fnabi<'tcx>( + tcx: TyCtxt<'tcx>, + fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + options: TypeIdOptions, +) -> u32 { + // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the + // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) let mut hash: XxHash64 = Default::default(); - hash.write( - typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, TypeIdOptions::NO_OPTIONS).as_bytes(), - ); + hash.write(typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, options).as_bytes()); hash.finish() as u32 } -/// Returns an LLVM KCFI type metadata identifier for the specified FnSig. -pub fn kcfi_typeid_for_fnsig<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: &FnSig<'tcx>) -> u32 { - // An LLVM KCFI type metadata identifier is a 32-bit constant produced by taking the lower half - // of the xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) +/// Returns a KCFI type metadata identifier for the specified FnSig. +pub fn kcfi_typeid_for_fnsig<'tcx>( + tcx: TyCtxt<'tcx>, + fn_sig: &FnSig<'tcx>, + options: TypeIdOptions, +) -> u32 { + // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the + // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) let mut hash: XxHash64 = Default::default(); - hash.write( - typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, TypeIdOptions::NO_OPTIONS).as_bytes(), - ); + hash.write(typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options).as_bytes()); hash.finish() as u32 } diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index a9152b8113f..5310ef26da7 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -1,14 +1,16 @@ -// For more information about type metadata and type metadata identifiers for cross-language LLVM -// CFI support, see Type metadata in the design document in the tracking issue #89653. - -// FIXME(rcvalle): Identify C char and integer type uses and encode them with their respective -// builtin type encodings as specified by the Itanium C++ ABI for extern function types with the "C" -// calling convention to use this encoding for cross-language LLVM CFI. - -use bitflags::bitflags; +/// Type metadata identifiers (using Itanium C++ ABI mangling for encoding) for LLVM Control Flow +/// Integrity (CFI) and cross-language LLVM CFI support. +/// +/// Encodes type metadata identifiers for LLVM CFI and cross-language LLVM CFI support using Itanium +/// C++ ABI mangling for encoding with vendor extended type qualifiers and types for Rust types that +/// are not used across the FFI boundary. +/// +/// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler, +/// see design document in the tracking issue #89653. use core::fmt::Display; use rustc_data_structures::base_n; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::DiagnosticMessage; use rustc_hir as hir; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{ @@ -16,11 +18,13 @@ use rustc_middle::ty::{ Ty, TyCtxt, UintTy, }; use rustc_span::def_id::DefId; -use rustc_span::symbol::sym; +use rustc_span::sym; use rustc_target::abi::call::{Conv, FnAbi}; use rustc_target::spec::abi::Abi; use std::fmt::Write as _; +use crate::typeid::TypeIdOptions; + /// Type and extended type qualifiers. #[derive(Eq, Hash, PartialEq)] enum TyQ { @@ -38,15 +42,6 @@ enum DictKey<'tcx> { Predicate(ExistentialPredicate<'tcx>), } -bitflags! { - /// Options for typeid_for_fnabi and typeid_for_fnsig. - pub struct TypeIdOptions: u32 { - const NO_OPTIONS = 0; - const GENERALIZE_POINTERS = 1; - const GENERALIZE_REPR_C = 2; - } -} - /// Options for encode_ty. type EncodeTyOptions = TypeIdOptions; @@ -91,21 +86,6 @@ fn compress<'tcx>( } } -// FIXME(rcvalle): Move to compiler/rustc_middle/src/ty/sty.rs after C types work is done, possibly -// along with other is_c_type methods. -/// Returns whether a `ty::Ty` is `c_void`. -fn is_c_void_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { - match ty.kind() { - ty::Adt(adt_def, ..) => { - let def_id = adt_def.0.did; - let crate_name = tcx.crate_name(def_id.krate); - tcx.item_name(def_id).as_str() == "c_void" - && (crate_name == sym::core || crate_name == sym::std || crate_name == sym::libc) - } - _ => false, - } -} - /// Encodes a const using the Itanium C++ ABI as a literal argument (see /// <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling.literal>). fn encode_const<'tcx>( @@ -448,6 +428,12 @@ fn encode_ty<'tcx>( match ty.kind() { // Primitive types + + // Rust's bool has the same layout as C17's _Bool, that is, its size and alignment are + // implementation-defined. Any bool can be cast into an integer, taking on the values 1 + // (true) or 0 (false). + // + // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#bool.) ty::Bool => { typeid.push('b'); } @@ -535,9 +521,33 @@ fn encode_ty<'tcx>( // User-defined types ty::Adt(adt_def, substs) => { let mut s = String::new(); - let def_id = adt_def.0.did; - if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() { - // For cross-language CFI support, the encoding must be compatible at the FFI + let def_id = adt_def.did(); + if let Some(cfi_encoding) = tcx.get_attr(def_id, sym::cfi_encoding) { + // Use user-defined CFI encoding for type + if let Some(value_str) = cfi_encoding.value_str() { + if !value_str.to_string().trim().is_empty() { + s.push_str(&value_str.to_string().trim()); + } else { + #[allow( + rustc::diagnostic_outside_of_impl, + rustc::untranslatable_diagnostic + )] + tcx.sess + .struct_span_err( + cfi_encoding.span, + DiagnosticMessage::Str(format!( + "invalid `cfi_encoding` for `{:?}`", + ty.kind() + )), + ) + .emit(); + } + } else { + bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind()); + } + compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); + } else if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() { + // For cross-language LLVM CFI support, the encoding must be compatible at the FFI // boundary. For instance: // // struct type1 {}; @@ -567,8 +577,33 @@ fn encode_ty<'tcx>( ty::Foreign(def_id) => { // <length><name>, where <name> is <unscoped-name> let mut s = String::new(); - let name = tcx.item_name(*def_id).to_string(); - let _ = write!(s, "{}{}", name.len(), &name); + if let Some(cfi_encoding) = tcx.get_attr(*def_id, sym::cfi_encoding) { + // Use user-defined CFI encoding for type + if let Some(value_str) = cfi_encoding.value_str() { + if !value_str.to_string().trim().is_empty() { + s.push_str(&value_str.to_string().trim()); + } else { + #[allow( + rustc::diagnostic_outside_of_impl, + rustc::untranslatable_diagnostic + )] + tcx.sess + .struct_span_err( + cfi_encoding.span, + DiagnosticMessage::Str(format!( + "invalid `cfi_encoding` for `{:?}`", + ty.kind() + )), + ) + .emit(); + } + } else { + bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind()); + } + } else { + let name = tcx.item_name(*def_id).to_string(); + let _ = write!(s, "{}{}", name.len(), &name); + } compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); typeid.push_str(&s); } @@ -618,7 +653,7 @@ fn encode_ty<'tcx>( ty::FnPtr(fn_sig) => { // PF<return-type><parameter-type1..parameter-typeN>E let mut s = String::from("P"); - s.push_str(&encode_fnsig(tcx, &fn_sig.skip_binder(), dict, TypeIdOptions::NO_OPTIONS)); + s.push_str(&encode_fnsig(tcx, &fn_sig.skip_binder(), dict, TypeIdOptions::empty())); compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); typeid.push_str(&s); } @@ -655,22 +690,59 @@ fn encode_ty<'tcx>( } // Transforms a ty:Ty for being encoded and used in the substitution dictionary. It transforms all -// c_void types into unit types unconditionally, and generalizes all pointers if -// TransformTyOptions::GENERALIZE_POINTERS option is set. -#[instrument(level = "trace", skip(tcx))] +// c_void types into unit types unconditionally, generalizes pointers if +// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if +// TransformTyOptions::NORMALIZE_INTEGERS option is set. fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptions) -> Ty<'tcx> { let mut ty = ty; match ty.kind() { - ty::Bool - | ty::Int(..) - | ty::Uint(..) - | ty::Float(..) - | ty::Char - | ty::Str - | ty::Never - | ty::Foreign(..) - | ty::Dynamic(..) => {} + ty::Float(..) | ty::Char | ty::Str | ty::Never | ty::Foreign(..) | ty::Dynamic(..) => {} + + ty::Bool => { + if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { + // Note: on all platforms that Rust's currently supports, its size and alignment are + // 1, and its ABI class is INTEGER - see Rust Layout and ABIs. + // + // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#bool.) + // + // Clang represents bool as an 8-bit unsigned integer. + ty = tcx.types.u8; + } + } + + ty::Int(..) | ty::Uint(..) => { + if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { + // Note: C99 7.18.2.4 requires uintptr_t and intptr_t to be at least 16-bit wide. + // All platforms we currently support have a C platform, and as a consequence, + // isize/usize are at least 16-bit wide for all of them. + // + // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize.) + match ty.kind() { + ty::Int(IntTy::Isize) => match tcx.sess.target.pointer_width { + 16 => ty = tcx.types.i16, + 32 => ty = tcx.types.i32, + 64 => ty = tcx.types.i64, + 128 => ty = tcx.types.i128, + _ => bug!( + "transform_ty: unexpected pointer width `{}`", + tcx.sess.target.pointer_width + ), + }, + ty::Uint(UintTy::Usize) => match tcx.sess.target.pointer_width { + 16 => ty = tcx.types.u16, + 32 => ty = tcx.types.u32, + 64 => ty = tcx.types.u64, + 128 => ty = tcx.types.u128, + _ => bug!( + "transform_ty: unexpected pointer width `{}`", + tcx.sess.target.pointer_width + ), + }, + _ => (), + } + } + } _ if ty.is_unit() => {} @@ -688,12 +760,17 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio } ty::Adt(adt_def, substs) => { - if is_c_void_ty(tcx, ty) { + if ty.is_c_void(tcx) { ty = tcx.mk_unit(); } else if options.contains(TransformTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() { ty = tcx.mk_adt(*adt_def, ty::List::empty()); } else if adt_def.repr().transparent() && adt_def.is_struct() { + // Don't transform repr(transparent) types with an user-defined CFI encoding to + // preserve the user-defined CFI encoding. + if let Some(_) = tcx.get_attr(adt_def.did(), sym::cfi_encoding) { + return ty; + } let variant = adt_def.non_enum_variant(); let param_env = tcx.param_env(variant.def_id); let field = variant.fields.iter().find(|field| { @@ -815,7 +892,7 @@ fn transform_substs<'tcx>( options: TransformTyOptions, ) -> SubstsRef<'tcx> { let substs = substs.iter().map(|subst| match subst.unpack() { - GenericArgKind::Type(ty) if is_c_void_ty(tcx, ty) => tcx.mk_unit().into(), + GenericArgKind::Type(ty) if ty.is_c_void(tcx) => tcx.mk_unit().into(), GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(), _ => subst, }); @@ -887,6 +964,15 @@ pub fn typeid_for_fnabi<'tcx>( // Close the "F..E" pair typeid.push('E'); + // Add encoding suffixes + if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { + typeid.push_str(".normalized"); + } + + if options.contains(EncodeTyOptions::GENERALIZE_POINTERS) { + typeid.push_str(".generalized"); + } + typeid } @@ -913,5 +999,14 @@ pub fn typeid_for_fnsig<'tcx>( // Encode the function signature typeid.push_str(&encode_fnsig(tcx, fn_sig, &mut dict, options)); + // Add encoding suffixes + if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { + typeid.push_str(".normalized"); + } + + if options.contains(EncodeTyOptions::GENERALIZE_POINTERS) { + typeid.push_str(".generalized"); + } + typeid } diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 57011aa8a14..52159a7b06a 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -65,7 +65,7 @@ mod attr_impl { // The subset of llvm::Attribute needed for arguments, packed into a bitfield. bitflags::bitflags! { #[derive(Default, HashStable_Generic)] - pub struct ArgAttribute: u16 { + pub struct ArgAttribute: u8 { const NoAlias = 1 << 1; const NoCapture = 1 << 2; const NonNull = 1 << 3; diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 266691b2c88..705966f5237 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -839,6 +839,7 @@ pub enum InlineAsmClobberAbi { AArch64, AArch64NoX18, RiscV, + LoongArch, } impl InlineAsmClobberAbi { @@ -880,6 +881,10 @@ impl InlineAsmClobberAbi { "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::RiscV), _ => Err(&["C", "system", "efiapi"]), }, + InlineAsmArch::LoongArch64 => match name { + "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch), + _ => Err(&["C", "system", "efiapi"]), + }, _ => Err(&[]), } } @@ -1022,6 +1027,21 @@ impl InlineAsmClobberAbi { v24, v25, v26, v27, v28, v29, v30, v31, } }, + InlineAsmClobberAbi::LoongArch => clobbered_regs! { + LoongArch LoongArchInlineAsmReg { + // ra + r1, + // a0-a7 + r4, r5, r6, r7, r8, r9, r10, r11, + // t0-t8 + r12, r13, r14, r15, r16, r17, r18, r19, r20, + // fa0-fa7 + f0, f1, f2, f3, f4, f5, f6, f7, + // ft0-ft15 + f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, + } + }, } } } diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs index 5582d909f6b..eb3f66ac308 100644 --- a/compiler/rustc_target/src/spec/abi.rs +++ b/compiler/rustc_target/src/spec/abi.rs @@ -148,8 +148,9 @@ pub fn is_enabled( pub fn is_stable(name: &str) -> Result<(), AbiDisabled> { match name { // Stable - "Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64" - | "system" | "efiapi" => Ok(()), + "Rust" | "C" | "C-unwind" | "cdecl" | "cdecl-unwind" | "stdcall" | "stdcall-unwind" + | "fastcall" | "fastcall-unwind" | "aapcs" | "aapcs-unwind" | "win64" | "win64-unwind" + | "sysv64" | "sysv64-unwind" | "system" | "system-unwind" | "efiapi" => Ok(()), "rust-intrinsic" => Err(AbiDisabled::Unstable { feature: sym::intrinsics, explain: "intrinsics are subject to change", @@ -162,10 +163,18 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> { feature: sym::abi_vectorcall, explain: "vectorcall is experimental and subject to change", }), + "vectorcall-unwind" => Err(AbiDisabled::Unstable { + feature: sym::abi_vectorcall, + explain: "vectorcall-unwind ABI is experimental and subject to change", + }), "thiscall" => Err(AbiDisabled::Unstable { feature: sym::abi_thiscall, explain: "thiscall is experimental and subject to change", }), + "thiscall-unwind" => Err(AbiDisabled::Unstable { + feature: sym::abi_thiscall, + explain: "thiscall-unwind ABI is experimental and subject to change", + }), "rust-call" => Err(AbiDisabled::Unstable { feature: sym::unboxed_closures, explain: "rust-call ABI is subject to change", @@ -202,46 +211,6 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> { feature: sym::abi_c_cmse_nonsecure_call, explain: "C-cmse-nonsecure-call ABI is experimental and subject to change", }), - "C-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "C-unwind ABI is experimental and subject to change", - }), - "stdcall-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "stdcall-unwind ABI is experimental and subject to change", - }), - "system-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "system-unwind ABI is experimental and subject to change", - }), - "thiscall-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "thiscall-unwind ABI is experimental and subject to change", - }), - "cdecl-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "cdecl-unwind ABI is experimental and subject to change", - }), - "fastcall-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "fastcall-unwind ABI is experimental and subject to change", - }), - "vectorcall-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "vectorcall-unwind ABI is experimental and subject to change", - }), - "aapcs-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "aapcs-unwind ABI is experimental and subject to change", - }), - "win64-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "win64-unwind ABI is experimental and subject to change", - }), - "sysv64-unwind" => Err(AbiDisabled::Unstable { - feature: sym::c_unwind, - explain: "sysv64-unwind ABI is experimental and subject to change", - }), "wasm" => Err(AbiDisabled::Unstable { feature: sym::wasm_abi, explain: "wasm ABI is experimental and subject to change", diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index fcf86da08f4..142c20014a0 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -66,7 +66,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult { - let trait_ref = self.tcx.mk_trait_ref(trait_def_id, params); + let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, params); let obligation = traits::Obligation { cause: traits::ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index f0840e0443c..e5d51064c8d 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -274,8 +274,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); } }; - let output_is_sized_pred = tupled_inputs_and_output - .map_bound(|(_, output)| tcx.at(DUMMY_SP).mk_trait_ref(LangItem::Sized, [output])); + let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| { + ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output]) + }); let pred = tupled_inputs_and_output .map_bound(|(inputs, output)| ty::ProjectionPredicate { @@ -333,10 +334,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { // FIXME(ptr_metadata): It would also be possible to return a `Ok(Ambig)` with no constraints. - let sized_predicate = ty::Binder::dummy(tcx.at(DUMMY_SP).mk_trait_ref( + let sized_predicate = ty::TraitRef::from_lang_item( + tcx, LangItem::Sized, + DUMMY_SP, [ty::GenericArg::from(goal.predicate.self_ty())], - )); + ); ecx.add_goal(goal.with(tcx, sized_predicate)); tcx.types.unit } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index c97473e6241..6c98fadd148 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -272,12 +272,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); } }; - let output_is_sized_pred = tupled_inputs_and_output - .map_bound(|(_, output)| tcx.at(DUMMY_SP).mk_trait_ref(LangItem::Sized, [output])); + let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| { + ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output]) + }); let pred = tupled_inputs_and_output .map_bound(|(inputs, _)| { - tcx.mk_trait_ref(goal.predicate.def_id(), [goal.predicate.self_ty(), inputs]) + ty::TraitRef::new(tcx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs]) }) .to_predicate(tcx); // A built-in `Fn` impl only holds if the output is sized. @@ -358,10 +359,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { Self::consider_implied_clause( ecx, goal, - ty::Binder::dummy( - tcx.mk_trait_ref(goal.predicate.def_id(), [self_ty, generator.resume_ty()]), - ) - .to_predicate(tcx), + ty::TraitRef::new(tcx, goal.predicate.def_id(), [self_ty, generator.resume_ty()]) + .to_predicate(tcx), // Technically, we need to check that the generator types are Sized, // but that's already proven by the generator being WF. [], @@ -410,9 +409,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))), ); // The type must be Sized to be unsized. - ecx.add_goal( - goal.with(tcx, ty::Binder::dummy(tcx.mk_trait_ref(sized_def_id, [a_ty]))), - ); + ecx.add_goal(goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty]))); // The type must outlive the lifetime of the `dyn` we're unsizing into. ecx.add_goal( goal.with(tcx, ty::Binder::dummy(ty::OutlivesPredicate(a_ty, region))), @@ -461,9 +458,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx.eq(goal.param_env, unsized_a_ty, b_ty)?; ecx.add_goal(goal.with( tcx, - ty::Binder::dummy( - tcx.mk_trait_ref(goal.predicate.def_id(), [a_tail_ty, b_tail_ty]), - ), + ty::TraitRef::new(tcx, goal.predicate.def_id(), [a_tail_ty, b_tail_ty]), )); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } @@ -482,9 +477,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // Similar to ADTs, require that the rest of the fields are equal. ecx.add_goal(goal.with( tcx, - ty::Binder::dummy( - tcx.mk_trait_ref(goal.predicate.def_id(), [*a_last_ty, *b_last_ty]), - ), + ty::TraitRef::new(tcx, goal.predicate.def_id(), [*a_last_ty, *b_last_ty]), )); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index e82672e8368..6b080a132f3 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -86,7 +86,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult<A> { let tcx = self.tcx; - let trait_ref = tcx.mk_trait_ref(trait_did, [ty]); + let trait_ref = ty::TraitRef::new(tcx, trait_did, [ty]); let infcx = tcx.infer_ctxt().build(); let mut selcx = SelectionContext::new(&infcx); @@ -263,7 +263,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); predicates.push_back(ty::Binder::dummy(ty::TraitPredicate { - trait_ref: infcx.tcx.mk_trait_ref(trait_did, [ty]), + trait_ref: ty::TraitRef::new(infcx.tcx, trait_did, [ty]), constness: ty::BoundConstness::NotConst, // Auto traits are positive diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 2beebe94b6d..000427bbe83 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -97,7 +97,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { def_id: DefId, ) { let tcx = self.infcx.tcx; - let trait_ref = tcx.mk_trait_ref(def_id, [ty]); + let trait_ref = ty::TraitRef::new(tcx, def_id, [ty]); self.register_obligation(Obligation { cause, recursion_depth: 0, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs index 0475f24d87c..7ab652761a4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs @@ -87,7 +87,7 @@ pub fn recompute_applicable_impls<'tcx>( if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = kind.skip_binder() && param_env_candidate_may_apply(kind.rebind(trait_pred)) { - if kind.rebind(trait_pred.trait_ref) == ty::TraitRef::identity(tcx, trait_pred.def_id()) { + if kind.rebind(trait_pred.trait_ref) == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) { ambiguities.push(Ambiguity::ParamEnv(tcx.def_span(trait_pred.def_id()))) } else { ambiguities.push(Ambiguity::ParamEnv(span)) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs deleted file mode 100644 index 7e1dba4ed26..00000000000 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs +++ /dev/null @@ -1,102 +0,0 @@ -use crate::infer::InferCtxt; - -use rustc_infer::infer::ObligationEmittingRelation; -use rustc_infer::traits::PredicateObligations; -use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::{self, Ty, TyCtxt}; - -pub struct CollectAllMismatches<'a, 'tcx> { - pub infcx: &'a InferCtxt<'tcx>, - pub param_env: ty::ParamEnv<'tcx>, - pub errors: Vec<TypeError<'tcx>>, -} - -impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> { - fn tag(&self) -> &'static str { - "CollectAllMismatches" - } - - fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env - } - - fn a_is_expected(&self) -> bool { - true - } - - fn relate_with_variance<T: Relate<'tcx>>( - &mut self, - _: ty::Variance, - _: ty::VarianceDiagInfo<'tcx>, - a: T, - b: T, - ) -> RelateResult<'tcx, T> { - self.relate(a, b) - } - - fn regions( - &mut self, - a: ty::Region<'tcx>, - _b: ty::Region<'tcx>, - ) -> RelateResult<'tcx, ty::Region<'tcx>> { - Ok(a) - } - - fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - self.infcx.probe(|_| { - if a.is_ty_var() || b.is_ty_var() { - Ok(a) - } else { - self.infcx.super_combine_tys(self, a, b).or_else(|e| { - self.errors.push(e); - Ok(a) - }) - } - }) - } - - fn consts( - &mut self, - a: ty::Const<'tcx>, - b: ty::Const<'tcx>, - ) -> RelateResult<'tcx, ty::Const<'tcx>> { - self.infcx.probe(|_| { - if a.is_ct_infer() || b.is_ct_infer() { - Ok(a) - } else { - relate::super_relate_consts(self, a, b) // could do something similar here for constants! - } - }) - } - - fn binders<T: Relate<'tcx>>( - &mut self, - a: ty::Binder<'tcx, T>, - b: ty::Binder<'tcx, T>, - ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> { - Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) - } -} - -impl<'tcx> ObligationEmittingRelation<'tcx> for CollectAllMismatches<'_, 'tcx> { - fn alias_relate_direction(&self) -> ty::AliasRelationDirection { - // FIXME(deferred_projection_equality): We really should get rid of this relation. - ty::AliasRelationDirection::Equate - } - - fn register_obligations(&mut self, _obligations: PredicateObligations<'tcx>) { - // FIXME(deferred_projection_equality) - } - - fn register_predicates( - &mut self, - _obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>, - ) { - // FIXME(deferred_projection_equality) - } -} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index ce187fbdf84..afb64da8b61 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1,5 +1,4 @@ mod ambiguity; -pub mod method_chain; pub mod on_unimplemented; pub mod suggestions; @@ -271,7 +270,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { let underscores = vec!["_"; expected_args.len()].join(", "); err.span_suggestion_verbose( closure_arg_span.unwrap_or(found_span), - &format!( + format!( "consider changing the closure to take and ignore the expected argument{}", pluralize!(expected_args.len()) ), @@ -358,7 +357,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, }); - let trait_ref = self.tcx.mk_trait_ref(trait_def_id, [ty.skip_binder(), var]); + let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, [ty.skip_binder(), var]); let obligation = Obligation::new( self.tcx, ObligationCause::dummy(), @@ -559,6 +558,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { suggest_increasing_limit, |err| { self.note_obligation_cause_code( + obligation.cause.body_id, err, predicate, obligation.param_env, @@ -575,7 +575,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { Limit(0) => Limit(2), limit => limit * 2, }; - err.help(&format!( + err.help(format!( "consider increasing the recursion limit by adding a \ `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)", suggested_limit, @@ -737,7 +737,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if is_try_conversion && let Some(ret_span) = self.return_type_span(&obligation) { err.span_label( ret_span, - &format!( + format!( "expected `{}` because of this", trait_ref.skip_binder().self_ty() ), @@ -780,7 +780,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.emit(); return; } - if let Some(ref s) = label { + if let Some(s) = label { // If it has a custom `#[rustc_on_unimplemented]` // error message, let's display it as the label! err.span_label(span, s); @@ -788,7 +788,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // When the self type is a type param We don't need to "the trait // `std::marker::Sized` is not implemented for `T`" as we will point // at the type param with a label to suggest constraining it. - err.help(&explanation); + err.help(explanation); } } else if let Some(custom_explanation) = safe_transmute_explanation { err.span_label(span, custom_explanation); @@ -811,13 +811,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); if let Some((msg, span)) = type_def { - err.span_label(span, &msg); + err.span_label(span, msg); } - if let Some(ref s) = note { + if let Some(s) = note { // If it has a custom `#[rustc_on_unimplemented]` note, let's display it - err.note(s.as_str()); + err.note(s); } - if let Some(ref s) = parent_label { + if let Some(s) = parent_label { let body = obligation.cause.body_id; err.span_label(tcx.def_span(body), s); } @@ -1028,7 +1028,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // which bounds actually failed to hold. self.tcx.sess.struct_span_err( span, - &format!("the type `{}` is not well-formed", ty), + format!("the type `{}` is not well-formed", ty), ) } } @@ -1071,7 +1071,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { let mut diag = self.tcx.sess.struct_span_err( span, - &format!("the constant `{}` is not of type `{}`", ct, ty), + format!("the constant `{}` is not of type `{}`", ct, ty), ); self.note_type_err( &mut diag, @@ -1431,6 +1431,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::ExprItemObligation(..) = code { self.note_obligation_cause_code( + error.obligation.cause.body_id, &mut diag, error.obligation.predicate, error.obligation.param_env, @@ -1835,7 +1836,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { candidates.sort(); candidates.dedup(); let end = if candidates.len() <= 9 { candidates.len() } else { 8 }; - err.help(&format!( + err.help(format!( "the following {other}types implement trait `{}`:{}{}", trait_ref.print_only_trait_path(), candidates[..end].join(""), @@ -2026,7 +2027,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "perhaps two different versions of crate `{}` are being used?", trait_crate ); - err.note(&crate_msg); + err.note(crate_msg); suggested = true; } suggested @@ -2158,7 +2159,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.cancel(); return; } - err.note(&format!("cannot satisfy `{}`", predicate)); + err.note(format!("cannot satisfy `{}`", predicate)); let impl_candidates = self.find_similar_impl_candidates( predicate.to_opt_poly_trait_pred().unwrap(), ); @@ -2178,7 +2179,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.cancel(); return; } - err.note(&format!("cannot satisfy `{}`", predicate)); + err.note(format!("cannot satisfy `{}`", predicate)); } } @@ -2223,9 +2224,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.cancel(); err = self.tcx.sess.struct_span_err_with_code( span, - &format!( + format!( "cannot {verb} associated {noun} on trait without specifying the corresponding `impl` type", - ), + ), rustc_errors::error_code!(E0790), ); @@ -2332,7 +2333,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ErrorCode::E0284, true, ); - err.note(&format!("cannot satisfy `{}`", predicate)); + err.note(format!("cannot satisfy `{}`", predicate)); err } else { // If we can't find a substitution, just print a generic error @@ -2343,7 +2344,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "type annotations needed: cannot satisfy `{}`", predicate, ); - err.span_label(span, &format!("cannot satisfy `{}`", predicate)); + err.span_label(span, format!("cannot satisfy `{}`", predicate)); err } } @@ -2371,7 +2372,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "type annotations needed: cannot satisfy `{}`", predicate, ); - err.span_label(span, &format!("cannot satisfy `{}`", predicate)); + err.span_label(span, format!("cannot satisfy `{}`", predicate)); err } } @@ -2386,7 +2387,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "type annotations needed: cannot satisfy `{}`", predicate, ); - err.span_label(span, &format!("cannot satisfy `{}`", predicate)); + err.span_label(span, format!("cannot satisfy `{}`", predicate)); err } }; @@ -2459,13 +2460,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { match (spans.len(), crates.len(), crate_names.len()) { (0, 0, 0) => { - err.note(&format!("cannot satisfy `{}`", predicate)); + err.note(format!("cannot satisfy `{}`", predicate)); } (0, _, 1) => { - err.note(&format!("{} in the `{}` crate{}", msg, crates[0], post,)); + err.note(format!("{} in the `{}` crate{}", msg, crates[0], post,)); } (0, _, _) => { - err.note(&format!( + err.note(format!( "{} in the following crates: {}{}", msg, crate_names.join(", "), @@ -2474,19 +2475,17 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } (_, 0, 0) => { let span: MultiSpan = spans.into(); - err.span_note(span, &msg); + err.span_note(span, msg); } (_, 1, 1) => { let span: MultiSpan = spans.into(); - err.span_note(span, &msg); - err.note( - &format!("and another `impl` found in the `{}` crate{}", crates[0], post,), - ); + err.span_note(span, msg); + err.note(format!("and another `impl` found in the `{}` crate{}", crates[0], post,)); } _ => { let span: MultiSpan = spans.into(); - err.span_note(span, &msg); - err.note(&format!( + err.span_note(span, msg); + err.note(format!( "and more `impl`s found in the following crates: {}{}", crate_names.join(", "), post, @@ -2546,6 +2545,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // message, and fall back to regular note otherwise. if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { self.note_obligation_cause_code( + obligation.cause.body_id, err, obligation.predicate, obligation.param_env, @@ -2657,7 +2657,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } err.span_help( multispan, - &format!( + format!( "you could relax the implicit `Sized` bound on `{T}` if it were \ used through indirection like `&{T}` or `Box<{T}>`", T = param.name.ident(), @@ -2882,7 +2882,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .fn_trait_kind_from_def_id(trait_ref.def_id()) .expect("expected to map DefId to ClosureKind"); if !implemented_kind.extends(selected_kind) { - err.note(&format!( + err.note(format!( "`{}` implements `{}`, but it must implement `{}`, which is more general", trait_ref.skip_binder().self_ty(), implemented_kind, @@ -2899,7 +2899,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if expected.len() != given.len() { // Note number of types that were expected and given err.note( - &format!( + format!( "expected a closure taking {} argument{}, but one taking {} argument{} was given", given.len(), pluralize!(given.len()), @@ -2942,7 +2942,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { unsatisfied_const = UnsatisfiedConst(true); err.span_note( span, - &format!( + format!( "the trait `{}` is implemented for `{}`, \ but that implementation is not `const`", non_const_predicate.print_modifiers_and_trait_path(), @@ -3171,7 +3171,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut err = self.tcx.sess.struct_span_err(span, "unconstrained generic constant"); let const_span = self.tcx.def_span(uv.def); match self.tcx.sess.source_map().span_to_snippet(const_span) { - Ok(snippet) => err.help(&format!( + Ok(snippet) => err.help(format!( "try adding a `where` bound using this expression: `where [(); {}]:`", snippet )), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 595f6e0b927..53bf38c0a34 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -25,10 +25,9 @@ use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node}; use rustc_hir::{Expr, HirId}; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime}; +use rustc_infer::infer::{DefineOpaqueTypes, InferOk, LateBoundRegionConversionTime}; use rustc_middle::hir::map; use rustc_middle::ty::error::TypeError::{self, Sorts}; -use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{ self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts, @@ -39,9 +38,9 @@ use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP}; use rustc_target::spec::abi; +use std::iter; use std::ops::Deref; -use super::method_chain::CollectAllMismatches; use super::InferCtxtPrivExt; use crate::infer::InferCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; @@ -319,6 +318,7 @@ pub trait TypeErrCtxtExt<'tcx> { fn note_obligation_cause_code<T>( &self, + body_id: LocalDefId, err: &mut Diagnostic, predicate: T, param_env: ty::ParamEnv<'tcx>, @@ -359,8 +359,9 @@ pub trait TypeErrCtxtExt<'tcx> { ); fn note_function_argument_obligation( &self, - arg_hir_id: HirId, + body_id: LocalDefId, err: &mut Diagnostic, + arg_hir_id: HirId, parent_code: &ObligationCauseCode<'tcx>, param_env: ty::ParamEnv<'tcx>, predicate: ty::Predicate<'tcx>, @@ -515,7 +516,7 @@ fn suggest_restriction<'tcx>( err.span_suggestion_verbose( sp, - &format!("consider further restricting {}", msg), + format!("consider further restricting {}", msg), suggestion, Applicability::MachineApplicable, ); @@ -530,6 +531,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { associated_ty: Option<(&'static str, Ty<'tcx>)>, mut body_id: LocalDefId, ) { + if trait_pred.skip_binder().polarity == ty::ImplPolarity::Negative { + return; + } + let trait_pred = self.resolve_numeric_literals_with_default(trait_pred); let self_ty = trait_pred.skip_binder().self_ty(); @@ -964,7 +969,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // a more general note. err.span_suggestion_verbose( obligation.cause.span.shrink_to_hi(), - &msg, + msg, format!("({args})"), Applicability::HasPlaceholders, ); @@ -994,7 +999,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } _ => return false, }; - err.help(&format!("{msg}: `{name}({args})`")); + err.help(format!("{msg}: `{name}({args})`")); } true } @@ -1334,7 +1339,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let msg = format!("the trait bound `{}` is not satisfied", old_pred); if has_custom_message { - err.note(&msg); + err.note(msg); } else { err.message = vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)]; @@ -1358,7 +1363,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } else { let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; let sugg_prefix = format!("&{}", if is_mut { "mut " } else { "" }); - let sugg_msg = &format!( + let sugg_msg = format!( "consider{} borrowing here", if is_mut { " mutably" } else { "" } ); @@ -1452,7 +1457,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_suggestion( obligation.cause.span.shrink_to_lo(), - &format!( + format!( "consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`" ), "&", @@ -1505,7 +1510,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }; err.multipart_suggestion_verbose( - &msg, + msg, suggestions, Applicability::MachineApplicable, ); @@ -1617,7 +1622,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = obligation.predicate.kind().skip_binder() { - err.span_label(*span, &format!("this call returns `{}`", pred.self_ty())); + err.span_label(*span, format!("this call returns `{}`", pred.self_ty())); } if let Some(typeck_results) = &self.typeck_results && let ty = typeck_results.expr_ty_adjusted(base) @@ -1632,14 +1637,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if vis_span.is_empty() { err.span_suggestion_verbose( span.shrink_to_lo(), - &msg, + msg, "async ", Applicability::MaybeIncorrect, ); } else { err.span_suggestion_verbose( vis_span.shrink_to_hi(), - &msg, + msg, " async", Applicability::MaybeIncorrect, ); @@ -1717,7 +1722,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { Applicability::MachineApplicable, ); } else { - err.note(&format!( + err.note(format!( "`{}` is implemented for `{:?}`, but not for `{:?}`", trait_pred.print_modifiers_and_trait_path(), suggested_ty, @@ -1754,7 +1759,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { err.span_label( expr.span, - &format!( + format!( "this expression has type `{}`, which implements `{}`", ty, trait_pred.print_modifiers_and_trait_path() @@ -1946,7 +1951,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Suggest `-> impl Trait`. err.span_suggestion( ret_ty.span, - &format!( + format!( "use `impl {1}` as the return type, as all return paths are of type `{}`, \ which implements `{1}`", last_ty, trait_obj, @@ -1981,13 +1986,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } else { // This is currently not possible to trigger because E0038 takes precedence, but // leave it in for completeness in case anything changes in an earlier stage. - err.note(&format!( + err.note(format!( "if trait `{}` were object-safe, you could return a trait object", trait_obj, )); } err.note(trait_obj_msg); - err.note(&format!( + err.note(format!( "if all the returned values were of the same type you could use `impl {}` as the \ return type", trait_obj, @@ -2027,7 +2032,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } else { err.span_label( expr.span, - &format!("this returned value is of type `{}`", ty), + format!("this returned value is of type `{}`", ty), ); } } @@ -2177,7 +2182,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) { if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) { if let ty::AssocKind::Const | ty::AssocKind::Type = assoc_item.kind { - err.note(&format!( + err.note(format!( "{}s cannot be accessed directly on a `trait`, they can only be \ accessed through a specific `impl`", self.tcx.def_kind_descr(assoc_item.kind.as_def_kind(), item_def_id) @@ -2607,7 +2612,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } err.span_note( span, - &format!( + format!( "{} {} as this value is used across {}", future_or_generator, trait_explanation, an_await_or_yield ), @@ -2628,7 +2633,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); err.span_note( span, - &format!( + format!( "future {not_trait} as it awaits another future which {not_trait}", not_trait = trait_explanation ), @@ -2730,7 +2735,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut span = MultiSpan::from_span(upvar_span); span.push_span_label(upvar_span, span_label); - err.span_note(span, &span_note); + err.span_note(span, span_note); } } @@ -2738,6 +2743,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // bound that introduced the obligation (e.g. `T: Send`). debug!(?next_code); self.note_obligation_cause_code( + obligation.cause.body_id, err, obligation.predicate, obligation.param_env, @@ -2749,6 +2755,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn note_obligation_cause_code<T>( &self, + body_id: LocalDefId, err: &mut Diagnostic, predicate: T, param_env: ty::ParamEnv<'tcx>, @@ -2786,7 +2793,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::LetElse | ObligationCauseCode::BinOp { .. } | ObligationCauseCode::AscribeUserTypeProvePredicate(..) - | ObligationCauseCode::RustCall => {} + | ObligationCauseCode::RustCall + | ObligationCauseCode::DropImpl => {} ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); } @@ -2794,15 +2802,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.note("only the last element of a tuple may have a dynamically sized type"); } ObligationCauseCode::ProjectionWf(data) => { - err.note(&format!("required so that the projection `{data}` is well-formed")); + err.note(format!("required so that the projection `{data}` is well-formed")); } ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => { - err.note(&format!( + err.note(format!( "required so that reference `{ref_ty}` does not outlive its referent" )); } ObligationCauseCode::ObjectTypeBound(object_ty, region) => { - err.note(&format!( + err.note(format!( "required so that the lifetime bound of `{}` for `{}` is satisfied", region, object_ty, )); @@ -2838,9 +2846,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if span.is_visible(sm) { let msg = format!("required by this bound in `{short_item_name}`"); multispan.push_span_label(span, msg); - err.span_note(multispan, &descr); + err.span_note(multispan, descr); } else { - err.span_note(tcx.def_span(item_def_id), &descr); + err.span_note(tcx.def_span(item_def_id), descr); } } ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => { @@ -2848,24 +2856,24 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty)); let (object_ty, object_file) = self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty)); - err.note(&with_forced_trimmed_paths!(format!( + err.note(with_forced_trimmed_paths!(format!( "required for the cast from `{concrete_ty}` to the object type `{object_ty}`", ))); if let Some(file) = concrete_file { - err.note(&format!( + err.note(format!( "the full name for the casted type has been written to '{}'", file.display(), )); } if let Some(file) = object_file { - err.note(&format!( + err.note(format!( "the full name for the object type has been written to '{}'", file.display(), )); } } ObligationCauseCode::Coercion { source: _, target } => { - err.note(&format!("required by cast to type `{}`", self.ty_to_string(target))); + err.note(format!("required by cast to type `{}`", self.ty_to_string(target))); } ObligationCauseCode::RepeatElementCopy { is_const_fn } => { err.note( @@ -3068,8 +3076,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { )); match ty.kind() { ty::Adt(def, _) => match self.tcx.opt_item_ident(def.did()) { - Some(ident) => err.span_note(ident.span, &msg), - None => err.note(&msg), + Some(ident) => err.span_note(ident.span, msg), + None => err.note(msg), }, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { // If the previous type is async fn, this is the future generated by the body of an async function. @@ -3090,7 +3098,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { break 'print; } - err.span_note(self.tcx.def_span(def_id), &msg) + err.span_note(self.tcx.def_span(def_id), msg) } ty::GeneratorWitness(bound_tys) => { use std::fmt::Write; @@ -3126,7 +3134,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let kind = tcx.generator_kind(def_id).unwrap().descr(); err.span_note( sp, - with_forced_trimmed_paths!(&format!( + with_forced_trimmed_paths!(format!( "required because it's used within this {kind}", )), ) @@ -3136,7 +3144,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "required because it's used within this closure", ), ty::Str => err.note("`str` is considered to contain a `[u8]` slice for auto trait purposes"), - _ => err.note(&msg), + _ => err.note(msg), }; } } @@ -3148,6 +3156,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // #74711: avoid a stack overflow ensure_sufficient_stack(|| { self.note_obligation_cause_code( + body_id, err, parent_predicate, param_env, @@ -3159,6 +3168,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } else { ensure_sufficient_stack(|| { self.note_obligation_cause_code( + body_id, err, parent_predicate, param_env, @@ -3190,7 +3200,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // FIXME: we should do something else so that it works even on crate foreign // auto traits. is_auto_trait = matches!(is_auto, hir::IsAuto::Yes); - err.span_note(ident.span, &msg); + err.span_note(ident.span, msg); } Some(Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }), @@ -3219,15 +3229,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "unsatisfied trait bound introduced here", ); } - err.span_note(spans, &msg); + err.span_note(spans, msg); } _ => { - err.note(&msg); + err.note(msg); } }; if let Some(file) = file { - err.note(&format!( + err.note(format!( "the full type name has been written to '{}'", file.display(), )); @@ -3267,19 +3277,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { parent_trait_pred = child_trait_pred; } if count > 0 { - err.note(&format!( + err.note(format!( "{} redundant requirement{} hidden", count, pluralize!(count) )); let (self_ty, file) = self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty()); - err.note(&format!( + err.note(format!( "required for `{self_ty}` to implement `{}`", parent_trait_pred.print_modifiers_and_trait_path() )); if let Some(file) = file { - err.note(&format!( + err.note(format!( "the full type name has been written to '{}'", file.display(), )); @@ -3288,6 +3298,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // #74711: avoid a stack overflow ensure_sufficient_stack(|| { self.note_obligation_cause_code( + body_id, err, parent_predicate, param_env, @@ -3303,6 +3314,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // #74711: avoid a stack overflow ensure_sufficient_stack(|| { self.note_obligation_cause_code( + body_id, err, parent_predicate, param_env, @@ -3319,8 +3331,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .. } => { self.note_function_argument_obligation( - arg_hir_id, + body_id, err, + arg_hir_id, parent_code, param_env, predicate, @@ -3328,6 +3341,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); ensure_sufficient_stack(|| { self.note_obligation_cause_code( + body_id, err, predicate, param_env, @@ -3360,7 +3374,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { assoc_span.push_span_label(ident.span, "in this trait"); } - err.span_note(assoc_span, &msg); + err.span_note(assoc_span, msg); } ObligationCauseCode::TrivialBound => { err.help("see issue #48214"); @@ -3498,7 +3512,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { _ => None, }; let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { - trait_ref: self.tcx.mk_trait_ref( + trait_ref: ty::TraitRef::new(self.tcx, trait_pred.def_id(), [field_ty].into_iter().chain(trait_substs), ), @@ -3516,7 +3530,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if can_derive { err.span_suggestion_verbose( self.tcx.def_span(adt.did()).shrink_to_lo(), - &format!( + format!( "consider annotating `{}` with `#[derive({})]`", trait_pred.skip_binder().self_ty(), diagnostic_name, @@ -3549,8 +3563,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } fn note_function_argument_obligation( &self, - arg_hir_id: HirId, + body_id: LocalDefId, err: &mut Diagnostic, + arg_hir_id: HirId, parent_code: &ObligationCauseCode<'tcx>, param_env: ty::ParamEnv<'tcx>, failed_pred: ty::Predicate<'tcx>, @@ -3583,7 +3598,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // to an associated type (as seen from `trait_pred`) in the predicate. Like in // trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>` let mut type_diffs = vec![]; - if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code.deref() && let Some(node_substs) = typeck_results.node_substs_opt(call_hir_id) && let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_substs) @@ -3592,14 +3606,26 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(where_pred) = where_pred.to_opt_poly_trait_pred() && let Some(failed_pred) = failed_pred.to_opt_poly_trait_pred() { - let mut c = CollectAllMismatches { - infcx: self.infcx, - param_env, - errors: vec![], + let where_pred = self.instantiate_binder_with_placeholders(where_pred); + let failed_pred = self.instantiate_binder_with_fresh_vars( + expr.span, + LateBoundRegionConversionTime::FnCall, + failed_pred + ); + + let zipped = + iter::zip(where_pred.trait_ref.substs, failed_pred.trait_ref.substs); + for (expected, actual) in zipped { + self.probe(|_| { + match self + .at(&ObligationCause::misc(expr.span, body_id), param_env) + .eq(DefineOpaqueTypes::No, expected, actual) + { + Ok(_) => (), // We ignore nested obligations here for now. + Err(err) => type_diffs.push(err), + } + }) }; - if let Ok(_) = c.relate(where_pred, failed_pred) { - type_diffs = c.errors; - } } else if let Some(where_pred) = where_pred.to_opt_poly_projection_pred() && let Some(failed_pred) = failed_pred.to_opt_poly_projection_pred() && let Some(found) = failed_pred.skip_binder().term.ty() @@ -3903,7 +3929,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .map(|trait_ref| trait_ref.trait_ref.self_ty()) .find(|t| is_slice(*t)) { - let msg = &format!("convert the array to a `{}` slice instead", slice_ty); + let msg = format!("convert the array to a `{}` slice instead", slice_ty); if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { let mut suggestions = vec![]; @@ -4124,7 +4150,7 @@ fn suggest_trait_object_return_type_alternatives( ) { err.span_suggestion( ret_ty, - &format!( + format!( "use `impl {}` as the return type if all return paths have the same type but you \ want to expose only the trait in the signature", trait_obj, @@ -4134,7 +4160,7 @@ fn suggest_trait_object_return_type_alternatives( ); if is_object_safe { err.multipart_suggestion( - &format!( + format!( "use a boxed trait object if all return paths implement trait `{}`", trait_obj, ), diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 63949843aed..2210ef975e6 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -2,13 +2,14 @@ use crate::traits::{self, ObligationCause, ObligationCtxt}; +use hir::LangItem; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::query::NoSolution; use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError}; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, AdtDef, GenericArg, List, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::DUMMY_SP; use super::outlives_bounds::InferCtxtExt; @@ -19,6 +20,11 @@ pub enum CopyImplementationError<'tcx> { HasDestructor, } +pub enum ConstParamTyImplementationError<'tcx> { + InfrigingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>), + NotAnAdtOrBuiltinAllowed, +} + pub enum InfringingFieldsReason<'tcx> { Fulfill(Vec<FulfillmentError<'tcx>>), Regions(Vec<RegionResolutionError<'tcx>>), @@ -27,7 +33,10 @@ pub enum InfringingFieldsReason<'tcx> { /// Checks that the fields of the type (an ADT) all implement copy. /// /// If fields don't implement copy, return an error containing a list of -/// those violating fields. If it's not an ADT, returns `Err(NotAnAdt)`. +/// those violating fields. +/// +/// If it's not an ADT, int ty, `bool`, float ty, `char`, raw pointer, `!`, +/// a reference or an array returns `Err(NotAnAdt)`. pub fn type_allowed_to_implement_copy<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -47,12 +56,82 @@ pub fn type_allowed_to_implement_copy<'tcx>( | ty::Ref(_, _, hir::Mutability::Not) | ty::Array(..) => return Ok(()), - ty::Adt(adt, substs) => (adt, substs), + &ty::Adt(adt, substs) => (adt, substs), _ => return Err(CopyImplementationError::NotAnAdt), }; - let copy_def_id = tcx.require_lang_item(hir::LangItem::Copy, Some(parent_cause.span)); + all_fields_implement_trait( + tcx, + param_env, + self_type, + adt, + substs, + parent_cause, + hir::LangItem::Copy, + ) + .map_err(CopyImplementationError::InfringingFields)?; + + if adt.has_dtor(tcx) { + return Err(CopyImplementationError::HasDestructor); + } + + Ok(()) +} + +/// Checks that the fields of the type (an ADT) all implement `ConstParamTy`. +/// +/// If fields don't implement `ConstParamTy`, return an error containing a list of +/// those violating fields. +/// +/// If it's not an ADT, int ty, `bool` or `char`, returns `Err(NotAnAdtOrBuiltinAllowed)`. +pub fn type_allowed_to_implement_const_param_ty<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + self_type: Ty<'tcx>, + parent_cause: ObligationCause<'tcx>, +) -> Result<(), ConstParamTyImplementationError<'tcx>> { + let (adt, substs) = match self_type.kind() { + // `core` provides these impls. + ty::Uint(_) + | ty::Int(_) + | ty::Bool + | ty::Char + | ty::Str + | ty::Array(..) + | ty::Slice(_) + | ty::Ref(.., hir::Mutability::Not) => return Ok(()), + + &ty::Adt(adt, substs) => (adt, substs), + + _ => return Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed), + }; + + all_fields_implement_trait( + tcx, + param_env, + self_type, + adt, + substs, + parent_cause, + hir::LangItem::ConstParamTy, + ) + .map_err(ConstParamTyImplementationError::InfrigingFields)?; + + Ok(()) +} + +/// Check that all fields of a given `adt` implement `lang_item` trait. +pub fn all_fields_implement_trait<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + self_type: Ty<'tcx>, + adt: AdtDef<'tcx>, + substs: &'tcx List<GenericArg<'tcx>>, + parent_cause: ObligationCause<'tcx>, + lang_item: LangItem, +) -> Result<(), Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>> { + let trait_def_id = tcx.require_lang_item(lang_item, Some(parent_cause.span)); let mut infringing = Vec::new(); for variant in adt.variants() { @@ -93,7 +172,7 @@ pub fn type_allowed_to_implement_copy<'tcx>( // between expected and found const-generic types. Don't report an // additional copy error here, since it's not typically useful. if !normalization_errors.is_empty() || ty.references_error() { - tcx.sess.delay_span_bug(field_span, format!("couldn't normalize struct field `{unnormalized_ty}` when checking Copy implementation")); + tcx.sess.delay_span_bug(field_span, format!("couldn't normalize struct field `{unnormalized_ty}` when checking {tr} implementation", tr = tcx.def_path_str(trait_def_id))); continue; } @@ -101,7 +180,7 @@ pub fn type_allowed_to_implement_copy<'tcx>( ObligationCause::dummy_with_span(field_ty_span), param_env, ty, - copy_def_id, + trait_def_id, ); let errors = ocx.select_all_or_error(); if !errors.is_empty() { @@ -124,15 +203,7 @@ pub fn type_allowed_to_implement_copy<'tcx>( } } - if !infringing.is_empty() { - return Err(CopyImplementationError::InfringingFields(infringing)); - } - - if adt.has_dtor(tcx) { - return Err(CopyImplementationError::HasDestructor); - } - - Ok(()) + if infringing.is_empty() { Ok(()) } else { Err(infringing) } } pub fn check_tys_might_be_eq<'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 0e8c74a6765..d8e5725d3ca 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -62,7 +62,7 @@ pub use self::util::elaborate; pub use self::util::{expand_trait_aliases, TraitAliasExpander}; pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices}; pub use self::util::{ - supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_type, + supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_item, SupertraitDefIds, }; @@ -127,7 +127,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( ty: Ty<'tcx>, def_id: DefId, ) -> bool { - let trait_ref = ty::Binder::dummy(infcx.tcx.mk_trait_ref(def_id, [ty])); + let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]); pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const()) } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 73e2efc3b00..06d9c10386e 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -279,7 +279,7 @@ fn predicates_reference_self( trait_def_id: DefId, supertraits_only: bool, ) -> SmallVec<[Span; 1]> { - let trait_ref = ty::TraitRef::identity(tcx, trait_def_id); + let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); let predicates = if supertraits_only { tcx.super_predicates_of(trait_def_id) } else { @@ -525,7 +525,7 @@ fn virtual_call_violation_for_method<'tcx>( // #78372 tcx.sess.delay_span_bug( tcx.def_span(method.def_id), - &format!("error: {}\n while computing layout for type {:?}", err, ty), + format!("error: {}\n while computing layout for type {:?}", err, ty), ); None } @@ -541,7 +541,7 @@ fn virtual_call_violation_for_method<'tcx>( abi => { tcx.sess.delay_span_bug( tcx.def_span(method.def_id), - &format!( + format!( "receiver when `Self = ()` should have a Scalar ABI; found {:?}", abi ), @@ -560,7 +560,7 @@ fn virtual_call_violation_for_method<'tcx>( abi => { tcx.sess.delay_span_bug( tcx.def_span(method.def_id), - &format!( + format!( "receiver when `Self = {}` should have a ScalarPair ABI; found {:?}", trait_object_ty, abi ), @@ -661,9 +661,9 @@ fn object_ty_for_trait<'tcx>( let trait_ref = ty::TraitRef::identity(tcx, trait_def_id); debug!(?trait_ref); - let trait_predicate = trait_ref.map_bound(|trait_ref| { - ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)) - }); + let trait_predicate = ty::Binder::dummy(ty::ExistentialPredicate::Trait( + ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref), + )); debug!(?trait_predicate); let pred: ty::Predicate<'tcx> = trait_ref.to_predicate(tcx); @@ -769,11 +769,10 @@ fn receiver_is_dispatchable<'tcx>( let param_env = tcx.param_env(method.def_id); // Self: Unsize<U> - let unsize_predicate = ty::Binder::dummy( - tcx.mk_trait_ref(unsize_did, [tcx.types.self_param, unsized_self_ty]), - ) - .without_const() - .to_predicate(tcx); + let unsize_predicate = + ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]) + .without_const() + .to_predicate(tcx); // U: Trait<Arg1, ..., ArgN> let trait_predicate = { @@ -782,7 +781,7 @@ fn receiver_is_dispatchable<'tcx>( if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) } }); - ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, substs)).to_predicate(tcx) + ty::TraitRef::new(tcx, trait_def_id, substs).to_predicate(tcx) }; let caller_bounds = @@ -797,9 +796,8 @@ fn receiver_is_dispatchable<'tcx>( // Receiver: DispatchFromDyn<Receiver[Self => U]> let obligation = { - let predicate = ty::Binder::dummy( - tcx.mk_trait_ref(dispatch_from_dyn_did, [receiver_ty, unsized_receiver_ty]), - ); + let predicate = + ty::TraitRef::new(tcx, dispatch_from_dyn_did, [receiver_ty, unsized_receiver_ty]); Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate) }; @@ -882,7 +880,8 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>( // Compute supertraits of current trait lazily. if self.supertraits.is_none() { - let trait_ref = ty::TraitRef::identity(self.tcx, self.trait_def_id); + let trait_ref = + ty::Binder::dummy(ty::TraitRef::identity(self.tcx, self.trait_def_id)); self.supertraits = Some( traits::supertraits(self.tcx, trait_ref).map(|t| t.def_id()).collect(), ); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index ea45412e47f..8c74860cdf3 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1319,7 +1319,7 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>( let trait_substs = obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id)); // FIXME(named-returns): Binders - let trait_predicate = ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, trait_substs)); + let trait_predicate = ty::TraitRef::new(tcx, trait_def_id, trait_substs); let _ = selcx.infcx.commit_if_ok(|_| { match selcx.select(&obligation.with(tcx, trait_predicate)) { @@ -1682,10 +1682,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( if selcx.infcx.predicate_must_hold_modulo_regions( &obligation.with( selcx.tcx(), - ty::Binder::dummy( - selcx.tcx().at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]), - ) - .without_const(), + ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]) + .without_const(), ), ) => { @@ -1749,7 +1747,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // These traits have no associated types. selcx.tcx().sess.delay_span_bug( obligation.cause.span, - &format!("Cannot project an associated type from `{:?}`", impl_source), + format!("Cannot project an associated type from `{:?}`", impl_source), ); return Err(()); } @@ -1948,8 +1946,11 @@ fn confirm_builtin_candidate<'cx, 'tcx>( ) }); if check_is_sized { - let sized_predicate = ty::Binder::dummy( - tcx.at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]), + let sized_predicate = ty::TraitRef::from_lang_item( + tcx, + LangItem::Sized, + obligation.cause.span(), + [self_ty], ) .without_const(); obligations.push(obligation.with(tcx, sized_predicate)); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 8f1b05c1190..1f8e756043d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -79,7 +79,7 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>( if !errors.is_empty() { infcx.tcx.sess.diagnostic().delay_span_bug( DUMMY_SP, - &format!("errors selecting obligation during MIR typeck: {:?}", errors), + format!("errors selecting obligation during MIR typeck: {:?}", errors), ); } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 1db9b8ce92e..33f502f8182 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -57,6 +57,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if obligation.polarity() == ty::ImplPolarity::Negative { self.assemble_candidates_for_trait_alias(obligation, &mut candidates); self.assemble_candidates_from_impls(obligation, &mut candidates); + self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?; } else { self.assemble_candidates_for_trait_alias(obligation, &mut candidates); @@ -187,6 +188,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Keep only those bounds which may apply, and propagate overflow if it occurs. for bound in matching_bounds { + if bound.skip_binder().polarity != stack.obligation.predicate.skip_binder().polarity { + continue; + } + // FIXME(oli-obk): it is suspicious that we are dropping the constness and // polarity here. let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?; @@ -454,7 +459,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, self.tcx().mk_predicate(obligation.predicate.map_bound(|mut pred| { pred.trait_ref = - self.tcx().mk_trait_ref(fn_ptr_trait, [pred.trait_ref.self_ty()]); + ty::TraitRef::new(self.tcx(), fn_ptr_trait, [pred.trait_ref.self_ty()]); ty::PredicateKind::Clause(ty::Clause::Trait(pred)) })), ); @@ -629,7 +634,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // <ty as Deref> - let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]); + let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]); let obligation = traits::Obligation::new(tcx, cause.clone(), param_env, ty::Binder::dummy(trait_ref)); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3bba11262f5..422285d9474 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -646,8 +646,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { output_ty, &mut nested, ); - let tr = - ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref(LangItem::Sized, [output_ty])); + let tr = ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [output_ty]); nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr)); Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested }) @@ -1050,8 +1049,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); // We can only make objects from sized types. - let tr = - ty::Binder::dummy(tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [source])); + let tr = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, cause.span, [source]); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); // If the type is `Foo + 'a`, ensure that the type @@ -1121,7 +1119,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Construct the nested `TailField<T>: Unsize<TailField<U>>` predicate. let tail_unsize_obligation = obligation.with( tcx, - tcx.mk_trait_ref(obligation.predicate.def_id(), [source_tail, target_tail]), + ty::TraitRef::new( + tcx, + obligation.predicate.def_id(), + [source_tail, target_tail], + ), ); nested.push(tail_unsize_obligation); } @@ -1146,8 +1148,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { nested.extend(obligations); // Add a nested `T: Unsize<U>` predicate. - let last_unsize_obligation = obligation - .with(tcx, tcx.mk_trait_ref(obligation.predicate.def_id(), [a_last, b_last])); + let last_unsize_obligation = obligation.with( + tcx, + ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]), + ); nested.push(last_unsize_obligation); } @@ -1271,10 +1275,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.clone(), obligation.recursion_depth + 1, self_ty.rebind(ty::TraitPredicate { - trait_ref: self - .tcx() - .at(cause.span) - .mk_trait_ref(LangItem::Destruct, [nested_ty]), + trait_ref: ty::TraitRef::from_lang_item( + self.tcx(), + LangItem::Destruct, + cause.span, + [nested_ty], + ), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }), @@ -1295,10 +1301,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // or it's an ADT (and we need to check for a custom impl during selection) _ => { let predicate = self_ty.rebind(ty::TraitPredicate { - trait_ref: self - .tcx() - .at(cause.span) - .mk_trait_ref(LangItem::Destruct, [nested_ty]), + trait_ref: ty::TraitRef::from_lang_item( + self.tcx(), + LangItem::Destruct, + cause.span, + [nested_ty], + ), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 863553670de..246d3ea2ef2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -67,7 +67,7 @@ impl IntercrateAmbiguityCause { /// Emits notes when the overlap is caused by complex intercrate ambiguities. /// See #23980 for details. pub fn add_intercrate_ambiguity_hint(&self, err: &mut Diagnostic) { - err.note(&self.intercrate_ambiguity_hint()); + err.note(self.intercrate_ambiguity_hint()); } pub fn intercrate_ambiguity_hint(&self) -> String { @@ -2413,7 +2413,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { self.tcx(), cause.clone(), param_env, - self.tcx().mk_trait_ref(trait_def_id, [normalized_ty]), + ty::TraitRef::new(self.tcx(), trait_def_id, [normalized_ty]), ); obligations.push(obligation); obligations @@ -2449,7 +2449,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // for a variable being generalized... let guar = self.infcx.tcx.sess.delay_span_bug( obligation.cause.span, - &format!( + format!( "Impl {:?} was matchable against {:?} but now is not", impl_def_id, obligation ), diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 8546bbe52dc..233d35aed38 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -373,7 +373,7 @@ fn report_conflicting_impls<'tcx>( } None => format!("conflicting implementation in crate `{}`", cname), }; - err.note(&msg); + err.note(msg); } } diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 7792ceabe7e..7b7e297c64b 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -262,7 +262,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => tcx.mk_tup(sig.skip_binder().inputs()), }; - let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]); + let trait_ref = ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty, arguments_tuple]); sig.map_bound(|sig| (trait_ref, sig.output())) } @@ -273,7 +273,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>( sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { assert!(!self_ty.has_escaping_bound_vars()); - let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]); + let trait_ref = ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]); sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty)) } @@ -284,7 +284,7 @@ pub fn future_trait_ref_and_outputs<'tcx>( sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> { assert!(!self_ty.has_escaping_bound_vars()); - let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty]); + let trait_ref = ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty]); sig.map_bound(|sig| (trait_ref, sig.return_ty)) } diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index c56e7c7cadd..f7a3126b4aa 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -359,7 +359,7 @@ pub(crate) fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( // this has been typecked-before, so diagnostics is not really needed. let unsize_trait_did = tcx.require_lang_item(LangItem::Unsize, None); - let trait_ref = tcx.mk_trait_ref(unsize_trait_did, [source, target]); + let trait_ref = ty::TraitRef::new(tcx, unsize_trait_did, [source, target]); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) { Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 40e19abc0d0..22710c7c059 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -328,6 +328,13 @@ impl<'tcx> WfPredicates<'tcx> { let tcx = self.tcx; let trait_ref = &trait_pred.trait_ref; + // Negative trait predicates don't require supertraits to hold, just + // that their substs are WF. + if trait_pred.polarity == ty::ImplPolarity::Negative { + self.compute_negative_trait_pred(trait_ref); + return; + } + // if the trait predicate is not const, the wf obligations should not be const as well. let obligations = if trait_pred.constness == ty::BoundConstness::NotConst { self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs) @@ -393,6 +400,14 @@ impl<'tcx> WfPredicates<'tcx> { ); } + // Compute the obligations that are required for `trait_ref` to be WF, + // given that it is a *negative* trait predicate. + fn compute_negative_trait_pred(&mut self, trait_ref: &ty::TraitRef<'tcx>) { + for arg in trait_ref.substs { + self.compute(arg); + } + } + /// Pushes the obligations required for `trait_ref::Item` to be WF /// into `self.out`. fn compute_projection(&mut self, data: ty::AliasTy<'tcx>) { @@ -448,7 +463,8 @@ impl<'tcx> WfPredicates<'tcx> { fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { if !subty.has_escaping_bound_vars() { let cause = self.cause(cause); - let trait_ref = self.tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [subty]); + let trait_ref = + ty::TraitRef::from_lang_item(self.tcx, LangItem::Sized, cause.span, [subty]); self.out.push(traits::Obligation::with_depth( self.tcx, cause, diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 58117c46f04..fcdffc7468b 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -190,7 +190,7 @@ fn dtorck_constraint_for_ty<'tcx>( tcx.sess.delay_span_bug( span, - &format!("upvar_tys for closure not found. Expected capture information for closure {ty}",), + format!("upvar_tys for closure not found. Expected capture information for closure {ty}",), ); return Err(NoSolution); } @@ -232,7 +232,7 @@ fn dtorck_constraint_for_ty<'tcx>( // be fully resolved. tcx.sess.delay_span_bug( span, - &format!("upvar_tys for generator not found. Expected capture information for generator {ty}",), + format!("upvar_tys for generator not found. Expected capture information for generator {ty}",), ); return Err(NoSolution); } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 64586a6782b..ec577072e19 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -27,8 +27,7 @@ fn resolve_instance<'tcx>( ) } else { let ty = tcx.type_of(def); - let item_type = - tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder()); + let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty); let def = match *item_type.kind() { ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => { @@ -85,7 +84,7 @@ fn resolve_associated_item<'tcx>( Err(CodegenObligationError::Ambiguity) => { let reported = tcx.sess.delay_span_bug( tcx.def_span(trait_item_id), - &format!( + format!( "encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \ overflow or prior type error", ), @@ -177,15 +176,55 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, substs)) } - traits::ImplSource::Generator(generator_data) => Some(Instance { - def: ty::InstanceDef::Item(generator_data.generator_def_id), - substs: generator_data.substs, - }), - traits::ImplSource::Future(future_data) => Some(Instance { - def: ty::InstanceDef::Item(future_data.generator_def_id), - substs: future_data.substs, - }), + traits::ImplSource::Generator(generator_data) => { + if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume { + // For compiler developers who'd like to add new items to `Generator`, + // you either need to generate a shim body, or perhaps return + // `InstanceDef::Item` pointing to a trait default method body if + // it is given a default implementation by the trait. + span_bug!( + tcx.def_span(generator_data.generator_def_id), + "no definition for `{trait_ref}::{}` for built-in generator type", + tcx.item_name(trait_item_id) + ) + } + Some(Instance { + def: ty::InstanceDef::Item(generator_data.generator_def_id), + substs: generator_data.substs, + }) + } + traits::ImplSource::Future(future_data) => { + if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::poll { + // For compiler developers who'd like to add new items to `Future`, + // you either need to generate a shim body, or perhaps return + // `InstanceDef::Item` pointing to a trait default method body if + // it is given a default implementation by the trait. + span_bug!( + tcx.def_span(future_data.generator_def_id), + "no definition for `{trait_ref}::{}` for built-in async generator type", + tcx.item_name(trait_item_id) + ) + } + Some(Instance { + def: ty::InstanceDef::Item(future_data.generator_def_id), + substs: future_data.substs, + }) + } traits::ImplSource::Closure(closure_data) => { + if cfg!(debug_assertions) + && ![sym::call, sym::call_mut, sym::call_once] + .contains(&tcx.item_name(trait_item_id)) + { + // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`, + // you either need to generate a shim body, or perhaps return + // `InstanceDef::Item` pointing to a trait default method body if + // it is given a default implementation by the trait. + span_bug!( + tcx.def_span(closure_data.closure_def_id), + "no definition for `{trait_ref}::{}` for built-in closure type", + tcx.item_name(trait_item_id) + ) + } let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap(); Instance::resolve_closure( tcx, @@ -195,11 +234,29 @@ fn resolve_associated_item<'tcx>( ) } traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() { - ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty), - substs: rcvr_substs, - }), - _ => None, + ty::FnDef(..) | ty::FnPtr(..) => { + if cfg!(debug_assertions) + && ![sym::call, sym::call_mut, sym::call_once] + .contains(&tcx.item_name(trait_item_id)) + { + // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`, + // you either need to generate a shim body, or perhaps return + // `InstanceDef::Item` pointing to a trait default method body if + // it is given a default implementation by the trait. + bug!( + "no definition for `{trait_ref}::{}` for built-in fn type", + tcx.item_name(trait_item_id) + ) + } + Some(Instance { + def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty), + substs: rcvr_substs, + }) + } + _ => bug!( + "no built-in definition for `{trait_ref}::{}` for non-fn type", + tcx.item_name(trait_item_id) + ), }, traits::ImplSource::Object(ref data) => { traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| { diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index ed513cb3c7f..c4a4cda6801 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -4,7 +4,7 @@ use rustc_middle::ty::{ }; use rustc_target::abi::*; -use std::cmp; +use std::assert_matches::assert_matches; /// Enforce some basic invariants on layouts. pub(super) fn sanity_check_layout<'tcx>( @@ -68,21 +68,31 @@ pub(super) fn sanity_check_layout<'tcx>( } fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayout<'tcx>) { + // Verify the ABI mandated alignment and size. + let align = layout.abi.inherent_align(cx).map(|align| align.abi); + let size = layout.abi.inherent_size(cx); + let Some((align, size)) = align.zip(size) else { + assert_matches!( + layout.layout.abi(), + Abi::Uninhabited | Abi::Aggregate { .. }, + "ABI unexpectedly missing alignment and/or size in {layout:#?}" + ); + return + }; + assert_eq!( + layout.layout.align().abi, + align, + "alignment mismatch between ABI and layout in {layout:#?}" + ); + assert_eq!( + layout.layout.size(), + size, + "size mismatch between ABI and layout in {layout:#?}" + ); + + // Verify per-ABI invariants match layout.layout.abi() { - Abi::Scalar(scalar) => { - // No padding in scalars. - let size = scalar.size(cx); - let align = scalar.align(cx).abi; - assert_eq!( - layout.layout.size(), - size, - "size mismatch between ABI and layout in {layout:#?}" - ); - assert_eq!( - layout.layout.align().abi, - align, - "alignment mismatch between ABI and layout in {layout:#?}" - ); + Abi::Scalar(_) => { // Check that this matches the underlying field. let inner = skip_newtypes(cx, layout); assert!( @@ -135,24 +145,6 @@ pub(super) fn sanity_check_layout<'tcx>( } } Abi::ScalarPair(scalar1, scalar2) => { - // Sanity-check scalar pairs. Computing the expected size and alignment is a bit of work. - let size1 = scalar1.size(cx); - let align1 = scalar1.align(cx).abi; - let size2 = scalar2.size(cx); - let align2 = scalar2.align(cx).abi; - let align = cmp::max(align1, align2); - let field2_offset = size1.align_to(align2); - let size = (field2_offset + size2).align_to(align); - assert_eq!( - layout.layout.size(), - size, - "size mismatch between ABI and layout in {layout:#?}" - ); - assert_eq!( - layout.layout.align().abi, - align, - "alignment mismatch between ABI and layout in {layout:#?}", - ); // Check that the underlying pair of fields matches. let inner = skip_newtypes(cx, layout); assert!( @@ -189,8 +181,9 @@ pub(super) fn sanity_check_layout<'tcx>( "`ScalarPair` layout for type with less than two non-ZST fields: {inner:#?}" ) }); - assert!( - fields.next().is_none(), + assert_matches!( + fields.next(), + None, "`ScalarPair` layout for type with at least three non-ZST fields: {inner:#?}" ); // The fields might be in opposite order. @@ -200,6 +193,10 @@ pub(super) fn sanity_check_layout<'tcx>( (offset2, field2, offset1, field1) }; // The fields should be at the right offset, and match the `scalar` layout. + let size1 = scalar1.size(cx); + let align1 = scalar1.align(cx).abi; + let size2 = scalar2.size(cx); + let align2 = scalar2.align(cx).abi; assert_eq!( offset1, Size::ZERO, @@ -213,10 +210,12 @@ pub(super) fn sanity_check_layout<'tcx>( field1.align.abi, align1, "`ScalarPair` first field with bad align in {inner:#?}", ); - assert!( - matches!(field1.abi, Abi::Scalar(_)), + assert_matches!( + field1.abi, + Abi::Scalar(_), "`ScalarPair` first field with bad ABI in {inner:#?}", ); + let field2_offset = size1.align_to(align2); assert_eq!( offset2, field2_offset, "`ScalarPair` second field at bad offset in {inner:#?}", @@ -229,27 +228,14 @@ pub(super) fn sanity_check_layout<'tcx>( field2.align.abi, align2, "`ScalarPair` second field with bad align in {inner:#?}", ); - assert!( - matches!(field2.abi, Abi::Scalar(_)), + assert_matches!( + field2.abi, + Abi::Scalar(_), "`ScalarPair` second field with bad ABI in {inner:#?}", ); } - Abi::Vector { count, element } => { - // No padding in vectors, except possibly for trailing padding to make the size a multiple of align. - let size = element.size(cx) * count; - let align = cx.data_layout().vector_align(size).abi; - let size = size.align_to(align); // needed e.g. for vectors of size 3 + Abi::Vector { element, .. } => { assert!(align >= element.align(cx).abi); // just sanity-checking `vector_align`. - assert_eq!( - layout.layout.size(), - size, - "size mismatch between ABI and layout in {layout:#?}" - ); - assert_eq!( - layout.layout.align().abi, - align, - "alignment mismatch between ABI and layout in {layout:#?}" - ); // FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair. } Abi::Uninhabited | Abi::Aggregate { .. } => {} // Nothing to check. diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 9d5a72a73cd..73a2f6af579 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -5,6 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(assert_matches)] #![feature(iterator_try_collect)] #![feature(let_chains)] #![feature(never_type)] diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 5f436f7c9fd..a04f85afb9e 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -132,7 +132,7 @@ where _ => { tcx.sess.delay_span_bug( tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP), - &format!("unexpected generator witness type {:?}", witness), + format!("unexpected generator witness type {:?}", witness), ); return Some(Err(AlwaysRequiresDrop)); } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index cb06c7acff0..78efcce572d 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -62,9 +62,8 @@ fn sized_constraint_for_ty<'tcx>( // it on the impl. let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; - let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref(sized_trait, [ty])) - .without_const() - .to_predicate(tcx); + let sized_predicate = + ty::TraitRef::new(tcx, sized_trait, [ty]).without_const().to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } } diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index efbbc1c2331..2daef82d6f1 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -3079,8 +3079,8 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { unsafe { self.root.reborrow() } .as_mut()? .borrow_mut() - .first_leaf_edge() - .next_kv() + .last_leaf_edge() + .next_back_kv() .ok()? .into_kv_valmut() } diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index da00d83bdbb..7ecffe3eef2 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -8,6 +8,7 @@ use crate::testing::crash_test::{CrashTestDummy, Panic}; use crate::testing::ord_chaos::{Cyclic3, Governed, Governor}; use crate::testing::rng::DeterministicRng; use crate::vec::Vec; +use core::assert_matches::assert_matches; use std::cmp::Ordering; use std::iter; use std::mem; @@ -2448,3 +2449,21 @@ fn test_cursor_mut_insert_after_4() { let mut cur = map.upper_bound_mut(Bound::Included(&2)); cur.insert_after(4, 'd'); } + +#[test] +fn cursor_peek_prev_agrees_with_cursor_mut() { + let mut map = BTreeMap::from([(1, 1), (2, 2), (3, 3)]); + + let cursor = map.lower_bound(Bound::Excluded(&3)); + assert!(cursor.key().is_none()); + + let prev = cursor.peek_prev(); + assert_matches!(prev, Some((&3, _))); + + // Shadow names so the two parts of this test match. + let mut cursor = map.lower_bound_mut(Bound::Excluded(&3)); + assert!(cursor.key().is_none()); + + let prev = cursor.peek_prev(); + assert_matches!(prev, Some((&3, _))); +} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index a002421aeef..18f25aec5fe 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -101,6 +101,7 @@ #![feature(array_into_iter_constructors)] #![feature(array_methods)] #![feature(array_windows)] +#![feature(ascii_char)] #![feature(assert_matches)] #![feature(async_iterator)] #![feature(coerce_unsized)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index cf16a3424a0..b9ef76c109a 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2527,6 +2527,15 @@ impl<T: fmt::Display + ?Sized> ToString for T { } #[cfg(not(no_global_oom_handling))] +#[unstable(feature = "ascii_char", issue = "110998")] +impl ToString for core::ascii::Char { + #[inline] + fn to_string(&self) -> String { + self.as_str().to_owned() + } +} + +#[cfg(not(no_global_oom_handling))] #[stable(feature = "char_to_string_specialization", since = "1.46.0")] impl ToString for char { #[inline] diff --git a/library/core/src/array/ascii.rs b/library/core/src/array/ascii.rs new file mode 100644 index 00000000000..3fea9a44049 --- /dev/null +++ b/library/core/src/array/ascii.rs @@ -0,0 +1,47 @@ +use crate::ascii; + +#[cfg(not(test))] +impl<const N: usize> [u8; N] { + /// Converts this array of bytes into a array of ASCII characters, + /// or returns `None` if any of the characters is non-ASCII. + /// + /// # Examples + /// + /// ``` + /// #![feature(ascii_char)] + /// #![feature(const_option)] + /// + /// const HEX_DIGITS: [std::ascii::Char; 16] = + /// *b"0123456789abcdef".as_ascii().unwrap(); + /// + /// assert_eq!(HEX_DIGITS[1].as_str(), "1"); + /// assert_eq!(HEX_DIGITS[10].as_str(), "a"); + /// ``` + #[unstable(feature = "ascii_char", issue = "110998")] + #[must_use] + #[inline] + pub const fn as_ascii(&self) -> Option<&[ascii::Char; N]> { + if self.is_ascii() { + // SAFETY: Just checked that it's ASCII + Some(unsafe { self.as_ascii_unchecked() }) + } else { + None + } + } + + /// Converts this array of bytes into a array of ASCII characters, + /// without checking whether they're valid. + /// + /// # Safety + /// + /// Every byte in the array must be in `0..=127`, or else this is UB. + #[unstable(feature = "ascii_char", issue = "110998")] + #[must_use] + #[inline] + pub const unsafe fn as_ascii_unchecked(&self) -> &[ascii::Char; N] { + let byte_ptr: *const [u8; N] = self; + let ascii_ptr = byte_ptr as *const [ascii::Char; N]; + // SAFETY: The caller promised all the bytes are ASCII + unsafe { &*ascii_ptr } + } +} diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 940558974e6..bdb4c975909 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -17,6 +17,7 @@ use crate::ops::{ }; use crate::slice::{Iter, IterMut}; +mod ascii; mod drain; mod equality; mod iter; diff --git a/library/core/src/ascii.rs b/library/core/src/ascii.rs index 8a4cb78cc7f..7fd14a7e1ea 100644 --- a/library/core/src/ascii.rs +++ b/library/core/src/ascii.rs @@ -9,10 +9,14 @@ #![stable(feature = "core_ascii", since = "1.26.0")] +use crate::escape; use crate::fmt; use crate::iter::FusedIterator; -use crate::ops::Range; -use crate::str::from_utf8_unchecked; +use crate::num::NonZeroUsize; + +mod ascii_char; +#[unstable(feature = "ascii_char", issue = "110998")] +pub use ascii_char::AsciiChar as Char; /// An iterator over the escaped version of a byte. /// @@ -21,10 +25,7 @@ use crate::str::from_utf8_unchecked; #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] -pub struct EscapeDefault { - range: Range<u8>, - data: [u8; 4], -} +pub struct EscapeDefault(escape::EscapeIterInner<4>); /// Returns an iterator that produces an escaped version of a `u8`. /// @@ -90,21 +91,9 @@ pub struct EscapeDefault { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn escape_default(c: u8) -> EscapeDefault { - let (data, len) = match c { - b'\t' => ([b'\\', b't', 0, 0], 2), - b'\r' => ([b'\\', b'r', 0, 0], 2), - b'\n' => ([b'\\', b'n', 0, 0], 2), - b'\\' => ([b'\\', b'\\', 0, 0], 2), - b'\'' => ([b'\\', b'\'', 0, 0], 2), - b'"' => ([b'\\', b'"', 0, 0], 2), - b'\x20'..=b'\x7e' => ([c, 0, 0, 0], 1), - _ => { - let hex_digits: &[u8; 16] = b"0123456789abcdef"; - ([b'\\', b'x', hex_digits[(c >> 4) as usize], hex_digits[(c & 0xf) as usize]], 4) - } - }; - - return EscapeDefault { range: 0..len, data }; + let mut data = [0; 4]; + let range = escape::escape_ascii_into(&mut data, c); + EscapeDefault(escape::EscapeIterInner::new(data, range)) } #[stable(feature = "rust1", since = "1.0.0")] @@ -113,33 +102,59 @@ impl Iterator for EscapeDefault { #[inline] fn next(&mut self) -> Option<u8> { - self.range.next().map(|i| self.data[i as usize]) + self.0.next() } + + #[inline] fn size_hint(&self) -> (usize, Option<usize>) { - self.range.size_hint() + let n = self.0.len(); + (n, Some(n)) } + + #[inline] + fn count(self) -> usize { + self.0.len() + } + + #[inline] fn last(mut self) -> Option<u8> { - self.next_back() + self.0.next_back() + } + + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + self.0.advance_by(n) } } + #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for EscapeDefault { + #[inline] fn next_back(&mut self) -> Option<u8> { - self.range.next_back().map(|i| self.data[i as usize]) + self.0.next_back() + } + + #[inline] + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + self.0.advance_back_by(n) } } + #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for EscapeDefault {} +impl ExactSizeIterator for EscapeDefault { + #[inline] + fn len(&self) -> usize { + self.0.len() + } +} + #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for EscapeDefault {} #[stable(feature = "ascii_escape_display", since = "1.39.0")] impl fmt::Display for EscapeDefault { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // SAFETY: ok because `escape_default` created only valid utf-8 data - f.write_str(unsafe { - from_utf8_unchecked(&self.data[(self.range.start as usize)..(self.range.end as usize)]) - }) + f.write_str(self.0.as_str()) } } diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs new file mode 100644 index 00000000000..f093a0990d1 --- /dev/null +++ b/library/core/src/ascii/ascii_char.rs @@ -0,0 +1,565 @@ +//! This uses the name `AsciiChar`, even though it's not exposed that way right now, +//! because it avoids a whole bunch of "are you sure you didn't mean `char`?" +//! suggestions from rustc if you get anything slightly wrong in here, and overall +//! helps with clarity as we're also referring to `char` intentionally in here. + +use crate::fmt; +use crate::mem::transmute; + +/// One of the 128 Unicode characters from U+0000 through U+007F, +/// often known as the [ASCII] subset. +/// +/// Officially, this is the first [block] in Unicode, _Basic Latin_. +/// For details, see the [*C0 Controls and Basic Latin*][chart] code chart. +/// +/// This block was based on older 7-bit character code standards such as +/// ANSI X3.4-1977, ISO 646-1973, and [NIST FIPS 1-2]. +/// +/// # When to use this +/// +/// The main advantage of this subset is that it's always valid UTF-8. As such, +/// the `&[ascii::Char]` -> `&str` conversion function (as well as other related +/// ones) are O(1): *no* runtime checks are needed. +/// +/// If you're consuming strings, you should usually handle Unicode and thus +/// accept `str`s, not limit yourself to `ascii::Char`s. +/// +/// However, certain formats are intentionally designed to produce ASCII-only +/// output in order to be 8-bit-clean. In those cases, it can be simpler and +/// faster to generate `ascii::Char`s instead of dealing with the variable width +/// properties of general UTF-8 encoded strings, while still allowing the result +/// to be used freely with other Rust things that deal in general `str`s. +/// +/// For example, a UUID library might offer a way to produce the string +/// representation of a UUID as an `[ascii::Char; 36]` to avoid memory +/// allocation yet still allow it to be used as UTF-8 via `as_str` without +/// paying for validation (or needing `unsafe` code) the way it would if it +/// were provided as a `[u8; 36]`. +/// +/// # Layout +/// +/// This type is guaranteed to have a size and alignment of 1 byte. +/// +/// # Names +/// +/// The variants on this type are [Unicode names][NamesList] of the characters +/// in upper camel case, with a few tweaks: +/// - For `<control>` characters, the primary alias name is used. +/// - `LATIN` is dropped, as this block has no non-latin letters. +/// - `LETTER` is dropped, as `CAPITAL`/`SMALL` suffices in this block. +/// - `DIGIT`s use a single digit rather than writing out `ZERO`, `ONE`, etc. +/// +/// [ASCII]: https://www.unicode.org/glossary/index.html#ASCII +/// [block]: https://www.unicode.org/glossary/index.html#block +/// [chart]: https://www.unicode.org/charts/PDF/U0000.pdf +/// [NIST FIPS 1-2]: https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub1-2-1977.pdf +/// [NamesList]: https://www.unicode.org/Public/15.0.0/ucd/NamesList.txt +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[unstable(feature = "ascii_char", issue = "110998")] +#[repr(u8)] +pub enum AsciiChar { + /// U+0000 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Null = 0, + /// U+0001 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + StartOfHeading = 1, + /// U+0002 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + StartOfText = 2, + /// U+0003 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + EndOfText = 3, + /// U+0004 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + EndOfTransmission = 4, + /// U+0005 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Enquiry = 5, + /// U+0006 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Acknowledge = 6, + /// U+0007 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Bell = 7, + /// U+0008 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Backspace = 8, + /// U+0009 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CharacterTabulation = 9, + /// U+000A + #[unstable(feature = "ascii_char_variants", issue = "110998")] + LineFeed = 10, + /// U+000B + #[unstable(feature = "ascii_char_variants", issue = "110998")] + LineTabulation = 11, + /// U+000C + #[unstable(feature = "ascii_char_variants", issue = "110998")] + FormFeed = 12, + /// U+000D + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CarriageReturn = 13, + /// U+000E + #[unstable(feature = "ascii_char_variants", issue = "110998")] + ShiftOut = 14, + /// U+000F + #[unstable(feature = "ascii_char_variants", issue = "110998")] + ShiftIn = 15, + /// U+0010 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + DataLinkEscape = 16, + /// U+0011 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + DeviceControlOne = 17, + /// U+0012 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + DeviceControlTwo = 18, + /// U+0013 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + DeviceControlThree = 19, + /// U+0014 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + DeviceControlFour = 20, + /// U+0015 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + NegativeAcknowledge = 21, + /// U+0016 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SynchronousIdle = 22, + /// U+0017 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + EndOfTransmissionBlock = 23, + /// U+0018 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Cancel = 24, + /// U+0019 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + EndOfMedium = 25, + /// U+001A + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Substitute = 26, + /// U+001B + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Escape = 27, + /// U+001C + #[unstable(feature = "ascii_char_variants", issue = "110998")] + InformationSeparatorFour = 28, + /// U+001D + #[unstable(feature = "ascii_char_variants", issue = "110998")] + InformationSeparatorThree = 29, + /// U+001E + #[unstable(feature = "ascii_char_variants", issue = "110998")] + InformationSeparatorTwo = 30, + /// U+001F + #[unstable(feature = "ascii_char_variants", issue = "110998")] + InformationSeparatorOne = 31, + /// U+0020 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Space = 32, + /// U+0021 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + ExclamationMark = 33, + /// U+0022 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + QuotationMark = 34, + /// U+0023 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + NumberSign = 35, + /// U+0024 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + DollarSign = 36, + /// U+0025 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + PercentSign = 37, + /// U+0026 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Ampersand = 38, + /// U+0027 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Apostrophe = 39, + /// U+0028 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + LeftParenthesis = 40, + /// U+0029 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + RightParenthesis = 41, + /// U+002A + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Asterisk = 42, + /// U+002B + #[unstable(feature = "ascii_char_variants", issue = "110998")] + PlusSign = 43, + /// U+002C + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Comma = 44, + /// U+002D + #[unstable(feature = "ascii_char_variants", issue = "110998")] + HyphenMinus = 45, + /// U+002E + #[unstable(feature = "ascii_char_variants", issue = "110998")] + FullStop = 46, + /// U+002F + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Solidus = 47, + /// U+0030 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit0 = 48, + /// U+0031 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit1 = 49, + /// U+0032 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit2 = 50, + /// U+0033 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit3 = 51, + /// U+0034 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit4 = 52, + /// U+0035 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit5 = 53, + /// U+0036 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit6 = 54, + /// U+0037 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit7 = 55, + /// U+0038 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit8 = 56, + /// U+0039 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Digit9 = 57, + /// U+003A + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Colon = 58, + /// U+003B + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Semicolon = 59, + /// U+003C + #[unstable(feature = "ascii_char_variants", issue = "110998")] + LessThanSign = 60, + /// U+003D + #[unstable(feature = "ascii_char_variants", issue = "110998")] + EqualsSign = 61, + /// U+003E + #[unstable(feature = "ascii_char_variants", issue = "110998")] + GreaterThanSign = 62, + /// U+003F + #[unstable(feature = "ascii_char_variants", issue = "110998")] + QuestionMark = 63, + /// U+0040 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CommercialAt = 64, + /// U+0041 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalA = 65, + /// U+0042 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalB = 66, + /// U+0043 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalC = 67, + /// U+0044 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalD = 68, + /// U+0045 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalE = 69, + /// U+0046 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalF = 70, + /// U+0047 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalG = 71, + /// U+0048 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalH = 72, + /// U+0049 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalI = 73, + /// U+004A + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalJ = 74, + /// U+004B + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalK = 75, + /// U+004C + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalL = 76, + /// U+004D + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalM = 77, + /// U+004E + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalN = 78, + /// U+004F + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalO = 79, + /// U+0050 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalP = 80, + /// U+0051 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalQ = 81, + /// U+0052 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalR = 82, + /// U+0053 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalS = 83, + /// U+0054 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalT = 84, + /// U+0055 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalU = 85, + /// U+0056 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalV = 86, + /// U+0057 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalW = 87, + /// U+0058 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalX = 88, + /// U+0059 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalY = 89, + /// U+005A + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CapitalZ = 90, + /// U+005B + #[unstable(feature = "ascii_char_variants", issue = "110998")] + LeftSquareBracket = 91, + /// U+005C + #[unstable(feature = "ascii_char_variants", issue = "110998")] + ReverseSolidus = 92, + /// U+005D + #[unstable(feature = "ascii_char_variants", issue = "110998")] + RightSquareBracket = 93, + /// U+005E + #[unstable(feature = "ascii_char_variants", issue = "110998")] + CircumflexAccent = 94, + /// U+005F + #[unstable(feature = "ascii_char_variants", issue = "110998")] + LowLine = 95, + /// U+0060 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + GraveAccent = 96, + /// U+0061 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallA = 97, + /// U+0062 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallB = 98, + /// U+0063 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallC = 99, + /// U+0064 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallD = 100, + /// U+0065 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallE = 101, + /// U+0066 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallF = 102, + /// U+0067 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallG = 103, + /// U+0068 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallH = 104, + /// U+0069 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallI = 105, + /// U+006A + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallJ = 106, + /// U+006B + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallK = 107, + /// U+006C + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallL = 108, + /// U+006D + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallM = 109, + /// U+006E + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallN = 110, + /// U+006F + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallO = 111, + /// U+0070 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallP = 112, + /// U+0071 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallQ = 113, + /// U+0072 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallR = 114, + /// U+0073 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallS = 115, + /// U+0074 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallT = 116, + /// U+0075 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallU = 117, + /// U+0076 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallV = 118, + /// U+0077 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallW = 119, + /// U+0078 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallX = 120, + /// U+0079 + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallY = 121, + /// U+007A + #[unstable(feature = "ascii_char_variants", issue = "110998")] + SmallZ = 122, + /// U+007B + #[unstable(feature = "ascii_char_variants", issue = "110998")] + LeftCurlyBracket = 123, + /// U+007C + #[unstable(feature = "ascii_char_variants", issue = "110998")] + VerticalLine = 124, + /// U+007D + #[unstable(feature = "ascii_char_variants", issue = "110998")] + RightCurlyBracket = 125, + /// U+007E + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Tilde = 126, + /// U+007F + #[unstable(feature = "ascii_char_variants", issue = "110998")] + Delete = 127, +} + +impl AsciiChar { + /// Creates an ascii character from the byte `b`, + /// or returns `None` if it's too large. + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn from_u8(b: u8) -> Option<Self> { + if b <= 127 { + // SAFETY: Just checked that `b` is in-range + Some(unsafe { Self::from_u8_unchecked(b) }) + } else { + None + } + } + + /// Creates an ASCII character from the byte `b`, + /// without checking whether it's valid. + /// + /// # Safety + /// + /// `b` must be in `0..=127`, or else this is UB. + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const unsafe fn from_u8_unchecked(b: u8) -> Self { + // SAFETY: Our safety precondition is that `b` is in-range. + unsafe { transmute(b) } + } + + /// When passed the *number* `0`, `1`, …, `9`, returns the *character* + /// `'0'`, `'1'`, …, `'9'` respectively. + /// + /// If `d >= 10`, returns `None`. + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn digit(d: u8) -> Option<Self> { + if d < 10 { + // SAFETY: Just checked it's in-range. + Some(unsafe { Self::digit_unchecked(d) }) + } else { + None + } + } + + /// When passed the *number* `0`, `1`, …, `9`, returns the *character* + /// `'0'`, `'1'`, …, `'9'` respectively, without checking that it's in-range. + /// + /// # Safety + /// + /// This is immediate UB if called with `d > 64`. + /// + /// If `d >= 10` and `d <= 64`, this is allowed to return any value or panic. + /// Notably, it should not be expected to return hex digits, or any other + /// reasonable extension of the decimal digits. + /// + /// (This lose safety condition is intended to simplify soundness proofs + /// when writing code using this method, since the implementation doesn't + /// need something really specific, not to make those other arguments do + /// something useful. It might be tightened before stabilization.) + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const unsafe fn digit_unchecked(d: u8) -> Self { + debug_assert!(d < 10); + + // SAFETY: `'0'` through `'9'` are U+00030 through U+0039, + // so because `d` must be 64 or less the addition can return at most + // 112 (0x70), which doesn't overflow and is within the ASCII range. + unsafe { + let byte = b'0'.unchecked_add(d); + Self::from_u8_unchecked(byte) + } + } + + /// Gets this ASCII character as a byte. + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn as_u8(self) -> u8 { + self as u8 + } + + /// Gets this ASCII character as a `char` Unicode Scalar Value. + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn as_char(self) -> char { + self as u8 as char + } + + /// Views this ASCII character as a one-code-unit UTF-8 `str`. + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn as_str(&self) -> &str { + crate::slice::from_ref(self).as_str() + } +} + +impl [AsciiChar] { + /// Views this slice of ASCII characters as a UTF-8 `str`. + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn as_str(&self) -> &str { + let ascii_ptr: *const Self = self; + let str_ptr = ascii_ptr as *const str; + // SAFETY: Each ASCII codepoint in UTF-8 is encoded as one single-byte + // code unit having the same value as the ASCII byte. + unsafe { &*str_ptr } + } + + /// Views this slice of ASCII characters as a slice of `u8` bytes. + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn as_bytes(&self) -> &[u8] { + self.as_str().as_bytes() + } +} + +#[unstable(feature = "ascii_char", issue = "110998")] +impl fmt::Display for AsciiChar { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + <str as fmt::Display>::fmt(self.as_str(), f) + } +} diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 9bc97ea0bff..1dfa9c34db1 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1,5 +1,6 @@ //! impl char {} +use crate::ascii; use crate::slice; use crate::str::from_utf8_unchecked_mut; use crate::unicode::printable::is_printable; @@ -380,20 +381,7 @@ impl char { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn escape_unicode(self) -> EscapeUnicode { - let c = self as u32; - - // or-ing 1 ensures that for c==0 the code computes that one - // digit should be printed and (which is the same) avoids the - // (31 - 32) underflow - let msb = 31 - (c | 1).leading_zeros(); - - // the index of the most significant hex digit - let ms_hex_digit = msb / 4; - EscapeUnicode { - c: self, - state: EscapeUnicodeState::Backslash, - hex_digit_idx: ms_hex_digit as usize, - } + EscapeUnicode::new(self) } /// An extended version of `escape_debug` that optionally permits escaping @@ -403,21 +391,20 @@ impl char { /// characters, and double quotes in strings. #[inline] pub(crate) fn escape_debug_ext(self, args: EscapeDebugExtArgs) -> EscapeDebug { - let init_state = match self { - '\0' => EscapeDefaultState::Backslash('0'), - '\t' => EscapeDefaultState::Backslash('t'), - '\r' => EscapeDefaultState::Backslash('r'), - '\n' => EscapeDefaultState::Backslash('n'), - '\\' => EscapeDefaultState::Backslash(self), - '"' if args.escape_double_quote => EscapeDefaultState::Backslash(self), - '\'' if args.escape_single_quote => EscapeDefaultState::Backslash(self), + match self { + '\0' => EscapeDebug::backslash(b'0'), + '\t' => EscapeDebug::backslash(b't'), + '\r' => EscapeDebug::backslash(b'r'), + '\n' => EscapeDebug::backslash(b'n'), + '\\' => EscapeDebug::backslash(b'\\'), + '"' if args.escape_double_quote => EscapeDebug::backslash(b'"'), + '\'' if args.escape_single_quote => EscapeDebug::backslash(b'\''), _ if args.escape_grapheme_extended && self.is_grapheme_extended() => { - EscapeDefaultState::Unicode(self.escape_unicode()) + EscapeDebug::from_unicode(self.escape_unicode()) } - _ if is_printable(self) => EscapeDefaultState::Char(self), - _ => EscapeDefaultState::Unicode(self.escape_unicode()), - }; - EscapeDebug(EscapeDefault { state: init_state }) + _ if is_printable(self) => EscapeDebug::printable(self), + _ => EscapeDebug::from_unicode(self.escape_unicode()), + } } /// Returns an iterator that yields the literal escape code of a character @@ -515,15 +502,14 @@ impl char { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn escape_default(self) -> EscapeDefault { - let init_state = match self { - '\t' => EscapeDefaultState::Backslash('t'), - '\r' => EscapeDefaultState::Backslash('r'), - '\n' => EscapeDefaultState::Backslash('n'), - '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self), - '\x20'..='\x7e' => EscapeDefaultState::Char(self), - _ => EscapeDefaultState::Unicode(self.escape_unicode()), - }; - EscapeDefault { state: init_state } + match self { + '\t' => EscapeDefault::backslash(b't'), + '\r' => EscapeDefault::backslash(b'r'), + '\n' => EscapeDefault::backslash(b'n'), + '\\' | '\'' | '"' => EscapeDefault::backslash(self as u8), + '\x20'..='\x7e' => EscapeDefault::printable(self as u8), + _ => EscapeDefault::from_unicode(self.escape_unicode()), + } } /// Returns the number of bytes this `char` would need if encoded in UTF-8. @@ -1116,6 +1102,24 @@ impl char { *self as u32 <= 0x7F } + /// Returns `Some` if the value is within the ASCII range, + /// or `None` if it's not. + /// + /// This is preferred to [`Self::is_ascii`] when you're passing the value + /// along to something else that can take [`ascii::Char`] rather than + /// needing to check again for itself whether the value is in ASCII. + #[must_use] + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn as_ascii(&self) -> Option<ascii::Char> { + if self.is_ascii() { + // SAFETY: Just checked that this is ASCII. + Some(unsafe { ascii::Char::from_u8_unchecked(*self as u8) }) + } else { + None + } + } + /// Makes a copy of the value in its ASCII upper case equivalent. /// /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 8ec78e88733..e186db7052c 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -39,8 +39,10 @@ pub use self::methods::encode_utf16_raw; pub use self::methods::encode_utf8_raw; use crate::error::Error; +use crate::escape; use crate::fmt::{self, Write}; use crate::iter::FusedIterator; +use crate::num::NonZeroUsize; pub(crate) use self::methods::EscapeDebugExtArgs; @@ -146,86 +148,44 @@ pub const fn from_digit(num: u32, radix: u32) -> Option<char> { /// [`escape_unicode`]: char::escape_unicode #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct EscapeUnicode { - c: char, - state: EscapeUnicodeState, - - // The index of the next hex digit to be printed (0 if none), - // i.e., the number of remaining hex digits to be printed; - // increasing from the least significant digit: 0x543210 - hex_digit_idx: usize, -} +pub struct EscapeUnicode(escape::EscapeIterInner<10>); -// The enum values are ordered so that their representation is the -// same as the remaining length (besides the hexadecimal digits). This -// likely makes `len()` a single load from memory) and inline-worth. -#[derive(Clone, Debug)] -enum EscapeUnicodeState { - Done, - RightBrace, - Value, - LeftBrace, - Type, - Backslash, +impl EscapeUnicode { + fn new(chr: char) -> Self { + let mut data = [0; 10]; + let range = escape::escape_unicode_into(&mut data, chr); + Self(escape::EscapeIterInner::new(data, range)) + } } #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for EscapeUnicode { type Item = char; + #[inline] fn next(&mut self) -> Option<char> { - match self.state { - EscapeUnicodeState::Backslash => { - self.state = EscapeUnicodeState::Type; - Some('\\') - } - EscapeUnicodeState::Type => { - self.state = EscapeUnicodeState::LeftBrace; - Some('u') - } - EscapeUnicodeState::LeftBrace => { - self.state = EscapeUnicodeState::Value; - Some('{') - } - EscapeUnicodeState::Value => { - let hex_digit = ((self.c as u32) >> (self.hex_digit_idx * 4)) & 0xf; - let c = char::from_digit(hex_digit, 16).unwrap(); - if self.hex_digit_idx == 0 { - self.state = EscapeUnicodeState::RightBrace; - } else { - self.hex_digit_idx -= 1; - } - Some(c) - } - EscapeUnicodeState::RightBrace => { - self.state = EscapeUnicodeState::Done; - Some('}') - } - EscapeUnicodeState::Done => None, - } + self.0.next().map(char::from) } #[inline] fn size_hint(&self) -> (usize, Option<usize>) { - let n = self.len(); + let n = self.0.len(); (n, Some(n)) } #[inline] fn count(self) -> usize { - self.len() + self.0.len() } - fn last(self) -> Option<char> { - match self.state { - EscapeUnicodeState::Done => None, + #[inline] + fn last(mut self) -> Option<char> { + self.0.next_back().map(char::from) + } - EscapeUnicodeState::RightBrace - | EscapeUnicodeState::Value - | EscapeUnicodeState::LeftBrace - | EscapeUnicodeState::Type - | EscapeUnicodeState::Backslash => Some('}'), - } + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + self.0.advance_by(n) } } @@ -233,16 +193,7 @@ impl Iterator for EscapeUnicode { impl ExactSizeIterator for EscapeUnicode { #[inline] fn len(&self) -> usize { - // The match is a single memory access with no branching - self.hex_digit_idx - + match self.state { - EscapeUnicodeState::Done => 0, - EscapeUnicodeState::RightBrace => 1, - EscapeUnicodeState::Value => 2, - EscapeUnicodeState::LeftBrace => 3, - EscapeUnicodeState::Type => 4, - EscapeUnicodeState::Backslash => 5, - } + self.0.len() } } @@ -252,10 +203,7 @@ impl FusedIterator for EscapeUnicode {} #[stable(feature = "char_struct_display", since = "1.16.0")] impl fmt::Display for EscapeUnicode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for c in self.clone() { - f.write_char(c)?; - } - Ok(()) + f.write_str(self.0.as_str()) } } @@ -267,90 +215,60 @@ impl fmt::Display for EscapeUnicode { /// [`escape_default`]: char::escape_default #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct EscapeDefault { - state: EscapeDefaultState, -} +pub struct EscapeDefault(escape::EscapeIterInner<10>); -#[derive(Clone, Debug)] -enum EscapeDefaultState { - Done, - Char(char), - Backslash(char), - Unicode(EscapeUnicode), +impl EscapeDefault { + fn printable(chr: u8) -> Self { + let data = [chr, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + Self(escape::EscapeIterInner::new(data, 0..1)) + } + + fn backslash(chr: u8) -> Self { + let data = [b'\\', chr, 0, 0, 0, 0, 0, 0, 0, 0]; + Self(escape::EscapeIterInner::new(data, 0..2)) + } + + fn from_unicode(esc: EscapeUnicode) -> Self { + Self(esc.0) + } } #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for EscapeDefault { type Item = char; + #[inline] fn next(&mut self) -> Option<char> { - match self.state { - EscapeDefaultState::Backslash(c) => { - self.state = EscapeDefaultState::Char(c); - Some('\\') - } - EscapeDefaultState::Char(c) => { - self.state = EscapeDefaultState::Done; - Some(c) - } - EscapeDefaultState::Done => None, - EscapeDefaultState::Unicode(ref mut iter) => iter.next(), - } + self.0.next().map(char::from) } #[inline] fn size_hint(&self) -> (usize, Option<usize>) { - let n = self.len(); + let n = self.0.len(); (n, Some(n)) } #[inline] fn count(self) -> usize { - self.len() + self.0.len() } - fn nth(&mut self, n: usize) -> Option<char> { - match self.state { - EscapeDefaultState::Backslash(c) if n == 0 => { - self.state = EscapeDefaultState::Char(c); - Some('\\') - } - EscapeDefaultState::Backslash(c) if n == 1 => { - self.state = EscapeDefaultState::Done; - Some(c) - } - EscapeDefaultState::Backslash(_) => { - self.state = EscapeDefaultState::Done; - None - } - EscapeDefaultState::Char(c) => { - self.state = EscapeDefaultState::Done; - - if n == 0 { Some(c) } else { None } - } - EscapeDefaultState::Done => None, - EscapeDefaultState::Unicode(ref mut i) => i.nth(n), - } + #[inline] + fn last(mut self) -> Option<char> { + self.0.next_back().map(char::from) } - fn last(self) -> Option<char> { - match self.state { - EscapeDefaultState::Unicode(iter) => iter.last(), - EscapeDefaultState::Done => None, - EscapeDefaultState::Backslash(c) | EscapeDefaultState::Char(c) => Some(c), - } + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + self.0.advance_by(n) } } #[stable(feature = "exact_size_escape", since = "1.11.0")] impl ExactSizeIterator for EscapeDefault { + #[inline] fn len(&self) -> usize { - match self.state { - EscapeDefaultState::Done => 0, - EscapeDefaultState::Char(_) => 1, - EscapeDefaultState::Backslash(_) => 2, - EscapeDefaultState::Unicode(ref iter) => iter.len(), - } + self.0.len() } } @@ -360,10 +278,7 @@ impl FusedIterator for EscapeDefault {} #[stable(feature = "char_struct_display", since = "1.16.0")] impl fmt::Display for EscapeDefault { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for c in self.clone() { - f.write_char(c)?; - } - Ok(()) + f.write_str(self.0.as_str()) } } @@ -375,21 +290,74 @@ impl fmt::Display for EscapeDefault { /// [`escape_debug`]: char::escape_debug #[stable(feature = "char_escape_debug", since = "1.20.0")] #[derive(Clone, Debug)] -pub struct EscapeDebug(EscapeDefault); +pub struct EscapeDebug(EscapeDebugInner); + +#[derive(Clone, Debug)] +// Note: It’s possible to manually encode the EscapeDebugInner inside of +// EscapeIterInner (e.g. with alive=254..255 indicating that data[0..4] holds +// a char) which would likely result in a more optimised code. For now we use +// the option easier to implement. +enum EscapeDebugInner { + Bytes(escape::EscapeIterInner<10>), + Char(char), +} + +impl EscapeDebug { + fn printable(chr: char) -> Self { + Self(EscapeDebugInner::Char(chr)) + } + + fn backslash(chr: u8) -> Self { + let data = [b'\\', chr, 0, 0, 0, 0, 0, 0, 0, 0]; + let iter = escape::EscapeIterInner::new(data, 0..2); + Self(EscapeDebugInner::Bytes(iter)) + } + + fn from_unicode(esc: EscapeUnicode) -> Self { + Self(EscapeDebugInner::Bytes(esc.0)) + } + + fn clear(&mut self) { + let bytes = escape::EscapeIterInner::new([0; 10], 0..0); + self.0 = EscapeDebugInner::Bytes(bytes); + } +} #[stable(feature = "char_escape_debug", since = "1.20.0")] impl Iterator for EscapeDebug { type Item = char; + + #[inline] fn next(&mut self) -> Option<char> { - self.0.next() + match self.0 { + EscapeDebugInner::Bytes(ref mut bytes) => bytes.next().map(char::from), + EscapeDebugInner::Char(chr) => { + self.clear(); + Some(chr) + } + } } + fn size_hint(&self) -> (usize, Option<usize>) { - self.0.size_hint() + let n = self.len(); + (n, Some(n)) + } + + #[inline] + fn count(self) -> usize { + self.len() } } #[stable(feature = "char_escape_debug", since = "1.20.0")] -impl ExactSizeIterator for EscapeDebug {} +impl ExactSizeIterator for EscapeDebug { + fn len(&self) -> usize { + match &self.0 { + EscapeDebugInner::Bytes(bytes) => bytes.len(), + EscapeDebugInner::Char(_) => 1, + } + } +} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for EscapeDebug {} @@ -397,7 +365,10 @@ impl FusedIterator for EscapeDebug {} #[stable(feature = "char_escape_debug", since = "1.20.0")] impl fmt::Display for EscapeDebug { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.0, f) + match &self.0 { + EscapeDebugInner::Bytes(bytes) => f.write_str(bytes.as_str()), + EscapeDebugInner::Char(chr) => f.write_char(*chr), + } } } diff --git a/library/core/src/escape.rs b/library/core/src/escape.rs new file mode 100644 index 00000000000..20ac3cf027f --- /dev/null +++ b/library/core/src/escape.rs @@ -0,0 +1,99 @@ +//! Helper code for character escaping. + +use crate::num::NonZeroUsize; +use crate::ops::Range; + +const HEX_DIGITS: [u8; 16] = *b"0123456789abcdef"; + +/// Escapes a byte into provided buffer; returns length of escaped +/// representation. +pub(crate) fn escape_ascii_into(output: &mut [u8; 4], byte: u8) -> Range<u8> { + let (data, len) = match byte { + b'\t' => ([b'\\', b't', 0, 0], 2), + b'\r' => ([b'\\', b'r', 0, 0], 2), + b'\n' => ([b'\\', b'n', 0, 0], 2), + b'\\' => ([b'\\', b'\\', 0, 0], 2), + b'\'' => ([b'\\', b'\'', 0, 0], 2), + b'"' => ([b'\\', b'"', 0, 0], 2), + b'\x20'..=b'\x7e' => ([byte, 0, 0, 0], 1), + _ => { + let hi = HEX_DIGITS[usize::from(byte >> 4)]; + let lo = HEX_DIGITS[usize::from(byte & 0xf)]; + ([b'\\', b'x', hi, lo], 4) + } + }; + *output = data; + 0..(len as u8) +} + +/// Escapes a character into provided buffer using `\u{NNNN}` representation. +pub(crate) fn escape_unicode_into(output: &mut [u8; 10], ch: char) -> Range<u8> { + output[9] = b'}'; + + let ch = ch as u32; + output[3] = HEX_DIGITS[((ch >> 20) & 15) as usize]; + output[4] = HEX_DIGITS[((ch >> 16) & 15) as usize]; + output[5] = HEX_DIGITS[((ch >> 12) & 15) as usize]; + output[6] = HEX_DIGITS[((ch >> 8) & 15) as usize]; + output[7] = HEX_DIGITS[((ch >> 4) & 15) as usize]; + output[8] = HEX_DIGITS[((ch >> 0) & 15) as usize]; + + // or-ing 1 ensures that for ch==0 the code computes that one digit should + // be printed. + let start = (ch | 1).leading_zeros() as usize / 4 - 2; + output[start..start + 3].copy_from_slice(b"\\u{"); + + (start as u8)..10 +} + +/// An iterator over an fixed-size array. +/// +/// This is essentially equivalent to array’s IntoIter except that indexes are +/// limited to u8 to reduce size of the structure. +#[derive(Clone, Debug)] +pub(crate) struct EscapeIterInner<const N: usize> { + // Invariant: data[alive] is all ASCII. + pub(crate) data: [u8; N], + + // Invariant: alive.start <= alive.end <= N. + pub(crate) alive: Range<u8>, +} + +impl<const N: usize> EscapeIterInner<N> { + pub fn new(data: [u8; N], alive: Range<u8>) -> Self { + const { assert!(N < 256) }; + debug_assert!(alive.start <= alive.end && usize::from(alive.end) <= N, "{alive:?}"); + let this = Self { data, alive }; + debug_assert!(this.as_bytes().is_ascii(), "Expected ASCII, got {:?}", this.as_bytes()); + this + } + + fn as_bytes(&self) -> &[u8] { + &self.data[usize::from(self.alive.start)..usize::from(self.alive.end)] + } + + pub fn as_str(&self) -> &str { + // SAFETY: self.data[self.alive] is all ASCII characters. + unsafe { crate::str::from_utf8_unchecked(self.as_bytes()) } + } + + pub fn len(&self) -> usize { + usize::from(self.alive.end - self.alive.start) + } + + pub fn next(&mut self) -> Option<u8> { + self.alive.next().map(|i| self.data[usize::from(i)]) + } + + pub fn next_back(&mut self) -> Option<u8> { + self.alive.next_back().map(|i| self.data[usize::from(i)]) + } + + pub fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + self.alive.advance_by(n) + } + + pub fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + self.alive.advance_back_by(n) + } +} diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index bd2b2c36c43..07b11814f96 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -79,9 +79,9 @@ use crate::str; /// /// [str]: prim@str "str" #[derive(Hash)] -#[cfg_attr(not(test), rustc_diagnostic_item = "CStr")] #[stable(feature = "core_c_str", since = "1.64.0")] #[rustc_has_incoherent_inherent_impls] +#[cfg_attr(not(bootstrap), lang = "CStr")] // FIXME: // `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies // on `CStr` being layout-compatible with `[u8]`. diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 146e8d3d22a..b85894259f1 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -202,6 +202,7 @@ mod c_long_definition { // would be uninhabited and at least dereferencing such pointers would // be UB. #[doc = include_str!("c_void.md")] +#[cfg_attr(not(bootstrap), lang = "c_void")] #[repr(u8)] #[stable(feature = "core_c_void", since = "1.30.0")] pub enum c_void { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 79bd0bbb0c1..077c0fdc380 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2257,12 +2257,23 @@ extern "rust-intrinsic" { /// This is an implementation detail of [`crate::ptr::read`] and should /// not be used anywhere else. See its comments for why this exists. /// - /// This intrinsic can *only* be called where the argument is a local without - /// projections (`read_via_copy(p)`, not `read_via_copy(*p)`) so that it + /// This intrinsic can *only* be called where the pointer is a local without + /// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it /// trivially obeys runtime-MIR rules about derefs in operands. #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] #[rustc_nounwind] - pub fn read_via_copy<T>(p: *const T) -> T; + pub fn read_via_copy<T>(ptr: *const T) -> T; + + /// This is an implementation detail of [`crate::ptr::write`] and should + /// not be used anywhere else. See its comments for why this exists. + /// + /// This intrinsic can *only* be called where the pointer is a local without + /// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so + /// that it trivially obeys runtime-MIR rules about derefs in operands. + #[cfg(not(bootstrap))] + #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] + #[rustc_nounwind] + pub fn write_via_move<T>(ptr: *mut T, value: T); /// Returns the value of the discriminant for the variant in 'v'; /// if `T` has no discriminant, returns `0`. @@ -2828,3 +2839,16 @@ pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst { // SAFETY: It's a transmute -- the caller promised it's fine. unsafe { transmute_copy(&ManuallyDrop::new(src)) } } + +/// Polyfill for bootstrap +#[cfg(bootstrap)] +pub const unsafe fn write_via_move<T>(ptr: *mut T, value: T) { + use crate::mem::*; + // SAFETY: the caller must guarantee that `dst` is valid for writes. + // `dst` cannot overlap `src` because the caller has mutable access + // to `dst` while `src` is owned by this function. + unsafe { + copy_nonoverlapping::<T>(&value, ptr, 1); + forget(value); + } +} diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 520ec9abcf0..2568aaf34f3 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -310,6 +310,7 @@ where /// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// this type. #[derive(Clone, Debug)] +#[unstable(feature = "trusted_len", issue = "37572")] struct FlattenCompat<I, U> { iter: Fuse<I>, frontiter: Option<U>, @@ -463,6 +464,7 @@ where } } +#[unstable(feature = "trusted_len", issue = "37572")] impl<I, U> Iterator for FlattenCompat<I, U> where I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>, @@ -577,6 +579,7 @@ where } } +#[unstable(feature = "trusted_len", issue = "37572")] impl<I, U> DoubleEndedIterator for FlattenCompat<I, U> where I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>, @@ -646,6 +649,7 @@ where } } +#[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<const N: usize, I, T> TrustedLen for FlattenCompat<I, <[T; N] as IntoIterator>::IntoIter> where @@ -653,6 +657,7 @@ where { } +#[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<'a, const N: usize, I, T> TrustedLen for FlattenCompat<I, <&'a [T; N] as IntoIterator>::IntoIter> where @@ -660,6 +665,7 @@ where { } +#[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<'a, const N: usize, I, T> TrustedLen for FlattenCompat<I, <&'a mut [T; N] as IntoIterator>::IntoIter> where diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 24a9d81d037..3abf66dbe29 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -107,6 +107,7 @@ #![feature(const_arguments_as_str)] #![feature(const_array_from_ref)] #![feature(const_array_into_iter_constructors)] +#![feature(const_assume)] #![feature(const_bigint_helper_methods)] #![feature(const_black_box)] #![feature(const_caller_location)] @@ -149,6 +150,7 @@ #![feature(const_slice_from_raw_parts_mut)] #![feature(const_slice_from_ref)] #![feature(const_slice_index)] +#![feature(const_slice_is_ascii)] #![feature(const_slice_ptr_len)] #![feature(const_slice_split_at_mut)] #![feature(const_str_from_utf8_unchecked_mut)] @@ -162,6 +164,7 @@ #![feature(const_waker)] #![feature(core_panic)] #![feature(duration_consts_float)] +#![feature(internal_impls_macro)] #![feature(ip)] #![feature(is_ascii_octdigit)] #![feature(maybe_uninit_uninit_array)] @@ -376,6 +379,7 @@ pub mod alloc; // note: does not need to be public mod bool; +mod escape; mod tuple; mod unit; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 40789cb3049..52f3d208aba 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -12,6 +12,60 @@ use crate::fmt::Debug; use crate::hash::Hash; use crate::hash::Hasher; +/// Implements a given marker trait for multiple types at the same time. +/// +/// The basic syntax looks like this: +/// ```ignore private macro +/// marker_impls! { MarkerTrait for u8, i8 } +/// ``` +/// You can also implement `unsafe` traits +/// ```ignore private macro +/// marker_impls! { unsafe MarkerTrait for u8, i8 } +/// ``` +/// Add attributes to all impls: +/// ```ignore private macro +/// marker_impls! { +/// #[allow(lint)] +/// #[unstable(feature = "marker_trait", issue = "none")] +/// MarkerTrait for u8, i8 +/// } +/// ``` +/// And use generics: +/// ```ignore private macro +/// marker_impls! { +/// MarkerTrait for +/// u8, i8, +/// {T: ?Sized} *const T, +/// {T: ?Sized} *mut T, +/// {T: MarkerTrait} PhantomData<T>, +/// u32, +/// } +/// ``` +#[unstable(feature = "internal_impls_macro", issue = "none")] +macro marker_impls { + ( $(#[$($meta:tt)*])* $Trait:ident for $( $({$($bounds:tt)*})? $T:ty ),+ $(,)?) => { + // This inner macro is needed because... idk macros are weird. + // It allows repeating `meta` on all impls. + #[unstable(feature = "internal_impls_macro", issue = "none")] + macro _impl { + ( $$({$$($$bounds_:tt)*})? $$T_:ty ) => { + $(#[$($meta)*])* impl<$$($$($$bounds_)*)?> $Trait for $$T_ {} + } + } + $( _impl! { $({$($bounds)*})? $T } )+ + }, + ( $(#[$($meta:tt)*])* unsafe $Trait:ident for $( $({$($bounds:tt)*})? $T:ty ),+ $(,)?) => { + #[unstable(feature = "internal_impls_macro", issue = "none")] + macro _impl { + ( $$({$$($$bounds_:tt)*})? $$T_:ty ) => { + $(#[$($meta)*])* unsafe impl<$$($$($$bounds_)*)?> $Trait for $$T_ {} + } + } + + $( _impl! { $({$($bounds)*})? $T } )+ + }, +} + /// Types that can be transferred across thread boundaries. /// /// This trait is automatically implemented when the compiler determines it's @@ -24,7 +78,7 @@ use crate::hash::Hasher; /// operations. Its cousin [`sync::Arc`][arc] does use atomic operations (incurring /// some overhead) and thus is `Send`. /// -/// See [the Nomicon](../../nomicon/send-and-sync.html) for more details. +/// See [the Nomicon](../../nomicon/send-and-sync.html) and the [`Sync`] trait for more details. /// /// [`Rc`]: ../../std/rc/struct.Rc.html /// [arc]: ../../std/sync/struct.Arc.html @@ -214,6 +268,20 @@ pub trait StructuralEq { // Empty. } +// FIXME: Remove special cases of these types from the compiler pattern checking code and always check `T: StructuralEq` instead +marker_impls! { + #[unstable(feature = "structural_match", issue = "31434")] + StructuralEq for + usize, u8, u16, u32, u64, u128, + isize, i8, i16, i32, i64, i128, + bool, + char, + str /* Technically requires `[u8]: StructuralEq` */, + {T, const N: usize} [T; N], + {T} [T], + {T: ?Sized} &T, +} + /// Types whose values can be duplicated simply by copying bits. /// /// By default, variable bindings have 'move semantics.' In other @@ -401,6 +469,30 @@ pub macro Copy($item:item) { /* compiler built-in */ } +// Implementations of `Copy` for primitive types. +// +// Implementations that cannot be described in Rust +// are implemented in `traits::SelectionContext::copy_clone_conditions()` +// in `rustc_trait_selection`. +marker_impls! { + #[stable(feature = "rust1", since = "1.0.0")] + Copy for + usize, u8, u16, u32, u64, u128, + isize, i8, i16, i32, i64, i128, + f32, f64, + bool, char, + {T: ?Sized} *const T, + {T: ?Sized} *mut T, + +} + +#[unstable(feature = "never_type", issue = "35121")] +impl Copy for ! {} + +/// Shared references can be copied, but mutable references *cannot*! +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Copy for &T {} + /// Types for which it is safe to share references between threads. /// /// This trait is automatically implemented when the compiler determines @@ -426,6 +518,11 @@ pub macro Copy($item:item) { /// becomes read-only, as if it were a `& &T`. Hence there is no risk /// of a data race. /// +/// A shorter overview of how [`Sync`] and [`Send`] relate to referencing: +/// * `&T` is [`Send`] if and only if `T` is [`Sync`] +/// * `&mut T` is [`Send`] if and only if `T` is [`Send`] +/// * `&T` and `&mut T` are [`Sync`] if and only if `T` is [`Sync`] +/// /// Types that are not `Sync` are those that have "interior /// mutability" in a non-thread-safe form, such as [`Cell`][cell] /// and [`RefCell`][refcell]. These types allow for mutation of @@ -773,11 +870,14 @@ pub trait DiscriminantKind { pub(crate) unsafe auto trait Freeze {} impl<T: ?Sized> !Freeze for UnsafeCell<T> {} -unsafe impl<T: ?Sized> Freeze for PhantomData<T> {} -unsafe impl<T: ?Sized> Freeze for *const T {} -unsafe impl<T: ?Sized> Freeze for *mut T {} -unsafe impl<T: ?Sized> Freeze for &T {} -unsafe impl<T: ?Sized> Freeze for &mut T {} +marker_impls! { + unsafe Freeze for + {T: ?Sized} PhantomData<T>, + {T: ?Sized} *const T, + {T: ?Sized} *mut T, + {T: ?Sized} &T, + {T: ?Sized} &mut T, +} /// Types that can be safely moved after being pinned. /// @@ -838,17 +938,19 @@ pub struct PhantomPinned; #[stable(feature = "pin", since = "1.33.0")] impl !Unpin for PhantomPinned {} -#[stable(feature = "pin", since = "1.33.0")] -impl<'a, T: ?Sized + 'a> Unpin for &'a T {} - -#[stable(feature = "pin", since = "1.33.0")] -impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {} - -#[stable(feature = "pin_raw", since = "1.38.0")] -impl<T: ?Sized> Unpin for *const T {} +marker_impls! { + #[stable(feature = "pin", since = "1.33.0")] + Unpin for + {T: ?Sized} &T, + {T: ?Sized} &mut T, +} -#[stable(feature = "pin_raw", since = "1.38.0")] -impl<T: ?Sized> Unpin for *mut T {} +marker_impls! { + #[stable(feature = "pin_raw", since = "1.38.0")] + Unpin for + {T: ?Sized} *const T, + {T: ?Sized} *mut T, +} /// A marker for types that can be dropped. /// @@ -883,43 +985,25 @@ pub trait Tuple {} )] pub trait PointerLike {} -/// Implementations of `Copy` for primitive types. -/// -/// Implementations that cannot be described in Rust -/// are implemented in `traits::SelectionContext::copy_clone_conditions()` -/// in `rustc_trait_selection`. -mod copy_impls { - - use super::Copy; - - macro_rules! impl_copy { - ($($t:ty)*) => { - $( - #[stable(feature = "rust1", since = "1.0.0")] - impl Copy for $t {} - )* - } - } - - impl_copy! { - usize u8 u16 u32 u64 u128 - isize i8 i16 i32 i64 i128 - f32 f64 - bool char - } - - #[unstable(feature = "never_type", issue = "35121")] - impl Copy for ! {} - - #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Copy for *const T {} - - #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Copy for *mut T {} - - /// Shared references can be copied, but mutable references *cannot*! - #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Copy for &T {} +/// A marker for types which can be used as types of `const` generic parameters. +#[cfg_attr(not(bootstrap), lang = "const_param_ty")] +#[unstable(feature = "adt_const_params", issue = "95174")] +#[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")] +pub trait ConstParamTy: StructuralEq {} + +// FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure` +// FIXME(generic_const_parameter_types): handle `ty::Tuple` +marker_impls! { + #[unstable(feature = "adt_const_params", issue = "95174")] + ConstParamTy for + usize, u8, u16, u32, u64, u128, + isize, i8, i16, i32, i64, i128, + bool, + char, + str /* Technically requires `[u8]: ConstParamTy` */, + {T: ConstParamTy, const N: usize} [T; N], + {T: ConstParamTy} [T], + {T: ?Sized + ConstParamTy} &T, } /// A common trait implemented by all function pointers. diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 2588b7d2bef..d09a24b4b1d 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1287,7 +1287,7 @@ impl<T, const N: usize> MaybeUninit<[T; N]> { #[inline] pub const fn transpose(self) -> [MaybeUninit<T>; N] { // SAFETY: T and MaybeUninit<T> have the same layout - unsafe { super::transmute_copy(&ManuallyDrop::new(self)) } + unsafe { intrinsics::transmute_unchecked(self) } } } @@ -1307,6 +1307,6 @@ impl<T, const N: usize> [MaybeUninit<T>; N] { #[inline] pub const fn transpose(self) -> MaybeUninit<[T; N]> { // SAFETY: T and MaybeUninit<T> have the same layout - unsafe { super::transmute_copy(&ManuallyDrop::new(self)) } + unsafe { intrinsics::transmute_unchecked(self) } } } diff --git a/library/core/src/net/socket_addr.rs b/library/core/src/net/socket_addr.rs index 2d48e271580..8396aecf947 100644 --- a/library/core/src/net/socket_addr.rs +++ b/library/core/src/net/socket_addr.rs @@ -122,6 +122,7 @@ impl SocketAddr { #[stable(feature = "ip_addr", since = "1.7.0")] #[must_use] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn new(ip: IpAddr, port: u16) -> SocketAddr { match ip { IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)), @@ -142,6 +143,7 @@ impl SocketAddr { #[must_use] #[stable(feature = "ip_addr", since = "1.7.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn ip(&self) -> IpAddr { match *self { SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()), @@ -161,6 +163,7 @@ impl SocketAddr { /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1))); /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] + #[inline] pub fn set_ip(&mut self, new_ip: IpAddr) { // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away. match (self, new_ip) { @@ -183,6 +186,7 @@ impl SocketAddr { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn port(&self) -> u16 { match *self { SocketAddr::V4(ref a) => a.port(), @@ -202,6 +206,7 @@ impl SocketAddr { /// assert_eq!(socket.port(), 1025); /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] + #[inline] pub fn set_port(&mut self, new_port: u16) { match *self { SocketAddr::V4(ref mut a) => a.set_port(new_port), @@ -227,6 +232,7 @@ impl SocketAddr { #[must_use] #[stable(feature = "sockaddr_checker", since = "1.16.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn is_ipv4(&self) -> bool { matches!(*self, SocketAddr::V4(_)) } @@ -249,6 +255,7 @@ impl SocketAddr { #[must_use] #[stable(feature = "sockaddr_checker", since = "1.16.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn is_ipv6(&self) -> bool { matches!(*self, SocketAddr::V6(_)) } @@ -269,6 +276,7 @@ impl SocketAddrV4 { #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 { SocketAddrV4 { ip, port } } @@ -286,6 +294,7 @@ impl SocketAddrV4 { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn ip(&self) -> &Ipv4Addr { &self.ip } @@ -302,6 +311,7 @@ impl SocketAddrV4 { /// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1)); /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] + #[inline] pub fn set_ip(&mut self, new_ip: Ipv4Addr) { self.ip = new_ip; } @@ -319,6 +329,7 @@ impl SocketAddrV4 { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn port(&self) -> u16 { self.port } @@ -335,6 +346,7 @@ impl SocketAddrV4 { /// assert_eq!(socket.port(), 4242); /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] + #[inline] pub fn set_port(&mut self, new_port: u16) { self.port = new_port; } @@ -360,6 +372,7 @@ impl SocketAddrV6 { #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> SocketAddrV6 { SocketAddrV6 { ip, port, flowinfo, scope_id } } @@ -377,6 +390,7 @@ impl SocketAddrV6 { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn ip(&self) -> &Ipv6Addr { &self.ip } @@ -393,6 +407,7 @@ impl SocketAddrV6 { /// assert_eq!(socket.ip(), &Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0)); /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] + #[inline] pub fn set_ip(&mut self, new_ip: Ipv6Addr) { self.ip = new_ip; } @@ -410,6 +425,7 @@ impl SocketAddrV6 { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn port(&self) -> u16 { self.port } @@ -426,6 +442,7 @@ impl SocketAddrV6 { /// assert_eq!(socket.port(), 4242); /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] + #[inline] pub fn set_port(&mut self, new_port: u16) { self.port = new_port; } @@ -453,6 +470,7 @@ impl SocketAddrV6 { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn flowinfo(&self) -> u32 { self.flowinfo } @@ -471,6 +489,7 @@ impl SocketAddrV6 { /// assert_eq!(socket.flowinfo(), 56); /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] + #[inline] pub fn set_flowinfo(&mut self, new_flowinfo: u32) { self.flowinfo = new_flowinfo; } @@ -493,6 +512,7 @@ impl SocketAddrV6 { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")] + #[inline] pub const fn scope_id(&self) -> u32 { self.scope_id } @@ -511,6 +531,7 @@ impl SocketAddrV6 { /// assert_eq!(socket.scope_id(), 42); /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] + #[inline] pub fn set_scope_id(&mut self, new_scope_id: u32) { self.scope_id = new_scope_id; } @@ -519,6 +540,7 @@ impl SocketAddrV6 { #[stable(feature = "ip_from_ip", since = "1.16.0")] impl From<SocketAddrV4> for SocketAddr { /// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`]. + #[inline] fn from(sock4: SocketAddrV4) -> SocketAddr { SocketAddr::V4(sock4) } @@ -527,6 +549,7 @@ impl From<SocketAddrV4> for SocketAddr { #[stable(feature = "ip_from_ip", since = "1.16.0")] impl From<SocketAddrV6> for SocketAddr { /// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`]. + #[inline] fn from(sock6: SocketAddrV6) -> SocketAddr { SocketAddr::V6(sock6) } @@ -624,6 +647,7 @@ impl fmt::Debug for SocketAddrV6 { #[stable(feature = "socketaddr_ordering", since = "1.45.0")] impl PartialOrd for SocketAddrV4 { + #[inline] fn partial_cmp(&self, other: &SocketAddrV4) -> Option<Ordering> { Some(self.cmp(other)) } @@ -631,6 +655,7 @@ impl PartialOrd for SocketAddrV4 { #[stable(feature = "socketaddr_ordering", since = "1.45.0")] impl PartialOrd for SocketAddrV6 { + #[inline] fn partial_cmp(&self, other: &SocketAddrV6) -> Option<Ordering> { Some(self.cmp(other)) } @@ -638,6 +663,7 @@ impl PartialOrd for SocketAddrV6 { #[stable(feature = "socketaddr_ordering", since = "1.45.0")] impl Ord for SocketAddrV4 { + #[inline] fn cmp(&self, other: &SocketAddrV4) -> Ordering { self.ip().cmp(other.ip()).then(self.port().cmp(&other.port())) } @@ -645,6 +671,7 @@ impl Ord for SocketAddrV4 { #[stable(feature = "socketaddr_ordering", since = "1.45.0")] impl Ord for SocketAddrV6 { + #[inline] fn cmp(&self, other: &SocketAddrV6) -> Ordering { self.ip().cmp(other.ip()).then(self.port().cmp(&other.port())) } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index fdd7be625ed..08444421dca 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -472,7 +472,16 @@ impl u8 { #[rustc_const_stable(feature = "const_u8_is_ascii", since = "1.43.0")] #[inline] pub const fn is_ascii(&self) -> bool { - *self & 128 == 0 + *self <= 127 + } + + /// If the value of this byte is within the ASCII range, returns it as an + /// [ASCII character](ascii::Char). Otherwise, returns `None`. + #[must_use] + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const fn as_ascii(&self) -> Option<ascii::Char> { + ascii::Char::from_u8(*self) } /// Makes a copy of the value in its ASCII upper case equivalent. diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index b80bfe1c92d..74a325b89d4 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -713,6 +713,32 @@ macro_rules! nonzero_signed_operations { unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) } } + /// Returns `true` if `self` is positive and `false` if the + /// number is negative. + /// + /// # Example + /// + /// ``` + /// #![feature(nonzero_negation_ops)] + /// + #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] + /// + /// assert!(pos_five.is_positive()); + /// assert!(!neg_five.is_positive()); + /// # Some(()) + /// # } + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + pub const fn is_positive(self) -> bool { + self.get().is_positive() + } + /// Returns `true` if `self` is negative and `false` if the /// number is positive. /// diff --git a/library/core/src/option.rs b/library/core/src/option.rs index c38c68e1d58..ec1ef3cf43d 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1641,10 +1641,8 @@ impl<T> Option<T> { where F: FnOnce() -> T, { - if let None = *self { - // the compiler isn't smart enough to know that we are not dropping a `T` - // here and wants us to ensure `T` can be dropped at compile time. - mem::forget(mem::replace(self, Some(f()))) + if let None = self { + *self = Some(f()); } // SAFETY: a `None` variant for `self` would have been replaced by a `Some` diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 08ffc407ead..e06ccb5b287 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -610,6 +610,9 @@ mod prim_pointer {} /// if the element type allows it. As a stopgap, trait implementations are /// statically generated up to size 32. /// +/// Arrays of sizes from 1 to 12 (inclusive) implement [`From<Tuple>`], where `Tuple` +/// is a homogenous [prim@tuple] of appropriate length. +/// /// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on /// an array. Indeed, this provides most of the API for working with arrays. /// @@ -672,6 +675,13 @@ mod prim_pointer {} /// move_away(roa); /// ``` /// +/// Arrays can be created from homogenous tuples of appropriate length: +/// +/// ``` +/// let tuple: (u32, u32, u32) = (1, 2, 3); +/// let array: [u32; 3] = tuple.into(); +/// ``` +/// /// # Editions /// /// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call @@ -774,6 +784,7 @@ mod prim_pointer {} /// [`Borrow`]: borrow::Borrow /// [`BorrowMut`]: borrow::BorrowMut /// [slice pattern]: ../reference/patterns.html#slice-patterns +/// [`From<Tuple>`]: convert::From #[stable(feature = "rust1", since = "1.0.0")] mod prim_array {} @@ -1000,7 +1011,9 @@ mod prim_str {} /// * [`Debug`] /// * [`Default`] /// * [`Hash`] +/// * [`From<[T; N]>`][from] /// +/// [from]: convert::From /// [`Debug`]: fmt::Debug /// [`Hash`]: hash::Hash /// @@ -1051,6 +1064,13 @@ mod prim_str {} /// assert_eq!(y, 5); /// ``` /// +/// Homogenous tuples can be created from arrays of appropriate length: +/// +/// ``` +/// let array: [u32; 3] = [1, 2, 3]; +/// let tuple: (u32, u32, u32) = array.into(); +/// ``` +/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_tuple {} diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 13e546497f2..4737ff5d756 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1349,13 +1349,13 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T { #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn write<T>(dst: *mut T, src: T) { - // We are calling the intrinsics directly to avoid function calls in the generated code - // as `intrinsics::copy_nonoverlapping` is a wrapper function. - extern "rust-intrinsic" { - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] - #[rustc_nounwind] - fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); - } + // Semantically, it would be fine for this to be implemented as a + // `copy_nonoverlapping` and appropriate drop suppression of `src`. + + // However, implementing via that currently produces more MIR than is ideal. + // Using an intrinsic keeps it down to just the simple `*dst = move src` in + // MIR (11 statements shorter, at the time of writing), and also allows + // `src` to stay an SSA value in codegen_ssa, rather than a memory one. // SAFETY: the caller must guarantee that `dst` is valid for writes. // `dst` cannot overlap `src` because the caller has mutable access @@ -1365,8 +1365,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) { "ptr::write requires that the pointer argument is aligned and non-null", [T](dst: *mut T) => is_aligned_and_not_null(dst) ); - copy_nonoverlapping(&src as *const T, dst, 1); - intrinsics::forget(src); + intrinsics::write_via_move(dst, src) } } @@ -1633,8 +1632,8 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz // FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <= // 1, where the method versions of these operations are not inlined. use intrinsics::{ - cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_shl, unchecked_shr, - unchecked_sub, wrapping_add, wrapping_mul, wrapping_sub, + assume, cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_shl, + unchecked_shr, unchecked_sub, wrapping_add, wrapping_mul, wrapping_sub, }; /// Calculate multiplicative modular inverse of `x` modulo `m`. @@ -1725,12 +1724,18 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz // in a branch-free way and then bitwise-OR it with whatever result the `-p mod a` // computation produces. + let aligned_address = wrapping_add(addr, a_minus_one) & wrapping_sub(0, a); + let byte_offset = wrapping_sub(aligned_address, addr); + // FIXME: Remove the assume after <https://github.com/llvm/llvm-project/issues/62502> + // SAFETY: Masking by `-a` can only affect the low bits, and thus cannot have reduced + // the value by more than `a-1`, so even though the intermediate values might have + // wrapped, the byte_offset is always in `[0, a)`. + unsafe { assume(byte_offset < a) }; + // SAFETY: `stride == 0` case has been handled by the special case above. let addr_mod_stride = unsafe { unchecked_rem(addr, stride) }; return if addr_mod_stride == 0 { - let aligned_address = wrapping_add(addr, a_minus_one) & wrapping_sub(0, a); - let byte_offset = wrapping_sub(aligned_address, addr); // SAFETY: `stride` is non-zero. This is guaranteed to divide exactly as well, because // addr has been verified to be aligned to the original type’s alignment requirements. unsafe { exact_div(byte_offset, stride) } diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 5e5399acc1b..f3311f76a7f 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -10,12 +10,43 @@ use crate::ops; impl [u8] { /// Checks if all bytes in this slice are within the ASCII range. #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] + #[rustc_const_unstable(feature = "const_slice_is_ascii", issue = "111090")] #[must_use] #[inline] - pub fn is_ascii(&self) -> bool { + pub const fn is_ascii(&self) -> bool { is_ascii(self) } + /// If this slice [`is_ascii`](Self::is_ascii), returns it as a slice of + /// [ASCII characters](`ascii::Char`), otherwise returns `None`. + #[unstable(feature = "ascii_char", issue = "110998")] + #[must_use] + #[inline] + pub const fn as_ascii(&self) -> Option<&[ascii::Char]> { + if self.is_ascii() { + // SAFETY: Just checked that it's ASCII + Some(unsafe { self.as_ascii_unchecked() }) + } else { + None + } + } + + /// Converts this slice of bytes into a slice of ASCII characters, + /// without checking whether they're valid. + /// + /// # Safety + /// + /// Every byte in the slice must be in `0..=127`, or else this is UB. + #[unstable(feature = "ascii_char", issue = "110998")] + #[must_use] + #[inline] + pub const unsafe fn as_ascii_unchecked(&self) -> &[ascii::Char] { + let byte_ptr: *const [u8] = self; + let ascii_ptr = byte_ptr as *const [ascii::Char]; + // SAFETY: The caller promised all the bytes are ASCII + unsafe { &*ascii_ptr } + } + /// Checks that two slices are an ASCII case-insensitive match. /// /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`, @@ -232,11 +263,29 @@ impl<'a> fmt::Debug for EscapeAscii<'a> { /// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed /// from `../str/mod.rs`, which does something similar for utf8 validation. #[inline] -fn contains_nonascii(v: usize) -> bool { +const fn contains_nonascii(v: usize) -> bool { const NONASCII_MASK: usize = usize::repeat_u8(0x80); (NONASCII_MASK & v) != 0 } +/// ASCII test *without* the chunk-at-a-time optimizations. +/// +/// This is carefully structured to produce nice small code -- it's smaller in +/// `-O` than what the "obvious" ways produces under `-C opt-level=s`. If you +/// touch it, be sure to run (and update if needed) the assembly test. +#[unstable(feature = "str_internals", issue = "none")] +#[doc(hidden)] +#[inline] +pub const fn is_ascii_simple(mut bytes: &[u8]) -> bool { + while let [rest @ .., last] = bytes { + if !last.is_ascii() { + break; + } + bytes = rest; + } + bytes.is_empty() +} + /// Optimized ASCII test that will use usize-at-a-time operations instead of /// byte-at-a-time operations (when possible). /// @@ -250,7 +299,7 @@ fn contains_nonascii(v: usize) -> bool { /// If any of these loads produces something for which `contains_nonascii` /// (above) returns true, then we know the answer is false. #[inline] -fn is_ascii(s: &[u8]) -> bool { +const fn is_ascii(s: &[u8]) -> bool { const USIZE_SIZE: usize = mem::size_of::<usize>(); let len = s.len(); @@ -262,7 +311,7 @@ fn is_ascii(s: &[u8]) -> bool { // We also do this for architectures where `size_of::<usize>()` isn't // sufficient alignment for `usize`, because it's a weird edge case. if len < USIZE_SIZE || len < align_offset || USIZE_SIZE < mem::align_of::<usize>() { - return s.iter().all(|b| b.is_ascii()); + return is_ascii_simple(s); } // We always read the first word unaligned, which means `align_offset` is @@ -291,18 +340,26 @@ fn is_ascii(s: &[u8]) -> bool { // Paranoia check about alignment, since we're about to do a bunch of // unaligned loads. In practice this should be impossible barring a bug in // `align_offset` though. - debug_assert_eq!(word_ptr.addr() % mem::align_of::<usize>(), 0); + // While this method is allowed to spuriously fail in CTFE, if it doesn't + // have alignment information it should have given a `usize::MAX` for + // `align_offset` earlier, sending things through the scalar path instead of + // this one, so this check should pass if it's reachable. + debug_assert!(word_ptr.is_aligned_to(mem::align_of::<usize>())); // Read subsequent words until the last aligned word, excluding the last // aligned word by itself to be done in tail check later, to ensure that // tail is always one `usize` at most to extra branch `byte_pos == len`. while byte_pos < len - USIZE_SIZE { - debug_assert!( - // Sanity check that the read is in bounds - (word_ptr.addr() + USIZE_SIZE) <= start.addr().wrapping_add(len) && - // And that our assumptions about `byte_pos` hold. - (word_ptr.addr() - start.addr()) == byte_pos - ); + // Sanity check that the read is in bounds + debug_assert!(byte_pos + USIZE_SIZE <= len); + // And that our assumptions about `byte_pos` hold. + debug_assert!(matches!( + word_ptr.cast::<u8>().guaranteed_eq(start.wrapping_add(byte_pos)), + // These are from the same allocation, so will hopefully always be + // known to match even in CTFE, but if it refuses to compare them + // that's ok since it's just a debug check anyway. + None | Some(true), + )); // SAFETY: We know `word_ptr` is properly aligned (because of // `align_offset`), and we know that we have enough bytes between `word_ptr` and the end diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 33a468a6bca..4c891ba550f 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -44,6 +44,10 @@ mod raw; mod rotate; mod specialize; +#[unstable(feature = "str_internals", issue = "none")] +#[doc(hidden)] +pub use ascii::is_ascii_simple; + #[stable(feature = "rust1", since = "1.0.0")] pub use iter::{Chunks, ChunksMut, Windows}; #[stable(feature = "rust1", since = "1.0.0")] @@ -4257,7 +4261,7 @@ impl<T, const N: usize> [[T; N]] { /// assert!(empty_slice_of_arrays.flatten().is_empty()); /// ``` #[unstable(feature = "slice_flatten", issue = "95629")] - pub fn flatten(&self) -> &[T] { + pub const fn flatten(&self) -> &[T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") } else { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index a13107fd0de..ef05b25fdd0 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -16,6 +16,7 @@ mod validations; use self::pattern::Pattern; use self::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher}; +use crate::ascii; use crate::char::{self, EscapeDebugExtArgs}; use crate::mem; use crate::slice::{self, SliceIndex}; @@ -2357,15 +2358,26 @@ impl str { /// assert!(!non_ascii.is_ascii()); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] + #[rustc_const_unstable(feature = "const_slice_is_ascii", issue = "111090")] #[must_use] #[inline] - pub fn is_ascii(&self) -> bool { + pub const fn is_ascii(&self) -> bool { // We can treat each byte as character here: all multibyte characters // start with a byte that is not in the ASCII range, so we will stop // there already. self.as_bytes().is_ascii() } + /// If this string slice [`is_ascii`](Self::is_ascii), returns it as a slice + /// of [ASCII characters](`ascii::Char`), otherwise returns `None`. + #[unstable(feature = "ascii_char", issue = "110998")] + #[must_use] + #[inline] + pub const fn as_ascii(&self) -> Option<&[ascii::Char]> { + // Like in `is_ascii`, we can work on the bytes directly. + self.as_bytes().as_ascii() + } + /// Checks that two strings are an ASCII case-insensitive match. /// /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`, diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 75d7a3f4005..172e5fccb61 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -1,7 +1,6 @@ // See src/libstd/primitive_docs.rs for documentation. use crate::cmp::Ordering::{self, *}; -use crate::mem::transmute; // Recursive macro for implementing n-ary tuple functions and operations // @@ -100,6 +99,26 @@ macro_rules! tuple_impls { } } } + + #[stable(feature = "array_tuple_conv", since = "CURRENT_RUSTC_VERSION")] + impl<T> From<[T; ${count(T)}]> for ($(${ignore(T)} T,)+) { + #[inline] + #[allow(non_snake_case)] + fn from(array: [T; ${count(T)}]) -> Self { + let [$($T,)+] = array; + ($($T,)+) + } + } + + #[stable(feature = "array_tuple_conv", since = "CURRENT_RUSTC_VERSION")] + impl<T> From<($(${ignore(T)} T,)+)> for [T; ${count(T)}] { + #[inline] + #[allow(non_snake_case)] + fn from(tuple: ($(${ignore(T)} T,)+)) -> Self { + let ($($T,)+) = tuple; + [$($T,)+] + } + } } } @@ -122,16 +141,13 @@ macro_rules! maybe_tuple_doc { #[inline] const fn ordering_is_some(c: Option<Ordering>, x: Ordering) -> bool { // FIXME: Just use `==` once that's const-stable on `Option`s. - // This isn't using `match` because that optimizes worse due to - // making a two-step check (`Some` *then* the inner value). - - // SAFETY: There's no public guarantee for `Option<Ordering>`, - // but we're core so we know that it's definitely a byte. - unsafe { - let c: i8 = transmute(c); - let x: i8 = transmute(Some(x)); - c == x - } + // This is mapping `None` to 2 and then doing the comparison afterwards + // because it optimizes better (`None::<Ordering>` is represented as 2). + x as i8 + == match c { + Some(c) => c as i8, + None => 2, + } } // Constructs an expression that performs a lexical ordering using method `$rel`. diff --git a/library/core/tests/clone.rs b/library/core/tests/clone.rs index 33ca9f2c6a3..aafe5ced2e9 100644 --- a/library/core/tests/clone.rs +++ b/library/core/tests/clone.rs @@ -1,4 +1,5 @@ #[test] +#[cfg_attr(not(bootstrap), allow(suspicious_double_ref_op))] fn test_borrowed_clone() { let x = 5; let y: &i32 = &x; diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs index c6d42308596..af18e19337c 100644 --- a/library/panic_unwind/src/emcc.rs +++ b/library/panic_unwind/src/emcc.rs @@ -47,7 +47,7 @@ static EXCEPTION_TYPE_INFO: TypeInfo = TypeInfo { name: b"rust_panic\0".as_ptr(), }; -// NOTE(nbdd0121): The `canary` field will be part of stable ABI after `c_unwind` stabilization. +// NOTE(nbdd0121): The `canary` field is part of stable ABI. #[repr(C)] struct Exception { // See `gcc.rs` on why this is present. We already have a static here so just use it. diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs index 0b7a873a691..08858dd92be 100644 --- a/library/panic_unwind/src/gcc.rs +++ b/library/panic_unwind/src/gcc.rs @@ -48,8 +48,8 @@ use unwind as uw; static CANARY: u8 = 0; // NOTE(nbdd0121) -// Once `c_unwind` feature is stabilized, there will be ABI stability requirement -// on this struct. The first two field must be `_Unwind_Exception` and `canary`, +// There is an ABI stability requirement on this struct. +// The first two field must be `_Unwind_Exception` and `canary`, // as it may be accessed by a different version of the std with a different compiler. #[repr(C)] struct Exception { diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 651115a8248..99db00e5490 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -52,7 +52,7 @@ use core::mem::{self, ManuallyDrop}; use core::ptr; use libc::{c_int, c_uint, c_void}; -// NOTE(nbdd0121): The `canary` field will be part of stable ABI after `c_unwind` stabilization. +// NOTE(nbdd0121): The `canary` field is part of stable ABI. #[repr(C)] struct Exception { // See `gcc.rs` on why this is present. We already have a static here so just use it. diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 54b11c543f1..caecda1bc63 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -337,6 +337,8 @@ pub enum LitKind { StrRaw(u8), ByteStr, ByteStrRaw(u8), + CStr, + CStrRaw(u8), Err, } @@ -350,6 +352,8 @@ rpc_encode_decode!( StrRaw(n), ByteStr, ByteStrRaw(n), + CStr, + CStrRaw(n), Err, } ); diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 72a5b477330..0441f7e6c86 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -19,7 +19,7 @@ libc = { version = "0.2.142", default-features = false, features = ['rustc-dep-o compiler_builtins = { version = "0.1.91" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } -hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] } +hashbrown = { version = "0.13", default-features = false, features = ['rustc-dep-of-std'] } std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] } # Dependencies of the `backtrace` crate diff --git a/library/std/src/ascii.rs b/library/std/src/ascii.rs index c29f015777f..b18ab50de12 100644 --- a/library/std/src/ascii.rs +++ b/library/std/src/ascii.rs @@ -16,6 +16,9 @@ #[stable(feature = "rust1", since = "1.0.0")] pub use core::ascii::{escape_default, EscapeDefault}; +#[unstable(feature = "ascii_char", issue = "110998")] +pub use core::ascii::Char; + /// Extension methods for ASCII-subset only operations. /// /// Be aware that operations on seemingly non-ASCII characters can sometimes diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 30e553f285b..6640c7fb162 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -709,6 +709,7 @@ impl File { // `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows. impl AsInner<fs_imp::File> for File { + #[inline] fn as_inner(&self) -> &fs_imp::File { &self.inner } @@ -1087,12 +1088,14 @@ impl OpenOptions { } impl AsInner<fs_imp::OpenOptions> for OpenOptions { + #[inline] fn as_inner(&self) -> &fs_imp::OpenOptions { &self.0 } } impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions { + #[inline] fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 } @@ -1352,6 +1355,7 @@ impl fmt::Debug for Metadata { } impl AsInner<fs_imp::FileAttr> for Metadata { + #[inline] fn as_inner(&self) -> &fs_imp::FileAttr { &self.0 } @@ -1604,6 +1608,7 @@ impl FileType { } impl AsInner<fs_imp::FileType> for FileType { + #[inline] fn as_inner(&self) -> &fs_imp::FileType { &self.0 } @@ -1616,6 +1621,7 @@ impl FromInner<fs_imp::FilePermissions> for Permissions { } impl AsInner<fs_imp::FilePermissions> for Permissions { + #[inline] fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 } @@ -1770,6 +1776,7 @@ impl fmt::Debug for DirEntry { } impl AsInner<fs_imp::DirEntry> for DirEntry { + #[inline] fn as_inner(&self) -> &fs_imp::DirEntry { &self.0 } @@ -2510,6 +2517,7 @@ impl DirBuilder { } impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder { + #[inline] fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder { &mut self.inner } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 401def18458..a8a0b9f122d 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -919,6 +919,7 @@ fn symlink_noexist() { #[test] fn read_link() { + let tmpdir = tmpdir(); if cfg!(windows) { // directory symlink assert_eq!(check!(fs::read_link(r"C:\Users\All Users")), Path::new(r"C:\ProgramData")); @@ -933,8 +934,11 @@ fn read_link() { Path::new(r"C:\Users") ); } + // Check that readlink works with non-drive paths on Windows. + let link = tmpdir.join("link_unc"); + check!(symlink_dir(r"\\localhost\c$\", &link)); + assert_eq!(check!(fs::read_link(&link)), Path::new(r"\\localhost\c$\")); } - let tmpdir = tmpdir(); let link = tmpdir.join("link"); if !got_symlink_permission(&tmpdir) { return; diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 4b42ad65ee6..541e95d229b 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -691,6 +691,7 @@ impl Write for &TcpStream { } impl AsInner<net_imp::TcpStream> for TcpStream { + #[inline] fn as_inner(&self) -> &net_imp::TcpStream { &self.0 } @@ -1033,6 +1034,7 @@ impl Iterator for IntoIncoming { impl FusedIterator for IntoIncoming {} impl AsInner<net_imp::TcpListener> for TcpListener { + #[inline] fn as_inner(&self) -> &net_imp::TcpListener { &self.0 } diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs index 864e1b0f345..9628bcc5108 100644 --- a/library/std/src/net/udp.rs +++ b/library/std/src/net/udp.rs @@ -788,6 +788,7 @@ impl UdpSocket { // `AsRawSocket`/`IntoRawSocket`/`FromRawSocket` on Windows. impl AsInner<net_imp::UdpSocket> for UdpSocket { + #[inline] fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 } diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs index 540363c0349..2b3ff76d7a4 100644 --- a/library/std/src/os/linux/process.rs +++ b/library/std/src/os/linux/process.rs @@ -52,6 +52,7 @@ pub struct PidFd { } impl AsInner<FileDesc> for PidFd { + #[inline] fn as_inner(&self) -> &FileDesc { &self.inner } @@ -70,6 +71,7 @@ impl IntoInner<FileDesc> for PidFd { } impl AsRawFd for PidFd { + #[inline] fn as_raw_fd(&self) -> RawFd { self.as_inner().as_raw_fd() } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 5b22333cc35..198996c5f70 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1395,11 +1395,16 @@ impl PathBuf { /// /// let mut buf = PathBuf::from("/"); /// assert!(buf.file_name() == None); - /// buf.set_file_name("bar"); - /// assert!(buf == PathBuf::from("/bar")); + /// + /// buf.set_file_name("foo.txt"); + /// assert!(buf == PathBuf::from("/foo.txt")); /// assert!(buf.file_name().is_some()); - /// buf.set_file_name("baz.txt"); - /// assert!(buf == PathBuf::from("/baz.txt")); + /// + /// buf.set_file_name("bar.txt"); + /// assert!(buf == PathBuf::from("/bar.txt")); + /// + /// buf.set_file_name("baz"); + /// assert!(buf == PathBuf::from("/baz")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn set_file_name<S: AsRef<OsStr>>(&mut self, file_name: S) { @@ -2562,7 +2567,8 @@ impl Path { /// ``` /// use std::path::{Path, PathBuf}; /// - /// let path = Path::new("/tmp/foo.txt"); + /// let path = Path::new("/tmp/foo.png"); + /// assert_eq!(path.with_file_name("bar"), PathBuf::from("/tmp/bar")); /// assert_eq!(path.with_file_name("bar.txt"), PathBuf::from("/tmp/bar.txt")); /// /// let path = Path::new("/tmp"); diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 08ffc407ead..e06ccb5b287 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -610,6 +610,9 @@ mod prim_pointer {} /// if the element type allows it. As a stopgap, trait implementations are /// statically generated up to size 32. /// +/// Arrays of sizes from 1 to 12 (inclusive) implement [`From<Tuple>`], where `Tuple` +/// is a homogenous [prim@tuple] of appropriate length. +/// /// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on /// an array. Indeed, this provides most of the API for working with arrays. /// @@ -672,6 +675,13 @@ mod prim_pointer {} /// move_away(roa); /// ``` /// +/// Arrays can be created from homogenous tuples of appropriate length: +/// +/// ``` +/// let tuple: (u32, u32, u32) = (1, 2, 3); +/// let array: [u32; 3] = tuple.into(); +/// ``` +/// /// # Editions /// /// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call @@ -774,6 +784,7 @@ mod prim_pointer {} /// [`Borrow`]: borrow::Borrow /// [`BorrowMut`]: borrow::BorrowMut /// [slice pattern]: ../reference/patterns.html#slice-patterns +/// [`From<Tuple>`]: convert::From #[stable(feature = "rust1", since = "1.0.0")] mod prim_array {} @@ -1000,7 +1011,9 @@ mod prim_str {} /// * [`Debug`] /// * [`Default`] /// * [`Hash`] +/// * [`From<[T; N]>`][from] /// +/// [from]: convert::From /// [`Debug`]: fmt::Debug /// [`Hash`]: hash::Hash /// @@ -1051,6 +1064,13 @@ mod prim_str {} /// assert_eq!(y, 5); /// ``` /// +/// Homogenous tuples can be created from arrays of appropriate length: +/// +/// ``` +/// let array: [u32; 3] = [1, 2, 3]; +/// let tuple: (u32, u32, u32) = array.into(); +/// ``` +/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_tuple {} diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 0ab72f7ea7a..bf22c2d46c9 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -211,6 +211,7 @@ pub struct Child { impl crate::sealed::Sealed for Child {} impl AsInner<imp::Process> for Child { + #[inline] fn as_inner(&self) -> &imp::Process { &self.handle } @@ -304,6 +305,7 @@ impl Write for &ChildStdin { } impl AsInner<AnonPipe> for ChildStdin { + #[inline] fn as_inner(&self) -> &AnonPipe { &self.inner } @@ -373,6 +375,7 @@ impl Read for ChildStdout { } impl AsInner<AnonPipe> for ChildStdout { + #[inline] fn as_inner(&self) -> &AnonPipe { &self.inner } @@ -438,6 +441,7 @@ impl Read for ChildStderr { } impl AsInner<AnonPipe> for ChildStderr { + #[inline] fn as_inner(&self) -> &AnonPipe { &self.inner } @@ -1107,12 +1111,14 @@ impl fmt::Debug for Command { } impl AsInner<imp::Command> for Command { + #[inline] fn as_inner(&self) -> &imp::Command { &self.inner } } impl AsInnerMut<imp::Command> for Command { + #[inline] fn as_inner_mut(&mut self) -> &mut imp::Command { &mut self.inner } @@ -1605,6 +1611,7 @@ impl ExitStatus { } impl AsInner<imp::ExitStatus> for ExitStatus { + #[inline] fn as_inner(&self) -> &imp::ExitStatus { &self.0 } @@ -1884,6 +1891,7 @@ impl From<u8> for ExitCode { } impl AsInner<imp::ExitCode> for ExitCode { + #[inline] fn as_inner(&self) -> &imp::ExitCode { &self.0 } diff --git a/library/std/src/sys/common/thread_local/mod.rs b/library/std/src/sys/common/thread_local/mod.rs index a7528c06c9d..77f64588310 100644 --- a/library/std/src/sys/common/thread_local/mod.rs +++ b/library/std/src/sys/common/thread_local/mod.rs @@ -1,12 +1,17 @@ #![unstable(feature = "thread_local_internals", reason = "should not be necessary", issue = "none")] +// There are three thread-local implementations: "static", "fast", "OS". +// The "OS" thread local key type is accessed via platform-specific API calls and is slow, while the +// "fast" key type is accessed via code generated via LLVM, where TLS keys are set up by the linker. +// "static" is for single-threaded platforms where a global static is sufficient. + cfg_if::cfg_if! { if #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))] { #[doc(hidden)] mod static_local; #[doc(hidden)] pub use static_local::{Key, thread_local_inner}; - } else if #[cfg(all(target_thread_local))] { + } else if #[cfg(target_thread_local)] { #[doc(hidden)] mod fast_local; #[doc(hidden)] diff --git a/library/std/src/sys/common/thread_local/os_local.rs b/library/std/src/sys/common/thread_local/os_local.rs index d004897df28..5d48ce1e03b 100644 --- a/library/std/src/sys/common/thread_local/os_local.rs +++ b/library/std/src/sys/common/thread_local/os_local.rs @@ -18,7 +18,7 @@ pub macro thread_local_inner { ) -> $crate::option::Option<&'static $t> { const INIT_EXPR: $t = $init; - // On platforms without `#[thread_local]` we fall back to the + // On platforms without `#[thread_local]` we fall back to the // same implementation as below for os thread locals. #[inline] const fn __init() -> $t { INIT_EXPR } diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs index 3a2cdd301ea..ccde05aa1d7 100644 --- a/library/std/src/sys/hermit/fd.rs +++ b/library/std/src/sys/hermit/fd.rs @@ -75,6 +75,7 @@ impl FromRawFd for FileDesc { } impl AsInner<OwnedFd> for FileDesc { + #[inline] fn as_inner(&self) -> &OwnedFd { &self.fd } diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs index cf0b271761f..4bb735668d2 100644 --- a/library/std/src/sys/hermit/fs.rs +++ b/library/std/src/sys/hermit/fs.rs @@ -367,12 +367,14 @@ impl DirBuilder { } impl AsInner<FileDesc> for File { + #[inline] fn as_inner(&self) -> &FileDesc { &self.0 } } impl AsInnerMut<FileDesc> for File { + #[inline] fn as_inner_mut(&mut self) -> &mut FileDesc { &mut self.0 } @@ -397,6 +399,7 @@ impl AsFd for File { } impl AsRawFd for File { + #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs index d6f64a29719..8c2d489d6a3 100644 --- a/library/std/src/sys/hermit/net.rs +++ b/library/std/src/sys/hermit/net.rs @@ -340,6 +340,7 @@ impl Socket { } impl AsInner<FileDesc> for Socket { + #[inline] fn as_inner(&self) -> &FileDesc { &self.0 } @@ -364,6 +365,7 @@ impl AsFd for Socket { } impl AsRawFd for Socket { + #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } diff --git a/library/std/src/sys/hermit/time.rs b/library/std/src/sys/hermit/time.rs index 32ddc4346ee..5440d85df4a 100644 --- a/library/std/src/sys/hermit/time.rs +++ b/library/std/src/sys/hermit/time.rs @@ -40,11 +40,7 @@ impl Timespec { } fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `libc::time_t` - .ok() - .and_then(|secs| self.t.tv_sec.checked_add(secs))?; + let mut secs = self.tv_sec.checked_add_unsigned(other.as_secs())?; // Nano calculations can't overflow because nanos are <1B which fit // in a u32. @@ -57,11 +53,7 @@ impl Timespec { } fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `libc::time_t` - .ok() - .and_then(|secs| self.t.tv_sec.checked_sub(secs))?; + let mut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?; // Similar to above, nanos can't overflow. let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32; diff --git a/library/std/src/sys/sgx/abi/entry.S b/library/std/src/sys/sgx/abi/entry.S index ca79d1d796e..8a063b65dac 100644 --- a/library/std/src/sys/sgx/abi/entry.S +++ b/library/std/src/sys/sgx/abi/entry.S @@ -26,7 +26,7 @@ IMAGE_BASE: .Lxsave_clear: .org .+24 .Lxsave_mxcsr: - .short 0x1f80 + .short 0x1fbf /* We can store a bunch of data in the gap between MXCSR and the XSAVE header */ @@ -178,6 +178,7 @@ sgx_entry: mov $-1, %rax mov $-1, %rdx xrstor .Lxsave_clear(%rip) + lfence mov %r10, %rdx /* check if returning from usercall */ @@ -311,6 +312,9 @@ usercall: movq $0,%gs:tcsls_last_rsp /* restore callee-saved state, cf. "save" above */ mov %r11,%rsp + /* MCDT mitigation requires an lfence after ldmxcsr _before_ any of the affected */ + /* vector instructions is used. We omit the lfence here as one is required before */ + /* the jmp instruction anyway. */ ldmxcsr (%rsp) fldcw 4(%rsp) add $8, %rsp diff --git a/library/std/src/sys/sgx/fd.rs b/library/std/src/sys/sgx/fd.rs index 0c02a107691..b3686d0e283 100644 --- a/library/std/src/sys/sgx/fd.rs +++ b/library/std/src/sys/sgx/fd.rs @@ -62,6 +62,7 @@ impl FileDesc { } impl AsInner<Fd> for FileDesc { + #[inline] fn as_inner(&self) -> &Fd { &self.fd } diff --git a/library/std/src/sys/sgx/net.rs b/library/std/src/sys/sgx/net.rs index 923be5eb944..03620a08f2c 100644 --- a/library/std/src/sys/sgx/net.rs +++ b/library/std/src/sys/sgx/net.rs @@ -24,6 +24,7 @@ impl Socket { } impl AsInner<FileDesc> for Socket { + #[inline] fn as_inner(&self) -> &FileDesc { &self.inner } @@ -220,6 +221,7 @@ impl TcpStream { } impl AsInner<Socket> for TcpStream { + #[inline] fn as_inner(&self) -> &Socket { &self.inner } @@ -304,6 +306,7 @@ impl TcpListener { } impl AsInner<Socket> for TcpListener { + #[inline] fn as_inner(&self) -> &Socket { &self.inner } diff --git a/library/std/src/sys/solid/net.rs b/library/std/src/sys/solid/net.rs index 7d7bfae1432..0bd2bc3b961 100644 --- a/library/std/src/sys/solid/net.rs +++ b/library/std/src/sys/solid/net.rs @@ -112,6 +112,7 @@ impl FileDesc { } impl AsInner<c_int> for FileDesc { + #[inline] fn as_inner(&self) -> &c_int { &self.fd } @@ -462,6 +463,7 @@ impl Socket { } impl AsInner<c_int> for Socket { + #[inline] fn as_inner(&self) -> &c_int { self.0.as_inner() } diff --git a/library/std/src/sys/solid/time.rs b/library/std/src/sys/solid/time.rs index ce31cb45a69..f83f1644fe8 100644 --- a/library/std/src/sys/solid/time.rs +++ b/library/std/src/sys/solid/time.rs @@ -47,10 +47,10 @@ impl SystemTime { } pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { - Some(SystemTime(self.0.checked_add(other.as_secs().try_into().ok()?)?)) + Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?)) } pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { - Some(SystemTime(self.0.checked_sub(other.as_secs().try_into().ok()?)?)) + Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?)) } } diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index ce5c048f252..45f96478fc3 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -481,6 +481,7 @@ impl<'a> Read for &'a FileDesc { } impl AsInner<OwnedFd> for FileDesc { + #[inline] fn as_inner(&self) -> &OwnedFd { &self.0 } @@ -505,6 +506,7 @@ impl AsFd for FileDesc { } impl AsRawFd for FileDesc { + #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index abef170dd5a..b398fd5eb24 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -547,6 +547,7 @@ impl FileAttr { } impl AsInner<stat64> for FileAttr { + #[inline] fn as_inner(&self) -> &stat64 { &self.stat } @@ -1193,8 +1194,6 @@ impl File { None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }), } }; - #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))] - let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?]; cfg_if::cfg_if! { if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] { // Redox doesn't appear to support `UTIME_OMIT`. @@ -1206,6 +1205,7 @@ impl File { "setting file times not supported", )) } else if #[cfg(any(target_os = "android", target_os = "macos"))] { + let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?]; // futimens requires macOS 10.13, and Android API level 19 cvt(unsafe { weak!(fn futimens(c_int, *const libc::timespec) -> c_int); @@ -1232,6 +1232,22 @@ impl File { })?; Ok(()) } else { + #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] + { + use crate::sys::{time::__timespec64, weak::weak}; + + // Added in glibc 2.34 + weak!(fn __futimens64(libc::c_int, *const __timespec64) -> libc::c_int); + + if let Some(futimens64) = __futimens64.get() { + let to_timespec = |time: Option<SystemTime>| time.map(|time| time.t.to_timespec64()) + .unwrap_or(__timespec64::new(0, libc::UTIME_OMIT as _)); + let times = [to_timespec(times.accessed), to_timespec(times.modified)]; + cvt(unsafe { futimens64(self.as_raw_fd(), times.as_ptr()) })?; + return Ok(()); + } + } + let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?]; cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?; Ok(()) } @@ -1254,12 +1270,14 @@ impl DirBuilder { } impl AsInner<FileDesc> for File { + #[inline] fn as_inner(&self) -> &FileDesc { &self.0 } } impl AsInnerMut<FileDesc> for File { + #[inline] fn as_inner_mut(&mut self) -> &mut FileDesc { &mut self.0 } @@ -1284,6 +1302,7 @@ impl AsFd for File { } impl AsRawFd for File { + #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } diff --git a/library/std/src/sys/unix/l4re.rs b/library/std/src/sys/unix/l4re.rs index 9967588939a..ee016887e70 100644 --- a/library/std/src/sys/unix/l4re.rs +++ b/library/std/src/sys/unix/l4re.rs @@ -129,6 +129,7 @@ pub mod net { } impl AsInner<FileDesc> for Socket { + #[inline] fn as_inner(&self) -> &FileDesc { &self.0 } @@ -153,6 +154,7 @@ pub mod net { } impl AsRawFd for Socket { + #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } @@ -183,6 +185,7 @@ pub mod net { unimpl!(); } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } @@ -305,6 +308,7 @@ pub mod net { unimpl!(); } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } @@ -371,6 +375,7 @@ pub mod net { unimpl!(); } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 573bfa6587e..39edb136c24 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -490,6 +490,7 @@ impl Socket { } impl AsInner<FileDesc> for Socket { + #[inline] fn as_inner(&self) -> &FileDesc { &self.0 } @@ -514,6 +515,7 @@ impl AsFd for Socket { } impl AsRawFd for Socket { + #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } diff --git a/library/std/src/sys/unix/os_str.rs b/library/std/src/sys/unix/os_str.rs index 017e2af29d4..488217f3941 100644 --- a/library/std/src/sys/unix/os_str.rs +++ b/library/std/src/sys/unix/os_str.rs @@ -89,6 +89,7 @@ impl IntoInner<Vec<u8>> for Buf { } impl AsInner<[u8]> for Buf { + #[inline] fn as_inner(&self) -> &[u8] { &self.inner } diff --git a/library/std/src/sys/unix/pipe.rs b/library/std/src/sys/unix/pipe.rs index dc17c9fac46..938a46bfdd8 100644 --- a/library/std/src/sys/unix/pipe.rs +++ b/library/std/src/sys/unix/pipe.rs @@ -135,6 +135,7 @@ pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> } impl AsRawFd for AnonPipe { + #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 15070b1f6a7..7307d9b2c86 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -326,6 +326,25 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> { } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] { use crate::ptr; + #[cfg(target_os = "freebsd")] + { + let mut set: libc::cpuset_t = unsafe { mem::zeroed() }; + unsafe { + if libc::cpuset_getaffinity( + libc::CPU_LEVEL_WHICH, + libc::CPU_WHICH_PID, + -1, + mem::size_of::<libc::cpuset_t>(), + &mut set, + ) == 0 { + let count = libc::CPU_COUNT(&set) as usize; + if count > 0 { + return Ok(NonZeroUsize::new_unchecked(count)); + } + } + } + } + let mut cpus: libc::c_uint = 0; let mut cpus_size = crate::mem::size_of_val(&cpus); diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index 6f53583409d..a9fbc7ab108 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -113,11 +113,7 @@ impl Timespec { } pub fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `i64` - .ok() - .and_then(|secs| self.tv_sec.checked_add(secs))?; + let mut secs = self.tv_sec.checked_add_unsigned(other.as_secs())?; // Nano calculations can't overflow because nanos are <1B which fit // in a u32. @@ -126,15 +122,11 @@ impl Timespec { nsec -= NSEC_PER_SEC as u32; secs = secs.checked_add(1)?; } - Some(Timespec::new(secs, nsec as i64)) + Some(Timespec::new(secs, nsec.into())) } pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `i64` - .ok() - .and_then(|secs| self.tv_sec.checked_sub(secs))?; + let mut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?; // Similar to above, nanos can't overflow. let mut nsec = self.tv_nsec.0 as i32 - other.subsec_nanos() as i32; @@ -142,7 +134,7 @@ impl Timespec { nsec += NSEC_PER_SEC as i32; secs = secs.checked_sub(1)?; } - Some(Timespec::new(secs, nsec as i64)) + Some(Timespec::new(secs, nsec.into())) } #[allow(dead_code)] @@ -166,6 +158,16 @@ impl Timespec { } self.to_timespec() } + + #[cfg(all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") + ))] + pub fn to_timespec64(&self) -> __timespec64 { + __timespec64::new(self.tv_sec, self.tv_nsec.0 as _) + } } impl From<libc::timespec> for Timespec { @@ -196,6 +198,18 @@ pub(in crate::sys::unix) struct __timespec64 { target_pointer_width = "32", not(target_arch = "riscv32") ))] +impl __timespec64 { + pub(in crate::sys::unix) fn new(tv_sec: i64, tv_nsec: i32) -> Self { + Self { tv_sec, tv_nsec, _padding: 0 } + } +} + +#[cfg(all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") +))] impl From<__timespec64> for Timespec { fn from(t: __timespec64) -> Timespec { Timespec::new(t.tv_sec, t.tv_nsec.into()) diff --git a/library/std/src/sys/unsupported/mod.rs b/library/std/src/sys/unsupported/mod.rs index 15b22c620d5..e1a38de6471 100644 --- a/library/std/src/sys/unsupported/mod.rs +++ b/library/std/src/sys/unsupported/mod.rs @@ -22,6 +22,7 @@ pub mod thread; #[cfg(target_thread_local)] pub mod thread_local_dtor; pub mod thread_local_key; +pub mod thread_parking; pub mod time; mod common; diff --git a/library/std/src/sys/unsupported/thread_parking.rs b/library/std/src/sys/unsupported/thread_parking.rs new file mode 100644 index 00000000000..197078bb186 --- /dev/null +++ b/library/std/src/sys/unsupported/thread_parking.rs @@ -0,0 +1,11 @@ +use crate::pin::Pin; +use crate::time::Duration; + +pub struct Parker {} + +impl Parker { + pub unsafe fn new_in_place(_parker: *mut Parker) {} + pub unsafe fn park(self: Pin<&Self>) {} + pub unsafe fn park_timeout(self: Pin<&Self>, _dur: Duration) {} + pub fn unpark(self: Pin<&Self>) {} +} diff --git a/library/std/src/sys/wasi/fd.rs b/library/std/src/sys/wasi/fd.rs index 191db4b60f7..9a8b2a0be5b 100644 --- a/library/std/src/sys/wasi/fd.rs +++ b/library/std/src/sys/wasi/fd.rs @@ -275,12 +275,14 @@ impl WasiFd { } impl AsInner<OwnedFd> for WasiFd { + #[inline] fn as_inner(&self) -> &OwnedFd { &self.fd } } impl AsInnerMut<OwnedFd> for WasiFd { + #[inline] fn as_inner_mut(&mut self) -> &mut OwnedFd { &mut self.fd } @@ -305,6 +307,7 @@ impl AsFd for WasiFd { } impl AsRawFd for WasiFd { + #[inline] fn as_raw_fd(&self) -> RawFd { self.fd.as_raw_fd() } diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index 3a205267e34..8d1dbf59155 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -498,6 +498,7 @@ impl File { } impl AsInner<WasiFd> for File { + #[inline] fn as_inner(&self) -> &WasiFd { &self.fd } @@ -522,6 +523,7 @@ impl AsFd for File { } impl AsRawFd for File { + #[inline] fn as_raw_fd(&self) -> RawFd { self.fd.as_raw_fd() } diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs index c468ae395fc..a2223708024 100644 --- a/library/std/src/sys/wasi/mod.rs +++ b/library/std/src/sys/wasi/mod.rs @@ -47,6 +47,8 @@ pub mod thread; pub mod thread_local_dtor; #[path = "../unsupported/thread_local_key.rs"] pub mod thread_local_key; +#[path = "../unsupported/thread_parking.rs"] +pub mod thread_parking; pub mod time; cfg_if::cfg_if! { diff --git a/library/std/src/sys/wasi/net.rs b/library/std/src/sys/wasi/net.rs index 59d94a3686d..2239880ffbe 100644 --- a/library/std/src/sys/wasi/net.rs +++ b/library/std/src/sys/wasi/net.rs @@ -17,6 +17,7 @@ pub struct TcpStream { } impl AsInner<WasiFd> for Socket { + #[inline] fn as_inner(&self) -> &WasiFd { &self.0 } @@ -41,6 +42,7 @@ impl AsFd for Socket { } impl AsRawFd for Socket { + #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } @@ -184,6 +186,7 @@ impl TcpStream { } } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } @@ -274,6 +277,7 @@ impl TcpListener { } } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } @@ -284,6 +288,7 @@ impl TcpListener { } impl AsInner<Socket> for TcpListener { + #[inline] fn as_inner(&self) -> &Socket { &self.inner } @@ -436,6 +441,7 @@ impl UdpSocket { unsupported() } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } @@ -446,6 +452,7 @@ impl UdpSocket { } impl AsInner<Socket> for UdpSocket { + #[inline] fn as_inner(&self) -> &Socket { &self.inner } diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index 77ebe3c4ac6..6c05b56e1bf 100644 --- a/library/std/src/sys/wasm/mod.rs +++ b/library/std/src/sys/wasm/mod.rs @@ -70,6 +70,8 @@ cfg_if::cfg_if! { pub mod once; #[path = "../unsupported/thread.rs"] pub mod thread; + #[path = "../unsupported/thread_parking.rs"] + pub mod thread_parking; } } diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs index 43c0cdb657e..5bfd8b52ed0 100644 --- a/library/std/src/sys/windows/args.rs +++ b/library/std/src/sys/windows/args.rs @@ -313,6 +313,9 @@ pub(crate) fn make_bat_command_line( /// /// This is necessary because cmd.exe does not support verbatim paths. pub(crate) fn to_user_path(path: &Path) -> io::Result<Vec<u16>> { + from_wide_to_user_path(to_u16s(path)?) +} +pub(crate) fn from_wide_to_user_path(mut path: Vec<u16>) -> io::Result<Vec<u16>> { use crate::ptr; use crate::sys::windows::fill_utf16_buf; @@ -325,8 +328,6 @@ pub(crate) fn to_user_path(path: &Path) -> io::Result<Vec<u16>> { const N: u16 = b'N' as _; const C: u16 = b'C' as _; - let mut path = to_u16s(path)?; - // Early return if the path is too long to remove the verbatim prefix. const LEGACY_MAX_PATH: usize = 260; if path.len() > LEGACY_MAX_PATH { diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 8ed62cdddcd..fe052c8281b 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -477,7 +477,7 @@ impl File { fn reparse_point( &self, space: &mut Align8<[MaybeUninit<u8>]>, - ) -> io::Result<(c::DWORD, *const c::REPARSE_DATA_BUFFER)> { + ) -> io::Result<(c::DWORD, *mut c::REPARSE_DATA_BUFFER)> { unsafe { let mut bytes = 0; cvt({ @@ -496,7 +496,7 @@ impl File { ) })?; const _: () = assert!(core::mem::align_of::<c::REPARSE_DATA_BUFFER>() <= 8); - Ok((bytes, space.0.as_ptr().cast::<c::REPARSE_DATA_BUFFER>())) + Ok((bytes, space.0.as_mut_ptr().cast::<c::REPARSE_DATA_BUFFER>())) } } @@ -506,22 +506,22 @@ impl File { unsafe { let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag { c::IO_REPARSE_TAG_SYMLINK => { - let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER = - ptr::addr_of!((*buf).rest).cast(); + let info: *mut c::SYMBOLIC_LINK_REPARSE_BUFFER = + ptr::addr_of_mut!((*buf).rest).cast(); assert!(info.is_aligned()); ( - ptr::addr_of!((*info).PathBuffer).cast::<u16>(), + ptr::addr_of_mut!((*info).PathBuffer).cast::<u16>(), (*info).SubstituteNameOffset / 2, (*info).SubstituteNameLength / 2, (*info).Flags & c::SYMLINK_FLAG_RELATIVE != 0, ) } c::IO_REPARSE_TAG_MOUNT_POINT => { - let info: *const c::MOUNT_POINT_REPARSE_BUFFER = - ptr::addr_of!((*buf).rest).cast(); + let info: *mut c::MOUNT_POINT_REPARSE_BUFFER = + ptr::addr_of_mut!((*buf).rest).cast(); assert!(info.is_aligned()); ( - ptr::addr_of!((*info).PathBuffer).cast::<u16>(), + ptr::addr_of_mut!((*info).PathBuffer).cast::<u16>(), (*info).SubstituteNameOffset / 2, (*info).SubstituteNameLength / 2, false, @@ -535,13 +535,20 @@ impl File { } }; let subst_ptr = path_buffer.add(subst_off.into()); - let mut subst = slice::from_raw_parts(subst_ptr, subst_len as usize); + let subst = slice::from_raw_parts_mut(subst_ptr, subst_len as usize); // Absolute paths start with an NT internal namespace prefix `\??\` // We should not let it leak through. if !relative && subst.starts_with(&[92u16, 63u16, 63u16, 92u16]) { - subst = &subst[4..]; + // Turn `\??\` into `\\?\` (a verbatim path). + subst[1] = b'\\' as u16; + // Attempt to convert to a more user-friendly path. + let user = super::args::from_wide_to_user_path( + subst.iter().copied().chain([0]).collect(), + )?; + Ok(PathBuf::from(OsString::from_wide(&user.strip_suffix(&[0]).unwrap_or(&user)))) + } else { + Ok(PathBuf::from(OsString::from_wide(subst))) } - Ok(PathBuf::from(OsString::from_wide(subst))) } } @@ -832,6 +839,7 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result< } impl AsInner<Handle> for File { + #[inline] fn as_inner(&self) -> &Handle { &self.handle } diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs index b290f4070e8..c7677d1c13a 100644 --- a/library/std/src/sys/windows/handle.rs +++ b/library/std/src/sys/windows/handle.rs @@ -34,6 +34,7 @@ impl Handle { } impl AsInner<OwnedHandle> for Handle { + #[inline] fn as_inner(&self) -> &OwnedHandle { &self.0 } diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index ee1f5482b47..8158713fa84 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -446,6 +446,7 @@ impl<'a> Read for &'a Socket { } impl AsInner<OwnedSocket> for Socket { + #[inline] fn as_inner(&self) -> &OwnedSocket { &self.0 } diff --git a/library/std/src/sys/windows/os_str.rs b/library/std/src/sys/windows/os_str.rs index 4bdd8c505ff..2f2b0e56e08 100644 --- a/library/std/src/sys/windows/os_str.rs +++ b/library/std/src/sys/windows/os_str.rs @@ -27,6 +27,7 @@ impl FromInner<Wtf8Buf> for Buf { } impl AsInner<Wtf8> for Buf { + #[inline] fn as_inner(&self) -> &Wtf8 { &self.inner } diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index cb24caa1e8a..652c695fc57 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -239,6 +239,7 @@ impl TcpStream { Ok(TcpStream { inner: sock }) } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } @@ -352,6 +353,7 @@ impl TcpStream { } impl AsInner<Socket> for TcpStream { + #[inline] fn as_inner(&self) -> &Socket { &self.inner } @@ -427,6 +429,7 @@ impl TcpListener { Ok(TcpListener { inner: sock }) } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } @@ -517,6 +520,7 @@ impl UdpSocket { Ok(UdpSocket { inner: sock }) } + #[inline] pub fn socket(&self) -> &Socket { &self.inner } diff --git a/library/std/src/sys_common/thread_parking/generic.rs b/library/std/src/sys_common/thread_parking/generic.rs deleted file mode 100644 index 3209bffe353..00000000000 --- a/library/std/src/sys_common/thread_parking/generic.rs +++ /dev/null @@ -1,125 +0,0 @@ -//! Parker implementation based on a Mutex and Condvar. - -use crate::pin::Pin; -use crate::sync::atomic::AtomicUsize; -use crate::sync::atomic::Ordering::SeqCst; -use crate::sync::{Condvar, Mutex}; -use crate::time::Duration; - -const EMPTY: usize = 0; -const PARKED: usize = 1; -const NOTIFIED: usize = 2; - -pub struct Parker { - state: AtomicUsize, - lock: Mutex<()>, - cvar: Condvar, -} - -impl Parker { - /// Construct the generic parker. The UNIX parker implementation - /// requires this to happen in-place. - pub unsafe fn new_in_place(parker: *mut Parker) { - parker.write(Parker { - state: AtomicUsize::new(EMPTY), - lock: Mutex::new(()), - cvar: Condvar::new(), - }); - } - - // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. - pub unsafe fn park(self: Pin<&Self>) { - // If we were previously notified then we consume this notification and - // return quickly. - if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() { - return; - } - - // Otherwise we need to coordinate going to sleep - let mut m = self.lock.lock().unwrap(); - match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) { - Ok(_) => {} - Err(NOTIFIED) => { - // We must read here, even though we know it will be `NOTIFIED`. - // This is because `unpark` may have been called again since we read - // `NOTIFIED` in the `compare_exchange` above. We must perform an - // acquire operation that synchronizes with that `unpark` to observe - // any writes it made before the call to unpark. To do that we must - // read from the write it made to `state`. - let old = self.state.swap(EMPTY, SeqCst); - assert_eq!(old, NOTIFIED, "park state changed unexpectedly"); - return; - } // should consume this notification, so prohibit spurious wakeups in next park. - Err(_) => panic!("inconsistent park state"), - } - loop { - m = self.cvar.wait(m).unwrap(); - match self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) { - Ok(_) => return, // got a notification - Err(_) => {} // spurious wakeup, go back to sleep - } - } - } - - // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. - pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) { - // Like `park` above we have a fast path for an already-notified thread, and - // afterwards we start coordinating for a sleep. - // return quickly. - if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() { - return; - } - let m = self.lock.lock().unwrap(); - match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) { - Ok(_) => {} - Err(NOTIFIED) => { - // We must read again here, see `park`. - let old = self.state.swap(EMPTY, SeqCst); - assert_eq!(old, NOTIFIED, "park state changed unexpectedly"); - return; - } // should consume this notification, so prohibit spurious wakeups in next park. - Err(_) => panic!("inconsistent park_timeout state"), - } - - // Wait with a timeout, and if we spuriously wake up or otherwise wake up - // from a notification we just want to unconditionally set the state back to - // empty, either consuming a notification or un-flagging ourselves as - // parked. - let (_m, _result) = self.cvar.wait_timeout(m, dur).unwrap(); - match self.state.swap(EMPTY, SeqCst) { - NOTIFIED => {} // got a notification, hurray! - PARKED => {} // no notification, alas - n => panic!("inconsistent park_timeout state: {n}"), - } - } - - // This implementation doesn't require `Pin`, but other implementations do. - pub fn unpark(self: Pin<&Self>) { - // To ensure the unparked thread will observe any writes we made - // before this call, we must perform a release operation that `park` - // can synchronize with. To do that we must write `NOTIFIED` even if - // `state` is already `NOTIFIED`. That is why this must be a swap - // rather than a compare-and-swap that returns if it reads `NOTIFIED` - // on failure. - match self.state.swap(NOTIFIED, SeqCst) { - EMPTY => return, // no one was waiting - NOTIFIED => return, // already unparked - PARKED => {} // gotta go wake someone up - _ => panic!("inconsistent state in unpark"), - } - - // There is a period between when the parked thread sets `state` to - // `PARKED` (or last checked `state` in the case of a spurious wake - // up) and when it actually waits on `cvar`. If we were to notify - // during this period it would be ignored and then when the parked - // thread went to sleep it would never wake up. Fortunately, it has - // `lock` locked at this stage so we can acquire `lock` to wait until - // it is ready to receive the notification. - // - // Releasing `lock` before the call to `notify_one` means that when the - // parked thread wakes it doesn't get woken only to have to wait for us - // to release `lock`. - drop(self.lock.lock().unwrap()); - self.cvar.notify_one() - } -} diff --git a/library/std/src/sys_common/thread_parking/mod.rs b/library/std/src/sys_common/thread_parking/mod.rs index e8e028bb330..c4d3f9ea2f4 100644 --- a/library/std/src/sys_common/thread_parking/mod.rs +++ b/library/std/src/sys_common/thread_parking/mod.rs @@ -18,10 +18,7 @@ cfg_if::cfg_if! { ))] { mod id; pub use id::Parker; - } else if #[cfg(any(windows, target_family = "unix"))] { - pub use crate::sys::thread_parking::Parker; } else { - mod generic; - pub use generic::Parker; + pub use crate::sys::thread_parking::Parker; } } diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index bc588bdbb3c..ff96c35fb0b 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -501,6 +501,7 @@ pub struct Wtf8 { } impl AsInner<[u8]> for Wtf8 { + #[inline] fn as_inner(&self) -> &[u8] { &self.bytes } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 9cdc17a287c..f712c872708 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -193,22 +193,22 @@ pub use scoped::{scope, Scope, ScopedJoinHandle}; #[macro_use] mod local; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::local::{AccessError, LocalKey}; - -// Provide the type used by the thread_local! macro to access TLS keys. This -// needs to be kept in sync with the macro itself (in `local.rs`). -// There are three types: "static", "fast", "OS". The "OS" thread local key -// type is accessed via platform-specific API calls and is slow, while the "fast" -// key type is accessed via code generated via LLVM, where TLS keys are set up -// by the elf linker. "static" is for single-threaded platforms where a global -// static is sufficient. - -// Implementation details used by the thread_local!{} macro. -#[doc(hidden)] -#[unstable(feature = "thread_local_internals", issue = "none")] -pub mod local_impl { - pub use crate::sys::common::thread_local::{thread_local_inner, Key}; +cfg_if::cfg_if! { + if #[cfg(test)] { + // Avoid duplicating the global state assoicated with thread-locals between this crate and + // realstd. Miri relies on this. + pub use realstd::thread::{local_impl, AccessError, LocalKey}; + } else { + #[stable(feature = "rust1", since = "1.0.0")] + pub use self::local::{AccessError, LocalKey}; + + // Implementation details used by the thread_local!{} macro. + #[doc(hidden)] + #[unstable(feature = "thread_local_internals", issue = "none")] + pub mod local_impl { + pub use crate::sys::common::thread_local::{thread_local_inner, Key}; + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 5c2e9da70fb..00e2857a137 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -119,7 +119,7 @@ pub use core::time::TryFromFloatSecsError; /// [QueryPerformanceCounter]: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter /// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode -/// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md#clock_time_get +/// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#clock_time_get /// [clock_gettime (Monotonic Clock)]: https://linux.die.net/man/3/clock_gettime /// [mach_absolute_time]: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html /// @@ -224,7 +224,7 @@ pub struct Instant(time::Instant); /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode /// [gettimeofday]: https://man7.org/linux/man-pages/man2/gettimeofday.2.html /// [clock_gettime (Realtime Clock)]: https://linux.die.net/man/3/clock_gettime -/// [__wasi_clock_time_get (Realtime Clock)]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md#clock_time_get +/// [__wasi_clock_time_get (Realtime Clock)]: https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#clock_time_get /// [GetSystemTimePreciseAsFileTime]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime /// [GetSystemTimeAsFileTime]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime /// diff --git a/library/std/src/time/tests.rs b/library/std/src/time/tests.rs index 2e64ae59aff..6ed84806e6d 100644 --- a/library/std/src/time/tests.rs +++ b/library/std/src/time/tests.rs @@ -1,4 +1,5 @@ use super::{Duration, Instant, SystemTime, UNIX_EPOCH}; +use core::fmt::Debug; #[cfg(not(target_arch = "wasm32"))] use test::{black_box, Bencher}; @@ -201,6 +202,32 @@ fn since_epoch() { assert!(a < hundred_twenty_years); } +#[test] +fn big_math() { + // Check that the same result occurs when adding/subtracting each duration one at a time as when + // adding/subtracting them all at once. + #[track_caller] + fn check<T: Eq + Copy + Debug>(start: Option<T>, op: impl Fn(&T, Duration) -> Option<T>) { + const DURATIONS: [Duration; 2] = + [Duration::from_secs(i64::MAX as _), Duration::from_secs(50)]; + if let Some(start) = start { + assert_eq!( + op(&start, DURATIONS.into_iter().sum()), + DURATIONS.into_iter().try_fold(start, |t, d| op(&t, d)) + ) + } + } + + check(SystemTime::UNIX_EPOCH.checked_sub(Duration::from_secs(100)), SystemTime::checked_add); + check(SystemTime::UNIX_EPOCH.checked_add(Duration::from_secs(100)), SystemTime::checked_sub); + + let instant = Instant::now(); + check(instant.checked_sub(Duration::from_secs(100)), Instant::checked_add); + check(instant.checked_sub(Duration::from_secs(i64::MAX as _)), Instant::checked_add); + check(instant.checked_add(Duration::from_secs(100)), Instant::checked_sub); + check(instant.checked_add(Duration::from_secs(i64::MAX as _)), Instant::checked_sub); +} + macro_rules! bench_instant_threaded { ($bench_name:ident, $thread_count:expr) => { #[bench] diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml new file mode 100644 index 00000000000..5356ee277cc --- /dev/null +++ b/library/sysroot/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "sysroot" +version = "0.0.0" +edition = "2021" + +# this is a dummy crate to ensure that all required crates appear in the sysroot +[dependencies] +proc_macro = { path = "../proc_macro" } +std = { path = "../std" } +test = { path = "../test" } + +# Forward features to the `std` crate as necessary +[features] +default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"] +backtrace = ["std/backtrace"] +compiler-builtins-c = ["std/compiler-builtins-c"] +compiler-builtins-mem = ["std/compiler-builtins-mem"] +compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"] +compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"] +llvm-libunwind = ["std/llvm-libunwind"] +system-llvm-libunwind = ["std/system-llvm-libunwind"] +panic-unwind = ["std/panic_unwind"] +panic_immediate_abort = ["std/panic_immediate_abort"] +profiler = ["std/profiler"] +std_detect_file_io = ["std/std_detect_file_io"] +std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"] +std_detect_env_override = ["std/std_detect_env_override"] diff --git a/library/sysroot/src/lib.rs b/library/sysroot/src/lib.rs new file mode 100644 index 00000000000..71ceb580a40 --- /dev/null +++ b/library/sysroot/src/lib.rs @@ -0,0 +1 @@ +// This is intentionally empty since this crate is only used to depend on other library crates. diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index 18cb023d274..91a1abde059 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -12,23 +12,3 @@ std = { path = "../std" } core = { path = "../core" } panic_unwind = { path = "../panic_unwind" } panic_abort = { path = "../panic_abort" } - -# not actually used but needed to always have proc_macro in the sysroot -proc_macro = { path = "../proc_macro" } - -# Forward features to the `std` crate as necessary -[features] -default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"] -backtrace = ["std/backtrace"] -compiler-builtins-c = ["std/compiler-builtins-c"] -compiler-builtins-mem = ["std/compiler-builtins-mem"] -compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"] -compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"] -llvm-libunwind = ["std/llvm-libunwind"] -system-llvm-libunwind = ["std/system-llvm-libunwind"] -panic-unwind = ["std/panic_unwind"] -panic_immediate_abort = ["std/panic_immediate_abort"] -profiler = ["std/profiler"] -std_detect_file_io = ["std/std_detect_file_io"] -std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"] -std_detect_env_override = ["std/std_detect_env_override"] diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs index 8572d1c20ce..47c4e7757e4 100644 --- a/library/test/src/formatters/json.rs +++ b/library/test/src/formatters/json.rs @@ -18,14 +18,10 @@ impl<T: Write> JsonFormatter<T> { } fn writeln_message(&mut self, s: &str) -> io::Result<()> { - assert!(!s.contains('\n')); - - self.out.write_all(s.as_ref())?; - self.out.write_all(b"\n") - } - - fn write_message(&mut self, s: &str) -> io::Result<()> { - assert!(!s.contains('\n')); + // self.out will take a lock, but that lock is released when write_all returns. This + // results in a race condition and json output may not end with a new line. We avoid this + // by issuing `write_all` calls line-by-line. + assert_eq!(s.chars().last(), Some('\n')); self.out.write_all(s.as_ref()) } @@ -34,34 +30,35 @@ impl<T: Write> JsonFormatter<T> { &mut self, ty: &str, name: &str, - evt: &str, + event: &str, exec_time: Option<&time::TestExecTime>, stdout: Option<Cow<'_, str>>, extra: Option<&str>, ) -> io::Result<()> { // A doc test's name includes a filename which must be escaped for correct json. - self.write_message(&format!( - r#"{{ "type": "{}", "name": "{}", "event": "{}""#, - ty, - EscapedString(name), - evt - ))?; - if let Some(exec_time) = exec_time { - self.write_message(&format!(r#", "exec_time": {}"#, exec_time.0.as_secs_f64()))?; - } - if let Some(stdout) = stdout { - self.write_message(&format!(r#", "stdout": "{}""#, EscapedString(stdout)))?; - } - if let Some(extra) = extra { - self.write_message(&format!(r#", {extra}"#))?; - } - self.writeln_message(" }") + let name = EscapedString(name); + let exec_time_json = if let Some(exec_time) = exec_time { + format!(r#", "exec_time": {}"#, exec_time.0.as_secs_f64()) + } else { + String::from("") + }; + let stdout_json = if let Some(stdout) = stdout { + format!(r#", "stdout": "{}""#, EscapedString(stdout)) + } else { + String::from("") + }; + let extra_json = + if let Some(extra) = extra { format!(r#", {extra}"#) } else { String::from("") }; + let newline = "\n"; + + self.writeln_message(&format!( + r#"{{ "type": "{ty}", "name": "{name}", "event": "{event}"{exec_time_json}{stdout_json}{extra_json} }}{newline}"#)) } } impl<T: Write> OutputFormatter for JsonFormatter<T> { fn write_discovery_start(&mut self) -> io::Result<()> { - self.writeln_message(&format!(r#"{{ "type": "suite", "event": "discovery" }}"#)) + self.writeln_message(concat!(r#"{ "type": "suite", "event": "discovery" }"#, "\n")) } fn write_test_discovered(&mut self, desc: &TestDesc, test_type: &str) -> io::Result<()> { @@ -77,11 +74,13 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> { .. } = desc; + let name = EscapedString(name.as_slice()); + let ignore_message = ignore_message.unwrap_or(""); + let source_path = EscapedString(source_file); + let newline = "\n"; + self.writeln_message(&format!( - r#"{{ "type": "{test_type}", "event": "discovered", "name": "{}", "ignore": {ignore}, "ignore_message": "{}", "source_path": "{}", "start_line": {start_line}, "start_col": {start_col}, "end_line": {end_line}, "end_col": {end_col} }}"#, - EscapedString(name.as_slice()), - ignore_message.unwrap_or(""), - EscapedString(source_file), + r#"{{ "type": "{test_type}", "event": "discovered", "name": "{name}", "ignore": {ignore}, "ignore_message": "{ignore_message}", "source_path": "{source_path}", "start_line": {start_line}, "start_col": {start_col}, "end_line": {end_line}, "end_col": {end_col} }}{newline}"# )) } @@ -89,9 +88,10 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> { let ConsoleTestDiscoveryState { tests, benchmarks, ignored, .. } = state; let total = tests + benchmarks; + let newline = "\n"; self.writeln_message(&format!( - r#"{{ "type": "suite", "event": "completed", "tests": {tests}, "benchmarks": {benchmarks}, "total": {total}, "ignored": {ignored} }}"# - )) + r#"{{ "type": "suite", "event": "completed", "tests": {tests}, "benchmarks": {benchmarks}, "total": {total}, "ignored": {ignored} }}{newline}"# + )) } fn write_run_start(&mut self, test_count: usize, shuffle_seed: Option<u64>) -> io::Result<()> { @@ -100,15 +100,17 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> { } else { String::new() }; + let newline = "\n"; self.writeln_message(&format!( - r#"{{ "type": "suite", "event": "started", "test_count": {test_count}{shuffle_seed_json} }}"# - )) + r#"{{ "type": "suite", "event": "started", "test_count": {test_count}{shuffle_seed_json} }}{newline}"# + )) } fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> { + let name = EscapedString(desc.name.as_slice()); + let newline = "\n"; self.writeln_message(&format!( - r#"{{ "type": "test", "event": "started", "name": "{}" }}"#, - EscapedString(desc.name.as_slice()) + r#"{{ "type": "test", "event": "started", "name": "{name}" }}{newline}"# )) } @@ -173,53 +175,43 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> { } else { format!(r#", "mib_per_second": {}"#, bs.mb_s) }; + let name = EscapedString(desc.name.as_slice()); - let line = format!( + self.writeln_message(&format!( "{{ \"type\": \"bench\", \ - \"name\": \"{}\", \ - \"median\": {}, \ - \"deviation\": {}{} }}", - EscapedString(desc.name.as_slice()), - median, - deviation, - mbps - ); - - self.writeln_message(&line) + \"name\": \"{name}\", \ + \"median\": {median}, \ + \"deviation\": {deviation}{mbps} }}\n", + )) } } } fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> { + let name = EscapedString(desc.name.as_slice()); + let newline = "\n"; self.writeln_message(&format!( - r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#, - EscapedString(desc.name.as_slice()) + r#"{{ "type": "test", "event": "timeout", "name": "{name}" }}{newline}"#, )) } fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> { - self.write_message(&format!( - "{{ \"type\": \"suite\", \ - \"event\": \"{}\", \ - \"passed\": {}, \ - \"failed\": {}, \ - \"ignored\": {}, \ - \"measured\": {}, \ - \"filtered_out\": {}", - if state.failed == 0 { "ok" } else { "failed" }, - state.passed, - state.failed, - state.ignored, - state.measured, - state.filtered_out, - ))?; - - if let Some(ref exec_time) = state.exec_time { - let time_str = format!(", \"exec_time\": {}", exec_time.0.as_secs_f64()); - self.write_message(&time_str)?; - } + let event = if state.failed == 0 { "ok" } else { "failed" }; + let passed = state.passed; + let failed = state.failed; + let ignored = state.ignored; + let measured = state.measured; + let filtered_out = state.filtered_out; + let exec_time_json = if let Some(ref exec_time) = state.exec_time { + format!(r#", "exec_time": {}"#, exec_time.0.as_secs_f64()) + } else { + String::from("") + }; + let newline = "\n"; - self.writeln_message(" }")?; + self.writeln_message(&format!( + r#"{{ "type": "suite", "event": "{event}", "passed": {passed}, "failed": {failed}, "ignored": {ignored}, "measured": {measured}, "filtered_out": {filtered_out}{exec_time_json} }}{newline}"# + ))?; Ok(state.failed == 0) } diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs index 2e07ce3c099..9f5bf24367e 100644 --- a/library/test/src/formatters/junit.rs +++ b/library/test/src/formatters/junit.rs @@ -11,7 +11,7 @@ use crate::{ pub struct JunitFormatter<T> { out: OutputLocation<T>, - results: Vec<(TestDesc, TestResult, Duration)>, + results: Vec<(TestDesc, TestResult, Duration, Vec<u8>)>, } impl<T: Write> JunitFormatter<T> { @@ -26,6 +26,18 @@ impl<T: Write> JunitFormatter<T> { } } +fn str_to_cdata(s: &str) -> String { + // Drop the stdout in a cdata. Unfortunately, you can't put either of `]]>` or + // `<?'` in a CDATA block, so the escaping gets a little weird. + let escaped_output = s.replace("]]>", "]]]]><![CDATA[>"); + let escaped_output = escaped_output.replace("<?", "<]]><![CDATA[?"); + // We also smuggle newlines as 
 so as to keep all the output on one line + let escaped_output = escaped_output.replace("\n", "]]>
<![CDATA["); + // Prune empty CDATA blocks resulting from any escaping + let escaped_output = escaped_output.replace("<![CDATA[]]>", ""); + format!("<![CDATA[{}]]>", escaped_output) +} + impl<T: Write> OutputFormatter for JunitFormatter<T> { fn write_discovery_start(&mut self) -> io::Result<()> { Err(io::Error::new(io::ErrorKind::NotFound, "Not yet implemented!")) @@ -63,14 +75,14 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> { desc: &TestDesc, result: &TestResult, exec_time: Option<&time::TestExecTime>, - _stdout: &[u8], + stdout: &[u8], _state: &ConsoleTestState, ) -> io::Result<()> { // Because the testsuite node holds some of the information as attributes, we can't write it // until all of the tests have finished. Instead of writing every result as they come in, we add // them to a Vec and write them all at once when run is complete. let duration = exec_time.map(|t| t.0).unwrap_or_default(); - self.results.push((desc.clone(), result.clone(), duration)); + self.results.push((desc.clone(), result.clone(), duration, stdout.to_vec())); Ok(()) } fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> { @@ -85,7 +97,7 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> { >", state.failed, state.total, state.ignored ))?; - for (desc, result, duration) in std::mem::take(&mut self.results) { + for (desc, result, duration, stdout) in std::mem::take(&mut self.results) { let (class_name, test_name) = parse_class_name(&desc); match result { TestResult::TrIgnored => { /* no-op */ } @@ -98,6 +110,11 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> { duration.as_secs_f64() ))?; self.write_message("<failure type=\"assert\"/>")?; + if !stdout.is_empty() { + self.write_message("<system-out>")?; + self.write_message(&str_to_cdata(&String::from_utf8_lossy(&stdout)))?; + self.write_message("</system-out>")?; + } self.write_message("</testcase>")?; } @@ -110,6 +127,11 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> { duration.as_secs_f64() ))?; self.write_message(&format!("<failure message=\"{m}\" type=\"assert\"/>"))?; + if !stdout.is_empty() { + self.write_message("<system-out>")?; + self.write_message(&str_to_cdata(&String::from_utf8_lossy(&stdout)))?; + self.write_message("</system-out>")?; + } self.write_message("</testcase>")?; } @@ -136,11 +158,19 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> { TestResult::TrOk => { self.write_message(&format!( "<testcase classname=\"{}\" \ - name=\"{}\" time=\"{}\"/>", + name=\"{}\" time=\"{}\"", class_name, test_name, duration.as_secs_f64() ))?; + if stdout.is_empty() || !state.options.display_output { + self.write_message("/>")?; + } else { + self.write_message("><system-out>")?; + self.write_message(&str_to_cdata(&String::from_utf8_lossy(&stdout)))?; + self.write_message("</system-out>")?; + self.write_message("</testcase>")?; + } } } } diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 19d67e80a61..dfe6bb7f057 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -12,6 +12,12 @@ dependencies = [ ] [[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -38,10 +44,10 @@ version = "0.0.0" dependencies = [ "build_helper", "cc", + "clap", "cmake", "fd-lock", "filetime", - "getopts", "hex", "ignore", "is-terminal", @@ -92,6 +98,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] +name = "clap" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" +dependencies = [ + "anstyle", + "bitflags", + "clap_lex", +] + +[[package]] +name = "clap_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "clap_lex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] name = "cmake" version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -175,7 +221,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" dependencies = [ "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -261,15 +307,6 @@ dependencies = [ ] [[package]] -name = "getopts" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" -dependencies = [ - "unicode-width", -] - -[[package]] name = "globset" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -283,6 +320,12 @@ dependencies = [ ] [[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -486,18 +529,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.46" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -606,7 +649,7 @@ checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -643,6 +686,17 @@ dependencies = [ ] [[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] name = "sysinfo" version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -708,12 +762,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" [[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 7b9eaceb00f..fd5eb740630 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -34,7 +34,6 @@ is-terminal = "0.4" build_helper = { path = "../tools/build_helper" } cmake = "0.1.38" filetime = "0.2" -getopts = "0.2.19" cc = "1.0.69" libc = "0.2" hex = "0.4" @@ -56,6 +55,7 @@ walkdir = "2" # Dependencies needed by the build-metrics feature sysinfo = { version = "0.26.0", optional = true } +clap = { version = "4.2.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] } # Solaris doesn't support flock() and thus fd-lock is not option now [target.'cfg(not(target_os = "solaris"))'.dependencies] @@ -86,6 +86,7 @@ build-metrics = ["sysinfo"] # dependencies, only bootstrap itself. [profile.dev] debug = 0 + [profile.dev.package] # Only use debuginfo=1 to further reduce compile times. bootstrap.debug = 1 diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index dd0b091a2a3..f22cdad7df4 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -28,6 +28,20 @@ if platform_is_win32(): else: EXE_SUFFIX = "" +def get_cpus(): + if hasattr(os, "sched_getaffinity"): + return len(os.sched_getaffinity(0)) + if hasattr(os, "cpu_count"): + cpus = os.cpu_count() + if cpus is not None: + return cpus + try: + return cpu_count() + except NotImplementedError: + return 1 + + + def get(base, url, path, checksums, verbose=False): with tempfile.NamedTemporaryFile(delete=False) as temp_file: temp_path = temp_file.name @@ -540,11 +554,15 @@ class RustBuild(object): # Unpack the tarballs in parallle. # In Python 2.7, Pool cannot be used as a context manager. - p = Pool(min(len(tarballs_download_info), cpu_count())) + pool_size = min(len(tarballs_download_info), get_cpus()) + if self.verbose: + print('Choosing a pool size of', pool_size, 'for the unpacking of the tarballs') + p = Pool(pool_size) try: p.map(unpack_component, tarballs_download_info) finally: p.close() + p.join() if self.should_fix_bins_and_dylibs(): self.fix_bin_or_dylib("{}/bin/cargo".format(bin_root)) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d9d4685dfc7..1267c0be719 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -33,6 +33,7 @@ pub use crate::Compiler; // - use std::lazy for `Lazy` // - use std::cell for `OnceCell` // Once they get stabilized and reach beta. +use clap::ValueEnum; use once_cell::sync::{Lazy, OnceCell}; pub struct Builder<'a> { @@ -576,19 +577,24 @@ impl<'a> ShouldRun<'a> { } } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, ValueEnum)] pub enum Kind { + #[clap(alias = "b")] Build, + #[clap(alias = "c")] Check, Clippy, Fix, Format, + #[clap(alias = "t")] Test, Bench, + #[clap(alias = "d")] Doc, Clean, Dist, Install, + #[clap(alias = "r")] Run, Setup, Suggest, @@ -887,18 +893,19 @@ impl<'a> Builder<'a> { } pub fn new(build: &Build) -> Builder<'_> { + let paths = &build.config.paths; let (kind, paths) = match build.config.cmd { - Subcommand::Build { ref paths } => (Kind::Build, &paths[..]), - Subcommand::Check { ref paths } => (Kind::Check, &paths[..]), - Subcommand::Clippy { ref paths, .. } => (Kind::Clippy, &paths[..]), - Subcommand::Fix { ref paths } => (Kind::Fix, &paths[..]), - Subcommand::Doc { ref paths, .. } => (Kind::Doc, &paths[..]), - Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]), - Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]), - Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]), - Subcommand::Install { ref paths } => (Kind::Install, &paths[..]), - Subcommand::Run { ref paths, .. } => (Kind::Run, &paths[..]), - Subcommand::Clean { ref paths, .. } => (Kind::Clean, &paths[..]), + Subcommand::Build => (Kind::Build, &paths[..]), + Subcommand::Check { .. } => (Kind::Check, &paths[..]), + Subcommand::Clippy { .. } => (Kind::Clippy, &paths[..]), + Subcommand::Fix => (Kind::Fix, &paths[..]), + Subcommand::Doc { .. } => (Kind::Doc, &paths[..]), + Subcommand::Test { .. } => (Kind::Test, &paths[..]), + Subcommand::Bench { .. } => (Kind::Bench, &paths[..]), + Subcommand::Dist => (Kind::Dist, &paths[..]), + Subcommand::Install => (Kind::Install, &paths[..]), + Subcommand::Run { .. } => (Kind::Run, &paths[..]), + Subcommand::Clean { .. } => (Kind::Clean, &paths[..]), Subcommand::Format { .. } => (Kind::Format, &[][..]), Subcommand::Suggest { .. } => (Kind::Suggest, &[][..]), Subcommand::Setup { profile: ref path } => ( diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 72ac46b6bfd..c32fe59bbf0 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -236,7 +236,7 @@ mod defaults { fn doc_default() { let mut config = configure("doc", &["A"], &["A"]); config.compiler_docs = true; - config.cmd = Subcommand::Doc { paths: Vec::new(), open: false, json: false }; + config.cmd = Subcommand::Doc { open: false, json: false }; let mut cache = run_build(&[], config); let a = TargetSelection::from_user("A"); @@ -545,12 +545,13 @@ mod dist { fn test_with_no_doc_stage0() { let mut config = configure(&["A"], &["A"]); config.stage = 0; + config.paths = vec!["library/std".into()]; config.cmd = Subcommand::Test { - paths: vec!["library/std".into()], test_args: vec![], rustc_args: vec![], - fail_fast: true, - doc_tests: DocTests::No, + no_fail_fast: false, + no_doc: true, + doc: false, bless: false, force_rerun: false, compare_mode: None, @@ -558,6 +559,7 @@ mod dist { pass: None, run: None, only_modified: false, + skip: vec![], }; let build = Build::new(config); @@ -587,7 +589,7 @@ mod dist { fn doc_ci() { let mut config = configure(&["A"], &["A"]); config.compiler_docs = true; - config.cmd = Subcommand::Doc { paths: Vec::new(), open: false, json: false }; + config.cmd = Subcommand::Doc { open: false, json: false }; let build = Build::new(config); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); @@ -616,11 +618,12 @@ mod dist { // Behavior of `x.py test` doing various documentation tests. let mut config = configure(&["A"], &["A"]); config.cmd = Subcommand::Test { - paths: vec![], test_args: vec![], rustc_args: vec![], - fail_fast: true, - doc_tests: DocTests::Yes, + no_fail_fast: false, + doc: true, + no_doc: false, + skip: vec![], bless: false, force_rerun: false, compare_mode: None, diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 60de46ce64c..b11be96cefe 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -20,15 +20,7 @@ fn args(builder: &Builder<'_>) -> Vec<String> { arr.iter().copied().map(String::from) } - if let Subcommand::Clippy { - fix, - clippy_lint_allow, - clippy_lint_deny, - clippy_lint_warn, - clippy_lint_forbid, - .. - } = &builder.config.cmd - { + if let Subcommand::Clippy { fix, allow, deny, warn, forbid, .. } = &builder.config.cmd { // disable the most spammy clippy lints let ignored_lints = vec![ "many_single_char_names", // there are a lot in stdarch @@ -53,10 +45,10 @@ fn args(builder: &Builder<'_>) -> Vec<String> { args.extend(strings(&["--", "--cap-lints", "warn"])); args.extend(ignored_lints.iter().map(|lint| format!("-Aclippy::{}", lint))); let mut clippy_lint_levels: Vec<String> = Vec::new(); - clippy_lint_allow.iter().for_each(|v| clippy_lint_levels.push(format!("-A{}", v))); - clippy_lint_deny.iter().for_each(|v| clippy_lint_levels.push(format!("-D{}", v))); - clippy_lint_warn.iter().for_each(|v| clippy_lint_levels.push(format!("-W{}", v))); - clippy_lint_forbid.iter().for_each(|v| clippy_lint_levels.push(format!("-F{}", v))); + allow.iter().for_each(|v| clippy_lint_levels.push(format!("-A{}", v))); + deny.iter().for_each(|v| clippy_lint_levels.push(format!("-D{}", v))); + warn.iter().for_each(|v| clippy_lint_levels.push(format!("-W{}", v))); + forbid.iter().for_each(|v| clippy_lint_levels.push(format!("-F{}", v))); args.extend(clippy_lint_levels); args.extend(builder.config.free_args.clone()); args @@ -79,7 +71,7 @@ impl Step for Std { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.all_krates("test").path("library") + run.all_krates("sysroot").path("library") } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index 7ebd0a8f270..0d9fd56b038 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -81,7 +81,7 @@ macro_rules! clean_crate_tree { clean_crate_tree! { Rustc, Mode::Rustc, "rustc-main"; - Std, Mode::Std, "test"; + Std, Mode::Std, "sysroot"; } fn clean_default(build: &Build, all: bool) { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 7d2a6862500..966ae00fa1d 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -56,7 +56,7 @@ impl Step for Std { // When downloading stage1, the standard library has already been copied to the sysroot, so // there's no need to rebuild it. let builder = run.builder; - run.crate_or_deps("test") + run.crate_or_deps("sysroot") .path("library") .lazy_default_condition(Box::new(|| !builder.download_rustc())) } @@ -364,7 +364,7 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car .arg("--features") .arg(features) .arg("--manifest-path") - .arg(builder.src.join("library/test/Cargo.toml")); + .arg(builder.src.join("library/sysroot/Cargo.toml")); // Help the libc crate compile by assisting it in finding various // sysroot native libraries. diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 4ef95b3370f..f4e97d7dfed 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -21,7 +21,7 @@ use crate::cache::{Interned, INTERNER}; use crate::cc_detect::{ndk_compiler, Language}; use crate::channel::{self, GitInfo}; pub use crate::flags::Subcommand; -use crate::flags::{Color, Flags}; +use crate::flags::{Color, Flags, Warnings}; use crate::util::{exe, output, t}; use once_cell::sync::OnceCell; use serde::{Deserialize, Deserializer}; @@ -237,6 +237,8 @@ pub struct Config { initial_rustfmt: RefCell<RustfmtState>, #[cfg(test)] pub initial_rustfmt: RefCell<RustfmtState>, + + pub paths: Vec<PathBuf>, } #[derive(Default, Deserialize, Clone)] @@ -376,6 +378,16 @@ pub struct TargetSelection { file: Option<Interned<String>>, } +/// Newtype over `Vec<TargetSelection>` so we can implement custom parsing logic +#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub struct TargetSelectionList(Vec<TargetSelection>); + +pub fn target_selection_list(s: &str) -> Result<TargetSelectionList, String> { + Ok(TargetSelectionList( + s.split(",").filter(|s| !s.is_empty()).map(TargetSelection::from_user).collect(), + )) +} + impl TargetSelection { pub fn from_user(selection: &str) -> Self { let path = Path::new(selection); @@ -871,26 +883,24 @@ impl Config { } fn parse_inner<'a>(args: &[String], get_toml: impl 'a + Fn(&Path) -> TomlConfig) -> Config { - let flags = Flags::parse(&args); + let mut flags = Flags::parse(&args); let mut config = Config::default_opts(); // Set flags. + config.paths = std::mem::take(&mut flags.paths); config.exclude = flags.exclude.into_iter().map(|path| TaskPath::parse(path)).collect(); config.include_default_paths = flags.include_default_paths; config.rustc_error_format = flags.rustc_error_format; config.json_output = flags.json_output; config.on_fail = flags.on_fail; - config.jobs = flags.jobs.map(threads_from_config); + config.jobs = Some(threads_from_config(flags.jobs as u32)); config.cmd = flags.cmd; config.incremental = flags.incremental; config.dry_run = if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled }; config.keep_stage = flags.keep_stage; config.keep_stage_std = flags.keep_stage_std; config.color = flags.color; - config.free_args = flags.free_args.clone().unwrap_or_default(); - if let Some(value) = flags.deny_warnings { - config.deny_warnings = value; - } + config.free_args = std::mem::take(&mut flags.free_args); config.llvm_profile_use = flags.llvm_profile_use; config.llvm_profile_generate = flags.llvm_profile_generate; config.llvm_bolt_profile_generate = flags.llvm_bolt_profile_generate; @@ -1021,14 +1031,14 @@ impl Config { config.out = dir; } - config.hosts = if let Some(arg_host) = flags.host { + config.hosts = if let Some(TargetSelectionList(arg_host)) = flags.host { arg_host } else if let Some(file_host) = build.host { file_host.iter().map(|h| TargetSelection::from_user(h)).collect() } else { vec![config.build] }; - config.targets = if let Some(arg_target) = flags.target { + config.targets = if let Some(TargetSelectionList(arg_target)) = flags.target { arg_target } else if let Some(file_target) = build.target { file_target.iter().map(|h| TargetSelection::from_user(h)).collect() @@ -1064,7 +1074,7 @@ impl Config { set(&mut config.print_step_rusage, build.print_step_rusage); set(&mut config.patch_binaries_for_nix, build.patch_binaries_for_nix); - config.verbose = cmp::max(config.verbose, flags.verbose); + config.verbose = cmp::max(config.verbose, flags.verbose as usize); if let Some(install) = toml.install { config.prefix = install.prefix.map(PathBuf::from); @@ -1137,7 +1147,14 @@ impl Config { config.rustc_default_linker = rust.default_linker; config.musl_root = rust.musl_root.map(PathBuf::from); config.save_toolstates = rust.save_toolstates.map(PathBuf::from); - set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings)); + set( + &mut config.deny_warnings, + match flags.warnings { + Warnings::Deny => Some(true), + Warnings::Warn => Some(false), + Warnings::Default => rust.deny_warnings, + }, + ); set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit; @@ -1442,6 +1459,28 @@ impl Config { git } + pub(crate) fn test_args(&self) -> Vec<&str> { + let mut test_args = match self.cmd { + Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => { + test_args.iter().flat_map(|s| s.split_whitespace()).collect() + } + _ => vec![], + }; + test_args.extend(self.free_args.iter().map(|s| s.as_str())); + test_args + } + + pub(crate) fn args(&self) -> Vec<&str> { + let mut args = match self.cmd { + Subcommand::Run { ref args, .. } => { + args.iter().flat_map(|s| s.split_whitespace()).collect() + } + _ => vec![], + }; + args.extend(self.free_args.iter().map(|s| s.as_str())); + args + } + /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. /// Return the version it would have used for the given commit. pub(crate) fn artifact_version_part(&self, commit: &str) -> String { diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs index 50569eb4f37..d913ca295e2 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -1,4 +1,5 @@ -use super::{Config, TomlConfig}; +use super::{Config, Flags, TomlConfig}; +use clap::CommandFactory; use std::{env, path::Path}; fn toml(config: &str) -> impl '_ + Fn(&Path) -> TomlConfig { @@ -88,3 +89,8 @@ fn detect_src_and_out() { test(parse("build.build-dir = \"/tmp\""), build_dir); } } + +#[test] +fn clap_verify() { + Flags::command().debug_assert(); +} diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 3b35ca1d15d..9cead7adc8c 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -822,6 +822,8 @@ fn copy_src_dirs( "llvm-project\\compiler-rt", "llvm-project/cmake", "llvm-project\\cmake", + "llvm-project/runtimes", + "llvm-project\\runtimes", ]; if spath.contains("llvm-project") && !spath.ends_with("llvm-project") @@ -976,6 +978,7 @@ impl Step for PlainSourceTarball { "config.example.toml", "Cargo.toml", "Cargo.lock", + ".gitmodules", ]; let src_dirs = ["src", "compiler", "library", "tests"]; diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 9ad98eb5702..8f5d9bb66e1 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -438,7 +438,7 @@ impl Step for Std { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.all_krates("test").path("library").default_condition(builder.config.docs) + run.all_krates("sysroot").path("library").default_condition(builder.config.docs) } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index c1cf9b93fb3..3e82a381a1b 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -427,7 +427,6 @@ impl Config { fn download_toolchain( &self, - // FIXME(ozkanonur) use CompilerMetadata instead of `version: &str` version: &str, sysroot: &str, stamp_key: &str, diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index b6f5f310398..c79a1bf9563 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -5,724 +5,409 @@ use std::path::PathBuf; -use getopts::Options; +use clap::{Parser, ValueEnum}; use crate::builder::{Builder, Kind}; -use crate::config::{Config, TargetSelection}; +use crate::config::{target_selection_list, Config, TargetSelectionList}; use crate::setup::Profile; -use crate::util::t; use crate::{Build, DocTests}; -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Default, Debug, ValueEnum)] pub enum Color { Always, Never, + #[default] Auto, } -impl Default for Color { - fn default() -> Self { - Self::Auto - } -} - -impl std::str::FromStr for Color { - type Err = (); - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s.to_lowercase().as_str() { - "always" => Ok(Self::Always), - "never" => Ok(Self::Never), - "auto" => Ok(Self::Auto), - _ => Err(()), - } - } +/// Whether to deny warnings, emit them as warnings, or use the default behavior +#[derive(Copy, Clone, Default, Debug, ValueEnum)] +pub enum Warnings { + Deny, + Warn, + #[default] + Default, } /// Deserialized version of all flags for this compile. +#[derive(Debug, Parser)] +#[clap( + override_usage = "x.py <subcommand> [options] [<paths>...]", + disable_help_subcommand(true), + about = "", + next_line_help(false) +)] pub struct Flags { - pub verbose: usize, // number of -v args; each extra -v after the first is passed to Cargo - pub on_fail: Option<String>, - pub stage: Option<u32>, - pub keep_stage: Vec<u32>, - pub keep_stage_std: Vec<u32>, + #[command(subcommand)] + pub cmd: Subcommand, - pub host: Option<Vec<TargetSelection>>, - pub target: Option<Vec<TargetSelection>>, + #[arg(global(true), short, long, action = clap::ArgAction::Count)] + /// use verbose output (-vv for very verbose) + pub verbose: u8, // each extra -v after the first is passed to Cargo + #[arg(global(true), short, long)] + /// use incremental compilation + pub incremental: bool, + #[arg(global(true), long, value_hint = clap::ValueHint::FilePath, value_name = "FILE")] + /// TOML configuration file for build pub config: Option<PathBuf>, + #[arg(global(true), long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")] + /// Build directory, overrides `build.build-dir` in `config.toml` pub build_dir: Option<PathBuf>, - pub jobs: Option<u32>, - pub cmd: Subcommand, - pub incremental: bool, + + #[arg(global(true), long, value_name = "BUILD")] + /// build target of the stage0 compiler + pub build: Option<String>, + + #[arg(global(true), long, value_name = "HOST", value_parser = target_selection_list)] + /// host targets to build + pub host: Option<TargetSelectionList>, + + #[arg(global(true), long, value_name = "TARGET", value_parser = target_selection_list)] + /// target targets to build + pub target: Option<TargetSelectionList>, + + #[arg(global(true), long, value_name = "PATH")] + /// build paths to exclude pub exclude: Vec<PathBuf>, + #[arg(global(true), long)] + /// include default paths in addition to the provided ones pub include_default_paths: bool, + + #[arg(global(true), long)] pub rustc_error_format: Option<String>, - pub json_output: bool, + + #[arg(global(true), long, value_hint = clap::ValueHint::CommandString, value_name = "CMD")] + /// command to run on failure + pub on_fail: Option<String>, + #[arg(global(true), long)] + /// dry run; don't build anything pub dry_run: bool, - pub color: Color, + #[arg(global(true), long, value_name = "N")] + /// stage to build (indicates compiler to use/test, e.g., stage 0 uses the + /// bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.) + pub stage: Option<u32>, + #[arg(global(true), long, value_name = "N")] + /// stage(s) to keep without recompiling + /// (pass multiple times to keep e.g., both stages 0 and 1) + pub keep_stage: Vec<u32>, + #[arg(global(true), long, value_name = "N")] + /// stage(s) of the standard library to keep without recompiling + /// (pass multiple times to keep e.g., both stages 0 and 1) + pub keep_stage_std: Vec<u32>, + #[arg(global(true), long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")] + /// path to the root of the rust checkout + pub src: Option<PathBuf>, + + #[arg( + global(true), + short, + long, + default_value_t = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get), + value_name = "JOBS" + )] + /// number of jobs to run in parallel + pub jobs: usize, // This overrides the deny-warnings configuration option, // which passes -Dwarnings to the compiler invocations. - // - // true => deny, false => warn - pub deny_warnings: Option<bool>, + #[arg(global(true), long)] + #[clap(value_enum, default_value_t=Warnings::Default, value_name = "deny|warn")] + /// if value is deny, will deny warnings + /// if value is warn, will emit warnings + /// otherwise, use the default configured behaviour + pub warnings: Warnings, + + #[arg(global(true), long, value_name = "FORMAT")] + /// rustc error format + pub error_format: Option<String>, + #[arg(global(true), long)] + /// use message-format=json + pub json_output: bool, - pub rust_profile_use: Option<String>, - pub rust_profile_generate: Option<String>, + #[arg(global(true), long, value_name = "STYLE")] + #[clap(value_enum, default_value_t = Color::Auto)] + /// whether to use color in cargo and rustc output + pub color: Color, + /// whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml + #[arg(global(true), long, value_name = "VALUE")] + pub llvm_skip_rebuild: Option<bool>, + /// generate PGO profile with rustc build + #[arg(global(true), long, value_name = "PROFILE")] + pub rust_profile_generate: Option<String>, + /// use PGO profile for rustc build + #[arg(global(true), long, value_name = "PROFILE")] + pub rust_profile_use: Option<String>, + /// use PGO profile for LLVM build + #[arg(global(true), long, value_name = "PROFILE")] pub llvm_profile_use: Option<String>, // LLVM doesn't support a custom location for generating profile // information. // // llvm_out/build/profiles/ is the location this writes to. + /// generate PGO profile with llvm built for rustc + #[arg(global(true), long)] pub llvm_profile_generate: bool, + /// generate BOLT profile for LLVM build + #[arg(global(true), long)] pub llvm_bolt_profile_generate: bool, + /// use BOLT profile for LLVM build + #[arg(global(true), long, value_name = "PROFILE")] pub llvm_bolt_profile_use: Option<String>, + #[arg(global(true))] + /// paths for the subcommand + pub paths: Vec<PathBuf>, + /// arguments passed to subcommands + #[arg(global(true), last(true), value_name = "ARGS")] + pub free_args: Vec<String>, +} - /// Arguments appearing after `--` to be forwarded to tools, - /// e.g. `--fix-broken` or test arguments. - pub free_args: Option<Vec<String>>, +impl Flags { + pub fn parse(args: &[String]) -> Self { + let first = String::from("x.py"); + let it = std::iter::once(&first).chain(args.iter()); + // We need to check for `<cmd> -h -v`, in which case we list the paths + #[derive(Parser)] + #[clap(disable_help_flag(true))] + struct HelpVerboseOnly { + #[arg(short, long)] + help: bool, + #[arg(global(true), short, long, action = clap::ArgAction::Count)] + pub verbose: u8, + #[arg(value_enum)] + cmd: Kind, + } + if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) = + HelpVerboseOnly::try_parse_from(it.clone()) + { + println!("note: updating submodules before printing available paths"); + let config = Config::parse(&[String::from("build")]); + let build = Build::new(config); + let paths = Builder::get_help(&build, subcommand); + if let Some(s) = paths { + println!("{}", s); + } else { + panic!("No paths available for subcommand `{}`", subcommand.as_str()); + } + crate::detail_exit(0); + } + + Flags::parse_from(it) + } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default, clap::Subcommand)] pub enum Subcommand { - Build { - paths: Vec<PathBuf>, - }, + #[clap(aliases = ["b"], long_about = "\n + Arguments: + This subcommand accepts a number of paths to directories to the crates + and/or artifacts to compile. For example, for a quick build of a usable + compiler: + ./x.py build --stage 1 library/std + This will build a compiler and standard library from the local source code. + Once this is done, build/$ARCH/stage1 contains a usable compiler. + If no arguments are passed then the default artifacts for that stage are + compiled. For example: + ./x.py build --stage 0 + ./x.py build ")] + /// Compile either the compiler or libraries + #[default] + Build, + #[clap(aliases = ["c"], long_about = "\n + Arguments: + This subcommand accepts a number of paths to directories to the crates + and/or artifacts to compile. For example: + ./x.py check library/std + If no arguments are passed then many artifacts are checked.")] + /// Compile either the compiler or libraries, using cargo check Check { - paths: Vec<PathBuf>, + #[arg(long)] + /// Check all targets + all_targets: bool, }, + /// Run Clippy (uses rustup/cargo-installed clippy binary) + #[clap(long_about = "\n + Arguments: + This subcommand accepts a number of paths to directories to the crates + and/or artifacts to run clippy against. For example: + ./x.py clippy library/core + ./x.py clippy library/core library/proc_macro")] Clippy { + #[arg(long)] fix: bool, - paths: Vec<PathBuf>, - clippy_lint_allow: Vec<String>, - clippy_lint_deny: Vec<String>, - clippy_lint_warn: Vec<String>, - clippy_lint_forbid: Vec<String>, - }, - Fix { - paths: Vec<PathBuf>, + /// clippy lints to allow + #[arg(global(true), short = 'A', action = clap::ArgAction::Append, value_name = "LINT")] + allow: Vec<String>, + /// clippy lints to deny + #[arg(global(true), short = 'D', action = clap::ArgAction::Append, value_name = "LINT")] + deny: Vec<String>, + /// clippy lints to warn on + #[arg(global(true), short = 'W', action = clap::ArgAction::Append, value_name = "LINT")] + warn: Vec<String>, + /// clippy lints to forbid + #[arg(global(true), short = 'F', action = clap::ArgAction::Append, value_name = "LINT")] + forbid: Vec<String>, }, + /// Run cargo fix + #[clap(long_about = "\n + Arguments: + This subcommand accepts a number of paths to directories to the crates + and/or artifacts to run `cargo fix` against. For example: + ./x.py fix library/core + ./x.py fix library/core library/proc_macro")] + Fix, + #[clap( + name = "fmt", + long_about = "\n + Arguments: + This subcommand optionally accepts a `--check` flag which succeeds if formatting is correct and + fails if it is not. For example: + ./x.py fmt + ./x.py fmt --check" + )] + /// Run rustfmt Format { - paths: Vec<PathBuf>, + /// check formatting instead of applying + #[arg(long)] check: bool, }, + #[clap(aliases = ["d"], long_about = "\n + Arguments: + This subcommand accepts a number of paths to directories of documentation + to build. For example: + ./x.py doc src/doc/book + ./x.py doc src/doc/nomicon + ./x.py doc src/doc/book library/std + ./x.py doc library/std --json + ./x.py doc library/std --open + If no arguments are passed then everything is documented: + ./x.py doc + ./x.py doc --stage 1")] + /// Build documentation Doc { - paths: Vec<PathBuf>, + #[arg(long)] + /// open the docs in a browser open: bool, + #[arg(long)] + /// render the documentation in JSON format in addition to the usual HTML format json: bool, }, + #[clap(aliases = ["t"], long_about = "\n + Arguments: + This subcommand accepts a number of paths to test directories that + should be compiled and run. For example: + ./x.py test tests/ui + ./x.py test library/std --test-args hash_map + ./x.py test library/std --stage 0 --no-doc + ./x.py test tests/ui --bless + ./x.py test tests/ui --compare-mode chalk + Note that `test tests/* --stage N` does NOT depend on `build compiler/rustc --stage N`; + just like `build library/std --stage N` it tests the compiler produced by the previous + stage. + Execute tool tests with a tool name argument: + ./x.py test tidy + If no arguments are passed then the complete artifacts for that stage are + compiled and tested. + ./x.py test + ./x.py test --stage 1")] + /// Build and run some test suites Test { - paths: Vec<PathBuf>, - /// Whether to automatically update stderr/stdout files + #[arg(long)] + /// run all tests regardless of failure + no_fail_fast: bool, + #[arg(long, value_name = "SUBSTRING")] + /// skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times + skip: Vec<String>, + #[arg(long, value_name = "ARGS", allow_hyphen_values(true))] + /// extra arguments to be passed for the test tool being used + /// (e.g. libtest, compiletest or rustdoc) + test_args: Vec<String>, + /// extra options to pass the compiler when running tests + #[arg(long, value_name = "ARGS", allow_hyphen_values(true))] + rustc_args: Vec<String>, + #[arg(long)] + /// do not run doc tests + no_doc: bool, + #[arg(long)] + /// only run doc tests + doc: bool, + #[arg(long)] + /// whether to automatically update stderr/stdout files bless: bool, + #[arg(long)] + /// rerun tests even if the inputs are unchanged force_rerun: bool, + #[arg(long)] + /// only run tests that result has been changed + only_modified: bool, + #[arg(long, value_name = "COMPARE MODE")] + /// mode describing what file the actual ui output will be compared to compare_mode: Option<String>, + #[arg(long, value_name = "check | build | run")] + /// force {check,build,run}-pass tests to this mode. pass: Option<String>, + #[arg(long, value_name = "auto | always | never")] + /// whether to execute run-* tests run: Option<String>, - test_args: Vec<String>, - rustc_args: Vec<String>, - fail_fast: bool, - doc_tests: DocTests, + #[arg(long)] + /// enable this to generate a Rustfix coverage file, which is saved in + /// `/<build_base>/rustfix_missing_coverage.txt` rustfix_coverage: bool, - only_modified: bool, }, + /// Build and run some benchmarks Bench { - paths: Vec<PathBuf>, + #[arg(long, allow_hyphen_values(true))] test_args: Vec<String>, }, + /// Clean out build directories Clean { - paths: Vec<PathBuf>, + #[arg(long)] all: bool, }, - Dist { - paths: Vec<PathBuf>, - }, - Install { - paths: Vec<PathBuf>, - }, + /// Duild distribution artifacts + Dist, + /// Install distribution artifacts + Install, + #[clap(aliases = ["r"], long_about = "\n + Arguments: + This subcommand accepts a number of paths to tools to build and run. For + example: + ./x.py run src/tools/expand-yaml-anchors + At least a tool needs to be called.")] + /// Run tools contained in this repository Run { - paths: Vec<PathBuf>, + /// arguments for the tool + #[arg(long, allow_hyphen_values(true))] args: Vec<String>, }, - Setup { - profile: Option<PathBuf>, - }, - Suggest { - run: bool, - }, -} - -impl Default for Subcommand { - fn default() -> Subcommand { - Subcommand::Build { paths: vec![PathBuf::from("nowhere")] } - } -} - -impl Flags { - pub fn parse(args: &[String]) -> Flags { - let (args, free_args) = if let Some(pos) = args.iter().position(|s| s == "--") { - let (args, free) = args.split_at(pos); - (args, Some(free[1..].to_vec())) - } else { - (args, None) - }; - let mut subcommand_help = String::from( - "\ -Usage: x.py <subcommand> [options] [<paths>...] - -Subcommands: - build, b Compile either the compiler or libraries - check, c Compile either the compiler or libraries, using cargo check - clippy Run clippy (uses rustup/cargo-installed clippy binary) - fix Run cargo fix - fmt Run rustfmt - test, t Build and run some test suites - bench Build and run some benchmarks - doc, d Build documentation - clean Clean out build directories - dist Build distribution artifacts - install Install distribution artifacts - run, r Run tools contained in this repository - setup Create a config.toml (making it easier to use `x.py` itself) - suggest Suggest a subset of tests to run, based on modified files - -To learn more about a subcommand, run `./x.py <subcommand> -h`", - ); - - let mut opts = Options::new(); - // Options common to all subcommands - opts.optflagmulti("v", "verbose", "use verbose output (-vv for very verbose)"); - opts.optflag("i", "incremental", "use incremental compilation"); - opts.optopt("", "config", "TOML configuration file for build", "FILE"); - opts.optopt( - "", - "build-dir", - "Build directory, overrides `build.build-dir` in `config.toml`", - "DIR", - ); - opts.optopt("", "build", "build target of the stage0 compiler", "BUILD"); - opts.optmulti("", "host", "host targets to build", "HOST"); - opts.optmulti("", "target", "target targets to build", "TARGET"); - opts.optmulti("", "exclude", "build paths to exclude", "PATH"); - opts.optflag( - "", - "include-default-paths", - "include default paths in addition to the provided ones", - ); - opts.optopt("", "on-fail", "command to run on failure", "CMD"); - opts.optflag("", "dry-run", "dry run; don't build anything"); - opts.optopt( - "", - "stage", - "stage to build (indicates compiler to use/test, e.g., stage 0 uses the \ - bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)", - "N", - ); - opts.optmulti( - "", - "keep-stage", - "stage(s) to keep without recompiling \ - (pass multiple times to keep e.g., both stages 0 and 1)", - "N", - ); - opts.optmulti( - "", - "keep-stage-std", - "stage(s) of the standard library to keep without recompiling \ - (pass multiple times to keep e.g., both stages 0 and 1)", - "N", - ); - opts.optopt("", "src", "path to the root of the rust checkout", "DIR"); - let j_msg = format!( - "number of jobs to run in parallel; \ - defaults to {} (this host's logical CPU count)", - std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) - ); - opts.optopt("j", "jobs", &j_msg, "JOBS"); - opts.optflag("h", "help", "print this help message"); - opts.optopt( - "", - "warnings", - "if value is deny, will deny warnings, otherwise use default", - "VALUE", - ); - opts.optopt("", "error-format", "rustc error format", "FORMAT"); - opts.optflag("", "json-output", "use message-format=json"); - opts.optopt("", "color", "whether to use color in cargo and rustc output", "STYLE"); - opts.optopt( - "", - "rust-profile-generate", - "generate PGO profile with rustc build", - "PROFILE", - ); - opts.optopt("", "rust-profile-use", "use PGO profile for rustc build", "PROFILE"); - opts.optflag("", "llvm-profile-generate", "generate PGO profile with llvm built for rustc"); - opts.optopt("", "llvm-profile-use", "use PGO profile for llvm build", "PROFILE"); - opts.optmulti("A", "", "allow certain clippy lints", "OPT"); - opts.optmulti("D", "", "deny certain clippy lints", "OPT"); - opts.optmulti("W", "", "warn about certain clippy lints", "OPT"); - opts.optmulti("F", "", "forbid certain clippy lints", "OPT"); - opts.optflag("", "llvm-bolt-profile-generate", "generate BOLT profile for LLVM build"); - opts.optopt("", "llvm-bolt-profile-use", "use BOLT profile for LLVM build", "PROFILE"); - - // We can't use getopt to parse the options until we have completed specifying which - // options are valid, but under the current implementation, some options are conditional on - // the subcommand. Therefore we must manually identify the subcommand first, so that we can - // complete the definition of the options. Then we can use the getopt::Matches object from - // there on out. - let subcommand = match args.iter().find_map(|s| Kind::parse(&s)) { - Some(s) => s, - None => { - // No or an invalid subcommand -- show the general usage and subcommand help - // An exit code will be 0 when no subcommand is given, and 1 in case of an invalid - // subcommand. - println!("{}\n", subcommand_help); - let exit_code = if args.is_empty() { 0 } else { 1 }; - crate::detail_exit(exit_code); - } - }; - - // Some subcommands get extra options - match subcommand { - Kind::Test => { - opts.optflag("", "no-fail-fast", "Run all tests regardless of failure"); - opts.optmulti("", "skip", "skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times", "SUBSTRING"); - opts.optmulti( - "", - "test-args", - "extra arguments to be passed for the test tool being used \ - (e.g. libtest, compiletest or rustdoc)", - "ARGS", - ); - opts.optmulti( - "", - "rustc-args", - "extra options to pass the compiler when running tests", - "ARGS", - ); - opts.optflag("", "no-doc", "do not run doc tests"); - opts.optflag("", "doc", "only run doc tests"); - opts.optflag("", "bless", "update all stderr/stdout files of failing ui tests"); - opts.optflag("", "force-rerun", "rerun tests even if the inputs are unchanged"); - opts.optflag("", "only-modified", "only run tests that result has been changed"); - opts.optopt( - "", - "compare-mode", - "mode describing what file the actual ui output will be compared to", - "COMPARE MODE", - ); - opts.optopt( - "", - "pass", - "force {check,build,run}-pass tests to this mode.", - "check | build | run", - ); - opts.optopt("", "run", "whether to execute run-* tests", "auto | always | never"); - opts.optflag( - "", - "rustfix-coverage", - "enable this to generate a Rustfix coverage file, which is saved in \ - `/<build_base>/rustfix_missing_coverage.txt`", - ); - } - Kind::Check => { - opts.optflag("", "all-targets", "Check all targets"); - } - Kind::Bench => { - opts.optmulti("", "test-args", "extra arguments", "ARGS"); - } - Kind::Clippy => { - opts.optflag("", "fix", "automatically apply lint suggestions"); - } - Kind::Doc => { - opts.optflag("", "open", "open the docs in a browser"); - opts.optflag( - "", - "json", - "render the documentation in JSON format in addition to the usual HTML format", - ); - } - Kind::Clean => { - opts.optflag("", "all", "clean all build artifacts"); - } - Kind::Format => { - opts.optflag("", "check", "check formatting instead of applying."); - } - Kind::Run => { - opts.optmulti("", "args", "arguments for the tool", "ARGS"); - } - Kind::Suggest => { - opts.optflag("", "run", "run suggested tests"); - } - _ => {} - }; - - // fn usage() - let usage = |exit_code: i32, opts: &Options, verbose: bool, subcommand_help: &str| -> ! { - println!("{}", opts.usage(subcommand_help)); - if verbose { - // We have an unfortunate situation here: some Steps use `builder.in_tree_crates` to determine their paths. - // To determine those crates, we need to run `cargo metadata`, which means we need all submodules to be checked out. - // That takes a while to run, so only do it when paths were explicitly requested, not on all CLI errors. - // `Build::new` won't load submodules for the `setup` command. - let cmd = if verbose { - println!("note: updating submodules before printing available paths"); - "build" - } else { - "setup" - }; - let config = Config::parse(&[cmd.to_string()]); - let build = Build::new(config); - let paths = Builder::get_help(&build, subcommand); - - if let Some(s) = paths { - println!("{}", s); - } else { - panic!("No paths available for subcommand `{}`", subcommand.as_str()); - } - } else { - println!( - "Run `./x.py {} -h -v` to see a list of available paths.", - subcommand.as_str() - ); - } - crate::detail_exit(exit_code); - }; - - // Done specifying what options are possible, so do the getopts parsing - let matches = opts.parse(args).unwrap_or_else(|e| { - // Invalid argument/option format - println!("\n{}\n", e); - usage(1, &opts, false, &subcommand_help); - }); - - // Extra sanity check to make sure we didn't hit this crazy corner case: - // - // ./x.py --frobulate clean build - // ^-- option ^ ^- actual subcommand - // \_ arg to option could be mistaken as subcommand - let mut pass_sanity_check = true; - match matches.free.get(0).and_then(|s| Kind::parse(&s)) { - Some(check_subcommand) => { - if check_subcommand != subcommand { - pass_sanity_check = false; - } - } - None => { - pass_sanity_check = false; - } - } - if !pass_sanity_check { - eprintln!("{}\n", subcommand_help); - eprintln!( - "Sorry, I couldn't figure out which subcommand you were trying to specify.\n\ - You may need to move some options to after the subcommand.\n" - ); - crate::detail_exit(1); - } - // Extra help text for some commands - match subcommand { - Kind::Build => { - subcommand_help.push_str( - "\n -Arguments: - This subcommand accepts a number of paths to directories to the crates - and/or artifacts to compile. For example, for a quick build of a usable - compiler: - - ./x.py build --stage 1 library/std - - This will build a compiler and standard library from the local source code. - Once this is done, build/$ARCH/stage1 contains a usable compiler. - - If no arguments are passed then the default artifacts for that stage are - compiled. For example: - - ./x.py build --stage 0 - ./x.py build ", - ); - } - Kind::Check => { - subcommand_help.push_str( - "\n -Arguments: - This subcommand accepts a number of paths to directories to the crates - and/or artifacts to compile. For example: - - ./x.py check library/std - - If no arguments are passed then many artifacts are checked.", - ); - } - Kind::Clippy => { - subcommand_help.push_str( - "\n -Arguments: - This subcommand accepts a number of paths to directories to the crates - and/or artifacts to run clippy against. For example: - - ./x.py clippy library/core - ./x.py clippy library/core library/proc_macro", - ); - } - Kind::Fix => { - subcommand_help.push_str( - "\n -Arguments: - This subcommand accepts a number of paths to directories to the crates - and/or artifacts to run `cargo fix` against. For example: - - ./x.py fix library/core - ./x.py fix library/core library/proc_macro", - ); - } - Kind::Format => { - subcommand_help.push_str( - "\n -Arguments: - This subcommand optionally accepts a `--check` flag which succeeds if formatting is correct and - fails if it is not. For example: - - ./x.py fmt - ./x.py fmt --check", - ); - } - Kind::Test => { - subcommand_help.push_str( - "\n -Arguments: - This subcommand accepts a number of paths to test directories that - should be compiled and run. For example: - - ./x.py test tests/ui - ./x.py test library/std --test-args hash_map - ./x.py test library/std --stage 0 --no-doc - ./x.py test tests/ui --bless - ./x.py test tests/ui --compare-mode chalk - - Note that `test tests/* --stage N` does NOT depend on `build compiler/rustc --stage N`; - just like `build library/std --stage N` it tests the compiler produced by the previous - stage. - - Execute tool tests with a tool name argument: - - ./x.py test tidy - - If no arguments are passed then the complete artifacts for that stage are - compiled and tested. - - ./x.py test - ./x.py test --stage 1", - ); - } - Kind::Doc => { - subcommand_help.push_str( - "\n -Arguments: - This subcommand accepts a number of paths to directories of documentation - to build. For example: - - ./x.py doc src/doc/book - ./x.py doc src/doc/nomicon - ./x.py doc src/doc/book library/std - ./x.py doc library/std --json - ./x.py doc library/std --open - - If no arguments are passed then everything is documented: - - ./x.py doc - ./x.py doc --stage 1", - ); - } - Kind::Run => { - subcommand_help.push_str( - "\n -Arguments: - This subcommand accepts a number of paths to tools to build and run. For - example: - - ./x.py run src/tools/expand-yaml-anchors - - At least a tool needs to be called.", - ); - } - Kind::Setup => { - subcommand_help.push_str(&format!( - "\n + /// Set up the environment for development + #[clap(long_about = format!( + "\n x.py setup creates a `config.toml` which changes the defaults for x.py itself, -as well as setting up a git pre-push hook, VS code config and toolchain link. - +as well as setting up a git pre-push hook, VS Code config and toolchain link. Arguments: This subcommand accepts a 'profile' to use for builds. For example: - ./x.py setup library - The profile is optional and you will be prompted interactively if it is not given. The following profiles are available: - {} - - To only set up the git hook, VS code or toolchain link, you may use + To only set up the git hook, VS Code config or toolchain link, you may use ./x.py setup hook ./x.py setup vscode - ./x.py setup link -", - Profile::all_for_help(" ").trim_end() - )); - } - Kind::Bench | Kind::Clean | Kind::Dist | Kind::Install | Kind::Suggest => {} - }; - // Get any optional paths which occur after the subcommand - let mut paths = matches.free[1..].iter().map(|p| p.into()).collect::<Vec<PathBuf>>(); - - let verbose = matches.opt_present("verbose"); - - // User passed in -h/--help? - if matches.opt_present("help") { - usage(0, &opts, verbose, &subcommand_help); - } - - let cmd = match subcommand { - Kind::Build => Subcommand::Build { paths }, - Kind::Check => { - if matches.opt_present("all-targets") { - println!( - "Warning: --all-targets is now on by default and does not need to be passed explicitly." - ); - } - Subcommand::Check { paths } - } - Kind::Clippy => Subcommand::Clippy { - paths, - fix: matches.opt_present("fix"), - clippy_lint_allow: matches.opt_strs("A"), - clippy_lint_warn: matches.opt_strs("W"), - clippy_lint_deny: matches.opt_strs("D"), - clippy_lint_forbid: matches.opt_strs("F"), - }, - Kind::Fix => Subcommand::Fix { paths }, - Kind::Test => Subcommand::Test { - paths, - bless: matches.opt_present("bless"), - force_rerun: matches.opt_present("force-rerun"), - compare_mode: matches.opt_str("compare-mode"), - pass: matches.opt_str("pass"), - run: matches.opt_str("run"), - test_args: matches.opt_strs("test-args"), - rustc_args: matches.opt_strs("rustc-args"), - fail_fast: !matches.opt_present("no-fail-fast"), - rustfix_coverage: matches.opt_present("rustfix-coverage"), - only_modified: matches.opt_present("only-modified"), - doc_tests: if matches.opt_present("doc") { - DocTests::Only - } else if matches.opt_present("no-doc") { - DocTests::No - } else { - DocTests::Yes - }, - }, - Kind::Bench => Subcommand::Bench { paths, test_args: matches.opt_strs("test-args") }, - Kind::Doc => Subcommand::Doc { - paths, - open: matches.opt_present("open"), - json: matches.opt_present("json"), - }, - Kind::Clean => Subcommand::Clean { all: matches.opt_present("all"), paths }, - Kind::Format => Subcommand::Format { check: matches.opt_present("check"), paths }, - Kind::Dist => Subcommand::Dist { paths }, - Kind::Install => Subcommand::Install { paths }, - Kind::Suggest => Subcommand::Suggest { run: matches.opt_present("run") }, - Kind::Run => { - if paths.is_empty() { - println!("\nrun requires at least a path!\n"); - usage(1, &opts, verbose, &subcommand_help); - } - Subcommand::Run { paths, args: matches.opt_strs("args") } - } - Kind::Setup => { - let profile = if paths.len() > 1 { - eprintln!("\nerror: At most one option can be passed to setup\n"); - usage(1, &opts, verbose, &subcommand_help) - } else if let Some(path) = paths.pop() { - let profile_string = t!(path.into_os_string().into_string().map_err( - |path| format!("{} is not a valid UTF8 string", path.to_string_lossy()) - )); - - let profile = profile_string.parse().unwrap_or_else(|err| { - eprintln!("error: {}", err); - eprintln!("help: the available profiles are:"); - eprint!("{}", Profile::all_for_help("- ")); - crate::detail_exit(1); - }); - Some(profile) - } else { - None - }; - Subcommand::Setup { profile } - } - }; - - Flags { - verbose: matches.opt_count("verbose"), - stage: matches.opt_str("stage").map(|j| j.parse().expect("`stage` should be a number")), - dry_run: matches.opt_present("dry-run"), - on_fail: matches.opt_str("on-fail"), - rustc_error_format: matches.opt_str("error-format"), - json_output: matches.opt_present("json-output"), - keep_stage: matches - .opt_strs("keep-stage") - .into_iter() - .map(|j| j.parse().expect("`keep-stage` should be a number")) - .collect(), - keep_stage_std: matches - .opt_strs("keep-stage-std") - .into_iter() - .map(|j| j.parse().expect("`keep-stage-std` should be a number")) - .collect(), - host: if matches.opt_present("host") { - Some( - split(&matches.opt_strs("host")) - .into_iter() - .map(|x| TargetSelection::from_user(&x)) - .collect::<Vec<_>>(), - ) - } else { - None - }, - target: if matches.opt_present("target") { - Some( - split(&matches.opt_strs("target")) - .into_iter() - .map(|x| TargetSelection::from_user(&x)) - .collect::<Vec<_>>(), - ) - } else { - None - }, - config: matches.opt_str("config").map(PathBuf::from), - build_dir: matches.opt_str("build-dir").map(PathBuf::from), - jobs: matches.opt_str("jobs").map(|j| j.parse().expect("`jobs` should be a number")), - cmd, - incremental: matches.opt_present("incremental"), - exclude: split(&matches.opt_strs("exclude")) - .into_iter() - .map(|p| p.into()) - .collect::<Vec<_>>(), - include_default_paths: matches.opt_present("include-default-paths"), - deny_warnings: parse_deny_warnings(&matches), - color: matches - .opt_get_default("color", Color::Auto) - .expect("`color` should be `always`, `never`, or `auto`"), - rust_profile_use: matches.opt_str("rust-profile-use"), - rust_profile_generate: matches.opt_str("rust-profile-generate"), - llvm_profile_use: matches.opt_str("llvm-profile-use"), - llvm_profile_generate: matches.opt_present("llvm-profile-generate"), - llvm_bolt_profile_generate: matches.opt_present("llvm-bolt-profile-generate"), - llvm_bolt_profile_use: matches.opt_str("llvm-bolt-profile-use"), - free_args, - } - } + ./x.py setup link", Profile::all_for_help(" ").trim_end()))] + Setup { + /// Either the profile for `config.toml` or another setup action. + /// May be omitted to set up interactively + #[arg(value_name = "<PROFILE>|hook|vscode|link")] + profile: Option<PathBuf>, + }, + /// Suggest a subset of tests to run, based on modified files + #[clap(long_about = "\n")] + Suggest { + /// run suggested tests + #[arg(long)] + run: bool, + }, } impl Subcommand { @@ -745,15 +430,6 @@ impl Subcommand { } } - pub fn test_args(&self) -> Vec<&str> { - match *self { - Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => { - test_args.iter().flat_map(|s| s.split_whitespace()).collect() - } - _ => vec![], - } - } - pub fn rustc_args(&self) -> Vec<&str> { match *self { Subcommand::Test { ref rustc_args, .. } => { @@ -763,25 +439,24 @@ impl Subcommand { } } - pub fn args(&self) -> Vec<&str> { - match *self { - Subcommand::Run { ref args, .. } => { - args.iter().flat_map(|s| s.split_whitespace()).collect() - } - _ => vec![], - } - } - pub fn fail_fast(&self) -> bool { match *self { - Subcommand::Test { fail_fast, .. } => fail_fast, + Subcommand::Test { no_fail_fast, .. } => !no_fail_fast, _ => false, } } pub fn doc_tests(&self) -> DocTests { match *self { - Subcommand::Test { doc_tests, .. } => doc_tests, + Subcommand::Test { doc, no_doc, .. } => { + if doc { + DocTests::Only + } else if no_doc { + DocTests::No + } else { + DocTests::Yes + } + } _ => DocTests::Yes, } } @@ -849,19 +524,3 @@ impl Subcommand { } } } - -fn split(s: &[String]) -> Vec<String> { - s.iter().flat_map(|s| s.split(',')).filter(|s| !s.is_empty()).map(|s| s.to_string()).collect() -} - -fn parse_deny_warnings(matches: &getopts::Matches) -> Option<bool> { - match matches.opt_str("warnings").as_deref() { - Some("deny") => Some(true), - Some("warn") => Some(false), - Some(value) => { - eprintln!(r#"invalid value for --warnings: {:?}, expected "warn" or "deny""#, value,); - crate::detail_exit(1); - } - None => None, - } -} diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 59d2e9cc69e..994336977dc 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -660,8 +660,8 @@ impl Build { // hardcoded subcommands match &self.config.cmd { - Subcommand::Format { check, paths } => { - return format::format(&builder::Builder::new(&self), *check, &paths); + Subcommand::Format { check } => { + return format::format(&builder::Builder::new(&self), *check, &self.config.paths); } Subcommand::Suggest { run } => { return suggest::suggest(&builder::Builder::new(&self), *run); diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index e14440f57a8..cb15d9a6325 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -105,7 +105,7 @@ impl Step for BumpStage0 { fn run(self, builder: &Builder<'_>) -> Self::Output { let mut cmd = builder.tool_cmd(Tool::BumpStage0); - cmd.args(builder.config.cmd.args()); + cmd.args(builder.config.args()); builder.run(&mut cmd); } } @@ -182,8 +182,7 @@ impl Step for Miri { miri.add_rustc_lib_path(builder, compiler); // Forward arguments. miri.arg("--").arg("--target").arg(target.rustc_target_arg()); - miri.args(builder.config.cmd.args()); - miri.args(&builder.config.free_args); + miri.args(builder.config.args()); // miri tests need to know about the stage sysroot miri.env("MIRI_SYSROOT", &miri_sysroot); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index aee84e9c9be..854b7f5bd3a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -263,7 +263,7 @@ impl Step for Cargotest { builder, cmd.arg(&cargo) .arg(&out_dir) - .args(builder.config.cmd.test_args()) + .args(builder.config.test_args()) .env("RUSTC", builder.rustc(compiler)) .env("RUSTDOC", builder.rustdoc(compiler)), ); @@ -634,7 +634,7 @@ impl Step for Miri { .arg(builder.src.join("src/tools/miri/test-cargo-miri/Cargo.toml")); cargo.arg("--target").arg(target.rustc_target_arg()); cargo.arg("--tests"); // don't run doctests, they are too confused by the staging - cargo.arg("--").args(builder.config.cmd.test_args()); + cargo.arg("--").args(builder.config.test_args()); // Tell `cargo miri` where to find things. cargo.env("MIRI_SYSROOT", &miri_sysroot); @@ -1060,7 +1060,7 @@ impl Step for RustdocGUI { } } } - for test_arg in builder.config.cmd.test_args() { + for test_arg in builder.config.test_args() { command.arg(test_arg); } builder.run(&mut command); @@ -1545,7 +1545,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the // Get paths from cmd args let paths = match &builder.config.cmd { - Subcommand::Test { ref paths, .. } => &paths[..], + Subcommand::Test { .. } => &builder.config.paths[..], _ => &[], }; @@ -1555,8 +1555,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the .filter_map(|p| util::is_valid_test_suite_arg(p, suite_path, builder)) .collect(); - test_args.append(&mut builder.config.cmd.test_args()); - test_args.extend(builder.config.free_args.iter().map(|s| s.as_str())); + test_args.append(&mut builder.config.test_args()); // On Windows, replace forward slashes in test-args by backslashes // so the correct filters are passed to libtest @@ -1962,7 +1961,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> cmd.arg(markdown); cmd.env("RUSTC_BOOTSTRAP", "1"); - let test_args = builder.config.cmd.test_args().join(" "); + let test_args = builder.config.test_args().join(" "); cmd.arg("--test-args").arg(test_args); if builder.config.verbose_tests { @@ -2099,7 +2098,7 @@ fn prepare_cargo_test( cargo.arg("-p").arg(krate); } - cargo.arg("--").args(&builder.config.cmd.test_args()).args(libtest_args); + cargo.arg("--").args(&builder.config.test_args()).args(libtest_args); if !builder.config.verbose_tests { cargo.arg("--quiet"); } @@ -2145,7 +2144,7 @@ impl Step for Crate { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.crate_or_deps("test") + run.crate_or_deps("sysroot") } fn make_run(run: RunConfig<'_>) { diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 9f7259f883a..5898a21d613 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -83,12 +83,12 @@ To run the image, A number of these images take quite a long time to compile as they're building whole gcc toolchains to do cross builds with. Much of this is relatively self-explanatory but some images use [crosstool-ng] which isn't quite as self -explanatory. Below is a description of where these `*.config` files come form, +explanatory. Below is a description of where these `*.defconfig` files come form, how to generate them, and how the existing ones were generated. [crosstool-ng]: https://github.com/crosstool-ng/crosstool-ng -### Generating a `.config` file +### Generating a `.defconfig` file **NOTE:** Existing Dockerfiles can also be a good guide for the process and order of script execution. @@ -100,14 +100,14 @@ next two steps. these steps are outside the container: ``` -# Note: We use ubuntu:16.04 because that's the "base" of linux-cross Docker +# Note: We use ubuntu:22.04 because that's the "base" of linux-cross Docker # image, or simply run ./src/ci/docker/run.sh once, which will download the correct # one and you can check it out with `docker images` -$ docker run -it ubuntu:16.04 bash +$ docker run -it ubuntu:22.04 bash # in another terminal: $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -cfbec05ed730 ubuntu:16.04 "bash" 16 seconds ago Up 15 seconds drunk_murdock +cfbec05ed730 ubuntu:22.04 "bash" 16 seconds ago Up 15 seconds drunk_murdock $ docker cp src/ci/docker/scripts drunk_murdock:/tmp/ ``` @@ -127,7 +127,7 @@ $ bash ./crosstool-ng.sh present. Otherwise one can use the TUI to load any config-file. ``` -$ docker cp arm-linux-gnueabi.config drunk_murdock:/tmp/.config +$ docker cp arm-linux-gnueabi.defconfig drunk_murdock:/tmp/.config ``` - Now, inside the container run the following command to configure the @@ -136,49 +136,54 @@ $ docker cp arm-linux-gnueabi.config drunk_murdock:/tmp/.config ``` $ cd /tmp/ +$ ct-ng olddefconfig $ ct-ng menuconfig +$ ct-ng savedefconfig ``` -- Finally, we retrieve the `.config` file from the container and give it a +- Finally, we retrieve the `defconfig` file from the container and give it a meaningful name. This is done outside the container. ``` -$ docker cp drunk_murdock:/tmp/.config arm-linux-gnueabi.config +$ docker cp drunk_murdock:/tmp/defconfig arm-linux-gnueabi.defconfig ``` - Now you can shutdown the container or repeat the two last steps to generate a - new `.config` file. + new `.defconfig` file. ### Toolchain configuration Changes on top of the default toolchain configuration used to generate the -`.config` files in this directory. The changes are formatted as follows: +`.defconfig` files in this directory. The changes are formatted as follows: ``` $category > $option = $value -- $comment ``` -### `arm-linux-gnueabi.config` +### `arm-linux-gnueabi.defconfig` For targets: `arm-unknown-linux-gnueabi` - Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} -- Path and misc options > Patches origin = Bundled only +- Path and misc options > Use a mirror = ENABLE +- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc - Target options > Target Architecture = arm - Target options > Architecture level = armv6 -- (+) - Target options > Floating point = software (no FPU) -- (\*) - Operating System > Target OS = linux - Operating System > Linux kernel version = 3.2.101 +- Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.17.0 -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM -### `arm-linux-gnueabihf.config` +### `arm-linux-gnueabihf.defconfig` For targets: `arm-unknown-linux-gnueabihf` - Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} -- Path and misc options > Patches origin = Bundled only +- Path and misc options > Use a mirror = ENABLE +- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc - Target options > Target Architecture = arm - Target options > Architecture level = armv6 -- (+) - Target options > Use specific FPU = vfp -- (+) @@ -186,16 +191,18 @@ For targets: `arm-unknown-linux-gnueabihf` - Target options > Default instruction set mode = arm -- (+) - Operating System > Target OS = linux - Operating System > Linux kernel version = 3.2.101 +- Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.17.0 -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM -### `armv7-linux-gnueabihf.config` +### `armv7-linux-gnueabihf.defconfig` For targets: `armv7-unknown-linux-gnueabihf` - Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} -- Path and misc options > Patches origin = Bundled only +- Path and misc options > Use a mirror = ENABLE +- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc - Target options > Target Architecture = arm - Target options > Suffix to the arch-part = v7 - Target options > Architecture level = armv7-a -- (+) @@ -204,8 +211,9 @@ For targets: `armv7-unknown-linux-gnueabihf` - Target options > Default instruction set mode = thumb -- (\*) - Operating System > Target OS = linux - Operating System > Linux kernel version = 3.2.101 +- Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.17.0 -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM (\*) These options have been selected to match the configuration of the arm @@ -214,7 +222,7 @@ For targets: `armv7-unknown-linux-gnueabihf` libraries like jemalloc. See the mk/cfg/arm(v7)-unknown-linux-gnueabi{,hf}.mk file in Rust's source code. -### `aarch64-linux-gnu.config` +### `aarch64-linux-gnu.defconfig` For targets: `aarch64-unknown-linux-gnu` @@ -225,17 +233,16 @@ For targets: `aarch64-unknown-linux-gnu` - Target options > Bitness = 64-bit - Operating System > Target OS = linux - Operating System > Linux kernel version = 4.1.49 -- Binary utilities > Version of binutils = 2.32 +- Binary utilities > Version of binutils = 2.29.1 - C-library > glibc version = 2.17 -- aarch64 support was introduced in this version -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM -### `i586-linux-gnu.config` +### `i586-linux-gnu.defconfig` For targets: `i586-unknown-linux-gnu` - Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} -- Path and misc options > Patches origin = Bundled only - Target options > Target Architecture = x86 - Target options > Architecture level = i586 - Target options > Target CFLAGS = -Wa,-mrelax-relocations=no @@ -244,13 +251,13 @@ For targets: `i586-unknown-linux-gnu` - Binary utilities > Version of binutils = 2.32 - Binary utilities > binutils extra config = --enable-compressed-debug-sections=none -- (\*) - C-library > glibc version = 2.17.0 -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE (\*) Compressed debug is enabled by default for gas (assembly) on Linux/x86 targets, but that makes our `compiler_builtins` incompatible with binutils < 2.32. -### `mips-linux-gnu.config` +### `mips-linux-gnu.defconfig` For targets: `mips-unknown-linux-gnu` @@ -265,14 +272,14 @@ For targets: `mips-unknown-linux-gnu` - Target options > Bitness = 32-bit - Target options > Architecture level = mips32r2 - Operating System > Target OS = linux -- Operating System > Linux kernel version = 4.4.174 +- Operating System > Linux kernel version = 4.4.302 - Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.23 -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > gcc extra config = --with-fp-32=xx --with-odd-spreg-32=no - C compiler > C++ = ENABLE -- to cross compile LLVM -### `mipsel-linux-gnu.config` +### `mipsel-linux-gnu.defconfig` For targets: `mipsel-unknown-linux-gnu` @@ -287,14 +294,14 @@ For targets: `mipsel-unknown-linux-gnu` - Target options > Bitness = 32-bit - Target options > Architecture level = mips32r2 - Operating System > Target OS = linux -- Operating System > Linux kernel version = 4.4.174 +- Operating System > Linux kernel version = 4.4.302 - Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.23 -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > gcc extra config = --with-fp-32=xx --with-odd-spreg-32=no - C compiler > C++ = ENABLE -- to cross compile LLVM -### `mips64-linux-gnu.config` +### `mips64-linux-gnu.defconfig` For targets: `mips64-unknown-linux-gnuabi64` @@ -309,13 +316,13 @@ For targets: `mips64-unknown-linux-gnuabi64` - Target options > Bitness = 64-bit - Target options > Architecture level = mips64r2 - Operating System > Target OS = linux -- Operating System > Linux kernel version = 4.4.174 +- Operating System > Linux kernel version = 4.4.302 - Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.23 -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM -### `mips64el-linux-gnu.config` +### `mips64el-linux-gnu.defconfig` For targets: `mips64el-unknown-linux-gnuabi64` @@ -330,13 +337,13 @@ For targets: `mips64el-unknown-linux-gnuabi64` - Target options > Bitness = 64-bit - Target options > Architecture level = mips64r2 - Operating System > Target OS = linux -- Operating System > Linux kernel version = 4.4.174 +- Operating System > Linux kernel version = 4.4.302 - Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.23 -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM -### `powerpc-linux-gnu.config` +### `powerpc-linux-gnu.defconfig` For targets: `powerpc-unknown-linux-gnu` @@ -349,10 +356,10 @@ For targets: `powerpc-unknown-linux-gnu` - Operating System > Linux kernel version = 3.2.101 - Binary utilities > Version of binutils = 2.30 - C-library > glibc version = 2.17 -- ~RHEL7 glibc -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM -### `powerpc64-linux-gnu.config` +### `powerpc64-linux-gnu.defconfig` For targets: `powerpc64-unknown-linux-gnu` @@ -367,12 +374,28 @@ For targets: `powerpc64-unknown-linux-gnu` - Operating System > Linux kernel version = 3.2.101 - Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.17 -- ~RHEL7 glibc -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM (+) These CPU options match the configuration of the toolchains in RHEL6. -### `s390x-linux-gnu.config` +### `riscv64-unknown-linux-gnu.defconfig` + +For targets: `riscv64-unknown-linux-gnu` + +- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} +- Path and misc options > Use a mirror = ENABLE +- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc +- Target options > Target Architecture = riscv +- Target options > Bitness = 64-bit +- Operating System > Target OS = linux +- Operating System > Linux kernel version = 4.20.17 +- Binary utilities > Version of binutils = 2.32 +- C-library > glibc version = 2.29 +- C compiler > gcc version = 8.5.0 +- C compiler > C++ = ENABLE -- to cross compile LLVM + +### `s390x-linux-gnu.defconfig` For targets: `s390x-unknown-linux-gnu` @@ -385,6 +408,6 @@ For targets: `s390x-unknown-linux-gnu` - Operating System > Linux kernel version = 3.2.101 - Binary utilities > Version of binutils = 2.32 - C-library > glibc version = 2.17 -- ~RHEL7 glibc -- C compiler > gcc version = 8.3.0 +- C compiler > gcc version = 8.5.0 - C compiler > gcc extra config = --with-arch=z10 -- LLVM's minimum support - C compiler > C++ = ENABLE -- to cross compile LLVM diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile index 23fa23f0f2d..18972387e34 100644 --- a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile @@ -1,20 +1,18 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh -USER rustbuild WORKDIR /tmp -COPY host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config host-x86_64/dist-aarch64-linux/build-toolchains.sh /tmp/ -RUN ./build-toolchains.sh - -USER root +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config deleted file mode 100644 index 4561e2a1ec3..00000000000 --- a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config +++ /dev/null @@ -1,754 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_BUNDLED_LOCAL is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -CT_ARCH_ARM=y -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="arm" -CT_ARCH_CHOICE_KSYM="ARM" -# CT_ARCH_ALPHA_EV4 is not set -# CT_ARCH_ALPHA_EV45 is not set -# CT_ARCH_ALPHA_EV5 is not set -# CT_ARCH_ALPHA_EV56 is not set -# CT_ARCH_ALPHA_EV6 is not set -# CT_ARCH_ALPHA_EV67 is not set -CT_ARCH_CPU="" -CT_ARCH_TUNE="" -CT_ARCH_ARM_SHOW=y - -# -# Options for arm -# -CT_ARCH_ARM_PKG_KSYM="" -# CT_ARCH_ARM_MODE_ARM is not set -# CT_ARCH_ARM_MODE_THUMB is not set -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_SUPPORTS_BOTH_MMU=y -CT_ARCH_DEFAULT_HAS_MMU=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_FLAT_FORMAT=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_LE=y -# CT_ARCH_BE is not set -CT_ARCH_LE=y -CT_ARCH_ENDIAN="little" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=64 -# CT_ARCH_32 is not set -CT_ARCH_64=y - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_CPU=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_EXCLUSIVE_WITH_CPU=y -CT_ARCH_ARCH="" -# CT_ARCH_FLOAT_AUTO is not set -# CT_ARCH_FLOAT_HW is not set -# CT_ARCH_FLOAT_SOFTFP is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -CT_LINUX_V_4_1=y -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="4.1.49" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_later_than_3_7=y -CT_LINUX_3_7_or_later=y -CT_LINUX_REQUIRE_3_7_or_later=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -# CT_BINUTILS_V_2_32 is not set -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -CT_BINUTILS_V_2_29=y -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.29.1" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_2_30_or_older=y -CT_BINUTILS_older_than_2_30=y -CT_BINUTILS_REQUIRE_older_than_2_30=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_GOLD_SUPPORTS_ARCH=y -CT_BINUTILS_GOLD_SUPPORT=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -# CT_BINUTILS_LINKER_LD_GOLD is not set -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_NEWLIB is not set -# CT_LIBC_NONE is not set -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -# CT_GLIBC_V_2_23 is not set -# CT_GLIBC_V_2_19 is not set -CT_GLIBC_V_2_17=y -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.17" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_older_than_2_23=y -CT_GLIBC_2_20_or_older=y -CT_GLIBC_older_than_2_20=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_2_17_or_older=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_NPTL_ADDON=y -CT_GLIBC_HAS_PORTS_ADDON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -CT_GLIBC_USE_PORTS_ADDON=y -CT_GLIBC_USE_NPTL_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="4.1.49" -# CT_GLIBC_SSP_DEFAULT is not set -# CT_GLIBC_SSP_NO is not set -# CT_GLIBC_SSP_YES is not set -# CT_GLIBC_SSP_ALL is not set -# CT_GLIBC_SSP_STRONG is not set -# CT_NEWLIB_USE_REDHAT is not set -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="http://isl.gforge.inria.fr" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig new file mode 100644 index 00000000000..47e984ef85a --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig @@ -0,0 +1,12 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_ARM=y +CT_ARCH_64=y +CT_KERNEL_LINUX=y +CT_LINUX_V_4_1=y +CT_BINUTILS_V_2_29=y +CT_GLIBC_V_2_17=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/build-toolchains.sh b/src/ci/docker/host-x86_64/dist-aarch64-linux/build-toolchains.sh deleted file mode 100755 index f15a7081612..00000000000 --- a/src/ci/docker/host-x86_64/dist-aarch64-linux/build-toolchains.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../aarch64-linux-gnu.config .config -ct-ng oldconfig -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile index 0c3b9ebdc33..3ac5343aa57 100644 --- a/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile @@ -1,14 +1,13 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh WORKDIR /build -COPY scripts/musl-patch-configure.diff /build/ COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well RUN CFLAGS="-Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ @@ -17,13 +16,11 @@ RUN CFLAGS="-Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=non COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh -USER rustbuild WORKDIR /tmp -COPY host-x86_64/dist-arm-linux/arm-linux-gnueabi.config host-x86_64/dist-arm-linux/build-toolchains.sh /tmp/ -RUN ./build-toolchains.sh - -USER root +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-arm-linux/arm-linux-gnueabi.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.config b/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.config deleted file mode 100644 index e047db92652..00000000000 --- a/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.config +++ /dev/null @@ -1,748 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -# CT_USE_MIRROR is not set -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_BUNDLED_LOCAL is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -CT_ARCH_ARM=y -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="arm" -CT_ARCH_CHOICE_KSYM="ARM" -CT_ARCH_CPU="" -CT_ARCH_TUNE="" -CT_ARCH_ARM_SHOW=y - -# -# Options for arm -# -CT_ARCH_ARM_PKG_KSYM="" -CT_ARCH_ARM_MODE="arm" -CT_ARCH_ARM_MODE_ARM=y -# CT_ARCH_ARM_MODE_THUMB is not set -# CT_ARCH_ARM_INTERWORKING is not set -CT_ARCH_ARM_EABI_FORCE=y -CT_ARCH_ARM_EABI=y -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_SUPPORTS_BOTH_MMU=y -CT_ARCH_DEFAULT_HAS_MMU=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_FLAT_FORMAT=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_LE=y -# CT_ARCH_BE is not set -CT_ARCH_LE=y -CT_ARCH_ENDIAN="little" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=32 -CT_ARCH_32=y -# CT_ARCH_64 is not set - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_CPU=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_SUPPORTS_WITH_FPU=y -CT_ARCH_SUPPORTS_SOFTFP=y -CT_ARCH_EXCLUSIVE_WITH_CPU=y -CT_ARCH_ARCH="armv6" -CT_ARCH_FPU="" -# CT_ARCH_FLOAT_AUTO is not set -# CT_ARCH_FLOAT_HW is not set -# CT_ARCH_FLOAT_SOFTFP is not set -CT_ARCH_FLOAT_SW=y -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="soft" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -CT_LINUX_V_3_2=y -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="3.2.101" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_3_7_or_older=y -CT_LINUX_older_than_3_7=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_GOLD_SUPPORTS_ARCH=y -CT_BINUTILS_GOLD_SUPPORT=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -# CT_BINUTILS_LINKER_LD_GOLD is not set -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -# CT_GLIBC_V_2_23 is not set -# CT_GLIBC_V_2_19 is not set -CT_GLIBC_V_2_17=y -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.17" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_older_than_2_23=y -CT_GLIBC_2_20_or_older=y -CT_GLIBC_older_than_2_20=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_2_17_or_older=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_NPTL_ADDON=y -CT_GLIBC_HAS_PORTS_ADDON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -CT_GLIBC_USE_PORTS_ADDON=y -CT_GLIBC_USE_NPTL_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="3.2.101" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="https://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.defconfig b/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.defconfig new file mode 100644 index 00000000000..e7afdbe9d4d --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.defconfig @@ -0,0 +1,13 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_ARM=y +CT_ARCH_ARCH="armv6" +CT_ARCH_FLOAT_SW=y +CT_KERNEL_LINUX=y +CT_LINUX_V_3_2=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_17=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-arm-linux/build-toolchains.sh b/src/ci/docker/host-x86_64/dist-arm-linux/build-toolchains.sh deleted file mode 100755 index ad53ba4dd1b..00000000000 --- a/src/ci/docker/host-x86_64/dist-arm-linux/build-toolchains.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../arm-linux-gnueabi.config .config -# FIXME ct-ng oldconfig is not working as intended. -# ct-ng oldconfig -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile index 753d6450502..855465aa38e 100644 --- a/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile @@ -1,20 +1,18 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh -USER rustbuild WORKDIR /tmp -COPY host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config host-x86_64/dist-armhf-linux/build-toolchains.sh /tmp/ -RUN ./build-toolchains.sh - -USER root +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config b/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config deleted file mode 100644 index e0f6417793d..00000000000 --- a/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config +++ /dev/null @@ -1,749 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -# CT_USE_MIRROR is not set -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_BUNDLED_LOCAL is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -CT_ARCH_ARM=y -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="arm" -CT_ARCH_CHOICE_KSYM="ARM" -CT_ARCH_CPU="" -CT_ARCH_TUNE="" -CT_ARCH_ARM_SHOW=y - -# -# Options for arm -# -CT_ARCH_ARM_PKG_KSYM="" -CT_ARCH_ARM_MODE="arm" -CT_ARCH_ARM_MODE_ARM=y -# CT_ARCH_ARM_MODE_THUMB is not set -# CT_ARCH_ARM_INTERWORKING is not set -CT_ARCH_ARM_EABI_FORCE=y -CT_ARCH_ARM_EABI=y -CT_ARCH_ARM_TUPLE_USE_EABIHF=y -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_SUPPORTS_BOTH_MMU=y -CT_ARCH_DEFAULT_HAS_MMU=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_FLAT_FORMAT=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_LE=y -# CT_ARCH_BE is not set -CT_ARCH_LE=y -CT_ARCH_ENDIAN="little" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=32 -CT_ARCH_32=y -# CT_ARCH_64 is not set - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_CPU=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_SUPPORTS_WITH_FPU=y -CT_ARCH_SUPPORTS_SOFTFP=y -CT_ARCH_EXCLUSIVE_WITH_CPU=y -CT_ARCH_ARCH="armv6" -CT_ARCH_FPU="vfp" -# CT_ARCH_FLOAT_AUTO is not set -CT_ARCH_FLOAT_HW=y -# CT_ARCH_FLOAT_SOFTFP is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="hard" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -CT_LINUX_V_3_2=y -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="3.2.101" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_3_7_or_older=y -CT_LINUX_older_than_3_7=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_GOLD_SUPPORTS_ARCH=y -CT_BINUTILS_GOLD_SUPPORT=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -# CT_BINUTILS_LINKER_LD_GOLD is not set -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -# CT_GLIBC_V_2_23 is not set -# CT_GLIBC_V_2_19 is not set -CT_GLIBC_V_2_17=y -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.17" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_older_than_2_23=y -CT_GLIBC_2_20_or_older=y -CT_GLIBC_older_than_2_20=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_2_17_or_older=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_NPTL_ADDON=y -CT_GLIBC_HAS_PORTS_ADDON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -CT_GLIBC_USE_PORTS_ADDON=y -CT_GLIBC_USE_NPTL_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="3.2.101" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="https://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.defconfig b/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.defconfig new file mode 100644 index 00000000000..c7c5b4d5a28 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.defconfig @@ -0,0 +1,14 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_ARM=y +CT_ARCH_ARCH="armv6" +CT_ARCH_FPU="vfp" +CT_ARCH_FLOAT_HW=y +CT_KERNEL_LINUX=y +CT_LINUX_V_3_2=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_17=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-armhf-linux/build-toolchains.sh b/src/ci/docker/host-x86_64/dist-armhf-linux/build-toolchains.sh deleted file mode 100755 index 6b5374422a6..00000000000 --- a/src/ci/docker/host-x86_64/dist-armhf-linux/build-toolchains.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../arm-linux-gnueabihf.config .config -# FIXME ct-ng oldconfig is not working as intended. -# ct-ng oldconfig -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile index 7eb5097aae8..dab0667ed55 100644 --- a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile @@ -1,20 +1,18 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh -USER rustbuild WORKDIR /tmp -COPY host-x86_64/dist-armv7-linux/build-toolchains.sh host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config /tmp/ -RUN ./build-toolchains.sh - -USER root +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config b/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config deleted file mode 100644 index 2d8167f1f33..00000000000 --- a/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config +++ /dev/null @@ -1,746 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="" -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -# CT_USE_MIRROR is not set -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_BUNDLED_LOCAL is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -CT_LOG_INFO=y -# CT_LOG_EXTRA is not set -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="INFO" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -CT_ARCH_ARM=y -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="arm" -CT_ARCH_CHOICE_KSYM="ARM" -CT_ARCH_CPU="" -CT_ARCH_TUNE="" -CT_ARCH_ARM_SHOW=y - -# -# Options for arm -# -CT_ARCH_ARM_PKG_KSYM="" -CT_ARCH_ARM_MODE="thumb" -# CT_ARCH_ARM_MODE_ARM is not set -CT_ARCH_ARM_MODE_THUMB=y -# CT_ARCH_ARM_INTERWORKING is not set -CT_ARCH_ARM_EABI_FORCE=y -CT_ARCH_ARM_EABI=y -CT_ARCH_ARM_TUPLE_USE_EABIHF=y -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="v7" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_SUPPORTS_BOTH_MMU=y -CT_ARCH_DEFAULT_HAS_MMU=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_FLAT_FORMAT=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_LE=y -# CT_ARCH_BE is not set -CT_ARCH_LE=y -CT_ARCH_ENDIAN="little" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=32 -CT_ARCH_32=y -# CT_ARCH_64 is not set - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_CPU=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_SUPPORTS_WITH_FPU=y -CT_ARCH_SUPPORTS_SOFTFP=y -CT_ARCH_EXCLUSIVE_WITH_CPU=y -CT_ARCH_ARCH="armv7-a" -CT_ARCH_FPU="vfpv3-d16" -# CT_ARCH_FLOAT_AUTO is not set -CT_ARCH_FLOAT_HW=y -# CT_ARCH_FLOAT_SOFTFP is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="hard" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -CT_LINUX_V_3_2=y -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="3.2.101" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_3_7_or_older=y -CT_LINUX_older_than_3_7=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_GOLD_SUPPORTS_ARCH=y -CT_BINUTILS_GOLD_SUPPORT=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -# CT_BINUTILS_LINKER_LD_GOLD is not set -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -# CT_GLIBC_V_2_23 is not set -# CT_GLIBC_V_2_19 is not set -CT_GLIBC_V_2_17=y -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.17" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_older_than_2_23=y -CT_GLIBC_2_20_or_older=y -CT_GLIBC_older_than_2_20=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_2_17_or_older=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_NPTL_ADDON=y -CT_GLIBC_HAS_PORTS_ADDON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -CT_GLIBC_USE_PORTS_ADDON=y -CT_GLIBC_USE_NPTL_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="3.2.101" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -# CT_MPC_V_1_1 is not set -CT_MPC_V_1_0=y -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.0.3" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_older=y -CT_MPC_older_than_1_1_0=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_3_1=y -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="3.1.6" -CT_MPFR_MIRRORS="https://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_4_0_0_or_older=y -CT_MPFR_older_than_4_0_0=y -CT_MPFR_REQUIRE_older_than_4_0_0=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="https://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.defconfig b/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.defconfig new file mode 100644 index 00000000000..3f37e546b42 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.defconfig @@ -0,0 +1,16 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_ARM=y +CT_ARCH_ARM_MODE_THUMB=y +CT_ARCH_SUFFIX="v7" +CT_ARCH_ARCH="armv7-a" +CT_ARCH_FPU="vfpv3-d16" +CT_ARCH_FLOAT_HW=y +CT_KERNEL_LINUX=y +CT_LINUX_V_3_2=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_17=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/build-toolchains.sh b/src/ci/docker/host-x86_64/dist-armv7-linux/build-toolchains.sh deleted file mode 100755 index 602ad8ac877..00000000000 --- a/src/ci/docker/host-x86_64/dist-armv7-linux/build-toolchains.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../armv7-linux-gnueabihf.config .config -# FIXME ct-ng oldconfig is not working as intended. -# ct-ng oldconfig -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile index 34829adf79b..a62f98b21d2 100644 --- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile @@ -21,17 +21,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp -COPY host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config \ - host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh \ - /tmp/ -RUN su rustbuild -c ./build-i586-gnu-toolchain.sh +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh + ENV PATH=$PATH:/x-tools/i586-unknown-linux-gnu/bin ENV \ CC_i586_unknown_linux_gnu=i586-unknown-linux-gnu-gcc \ diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh deleted file mode 100755 index ceab60cfb45..00000000000 --- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../i586-linux-gnu.config .config -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config deleted file mode 100644 index cdbd52d23bc..00000000000 --- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config +++ /dev/null @@ -1,726 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_BUNDLED_LOCAL is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -CT_ARCH_X86=y -# CT_ARCH_XTENSA is not set -CT_ARCH="x86" -CT_ARCH_CHOICE_KSYM="X86" -CT_ARCH_CPU="" -CT_ARCH_TUNE="" -CT_ARCH_X86_SHOW=y - -# -# Options for x86 -# -CT_ARCH_X86_PKG_KSYM="" -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=32 -CT_ARCH_32=y -# CT_ARCH_64 is not set - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_CPU=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_ARCH="i586" -CT_TARGET_CFLAGS="-Wa,-mrelax-relocations=no" -CT_TARGET_LDFLAGS="" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -CT_LINUX_V_3_2=y -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="3.2.101" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_3_7_or_older=y -CT_LINUX_older_than_3_7=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_GOLD_SUPPORTS_ARCH=y -CT_BINUTILS_GOLD_SUPPORT=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -# CT_BINUTILS_LINKER_LD_GOLD is not set -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="--enable-compressed-debug-sections=none" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -# CT_GLIBC_V_2_23 is not set -# CT_GLIBC_V_2_19 is not set -CT_GLIBC_V_2_17=y -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.17" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_older_than_2_23=y -CT_GLIBC_2_20_or_older=y -CT_GLIBC_older_than_2_20=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_2_17_or_older=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_NPTL_ADDON=y -CT_GLIBC_HAS_PORTS_ADDON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -CT_GLIBC_USE_NPTL_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="3.2.101" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set -CT_CC_GCC_LIBMPX=y - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig new file mode 100644 index 00000000000..01fe493a9fe --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig @@ -0,0 +1,14 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_X86=y +CT_ARCH_ARCH="i586" +CT_TARGET_CFLAGS="-Wa,-mrelax-relocations=no" +CT_KERNEL_LINUX=y +CT_LINUX_V_3_2=y +CT_BINUTILS_V_2_32=y +CT_BINUTILS_EXTRA_CONFIG_ARRAY="--enable-compressed-debug-sections=none" +CT_GLIBC_V_2_17=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile index eb511b32107..c08febf423a 100644 --- a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile @@ -3,16 +3,17 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp +COPY scripts/crosstool-ng-build.sh /scripts/ COPY host-x86_64/dist-mips-linux/patches/ /tmp/patches/ -COPY host-x86_64/dist-mips-linux/mips-linux-gnu.config host-x86_64/dist-mips-linux/build-mips-toolchain.sh /tmp/ -RUN su rustbuild -c ./build-mips-toolchain.sh +COPY host-x86_64/dist-mips-linux/mips-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/build-mips-toolchain.sh b/src/ci/docker/host-x86_64/dist-mips-linux/build-mips-toolchain.sh deleted file mode 100755 index 32612cf6852..00000000000 --- a/src/ci/docker/host-x86_64/dist-mips-linux/build-mips-toolchain.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../mips-linux-gnu.config .config -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config deleted file mode 100644 index 5bfbbae206b..00000000000 --- a/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config +++ /dev/null @@ -1,740 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -# CT_PATCH_BUNDLED is not set -CT_PATCH_BUNDLED_LOCAL=y -CT_PATCH_ORDER="bundled,local" -CT_PATCH_USE_LOCAL=y -CT_LOCAL_PATCH_DIR="/tmp/patches" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -CT_ARCH_MIPS=y -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="mips" -CT_ARCH_CHOICE_KSYM="MIPS" -CT_ARCH_TUNE="" -CT_ARCH_MIPS_SHOW=y - -# -# Options for mips -# -CT_ARCH_MIPS_PKG_KSYM="" -CT_ARCH_mips_o32=y -CT_ARCH_mips_ABI="32" -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_BE=y -CT_ARCH_BE=y -# CT_ARCH_LE is not set -CT_ARCH_ENDIAN="big" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=32 -CT_ARCH_32=y -# CT_ARCH_64 is not set - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_ARCH="mips32r2" -CT_ARCH_FLOAT_AUTO=y -# CT_ARCH_FLOAT_HW is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="auto" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -CT_LINUX_V_4_4=y -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -# CT_LINUX_V_3_2 is not set -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="4.4.174" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_later_than_3_7=y -CT_LINUX_3_7_or_later=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -CT_GLIBC_V_2_23=y -# CT_GLIBC_V_2_19 is not set -# CT_GLIBC_V_2_17 is not set -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.23" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_later=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_later_than_2_20=y -CT_GLIBC_2_20_or_later=y -CT_GLIBC_later_than_2_17=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_NO_SPARC_V8=y -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="4.4.174" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-fp-32=xx --with-odd-spreg-32=no" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_CC_GCC_HAS_ARCH_OPTIONS=y - -# -# architecture-specific options -# -CT_CC_GCC_mips_llsc=m -CT_CC_GCC_mips_synci=m -# CT_CC_GCC_mips_plt is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="http://isl.gforge.inria.fr" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.defconfig new file mode 100644 index 00000000000..75743fe8141 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.defconfig @@ -0,0 +1,16 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_PATCH_BUNDLED_LOCAL=y +CT_LOCAL_PATCH_DIR="/tmp/patches" +CT_ARCH_MIPS=y +CT_ARCH_mips_o32=y +CT_ARCH_ARCH="mips32r2" +CT_KERNEL_LINUX=y +CT_LINUX_V_4_4=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_23=y +CT_GCC_V_8=y +CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-fp-32=xx --with-odd-spreg-32=no" +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile index de862e1df2d..10f31075e2d 100644 --- a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile @@ -3,16 +3,17 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp +COPY scripts/crosstool-ng-build.sh /scripts/ COPY host-x86_64/dist-mips-linux/patches/ /tmp/patches/ -COPY host-x86_64/dist-mips64-linux/mips64-linux-gnu.config host-x86_64/dist-mips64-linux/build-mips64-toolchain.sh /tmp/ -RUN su rustbuild -c ./build-mips64-toolchain.sh +COPY host-x86_64/dist-mips64-linux/mips64-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/build-mips64-toolchain.sh b/src/ci/docker/host-x86_64/dist-mips64-linux/build-mips64-toolchain.sh deleted file mode 100755 index f554a5f4754..00000000000 --- a/src/ci/docker/host-x86_64/dist-mips64-linux/build-mips64-toolchain.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../mips64-linux-gnu.config .config -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config deleted file mode 100644 index c28d655427e..00000000000 --- a/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config +++ /dev/null @@ -1,741 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -# CT_PATCH_BUNDLED is not set -CT_PATCH_BUNDLED_LOCAL=y -CT_PATCH_ORDER="bundled,local" -CT_PATCH_USE_LOCAL=y -CT_LOCAL_PATCH_DIR="/tmp/patches" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -CT_ARCH_MIPS=y -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="mips" -CT_ARCH_CHOICE_KSYM="MIPS" -CT_ARCH_TUNE="" -CT_ARCH_MIPS_SHOW=y - -# -# Options for mips -# -CT_ARCH_MIPS_PKG_KSYM="" -# CT_ARCH_mips_n32 is not set -CT_ARCH_mips_n64=y -CT_ARCH_mips_ABI="64" -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_BE=y -CT_ARCH_BE=y -# CT_ARCH_LE is not set -CT_ARCH_ENDIAN="big" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=64 -# CT_ARCH_32 is not set -CT_ARCH_64=y - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_ARCH="mips64r2" -CT_ARCH_FLOAT_AUTO=y -# CT_ARCH_FLOAT_HW is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="auto" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -CT_LINUX_V_4_4=y -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -# CT_LINUX_V_3_2 is not set -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="4.4.174" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_later_than_3_7=y -CT_LINUX_3_7_or_later=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -CT_GLIBC_V_2_23=y -# CT_GLIBC_V_2_19 is not set -# CT_GLIBC_V_2_17 is not set -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.23" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_later=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_later_than_2_20=y -CT_GLIBC_2_20_or_later=y -CT_GLIBC_later_than_2_17=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_NO_SPARC_V8=y -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="4.4.174" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_CC_GCC_HAS_ARCH_OPTIONS=y - -# -# architecture-specific options -# -CT_CC_GCC_mips_llsc=m -CT_CC_GCC_mips_synci=m -# CT_CC_GCC_mips_plt is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="http://isl.gforge.inria.fr" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.defconfig new file mode 100644 index 00000000000..4b8f7a54920 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.defconfig @@ -0,0 +1,16 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_PATCH_BUNDLED_LOCAL=y +CT_LOCAL_PATCH_DIR="/tmp/patches" +CT_ARCH_MIPS=y +CT_ARCH_mips_n64=y +CT_ARCH_64=y +CT_ARCH_ARCH="mips64r2" +CT_KERNEL_LINUX=y +CT_LINUX_V_4_4=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_23=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile index b90950f7330..5ab4a53de8a 100644 --- a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile @@ -3,16 +3,17 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp +COPY scripts/crosstool-ng-build.sh /scripts/ COPY host-x86_64/dist-mips-linux/patches/ /tmp/patches/ -COPY host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config host-x86_64/dist-mips64el-linux/build-mips64el-toolchain.sh /tmp/ -RUN su rustbuild -c ./build-mips64el-toolchain.sh +COPY host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/build-mips64el-toolchain.sh b/src/ci/docker/host-x86_64/dist-mips64el-linux/build-mips64el-toolchain.sh deleted file mode 100755 index 1ad406800b1..00000000000 --- a/src/ci/docker/host-x86_64/dist-mips64el-linux/build-mips64el-toolchain.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../mips64el-linux-gnu.config .config -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config deleted file mode 100644 index 50dfe7b2dd1..00000000000 --- a/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config +++ /dev/null @@ -1,741 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -# CT_PATCH_BUNDLED is not set -CT_PATCH_BUNDLED_LOCAL=y -CT_PATCH_ORDER="bundled,local" -CT_PATCH_USE_LOCAL=y -CT_LOCAL_PATCH_DIR="/tmp/patches" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -CT_ARCH_MIPS=y -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="mips" -CT_ARCH_CHOICE_KSYM="MIPS" -CT_ARCH_TUNE="" -CT_ARCH_MIPS_SHOW=y - -# -# Options for mips -# -CT_ARCH_MIPS_PKG_KSYM="" -# CT_ARCH_mips_n32 is not set -CT_ARCH_mips_n64=y -CT_ARCH_mips_ABI="64" -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_BE=y -# CT_ARCH_BE is not set -CT_ARCH_LE=y -CT_ARCH_ENDIAN="little" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=64 -# CT_ARCH_32 is not set -CT_ARCH_64=y - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_ARCH="mips64r2" -CT_ARCH_FLOAT_AUTO=y -# CT_ARCH_FLOAT_HW is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="auto" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -CT_LINUX_V_4_4=y -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -# CT_LINUX_V_3_2 is not set -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="4.4.174" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_later_than_3_7=y -CT_LINUX_3_7_or_later=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -CT_GLIBC_V_2_23=y -# CT_GLIBC_V_2_19 is not set -# CT_GLIBC_V_2_17 is not set -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.23" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_later=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_later_than_2_20=y -CT_GLIBC_2_20_or_later=y -CT_GLIBC_later_than_2_17=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_NO_SPARC_V8=y -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="4.4.174" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_CC_GCC_HAS_ARCH_OPTIONS=y - -# -# architecture-specific options -# -CT_CC_GCC_mips_llsc=m -CT_CC_GCC_mips_synci=m -# CT_CC_GCC_mips_plt is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="http://isl.gforge.inria.fr" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.defconfig new file mode 100644 index 00000000000..9c8eb5007b7 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.defconfig @@ -0,0 +1,17 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_PATCH_BUNDLED_LOCAL=y +CT_LOCAL_PATCH_DIR="/tmp/patches" +CT_ARCH_MIPS=y +CT_ARCH_mips_n64=y +CT_ARCH_LE=y +CT_ARCH_64=y +CT_ARCH_ARCH="mips64r2" +CT_KERNEL_LINUX=y +CT_LINUX_V_4_4=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_23=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile index 6cc2de5e47d..0bbaf00339d 100644 --- a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile @@ -3,16 +3,17 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp +COPY scripts/crosstool-ng-build.sh /scripts/ COPY host-x86_64/dist-mips-linux/patches/ /tmp/patches/ -COPY host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config host-x86_64/dist-mipsel-linux/build-mipsel-toolchain.sh /tmp/ -RUN su rustbuild -c ./build-mipsel-toolchain.sh +COPY host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/build-mipsel-toolchain.sh b/src/ci/docker/host-x86_64/dist-mipsel-linux/build-mipsel-toolchain.sh deleted file mode 100755 index 598e4893325..00000000000 --- a/src/ci/docker/host-x86_64/dist-mipsel-linux/build-mipsel-toolchain.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../mipsel-linux-gnu.config .config -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config deleted file mode 100644 index 3566c7c8593..00000000000 --- a/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config +++ /dev/null @@ -1,740 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -# CT_PATCH_BUNDLED is not set -CT_PATCH_BUNDLED_LOCAL=y -CT_PATCH_ORDER="bundled,local" -CT_PATCH_USE_LOCAL=y -CT_LOCAL_PATCH_DIR="/tmp/patches" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -CT_ARCH_MIPS=y -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="mips" -CT_ARCH_CHOICE_KSYM="MIPS" -CT_ARCH_TUNE="" -CT_ARCH_MIPS_SHOW=y - -# -# Options for mips -# -CT_ARCH_MIPS_PKG_KSYM="" -CT_ARCH_mips_o32=y -CT_ARCH_mips_ABI="32" -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_BE=y -# CT_ARCH_BE is not set -CT_ARCH_LE=y -CT_ARCH_ENDIAN="little" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=32 -CT_ARCH_32=y -# CT_ARCH_64 is not set - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_ARCH="mips32r2" -CT_ARCH_FLOAT_AUTO=y -# CT_ARCH_FLOAT_HW is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="auto" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -CT_LINUX_V_4_4=y -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -# CT_LINUX_V_3_2 is not set -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="4.4.174" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_later_than_3_7=y -CT_LINUX_3_7_or_later=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -CT_GLIBC_V_2_23=y -# CT_GLIBC_V_2_19 is not set -# CT_GLIBC_V_2_17 is not set -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.23" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_later=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_later_than_2_20=y -CT_GLIBC_2_20_or_later=y -CT_GLIBC_later_than_2_17=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_NO_SPARC_V8=y -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="4.4.174" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-fp-32=xx --with-odd-spreg-32=no" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_CC_GCC_HAS_ARCH_OPTIONS=y - -# -# architecture-specific options -# -CT_CC_GCC_mips_llsc=m -CT_CC_GCC_mips_synci=m -# CT_CC_GCC_mips_plt is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="http://isl.gforge.inria.fr" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.defconfig new file mode 100644 index 00000000000..a9dae121e53 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.defconfig @@ -0,0 +1,17 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_PATCH_BUNDLED_LOCAL=y +CT_LOCAL_PATCH_DIR="/tmp/patches" +CT_ARCH_MIPS=y +CT_ARCH_mips_o32=y +CT_ARCH_LE=y +CT_ARCH_ARCH="mips32r2" +CT_KERNEL_LINUX=y +CT_LINUX_V_4_4=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_23=y +CT_GCC_V_8=y +CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-fp-32=xx --with-odd-spreg-32=no" +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile index 94a837151c6..b546f571f66 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile @@ -1,20 +1,18 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh -USER rustbuild WORKDIR /tmp -COPY host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config host-x86_64/dist-powerpc-linux/build-powerpc-toolchain.sh /tmp/ -RUN ./build-powerpc-toolchain.sh - -USER root +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-powerpc-linux/build-powerpc-toolchain.sh b/src/ci/docker/host-x86_64/dist-powerpc-linux/build-powerpc-toolchain.sh deleted file mode 100755 index 264d0764f29..00000000000 --- a/src/ci/docker/host-x86_64/dist-powerpc-linux/build-powerpc-toolchain.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../powerpc-linux-gnu.config .config -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config b/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config deleted file mode 100644 index 0df859ad944..00000000000 --- a/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config +++ /dev/null @@ -1,736 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_BUNDLED_LOCAL is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_NIOS2 is not set -CT_ARCH_POWERPC=y -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="powerpc" -CT_ARCH_CHOICE_KSYM="POWERPC" -CT_ARCH_CPU="powerpc" -CT_ARCH_TUNE="" -CT_ARCH_POWERPC_SHOW=y - -# -# Options for powerpc -# -CT_ARCH_POWERPC_PKG_KSYM="" -CT_ARCH_powerpc_ABI="" -CT_ARCH_powerpc_ABI_DEFAULT=y -# CT_ARCH_powerpc_ABI_SPE is not set -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_BE=y -CT_ARCH_BE=y -# CT_ARCH_LE is not set -CT_ARCH_ENDIAN="big" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=32 -CT_ARCH_32=y -# CT_ARCH_64 is not set - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ABI=y -CT_ARCH_SUPPORTS_WITH_CPU=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_ABI="" -CT_ARCH_FLOAT_AUTO=y -# CT_ARCH_FLOAT_HW is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="auto" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -CT_LINUX_V_3_2=y -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="3.2.101" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_3_7_or_older=y -CT_LINUX_older_than_3_7=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -# CT_BINUTILS_V_2_32 is not set -# CT_BINUTILS_V_2_31 is not set -CT_BINUTILS_V_2_30=y -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.30" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_2_30_or_older=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -# CT_GLIBC_V_2_23 is not set -# CT_GLIBC_V_2_19 is not set -CT_GLIBC_V_2_17=y -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.17" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_older_than_2_23=y -CT_GLIBC_2_20_or_older=y -CT_GLIBC_older_than_2_20=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_2_17_or_older=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_NPTL_ADDON=y -CT_GLIBC_HAS_PORTS_ADDON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -CT_GLIBC_USE_PORTS_ADDON=y -CT_GLIBC_USE_NPTL_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="3.2.101" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="http://isl.gforge.inria.fr" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.defconfig new file mode 100644 index 00000000000..6a0e96a3b67 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.defconfig @@ -0,0 +1,12 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_POWERPC=y +CT_ARCH_CPU="powerpc" +CT_KERNEL_LINUX=y +CT_LINUX_V_3_2=y +CT_BINUTILS_V_2_30=y +CT_GLIBC_V_2_17=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile index c976536cb7c..c88185a2000 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile @@ -1,20 +1,18 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh -USER rustbuild WORKDIR /tmp -COPY host-x86_64/dist-powerpc64-linux/shared.sh host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config host-x86_64/dist-powerpc64-linux/build-powerpc64-toolchain.sh /tmp/ -RUN ./build-powerpc64-toolchain.sh - -USER root +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/build-powerpc64-toolchain.sh b/src/ci/docker/host-x86_64/dist-powerpc64-linux/build-powerpc64-toolchain.sh deleted file mode 100755 index f7aa2cd3268..00000000000 --- a/src/ci/docker/host-x86_64/dist-powerpc64-linux/build-powerpc64-toolchain.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -set -ex - -source shared.sh - -mkdir build -cd build -cp ../powerpc64-linux-gnu.config .config -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config b/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config deleted file mode 100644 index d3293eab2be..00000000000 --- a/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config +++ /dev/null @@ -1,736 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_BUNDLED_LOCAL is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_NIOS2 is not set -CT_ARCH_POWERPC=y -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="powerpc" -CT_ARCH_CHOICE_KSYM="POWERPC" -CT_ARCH_CPU="power4" -CT_ARCH_TUNE="power6" -CT_ARCH_POWERPC_SHOW=y - -# -# Options for powerpc -# -CT_ARCH_POWERPC_PKG_KSYM="" -CT_ARCH_powerpc_ABI="" -CT_ARCH_powerpc_ABI_DEFAULT=y -# CT_ARCH_powerpc_ABI_SPE is not set -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_EITHER_ENDIAN=y -CT_ARCH_DEFAULT_BE=y -CT_ARCH_BE=y -# CT_ARCH_LE is not set -CT_ARCH_ENDIAN="big" -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=64 -# CT_ARCH_32 is not set -CT_ARCH_64=y - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ABI=y -CT_ARCH_SUPPORTS_WITH_CPU=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_SUPPORTS_WITH_FLOAT=y -CT_ARCH_ABI="" -CT_ARCH_FLOAT_AUTO=y -# CT_ARCH_FLOAT_HW is not set -# CT_ARCH_FLOAT_SW is not set -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" -CT_ARCH_FLOAT="auto" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -CT_LINUX_V_3_2=y -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="3.2.101" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_3_7_or_older=y -CT_LINUX_older_than_3_7=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -# CT_GLIBC_V_2_23 is not set -# CT_GLIBC_V_2_19 is not set -CT_GLIBC_V_2_17=y -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.17" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_older_than_2_23=y -CT_GLIBC_2_20_or_older=y -CT_GLIBC_older_than_2_20=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_2_17_or_older=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_NPTL_ADDON=y -CT_GLIBC_HAS_PORTS_ADDON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -CT_GLIBC_USE_PORTS_ADDON=y -CT_GLIBC_USE_NPTL_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="3.2.101" -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="http://isl.gforge.inria.fr" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.defconfig new file mode 100644 index 00000000000..2b442cbe794 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.defconfig @@ -0,0 +1,14 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_POWERPC=y +CT_ARCH_CPU="power4" +CT_ARCH_TUNE="power6" +CT_ARCH_64=y +CT_KERNEL_LINUX=y +CT_LINUX_V_3_2=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_17=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/shared.sh b/src/ci/docker/host-x86_64/dist-powerpc64-linux/shared.sh deleted file mode 100644 index dc86dddd464..00000000000 --- a/src/ci/docker/host-x86_64/dist-powerpc64-linux/shared.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile index 397f9538b8b..426e601f5d3 100644 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile @@ -1,20 +1,18 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh -USER rustbuild WORKDIR /tmp -COPY host-x86_64/dist-riscv64-linux/build-toolchains.sh host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config /tmp/ -RUN ./build-toolchains.sh - -USER root +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config deleted file mode 100644 index 7400a8a038d..00000000000 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config +++ /dev/null @@ -1,907 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -CT_EXPERIMENTAL=y -# CT_ALLOW_BUILD_AS_ROOT is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -# CT_USE_MIRROR is not set -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_LOCAL is not set -# CT_PATCH_BUNDLED_LOCAL is not set -# CT_PATCH_LOCAL_BUNDLED is not set -# CT_PATCH_NONE is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -# CT_LOG_EXTRA is not set -CT_LOG_ALL=y -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="ALL" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MICROBLAZE is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_MOXIE is not set -# CT_ARCH_MSP430 is not set -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -CT_ARCH_RISCV=y -# CT_ARCH_S390 is not set -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="riscv" -CT_ARCH_CHOICE_KSYM="RISCV" -CT_ARCH_TUNE="" -CT_ARCH_RISCV_SHOW=y - -# -# Options for riscv -# -CT_ARCH_RISCV_PKG_KSYM="" -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -# CT_DEMULTILIB is not set -CT_ARCH_SUPPORTS_BOTH_MMU=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=64 -# CT_ARCH_32 is not set -CT_ARCH_64=y - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_ARCH=y -CT_ARCH_SUPPORTS_WITH_ABI=y -CT_ARCH_SUPPORTS_WITH_TUNE=y -CT_ARCH_ARCH="rv64gc" -CT_ARCH_ABI="" -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -# CT_NATIVE is not set -CT_CROSS=y -# CT_CROSS_NATIVE is not set -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -# CT_LINUX_SRC_DEVEL is not set -# CT_LINUX_SRC_CUSTOM is not set -CT_LINUX_PATCH_GLOBAL=y -# CT_LINUX_PATCH_BUNDLED is not set -# CT_LINUX_PATCH_LOCAL is not set -# CT_LINUX_PATCH_BUNDLED_LOCAL is not set -# CT_LINUX_PATCH_LOCAL_BUNDLED is not set -# CT_LINUX_PATCH_NONE is not set -CT_LINUX_PATCH_ORDER="global" -CT_LINUX_V_4_20=y -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -# CT_LINUX_V_3_2 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="4.20.8" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_later_than_4_8=y -CT_LINUX_4_8_or_later=y -CT_LINUX_later_than_3_7=y -CT_LINUX_3_7_or_later=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_LINUX_REQUIRE_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -# CT_BINUTILS_SRC_DEVEL is not set -# CT_BINUTILS_SRC_CUSTOM is not set -CT_BINUTILS_PATCH_GLOBAL=y -# CT_BINUTILS_PATCH_BUNDLED is not set -# CT_BINUTILS_PATCH_LOCAL is not set -# CT_BINUTILS_PATCH_BUNDLED_LOCAL is not set -# CT_BINUTILS_PATCH_LOCAL_BUNDLED is not set -# CT_BINUTILS_PATCH_NONE is not set -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_REQUIRE_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_MUSL is not set -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -# CT_GLIBC_SRC_DEVEL is not set -# CT_GLIBC_SRC_CUSTOM is not set -CT_GLIBC_PATCH_GLOBAL=y -# CT_GLIBC_PATCH_BUNDLED is not set -# CT_GLIBC_PATCH_LOCAL is not set -# CT_GLIBC_PATCH_BUNDLED_LOCAL is not set -# CT_GLIBC_PATCH_LOCAL_BUNDLED is not set -# CT_GLIBC_PATCH_NONE is not set -CT_GLIBC_PATCH_ORDER="global" -CT_GLIBC_V_2_29=y -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.29" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_later=y -CT_GLIBC_2_29_or_older=y -CT_GLIBC_REQUIRE_2_29_or_later=y -CT_GLIBC_later_than_2_27=y -CT_GLIBC_2_27_or_later=y -CT_GLIBC_later_than_2_26=y -CT_GLIBC_2_26_or_later=y -CT_GLIBC_later_than_2_25=y -CT_GLIBC_2_25_or_later=y -CT_GLIBC_later_than_2_24=y -CT_GLIBC_2_24_or_later=y -CT_GLIBC_later_than_2_23=y -CT_GLIBC_2_23_or_later=y -CT_GLIBC_later_than_2_20=y -CT_GLIBC_2_20_or_later=y -CT_GLIBC_later_than_2_17=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_BUILD_SSP=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_NO_SPARC_V8=y -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_ENABLE_FORTIFIED_BUILD is not set -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -CT_GLIBC_KERNEL_VERSION_NONE=y -# CT_GLIBC_KERNEL_VERSION_AS_HEADERS is not set -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="" -CT_GLIBC_SSP_DEFAULT=y -# CT_GLIBC_SSP_NO is not set -# CT_GLIBC_SSP_YES is not set -# CT_GLIBC_SSP_ALL is not set -# CT_GLIBC_SSP_STRONG is not set -# CT_GLIBC_ENABLE_WERROR is not set -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -# CT_GCC_USE_LINARO is not set -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -# CT_GCC_SRC_DEVEL is not set -# CT_GCC_SRC_CUSTOM is not set -CT_GCC_PATCH_GLOBAL=y -# CT_GCC_PATCH_BUNDLED is not set -# CT_GCC_PATCH_LOCAL is not set -# CT_GCC_PATCH_BUNDLED_LOCAL is not set -# CT_GCC_PATCH_LOCAL_BUNDLED is not set -# CT_GCC_PATCH_NONE is not set -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_REQUIRE_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_REQUIRE_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_REQUIRE_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set -# CT_CC_LANG_ADA is not set -# CT_CC_LANG_OBJC is not set -# CT_CC_LANG_OBJCXX is not set -# CT_CC_LANG_GOLANG is not set -CT_CC_LANG_OTHERS="" - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -CT_DEBUG_GDB=y -CT_DEBUG_GDB_PKG_KSYM="GDB" -CT_GDB_DIR_NAME="gdb" -CT_GDB_USE_GNU=y -CT_GDB_USE="GDB" -CT_GDB_PKG_NAME="gdb" -CT_GDB_SRC_RELEASE=y -# CT_GDB_SRC_DEVEL is not set -# CT_GDB_SRC_CUSTOM is not set -CT_GDB_PATCH_GLOBAL=y -# CT_GDB_PATCH_BUNDLED is not set -# CT_GDB_PATCH_LOCAL is not set -# CT_GDB_PATCH_BUNDLED_LOCAL is not set -# CT_GDB_PATCH_LOCAL_BUNDLED is not set -# CT_GDB_PATCH_NONE is not set -CT_GDB_PATCH_ORDER="global" -CT_GDB_V_8_2=y -# CT_GDB_V_8_1 is not set -# CT_GDB_V_8_0 is not set -# CT_GDB_NO_VERSIONS is not set -CT_GDB_VERSION="8.2.1" -CT_GDB_MIRRORS="$(CT_Mirrors GNU gdb) $(CT_Mirrors sourceware gdb/releases)" -CT_GDB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GDB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GDB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GDB_SIGNATURE_FORMAT="" -CT_GDB_later_than_8_0=y -CT_GDB_8_0_or_later=y -CT_GDB_REQUIRE_8_0_or_later=y -CT_GDB_later_than_7_12=y -CT_GDB_7_12_or_later=y -CT_GDB_later_than_7_2=y -CT_GDB_7_2_or_later=y -CT_GDB_later_than_7_0=y -CT_GDB_7_0_or_later=y -CT_GDB_CROSS=y -# CT_GDB_CROSS_STATIC is not set -# CT_GDB_CROSS_SIM is not set -# CT_GDB_CROSS_PYTHON is not set -CT_GDB_CROSS_EXTRA_CONFIG_ARRAY="" -# CT_GDB_NATIVE is not set -# CT_GDB_GDBSERVER is not set -CT_GDB_HAS_PKGVERSION_BUGURL=y -CT_GDB_HAS_PYTHON=y -CT_GDB_INSTALL_GDBINIT=y -CT_GDB_HAS_IPA_LIB=y -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -CT_COMP_LIBS_EXPAT=y -CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT" -CT_EXPAT_DIR_NAME="expat" -CT_EXPAT_PKG_NAME="expat" -CT_EXPAT_SRC_RELEASE=y -# CT_EXPAT_SRC_DEVEL is not set -# CT_EXPAT_SRC_CUSTOM is not set -CT_EXPAT_PATCH_GLOBAL=y -# CT_EXPAT_PATCH_BUNDLED is not set -# CT_EXPAT_PATCH_LOCAL is not set -# CT_EXPAT_PATCH_BUNDLED_LOCAL is not set -# CT_EXPAT_PATCH_LOCAL_BUNDLED is not set -# CT_EXPAT_PATCH_NONE is not set -CT_EXPAT_PATCH_ORDER="global" -CT_EXPAT_V_2_2=y -# CT_EXPAT_NO_VERSIONS is not set -CT_EXPAT_VERSION="2.4.1" -CT_EXPAT_VERSION_TAG="2_4_1" -CT_EXPAT_MIRRORS="https://github.com/libexpat/libexpat/releases/download/R_${CT_EXPAT_VERSION_TAG}" -CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2" -CT_EXPAT_SIGNATURE_FORMAT="" -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -# CT_GETTEXT_SRC_DEVEL is not set -# CT_GETTEXT_SRC_CUSTOM is not set -CT_GETTEXT_PATCH_GLOBAL=y -# CT_GETTEXT_PATCH_BUNDLED is not set -# CT_GETTEXT_PATCH_LOCAL is not set -# CT_GETTEXT_PATCH_BUNDLED_LOCAL is not set -# CT_GETTEXT_PATCH_LOCAL_BUNDLED is not set -# CT_GETTEXT_PATCH_NONE is not set -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -# CT_GMP_SRC_DEVEL is not set -# CT_GMP_SRC_CUSTOM is not set -CT_GMP_PATCH_GLOBAL=y -# CT_GMP_PATCH_BUNDLED is not set -# CT_GMP_PATCH_LOCAL is not set -# CT_GMP_PATCH_BUNDLED_LOCAL is not set -# CT_GMP_PATCH_LOCAL_BUNDLED is not set -# CT_GMP_PATCH_NONE is not set -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -# CT_ISL_SRC_DEVEL is not set -# CT_ISL_SRC_CUSTOM is not set -CT_ISL_PATCH_GLOBAL=y -# CT_ISL_PATCH_BUNDLED is not set -# CT_ISL_PATCH_LOCAL is not set -# CT_ISL_PATCH_BUNDLED_LOCAL is not set -# CT_ISL_PATCH_LOCAL_BUNDLED is not set -# CT_ISL_PATCH_NONE is not set -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -# CT_LIBICONV_SRC_DEVEL is not set -# CT_LIBICONV_SRC_CUSTOM is not set -CT_LIBICONV_PATCH_GLOBAL=y -# CT_LIBICONV_PATCH_BUNDLED is not set -# CT_LIBICONV_PATCH_LOCAL is not set -# CT_LIBICONV_PATCH_BUNDLED_LOCAL is not set -# CT_LIBICONV_PATCH_LOCAL_BUNDLED is not set -# CT_LIBICONV_PATCH_NONE is not set -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -# CT_MPC_SRC_DEVEL is not set -# CT_MPC_SRC_CUSTOM is not set -CT_MPC_PATCH_GLOBAL=y -# CT_MPC_PATCH_BUNDLED is not set -# CT_MPC_PATCH_LOCAL is not set -# CT_MPC_PATCH_BUNDLED_LOCAL is not set -# CT_MPC_PATCH_LOCAL_BUNDLED is not set -# CT_MPC_PATCH_NONE is not set -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -# CT_MPFR_SRC_DEVEL is not set -# CT_MPFR_SRC_CUSTOM is not set -CT_MPFR_PATCH_GLOBAL=y -# CT_MPFR_PATCH_BUNDLED is not set -# CT_MPFR_PATCH_LOCAL is not set -# CT_MPFR_PATCH_BUNDLED_LOCAL is not set -# CT_MPFR_PATCH_LOCAL_BUNDLED is not set -# CT_MPFR_PATCH_NONE is not set -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -# CT_NCURSES_SRC_DEVEL is not set -# CT_NCURSES_SRC_CUSTOM is not set -CT_NCURSES_PATCH_GLOBAL=y -# CT_NCURSES_PATCH_BUNDLED is not set -# CT_NCURSES_PATCH_LOCAL is not set -# CT_NCURSES_PATCH_BUNDLED_LOCAL is not set -# CT_NCURSES_PATCH_LOCAL_BUNDLED is not set -# CT_NCURSES_PATCH_NONE is not set -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -# CT_NCURSES_NEW_ABI is not set -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -# CT_ZLIB_SRC_DEVEL is not set -# CT_ZLIB_SRC_CUSTOM is not set -CT_ZLIB_PATCH_GLOBAL=y -# CT_ZLIB_PATCH_BUNDLED is not set -# CT_ZLIB_PATCH_LOCAL is not set -# CT_ZLIB_PATCH_BUNDLED_LOCAL is not set -# CT_ZLIB_PATCH_LOCAL_BUNDLED is not set -# CT_ZLIB_PATCH_NONE is not set -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="https://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_EXPAT_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_EXPAT=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" - -# -# Test suite -# -# CT_TEST_SUITE_GCC is not set diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig new file mode 100644 index 00000000000..10075907beb --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig @@ -0,0 +1,16 @@ +CT_CONFIG_VERSION="4" +CT_EXPERIMENTAL=y +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_RISCV=y +# CT_DEMULTILIB is not set +CT_ARCH_USE_MMU=y +CT_ARCH_64=y +CT_ARCH_ARCH="rv64gc" +CT_KERNEL_LINUX=y +CT_LINUX_V_4_20=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_29=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile index adb98d7ebb5..de776911d62 100644 --- a/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile @@ -1,20 +1,18 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-1.24.sh /scripts/ -RUN sh /scripts/crosstool-ng-1.24.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh -USER rustbuild WORKDIR /tmp -COPY host-x86_64/dist-s390x-linux/s390x-linux-gnu.config host-x86_64/dist-s390x-linux/build-s390x-toolchain.sh /tmp/ -RUN ./build-s390x-toolchain.sh - -USER root +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-s390x-linux/s390x-linux-gnu.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-s390x-linux/build-s390x-toolchain.sh b/src/ci/docker/host-x86_64/dist-s390x-linux/build-s390x-toolchain.sh deleted file mode 100755 index 6f8d6be842b..00000000000 --- a/src/ci/docker/host-x86_64/dist-s390x-linux/build-s390x-toolchain.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -ex - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - "$@" &> /tmp/build.log - rm /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir build -cd build -cp ../s390x-linux-gnu.config .config -hide_output ct-ng build -cd .. -rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config b/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config deleted file mode 100644 index 51ef36b03ac..00000000000 --- a/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config +++ /dev/null @@ -1,732 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# crosstool-NG Configuration -# -CT_CONFIGURE_has_static_link=y -CT_CONFIGURE_has_cxx11=y -CT_CONFIGURE_has_wget=y -CT_CONFIGURE_has_curl=y -CT_CONFIGURE_has_make_3_81_or_newer=y -CT_CONFIGURE_has_make_4_0_or_newer=y -CT_CONFIGURE_has_libtool_2_4_or_newer=y -CT_CONFIGURE_has_libtoolize_2_4_or_newer=y -CT_CONFIGURE_has_autoconf_2_65_or_newer=y -CT_CONFIGURE_has_autoreconf_2_65_or_newer=y -CT_CONFIGURE_has_automake_1_15_or_newer=y -CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y -CT_CONFIGURE_has_python_3_4_or_newer=y -CT_CONFIGURE_has_bison_2_7_or_newer=y -CT_CONFIGURE_has_python=y -CT_CONFIGURE_has_git=y -CT_CONFIGURE_has_md5sum=y -CT_CONFIGURE_has_sha1sum=y -CT_CONFIGURE_has_sha256sum=y -CT_CONFIGURE_has_sha512sum=y -CT_CONFIGURE_has_install_with_strip_program=y -CT_CONFIG_VERSION_CURRENT="3" -CT_CONFIG_VERSION="3" -CT_MODULES=y - -# -# Paths and misc options -# - -# -# crosstool-NG behavior -# -# CT_OBSOLETE is not set -# CT_EXPERIMENTAL is not set -# CT_DEBUG_CT is not set - -# -# Paths -# -CT_LOCAL_TARBALLS_DIR="${HOME}/src" -CT_SAVE_TARBALLS=y -# CT_TARBALLS_BUILDROOT_LAYOUT is not set -CT_WORK_DIR="${CT_TOP_DIR}/.build" -CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" -CT_PREFIX_DIR="/x-tools/${CT_TARGET}" -CT_RM_RF_PREFIX_DIR=y -CT_REMOVE_DOCS=y -CT_INSTALL_LICENSES=y -CT_PREFIX_DIR_RO=y -CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y -# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set - -# -# Downloading -# -CT_DOWNLOAD_AGENT_WGET=y -# CT_DOWNLOAD_AGENT_CURL is not set -# CT_DOWNLOAD_AGENT_NONE is not set -# CT_FORBID_DOWNLOAD is not set -# CT_FORCE_DOWNLOAD is not set -CT_CONNECT_TIMEOUT=10 -CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" -# CT_ONLY_DOWNLOAD is not set -CT_USE_MIRROR=y -# CT_FORCE_MIRROR is not set -CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" -CT_VERIFY_DOWNLOAD_DIGEST=y -CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y -# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set -# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set -CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" -# CT_VERIFY_DOWNLOAD_SIGNATURE is not set - -# -# Extracting -# -# CT_FORCE_EXTRACT is not set -CT_OVERRIDE_CONFIG_GUESS_SUB=y -# CT_ONLY_EXTRACT is not set -CT_PATCH_BUNDLED=y -# CT_PATCH_BUNDLED_LOCAL is not set -CT_PATCH_ORDER="bundled" - -# -# Build behavior -# -CT_PARALLEL_JOBS=0 -CT_LOAD="" -CT_USE_PIPES=y -CT_EXTRA_CFLAGS_FOR_BUILD="" -CT_EXTRA_LDFLAGS_FOR_BUILD="" -CT_EXTRA_CFLAGS_FOR_HOST="" -CT_EXTRA_LDFLAGS_FOR_HOST="" -# CT_CONFIG_SHELL_SH is not set -# CT_CONFIG_SHELL_ASH is not set -CT_CONFIG_SHELL_BASH=y -# CT_CONFIG_SHELL_CUSTOM is not set -CT_CONFIG_SHELL="${bash}" - -# -# Logging -# -# CT_LOG_ERROR is not set -# CT_LOG_WARN is not set -# CT_LOG_INFO is not set -CT_LOG_EXTRA=y -# CT_LOG_ALL is not set -# CT_LOG_DEBUG is not set -CT_LOG_LEVEL_MAX="EXTRA" -# CT_LOG_SEE_TOOLS_WARN is not set -CT_LOG_PROGRESS_BAR=y -CT_LOG_TO_FILE=y -CT_LOG_FILE_COMPRESS=y - -# -# Target options -# -# CT_ARCH_ALPHA is not set -# CT_ARCH_ARC is not set -# CT_ARCH_ARM is not set -# CT_ARCH_AVR is not set -# CT_ARCH_M68K is not set -# CT_ARCH_MIPS is not set -# CT_ARCH_NIOS2 is not set -# CT_ARCH_POWERPC is not set -CT_ARCH_S390=y -# CT_ARCH_SH is not set -# CT_ARCH_SPARC is not set -# CT_ARCH_X86 is not set -# CT_ARCH_XTENSA is not set -CT_ARCH="s390" -CT_ARCH_CHOICE_KSYM="S390" -# CT_ARCH_ALPHA_EV4 is not set -# CT_ARCH_ALPHA_EV45 is not set -# CT_ARCH_ALPHA_EV5 is not set -# CT_ARCH_ALPHA_EV56 is not set -# CT_ARCH_ALPHA_EV6 is not set -# CT_ARCH_ALPHA_EV67 is not set -CT_ARCH_S390_SHOW=y - -# -# Options for s390 -# -CT_ARCH_S390_PKG_KSYM="" -CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" -CT_ARCH_SUFFIX="" -# CT_OMIT_TARGET_VENDOR is not set - -# -# Generic target options -# -# CT_MULTILIB is not set -CT_DEMULTILIB=y -CT_ARCH_USE_MMU=y -CT_ARCH_SUPPORTS_32=y -CT_ARCH_SUPPORTS_64=y -CT_ARCH_DEFAULT_32=y -CT_ARCH_BITNESS=64 -# CT_ARCH_32 is not set -CT_ARCH_64=y - -# -# Target optimisations -# -CT_ARCH_SUPPORTS_WITH_FPU=y -CT_ARCH_FPU="" -CT_TARGET_CFLAGS="" -CT_TARGET_LDFLAGS="" - -# -# Toolchain options -# - -# -# General toolchain options -# -CT_FORCE_SYSROOT=y -CT_USE_SYSROOT=y -CT_SYSROOT_NAME="sysroot" -CT_SYSROOT_DIR_PREFIX="" -CT_WANTS_STATIC_LINK=y -CT_WANTS_STATIC_LINK_CXX=y -# CT_STATIC_TOOLCHAIN is not set -CT_SHOW_CT_VERSION=y -CT_TOOLCHAIN_PKGVERSION="" -CT_TOOLCHAIN_BUGURL="" - -# -# Tuple completion and aliasing -# -CT_TARGET_VENDOR="unknown" -CT_TARGET_ALIAS_SED_EXPR="" -CT_TARGET_ALIAS="" - -# -# Toolchain type -# -CT_CROSS=y -# CT_CANADIAN is not set -CT_TOOLCHAIN_TYPE="cross" - -# -# Build system -# -CT_BUILD="" -CT_BUILD_PREFIX="" -CT_BUILD_SUFFIX="" - -# -# Misc options -# -# CT_TOOLCHAIN_ENABLE_NLS is not set - -# -# Operating System -# -CT_KERNEL_SUPPORTS_SHARED_LIBS=y -# CT_KERNEL_BARE_METAL is not set -CT_KERNEL_LINUX=y -CT_KERNEL="linux" -CT_KERNEL_CHOICE_KSYM="LINUX" -CT_KERNEL_LINUX_SHOW=y - -# -# Options for linux -# -CT_KERNEL_LINUX_PKG_KSYM="LINUX" -CT_LINUX_DIR_NAME="linux" -CT_LINUX_PKG_NAME="linux" -CT_LINUX_SRC_RELEASE=y -CT_LINUX_PATCH_ORDER="global" -# CT_LINUX_V_4_20 is not set -# CT_LINUX_V_4_19 is not set -# CT_LINUX_V_4_18 is not set -# CT_LINUX_V_4_17 is not set -# CT_LINUX_V_4_16 is not set -# CT_LINUX_V_4_15 is not set -# CT_LINUX_V_4_14 is not set -# CT_LINUX_V_4_13 is not set -# CT_LINUX_V_4_12 is not set -# CT_LINUX_V_4_11 is not set -# CT_LINUX_V_4_10 is not set -# CT_LINUX_V_4_9 is not set -# CT_LINUX_V_4_4 is not set -# CT_LINUX_V_4_1 is not set -# CT_LINUX_V_3_16 is not set -# CT_LINUX_V_3_13 is not set -# CT_LINUX_V_3_12 is not set -# CT_LINUX_V_3_10 is not set -# CT_LINUX_V_3_4 is not set -CT_LINUX_V_3_2=y -# CT_LINUX_V_2_6_32 is not set -# CT_LINUX_NO_VERSIONS is not set -CT_LINUX_VERSION="3.2.101" -CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" -CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" -CT_LINUX_4_8_or_older=y -CT_LINUX_older_than_4_8=y -CT_LINUX_3_7_or_older=y -CT_LINUX_older_than_3_7=y -CT_LINUX_later_than_3_2=y -CT_LINUX_3_2_or_later=y -CT_KERNEL_LINUX_VERBOSITY_0=y -# CT_KERNEL_LINUX_VERBOSITY_1 is not set -# CT_KERNEL_LINUX_VERBOSITY_2 is not set -CT_KERNEL_LINUX_VERBOSE_LEVEL=0 -CT_KERNEL_LINUX_INSTALL_CHECK=y -CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" - -# -# Common kernel options -# -CT_SHARED_LIBS=y - -# -# Binary utilities -# -CT_ARCH_BINFMT_ELF=y -CT_BINUTILS_BINUTILS=y -CT_BINUTILS="binutils" -CT_BINUTILS_CHOICE_KSYM="BINUTILS" -CT_BINUTILS_BINUTILS_SHOW=y - -# -# Options for binutils -# -CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" -CT_BINUTILS_DIR_NAME="binutils" -CT_BINUTILS_USE_GNU=y -CT_BINUTILS_USE="BINUTILS" -CT_BINUTILS_PKG_NAME="binutils" -CT_BINUTILS_SRC_RELEASE=y -CT_BINUTILS_PATCH_ORDER="global" -CT_BINUTILS_V_2_32=y -# CT_BINUTILS_V_2_31 is not set -# CT_BINUTILS_V_2_30 is not set -# CT_BINUTILS_V_2_29 is not set -# CT_BINUTILS_V_2_28 is not set -# CT_BINUTILS_V_2_27 is not set -# CT_BINUTILS_V_2_26 is not set -# CT_BINUTILS_NO_VERSIONS is not set -CT_BINUTILS_VERSION="2.32" -CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" -CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" -CT_BINUTILS_later_than_2_30=y -CT_BINUTILS_2_30_or_later=y -CT_BINUTILS_later_than_2_27=y -CT_BINUTILS_2_27_or_later=y -CT_BINUTILS_later_than_2_25=y -CT_BINUTILS_2_25_or_later=y -CT_BINUTILS_later_than_2_23=y -CT_BINUTILS_2_23_or_later=y - -# -# GNU binutils -# -CT_BINUTILS_HAS_HASH_STYLE=y -CT_BINUTILS_HAS_GOLD=y -CT_BINUTILS_HAS_PLUGINS=y -CT_BINUTILS_HAS_PKGVERSION_BUGURL=y -CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y -CT_BINUTILS_LINKER_LD=y -CT_BINUTILS_LINKERS_LIST="ld" -CT_BINUTILS_LINKER_DEFAULT="bfd" -# CT_BINUTILS_PLUGINS is not set -CT_BINUTILS_RELRO=m -CT_BINUTILS_EXTRA_CONFIG_ARRAY="" -# CT_BINUTILS_FOR_TARGET is not set -CT_ALL_BINUTILS_CHOICES="BINUTILS" - -# -# C-library -# -CT_LIBC_GLIBC=y -# CT_LIBC_NEWLIB is not set -# CT_LIBC_NONE is not set -# CT_LIBC_UCLIBC is not set -CT_LIBC="glibc" -CT_LIBC_CHOICE_KSYM="GLIBC" -CT_THREADS="nptl" -CT_LIBC_GLIBC_SHOW=y - -# -# Options for glibc -# -CT_LIBC_GLIBC_PKG_KSYM="GLIBC" -CT_GLIBC_DIR_NAME="glibc" -CT_GLIBC_USE_GNU=y -CT_GLIBC_USE="GLIBC" -CT_GLIBC_PKG_NAME="glibc" -CT_GLIBC_SRC_RELEASE=y -CT_GLIBC_PATCH_ORDER="global" -# CT_GLIBC_V_2_29 is not set -# CT_GLIBC_V_2_28 is not set -# CT_GLIBC_V_2_27 is not set -# CT_GLIBC_V_2_26 is not set -# CT_GLIBC_V_2_25 is not set -# CT_GLIBC_V_2_24 is not set -# CT_GLIBC_V_2_23 is not set -# CT_GLIBC_V_2_19 is not set -CT_GLIBC_V_2_17=y -# CT_GLIBC_V_2_12_1 is not set -# CT_GLIBC_NO_VERSIONS is not set -CT_GLIBC_VERSION="2.17" -CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" -CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" -CT_GLIBC_2_29_or_older=y -CT_GLIBC_older_than_2_29=y -CT_GLIBC_2_27_or_older=y -CT_GLIBC_older_than_2_27=y -CT_GLIBC_2_26_or_older=y -CT_GLIBC_older_than_2_26=y -CT_GLIBC_2_25_or_older=y -CT_GLIBC_older_than_2_25=y -CT_GLIBC_2_24_or_older=y -CT_GLIBC_older_than_2_24=y -CT_GLIBC_2_23_or_older=y -CT_GLIBC_older_than_2_23=y -CT_GLIBC_2_20_or_older=y -CT_GLIBC_older_than_2_20=y -CT_GLIBC_2_17_or_later=y -CT_GLIBC_2_17_or_older=y -CT_GLIBC_later_than_2_14=y -CT_GLIBC_2_14_or_later=y -CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y -CT_GLIBC_DEP_BINUTILS=y -CT_GLIBC_DEP_GCC=y -CT_GLIBC_DEP_PYTHON=y -CT_GLIBC_HAS_NPTL_ADDON=y -CT_GLIBC_HAS_PORTS_ADDON=y -CT_GLIBC_HAS_LIBIDN_ADDON=y -CT_GLIBC_USE_NPTL_ADDON=y -# CT_GLIBC_USE_LIBIDN_ADDON is not set -CT_GLIBC_HAS_OBSOLETE_RPC=y -CT_GLIBC_EXTRA_CONFIG_ARRAY="" -CT_GLIBC_CONFIGPARMS="" -CT_GLIBC_EXTRA_CFLAGS="" -CT_GLIBC_ENABLE_OBSOLETE_RPC=y -# CT_GLIBC_DISABLE_VERSIONING is not set -CT_GLIBC_OLDEST_ABI="" -CT_GLIBC_FORCE_UNWIND=y -# CT_GLIBC_LOCALES is not set -# CT_GLIBC_KERNEL_VERSION_NONE is not set -CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y -# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set -CT_GLIBC_MIN_KERNEL="3.2.101" -# CT_GLIBC_SSP_DEFAULT is not set -# CT_GLIBC_SSP_NO is not set -# CT_GLIBC_SSP_YES is not set -# CT_GLIBC_SSP_ALL is not set -# CT_GLIBC_SSP_STRONG is not set -# CT_NEWLIB_USE_REDHAT is not set -CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" -CT_LIBC_SUPPORT_THREADS_ANY=y -CT_LIBC_SUPPORT_THREADS_NATIVE=y - -# -# Common C library options -# -CT_THREADS_NATIVE=y -# CT_CREATE_LDSO_CONF is not set -CT_LIBC_XLDD=y - -# -# C compiler -# -CT_CC_CORE_PASSES_NEEDED=y -CT_CC_CORE_PASS_1_NEEDED=y -CT_CC_CORE_PASS_2_NEEDED=y -CT_CC_SUPPORT_CXX=y -CT_CC_SUPPORT_FORTRAN=y -CT_CC_SUPPORT_ADA=y -CT_CC_SUPPORT_OBJC=y -CT_CC_SUPPORT_OBJCXX=y -CT_CC_SUPPORT_GOLANG=y -CT_CC_GCC=y -CT_CC="gcc" -CT_CC_CHOICE_KSYM="GCC" -CT_CC_GCC_SHOW=y - -# -# Options for gcc -# -CT_CC_GCC_PKG_KSYM="GCC" -CT_GCC_DIR_NAME="gcc" -CT_GCC_USE_GNU=y -CT_GCC_USE="GCC" -CT_GCC_PKG_NAME="gcc" -CT_GCC_SRC_RELEASE=y -CT_GCC_PATCH_ORDER="global" -CT_GCC_V_8=y -# CT_GCC_V_7 is not set -# CT_GCC_V_6 is not set -# CT_GCC_V_5 is not set -# CT_GCC_V_4_9 is not set -# CT_GCC_NO_VERSIONS is not set -CT_GCC_VERSION="8.3.0" -CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" -CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_GCC_SIGNATURE_FORMAT="" -CT_GCC_later_than_7=y -CT_GCC_7_or_later=y -CT_GCC_later_than_6=y -CT_GCC_6_or_later=y -CT_GCC_later_than_5=y -CT_GCC_5_or_later=y -CT_GCC_later_than_4_9=y -CT_GCC_4_9_or_later=y -CT_GCC_later_than_4_8=y -CT_GCC_4_8_or_later=y -CT_CC_GCC_HAS_LIBMPX=y -CT_CC_GCC_ENABLE_CXX_FLAGS="" -CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" -CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-arch=z10" -CT_CC_GCC_STATIC_LIBSTDCXX=y -# CT_CC_GCC_SYSTEM_ZLIB is not set -CT_CC_GCC_CONFIG_TLS=m - -# -# Optimisation features -# -CT_CC_GCC_USE_GRAPHITE=y -CT_CC_GCC_USE_LTO=y - -# -# Settings for libraries running on target -# -CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y -# CT_CC_GCC_LIBMUDFLAP is not set -# CT_CC_GCC_LIBGOMP is not set -# CT_CC_GCC_LIBSSP is not set -# CT_CC_GCC_LIBQUADMATH is not set -# CT_CC_GCC_LIBSANITIZER is not set - -# -# Misc. obscure options. -# -CT_CC_CXA_ATEXIT=y -# CT_CC_GCC_DISABLE_PCH is not set -CT_CC_GCC_SJLJ_EXCEPTIONS=m -CT_CC_GCC_LDBL_128=m -# CT_CC_GCC_BUILD_ID is not set -CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y -# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set -# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set -# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set -CT_CC_GCC_LNK_HASH_STYLE="" -CT_CC_GCC_DEC_FLOAT_AUTO=y -# CT_CC_GCC_DEC_FLOAT_BID is not set -# CT_CC_GCC_DEC_FLOAT_DPD is not set -# CT_CC_GCC_DEC_FLOATS_NO is not set -CT_ALL_CC_CHOICES="GCC" - -# -# Additional supported languages: -# -CT_CC_LANG_CXX=y -# CT_CC_LANG_FORTRAN is not set - -# -# Debug facilities -# -# CT_DEBUG_DUMA is not set -# CT_DEBUG_GDB is not set -# CT_DEBUG_LTRACE is not set -# CT_DEBUG_STRACE is not set -CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" - -# -# Companion libraries -# -# CT_COMPLIBS_CHECK is not set -# CT_COMP_LIBS_CLOOG is not set -# CT_COMP_LIBS_EXPAT is not set -CT_COMP_LIBS_GETTEXT=y -CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" -CT_GETTEXT_DIR_NAME="gettext" -CT_GETTEXT_PKG_NAME="gettext" -CT_GETTEXT_SRC_RELEASE=y -CT_GETTEXT_PATCH_ORDER="global" -CT_GETTEXT_V_0_19_8_1=y -# CT_GETTEXT_NO_VERSIONS is not set -CT_GETTEXT_VERSION="0.19.8.1" -CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" -CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" -CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_GMP=y -CT_COMP_LIBS_GMP_PKG_KSYM="GMP" -CT_GMP_DIR_NAME="gmp" -CT_GMP_PKG_NAME="gmp" -CT_GMP_SRC_RELEASE=y -CT_GMP_PATCH_ORDER="global" -CT_GMP_V_6_1=y -# CT_GMP_NO_VERSIONS is not set -CT_GMP_VERSION="6.1.2" -CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" -CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" -CT_GMP_SIGNATURE_FORMAT="packed/.sig" -CT_GMP_later_than_5_1_0=y -CT_GMP_5_1_0_or_later=y -CT_GMP_later_than_5_0_0=y -CT_GMP_5_0_0_or_later=y -CT_GMP_REQUIRE_5_0_0_or_later=y -CT_COMP_LIBS_ISL=y -CT_COMP_LIBS_ISL_PKG_KSYM="ISL" -CT_ISL_DIR_NAME="isl" -CT_ISL_PKG_NAME="isl" -CT_ISL_SRC_RELEASE=y -CT_ISL_PATCH_ORDER="global" -CT_ISL_V_0_20=y -# CT_ISL_V_0_19 is not set -# CT_ISL_V_0_18 is not set -# CT_ISL_V_0_17 is not set -# CT_ISL_V_0_16 is not set -# CT_ISL_V_0_15 is not set -# CT_ISL_NO_VERSIONS is not set -CT_ISL_VERSION="0.20" -CT_ISL_MIRRORS="http://isl.gforge.inria.fr" -CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" -CT_ISL_SIGNATURE_FORMAT="" -CT_ISL_later_than_0_18=y -CT_ISL_0_18_or_later=y -CT_ISL_later_than_0_15=y -CT_ISL_0_15_or_later=y -CT_ISL_REQUIRE_0_15_or_later=y -CT_ISL_later_than_0_14=y -CT_ISL_0_14_or_later=y -CT_ISL_REQUIRE_0_14_or_later=y -CT_ISL_later_than_0_13=y -CT_ISL_0_13_or_later=y -CT_ISL_later_than_0_12=y -CT_ISL_0_12_or_later=y -CT_ISL_REQUIRE_0_12_or_later=y -# CT_COMP_LIBS_LIBELF is not set -CT_COMP_LIBS_LIBICONV=y -CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" -CT_LIBICONV_DIR_NAME="libiconv" -CT_LIBICONV_PKG_NAME="libiconv" -CT_LIBICONV_SRC_RELEASE=y -CT_LIBICONV_PATCH_ORDER="global" -CT_LIBICONV_V_1_15=y -# CT_LIBICONV_NO_VERSIONS is not set -CT_LIBICONV_VERSION="1.15" -CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" -CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" -CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" -CT_COMP_LIBS_MPC=y -CT_COMP_LIBS_MPC_PKG_KSYM="MPC" -CT_MPC_DIR_NAME="mpc" -CT_MPC_PKG_NAME="mpc" -CT_MPC_SRC_RELEASE=y -CT_MPC_PATCH_ORDER="global" -CT_MPC_V_1_1=y -# CT_MPC_V_1_0 is not set -# CT_MPC_NO_VERSIONS is not set -CT_MPC_VERSION="1.1.0" -CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" -CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPC_ARCHIVE_FORMATS=".tar.gz" -CT_MPC_SIGNATURE_FORMAT="packed/.sig" -CT_MPC_1_1_0_or_later=y -CT_MPC_1_1_0_or_older=y -CT_COMP_LIBS_MPFR=y -CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" -CT_MPFR_DIR_NAME="mpfr" -CT_MPFR_PKG_NAME="mpfr" -CT_MPFR_SRC_RELEASE=y -CT_MPFR_PATCH_ORDER="global" -CT_MPFR_V_4_0=y -# CT_MPFR_V_3_1 is not set -# CT_MPFR_NO_VERSIONS is not set -CT_MPFR_VERSION="4.0.2" -CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" -CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" -CT_MPFR_SIGNATURE_FORMAT="packed/.asc" -CT_MPFR_later_than_4_0_0=y -CT_MPFR_4_0_0_or_later=y -CT_MPFR_later_than_3_0_0=y -CT_MPFR_3_0_0_or_later=y -CT_MPFR_REQUIRE_3_0_0_or_later=y -CT_COMP_LIBS_NCURSES=y -CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" -CT_NCURSES_DIR_NAME="ncurses" -CT_NCURSES_PKG_NAME="ncurses" -CT_NCURSES_SRC_RELEASE=y -CT_NCURSES_PATCH_ORDER="global" -CT_NCURSES_V_6_1=y -# CT_NCURSES_V_6_0 is not set -# CT_NCURSES_NO_VERSIONS is not set -CT_NCURSES_VERSION="6.1" -CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" -CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" -CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" -CT_NCURSES_HOST_CONFIG_ARGS="" -CT_NCURSES_HOST_DISABLE_DB=y -CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" -CT_NCURSES_TARGET_CONFIG_ARGS="" -# CT_NCURSES_TARGET_DISABLE_DB is not set -CT_NCURSES_TARGET_FALLBACKS="" -CT_COMP_LIBS_ZLIB=y -CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" -CT_ZLIB_DIR_NAME="zlib" -CT_ZLIB_PKG_NAME="zlib" -CT_ZLIB_SRC_RELEASE=y -CT_ZLIB_PATCH_ORDER="global" -CT_ZLIB_V_1_2_11=y -# CT_ZLIB_NO_VERSIONS is not set -CT_ZLIB_VERSION="1.2.11" -CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" -CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" -CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" -CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" -CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" -CT_LIBICONV_NEEDED=y -CT_GETTEXT_NEEDED=y -CT_GMP_NEEDED=y -CT_MPFR_NEEDED=y -CT_ISL_NEEDED=y -CT_MPC_NEEDED=y -CT_NCURSES_NEEDED=y -CT_ZLIB_NEEDED=y -CT_LIBICONV=y -CT_GETTEXT=y -CT_GMP=y -CT_MPFR=y -CT_ISL=y -CT_MPC=y -CT_NCURSES=y -CT_ZLIB=y - -# -# Companion tools -# -# CT_COMP_TOOLS_FOR_HOST is not set -# CT_COMP_TOOLS_AUTOCONF is not set -# CT_COMP_TOOLS_AUTOMAKE is not set -# CT_COMP_TOOLS_BISON is not set -# CT_COMP_TOOLS_DTC is not set -# CT_COMP_TOOLS_LIBTOOL is not set -# CT_COMP_TOOLS_M4 is not set -# CT_COMP_TOOLS_MAKE is not set -CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.defconfig new file mode 100644 index 00000000000..1fe21966600 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.defconfig @@ -0,0 +1,13 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_S390=y +CT_ARCH_64=y +CT_KERNEL_LINUX=y +CT_LINUX_V_3_2=y +CT_BINUTILS_V_2_32=y +CT_GLIBC_V_2_17=y +CT_GCC_V_8=y +CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-arch=z10" +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile index 13eaf7fce8c..6f04dcad9a5 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile @@ -25,7 +25,6 @@ WORKDIR /build/ COPY scripts/cmake.sh /scripts/ RUN /scripts/cmake.sh -COPY scripts/musl-patch-configure.diff /build/ COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well RUN CFLAGS="-Wa,-mrelax-relocations=no -Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile index 62e3f627ec0..1dc7b798724 100644 --- a/src/ci/docker/host-x86_64/test-various/Dockerfile +++ b/src/ci/docker/host-x86_64/test-various/Dockerfile @@ -33,7 +33,6 @@ RUN curl -sL --output ovmf-ia32.deb http://mirrors.kernel.org/ubuntu/pool/univer RUN dpkg -i ovmf-ia32.deb && rm ovmf-ia32.deb WORKDIR /build/ -COPY scripts/musl-patch-configure.diff /build/ COPY scripts/musl-toolchain.sh /build/ RUN bash musl-toolchain.sh x86_64 && rm -rf build WORKDIR / diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 69d4916e5a9..8bea8cd4c87 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -169,6 +169,7 @@ if [ "$SCCACHE_BUCKET" != "" ]; then args="$args --env SCCACHE_REGION" args="$args --env AWS_ACCESS_KEY_ID" args="$args --env AWS_SECRET_ACCESS_KEY" + args="$args --env AWS_REGION" else mkdir -p $HOME/.cache/sccache args="$args --env SCCACHE_DIR=/sccache --volume $HOME/.cache/sccache:/sccache" diff --git a/src/ci/docker/scripts/crosstool-ng-1.24.sh b/src/ci/docker/scripts/crosstool-ng-1.24.sh deleted file mode 100644 index 3a40f6cddb3..00000000000 --- a/src/ci/docker/scripts/crosstool-ng-1.24.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -set -ex - -# Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz -url="https://ci-mirrors.rust-lang.org/rustc/crosstool-ng-1.24.0.tar.gz" -curl -Lf $url | tar xzf - -cd crosstool-ng-crosstool-ng-1.24.0 -./bootstrap -./configure --prefix=/usr/local -make -j$(nproc) -make install -cd .. -rm -rf crosstool-ng-crosstool-ng-1.24.0 diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/build-toolchains.sh b/src/ci/docker/scripts/crosstool-ng-build.sh index a7025b2b754..c813d10eb9d 100755 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/build-toolchains.sh +++ b/src/ci/docker/scripts/crosstool-ng-build.sh @@ -2,6 +2,10 @@ set -ex +if [ $UID -eq 0 ]; then + exec su rustbuild -c "$0" +fi + hide_output() { set +x on_err=" @@ -21,7 +25,8 @@ exit 1 mkdir build cd build -cp ../riscv64-unknown-linux-gnu.config .config +cp ../crosstool.defconfig .config +ct-ng olddefconfig hide_output ct-ng build cd .. rm -rf build diff --git a/src/ci/docker/scripts/crosstool-ng.sh b/src/ci/docker/scripts/crosstool-ng.sh index 1d0c28c8e58..a28d7bde2ac 100644 --- a/src/ci/docker/scripts/crosstool-ng.sh +++ b/src/ci/docker/scripts/crosstool-ng.sh @@ -1,12 +1,19 @@ #!/bin/sh set -ex -url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.22.0.tar.gz" +CT_NG=1.25.0 + +url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-$CT_NG.tar.gz" curl -Lf $url | tar xzf - -cd crosstool-ng-crosstool-ng-1.22.0 +cd crosstool-ng-crosstool-ng-$CT_NG + +# https://github.com/crosstool-ng/crosstool-ng/issues/1832 +# "download source of zlib is invalid now" +sed -e "s|zlib.net/'|zlib.net/fossils'|" -i packages/zlib/package.desc + ./bootstrap ./configure --prefix=/usr/local make -j$(nproc) make install cd .. -rm -rf crosstool-ng-crosstool-ng-1.22.0 +rm -rf crosstool-ng-crosstool-ng-$CT_NG diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index e7d1d9781d5..ecef56f56f1 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -168,85 +168,17 @@ class TestEnvironment: def ffx_isolate_dir(self): return os.path.join(self.tmp_dir(), "ffx_isolate") - def ffx_home_dir(self): - return os.path.join(self.ffx_isolate_dir(), "user-home") + def home_dir(self): + return os.path.join(self.tmp_dir(), "user-home") - def ffx_tmp_dir(self): - return os.path.join(self.ffx_isolate_dir(), "tmp") - - def ffx_log_dir(self): - return os.path.join(self.ffx_isolate_dir(), "log") - - def ffx_user_config_dir(self): - return os.path.join(self.ffx_xdg_config_home(), "Fuchsia", "ffx", "config") - - def ffx_user_config_path(self): - return os.path.join(self.ffx_user_config_dir(), "config.json") - - def ffx_xdg_config_home(self): - if platform.system() == "Darwin": - return os.path.join(self.ffx_home_dir(), "Library", "Preferences") - return os.path.join(self.ffx_home_dir(), ".local", "share") - - def ffx_ascendd_path(self): - return os.path.join(self.ffx_tmp_dir(), "ascendd") def start_ffx_isolation(self): # Most of this is translated directly from ffx's isolate library os.mkdir(self.ffx_isolate_dir()) - os.mkdir(self.ffx_home_dir()) - os.mkdir(self.ffx_tmp_dir()) - os.mkdir(self.ffx_log_dir()) - - fuchsia_dir = os.path.join(self.ffx_home_dir(), ".fuchsia") - os.mkdir(fuchsia_dir) - - fuchsia_debug_dir = os.path.join(fuchsia_dir, "debug") - os.mkdir(fuchsia_debug_dir) - - metrics_dir = os.path.join(fuchsia_dir, "metrics") - os.mkdir(metrics_dir) + os.mkdir(self.home_dir()) - analytics_path = os.path.join(metrics_dir, "analytics-status") - with open(analytics_path, "w", encoding="utf-8") as analytics_file: - print("0", file=analytics_file) - - ffx_path = os.path.join(metrics_dir, "ffx") - with open(ffx_path, "w", encoding="utf-8") as ffx_file: - print("1", file=ffx_file) - - os.makedirs(self.ffx_user_config_dir()) - - with open( - self.ffx_user_config_path(), "w", encoding="utf-8" - ) as config_json_file: - user_config_for_test = { - "log": { - "enabled": True, - "dir": self.ffx_log_dir(), - }, - "overnet": { - "socket": self.ffx_ascendd_path(), - }, - "ssh": { - "pub": self.ssh_authfile_path(), - "priv": self.ssh_keyfile_path(), - }, - "test": { - "is_isolated": True, - "experimental_structured_output": True, - }, - } - print(json.dumps(user_config_for_test), file=config_json_file) - - ffx_env_path = os.path.join(self.ffx_user_config_dir(), ".ffx_env") - with open(ffx_env_path, "w", encoding="utf-8") as ffx_env_file: - ffx_env_config_for_test = { - "user": self.ffx_user_config_path(), - "build": None, - "global": None, - } - print(json.dumps(ffx_env_config_for_test), file=ffx_env_file) + ffx_path = self.tool_path("ffx") + ffx_env = self.ffx_cmd_env() # Start ffx daemon # We want this to be a long-running process that persists after the script finishes @@ -256,23 +188,54 @@ class TestEnvironment: ) as ffx_daemon_log_file: subprocess.Popen( [ - self.tool_path("ffx"), - "--config", - self.ffx_user_config_path(), + ffx_path, "daemon", "start", ], - env=self.ffx_cmd_env(), + env=ffx_env, stdout=ffx_daemon_log_file, stderr=ffx_daemon_log_file, ) + # Disable analytics + subprocess.check_call( + [ + ffx_path, + "config", + "analytics", + "disable", + ], + env=ffx_env, + stdout=self.subprocess_output(), + stderr=self.subprocess_output(), + ) + + # Set configs + configs = { + "log.enabled": "true", + "ssh.pub": self.ssh_authfile_path(), + "ssh.priv": self.ssh_keyfile_path(), + "test.is_isolated": "true", + "test.experimental_structured_output": "true", + } + for key, value in configs.items(): + subprocess.check_call( + [ + self.tool_path("ffx"), + "config", + "set", + key, + value, + ], + env=self.ffx_cmd_env(), + stdout=self.subprocess_output(), + stderr=self.subprocess_output(), + ) + def ffx_cmd_env(self): - result = { - "HOME": self.ffx_home_dir(), - "XDG_CONFIG_HOME": self.ffx_xdg_config_home(), - "ASCENDD": self.ffx_ascendd_path(), - "FUCHSIA_SSH_KEY": self.ssh_keyfile_path(), + return { + "HOME": self.home_dir(), + "FFX_ISOLATE_DIR": self.ffx_isolate_dir(), # We want to use our own specified temp directory "TMP": self.tmp_dir(), "TEMP": self.tmp_dir(), @@ -280,14 +243,10 @@ class TestEnvironment: "TEMPDIR": self.tmp_dir(), } - return result - def stop_ffx_isolation(self): subprocess.check_call( [ self.tool_path("ffx"), - "--config", - self.ffx_user_config_path(), "daemon", "stop", ], @@ -709,8 +668,6 @@ class TestEnvironment: subprocess.run( [ self.tool_path("ffx"), - "--config", - self.ffx_user_config_path(), "test", "run", f"fuchsia-pkg://{self.TEST_REPO_NAME}/{package_name}#meta/{package_name}.cm", @@ -849,8 +806,6 @@ class TestEnvironment: def debug(self, args): command = [ self.tool_path("ffx"), - "--config", - self.ffx_user_config_path(), "debug", "connect", "--", @@ -948,8 +903,6 @@ class TestEnvironment: subprocess.run( [ self.tool_path("ffx"), - "--config", - self.ffx_user_config_path(), "log", "--since", "now", diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index e358b8139d7..bc1b30e2d31 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -4,7 +4,7 @@ # # Versions of the toolchain components are configurable in `musl-cross-make/Makefile` and # musl unlike GLIBC is forward compatible so upgrading it shouldn't break old distributions. -# Right now we have: Binutils 2.31.1, GCC 9.2.0, musl 1.1.24. +# Right now we have: Binutils 2.31.1, GCC 9.2.0, musl 1.2.3. # ignore-tidy-linelength @@ -32,6 +32,7 @@ TARGET=$ARCH-linux-musl # Don't depend on the mirrors of sabotage linux that musl-cross-make uses. LINUX_HEADERS_SITE=https://ci-mirrors.rust-lang.org/rustc/sabotage-linux-tarballs +LINUX_VER=headers-4.19.88 OUTPUT=/usr/local shift @@ -44,18 +45,11 @@ export CFLAGS="-fPIC -g1 $CFLAGS" git clone https://github.com/richfelker/musl-cross-make # -b v0.9.9 cd musl-cross-make -# A few commits ahead of v0.9.9 to include the cowpatch fix: -git checkout a54eb56f33f255dfca60be045f12a5cfaf5a72a9 +# A version that includes support for building musl 1.2.3 +git checkout fe915821b652a7fa37b34a596f47d8e20bc72338 -# Fix the cfi detection script in musl's configure so cfi is generated -# when debug info is asked for. This patch is derived from -# https://git.musl-libc.org/cgit/musl/commit/?id=c4d4028dde90562f631edf559fbc42d8ec1b29de. -# When we upgrade to a version that includes this commit, we can remove the patch. -mkdir patches/musl-1.1.24 -cp ../musl-patch-configure.diff patches/musl-1.1.24/0001-fix-cfi-detection.diff - -hide_output make -j$(nproc) TARGET=$TARGET MUSL_VER=1.1.24 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE -hide_output make install TARGET=$TARGET MUSL_VER=1.1.24 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE OUTPUT=$OUTPUT +hide_output make -j$(nproc) TARGET=$TARGET MUSL_VER=1.2.3 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER +hide_output make install TARGET=$TARGET MUSL_VER=1.2.3 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER OUTPUT=$OUTPUT cd - diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh index 3e5dc4af04a..ece8e6c15c0 100644 --- a/src/ci/docker/scripts/musl.sh +++ b/src/ci/docker/scripts/musl.sh @@ -25,7 +25,7 @@ shift # Apparently applying `-fPIC` everywhere allows them to link successfully. export CFLAGS="-fPIC $CFLAGS" -MUSL=musl-1.1.24 +MUSL=musl-1.2.3 # may have been downloaded in a previous run if [ ! -d $MUSL ]; then diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 8409b9ca569..f81e740936b 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -53,6 +53,7 @@ x--expand-yaml-anchors--remove: # (caches, artifacts...). CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 + AWS_REGION: us-west-1 CACHE_DOMAIN: ci-caches.rust-lang.org - &dummy-variables @@ -68,11 +69,16 @@ x--expand-yaml-anchors--remove: # (caches, artifacts...). CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZOMUQATD5 ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZH5AYXDVF + AWS_REGION: us-west-1 CACHE_DOMAIN: ci-caches-gha.rust-lang.org - &base-job env: {} + - &job-linux-4c + os: ubuntu-20.04-4core-16gb + <<: *base-job + - &job-linux-8c os: ubuntu-20.04-8core-32gb <<: *base-job @@ -154,10 +160,6 @@ x--expand-yaml-anchors--remove: run: src/ci/scripts/dump-environment.sh <<: *step - - name: install awscli - run: src/ci/scripts/install-awscli.sh - <<: *step - - name: install sccache run: src/ci/scripts/install-sccache.sh <<: *step @@ -296,25 +298,21 @@ jobs: env: <<: [*shared-ci-variables, *public-variables] if: github.event_name == 'pull_request' - continue-on-error: ${{ matrix.tidy }} + continue-on-error: ${{ matrix.name == 'mingw-check-tidy' }} strategy: matrix: include: - name: mingw-check <<: *job-linux-16c - tidy: false - name: mingw-check-tidy <<: *job-linux-16c - tidy: true - name: x86_64-gnu-llvm-14 <<: *job-linux-16c - tidy: false - name: x86_64-gnu-tools <<: *job-linux-16c - tidy: false auto: permissions: @@ -416,13 +414,13 @@ jobs: <<: *job-linux-8c - name: i686-gnu - <<: *job-linux-16c + <<: *job-linux-8c - name: i686-gnu-nopt - <<: *job-linux-16c + <<: *job-linux-8c - name: mingw-check - <<: *job-linux-8c + <<: *job-linux-4c - name: test-various <<: *job-linux-8c @@ -431,7 +429,7 @@ jobs: <<: *job-linux-8c - name: x86_64-gnu - <<: *job-linux-8c + <<: *job-linux-4c # This job ensures commits landing on nightly still pass the full # test suite on the stable channel. There are some UI tests that @@ -446,10 +444,10 @@ jobs: # could cause failures when `dev: 1` in `stage0.txt`, and running # this on stable is useless. CI_ONLY_WHEN_CHANNEL: nightly - <<: *job-linux-8c + <<: *job-linux-4c - name: x86_64-gnu-aux - <<: *job-linux-8c + <<: *job-linux-4c - name: x86_64-gnu-debug <<: *job-linux-8c @@ -478,7 +476,7 @@ jobs: <<: *job-linux-8c - name: x86_64-gnu-nopt - <<: *job-linux-8c + <<: *job-linux-4c - name: x86_64-gnu-tools env: diff --git a/src/ci/scripts/install-awscli.sh b/src/ci/scripts/install-awscli.sh deleted file mode 100755 index aa62407eaea..00000000000 --- a/src/ci/scripts/install-awscli.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -# This script downloads and installs awscli from the packages mirrored in our -# own S3 bucket. This follows the recommendations at: -# -# https://packaging.python.org/guides/index-mirrors-and-caches/#caching-with-pip -# -# To create a new mirrored copy you can run the command: -# -# pip wheel awscli -# -# Before compressing please make sure all the wheels end with `-none-any.whl`. -# If that's not the case you'll need to remove the non-cross-platform ones and -# replace them with the .tar.gz downloaded from https://pypi.org. - -set -euo pipefail -IFS=$'\n\t' - -source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" - -MIRROR="${MIRRORS_BASE}/2023-04-28-awscli.tar" -DEPS_DIR="/tmp/awscli-deps" - -pip="pip" -pipflags="" -if isLinux; then - pip="pip3" - pipflags="--user" - - sudo apt-get install -y python3-setuptools python3-wheel - ciCommandAddPath "${HOME}/.local/bin" -elif isMacOS; then - pip="pip3" -fi - -mkdir -p "${DEPS_DIR}" -curl "${MIRROR}" | tar xf - -C "${DEPS_DIR}" -"${pip}" install ${pipflags} --no-index "--find-links=${DEPS_DIR}" awscli -rm -rf "${DEPS_DIR}" diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index d7c6a884fc8..1041d502669 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -90,6 +90,14 @@ It takes one of the following values: For example, for gcc flavor linkers, this issues the `-nodefaultlibs` flag to the linker. +## dlltool + +On `windows-gnu` targets, this flag controls which dlltool `rustc` invokes to +generate import libraries when using the [`raw-dylib` link kind](../../reference/items/external-blocks.md#the-link-attribute). +It takes a path to [the dlltool executable](https://sourceware.org/binutils/docs/binutils/dlltool.html). +If this flag is not specified, a dlltool executable will be inferred based on +the host environment and target. + ## embed-bitcode This flag controls whether or not the compiler embeds LLVM bitcode into object @@ -574,7 +582,8 @@ change in the future. This instructs `rustc` to generate code specifically for a particular processor. You can run `rustc --print target-cpus` to see the valid options to pass -here. Each target has a default base CPU. Special values include: +and the default target CPU for the current buid target. +Each target has a default base CPU. Special values include: * `native` can be passed to use the processor of the host machine. * `generic` refers to an LLVM target with minimal features but modern tuning. diff --git a/src/doc/unstable-book/src/compiler-flags/extern-options.md b/src/doc/unstable-book/src/compiler-flags/extern-options.md index dfc1de77be4..087b37dd8de 100644 --- a/src/doc/unstable-book/src/compiler-flags/extern-options.md +++ b/src/doc/unstable-book/src/compiler-flags/extern-options.md @@ -4,6 +4,7 @@ * Tracking issue for `noprelude`: [#98398](https://github.com/rust-lang/rust/issues/98398) * Tracking issue for `priv`: [#98399](https://github.com/rust-lang/rust/issues/98399) * Tracking issue for `nounused`: [#98400](https://github.com/rust-lang/rust/issues/98400) +* Tracking issue for `force`: [#111302](https://github.com/rust-lang/rust/issues/111302) The behavior of the `--extern` flag can be modified with `noprelude`, `priv` or `nounused` options. @@ -25,3 +26,4 @@ To use multiple options, separate them with a comma: This is used by the [build-std project](https://github.com/rust-lang/wg-cargo-std-aware/) to simulate compatibility with sysroot-only crates. * `priv`: Mark the crate as a private dependency for the [`exported_private_dependencies`](../../rustc/lints/listing/warn-by-default.html#exported-private-dependencies) lint. * `nounused`: Suppress [`unused-crate-dependencies`](../../rustc/lints/listing/allowed-by-default.html#unused-crate-dependencies) warnings for the crate. +* `force`: Resolve the crate as if it is used, even if it is not used. This can be used to satisfy compilation session requirements like the presence of an allocator or panic handler. diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index b55348b7889..aa776daf09d 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -196,18 +196,18 @@ Shadow byte legend (one shadow byte represents 8 application bytes): # ControlFlowIntegrity -The LLVM Control Flow Integrity (CFI) support in the Rust compiler initially -provides forward-edge control flow protection for Rust-compiled code only by -aggregating function pointers in groups identified by their return and parameter -types. - -Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed -binaries" (i.e., for when C or C++ and Rust -compiled code share the same -virtual address space) will be provided in later work by defining and using -compatible type identifiers (see Type metadata in the design document in the -tracking issue [#89653](https://github.com/rust-lang/rust/issues/89653)). - -LLVM CFI can be enabled with -Zsanitizer=cfi and requires LTO (i.e., -Clto). +The LLVM Control Flow Integrity (CFI) support in the Rust compiler provides +forward-edge control flow protection for both Rust-compiled code only and for C +or C++ and Rust -compiled code mixed-language binaries, also known as “mixed +binaries” (i.e., for when C or C++ and Rust -compiled code share the same +virtual address space), by aggregating function pointers in groups identified by +their return and parameter types. + +LLVM CFI can be enabled with `-Zsanitizer=cfi` and requires LTO (i.e., `-Clto`). +Cross-language LLVM CFI can be enabled with `-Zsanitizer=cfi`, and requires the +`-Zsanitizer-cfi-normalize-integers` option to be used with Clang +`-fsanitize-cfi-icall-normalize-integers` for normalizing integer types, and +proper (i.e., non-rustc) LTO (i.e., `-Clinker-plugin-lto`). See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details. @@ -343,7 +343,7 @@ $ Fig. 5. Build and execution of the modified example with LLVM CFI disabled. ```shell -$ RUSTFLAGS="-Zsanitizer=cfi -Cembed-bitcode=yes -Clto" cargo run --release +$ RUSTFLAGS="-Cembed-bitcode=yes -Clto -Zsanitizer=cfi" cargo run --release Compiling rust-cfi-2 v0.1.0 (/home/rcvalle/rust-cfi-2) Finished release [optimized] target(s) in 3.38s Running `target/release/rust-cfi-2` @@ -392,7 +392,7 @@ Closures][rust-book-ch19-05] chapter of the [The Rust Programming Language][rust-book] book. ```shell - cargo run --release +$ cargo run --release Compiling rust-cfi-3 v0.1.0 (/home/rcvalle/rust-cfi-3) Finished release [optimized] target(s) in 0.74s Running `target/release/rust-cfi-3` @@ -404,7 +404,7 @@ $ Fig. 8. Build and execution of the modified example with LLVM CFI disabled. ```shell -$ RUSTFLAGS="-Zsanitizer=cfi -Cembed-bitcode=yes -Clto" cargo run --release +$ RUSTFLAGS="-Cembed-bitcode=yes -Clto -Zsanitizer=cfi" cargo run --release Compiling rust-cfi-3 v0.1.0 (/home/rcvalle/rust-cfi-3) Finished release [optimized] target(s) in 3.40s Running `target/release/rust-cfi-3` @@ -420,8 +420,92 @@ flow using an indirect branch/call to a function with different return and parameter types than the return type expected and arguments intended/passed in the call/branch site, the execution is also terminated (see Fig. 9). -[rust-book-ch19-05]: ../../book/ch19-05-advanced-functions-and-closures.html -[rust-book]: ../../book/title-page.html +```ignore (cannot-test-this-because-uses-custom-build) +int +do_twice(int (*fn)(int), int arg) { + return fn(arg) + fn(arg); +} +``` +Fig. 10. Example C library. + +```ignore (cannot-test-this-because-uses-custom-build) +use std::mem; + +#[link(name = "foo")] +extern "C" { + fn do_twice(f: unsafe extern "C" fn(i32) -> i32, arg: i32) -> i32; +} + +unsafe extern "C" fn add_one(x: i32) -> i32 { + x + 1 +} + +unsafe extern "C" fn add_two(x: i64) -> i64 { + x + 2 +} + +fn main() { + let answer = unsafe { do_twice(add_one, 5) }; + + println!("The answer is: {}", answer); + + println!("With CFI enabled, you should not see the next answer"); + let f: unsafe extern "C" fn(i32) -> i32 = unsafe { + mem::transmute::<*const u8, unsafe extern "C" fn(i32) -> i32>(add_two as *const u8) + }; + let next_answer = unsafe { do_twice(f, 5) }; + + println!("The next answer is: {}", next_answer); +} +``` +Fig. 11. Another modified example from the [Advanced Functions and +Closures][rust-book-ch19-05] chapter of the [The Rust Programming +Language][rust-book] book. + +```shell +$ make +mkdir -p target/debug +clang -I. -Isrc -Wall -flto -fvisibility=hidden -c -emit-llvm src/foo.c -o target/debug/libfoo.bc +llvm-ar rcs target/debug/libfoo.a target/debug/libfoo.bc +RUSTFLAGS="-L./target/debug -Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld" cargo build + Compiling main v0.1.0 (/home/rcvalle/rust-cross-cfi-1) + Finished dev [unoptimized + debuginfo] target(s) in 0.45s +$ ./target/debug/main +The answer is: 12 +With CFI enabled, you should not see the next answer +The next answer is: 14 +$ +``` +Fig. 12. Build and execution of the modified example with LLVM CFI disabled. + +```shell +$ make +mkdir -p target/debug +clang -I. -Isrc -Wall -flto -fvisibility=hidden -fsanitize=cfi -fsanitize-cfi-icall-normalize-integers -c -emit-llvm src/foo.c -o target/debug/libfoo.bc +llvm-ar rcs target/debug/libfoo.a target/debug/libfoo.bc +RUSTFLAGS="-L./target/debug -Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers" cargo build + Compiling main v0.1.0 (/home/rcvalle/rust-cross-cfi-1) + Finished dev [unoptimized + debuginfo] target(s) in 0.45s +$ ./target/debug/main +The answer is: 12 +With CFI enabled, you should not see the next answer +Illegal instruction +$ +``` +Fig. 13. Build and execution of the modified example with LLVM CFI enabled. + +When LLVM CFI is enabled, if there are any attempts to change/hijack control +flow using an indirect branch/call to a function with different return and +parameter types than the return type expected and arguments intended/passed in +the call/branch site, even across the FFI boundary and for extern "C" function +types indirectly called (i.e., callbacks/function pointers) across the FFI +boundary, in C or C++ and Rust -compiled code mixed-language binaries, also +known as “mixed binaries” (i.e., for when C or C++ and Rust -compiled code share +the same virtual address space), the execution is also terminated (see Fig. 13). + + +[rust-book-ch19-05]: https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html +[rust-book]: https://doc.rust-lang.org/book/title-page.html # HWAddressSanitizer diff --git a/src/doc/unstable-book/src/language-features/cfi-encoding.md b/src/doc/unstable-book/src/language-features/cfi-encoding.md new file mode 100644 index 00000000000..f2f74cc17b3 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/cfi-encoding.md @@ -0,0 +1,25 @@ +# `cfi_encoding` + +The tracking issue for this feature is: [#89653] + +[#89653]: https://github.com/rust-lang/rust/issues/89653 + +------------------------ + +The `cfi_encoding` feature allows the user to define a CFI encoding for a type. +It allows the user to use a different names for types that otherwise would be +required to have the same name as used in externally defined C functions. + +## Examples + +```rust +#![feature(cfi_encoding, extern_types)] + +#[cfi_encoding = "3Foo"] +pub struct Type1(i32); + +extern { + #[cfi_encoding = "3Bar"] + type Type2; +} +``` diff --git a/src/doc/unstable-book/src/language-features/debugger-visualizer.md b/src/doc/unstable-book/src/language-features/debugger-visualizer.md deleted file mode 100644 index c7a0414b676..00000000000 --- a/src/doc/unstable-book/src/language-features/debugger-visualizer.md +++ /dev/null @@ -1,27 +0,0 @@ -# `debugger_visualizer` - -The tracking issue for this feature is: [#95939] - -[#95939]: https://github.com/rust-lang/rust/issues/95939 - ------------------------- - -The `debugger_visualizer` attribute can be used to instruct the compiler -to embed a debugger visualizer file into the PDB/ELF generated by `rustc`. - -## Examples - -``` rust,ignore (partial-example) -#![feature(debugger_visualizer)] -#![debugger_visualizer(natvis_file = "foo.natvis")] -#![debugger_visualizer(gdb_script_file = "foo.py")] -struct Foo { - -} -``` - -## Limitations - -Currently, this feature only supports embedding Natvis files on `-windows-msvc` -targets via the `natvis_file` meta item. `-windows-gnu` targets are not currently -supported. diff --git a/src/doc/unstable-book/src/language-features/raw-dylib.md b/src/doc/unstable-book/src/language-features/raw-dylib.md deleted file mode 100644 index 5fd208ae757..00000000000 --- a/src/doc/unstable-book/src/language-features/raw-dylib.md +++ /dev/null @@ -1,34 +0,0 @@ -# `raw_dylib` - -The tracking issue for this feature is: [#58713] - -[#58713]: https://github.com/rust-lang/rust/issues/58713 - ------------------------- - -The `raw_dylib` feature allows you to link against the implementations of functions in an `extern` -block without, on Windows, linking against an import library. - -```rust,ignore (partial-example) -#![feature(raw_dylib)] - -#[link(name="library", kind="raw-dylib")] -extern { - fn extern_function(x: i32); -} - -fn main() { - unsafe { - extern_function(14); - } -} -``` - -## Limitations - -This feature is unstable for the `x86` architecture, and stable for all other architectures. - -This feature is only supported on Windows. - -On the `x86` architecture, this feature supports only the `cdecl`, `stdcall`, `system`, `fastcall`, and -`vectorcall` calling conventions. diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 1b622905e1a..fb32b6ef1d3 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -44,7 +44,7 @@ where discard_positive_impl: bool, ) -> Option<Item> { let tcx = self.cx.tcx; - let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, [ty])); + let trait_ref = ty::Binder::dummy(ty::TraitRef::new(tcx, trait_def_id, [ty])); if !self.cx.generated_synthetics.insert((ty, trait_def_id)) { debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref); return None; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3f6a5d6d901..951f54e9366 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -152,8 +152,9 @@ pub(crate) fn try_inline_glob( // reexported by the glob, e.g. because they are shadowed by something else. let reexports = cx .tcx - .module_children_reexports(current_mod) + .module_children_local(current_mod) .iter() + .filter(|child| !child.reexport_chain.is_empty()) .filter_map(|child| child.res.opt_def_id()) .collect(); let mut items = build_module_items(cx, did, visited, inlined_names, Some(&reexports)); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1531e7fc7b9..23449a25c3a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -131,7 +131,7 @@ fn clean_generic_bound<'tcx>( hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { let def_id = cx.tcx.require_lang_item(lang_item, Some(span)); - let trait_ref = ty::TraitRef::identity(cx.tcx, def_id); + let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(cx.tcx, def_id)); let generic_args = clean_generic_args(generic_args, cx); let GenericArgs::AngleBracketed { bindings, .. } = generic_args @@ -2089,9 +2089,9 @@ pub(crate) fn reexport_chain<'tcx>( import_def_id: LocalDefId, target_def_id: LocalDefId, ) -> &'tcx [Reexport] { - for child in tcx.module_children_reexports(tcx.local_parent(import_def_id)) { + for child in tcx.module_children_local(tcx.local_parent(import_def_id)) { if child.res.opt_def_id() == Some(target_def_id.to_def_id()) - && child.reexport_chain[0].id() == Some(import_def_id.to_def_id()) + && child.reexport_chain.first().and_then(|r| r.id()) == Some(import_def_id.to_def_id()) { return &child.reexport_chain; } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index b579e7f5ae9..dfa4b091b01 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -382,7 +382,7 @@ impl Options { match kind.parse() { Ok(kind) => emit.push(kind), Err(()) => { - diag.err(&format!("unrecognized emission type: {}", kind)); + diag.err(format!("unrecognized emission type: {}", kind)); return Err(1); } } @@ -559,28 +559,28 @@ impl Options { matches.opt_strs("theme").iter().map(|s| (PathBuf::from(&s), s.to_owned())) { if !theme_file.is_file() { - diag.struct_err(&format!("invalid argument: \"{}\"", theme_s)) + diag.struct_err(format!("invalid argument: \"{}\"", theme_s)) .help("arguments to --theme must be files") .emit(); return Err(1); } if theme_file.extension() != Some(OsStr::new("css")) { - diag.struct_err(&format!("invalid argument: \"{}\"", theme_s)) + diag.struct_err(format!("invalid argument: \"{}\"", theme_s)) .help("arguments to --theme must have a .css extension") .emit(); return Err(1); } let (success, ret) = theme::test_theme_against(&theme_file, &paths, &diag); if !success { - diag.struct_err(&format!("error loading theme file: \"{}\"", theme_s)).emit(); + diag.struct_err(format!("error loading theme file: \"{}\"", theme_s)).emit(); return Err(1); } else if !ret.is_empty() { - diag.struct_warn(&format!( + diag.struct_warn(format!( "theme file \"{}\" is missing CSS rules from the default theme", theme_s )) .warn("the theme may appear incorrect when loaded") - .help(&format!( + .help(format!( "to see what rules are missing, call `rustdoc --check-theme \"{}\"`", theme_s )) @@ -611,7 +611,7 @@ impl Options { match matches.opt_str("r").as_deref() { Some("rust") | None => {} Some(s) => { - diag.struct_err(&format!("unknown input format: {}", s)).emit(); + diag.struct_err(format!("unknown input format: {}", s)).emit(); return Err(1); } } @@ -631,7 +631,7 @@ impl Options { let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) { Ok(types) => types, Err(e) => { - diag.struct_err(&format!("unknown crate type: {}", e)).emit(); + diag.struct_err(format!("unknown crate type: {}", e)).emit(); return Err(1); } }; @@ -649,7 +649,7 @@ impl Options { out_fmt } Err(e) => { - diag.struct_err(&e).emit(); + diag.struct_err(e).emit(); return Err(1); } }, @@ -790,7 +790,7 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han for &flag in deprecated_flags.iter() { if matches.opt_present(flag) { - diag.struct_warn(&format!("the `{}` flag is deprecated", flag)) + diag.struct_warn(format!("the `{}` flag is deprecated", flag)) .note( "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \ for more information", @@ -803,7 +803,7 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han for &flag in removed_flags.iter() { if matches.opt_present(flag) { - let mut err = diag.struct_warn(&format!("the `{}` flag no longer functions", flag)); + let mut err = diag.struct_warn(format!("the `{}` flag no longer functions", flag)); err.note( "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \ for more information", diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 3a0c2ab0297..a6be132337e 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -383,7 +383,7 @@ pub(crate) fn run_global_ctxt( fn report_deprecated_attr(name: &str, diag: &rustc_errors::Handler, sp: Span) { let mut msg = - diag.struct_span_warn(sp, &format!("the `#![doc({})]` attribute is deprecated", name)); + diag.struct_span_warn(sp, format!("the `#![doc({})]` attribute is deprecated", name)); msg.note( "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \ for more information", diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 37fd909c933..88049c4ca00 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -83,14 +83,14 @@ pub(crate) fn load_string<P: AsRef<Path>>( let contents = match fs::read(file_path) { Ok(bytes) => bytes, Err(e) => { - diag.struct_err(&format!("error reading `{}`: {}", file_path.display(), e)).emit(); + diag.struct_err(format!("error reading `{}`: {}", file_path.display(), e)).emit(); return Err(LoadStringError::ReadFail); } }; match str::from_utf8(&contents) { Ok(s) => Ok(s.to_string()), Err(_) => { - diag.struct_err(&format!("error reading `{}`: not UTF-8", file_path.display())).emit(); + diag.struct_err(format!("error reading `{}`: not UTF-8", file_path.display())).emit(); Err(LoadStringError::BadUtf8) } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1b445b8981e..1c6810bdaf9 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -167,7 +167,7 @@ pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( display_fn(move |f| { let mut bounds_dup = FxHashSet::default(); - for (i, bound) in bounds.iter().filter(|b| bounds_dup.insert(b.clone())).enumerate() { + for (i, bound) in bounds.iter().filter(|b| bounds_dup.insert(*b)).enumerate() { if i > 0 { f.write_str(" + ")?; } @@ -439,6 +439,7 @@ impl clean::GenericBound { let modifier_str = match modifier { hir::TraitBoundModifier::None => "", hir::TraitBoundModifier::Maybe => "?", + hir::TraitBoundModifier::Negative => "!", // ~const is experimental; do not display those bounds in rustdoc hir::TraitBoundModifier::MaybeConst => "", }; diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 946c85a205f..c94968b4817 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -811,7 +811,9 @@ impl<'src> Classifier<'src> { | LiteralKind::Str { .. } | LiteralKind::ByteStr { .. } | LiteralKind::RawStr { .. } - | LiteralKind::RawByteStr { .. } => Class::String, + | LiteralKind::RawByteStr { .. } + | LiteralKind::CStr { .. } + | LiteralKind::RawCStr { .. } => Class::String, // Number literals. LiteralKind::Float { .. } | LiteralKind::Int { .. } => Class::Number, }, diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index a063c8c9f02..01a92f6df6a 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -746,7 +746,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { // Flush pending errors. Rc::get_mut(&mut self.shared).unwrap().fs.close(); let nb_errors = - self.shared.errors.iter().map(|err| self.tcx().sess.struct_err(&err).emit()).count(); + self.shared.errors.iter().map(|err| self.tcx().sess.struct_err(err).emit()).count(); if nb_errors > 0 { Err(Error::new(io::Error::new(io::ErrorKind::Other, "I/O error"), "")) } else { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 73bf27c9d34..e09c6480060 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2256,8 +2256,7 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c Ok(contents) => contents, Err(err) => { let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner()); - tcx.sess - .span_err(span, &format!("failed to read file {}: {}", path.display(), err)); + tcx.sess.span_err(span, format!("failed to read file {}: {}", path.display(), err)); return false; } }; diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index f5b4a3f5abd..a3be6dd5269 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -391,12 +391,14 @@ fn get_index_type_id(clean_type: &clean::Type) -> Option<RenderTypeId> { clean::BorrowedRef { ref type_, .. } | clean::RawPointer(_, ref type_) => { get_index_type_id(type_) } + // The type parameters are converted to generics in `add_generics_and_bounds_as_types` + clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)), + clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)), + // Not supported yet clean::BareFunction(_) | clean::Generic(_) | clean::ImplTrait(_) | clean::Tuple(_) - | clean::Slice(_) - | clean::Array(_, _) | clean::QPath { .. } | clean::Infer => None, } @@ -563,6 +565,30 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>( } } insert_ty(res, arg.clone(), ty_generics); + } else if let Type::Slice(ref ty) = *arg { + let mut ty_generics = Vec::new(); + add_generics_and_bounds_as_types( + self_, + generics, + &ty, + tcx, + recurse + 1, + &mut ty_generics, + cache, + ); + insert_ty(res, arg.clone(), ty_generics); + } else if let Type::Array(ref ty, _) = *arg { + let mut ty_generics = Vec::new(); + add_generics_and_bounds_as_types( + self_, + generics, + &ty, + tcx, + recurse + 1, + &mut ty_generics, + cache, + ); + insert_ty(res, arg.clone(), ty_generics); } else { // This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're // looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't. diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index c8397967c87..a26fa374912 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -145,7 +145,7 @@ impl DocVisitor for SourceCollector<'_, '_> { Err(e) => { self.cx.shared.tcx.sess.span_err( span, - &format!( + format!( "failed to render source code for `{}`: {}", filename.prefer_local(), e, diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 6fbb4508662..a7d5f497756 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1259,6 +1259,10 @@ a.tooltip:hover::after { background-color: var(--search-error-code-background-color); } +.search-corrections { + font-weight: normal; +} + #src-sidebar-toggle { position: sticky; top: 0; diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js index 4c81a0979c1..8b931f74e60 100644 --- a/src/librustdoc/html/static/js/externs.js +++ b/src/librustdoc/html/static/js/externs.js @@ -9,6 +9,7 @@ function initSearch(searchIndex){} /** * @typedef {{ * name: string, + * id: integer, * fullPath: Array<string>, * pathWithoutLast: Array<string>, * pathLast: string, @@ -36,6 +37,8 @@ let ParserState; * args: Array<QueryElement>, * returned: Array<QueryElement>, * foundElems: number, + * literalSearch: boolean, + * corrections: Array<{from: string, to: integer}>, * }} */ let ParsedQuery; @@ -139,7 +142,7 @@ let FunctionSearchType; /** * @typedef {{ - * name: (null|string), + * id: (null|number), * ty: (null|number), * generics: Array<FunctionType>, * }} diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 3dc4f2149b8..62afe40bb31 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -58,6 +58,7 @@ function printTab(nb) { } iter += 1; }); + const isTypeSearch = (nb > 0 || iter === 1); iter = 0; onEachLazy(document.getElementById("results").childNodes, elem => { if (nb === iter) { @@ -70,6 +71,13 @@ function printTab(nb) { }); if (foundCurrentTab && foundCurrentResultSet) { searchState.currentTab = nb; + // Corrections only kick in on type-based searches. + const correctionsElem = document.getElementsByClassName("search-corrections"); + if (isTypeSearch) { + removeClass(correctionsElem[0], "hidden"); + } else { + addClass(correctionsElem[0], "hidden"); + } } else if (nb !== 0) { printTab(0); } @@ -191,6 +199,13 @@ function initSearch(rawSearchIndex) { */ let searchIndex; let currentResults; + /** + * Map from normalized type names to integers. Used to make type search + * more efficient. + * + * @type {Map<string, integer>} + */ + let typeNameIdMap; const ALIASES = new Map(); function isWhitespace(c) { @@ -358,6 +373,7 @@ function initSearch(rawSearchIndex) { parserState.typeFilter = null; return { name: name, + id: -1, fullPath: pathSegments, pathWithoutLast: pathSegments.slice(0, pathSegments.length - 1), pathLast: pathSegments[pathSegments.length - 1], @@ -718,6 +734,7 @@ function initSearch(rawSearchIndex) { foundElems: 0, literalSearch: false, error: null, + correction: null, }; } @@ -873,7 +890,7 @@ function initSearch(rawSearchIndex) { * * @param {Array<Result>} results_in_args * @param {Array<Result>} results_returned - * @param {Array<Result>} results_in_args + * @param {Array<Result>} results_others * @param {ParsedQuery} parsedQuery * * @return {ResultsTable} @@ -1091,48 +1108,50 @@ function initSearch(rawSearchIndex) { * * @param {Row} row - The object to check. * @param {QueryElement} elem - The element from the parsed query. - * @param {integer} defaultDistance - This is the value to return in case there are no - * generics. * - * @return {integer} - Returns the best match (if any) or `maxEditDistance + 1`. + * @return {boolean} - Returns true if a match, false otherwise. */ - function checkGenerics(row, elem, defaultDistance, maxEditDistance) { - if (row.generics.length === 0) { - return elem.generics.length === 0 ? defaultDistance : maxEditDistance + 1; - } else if (row.generics.length > 0 && row.generics[0].name === null) { - return checkGenerics(row.generics[0], elem, defaultDistance, maxEditDistance); - } - // The names match, but we need to be sure that all generics kinda - // match as well. + function checkGenerics(row, elem) { + if (row.generics.length === 0 || elem.generics.length === 0) { + return false; + } + // This function is called if the names match, but we need to make + // sure that all generics match as well. + // + // This search engine implements order-agnostic unification. There + // should be no missing duplicates (generics have "bag semantics"), + // and the row is allowed to have extras. if (elem.generics.length > 0 && row.generics.length >= elem.generics.length) { const elems = new Map(); - for (const entry of row.generics) { - if (entry.name === "") { + const addEntryToElems = function addEntryToElems(entry) { + if (entry.id === -1) { // Pure generic, needs to check into it. - if (checkGenerics(entry, elem, maxEditDistance + 1, maxEditDistance) - !== 0) { - return maxEditDistance + 1; + for (const inner_entry of entry.generics) { + addEntryToElems(inner_entry); } - continue; + return; } let currentEntryElems; - if (elems.has(entry.name)) { - currentEntryElems = elems.get(entry.name); + if (elems.has(entry.id)) { + currentEntryElems = elems.get(entry.id); } else { currentEntryElems = []; - elems.set(entry.name, currentEntryElems); + elems.set(entry.id, currentEntryElems); } currentEntryElems.push(entry); + }; + for (const entry of row.generics) { + addEntryToElems(entry); } // We need to find the type that matches the most to remove it in order // to move forward. const handleGeneric = generic => { - if (!elems.has(generic.name)) { + if (!elems.has(generic.id)) { return false; } - const matchElems = elems.get(generic.name); + const matchElems = elems.get(generic.id); const matchIdx = matchElems.findIndex(tmp_elem => { - if (checkGenerics(tmp_elem, generic, 0, maxEditDistance) !== 0) { + if (generic.generics.length > 0 && !checkGenerics(tmp_elem, generic)) { return false; } return typePassesFilter(generic.typeFilter, tmp_elem.ty); @@ -1142,7 +1161,7 @@ function initSearch(rawSearchIndex) { } matchElems.splice(matchIdx, 1); if (matchElems.length === 0) { - elems.delete(generic.name); + elems.delete(generic.id); } return true; }; @@ -1152,17 +1171,17 @@ function initSearch(rawSearchIndex) { // own type. for (const generic of elem.generics) { if (generic.typeFilter !== -1 && !handleGeneric(generic)) { - return maxEditDistance + 1; + return false; } } for (const generic of elem.generics) { if (generic.typeFilter === -1 && !handleGeneric(generic)) { - return maxEditDistance + 1; + return false; } } - return 0; + return true; } - return maxEditDistance + 1; + return false; } /** @@ -1172,17 +1191,15 @@ function initSearch(rawSearchIndex) { * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. * - * @return {integer} - Returns an edit distance to the best match. + * @return {boolean} - Returns true if found, false otherwise. */ - function checkIfInGenerics(row, elem, maxEditDistance) { - let dist = maxEditDistance + 1; + function checkIfInGenerics(row, elem) { for (const entry of row.generics) { - dist = Math.min(checkType(entry, elem, true, maxEditDistance), dist); - if (dist === 0) { - break; + if (checkType(entry, elem)) { + return true; } } - return dist; + return false; } /** @@ -1191,75 +1208,26 @@ function initSearch(rawSearchIndex) { * * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. - * @param {boolean} literalSearch * - * @return {integer} - Returns an edit distance to the best match. If there is - * no match, returns `maxEditDistance + 1`. + * @return {boolean} - Returns true if the type matches, false otherwise. */ - function checkType(row, elem, literalSearch, maxEditDistance) { - if (row.name === null) { + function checkType(row, elem) { + if (row.id === -1) { // This is a pure "generic" search, no need to run other checks. - if (row.generics.length > 0) { - return checkIfInGenerics(row, elem, maxEditDistance); - } - return maxEditDistance + 1; + return row.generics.length > 0 ? checkIfInGenerics(row, elem) : false; } - let dist; - if (typePassesFilter(elem.typeFilter, row.ty)) { - dist = editDistance(row.name, elem.name, maxEditDistance); - } else { - dist = maxEditDistance + 1; - } - if (literalSearch) { - if (dist !== 0) { - // The name didn't match, let's try to check if the generics do. - if (elem.generics.length === 0) { - const checkGeneric = row.generics.length > 0; - if (checkGeneric && row.generics - .findIndex(tmp_elem => tmp_elem.name === elem.name && - typePassesFilter(elem.typeFilter, tmp_elem.ty)) !== -1) { - return 0; - } - } - return maxEditDistance + 1; - } else if (elem.generics.length > 0) { - return checkGenerics(row, elem, maxEditDistance + 1, maxEditDistance); - } - return 0; - } else if (row.generics.length > 0) { - if (elem.generics.length === 0) { - if (dist === 0) { - return 0; - } - // The name didn't match so we now check if the type we're looking for is inside - // the generics! - dist = Math.min(dist, checkIfInGenerics(row, elem, maxEditDistance)); - return dist; - } else if (dist > maxEditDistance) { - // So our item's name doesn't match at all and has generics. - // - // Maybe it's present in a sub generic? For example "f<A<B<C>>>()", if we're - // looking for "B<C>", we'll need to go down. - return checkIfInGenerics(row, elem, maxEditDistance); - } else { - // At this point, the name kinda match and we have generics to check, so - // let's go! - const tmp_dist = checkGenerics(row, elem, dist, maxEditDistance); - if (tmp_dist > maxEditDistance) { - return maxEditDistance + 1; - } - // We compute the median value of both checks and return it. - return (tmp_dist + dist) / 2; + if (row.id === elem.id && typePassesFilter(elem.typeFilter, row.ty)) { + if (elem.generics.length > 0) { + return checkGenerics(row, elem); } - } else if (elem.generics.length > 0) { - // In this case, we were expecting generics but there isn't so we simply reject this - // one. - return maxEditDistance + 1; + return true; } - // No generics on our query or on the target type so we can return without doing - // anything else. - return dist; + + // If the current item does not match, try [unboxing] the generic. + // [unboxing]: + // https://ndmitchell.com/downloads/slides-hoogle_fast_type_searching-09_aug_2008.pdf + return checkIfInGenerics(row, elem); } /** @@ -1267,17 +1235,11 @@ function initSearch(rawSearchIndex) { * * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. - * @param {integer} maxEditDistance * @param {Array<integer>} skipPositions - Do not return one of these positions. * - * @return {dist: integer, position: integer} - Returns an edit distance to the best match. - * If there is no match, returns - * `maxEditDistance + 1` and position: -1. + * @return {integer} - Returns the position of the match, or -1 if none. */ - function findArg(row, elem, maxEditDistance, skipPositions) { - let dist = maxEditDistance + 1; - let position = -1; - + function findArg(row, elem, skipPositions) { if (row && row.type && row.type.inputs && row.type.inputs.length > 0) { let i = 0; for (const input of row.type.inputs) { @@ -1285,24 +1247,13 @@ function initSearch(rawSearchIndex) { i += 1; continue; } - const typeDist = checkType( - input, - elem, - parsedQuery.literalSearch, - maxEditDistance - ); - if (typeDist === 0) { - return {dist: 0, position: i}; - } - if (typeDist < dist) { - dist = typeDist; - position = i; + if (checkType(input, elem)) { + return i; } i += 1; } } - dist = parsedQuery.literalSearch ? maxEditDistance + 1 : dist; - return {dist, position}; + return -1; } /** @@ -1310,43 +1261,25 @@ function initSearch(rawSearchIndex) { * * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. - * @param {integer} maxEditDistance * @param {Array<integer>} skipPositions - Do not return one of these positions. * - * @return {dist: integer, position: integer} - Returns an edit distance to the best match. - * If there is no match, returns - * `maxEditDistance + 1` and position: -1. + * @return {integer} - Returns the position of the matching item, or -1 if none. */ - function checkReturned(row, elem, maxEditDistance, skipPositions) { - let dist = maxEditDistance + 1; - let position = -1; - + function checkReturned(row, elem, skipPositions) { if (row && row.type && row.type.output.length > 0) { - const ret = row.type.output; let i = 0; - for (const ret_ty of ret) { + for (const ret_ty of row.type.output) { if (skipPositions.indexOf(i) !== -1) { i += 1; continue; } - const typeDist = checkType( - ret_ty, - elem, - parsedQuery.literalSearch, - maxEditDistance - ); - if (typeDist === 0) { - return {dist: 0, position: i}; - } - if (typeDist < dist) { - dist = typeDist; - position = i; + if (checkType(ret_ty, elem)) { + return i; } i += 1; } } - dist = parsedQuery.literalSearch ? maxEditDistance + 1 : dist; - return {dist, position}; + return -1; } function checkPath(contains, ty, maxEditDistance) { @@ -1543,17 +1476,20 @@ function initSearch(rawSearchIndex) { if (!row || (filterCrates !== null && row.crate !== filterCrates)) { return; } - let dist, index = -1, path_dist = 0; + let index = -1, path_dist = 0; const fullId = row.id; const searchWord = searchWords[pos]; - const in_args = findArg(row, elem, maxEditDistance, []); - const returned = checkReturned(row, elem, maxEditDistance, []); - - // path_dist is 0 because no parent path information is currently stored - // in the search index - addIntoResults(results_in_args, fullId, pos, -1, in_args.dist, 0, maxEditDistance); - addIntoResults(results_returned, fullId, pos, -1, returned.dist, 0, maxEditDistance); + const in_args = findArg(row, elem, []); + if (in_args !== -1) { + // path_dist is 0 because no parent path information is currently stored + // in the search index + addIntoResults(results_in_args, fullId, pos, -1, 0, 0, maxEditDistance); + } + const returned = checkReturned(row, elem, []); + if (returned !== -1) { + addIntoResults(results_returned, fullId, pos, -1, 0, 0, maxEditDistance); + } if (!typePassesFilter(elem.typeFilter, row.ty)) { return; @@ -1574,16 +1510,6 @@ function initSearch(rawSearchIndex) { index = row_index; } - // No need to check anything else if it's a "pure" generics search. - if (elem.name.length === 0) { - if (row.type !== null) { - dist = checkGenerics(row.type, elem, maxEditDistance + 1, maxEditDistance); - // path_dist is 0 because we know it's empty - addIntoResults(results_others, fullId, pos, index, dist, 0, maxEditDistance); - } - return; - } - if (elem.fullPath.length > 1) { path_dist = checkPath(elem.pathWithoutLast, row, maxEditDistance); if (path_dist > maxEditDistance) { @@ -1598,7 +1524,7 @@ function initSearch(rawSearchIndex) { return; } - dist = editDistance(searchWord, elem.pathLast, maxEditDistance); + const dist = editDistance(searchWord, elem.pathLast, maxEditDistance); if (index === -1 && dist + path_dist > maxEditDistance) { return; @@ -1616,28 +1542,22 @@ function initSearch(rawSearchIndex) { * @param {integer} pos - Position in the `searchIndex`. * @param {Object} results */ - function handleArgs(row, pos, results, maxEditDistance) { + function handleArgs(row, pos, results) { if (!row || (filterCrates !== null && row.crate !== filterCrates)) { return; } - let totalDist = 0; - let nbDist = 0; - // If the result is too "bad", we return false and it ends this search. function checkArgs(elems, callback) { const skipPositions = []; for (const elem of elems) { // There is more than one parameter to the query so all checks should be "exact" - const { dist, position } = callback( + const position = callback( row, elem, - maxEditDistance, skipPositions ); - if (dist <= 1) { - nbDist += 1; - totalDist += dist; + if (position !== -1) { skipPositions.push(position); } else { return false; @@ -1652,11 +1572,7 @@ function initSearch(rawSearchIndex) { return; } - if (nbDist === 0) { - return; - } - const dist = Math.round(totalDist / nbDist); - addIntoResults(results, row.id, pos, 0, dist, 0, maxEditDistance); + addIntoResults(results, row.id, pos, 0, 0, 0, Number.MAX_VALUE); } function innerRunQuery() { @@ -1671,6 +1587,53 @@ function initSearch(rawSearchIndex) { } const maxEditDistance = Math.floor(queryLen / 3); + /** + * Convert names to ids in parsed query elements. + * This is not used for the "In Names" tab, but is used for the + * "In Params", "In Returns", and "In Function Signature" tabs. + * + * If there is no matching item, but a close-enough match, this + * function also that correction. + * + * See `buildTypeMapIndex` for more information. + * + * @param {QueryElement} elem + */ + function convertNameToId(elem) { + if (typeNameIdMap.has(elem.name)) { + elem.id = typeNameIdMap.get(elem.name); + } else if (!parsedQuery.literalSearch) { + let match = -1; + let matchDist = maxEditDistance + 1; + let matchName = ""; + for (const [name, id] of typeNameIdMap) { + const dist = editDistance(name, elem.name, maxEditDistance); + if (dist <= matchDist && dist <= maxEditDistance) { + if (dist === matchDist && matchName > name) { + continue; + } + match = id; + matchDist = dist; + matchName = name; + } + } + if (match !== -1) { + parsedQuery.correction = matchName; + } + elem.id = match; + } + for (const elem2 of elem.generics) { + convertNameToId(elem2); + } + } + + for (const elem of parsedQuery.elems) { + convertNameToId(elem); + } + for (const elem of parsedQuery.returned) { + convertNameToId(elem); + } + if (parsedQuery.foundElems === 1) { if (parsedQuery.elems.length === 1) { elem = parsedQuery.elems[0]; @@ -1695,22 +1658,23 @@ function initSearch(rawSearchIndex) { in_returned = checkReturned( row, elem, - maxEditDistance, [] ); - addIntoResults( - results_others, - row.id, - i, - -1, - in_returned.dist, - maxEditDistance - ); + if (in_returned !== -1) { + addIntoResults( + results_others, + row.id, + i, + -1, + 0, + Number.MAX_VALUE + ); + } } } } else if (parsedQuery.foundElems > 0) { for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { - handleArgs(searchIndex[i], i, results_others, maxEditDistance); + handleArgs(searchIndex[i], i, results_others); } } } @@ -2030,6 +1994,16 @@ function initSearch(rawSearchIndex) { currentTab = 0; } + if (results.query.correction !== null) { + const orig = results.query.returned.length > 0 + ? results.query.returned[0].name + : results.query.elems[0].name; + output += "<h3 class=\"search-corrections\">" + + `Type "${orig}" not found. ` + + "Showing results for closest type name " + + `"${results.query.correction}" instead.</h3>`; + } + const resultsElem = document.createElement("div"); resultsElem.id = "results"; resultsElem.appendChild(ret_others[0]); @@ -2109,6 +2083,34 @@ function initSearch(rawSearchIndex) { } /** + * Add an item to the type Name->ID map, or, if one already exists, use it. + * Returns the number. If name is "" or null, return -1 (pure generic). + * + * This is effectively string interning, so that function matching can be + * done more quickly. Two types with the same name but different item kinds + * get the same ID. + * + * @param {Map<string, integer>} typeNameIdMap + * @param {string} name + * + * @returns {integer} + */ + function buildTypeMapIndex(typeNameIdMap, name) { + + if (name === "" || name === null) { + return -1; + } + + if (typeNameIdMap.has(name)) { + return typeNameIdMap.get(name); + } else { + const id = typeNameIdMap.size; + typeNameIdMap.set(name, id); + return id; + } + } + + /** * Convert a list of RawFunctionType / ID to object-based FunctionType. * * Crates often have lots of functions in them, and it's common to have a large number of @@ -2126,7 +2128,7 @@ function initSearch(rawSearchIndex) { * * @return {Array<FunctionSearchType>} */ - function buildItemSearchTypeAll(types, lowercasePaths) { + function buildItemSearchTypeAll(types, lowercasePaths, typeNameIdMap) { const PATH_INDEX_DATA = 0; const GENERICS_DATA = 1; return types.map(type => { @@ -2136,11 +2138,17 @@ function initSearch(rawSearchIndex) { generics = []; } else { pathIndex = type[PATH_INDEX_DATA]; - generics = buildItemSearchTypeAll(type[GENERICS_DATA], lowercasePaths); + generics = buildItemSearchTypeAll( + type[GENERICS_DATA], + lowercasePaths, + typeNameIdMap + ); } return { // `0` is used as a sentinel because it's fewer bytes than `null` - name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + id: pathIndex === 0 + ? -1 + : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: generics, }; @@ -2159,10 +2167,11 @@ function initSearch(rawSearchIndex) { * * @param {RawFunctionSearchType} functionSearchType * @param {Array<{name: string, ty: number}>} lowercasePaths + * @param {Map<string, integer>} * * @return {null|FunctionSearchType} */ - function buildFunctionSearchType(functionSearchType, lowercasePaths) { + function buildFunctionSearchType(functionSearchType, lowercasePaths, typeNameIdMap) { const INPUTS_DATA = 0; const OUTPUT_DATA = 1; // `0` is used as a sentinel because it's fewer bytes than `null` @@ -2173,23 +2182,35 @@ function initSearch(rawSearchIndex) { if (typeof functionSearchType[INPUTS_DATA] === "number") { const pathIndex = functionSearchType[INPUTS_DATA]; inputs = [{ - name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + id: pathIndex === 0 + ? -1 + : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: [], }]; } else { - inputs = buildItemSearchTypeAll(functionSearchType[INPUTS_DATA], lowercasePaths); + inputs = buildItemSearchTypeAll( + functionSearchType[INPUTS_DATA], + lowercasePaths, + typeNameIdMap + ); } if (functionSearchType.length > 1) { if (typeof functionSearchType[OUTPUT_DATA] === "number") { const pathIndex = functionSearchType[OUTPUT_DATA]; output = [{ - name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + id: pathIndex === 0 + ? -1 + : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: [], }]; } else { - output = buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA], lowercasePaths); + output = buildItemSearchTypeAll( + functionSearchType[OUTPUT_DATA], + lowercasePaths, + typeNameIdMap + ); } } else { output = []; @@ -2202,9 +2223,12 @@ function initSearch(rawSearchIndex) { function buildIndex(rawSearchIndex) { searchIndex = []; /** + * List of normalized search words (ASCII lowercased, and undescores removed). + * * @type {Array<string>} */ const searchWords = []; + typeNameIdMap = new Map(); const charA = "A".charCodeAt(0); let currentIndex = 0; let id = 0; @@ -2337,7 +2361,11 @@ function initSearch(rawSearchIndex) { path: itemPaths.has(i) ? itemPaths.get(i) : lastPath, desc: itemDescs[i], parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, - type: buildFunctionSearchType(itemFunctionSearchTypes[i], lowercasePaths), + type: buildFunctionSearchType( + itemFunctionSearchTypes[i], + lowercasePaths, + typeNameIdMap + ), id: id, normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""), deprecated: deprecatedItems.has(i), diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html index 58b220c7428..20e09a54805 100644 --- a/src/librustdoc/html/templates/type_layout.html +++ b/src/librustdoc/html/templates/type_layout.html @@ -1,53 +1,58 @@ -<h2 id="layout" class="small-section-header"> {# #} +<h2 id="layout" class="small-section-header"> {# #} Layout<a href="#layout" class="anchor">§</a> {# #} </h2> {# #} <div class="docblock"> {# #} {% match type_layout_size %} - {% when Ok(type_layout_size) %} - <div class="warning"> {# #} - <p> {# #} - <strong>Note:</strong> Most layout information is <strong>completely {#+ #} - unstable</strong> and may even differ between compilations. {#+ #} - The only exception is types with certain <code>repr(...)</code> {#+ #} - attributes. Please see the Rust Reference’s {#+ #} - <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #} - chapter for details on type layout guarantees. {# #} - </p> {# #} - </div> {# #} - <p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #} - {% if !variants.is_empty() %} - <p> {# #} - <strong>Size for each variant:</strong> {# #} - </p> {# #} - <ul> {# #} - {% for (name, layout_size) in variants %} - <li> {# #} - <code>{{ name }}</code>: {#+ #} - {{ layout_size|safe }} - </li> {# #} - {% endfor %} - </ul> {# #} - {% endif %} - {# This kind of layout error can occur with valid code, e.g. if you try to - get the layout of a generic type such as `Vec<T>`. #} + {% when Ok(type_layout_size) %} + <div class="warning"> {# #} + <p> {# #} + <strong>Note:</strong> Most layout information is <strong>completely {#+ #} + unstable</strong> and may even differ between compilations. {#+ #} + The only exception is types with certain <code>repr(...)</code> {#+ #} + attributes. Please see the Rust Reference’s {#+ #} + <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #} + chapter for details on type layout guarantees. {# #} + </p> {# #} + </div> {# #} + <p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #} + {% if !variants.is_empty() %} + <p> {# #} + <strong>Size for each variant:</strong> {# #} + </p> {# #} + <ul> {# #} + {% for (name, layout_size) in variants %} + <li> {# #} + <code>{{ name }}</code>: {#+ #} + {{ layout_size|safe }} + </li> {# #} + {% endfor %} + </ul> {# #} + {% endif %} + {# This kind of layout error can occur with valid code, e.g. if you try to + get the layout of a generic type such as `Vec<T>`. #} {% when Err(LayoutError::Unknown(_)) %} - <p> {# #} - <strong>Note:</strong> Unable to compute type layout, {#+ #} - possibly due to this type having generic parameters. {#+ #} - Layout can only be computed for concrete, fully-instantiated types. {# #} - </p> {# #} + <p> {# #} + <strong>Note:</strong> Unable to compute type layout, {#+ #} + possibly due to this type having generic parameters. {#+ #} + Layout can only be computed for concrete, fully-instantiated types. {# #} + </p> {# #} {# This kind of error probably can't happen with valid code, but we don't - want to panic and prevent the docs from building, so we just let the - user know that we couldn't compute the layout. #} + want to panic and prevent the docs from building, so we just let the + user know that we couldn't compute the layout. #} {% when Err(LayoutError::SizeOverflow(_)) %} - <p> {# #} - <strong>Note:</strong> Encountered an error during type layout; {#+ #} - the type was too big. {# #} - </p> {# #} + <p> {# #} + <strong>Note:</strong> Encountered an error during type layout; {#+ #} + the type was too big. {# #} + </p> {# #} {% when Err(LayoutError::NormalizationFailure(_, _)) %} - <p> {# #} - <strong>Note:</strong> Encountered an error during type layout; {#+ #} - the type failed to be normalized. {# #} - </p> {# #} - {% endmatch %} + <p> {# #} + <strong>Note:</strong> Encountered an error during type layout; {#+ #} + the type failed to be normalized. {# #} + </p> {# #} + {% when Err(LayoutError::Cycle) %} + <p> {# #} + <strong>Note:</strong> Encountered an error during type layout; {#+ #} + the type's layout depended on the type's layout itself. {# #} + </p> {# #} + {% endmatch %} </div> {# #} diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 62aab46fa7e..b5bebb70593 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -533,6 +533,10 @@ pub(crate) fn from_trait_bound_modifier( None => TraitBoundModifier::None, Maybe => TraitBoundModifier::Maybe, MaybeConst => TraitBoundModifier::MaybeConst, + // FIXME(negative-bounds): This bound should be rendered negative, but + // since that's experimental, maybe let's not add it to the rustdoc json + // API just now... + Negative => TraitBoundModifier::None, } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 66080f64b9c..b6eb450d62b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -156,15 +156,19 @@ pub fn main() { } } - rustc_driver::install_ice_hook(); + rustc_driver::install_ice_hook( + "https://github.com/rust-lang/rust/issues/new\ + ?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md", + |_| (), + ); - // When using CI artifacts (with `download_stage1 = true`), tracing is unconditionally built + // When using CI artifacts with `download-rustc`, tracing is unconditionally built // with `--features=static_max_level_info`, which disables almost all rustdoc logging. To avoid // this, compile our own version of `tracing` that logs all levels. // NOTE: this compiles both versions of tracing unconditionally, because // - The compile time hit is not that bad, especially compared to rustdoc's incremental times, and - // - Otherwise, there's no warning that logging is being ignored when `download_stage1 = true`. - // NOTE: The reason this doesn't show double logging when `download_stage1 = false` and + // - Otherwise, there's no warning that logging is being ignored when `download-rustc` is enabled + // NOTE: The reason this doesn't show double logging when `download-rustc = false` and // `debug_logging = true` is because all rustc logging goes to its version of tracing (the one // in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml). init_logging(); @@ -172,7 +176,11 @@ pub fn main() { let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() { Some(args) => main_args(&args), - _ => Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()), + _ => + { + #[allow(deprecated)] + Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + } }); process::exit(exit_code); } @@ -677,7 +685,7 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes match res { Ok(()) => diag.has_errors().map_or(Ok(()), Err), Err(err) => { - let reported = diag.struct_err(&err).emit(); + let reported = diag.struct_err(err).emit(); Err(reported) } } @@ -693,10 +701,10 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( Ok(_) => tcx.sess.has_errors().map_or(Ok(()), Err), Err(e) => { let mut msg = - tcx.sess.struct_err(&format!("couldn't generate documentation: {}", e.error)); + tcx.sess.struct_err(format!("couldn't generate documentation: {}", e.error)); let file = e.file.display().to_string(); if !file.is_empty() { - msg.note(&format!("failed to create or modify \"{}\"", file)); + msg.note(format!("failed to create or modify \"{}\"", file)); } Err(msg.emit()) } @@ -725,6 +733,7 @@ fn main_args(at_args: &[String]) -> MainResult { return if code == 0 { Ok(()) } else { + #[allow(deprecated)] Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) }; } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 7e173a171a8..a885ff0ca5e 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1179,9 +1179,9 @@ impl LinkCollector<'_, '_> { specified.descr(), ); if let Some(sp) = sp { - diag.span_label(sp, ¬e); + diag.span_label(sp, note); } else { - diag.note(¬e); + diag.note(note); } suggest_disambiguator(resolved, diag, path_str, &ori_link.link, sp); }; @@ -1617,7 +1617,7 @@ fn report_diagnostic( let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); // Print the line containing the `link_range` and manually mark it with '^'s. - lint.note(&format!( + lint.note(format!( "the link appears in this line:\n\n{line}\n\ {indicator: <before$}{indicator:^<found$}", line = line, @@ -1730,9 +1730,9 @@ fn resolution_failure( format!("no item named `{}` in scope", unresolved) }; if let Some(span) = sp { - diag.span_label(span, ¬e); + diag.span_label(span, note); } else { - diag.note(¬e); + diag.note(note); } if !path_str.contains("::") { @@ -1787,9 +1787,9 @@ fn resolution_failure( let variant = res.name(tcx); let note = format!("variant `{variant}` has no such field"); if let Some(span) = sp { - diag.span_label(span, ¬e); + diag.span_label(span, note); } else { - diag.note(¬e); + diag.note(note); } return; } @@ -1812,9 +1812,9 @@ fn resolution_failure( | InlineConst => { let note = assoc_item_not_allowed(res); if let Some(span) = sp { - diag.span_label(span, ¬e); + diag.span_label(span, note); } else { - diag.note(¬e); + diag.note(note); } return; } @@ -1834,9 +1834,9 @@ fn resolution_failure( unresolved, ); if let Some(span) = sp { - diag.span_label(span, ¬e); + diag.span_label(span, note); } else { - diag.note(¬e); + diag.note(note); } continue; @@ -1854,9 +1854,9 @@ fn resolution_failure( } }; if let Some(span) = sp { - diag.span_label(span, ¬e); + diag.span_label(span, note); } else { - diag.note(¬e); + diag.note(note); } } }, @@ -1906,7 +1906,7 @@ fn disambiguator_error( "see {}/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators", crate::DOC_RUST_LANG_ORG_CHANNEL ); - diag.note(&msg); + diag.note(msg); }); } @@ -2023,13 +2023,13 @@ fn suggest_disambiguator( if let Some(sp) = sp { let mut spans = suggestion.as_help_span(path_str, ori_link, sp); if spans.len() > 1 { - diag.multipart_suggestion(&help, spans, Applicability::MaybeIncorrect); + diag.multipart_suggestion(help, spans, Applicability::MaybeIncorrect); } else { let (sp, suggestion_text) = spans.pop().unwrap(); - diag.span_suggestion_verbose(sp, &help, suggestion_text, Applicability::MaybeIncorrect); + diag.span_suggestion_verbose(sp, help, suggestion_text, Applicability::MaybeIncorrect); } } else { - diag.help(&format!("{}: {}", help, suggestion.as_help(path_str))); + diag.help(format!("{}: {}", help, suggestion.as_help(path_str))); } } diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 26fbb03a43e..8f873dbe501 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -108,7 +108,7 @@ fn check_rust_syntax( // just give a `help` instead. lint.span_help( sp.from_inner(InnerSpan::new(0, 3)), - &format!("{}: ```text", explanation), + format!("{}: ```text", explanation), ); } else if empty_block { lint.span_suggestion( @@ -119,12 +119,12 @@ fn check_rust_syntax( ); } } else if empty_block || is_ignore { - lint.help(&format!("{}: ```text", explanation)); + lint.help(format!("{}: ```text", explanation)); } // FIXME(#67563): Provide more context for these errors by displaying the spans inline. for message in buffer.messages.iter() { - lint.note(message); + lint.note(message.clone()); } lint diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index dfa99ffcb7c..d2fa7769bbd 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -331,7 +331,7 @@ pub(crate) fn run( }; if let Err(e) = inner() { - tcx.sess.fatal(&e); + tcx.sess.fatal(e); } Ok(()) @@ -358,7 +358,7 @@ pub(crate) fn load_call_locations( }; inner().map_err(|e: String| { - diag.err(&format!("failed to load examples: {}", e)); + diag.err(format!("failed to load examples: {}", e)); 1 }) } diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs index e7a26cb346e..722e01cd1fc 100644 --- a/src/librustdoc/theme.rs +++ b/src/librustdoc/theme.rs @@ -241,7 +241,7 @@ pub(crate) fn test_theme_against<P: AsRef<Path>>( { Ok(c) => c, Err(e) => { - diag.struct_err(&e).emit(); + diag.struct_err(e).emit(); return (false, vec![]); } }; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index a6089680fae..841c7a78b2d 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -136,14 +136,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // is declared but also a reexport of itself producing two exports of the same // macro in the same module. let mut inserted = FxHashSet::default(); - for export in self.cx.tcx.module_children_reexports(CRATE_DEF_ID) { - if let Res::Def(DefKind::Macro(_), def_id) = export.res && + for child in self.cx.tcx.module_children_local(CRATE_DEF_ID) { + if !child.reexport_chain.is_empty() && + let Res::Def(DefKind::Macro(_), def_id) = child.res && let Some(local_def_id) = def_id.as_local() && self.cx.tcx.has_attr(def_id, sym::macro_export) && inserted.insert(def_id) { - let item = self.cx.tcx.hir().expect_item(local_def_id); - top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None)); + let item = self.cx.tcx.hir().expect_item(local_def_id); + top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None)); } } diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index c437bde5ae6..6c3b5bb00a3 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -9,6 +9,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" anyhow = "1.0.32" flate2 = "1.0.16" +xz2 = "0.1.7" tar = "0.4.29" sha2 = "0.10.1" rayon = "1.5.1" diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index dde9745afb7..7a4c15d01ea 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -5,6 +5,7 @@ use std::fs::File; use std::io::Read; use std::path::{Path, PathBuf}; use tar::Archive; +use xz2::read::XzDecoder; const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu"; @@ -175,9 +176,23 @@ impl Versions { } fn load_version_from_tarball(&mut self, package: &PkgType) -> Result<VersionInfo, Error> { - let tarball_name = self.tarball_name(package, DEFAULT_TARGET)?; - let tarball = self.dist_path.join(tarball_name); + for ext in ["xz", "gz"] { + let info = + self.load_version_from_tarball_inner(&self.dist_path.join(self.archive_name( + package, + DEFAULT_TARGET, + &format!("tar.{}", ext), + )?))?; + if info.present { + return Ok(info); + } + } + + // If neither tarball is present, we fallback to returning the non-present info. + Ok(VersionInfo::default()) + } + fn load_version_from_tarball_inner(&mut self, tarball: &Path) -> Result<VersionInfo, Error> { let file = match File::open(&tarball) { Ok(file) => file, Err(err) if err.kind() == std::io::ErrorKind::NotFound => { @@ -187,7 +202,14 @@ impl Versions { } Err(err) => return Err(err.into()), }; - let mut tar = Archive::new(GzDecoder::new(file)); + let mut tar: Archive<Box<dyn std::io::Read>> = + Archive::new(if tarball.extension().map_or(false, |e| e == "gz") { + Box::new(GzDecoder::new(file)) + } else if tarball.extension().map_or(false, |e| e == "xz") { + Box::new(XzDecoder::new(file)) + } else { + unimplemented!("tarball extension not recognized: {}", tarball.display()) + }); let mut version = None; let mut git_commit = None; diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 9e586fbd8b931494067144623b76c37d213b1ab +Subproject 569b648b5831ae8a515e90c80843a5287c3304e diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml index 116058b7c75..0bc2f49f5e9 100644 --- a/src/tools/clippy/.github/workflows/remark.yml +++ b/src/tools/clippy/.github/workflows/remark.yml @@ -36,6 +36,12 @@ jobs: - name: Check *.md files run: git ls-files -z '*.md' | xargs -0 -n 1 -I {} ./node_modules/.bin/remark {} -u lint -f > /dev/null + - name: Linkcheck book + run: | + rustup toolchain install nightly --component rust-docs + curl https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh -o linkcheck.sh + sh linkcheck.sh clippy --path ./book + - name: Build mdbook run: mdbook build book diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md index d7102d2474e..ebf5b58a586 100644 --- a/src/tools/clippy/CHANGELOG.md +++ b/src/tools/clippy/CHANGELOG.md @@ -44,7 +44,7 @@ Current stable, released 2023-04-20 ### Enhancements -* [`arithmetic_side_effects`]: No longer lints, if safe constant values are used. +* [`arithmetic_side_effects`]: No longer lints if safe constant values are used. [#10310](https://github.com/rust-lang/rust-clippy/pull/10310) * [`needless_lifetimes`]: Now works in local macros [#10257](https://github.com/rust-lang/rust-clippy/pull/10257) @@ -60,39 +60,39 @@ Current stable, released 2023-04-20 ### False Positive Fixes -* [`explicit_auto_deref`]: Now considers projections, when determining if auto deref is applicable +* [`explicit_auto_deref`]: Now considers projections when determining if auto deref is applicable [#10386](https://github.com/rust-lang/rust-clippy/pull/10386) -* [`manual_let_else`]: Now considers side effects of branches, before linting +* [`manual_let_else`]: Now considers side effects of branches before linting [#10336](https://github.com/rust-lang/rust-clippy/pull/10336) * [`uninlined_format_args`]: No longer lints for arguments with generic parameters [#10343](https://github.com/rust-lang/rust-clippy/pull/10343) -* [`needless_lifetimes`]: No longer lints signatures in macros, if the lifetime is a metavariable +* [`needless_lifetimes`]: No longer lints signatures in macros if the lifetime is a metavariable [#10380](https://github.com/rust-lang/rust-clippy/pull/10380) -* [`len_without_is_empty`]: No longer lints, if `len` as a non-default signature +* [`len_without_is_empty`]: No longer lints if `len` as a non-default signature [#10255](https://github.com/rust-lang/rust-clippy/pull/10255) -* [`unusual_byte_groupings`]: Relaxed the required restrictions for specific sizes, to reduce false +* [`unusual_byte_groupings`]: Relaxed the required restrictions for specific sizes to reduce false positives [#10353](https://github.com/rust-lang/rust-clippy/pull/10353) * [`manual_let_else`]: No longer lints `if-else` blocks if they can divergent [#10332](https://github.com/rust-lang/rust-clippy/pull/10332) * [`expect_used`], [`unwrap_used`], [`dbg_macro`], [`print_stdout`], [`print_stderr`]: No longer lint - in test functions, if `allow-expect-in-tests` is set + in test functions if `allow-expect-in-tests` is set [#10391](https://github.com/rust-lang/rust-clippy/pull/10391) * [`unnecessary_safety_comment`]: No longer lints code inside macros [#10106](https://github.com/rust-lang/rust-clippy/pull/10106) -* [`never_loop`]: No longer lints, for statements following break statements for outer blocks. +* [`never_loop`]: No longer lints statements following break statements for outer blocks. [#10311](https://github.com/rust-lang/rust-clippy/pull/10311) ### Suggestion Fixes/Improvements -* [`box_default`]: The suggestion now includes the type for trait objects, when needed +* [`box_default`]: The suggestion now includes the type for trait objects when needed [#10382](https://github.com/rust-lang/rust-clippy/pull/10382) * [`cast_possible_truncation`]: Now suggests using `try_from` or allowing the lint [#10038](https://github.com/rust-lang/rust-clippy/pull/10038) * [`invalid_regex`]: Regex errors for non-literals or regular strings containing escape sequences will now show the complete error [#10231](https://github.com/rust-lang/rust-clippy/pull/10231) -* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works, if the base type is borrowed +* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works if the base type is borrowed [#10193](https://github.com/rust-lang/rust-clippy/pull/10193) * [`needless_return`]: Now removes all semicolons on the same line [#10187](https://github.com/rust-lang/rust-clippy/pull/10187) @@ -113,7 +113,7 @@ Current stable, released 2023-04-20 ### ICE Fixes -* [`needless_pass_by_value`]: Fixed an ICE, caused by how late bounds were handled +* [`needless_pass_by_value`]: Fixed an ICE caused by how late bounds were handled [#10328](https://github.com/rust-lang/rust-clippy/pull/10328) * [`needless_borrow`]: No longer panics on ambiguous projections [#10403](https://github.com/rust-lang/rust-clippy/pull/10403) @@ -4582,6 +4582,7 @@ Released 2018-09-13 [`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call [`decimal_literal_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation [`declare_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const +[`default_constructed_unit_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs [`default_instead_of_iter_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_instead_of_iter_empty [`default_numeric_fallback`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_numeric_fallback [`default_trait_access`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_trait_access @@ -4797,6 +4798,7 @@ Released 2018-09-13 [`manual_strip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip [`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap [`manual_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or +[`manual_while_let_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_while_let_some [`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names [`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone [`map_collect_result_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_collect_result_unit @@ -4864,6 +4866,7 @@ Released 2018-09-13 [`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type [`needless_bitwise_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bitwise_bool [`needless_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool +[`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign [`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow [`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference [`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml index 4db15ddb283..3c72bb62ed1 100644 --- a/src/tools/clippy/Cargo.toml +++ b/src/tools/clippy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.70" +version = "0.1.71" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/src/tools/clippy/README.md b/src/tools/clippy/README.md index 85798e0e80c..6745e15c006 100644 --- a/src/tools/clippy/README.md +++ b/src/tools/clippy/README.md @@ -91,7 +91,8 @@ cargo clippy #### Automatically applying Clippy suggestions -Clippy can automatically apply some lint suggestions, just like the compiler. +Clippy can automatically apply some lint suggestions, just like the compiler. Note that `--fix` implies +`--all-targets`, so it can fix as much code as it can. ```terminal cargo clippy --fix diff --git a/src/tools/clippy/book/src/development/lint_passes.md b/src/tools/clippy/book/src/development/lint_passes.md index 131f6455fde..621fc20972e 100644 --- a/src/tools/clippy/book/src/development/lint_passes.md +++ b/src/tools/clippy/book/src/development/lint_passes.md @@ -50,7 +50,7 @@ questions already, but the parser is okay with it. This is what we mean when we say `EarlyLintPass` deals with only syntax on the AST level. Alternatively, think of the `foo_functions` lint we mentioned in -define new lints chapter. +define new lints <!-- FIXME: add link --> chapter. We want the `foo_functions` lint to detect functions with `foo` as their name. Writing a lint that only checks for the name of a function means that we only diff --git a/src/tools/clippy/book/src/development/proposals/syntax-tree-patterns.md b/src/tools/clippy/book/src/development/proposals/syntax-tree-patterns.md index 36d722609f4..285488cec55 100644 --- a/src/tools/clippy/book/src/development/proposals/syntax-tree-patterns.md +++ b/src/tools/clippy/book/src/development/proposals/syntax-tree-patterns.md @@ -139,7 +139,7 @@ whether the pattern matched. ## Pattern syntax -The following examples demonstate the pattern syntax: +The following examples demonstrate the pattern syntax: #### Any (`_`) diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md index a702226e861..5646c9b1520 100644 --- a/src/tools/clippy/book/src/lint_configuration.md +++ b/src/tools/clippy/book/src/lint_configuration.md @@ -13,6 +13,8 @@ Please use that command to update the file and do not edit it by hand. | [msrv](#msrv) | `None` | | [cognitive-complexity-threshold](#cognitive-complexity-threshold) | `25` | | [disallowed-names](#disallowed-names) | `["foo", "baz", "quux"]` | +| [semicolon-inside-block-ignore-singleline](#semicolon-inside-block-ignore-singleline) | `false` | +| [semicolon-outside-block-ignore-multiline](#semicolon-outside-block-ignore-multiline) | `false` | | [doc-valid-idents](#doc-valid-idents) | `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` | | [too-many-arguments-threshold](#too-many-arguments-threshold) | `7` | | [type-complexity-threshold](#type-complexity-threshold) | `250` | @@ -203,6 +205,22 @@ default configuration of Clippy. By default, any configuration will replace the * [disallowed_names](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names) +### semicolon-inside-block-ignore-singleline +Whether to lint only if it's multiline. + +**Default Value:** `false` (`bool`) + +* [semicolon_inside_block](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block) + + +### semicolon-outside-block-ignore-multiline +Whether to lint only if it's singleline. + +**Default Value:** `false` (`bool`) + +* [semicolon_outside_block](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block) + + ### doc-valid-idents The list of words this lint should not consider as identifiers needing ticks. The value `".."` can be used as part of the list to indicate, that the configured values should be appended to the diff --git a/src/tools/clippy/book/src/usage.md b/src/tools/clippy/book/src/usage.md index 32084a9199b..36448e4cccf 100644 --- a/src/tools/clippy/book/src/usage.md +++ b/src/tools/clippy/book/src/usage.md @@ -111,7 +111,8 @@ fn main() { ### Automatically applying Clippy suggestions -Clippy can automatically apply some lint suggestions, just like the compiler. +Clippy can automatically apply some lint suggestions, just like the compiler. Note that `--fix` implies +`--all-targets`, so it can fix as much code as it can. ```terminal cargo clippy --fix diff --git a/src/tools/clippy/clippy_dev/src/dogfood.rs b/src/tools/clippy/clippy_dev/src/dogfood.rs index b69e9f649ec..a0d57f5ab48 100644 --- a/src/tools/clippy/clippy_dev/src/dogfood.rs +++ b/src/tools/clippy/clippy_dev/src/dogfood.rs @@ -1,4 +1,4 @@ -use crate::clippy_project_root; +use crate::{clippy_project_root, exit_if_err}; use std::process::Command; /// # Panics @@ -10,7 +10,7 @@ pub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool) { cmd.current_dir(clippy_project_root()) .args(["test", "--test", "dogfood"]) .args(["--features", "internal"]) - .args(["--", "dogfood_clippy"]); + .args(["--", "dogfood_clippy", "--nocapture"]); let mut dogfood_args = Vec::new(); if fix { @@ -27,7 +27,5 @@ pub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool) { cmd.env("__CLIPPY_DOGFOOD_ARGS", dogfood_args.join(" ")); - let output = cmd.output().expect("failed to run command"); - - println!("{}", String::from_utf8_lossy(&output.stdout)); + exit_if_err(cmd.status()); } diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs index 3a8b070d735..56a269288c0 100644 --- a/src/tools/clippy/clippy_dev/src/lib.rs +++ b/src/tools/clippy/clippy_dev/src/lib.rs @@ -10,7 +10,9 @@ extern crate rustc_driver; extern crate rustc_lexer; +use std::io; use std::path::PathBuf; +use std::process::{self, ExitStatus}; pub mod bless; pub mod dogfood; @@ -58,3 +60,14 @@ pub fn clippy_project_root() -> PathBuf { } panic!("error: Can't determine root of project. Please run inside a Clippy working dir."); } + +pub fn exit_if_err(status: io::Result<ExitStatus>) { + match status.expect("failed to run command").code() { + Some(0) => {}, + Some(n) => process::exit(n), + None => { + eprintln!("Killed by signal"); + process::exit(1); + }, + } +} diff --git a/src/tools/clippy/clippy_dev/src/lint.rs b/src/tools/clippy/clippy_dev/src/lint.rs index aafd0f71a59..a19be1bca6c 100644 --- a/src/tools/clippy/clippy_dev/src/lint.rs +++ b/src/tools/clippy/clippy_dev/src/lint.rs @@ -1,17 +1,6 @@ -use crate::cargo_clippy_path; -use std::process::{self, Command, ExitStatus}; -use std::{fs, io}; - -fn exit_if_err(status: io::Result<ExitStatus>) { - match status.expect("failed to run command").code() { - Some(0) => {}, - Some(n) => process::exit(n), - None => { - eprintln!("Killed by signal"); - process::exit(1); - }, - } -} +use crate::{cargo_clippy_path, exit_if_err}; +use std::fs; +use std::process::{self, Command}; pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) { let is_file = match fs::metadata(path) { diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs index dd90a38f757..7213c9dfede 100644 --- a/src/tools/clippy/clippy_dev/src/update_lints.rs +++ b/src/tools/clippy/clippy_dev/src/update_lints.rs @@ -36,60 +36,6 @@ pub enum UpdateMode { pub fn update(update_mode: UpdateMode) { let (lints, deprecated_lints, renamed_lints) = gather_all(); generate_lint_files(update_mode, &lints, &deprecated_lints, &renamed_lints); - remove_old_files(update_mode); -} - -/// Remove files no longer needed after <https://github.com/rust-lang/rust-clippy/pull/9541> -/// that may be reintroduced unintentionally -/// -/// FIXME: This is a temporary measure that should be removed when there are no more PRs that -/// include the stray files -fn remove_old_files(update_mode: UpdateMode) { - let mut failed = false; - let mut remove_file = |path: &Path| match update_mode { - UpdateMode::Check => { - if path.exists() { - failed = true; - println!("unexpected file: {}", path.display()); - } - }, - UpdateMode::Change => { - if fs::remove_file(path).is_ok() { - println!("removed file: {}", path.display()); - } - }, - }; - - let files = [ - "clippy_lints/src/lib.register_all.rs", - "clippy_lints/src/lib.register_cargo.rs", - "clippy_lints/src/lib.register_complexity.rs", - "clippy_lints/src/lib.register_correctness.rs", - "clippy_lints/src/lib.register_internal.rs", - "clippy_lints/src/lib.register_lints.rs", - "clippy_lints/src/lib.register_nursery.rs", - "clippy_lints/src/lib.register_pedantic.rs", - "clippy_lints/src/lib.register_perf.rs", - "clippy_lints/src/lib.register_restriction.rs", - "clippy_lints/src/lib.register_style.rs", - "clippy_lints/src/lib.register_suspicious.rs", - "src/docs.rs", - ]; - - for file in files { - remove_file(Path::new(file)); - } - - if let Ok(docs_dir) = fs::read_dir("src/docs") { - for doc_file in docs_dir { - let path = doc_file.unwrap().path(); - remove_file(&path); - } - } - - if failed { - exit_with_failure(); - } } fn generate_lint_files( diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml index 18e8bf77225..37e1e6a742f 100644 --- a/src/tools/clippy/clippy_lints/Cargo.toml +++ b/src/tools/clippy/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.70" +version = "0.1.71" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/src/tools/clippy/clippy_lints/src/allow_attributes.rs b/src/tools/clippy/clippy_lints/src/allow_attributes.rs index b984132acf5..add73d0aeee 100644 --- a/src/tools/clippy/clippy_lints/src/allow_attributes.rs +++ b/src/tools/clippy/clippy_lints/src/allow_attributes.rs @@ -2,7 +2,8 @@ use ast::AttrStyle; use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_ast as ast; use rustc_errors::Applicability; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { @@ -51,6 +52,7 @@ impl LateLintPass<'_> for AllowAttribute { // Separate each crate's features. fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) { if_chain! { + if !in_external_macro(cx.sess(), attr.span); if cx.tcx.features().lint_reasons; if let AttrStyle::Outer = attr.style; if let Some(ident) = attr.ident(); diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs index d74bd57fe45..cfeb75eed3b 100644 --- a/src/tools/clippy/clippy_lints/src/casts/mod.rs +++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs @@ -638,7 +638,7 @@ declare_clippy_lint! { #[clippy::version = "1.66.0"] pub AS_PTR_CAST_MUT, nursery, - "casting the result of the `&self`-taking `as_ptr` to a mutabe pointer" + "casting the result of the `&self`-taking `as_ptr` to a mutable pointer" } declare_clippy_lint! { diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs index 7e23318076c..804ae841100 100644 --- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs +++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs @@ -141,9 +141,9 @@ fn lint_unnecessary_cast( fn get_numeric_literal<'e>(expr: &'e Expr<'e>) -> Option<&'e Lit> { match expr.kind { - ExprKind::Lit(ref lit) => Some(lit), + ExprKind::Lit(lit) => Some(lit), ExprKind::Unary(UnOp::Neg, e) => { - if let ExprKind::Lit(ref lit) = e.kind { + if let ExprKind::Lit(lit) = e.kind { Some(lit) } else { None diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs index 970f5004993..1c321f46e2d 100644 --- a/src/tools/clippy/clippy_lints/src/copies.rs +++ b/src/tools/clippy/clippy_lints/src/copies.rs @@ -591,7 +591,7 @@ fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &De conds, |e| hash_expr(cx, e), |lhs, rhs| { - // Ignore eq_expr side effects iff one of the expressin kind is a method call + // Ignore eq_expr side effects iff one of the expression kind is a method call // and the caller is not a mutable, including inner mutable type. if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind { if method_caller_is_mutable(cx, caller, ignored_ty_ids) { diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index 0c66d36a1d6..79d0f6f3607 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -105,6 +105,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::dbg_macro::DBG_MACRO_INFO, crate::default::DEFAULT_TRAIT_ACCESS_INFO, crate::default::FIELD_REASSIGN_WITH_DEFAULT_INFO, + crate::default_constructed_unit_structs::DEFAULT_CONSTRUCTED_UNIT_STRUCTS_INFO, crate::default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY_INFO, crate::default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK_INFO, crate::default_union_representation::DEFAULT_UNION_REPRESENTATION_INFO, @@ -249,6 +250,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::loops::MANUAL_FIND_INFO, crate::loops::MANUAL_FLATTEN_INFO, crate::loops::MANUAL_MEMCPY_INFO, + crate::loops::MANUAL_WHILE_LET_SOME_INFO, crate::loops::MISSING_SPIN_LOOP_INFO, crate::loops::MUT_RANGE_BOUND_INFO, crate::loops::NEEDLESS_RANGE_LOOP_INFO, @@ -313,7 +315,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::CHARS_NEXT_CMP_INFO, crate::methods::CLEAR_WITH_DRAIN_INFO, crate::methods::CLONED_INSTEAD_OF_COPIED_INFO, - crate::methods::CLONE_DOUBLE_REF_INFO, crate::methods::CLONE_ON_COPY_INFO, crate::methods::CLONE_ON_REF_PTR_INFO, crate::methods::COLLAPSIBLE_STR_REPLACE_INFO, @@ -446,6 +447,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE_INFO, crate::needless_bool::BOOL_COMPARISON_INFO, crate::needless_bool::NEEDLESS_BOOL_INFO, + crate::needless_bool::NEEDLESS_BOOL_ASSIGN_INFO, crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO, crate::needless_continue::NEEDLESS_CONTINUE_INFO, crate::needless_for_each::NEEDLESS_FOR_EACH_INFO, diff --git a/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs b/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs new file mode 100644 index 00000000000..e529d81a7e9 --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs @@ -0,0 +1,72 @@ +use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, match_def_path, paths}; +use hir::{def::Res, ExprKind}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Check for construction on unit struct using `default`. + /// + /// ### Why is this bad? + /// This adds code complexity and an unnecessary function call. + /// + /// ### Example + /// ```rust + /// # use std::marker::PhantomData; + /// #[derive(Default)] + /// struct S<T> { + /// _marker: PhantomData<T> + /// } + /// + /// let _: S<i32> = S { + /// _marker: PhantomData::default() + /// }; + /// ``` + /// Use instead: + /// ```rust + /// # use std::marker::PhantomData; + /// struct S<T> { + /// _marker: PhantomData<T> + /// } + /// + /// let _: S<i32> = S { + /// _marker: PhantomData + /// }; + /// ``` + #[clippy::version = "1.71.0"] + pub DEFAULT_CONSTRUCTED_UNIT_STRUCTS, + complexity, + "unit structs can be contructed without calling `default`" +} +declare_lint_pass!(DefaultConstructedUnitStructs => [DEFAULT_CONSTRUCTED_UNIT_STRUCTS]); + +impl LateLintPass<'_> for DefaultConstructedUnitStructs { + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + if_chain!( + // make sure we have a call to `Default::default` + if let hir::ExprKind::Call(fn_expr, &[]) = expr.kind; + if let ExprKind::Path(ref qpath@ hir::QPath::TypeRelative(_,_)) = fn_expr.kind; + if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id); + if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD); + // make sure we have a struct with no fields (unit struct) + if let ty::Adt(def, ..) = cx.typeck_results().expr_ty(expr).kind(); + if def.is_struct(); + if let var @ ty::VariantDef { ctor: Some((hir::def::CtorKind::Const, _)), .. } = def.non_enum_variant(); + if !var.is_field_list_non_exhaustive() && !is_from_proc_macro(cx, expr); + then { + span_lint_and_sugg( + cx, + DEFAULT_CONSTRUCTED_UNIT_STRUCTS, + expr.span.with_lo(qpath.qself_span().hi()), + "use of `default` to create a unit struct", + "remove this call to `default`", + String::new(), + Applicability::MachineApplicable, + ) + } + ); + } +} diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index f425dd5fb70..8f5d319cd4f 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -517,7 +517,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> tcx.mk_predicates_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate { - trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), + trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), constness: BoundConstness::NotConst, polarity: ImplPolarity::Positive, })))) diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index d6ab4c25e83..a51a8ee09f6 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -92,11 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { if trait_item.id.owner_id.def_id == fn_def_id { // be sure we have `self` parameter in this function if trait_item.kind == (AssocItemKind::Fn { has_self: true }) { - trait_self_ty = Some( - TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id()) - .self_ty() - .skip_binder(), - ); + trait_self_ty = + Some(TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id()).self_ty()); } } } diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs index 6fee7fb308c..93bf50fd5e7 100644 --- a/src/tools/clippy/clippy_lints/src/float_literal.rs +++ b/src/tools/clippy/clippy_lints/src/float_literal.rs @@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { let ty = cx.typeck_results().expr_ty(expr); if_chain! { if let ty::Float(fty) = *ty.kind(); - if let hir::ExprKind::Lit(ref lit) = expr.kind; + if let hir::ExprKind::Lit(lit) = expr.kind; if let LitKind::Float(sym, lit_float_ty) = lit.node; then { let sym_str = sym.as_str(); diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs index f95b628e6c3..a1a2c398a8a 100644 --- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs @@ -2,9 +2,10 @@ use clippy_utils::consts::{ constant, constant_simple, Constant, Constant::{Int, F32, F64}, }; -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::higher; -use clippy_utils::{eq_expr_value, get_parent_expr, in_constant, numeric_literal, peel_blocks, sugg}; +use clippy_utils::{ + diagnostics::span_lint_and_sugg, eq_expr_value, get_parent_expr, higher, in_constant, is_no_std_crate, + numeric_literal, peel_blocks, sugg, +}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp}; @@ -677,7 +678,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { { let mut proposal = format!("{}.to_degrees()", Sugg::hir(cx, mul_lhs, "..").maybe_par()); if_chain! { - if let ExprKind::Lit(ref literal) = mul_lhs.kind; + if let ExprKind::Lit(literal) = mul_lhs.kind; if let ast::LitKind::Float(ref value, float_type) = literal.node; if float_type == ast::LitFloatType::Unsuffixed; then { @@ -703,7 +704,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { { let mut proposal = format!("{}.to_radians()", Sugg::hir(cx, mul_lhs, "..").maybe_par()); if_chain! { - if let ExprKind::Lit(ref literal) = mul_lhs.kind; + if let ExprKind::Lit(literal) = mul_lhs.kind; if let ast::LitKind::Float(ref value, float_type) = literal.node; if float_type == ast::LitFloatType::Unsuffixed; then { @@ -730,7 +731,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - // All of these operations are currently not const. + // All of these operations are currently not const and are in std. if in_constant(cx, expr.hir_id) { return; } @@ -738,7 +739,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { if let ExprKind::MethodCall(path, receiver, args, _) = &expr.kind { let recv_ty = cx.typeck_results().expr_ty(receiver); - if recv_ty.is_floating_point() { + if recv_ty.is_floating_point() && !is_no_std_crate(cx) { match path.ident.name.as_str() { "ln" => check_ln1p(cx, expr, receiver), "log" => check_log_base(cx, expr, receiver, args), @@ -749,10 +750,12 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { } } } else { - check_expm1(cx, expr); - check_mul_add(cx, expr); - check_custom_abs(cx, expr); - check_log_division(cx, expr); + if !is_no_std_crate(cx) { + check_expm1(cx, expr); + check_mul_add(cx, expr); + check_custom_abs(cx, expr); + check_log_division(cx, expr); + } check_radians(cx, expr); } } diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index bd66ace4500..10ce2a0f0c7 100644 --- a/src/tools/clippy/clippy_lints/src/from_over_into.rs +++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs @@ -94,7 +94,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { ); } - let message = format!("replace the `Into` implentation with `From<{}>`", middle_trait_ref.self_ty()); + let message = format!("replace the `Into` implementation with `From<{}>`", middle_trait_ref.self_ty()); if let Some(suggestions) = convert_to_from(cx, into_trait_seg, target_ty, self_ty, impl_item_ref) { diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable); } else { diff --git a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs index e5945939e60..b244b913314 100644 --- a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs +++ b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs @@ -40,7 +40,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: }; // Body must be &(mut) <self_data>.name - // self_data is not neccessarilly self, to also lint sub-getters, etc… + // self_data is not necessarily self, to also lint sub-getters, etc… let block_expr = if_chain! { if let ExprKind::Block(block,_) = body.value.kind; diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs index ac2d253fe83..ee10334c67f 100644 --- a/src/tools/clippy/clippy_lints/src/functions/mod.rs +++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs @@ -252,6 +252,11 @@ declare_clippy_lint! { /// A `Result` is at least as large as the `Err`-variant. While we /// expect that variant to be seldomly used, the compiler needs to reserve /// and move that much memory every single time. + /// Furthermore, errors are often simply passed up the call-stack, making + /// use of the `?`-operator and its type-conversion mechanics. If the + /// `Err`-variant further up the call-stack stores the `Err`-variant in + /// question (as library code often does), it itself needs to be at least + /// as large, propagating the problem. /// /// ### Known problems /// The size determined by Clippy is platform-dependent. @@ -330,7 +335,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Lints when `impl Trait` is being used in a function's paremeters. + /// Lints when `impl Trait` is being used in a function's parameters. /// ### Why is this bad? /// Turbofish syntax (`::<>`) cannot be used when `impl Trait` is being used, making `impl Trait` less powerful. Readability may also be a factor. /// diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index ff838c2d56e..d1314795f58 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { if let PredicateKind::Clause(Clause::Trait(trait_pred)) = obligation.predicate.kind().skip_binder() { - db.note(&format!( + db.note(format!( "`{}` doesn't implement `{}`", trait_pred.self_ty(), trait_pred.trait_ref.print_only_trait_path(), diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs index 57e6caa8711..012aa5a1d1d 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs @@ -60,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { if expr1.span.ctxt() == ctxt; if clippy_utils::SpanlessEq::new(cx).eq_expr(l, target); if BinOpKind::Add == op1.node; - if let ExprKind::Lit(ref lit) = value.kind; + if let ExprKind::Lit(lit) = value.kind; if let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node; if block.expr.is_none(); then { diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs index 0c7aea6da8f..1e99b6faa6c 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs @@ -87,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub { // Get the variable name let var_name = ares_path.segments[0].ident.name.as_str(); match cond_num_val.kind { - ExprKind::Lit(ref cond_lit) => { + ExprKind::Lit(cond_lit) => { // Check if the constant is zero if let LitKind::Int(0, _) = cond_lit.node { if cx.typeck_results().expr_ty(cond_left).is_signed() { diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index c384172fbde..924a361c0f6 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -170,7 +170,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { return; } // Index is a constant uint. - if let Some(..) = constant(cx, cx.typeck_results(), index) { + if constant(cx, cx.typeck_results(), index).is_some() { // Let rustc's `const_err` lint handle constant `usize` indexing on arrays. return; } diff --git a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs index 52d716feea0..b992d689aa9 100644 --- a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs +++ b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs @@ -64,20 +64,21 @@ impl LateLintPass<'_> for ItemsAfterTestModule { span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined"); }}; - if matches!(item.kind, ItemKind::Mod(_)) { - for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) { - if_chain! { - if attr.has_name(sym::cfg); + if let ItemKind::Mod(module) = item.kind && item.span.hi() == module.spans.inner_span.hi() { + // Check that it works the same way, the only I way I've found for #10713 + for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) { + if_chain! { + if attr.has_name(sym::cfg); if let Some(mitems) = attr.meta_item_list(); if let [mitem] = &*mitems; if mitem.has_name(sym::test); then { - was_test_mod_visited = true; + was_test_mod_visited = true; test_mod_span = Some(item.span); } } } - } + } } } } diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs index 1b054481371..0ca31033b16 100644 --- a/src/tools/clippy/clippy_lints/src/large_futures.rs +++ b/src/tools/clippy/clippy_lints/src/large_futures.rs @@ -11,7 +11,7 @@ declare_clippy_lint! { /// It checks for the size of a `Future` created by `async fn` or `async {}`. /// /// ### Why is this bad? - /// Due to the current [unideal implemention](https://github.com/rust-lang/rust/issues/69826) of `Generator`, + /// Due to the current [unideal implementation](https://github.com/rust-lang/rust/issues/69826) of `Generator`, /// large size of a `Future` may cause stack overflows. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index fec9c6f626c..17bd89efaee 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -532,7 +532,7 @@ fn check_empty_expr(cx: &LateContext<'_>, span: Span, lit1: &Expr<'_>, lit2: &Ex } fn is_empty_string(expr: &Expr<'_>) -> bool { - if let ExprKind::Lit(ref lit) = expr.kind { + if let ExprKind::Lit(lit) = expr.kind { if let LitKind::Str(lit, _) = lit.node { let lit = lit.as_str(); return lit.is_empty(); diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs index 637b7de920e..16772a9d598 100644 --- a/src/tools/clippy/clippy_lints/src/let_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs @@ -6,6 +6,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::subst::GenericArgKind; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -205,8 +206,13 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { LET_UNDERSCORE_UNTYPED, local.span, "non-binding `let` without a type annotation", - None, - "consider adding a type annotation or removing the `let` keyword", + Some( + Span::new(local.pat.span.hi(), + local.pat.span.hi() + BytePos(1), + local.pat.span.ctxt(), + local.pat.span.parent() + )), + "consider adding a type annotation", ); } } diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 573ffe349ec..3517842a01e 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -94,6 +94,7 @@ mod crate_in_macro_def; mod create_dir; mod dbg_macro; mod default; +mod default_constructed_unit_structs; mod default_instead_of_iter_empty; mod default_numeric_fallback; mod default_union_representation; @@ -353,7 +354,7 @@ pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Se pub fn read_conf(sess: &Session, path: &io::Result<(Option<PathBuf>, Vec<String>)>) -> Conf { if let Ok((_, warnings)) = path { for warning in warnings { - sess.warn(warning); + sess.warn(warning.clone()); } } let file_name = match path { @@ -933,7 +934,14 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(from_raw_with_void_ptr::FromRawWithVoidPtr)); store.register_late_pass(|_| Box::new(suspicious_xor_used_as_pow::ConfusingXorAndPow)); store.register_late_pass(move |_| Box::new(manual_is_ascii_check::ManualIsAsciiCheck::new(msrv()))); - store.register_late_pass(|_| Box::new(semicolon_block::SemicolonBlock)); + let semicolon_inside_block_ignore_singleline = conf.semicolon_inside_block_ignore_singleline; + let semicolon_outside_block_ignore_multiline = conf.semicolon_outside_block_ignore_multiline; + store.register_late_pass(move |_| { + Box::new(semicolon_block::SemicolonBlock::new( + semicolon_inside_block_ignore_singleline, + semicolon_outside_block_ignore_multiline, + )) + }); store.register_late_pass(|_| Box::new(fn_null_check::FnNullCheck)); store.register_late_pass(|_| Box::new(permissions_set_readonly_false::PermissionsSetReadonlyFalse)); store.register_late_pass(|_| Box::new(size_of_ref::SizeOfRef)); @@ -963,6 +971,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation)); store.register_early_pass(|| Box::new(suspicious_doc_comments::SuspiciousDocComments)); store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule)); + store.register_late_pass(|_| Box::new(default_constructed_unit_structs::DefaultConstructedUnitStructs)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs index c87fc4f90e2..d4c3f76b864 100644 --- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs +++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs @@ -15,7 +15,7 @@ use rustc_span::symbol::sym; use std::fmt::Display; use std::iter::Iterator; -/// Checks for for loops that sequentially copy items from one slice-like +/// Checks for `for` loops that sequentially copy items from one slice-like /// object to another. pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs b/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs new file mode 100644 index 00000000000..cb9c84be4c7 --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs @@ -0,0 +1,110 @@ +use clippy_utils::{ + diagnostics::{multispan_sugg_with_applicability, span_lint_and_then}, + match_def_path, paths, + source::snippet, + SpanlessEq, +}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, Pat, Stmt, StmtKind, UnOp}; +use rustc_lint::LateContext; +use rustc_span::Span; +use std::borrow::Cow; + +use super::MANUAL_WHILE_LET_SOME; + +/// The kind of statement that the `pop()` call appeared in. +/// +/// Depending on whether the value was assigned to a variable or not changes what pattern +/// we use for the suggestion. +#[derive(Copy, Clone)] +enum PopStmt<'hir> { + /// `x.pop().unwrap()` was and assigned to a variable. + /// The pattern of this local variable will be used and the local statement + /// is deleted in the suggestion. + Local(&'hir Pat<'hir>), + /// `x.pop().unwrap()` appeared in an arbitrary expression and was not assigned to a variable. + /// The suggestion will use some placeholder identifier and the `x.pop().unwrap()` expression + /// is replaced with that identifier. + Anonymous, +} + +fn report_lint(cx: &LateContext<'_>, pop_span: Span, pop_stmt_kind: PopStmt<'_>, loop_span: Span, receiver_span: Span) { + span_lint_and_then( + cx, + MANUAL_WHILE_LET_SOME, + pop_span, + "you seem to be trying to pop elements from a `Vec` in a loop", + |diag| { + let (pat, pop_replacement) = match pop_stmt_kind { + PopStmt::Local(pat) => (snippet(cx, pat.span, ".."), String::new()), + PopStmt::Anonymous => (Cow::Borrowed("element"), "element".into()), + }; + + let loop_replacement = format!("while let Some({}) = {}.pop()", pat, snippet(cx, receiver_span, "..")); + multispan_sugg_with_applicability( + diag, + "consider using a `while..let` loop", + Applicability::MachineApplicable, + [(loop_span, loop_replacement), (pop_span, pop_replacement)], + ); + }, + ); +} + +fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: &[&str]) -> bool { + if let ExprKind::MethodCall(..) = expr.kind + && let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) + { + match_def_path(cx, id, method) + } else { + false + } +} + +fn is_vec_pop_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, is_empty_recv: &Expr<'_>) -> bool { + if (match_method_call(cx, expr, &paths::OPTION_UNWRAP) || match_method_call(cx, expr, &paths::OPTION_EXPECT)) + && let ExprKind::MethodCall(_, unwrap_recv, ..) = expr.kind + && match_method_call(cx, unwrap_recv, &paths::VEC_POP) + && let ExprKind::MethodCall(_, pop_recv, ..) = unwrap_recv.kind + { + // make sure they're the same `Vec` + SpanlessEq::new(cx).eq_expr(pop_recv, is_empty_recv) + } else { + false + } +} + +fn check_local(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &Expr<'_>, loop_span: Span) { + if let StmtKind::Local(local) = stmt.kind + && let Some(init) = local.init + && is_vec_pop_unwrap(cx, init, is_empty_recv) + { + report_lint(cx, stmt.span, PopStmt::Local(local.pat), loop_span, is_empty_recv.span); + } +} + +fn check_call_arguments(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &Expr<'_>, loop_span: Span) { + if let StmtKind::Semi(expr) | StmtKind::Expr(expr) = stmt.kind { + if let ExprKind::MethodCall(.., args, _) | ExprKind::Call(_, args) = expr.kind { + let offending_arg = args + .iter() + .find_map(|arg| is_vec_pop_unwrap(cx, arg, is_empty_recv).then_some(arg.span)); + + if let Some(offending_arg) = offending_arg { + report_lint(cx, offending_arg, PopStmt::Anonymous, loop_span, is_empty_recv.span); + } + } + } +} + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, full_cond: &'tcx Expr<'_>, body: &'tcx Expr<'_>, loop_span: Span) { + if let ExprKind::Unary(UnOp::Not, cond) = full_cond.kind + && let ExprKind::MethodCall(_, is_empty_recv, _, _) = cond.kind + && match_method_call(cx, cond, &paths::VEC_IS_EMPTY) + && let ExprKind::Block(body, _) = body.kind + && let Some(stmt) = body.stmts.first() + { + check_local(cx, stmt, is_empty_recv, loop_span); + check_call_arguments(cx, stmt, is_empty_recv, loop_span); + } +} diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs index 610a0233eee..f83ad388a74 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mod.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs @@ -7,6 +7,7 @@ mod iter_next_loop; mod manual_find; mod manual_flatten; mod manual_memcpy; +mod manual_while_let_some; mod missing_spin_loop; mod mut_range_bound; mod needless_range_loop; @@ -575,6 +576,36 @@ declare_clippy_lint! { "manual implementation of `Iterator::find`" } +declare_clippy_lint! { + /// ### What it does + /// Looks for loops that check for emptiness of a `Vec` in the condition and pop an element + /// in the body as a separate operation. + /// + /// ### Why is this bad? + /// Such loops can be written in a more idiomatic way by using a while-let loop and directly + /// pattern matching on the return value of `Vec::pop()`. + /// + /// ### Example + /// ```rust + /// let mut numbers = vec![1, 2, 3, 4, 5]; + /// while !numbers.is_empty() { + /// let number = numbers.pop().unwrap(); + /// // use `number` + /// } + /// ``` + /// Use instead: + /// ```rust + /// let mut numbers = vec![1, 2, 3, 4, 5]; + /// while let Some(number) = numbers.pop() { + /// // use `number` + /// } + /// ``` + #[clippy::version = "1.70.0"] + pub MANUAL_WHILE_LET_SOME, + style, + "checking for emptiness of a `Vec` in the loop condition and popping an element in the body" +} + declare_lint_pass!(Loops => [ MANUAL_MEMCPY, MANUAL_FLATTEN, @@ -594,6 +625,7 @@ declare_lint_pass!(Loops => [ SINGLE_ELEMENT_LOOP, MISSING_SPIN_LOOP, MANUAL_FIND, + MANUAL_WHILE_LET_SOME ]); impl<'tcx> LateLintPass<'tcx> for Loops { @@ -640,9 +672,10 @@ impl<'tcx> LateLintPass<'tcx> for Loops { while_let_on_iterator::check(cx, expr); - if let Some(higher::While { condition, body }) = higher::While::hir(expr) { + if let Some(higher::While { condition, body, span }) = higher::While::hir(expr) { while_immutable_condition::check(cx, condition, body); missing_spin_loop::check(cx, condition, body); + manual_while_let_some::check(cx, condition, body, span); } } } diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index 5c317c2a5bb..cb446567506 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -208,7 +208,7 @@ fn is_end_eq_array_len<'tcx>( indexed_ty: Ty<'tcx>, ) -> bool { if_chain! { - if let ExprKind::Lit(ref lit) = end.kind; + if let ExprKind::Lit(lit) = end.kind; if let ast::LitKind::Int(end_int, _) = lit.node; if let ty::Array(_, arr_len_const) = indexed_ty.kind(); if let Some(arr_len) = arr_len_const.try_eval_target_usize(cx.tcx, cx.param_env); diff --git a/src/tools/clippy/clippy_lints/src/manual_assert.rs b/src/tools/clippy/clippy_lints/src/manual_assert.rs index ce5d657bcf0..45ea5aab4c2 100644 --- a/src/tools/clippy/clippy_lints/src/manual_assert.rs +++ b/src/tools/clippy/clippy_lints/src/manual_assert.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert { }; let cond_sugg = sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par(); let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip});"); - // we show to the user the suggestion without the comments, but when applicating the fix, include the comments in the block + // we show to the user the suggestion without the comments, but when applying the fix, include the comments in the block span_lint_and_then( cx, MANUAL_ASSERT, diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs index 98e698c6c2a..1247370b74a 100644 --- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs +++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs @@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualLetElse { if source != MatchSource::Normal { return; } - // Any other number than two arms doesn't (neccessarily) + // Any other number than two arms doesn't (necessarily) // have a trivial mapping to let else. if arms.len() != 2 { return; diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs index 72cdb9c1736..5259066eb71 100644 --- a/src/tools/clippy/clippy_lints/src/manual_retain.rs +++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs @@ -46,7 +46,7 @@ declare_clippy_lint! { #[clippy::version = "1.64.0"] pub MANUAL_RETAIN, perf, - "`retain()` is simpler and the same functionalitys" + "`retain()` is simpler and the same functionalities" } pub struct ManualRetain { diff --git a/src/tools/clippy/clippy_lints/src/matches/match_bool.rs b/src/tools/clippy/clippy_lints/src/matches/match_bool.rs index df1e585f10b..69105ff0d5c 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_bool.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_bool.rs @@ -22,7 +22,7 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>] if arms.len() == 2 { // no guards let exprs = if let PatKind::Lit(arm_bool) = arms[0].pat.kind { - if let ExprKind::Lit(ref lit) = arm_bool.kind { + if let ExprKind::Lit(lit) = arm_bool.kind { match lit.node { LitKind::Bool(true) => Some((arms[0].body, arms[1].body)), LitKind::Bool(false) => Some((arms[1].body, arms[0].body)), diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index 158e6caa4de..a48f4c77f85 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -284,6 +284,7 @@ impl<'a> NormalizedPat<'a> { LitKind::Str(sym, _) => Self::LitStr(sym), LitKind::ByteStr(ref bytes, _) => Self::LitBytes(bytes), LitKind::Byte(val) => Self::LitInt(val.into()), + LitKind::CStr(ref bytes, _) => Self::LitBytes(bytes), LitKind::Char(val) => Self::LitInt(val.into()), LitKind::Int(val, _) => Self::LitInt(val), LitKind::Bool(val) => Self::LitBool(val), diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index 7b609ff3df8..af121f317cd 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -63,8 +63,11 @@ fn find_sugg_for_if_let<'tcx>( // Determine which function should be used, and the type contained by the corresponding // variant. let (good_method, inner_ty) = match check_pat.kind { - PatKind::TupleStruct(ref qpath, [sub_pat], _) => { - if let PatKind::Wild = sub_pat.kind { + PatKind::TupleStruct(ref qpath, args, rest) => { + let is_wildcard = matches!(args.first().map(|p| &p.kind), Some(PatKind::Wild)); + let is_rest = matches!((args, rest.as_opt_usize()), ([], Some(_))); + + if is_wildcard || is_rest { let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id); let Some(id) = res.opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id)) else { return }; let lang_items = cx.tcx.lang_items(); @@ -334,7 +337,7 @@ fn find_good_method_for_match<'a>( }; match body_node_pair { - (ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) { + (ExprKind::Lit(lit_left), ExprKind::Lit(lit_right)) => match (&lit_left.node, &lit_right.node) { (LitKind::Bool(true), LitKind::Bool(false)) => Some(should_be_left), (LitKind::Bool(false), LitKind::Bool(true)) => Some(should_be_right), _ => None, diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs index 27a05337a29..8984b2cf8fd 100644 --- a/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs @@ -18,7 +18,7 @@ pub(super) fn check( ) -> bool { if_chain! { if let Some(args) = method_chain_args(info.chain, chain_methods); - if let hir::ExprKind::Lit(ref lit) = info.other.kind; + if let hir::ExprKind::Lit(lit) = info.other.kind; if let ast::LitKind::Char(c) = lit.node; then { let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs index 3795c0ec250..65fd50dff58 100644 --- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs +++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs @@ -1,7 +1,6 @@ -use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_node; use clippy_utils::source::snippet_with_context; -use clippy_utils::sugg; use clippy_utils::ty::is_copy; use rustc_errors::Applicability; use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, MatchSource, Node, PatKind, QPath}; @@ -9,7 +8,6 @@ use rustc_lint::LateContext; use rustc_middle::ty::{self, adjustment::Adjust, print::with_forced_trimmed_paths}; use rustc_span::symbol::{sym, Symbol}; -use super::CLONE_DOUBLE_REF; use super::CLONE_ON_COPY; /// Checks for the `CLONE_ON_COPY` lint. @@ -42,41 +40,7 @@ pub(super) fn check( let ty = cx.typeck_results().expr_ty(expr); if let ty::Ref(_, inner, _) = arg_ty.kind() { - if let ty::Ref(_, innermost, _) = inner.kind() { - span_lint_and_then( - cx, - CLONE_DOUBLE_REF, - expr.span, - &with_forced_trimmed_paths!(format!( - "using `clone` on a double-reference; \ - this will copy the reference of type `{ty}` instead of cloning the inner type" - )), - |diag| { - if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { - let mut ty = innermost; - let mut n = 0; - while let ty::Ref(_, inner, _) = ty.kind() { - ty = inner; - n += 1; - } - let refs = "&".repeat(n + 1); - let derefs = "*".repeat(n); - let explicit = with_forced_trimmed_paths!(format!("<{refs}{ty}>::clone({snip})")); - diag.span_suggestion( - expr.span, - "try dereferencing it", - with_forced_trimmed_paths!(format!("{refs}({derefs}{}).clone()", snip.deref())), - Applicability::MaybeIncorrect, - ); - diag.span_suggestion( - expr.span, - "or try being explicit if you are sure, that you want to clone a reference", - explicit, - Applicability::MaybeIncorrect, - ); - } - }, - ); + if let ty::Ref(..) = inner.kind() { return; // don't report clone_on_copy } } diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs b/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs index 83c1bf20346..e2029da8081 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, cal if let hir::ExprKind::Index(caller_var, index_expr) = &caller_expr.kind; if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen }) = higher::Range::hir(index_expr); - if let hir::ExprKind::Lit(ref start_lit) = &start_expr.kind; + if let hir::ExprKind::Lit(start_lit) = &start_expr.kind; if let ast::LitKind::Int(start_idx, _) = start_lit.node; then { let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 9cafbc2e5f5..06b88e34d24 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -986,29 +986,6 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usage of `.clone()` on an `&&T`. - /// - /// ### Why is this bad? - /// Cloning an `&&T` copies the inner `&T`, instead of - /// cloning the underlying `T`. - /// - /// ### Example - /// ```rust - /// fn main() { - /// let x = vec![1]; - /// let y = &&x; - /// let z = y.clone(); - /// println!("{:p} {:p}", *y, z); // prints out the same pointer - /// } - /// ``` - #[clippy::version = "pre 1.29.0"] - pub CLONE_DOUBLE_REF, - correctness, - "using `clone` on `&&T`" -} - -declare_clippy_lint! { - /// ### What it does /// Checks for usage of `.to_string()` on an `&&T` where /// `T` implements `ToString` directly (like `&&str` or `&&String`). /// @@ -3258,7 +3235,6 @@ impl_lint_pass!(Methods => [ CHARS_LAST_CMP, CLONE_ON_COPY, CLONE_ON_REF_PTR, - CLONE_DOUBLE_REF, COLLAPSIBLE_STR_REPLACE, ITER_OVEREAGER_CLONED, CLONED_INSTEAD_OF_COPIED, @@ -3500,8 +3476,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let first_arg_span = first_arg_ty.span; let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty); let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()) - .self_ty() - .skip_binder(); + .self_ty(); wrong_self_convention::check( cx, item.ident.name.as_str(), @@ -3519,8 +3494,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if let TraitItemKind::Fn(_, _) = item.kind; let ret_ty = return_ty(cx, item.owner_id); let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()) - .self_ty() - .skip_binder(); + .self_ty(); if !ret_ty.contains(self_ty); then { diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs index 23d23f25f14..bd625a6914c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs @@ -42,11 +42,11 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec // Only proceed if this is a call on some object of type std::fs::OpenOptions if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && !arguments.is_empty() { let argument_option = match arguments[0].kind { - ExprKind::Lit(ref span) => { + ExprKind::Lit(span) => { if let Spanned { node: LitKind::Bool(lit), .. - } = *span + } = span { if *lit { Argument::True } else { Argument::False } } else { diff --git a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs index e3f2de3cd46..0284d9dea30 100644 --- a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs +++ b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs @@ -15,7 +15,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::PathBuf); - if let ExprKind::Lit(ref lit) = arg.kind; + if let ExprKind::Lit(lit) = arg.kind; if let LitKind::Str(ref path_lit, _) = lit.node; if let pushed_path = Path::new(path_lit.as_str()); if let Some(pushed_path_lit) = pushed_path.to_str(); diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs index 361a3082f94..c028e954381 100644 --- a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs +++ b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs @@ -38,7 +38,7 @@ fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) match_def_path(cx, def_id, &paths::STD_IO_SEEK_FROM_CURRENT) { // check if argument of `SeekFrom::Current` is `0` if args.len() == 1 && - let ExprKind::Lit(ref lit) = args[0].kind && + let ExprKind::Lit(lit) = args[0].kind && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node { return true } diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs index 660b7049cce..787e9e0ebd2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs +++ b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>( let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id() && match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START) && args1.len() == 1 && - let ExprKind::Lit(ref lit) = args1[0].kind && + let ExprKind::Lit(lit) = args1[0].kind && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node { let method_call_span = expr.span.with_lo(name_span.lo()); diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs index d00708e828e..91f7ce1dbe5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs +++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs @@ -175,13 +175,13 @@ fn check_manual_split_once_indirect( let remove_msg = format!("remove the `{iter_ident}` usages"); diag.span_suggestion( first.span, - &remove_msg, + remove_msg.clone(), "", app, ); diag.span_suggestion( second.span, - &remove_msg, + remove_msg, "", app, ); diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs index aa87dead38f..5a3d12fd790 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs @@ -78,7 +78,7 @@ pub(super) fn check( } // Check if the first argument to .fold is a suitable literal - if let hir::ExprKind::Lit(ref lit) = init.kind { + if let hir::ExprKind::Lit(lit) = init.kind { match lit.node { ast::LitKind::Bool(false) => check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, "any", true), ast::LitKind::Bool(true) => check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, "all", true), diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 4c4c003ca46..67b7d3691dc 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -385,6 +385,9 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< Node::Expr(parent_expr) => { if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr) { + // FIXME: the `subst_identity()` below seems incorrect, since we eventually + // call `tcx.try_subst_and_normalize_erasing_regions` further down + // (i.e., we are explicitly not in the identity context). let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder(); if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id) && let Some(param_ty) = fn_sig.inputs().get(arg_index) @@ -435,7 +438,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< let output_ty = fn_sig.output(); if output_ty.contains(*param_ty) { if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions( - new_subst, cx.param_env, output_ty) { + new_subst, cx.param_env, EarlyBinder(output_ty)) { expr = parent_expr; ty = new_ty; continue; diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs index e99081ad062..1adecd2caac 100644 --- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs +++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs @@ -12,7 +12,7 @@ declare_clippy_lint! { /// Checks if a provided method is used implicitly by a trait /// implementation. A usage example would be a wrapper where every method /// should perform some operation before delegating to the inner type's - /// implemenation. + /// implementation. /// /// This lint should typically be enabled on a specific trait `impl` item /// rather than globally. diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs index c87059bf61d..71281a0b40b 100644 --- a/src/tools/clippy/clippy_lints/src/needless_bool.rs +++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs @@ -3,10 +3,12 @@ //! This lint is **warn** by default use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; -use clippy_utils::higher; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; -use clippy_utils::{get_parent_node, is_else_clause, is_expn_of, peel_blocks, peel_blocks_with_stmt}; +use clippy_utils::{ + get_parent_node, is_else_clause, is_expn_of, peel_blocks, peel_blocks_with_stmt, span_extract_comment, +}; +use clippy_utils::{higher, SpanlessEq}; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Node, UnOp}; @@ -77,7 +79,39 @@ declare_clippy_lint! { "comparing a variable to a boolean, e.g., `if x == true` or `if x != true`" } -declare_lint_pass!(NeedlessBool => [NEEDLESS_BOOL]); +declare_clippy_lint! { + /// ### What it does + /// Checks for expressions of the form `if c { x = true } else { x = false }` + /// (or vice versa) and suggest assigning the variable directly from the + /// condition. + /// + /// ### Why is this bad? + /// Redundant code. + /// + /// ### Example + /// ```rust,ignore + /// # fn must_keep(x: i32, y: i32) -> bool { x == y } + /// # let x = 32; let y = 10; + /// # let mut skip: bool; + /// if must_keep(x, y) { + /// skip = false; + /// } else { + /// skip = true; + /// } + /// ``` + /// Use instead: + /// ```rust,ignore + /// # fn must_keep(x: i32, y: i32) -> bool { x == y } + /// # let x = 32; let y = 10; + /// # let mut skip: bool; + /// skip = !must_keep(x, y); + /// ``` + #[clippy::version = "1.69.0"] + pub NEEDLESS_BOOL_ASSIGN, + complexity, + "setting the same boolean variable in both branches of an if-statement" +} +declare_lint_pass!(NeedlessBool => [NEEDLESS_BOOL, NEEDLESS_BOOL_ASSIGN]); fn condition_needs_parentheses(e: &Expr<'_>) -> bool { let mut inner = e; @@ -173,6 +207,29 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool { _ => (), } } + if let Some((lhs_a, a)) = fetch_assign(then) && + let Some((lhs_b, b)) = fetch_assign(r#else) && + SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) && + span_extract_comment(cx.tcx.sess.source_map(), e.span).is_empty() + { + let mut applicability = Applicability::MachineApplicable; + let cond = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability); + let lhs = snippet_with_applicability(cx, lhs_a.span, "..", &mut applicability); + let sugg = if a == b { + format!("{cond}; {lhs} = {a:?};") + } else { + format!("{lhs} = {};", if a { cond } else { !cond }) + }; + span_lint_and_sugg( + cx, + NEEDLESS_BOOL_ASSIGN, + e.span, + "this if-then-else expression assigns a bool literal", + "you can reduce it to", + sugg, + applicability + ); + } } } } @@ -369,10 +426,18 @@ fn fetch_bool_block(expr: &Expr<'_>) -> Option<Expression> { } fn fetch_bool_expr(expr: &Expr<'_>) -> Option<bool> { - if let ExprKind::Lit(ref lit_ptr) = peel_blocks(expr).kind { + if let ExprKind::Lit(lit_ptr) = peel_blocks(expr).kind { if let LitKind::Bool(value) = lit_ptr.node { return Some(value); } } None } + +fn fetch_assign<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, bool)> { + if let ExprKind::Assign(lhs, rhs, _) = peel_blocks_with_stmt(expr).kind { + fetch_bool_expr(rhs).map(|b| (lhs, b)) + } else { + None + } +} diff --git a/src/tools/clippy/clippy_lints/src/needless_parens_on_range_literals.rs b/src/tools/clippy/clippy_lints/src/needless_parens_on_range_literals.rs index 6e54b243c03..da1b9d99931 100644 --- a/src/tools/clippy/clippy_lints/src/needless_parens_on_range_literals.rs +++ b/src/tools/clippy/clippy_lints/src/needless_parens_on_range_literals.rs @@ -49,14 +49,14 @@ fn snippet_enclosed_in_parenthesis(snippet: &str) -> bool { fn check_for_parens(cx: &LateContext<'_>, e: &Expr<'_>, is_start: bool) { if is_start && - let ExprKind::Lit(ref literal) = e.kind && + let ExprKind::Lit(literal) = e.kind && let ast::LitKind::Float(_sym, ast::LitFloatType::Unsuffixed) = literal.node { // don't check floating point literals on the start expression of a range return; } if_chain! { - if let ExprKind::Lit(ref literal) = e.kind; + if let ExprKind::Lit(literal) = e.kind; // the indicator that parenthesis surround the literal is that the span of the expression and the literal differ if (literal.span.data().hi - literal.span.data().lo) != (e.span.data().hi - e.span.data().lo); // inspect the source code of the expression for parenthesis diff --git a/src/tools/clippy/clippy_lints/src/neg_multiply.rs b/src/tools/clippy/clippy_lints/src/neg_multiply.rs index ed3e2c6e7f4..db0e22842d1 100644 --- a/src/tools/clippy/clippy_lints/src/neg_multiply.rs +++ b/src/tools/clippy/clippy_lints/src/neg_multiply.rs @@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for NegMultiply { fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { if_chain! { - if let ExprKind::Lit(ref l) = lit.kind; + if let ExprKind::Lit(l) = lit.kind; if consts::lit_to_mir_constant(&l.node, cx.typeck_results().expr_ty_opt(lit)) == Constant::Int(1); if cx.typeck_results().expr_ty(exp).is_integral(); diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index 839c3a3815c..7eaa7db78a4 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -131,13 +131,13 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { for field in non_send_fields { diag.span_note( field.def.span, - &format!("it is not safe to send field `{}` to another thread", field.def.ident.name), + format!("it is not safe to send field `{}` to another thread", field.def.ident.name), ); match field.generic_params.len() { 0 => diag.help("use a thread-safe type that implements `Send`"), - 1 if is_ty_param(field.ty) => diag.help(&format!("add `{}: Send` bound in `Send` impl", field.ty)), - _ => diag.help(&format!( + 1 if is_ty_param(field.ty) => diag.help(format!("add `{}: Send` bound in `Send` impl", field.ty)), + _ => diag.help(format!( "add bounds on type parameter{} `{}` that satisfy `{}: Send`", if field.generic_params.len() > 1 { "s" } else { "" }, field.generic_params_string(), diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs index fafcf257094..f72595987ee 100644 --- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -110,7 +110,7 @@ impl ArithmeticSideEffects { /// like `i32::MAX` or constant references like `N` from `const N: i32 = 1;`, fn literal_integer(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<u128> { let actual = peel_hir_expr_unary(expr).0; - if let hir::ExprKind::Lit(ref lit) = actual.kind && let ast::LitKind::Int(n, _) = lit.node { + if let hir::ExprKind::Lit(lit) = actual.kind && let ast::LitKind::Int(n, _) = lit.node { return Some(n) } if let Some((Constant::Int(n), _)) = constant(cx, cx.typeck_results(), expr) { diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs index 9e6c6c73d4f..b8b32df6cc6 100644 --- a/src/tools/clippy/clippy_lints/src/regex.rs +++ b/src/tools/clippy/clippy_lints/src/regex.rs @@ -180,7 +180,7 @@ fn check_regex<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) { .allow_invalid_utf8(!utf8) .build(); - if let ExprKind::Lit(ref lit) = expr.kind { + if let ExprKind::Lit(lit) = expr.kind { if let LitKind::Str(ref r, style) = lit.node { let r = r.as_str(); let offset = if let StrStyle::Raw(n) = style { 2 + n } else { 1 }; diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs index 9f487dedb8c..5e81a01a461 100644 --- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs +++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs @@ -30,6 +30,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::stutter", "clippy::module_name_repetitions"), ("clippy::to_string_in_display", "clippy::recursive_format_impl"), ("clippy::zero_width_space", "clippy::invisible_characters"), + ("clippy::clone_double_ref", "suspicious_double_ref_op"), ("clippy::drop_bounds", "drop_bounds"), ("clippy::for_loop_over_option", "for_loops_over_fallibles"), ("clippy::for_loop_over_result", "for_loops_over_fallibles"), diff --git a/src/tools/clippy/clippy_lints/src/semicolon_block.rs b/src/tools/clippy/clippy_lints/src/semicolon_block.rs index 34a3e5ddf4f..419d7991f0e 100644 --- a/src/tools/clippy/clippy_lints/src/semicolon_block.rs +++ b/src/tools/clippy/clippy_lints/src/semicolon_block.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and use rustc_errors::Applicability; use rustc_hir::{Block, Expr, ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Span; declare_clippy_lint! { @@ -64,7 +64,78 @@ declare_clippy_lint! { restriction, "add a semicolon outside the block" } -declare_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK]); +impl_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK]); + +#[derive(Copy, Clone)] +pub struct SemicolonBlock { + semicolon_inside_block_ignore_singleline: bool, + semicolon_outside_block_ignore_multiline: bool, +} + +impl SemicolonBlock { + pub fn new(semicolon_inside_block_ignore_singleline: bool, semicolon_outside_block_ignore_multiline: bool) -> Self { + Self { + semicolon_inside_block_ignore_singleline, + semicolon_outside_block_ignore_multiline, + } + } + + fn semicolon_inside_block(self, cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<'_>, semi_span: Span) { + let insert_span = tail.span.source_callsite().shrink_to_hi(); + let remove_span = semi_span.with_lo(block.span.hi()); + + if self.semicolon_inside_block_ignore_singleline && get_line(cx, remove_span) == get_line(cx, insert_span) { + return; + } + + span_lint_and_then( + cx, + SEMICOLON_INSIDE_BLOCK, + semi_span, + "consider moving the `;` inside the block for consistent formatting", + |diag| { + multispan_sugg_with_applicability( + diag, + "put the `;` here", + Applicability::MachineApplicable, + [(remove_span, String::new()), (insert_span, ";".to_owned())], + ); + }, + ); + } + + fn semicolon_outside_block( + self, + cx: &LateContext<'_>, + block: &Block<'_>, + tail_stmt_expr: &Expr<'_>, + semi_span: Span, + ) { + let insert_span = block.span.with_lo(block.span.hi()); + // account for macro calls + let semi_span = cx.sess().source_map().stmt_span(semi_span, block.span); + let remove_span = semi_span.with_lo(tail_stmt_expr.span.source_callsite().hi()); + + if self.semicolon_outside_block_ignore_multiline && get_line(cx, remove_span) != get_line(cx, insert_span) { + return; + } + + span_lint_and_then( + cx, + SEMICOLON_OUTSIDE_BLOCK, + block.span, + "consider moving the `;` outside the block for consistent formatting", + |diag| { + multispan_sugg_with_applicability( + diag, + "put the `;` here", + Applicability::MachineApplicable, + [(remove_span, String::new()), (insert_span, ";".to_owned())], + ); + }, + ); + } +} impl LateLintPass<'_> for SemicolonBlock { fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) { @@ -83,55 +154,23 @@ impl LateLintPass<'_> for SemicolonBlock { span, .. } = stmt else { return }; - semicolon_outside_block(cx, block, expr, span); + self.semicolon_outside_block(cx, block, expr, span); }, StmtKind::Semi(Expr { kind: ExprKind::Block(block @ Block { expr: Some(tail), .. }, _), .. - }) if !block.span.from_expansion() => semicolon_inside_block(cx, block, tail, stmt.span), + }) if !block.span.from_expansion() => { + self.semicolon_inside_block(cx, block, tail, stmt.span); + }, _ => (), } } } -fn semicolon_inside_block(cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<'_>, semi_span: Span) { - let insert_span = tail.span.source_callsite().shrink_to_hi(); - let remove_span = semi_span.with_lo(block.span.hi()); - - span_lint_and_then( - cx, - SEMICOLON_INSIDE_BLOCK, - semi_span, - "consider moving the `;` inside the block for consistent formatting", - |diag| { - multispan_sugg_with_applicability( - diag, - "put the `;` here", - Applicability::MachineApplicable, - [(remove_span, String::new()), (insert_span, ";".to_owned())], - ); - }, - ); -} - -fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_expr: &Expr<'_>, semi_span: Span) { - let insert_span = block.span.with_lo(block.span.hi()); - // account for macro calls - let semi_span = cx.sess().source_map().stmt_span(semi_span, block.span); - let remove_span = semi_span.with_lo(tail_stmt_expr.span.source_callsite().hi()); +fn get_line(cx: &LateContext<'_>, span: Span) -> Option<usize> { + if let Ok(line) = cx.sess().source_map().lookup_line(span.lo()) { + return Some(line.line); + } - span_lint_and_then( - cx, - SEMICOLON_OUTSIDE_BLOCK, - block.span, - "consider moving the `;` outside the block for consistent formatting", - |diag| { - multispan_sugg_with_applicability( - diag, - "put the `;` here", - Applicability::MachineApplicable, - [(remove_span, String::new()), (insert_span, ";".to_owned())], - ); - }, - ); + None } diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index ae7d19624ba..993f9373d85 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { let PatKind::Binding(_, id, ident, _) = pat.kind else { return }; - if pat.span.desugaring_kind().is_some() { + if pat.span.desugaring_kind().is_some() || pat.span.from_expansion() { return; } diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs index a2109038a05..858135c8d46 100644 --- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs +++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs @@ -74,7 +74,7 @@ enum InitializationType<'tcx> { impl<'tcx> LateLintPass<'tcx> for SlowVectorInit { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - // Matches initialization on reassignements. For example: `vec = Vec::with_capacity(100)` + // Matches initialization on reassignments. For example: `vec = Vec::with_capacity(100)` if_chain! { if let ExprKind::Assign(left, right, _) = expr.kind; diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index b2f4b310915..5b588e914fd 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -292,6 +292,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { } if_chain! { + if !in_external_macro(cx.sess(), e.span); if let ExprKind::MethodCall(path, receiver, ..) = &e.kind; if path.ident.name == sym!(as_bytes); if let ExprKind::Lit(lit) = &receiver.kind; diff --git a/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs b/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs index 03324c66e8e..2f2e84fa35a 100644 --- a/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs +++ b/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_context; -use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::visitors::is_expr_unsafe; use clippy_utils::{get_parent_node, match_libc_symbol}; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, Node, UnsafeSource}; +use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, LangItem, Node, UnsafeSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; @@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings { let val_name = snippet_with_context(cx, self_arg.span, ctxt, "..", &mut app).0; let method_name = if is_type_diagnostic_item(cx, ty, sym::cstring_type) { "as_bytes" - } else if is_type_diagnostic_item(cx, ty, sym::CStr) { + } else if is_type_lang_item(cx, ty, LangItem::CStr) { "to_bytes" } else { return; diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index 98f5b47f7a0..bb9da3a2047 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -60,7 +60,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_ if let Some(last_field) = data.fields().last(); if let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind; - // Then check if that that array zero-sized + // Then check if that array is zero-sized let length = Const::from_anon_const(cx.tcx, length.def_id); let length = length.try_eval_target_usize(cx.tcx, cx.param_env); if let Some(length) = length; diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index c6834a8fdaa..3c873a5901d 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -90,8 +90,8 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// `Option<_>` represents an optional value. `Option<Option<_>>` - /// represents an optional optional value which is logically the same thing as an optional - /// value but has an unneeded extra level of wrapping. + /// represents an optional value which itself wraps an optional. This is logically the + /// same thing as an optional value but has an unneeded extra level of wrapping. /// /// If you have a case where `Some(Some(_))`, `Some(None)` and `None` are distinct cases, /// consider a custom `enum` instead, with clear names for each case. diff --git a/src/tools/clippy/clippy_lints/src/unicode.rs b/src/tools/clippy/clippy_lints/src/unicode.rs index 8980283e5c8..e275bfd37b0 100644 --- a/src/tools/clippy/clippy_lints/src/unicode.rs +++ b/src/tools/clippy/clippy_lints/src/unicode.rs @@ -76,7 +76,7 @@ declare_lint_pass!(Unicode => [INVISIBLE_CHARACTERS, NON_ASCII_LITERAL, UNICODE_ impl LateLintPass<'_> for Unicode { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) { - if let ExprKind::Lit(ref lit) = expr.kind { + if let ExprKind::Lit(lit) = expr.kind { if let LitKind::Str(_, _) | LitKind::Char(_) = lit.node { check_str(cx, lit.span, expr.hir_id); } diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs index af1c8d83b4f..e7449639f3a 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs @@ -109,7 +109,7 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns { fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) { // Ignore implementations of traits, because the lint should be on the - // trait, not on the implmentation of it. + // trait, not on the implementation of it. let Node::Item(parent) = cx.tcx.hir().get_parent(item.hir_id()) else { return }; let ItemKind::Impl(parent) = parent.kind else { return }; if parent.of_trait.is_some() { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 01927b6b5f1..935ea90d245 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -304,6 +304,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("ByteStr(ref {vec})"); chain!(self, "let [{:?}] = **{vec}", vec.value); }, + LitKind::CStr(ref vec, _) => { + bind!(self, vec); + kind!("CStr(ref {vec})"); + chain!(self, "let [{:?}] = **{vec}", vec.value); + } LitKind::Str(s, _) => { bind!(self, s); kind!("Str({s}, _)"); @@ -333,7 +338,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { #[allow(clippy::too_many_lines)] fn expr(&self, expr: &Binding<&hir::Expr<'_>>) { - if let Some(higher::While { condition, body }) = higher::While::hir(expr.value) { + if let Some(higher::While { condition, body, .. }) = higher::While::hir(expr.value) { bind!(self, condition, body); chain!( self, @@ -561,7 +566,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { ExprKind::OffsetOf(container, ref fields) => { bind!(self, container, fields); kind!("OffsetOf({container}, {fields})"); - } + }, ExprKind::Struct(qpath, fields, base) => { bind!(self, qpath, fields); opt_bind!(self, base); diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs index 67bb499c455..5f05d971fce 100644 --- a/src/tools/clippy/clippy_lints/src/utils/conf.rs +++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs @@ -277,6 +277,14 @@ define_Conf! { /// `".."` can be used as part of the list to indicate, that the configured values should be appended to the /// default configuration of Clippy. By default, any configuration will replace the default value. (disallowed_names: Vec<String> = super::DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()), + /// Lint: SEMICOLON_INSIDE_BLOCK. + /// + /// Whether to lint only if it's multiline. + (semicolon_inside_block_ignore_singleline: bool = false), + /// Lint: SEMICOLON_OUTSIDE_BLOCK. + /// + /// Whether to lint only if it's singleline. + (semicolon_outside_block_ignore_multiline: bool = false), /// Lint: DOC_MARKDOWN. /// /// The list of words this lint should not consider as identifiers needing ticks. The value diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml index 124ebd164e6..66a5079fa85 100644 --- a/src/tools/clippy/clippy_utils/Cargo.toml +++ b/src/tools/clippy/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.70" +version = "0.1.71" edition = "2021" publish = false diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index b4ad42a5027..49cb9718ef6 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -133,7 +133,7 @@ pub fn get_unique_attr<'a>( let mut unique_attr: Option<&ast::Attribute> = None; for attr in get_attr(sess, attrs, name) { if let Some(duplicate) = unique_attr { - sess.struct_span_err(attr.span, &format!("`{name}` is defined multiple times")) + sess.struct_span_err(attr.span, format!("`{name}` is defined multiple times")) .span_note(duplicate.span, "first definition found here") .emit(); } else { diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index d3a6929f67e..9edaae85373 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -117,7 +117,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) { ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat(tcx, e).1), ExprKind::Unary(UnOp::Not, e) => (Pat::Str("!"), expr_search_pat(tcx, e).1), ExprKind::Unary(UnOp::Neg, e) => (Pat::Str("-"), expr_search_pat(tcx, e).1), - ExprKind::Lit(ref lit) => lit_search_pat(&lit.node), + ExprKind::Lit(lit) => lit_search_pat(&lit.node), ExprKind::Array(_) | ExprKind::Repeat(..) => (Pat::Str("["), Pat::Str("]")), ExprKind::Call(e, []) | ExprKind::MethodCall(_, e, [], _) => (expr_search_pat(tcx, e).0, Pat::Str("(")), ExprKind::Call(first, [.., last]) diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 99bfc4b5717..8075881e3bb 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -211,6 +211,7 @@ pub fn lit_to_mir_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant { LitKind::Str(ref is, _) => Constant::Str(is.to_string()), LitKind::Byte(b) => Constant::Int(u128::from(b)), LitKind::ByteStr(ref s, _) => Constant::Binary(Lrc::clone(s)), + LitKind::CStr(ref s, _) => Constant::Binary(Lrc::clone(s)), LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { @@ -324,7 +325,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { match e.kind { ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id, self.typeck_results.expr_ty(e)), ExprKind::Block(block, _) => self.block(block), - ExprKind::Lit(ref lit) => { + ExprKind::Lit(lit) => { if is_direct_expn_of(e.span, "cfg").is_some() { None } else { diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index 50bef370930..a61e4c38088 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -311,6 +311,8 @@ pub struct While<'hir> { pub condition: &'hir Expr<'hir>, /// `while` loop body pub body: &'hir Expr<'hir>, + /// Span of the loop header + pub span: Span, } impl<'hir> While<'hir> { @@ -336,10 +338,10 @@ impl<'hir> While<'hir> { }, _, LoopSource::While, - _, + span, ) = expr.kind { - return Some(Self { condition, body }); + return Some(Self { condition, body, span }); } None } diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index d972ed82c25..9b7408d5133 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -301,7 +301,7 @@ impl HirEqInterExpr<'_, '_, '_> { (&ExprKind::Unary(l_op, le), &ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re), (&ExprKind::Array(l), &ExprKind::Array(r)) => self.eq_exprs(l, r), (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re), - (&ExprKind::OffsetOf(l_container, ref l_fields), &ExprKind::OffsetOf(r_container, ref r_fields)) => { + (&ExprKind::OffsetOf(l_container, l_fields), &ExprKind::OffsetOf(r_container, r_fields)) => { self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name) }, _ => false, @@ -718,7 +718,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_pat(pat); }, ExprKind::Err(_) => {}, - ExprKind::Lit(ref l) => { + ExprKind::Lit(l) => { l.node.hash(&mut self.s); }, ExprKind::Loop(b, ref i, ..) => { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 6b677df4641..964104fc31d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -86,10 +86,10 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet}; use rustc_hir::intravisit::{walk_expr, FnKind, Visitor}; use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk}; use rustc_hir::{ - self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination, - Expr, ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, Item, ItemKind, LangItem, Local, + self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr, + ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, Item, ItemKind, LangItem, Local, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, - TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, + TraitItem, TraitItemRef, TraitRef, TyKind, UnOp, }; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::{LateContext, Level, Lint, LintContext}; @@ -197,31 +197,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option< /// } /// ``` pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool { - let parent_id = cx.tcx.hir().get_parent_item(id).def_id; - match cx.tcx.hir().get_by_def_id(parent_id) { - Node::Item(&Item { - kind: ItemKind::Const(..) | ItemKind::Static(..) | ItemKind::Enum(..), - .. - }) - | Node::TraitItem(&TraitItem { - kind: TraitItemKind::Const(..), - .. - }) - | Node::ImplItem(&ImplItem { - kind: ImplItemKind::Const(..), - .. - }) - | Node::AnonConst(_) => true, - Node::Item(&Item { - kind: ItemKind::Fn(ref sig, ..), - .. - }) - | Node::ImplItem(&ImplItem { - kind: ImplItemKind::Fn(ref sig, _), - .. - }) => sig.header.constness == Constness::Const, - _ => false, - } + cx.tcx.hir().is_inside_const_context(id) } /// Checks if a `Res` refers to a constructor of a `LangItem` @@ -846,7 +822,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { }, ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)), ExprKind::Repeat(x, ArrayLen::Body(len)) => if_chain! { - if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind; + if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind; if let LitKind::Int(v, _) = const_lit.node; if v <= 32 && is_default_equivalent(cx, x); then { @@ -875,7 +851,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: & }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String), ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec), ExprKind::Repeat(_, ArrayLen::Body(len)) => { - if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind && + if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind && let LitKind::Int(v, _) = const_lit.node { return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec); @@ -1569,7 +1545,7 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool /// Checks whether the given expression is a constant literal of the given value. pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool { // FIXME: use constant folding - if let ExprKind::Lit(ref spanned) = expr.kind { + if let ExprKind::Lit(spanned) = expr.kind { if let LitKind::Int(v, _) = spanned.node { return v == value; } @@ -2165,10 +2141,7 @@ pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool { .predicates .iter() .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); - traits::impossible_predicates( - cx.tcx, - traits::elaborate(cx.tcx, predicates).collect::<Vec<_>>(), - ) + traits::impossible_predicates(cx.tcx, traits::elaborate(cx.tcx, predicates).collect::<Vec<_>>()) } /// Returns the `DefId` of the callee if the given expression is a function or method call. @@ -2233,8 +2206,12 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<S None } -/// returns list of all pairs (a, b) from `exprs` such that `eq(a, b)` -/// `hash` must be comformed with `eq` +/// Returns list of all pairs `(a, b)` where `eq(a, b) == true` +/// and `a` is before `b` in `exprs` for all `a` and `b` in +/// `exprs` +/// +/// Given functions `eq` and `hash` such that `eq(a, b) == true` +/// implies `hash(a) == hash(b)` pub fn search_same<T, Hash, Eq>(exprs: &[T], hash: Hash, eq: Eq) -> Vec<(&T, &T)> where Hash: Fn(&T) -> u64, diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs index 62d388a5ece..e4a4936ff42 100644 --- a/src/tools/clippy/clippy_utils/src/macros.rs +++ b/src/tools/clippy/clippy_utils/src/macros.rs @@ -362,7 +362,7 @@ thread_local! { /// able to access the many features of a [`LateContext`]. /// /// A thread local is used because [`FormatArgs`] is `!Send` and `!Sync`, we are making an - /// assumption that the early pass the populates the map and the later late passes will all be + /// assumption that the early pass that populates the map and the later late passes will all be /// running on the same thread. static AST_FORMAT_ARGS: RefCell<FxHashMap<Span, FormatArgs>> = { static CALLED: AtomicBool = AtomicBool::new(false); diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index 9be2d0eae80..0f0792fdaa9 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -159,3 +159,7 @@ pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"]; pub const PTR_NON_NULL: [&str; 4] = ["core", "ptr", "non_null", "NonNull"]; pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"]; pub const INSTANT: [&str; 3] = ["std", "time", "Instant"]; +pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"]; +pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"]; +pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"]; +pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"]; diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index ecd712f32dc..c0d2c835d63 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -194,7 +194,9 @@ fn check_rvalue<'tcx>( )) } }, - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()), + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => { + Ok(()) + }, Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, tcx); if ty.is_integral() || ty.is_bool() { diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index e81eadceec0..14f7f03016f 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -162,8 +162,9 @@ impl<'a> Sugg<'a> { get_snippet(lhs.span), get_snippet(rhs.span), ), - hir::ExprKind::Cast(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)), - hir::ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::Colon, get_snippet(lhs.span), get_snippet(ty.span)), + hir::ExprKind::Cast(lhs, ty) | + //FIXME(chenyukang), remove this after type ascription is removed from AST + hir::ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)), } } @@ -253,13 +254,10 @@ impl<'a> Sugg<'a> { snippet_with_context(cx, lhs.span, ctxt, default, app).0, snippet_with_context(cx, rhs.span, ctxt, default, app).0, ), - ast::ExprKind::Cast(ref lhs, ref ty) => Sugg::BinOp( - AssocOp::As, - snippet_with_context(cx, lhs.span, ctxt, default, app).0, - snippet_with_context(cx, ty.span, ctxt, default, app).0, - ), + ast::ExprKind::Cast(ref lhs, ref ty) | + //FIXME(chenyukang), remove this after type ascription is removed from AST ast::ExprKind::Type(ref lhs, ref ty) => Sugg::BinOp( - AssocOp::Colon, + AssocOp::As, snippet_with_context(cx, lhs.span, ctxt, default, app).0, snippet_with_context(cx, ty.span, ctxt, default, app).0, ), @@ -392,7 +390,6 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String { AssocOp::As => format!("{lhs} as {rhs}"), AssocOp::DotDot => format!("{lhs}..{rhs}"), AssocOp::DotDotEq => format!("{lhs}..={rhs}"), - AssocOp::Colon => format!("{lhs}: {rhs}"), } } @@ -602,13 +599,13 @@ enum Associativity { #[must_use] fn associativity(op: AssocOp) -> Associativity { use rustc_ast::util::parser::AssocOp::{ - Add, As, Assign, AssignOp, BitAnd, BitOr, BitXor, Colon, Divide, DotDot, DotDotEq, Equal, Greater, - GreaterEqual, LAnd, LOr, Less, LessEqual, Modulus, Multiply, NotEqual, ShiftLeft, ShiftRight, Subtract, + Add, As, Assign, AssignOp, BitAnd, BitOr, BitXor, Divide, DotDot, DotDotEq, Equal, Greater, GreaterEqual, LAnd, + LOr, Less, LessEqual, Modulus, Multiply, NotEqual, ShiftLeft, ShiftRight, Subtract, }; match op { Assign | AssignOp(_) => Associativity::Right, - Add | BitAnd | BitOr | BitXor | LAnd | LOr | Multiply | As | Colon => Associativity::Both, + Add | BitAnd | BitOr | BitXor | LAnd | LOr | Multiply | As => Associativity::Both, Divide | Equal | Greater | GreaterEqual | Less | LessEqual | Modulus | NotEqual | ShiftLeft | ShiftRight | Subtract => Associativity::Left, DotDot | DotDotEq => Associativity::None, diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index a6572011644..7b4ed77e8ed 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -93,7 +93,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { match predicate.kind().skip_binder() { // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through - // and check substituions to find `U`. + // and check substitutions to find `U`. ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { if trait_predicate .trait_ref @@ -837,7 +837,7 @@ pub fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { if let ty::Adt(adt, _) = ty.kind() && let &[krate, .., name] = &*cx.get_def_path(adt.did()) && let sym::libc | sym::core | sym::std = krate - && name.as_str() == "c_void" + && name == rustc_span::sym::c_void { true } else { @@ -1101,7 +1101,7 @@ pub fn make_projection<'tcx>( /// /// This function is for associated types which are "known" to be valid with the given /// substitutions, and as such, will only return `None` when debug assertions are disabled in order -/// to prevent ICE's. With debug assertions enabled this will check that that type normalization +/// to prevent ICE's. With debug assertions enabled this will check that type normalization /// succeeds as well as everything checked by `make_projection`. pub fn make_normalized_projection<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml index bd26f4fc913..139102798c4 100644 --- a/src/tools/clippy/declare_clippy_lint/Cargo.toml +++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.70" +version = "0.1.71" edition = "2021" publish = false diff --git a/src/tools/clippy/lintcheck/README.md b/src/tools/clippy/lintcheck/README.md index faf3ce9093a..37cc0453809 100644 --- a/src/tools/clippy/lintcheck/README.md +++ b/src/tools/clippy/lintcheck/README.md @@ -79,9 +79,11 @@ is explicitly specified in the options. ### Fix mode You can run `cargo lintcheck --fix` which will run Clippy with `--fix` and -print a warning if Clippy's suggestions fail to apply (if the resulting code does not build). +print a warning if Clippy's suggestions fail to apply (if the resulting code does not build). This lets us spot bad suggestions or false positives automatically in some cases. +> Note: Fix mode implies `--all-targets`, so it can fix as much code as it can. + Please note that the target dir should be cleaned afterwards since clippy will modify the downloaded sources which can lead to unexpected results when running lintcheck again afterwards. diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs index 23c85298027..03d1877d6c6 100644 --- a/src/tools/clippy/lintcheck/src/main.rs +++ b/src/tools/clippy/lintcheck/src/main.rs @@ -421,7 +421,7 @@ impl Crate { { let subcrate = &stderr[63..]; println!( - "ERROR: failed to apply some suggetion to {} / to (sub)crate {subcrate}", + "ERROR: failed to apply some suggestion to {} / to (sub)crate {subcrate}", self.name ); } diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain index 91e8ccea1f4..60b8a5ac071 100644 --- a/src/tools/clippy/rust-toolchain +++ b/src/tools/clippy/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-04-06" +channel = "nightly-2023-05-05" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 205905d5091..59bf447a7cd 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -11,7 +11,6 @@ // FIXME: switch to something more ergonomic here, once available. // (Currently there is no way to opt into sysroot crates without `extern crate`.) extern crate rustc_driver; -extern crate rustc_errors; extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; @@ -20,13 +19,10 @@ use rustc_interface::interface; use rustc_session::parse::ParseSess; use rustc_span::symbol::Symbol; -use std::borrow::Cow; use std::env; use std::ops::Deref; -use std::panic; use std::path::Path; use std::process::exit; -use std::sync::LazyLock; /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`. @@ -198,66 +194,18 @@ You can use tool lints to allow or deny lints from your code, eg.: const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new"; -type PanicCallback = dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static; -static ICE_HOOK: LazyLock<Box<PanicCallback>> = LazyLock::new(|| { - let hook = panic::take_hook(); - panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL))); - hook -}); - -fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { - // Invoke our ICE handler, which prints the actual panic message and optionally a backtrace - (*ICE_HOOK)(info); - - // Separate the output with an empty line - eprintln!(); - - let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false); - let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( - rustc_errors::ColorConfig::Auto, - None, - None, - fallback_bundle, - false, - false, - None, - false, - false, - rustc_errors::TerminalUrl::No, - )); - let handler = rustc_errors::Handler::with_emitter(true, None, emitter); - - // a .span_bug or .bug call has already printed what - // it wants to print. - if !info.payload().is::<rustc_errors::ExplicitBug>() { - let mut d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic"); - handler.emit_diagnostic(&mut d); - } - - let version_info = rustc_tools_util::get_version_info!(); - - let xs: Vec<Cow<'static, str>> = vec![ - "the compiler unexpectedly panicked. this is a bug.".into(), - format!("we would appreciate a bug report: {bug_report_url}").into(), - format!("Clippy version: {version_info}").into(), - ]; - - for note in &xs { - handler.note_without_error(note.as_ref()); - } - - // If backtraces are enabled, also print the query stack - let backtrace = env::var_os("RUST_BACKTRACE").map_or(false, |x| &x != "0"); - - let num_frames = if backtrace { None } else { Some(2) }; - - interface::try_print_query_stack(&handler, num_frames); -} - #[allow(clippy::too_many_lines)] pub fn main() { rustc_driver::init_rustc_env_logger(); - LazyLock::force(&ICE_HOOK); + + rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| { + // FIXME: this macro calls unwrap internally but is called in a panicking context! It's not + // as simple as moving the call from the hook to main, because `install_ice_hook` doesn't + // accept a generic closure. + let version_info = rustc_tools_util::get_version_info!(); + handler.note_without_error(format!("Clippy version: {version_info}")); + }); + exit(rustc_driver::catch_with_exit_code(move || { let mut orig_args: Vec<String> = env::args().collect(); let has_sysroot_arg = arg_value(&orig_args, "--sysroot", |_| true).is_some(); diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs index c5e9b96cf3f..188ff87abfc 100644 --- a/src/tools/clippy/src/main.rs +++ b/src/tools/clippy/src/main.rs @@ -13,7 +13,7 @@ Usage: Common options: --no-deps Run Clippy only on the given crate, without linting the dependencies - --fix Automatically apply lint suggestions. This flag implies `--no-deps` + --fix Automatically apply lint suggestions. This flag implies `--no-deps` and `--all-targets` -h, --help Print this message -V, --version Print version info and exit --explain LINT Print the documentation for a given lint diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs index 68a878e9a3d..afde31face1 100644 --- a/src/tools/clippy/tests/dogfood.rs +++ b/src/tools/clippy/tests/dogfood.rs @@ -39,7 +39,7 @@ fn dogfood_clippy() { assert!( failed_packages.is_empty(), "Dogfood failed for packages `{}`", - failed_packages.iter().format(", "), + failed_packages.iter().join(", "), ); } diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/both.fixed b/src/tools/clippy/tests/ui-toml/semicolon_block/both.fixed new file mode 100644 index 00000000000..fc8038a0907 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/both.fixed @@ -0,0 +1,86 @@ +//@run-rustfix +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_inside_block)] +#![warn(clippy::semicolon_outside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()) }; + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/both.rs b/src/tools/clippy/tests/ui-toml/semicolon_block/both.rs new file mode 100644 index 00000000000..52ce1f0387e --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/both.rs @@ -0,0 +1,86 @@ +//@run-rustfix +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_inside_block)] +#![warn(clippy::semicolon_outside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); } + unsafe { unit_fn_block(); } + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block() + }; + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()); } + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/both.stderr b/src/tools/clippy/tests/ui-toml/semicolon_block/both.stderr new file mode 100644 index 00000000000..2f58842eab0 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/both.stderr @@ -0,0 +1,55 @@ +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/both.rs:43:5 + | +LL | { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::semicolon-outside-block` implied by `-D warnings` +help: put the `;` here + | +LL - { unit_fn_block(); } +LL + { unit_fn_block() }; + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/both.rs:44:5 + | +LL | unsafe { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: put the `;` here + | +LL - unsafe { unit_fn_block(); } +LL + unsafe { unit_fn_block() }; + | + +error: consider moving the `;` inside the block for consistent formatting + --> $DIR/both.rs:49:5 + | +LL | / { +LL | | unit_fn_block(); +LL | | unit_fn_block() +LL | | }; + | |______^ + | + = note: `-D clippy::semicolon-inside-block` implied by `-D warnings` +help: put the `;` here + | +LL ~ unit_fn_block(); +LL ~ } + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/both.rs:63:5 + | +LL | { m!(()); } + | ^^^^^^^^^^^ + | +help: put the `;` here + | +LL - { m!(()); } +LL + { m!(()) }; + | + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/clippy.toml b/src/tools/clippy/tests/ui-toml/semicolon_block/clippy.toml new file mode 100644 index 00000000000..4d03e88deba --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/clippy.toml @@ -0,0 +1,2 @@ +semicolon-inside-block-ignore-singleline = true +semicolon-outside-block-ignore-multiline = true diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed new file mode 100644 index 00000000000..23df9830177 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed @@ -0,0 +1,85 @@ +//@run-rustfix +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_inside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); } + unsafe { unit_fn_block(); } + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()); } + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.rs b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.rs new file mode 100644 index 00000000000..e8516f79b20 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.rs @@ -0,0 +1,85 @@ +//@run-rustfix +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_inside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); } + unsafe { unit_fn_block(); } + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block() + }; + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()); } + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr new file mode 100644 index 00000000000..2569dc4b4e4 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr @@ -0,0 +1,18 @@ +error: consider moving the `;` inside the block for consistent formatting + --> $DIR/semicolon_inside_block.rs:48:5 + | +LL | / { +LL | | unit_fn_block(); +LL | | unit_fn_block() +LL | | }; + | |______^ + | + = note: `-D clippy::semicolon-inside-block` implied by `-D warnings` +help: put the `;` here + | +LL ~ unit_fn_block(); +LL ~ } + | + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed new file mode 100644 index 00000000000..7e9055e7110 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed @@ -0,0 +1,85 @@ +//@run-rustfix +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_outside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block() + }; + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()) }; + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.rs b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.rs new file mode 100644 index 00000000000..4dc956d8a4b --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.rs @@ -0,0 +1,85 @@ +//@run-rustfix +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_outside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); } + unsafe { unit_fn_block(); } + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block() + }; + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()); } + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr new file mode 100644 index 00000000000..6dd3577dd09 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr @@ -0,0 +1,39 @@ +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/semicolon_outside_block.rs:42:5 + | +LL | { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::semicolon-outside-block` implied by `-D warnings` +help: put the `;` here + | +LL - { unit_fn_block(); } +LL + { unit_fn_block() }; + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/semicolon_outside_block.rs:43:5 + | +LL | unsafe { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: put the `;` here + | +LL - unsafe { unit_fn_block(); } +LL + unsafe { unit_fn_block() }; + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/semicolon_outside_block.rs:62:5 + | +LL | { m!(()); } + | ^^^^^^^^^^^ + | +help: put the `;` here + | +LL - { m!(()); } +LL + { m!(()) }; + | + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 36b372b36f4..44710b09648 100644 --- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -37,6 +37,8 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie missing-docs-in-crate-items msrv pass-by-value-size-limit + semicolon-inside-block-ignore-singleline + semicolon-outside-block-ignore-multiline single-char-binding-names-threshold standard-macro-braces suppress-restriction-lint-in-const diff --git a/src/tools/clippy/tests/ui/allow_attributes_false_positive.rs b/src/tools/clippy/tests/ui/allow_attributes_false_positive.rs new file mode 100644 index 00000000000..5c3407628be --- /dev/null +++ b/src/tools/clippy/tests/ui/allow_attributes_false_positive.rs @@ -0,0 +1,5 @@ +#![warn(clippy::allow_attributes)] +#![feature(lint_reasons)] +#![crate_type = "proc-macro"] + +fn main() {} diff --git a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs index a9bb61451dc..e5bb906663c 100644 --- a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs +++ b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs @@ -22,6 +22,13 @@ macro_rules! string_add { } #[macro_export] +macro_rules! string_lit_as_bytes { + ($s:literal) => { + const C: &[u8] = $s.as_bytes(); + }; +} + +#[macro_export] macro_rules! mut_mut { () => { let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32; diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs index 92c47b41a38..d164dd0e545 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs @@ -82,7 +82,7 @@ pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStrea elided += 1; // HACK: Syn uses `Span` from the proc_macro2 crate, and does not seem to reexport it. - // In order to avoid adding the dependency, get a default span from a non-existent token. + // In order to avoid adding the dependency, get a default span from a nonexistent token. // A default span is needed to mark the code as coming from expansion. let span = Star::default().span(); diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed index 9831c3373d4..fbb10a133e2 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed @@ -1,6 +1,6 @@ //@run-rustfix -#![feature(let_chains)] +#![feature(let_chains, inline_const)] #![warn(clippy::bool_to_int_with_if)] #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] @@ -79,6 +79,13 @@ fn main() { pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 }; + // https://github.com/rust-lang/rust-clippy/issues/10452 + let should_not_lint = [(); if true { 1 } else { 0 }]; + + let should_not_lint = const { + if true { 1 } else { 0 } + }; + some_fn(a); } diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs index 5e3047bb32c..709a18d63e4 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs @@ -1,6 +1,6 @@ //@run-rustfix -#![feature(let_chains)] +#![feature(let_chains, inline_const)] #![warn(clippy::bool_to_int_with_if)] #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] @@ -111,6 +111,13 @@ fn main() { pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 }; + // https://github.com/rust-lang/rust-clippy/issues/10452 + let should_not_lint = [(); if true { 1 } else { 0 }]; + + let should_not_lint = const { + if true { 1 } else { 0 } + }; + some_fn(a); } diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr index 5cfb75cc0df..3bdae75cad2 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr @@ -98,7 +98,7 @@ LL | | }; = note: `!b as i32` or `(!b).into()` can also be valid options error: boolean to int conversion using if - --> $DIR/bool_to_int_with_if.rs:119:5 + --> $DIR/bool_to_int_with_if.rs:126:5 | LL | if a { 1 } else { 0 } | ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)` diff --git a/src/tools/clippy/tests/ui/box_default.fixed b/src/tools/clippy/tests/ui/box_default.fixed index 6afce208769..e6331290420 100644 --- a/src/tools/clippy/tests/ui/box_default.fixed +++ b/src/tools/clippy/tests/ui/box_default.fixed @@ -1,5 +1,6 @@ //@run-rustfix #![warn(clippy::box_default)] +#![allow(clippy::default_constructed_unit_structs)] #[derive(Default)] struct ImplementsDefault; diff --git a/src/tools/clippy/tests/ui/box_default.rs b/src/tools/clippy/tests/ui/box_default.rs index 09365618e63..34a05a29c5a 100644 --- a/src/tools/clippy/tests/ui/box_default.rs +++ b/src/tools/clippy/tests/ui/box_default.rs @@ -1,5 +1,6 @@ //@run-rustfix #![warn(clippy::box_default)] +#![allow(clippy::default_constructed_unit_structs)] #[derive(Default)] struct ImplementsDefault; diff --git a/src/tools/clippy/tests/ui/box_default.stderr b/src/tools/clippy/tests/ui/box_default.stderr index 78e17b9f035..c9834863601 100644 --- a/src/tools/clippy/tests/ui/box_default.stderr +++ b/src/tools/clippy/tests/ui/box_default.stderr @@ -1,5 +1,5 @@ error: `Box::new(_)` of default value - --> $DIR/box_default.rs:22:32 + --> $DIR/box_default.rs:23:32 | LL | let _string: Box<String> = Box::new(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` @@ -7,91 +7,91 @@ LL | let _string: Box<String> = Box::new(Default::default()); = note: `-D clippy::box-default` implied by `-D warnings` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:23:17 + --> $DIR/box_default.rs:24:17 | LL | let _byte = Box::new(u8::default()); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<u8>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:24:16 + --> $DIR/box_default.rs:25:16 | LL | let _vec = Box::new(Vec::<u8>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Vec<u8>>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:25:17 + --> $DIR/box_default.rs:26:17 | LL | let _impl = Box::new(ImplementsDefault::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:26:18 + --> $DIR/box_default.rs:27:18 | LL | let _impl2 = Box::new(<ImplementsDefault as Default>::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:27:42 + --> $DIR/box_default.rs:28:42 | LL | let _impl3: Box<ImplementsDefault> = Box::new(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:29:28 + --> $DIR/box_default.rs:30:28 | LL | let _in_macro = outer!(Box::new(String::new())); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<String>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:30:34 + --> $DIR/box_default.rs:31:34 | LL | let _string_default = outer!(Box::new(String::from(""))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<String>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:31:46 + --> $DIR/box_default.rs:32:46 | LL | let _vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]); | ^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:32:33 + --> $DIR/box_default.rs:33:33 | LL | let _vec3: Box<Vec<bool>> = Box::new(Vec::from([])); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:33:25 + --> $DIR/box_default.rs:34:25 | LL | let _vec4: Box<_> = Box::new(Vec::from([false; 0])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Vec<bool>>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:35:16 + --> $DIR/box_default.rs:36:16 | LL | call_ty_fn(Box::new(u8::default())); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:40:5 + --> $DIR/box_default.rs:41:5 | LL | Box::new(bool::default()) | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<bool>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:57:28 + --> $DIR/box_default.rs:58:28 | LL | let _: Box<dyn Read> = Box::new(ImplementsDefault::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:66:17 + --> $DIR/box_default.rs:67:17 | LL | let _ = Box::new(WeirdPathed::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<WeirdPathed>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:78:18 + --> $DIR/box_default.rs:79:18 | LL | Some(Box::new(Foo::default())) | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Foo>::default()` diff --git a/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs b/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs index 24d7eb28a19..b77f01883bf 100644 --- a/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs +++ b/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs @@ -23,7 +23,7 @@ fn main() { r_x as *const [i32] } as *const [u8]; - // Check that resores of the same size are detected through blocks + // Check that resources of the same size are detected through blocks let restore_block_1 = { r_x as *const [i32] } as *const [u8] as *const [u32]; let restore_block_2 = { ({ r_x as *const [i32] }) as *const [u8] } as *const [u32]; let restore_block_3 = { diff --git a/src/tools/clippy/tests/ui/crashes/ice-10645.rs b/src/tools/clippy/tests/ui/crashes/ice-10645.rs new file mode 100644 index 00000000000..4d8698d383b --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-10645.rs @@ -0,0 +1,7 @@ +// compile-flags: --cap-lints=warn +// https://github.com/rust-lang/rust-clippy/issues/10645 + +#![warn(clippy::future_not_send)] +pub async fn bar<'a, T: 'a>(_: T) {} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/crashes/ice-5207.stderr b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr index 59146c23e0d..fc084e30d7f 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-5207.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr @@ -1,11 +1,11 @@ error: future cannot be sent between threads safely - --> $DIR/ice-5207.rs:6:35 + --> $DIR/ice-10645.rs:5:35 | LL | pub async fn bar<'a, T: 'a>(_: T) {} | ^ future returned by `bar` is not `Send` | note: captured value is not `Send` - --> $DIR/ice-5207.rs:6:29 + --> $DIR/ice-10645.rs:5:29 | LL | pub async fn bar<'a, T: 'a>(_: T) {} | ^ has type `T` which is not `Send` diff --git a/src/tools/clippy/tests/ui/crashes/ice-5207.rs b/src/tools/clippy/tests/ui/crashes/ice-5207.rs index 893c15f5d73..0df8b88fea2 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-5207.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-5207.rs @@ -1,8 +1,4 @@ -// compile-flags: --cap-lints=warn -// ^ for https://github.com/rust-lang/rust-clippy/issues/10645 - // Regression test for https://github.com/rust-lang/rust-clippy/issues/5207 -#![warn(clippy::future_not_send)] pub async fn bar<'a, T: 'a>(_: T) {} fn main() {} diff --git a/src/tools/clippy/tests/ui/crashes/ice_exacte_size.rs b/src/tools/clippy/tests/ui/crashes/ice_exact_size.rs index 30e4b11ec0b..30e4b11ec0b 100644 --- a/src/tools/clippy/tests/ui/crashes/ice_exacte_size.rs +++ b/src/tools/clippy/tests/ui/crashes/ice_exact_size.rs diff --git a/src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed b/src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed new file mode 100644 index 00000000000..4c2d1ea48e1 --- /dev/null +++ b/src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed @@ -0,0 +1,119 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::default_constructed_unit_structs)] +use std::marker::PhantomData; + +#[derive(Default)] +struct UnitStruct; + +impl UnitStruct { + fn new() -> Self { + //should lint + Self + } +} + +#[derive(Default)] +struct TupleStruct(usize); + +impl TupleStruct { + fn new() -> Self { + // should not lint + Self(Default::default()) + } +} + +// no lint for derived impl +#[derive(Default)] +struct NormalStruct { + inner: PhantomData<usize>, +} + +struct NonDefaultStruct; + +impl NonDefaultStruct { + fn default() -> Self { + Self + } +} + +#[derive(Default)] +enum SomeEnum { + #[default] + Unit, + Tuple(UnitStruct), + Struct { + inner: usize, + }, +} + +impl NormalStruct { + fn new() -> Self { + // should lint + Self { + inner: PhantomData, + } + } + + fn new2() -> Self { + // should not lint + Self { + inner: Default::default(), + } + } +} + +#[derive(Default)] +struct GenericStruct<T> { + t: T, +} + +impl<T: Default> GenericStruct<T> { + fn new() -> Self { + // should not lint + Self { t: T::default() } + } + + fn new2() -> Self { + // should not lint + Self { t: Default::default() } + } +} + +struct FakeDefault; +impl FakeDefault { + fn default() -> Self { + Self + } +} + +impl Default for FakeDefault { + fn default() -> Self { + Self + } +} + +#[derive(Default)] +struct EmptyStruct {} + +#[derive(Default)] +#[non_exhaustive] +struct NonExhaustiveStruct; + +fn main() { + // should lint + let _ = PhantomData::<usize>; + let _: PhantomData<i32> = PhantomData; + let _ = UnitStruct; + + // should not lint + let _ = TupleStruct::default(); + let _ = NormalStruct::default(); + let _ = NonExhaustiveStruct::default(); + let _ = SomeEnum::default(); + let _ = NonDefaultStruct::default(); + let _ = EmptyStruct::default(); + let _ = FakeDefault::default(); + let _ = <FakeDefault as Default>::default(); +} diff --git a/src/tools/clippy/tests/ui/default_constructed_unit_structs.rs b/src/tools/clippy/tests/ui/default_constructed_unit_structs.rs new file mode 100644 index 00000000000..850793dd5de --- /dev/null +++ b/src/tools/clippy/tests/ui/default_constructed_unit_structs.rs @@ -0,0 +1,119 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::default_constructed_unit_structs)] +use std::marker::PhantomData; + +#[derive(Default)] +struct UnitStruct; + +impl UnitStruct { + fn new() -> Self { + //should lint + Self::default() + } +} + +#[derive(Default)] +struct TupleStruct(usize); + +impl TupleStruct { + fn new() -> Self { + // should not lint + Self(Default::default()) + } +} + +// no lint for derived impl +#[derive(Default)] +struct NormalStruct { + inner: PhantomData<usize>, +} + +struct NonDefaultStruct; + +impl NonDefaultStruct { + fn default() -> Self { + Self + } +} + +#[derive(Default)] +enum SomeEnum { + #[default] + Unit, + Tuple(UnitStruct), + Struct { + inner: usize, + }, +} + +impl NormalStruct { + fn new() -> Self { + // should lint + Self { + inner: PhantomData::default(), + } + } + + fn new2() -> Self { + // should not lint + Self { + inner: Default::default(), + } + } +} + +#[derive(Default)] +struct GenericStruct<T> { + t: T, +} + +impl<T: Default> GenericStruct<T> { + fn new() -> Self { + // should not lint + Self { t: T::default() } + } + + fn new2() -> Self { + // should not lint + Self { t: Default::default() } + } +} + +struct FakeDefault; +impl FakeDefault { + fn default() -> Self { + Self + } +} + +impl Default for FakeDefault { + fn default() -> Self { + Self + } +} + +#[derive(Default)] +struct EmptyStruct {} + +#[derive(Default)] +#[non_exhaustive] +struct NonExhaustiveStruct; + +fn main() { + // should lint + let _ = PhantomData::<usize>::default(); + let _: PhantomData<i32> = PhantomData::default(); + let _ = UnitStruct::default(); + + // should not lint + let _ = TupleStruct::default(); + let _ = NormalStruct::default(); + let _ = NonExhaustiveStruct::default(); + let _ = SomeEnum::default(); + let _ = NonDefaultStruct::default(); + let _ = EmptyStruct::default(); + let _ = FakeDefault::default(); + let _ = <FakeDefault as Default>::default(); +} diff --git a/src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr b/src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr new file mode 100644 index 00000000000..4058943d087 --- /dev/null +++ b/src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr @@ -0,0 +1,34 @@ +error: use of `default` to create a unit struct + --> $DIR/default_constructed_unit_structs.rs:13:13 + | +LL | Self::default() + | ^^^^^^^^^^^ help: remove this call to `default` + | + = note: `-D clippy::default-constructed-unit-structs` implied by `-D warnings` + +error: use of `default` to create a unit struct + --> $DIR/default_constructed_unit_structs.rs:55:31 + | +LL | inner: PhantomData::default(), + | ^^^^^^^^^^^ help: remove this call to `default` + +error: use of `default` to create a unit struct + --> $DIR/default_constructed_unit_structs.rs:106:33 + | +LL | let _ = PhantomData::<usize>::default(); + | ^^^^^^^^^^^ help: remove this call to `default` + +error: use of `default` to create a unit struct + --> $DIR/default_constructed_unit_structs.rs:107:42 + | +LL | let _: PhantomData<i32> = PhantomData::default(); + | ^^^^^^^^^^^ help: remove this call to `default` + +error: use of `default` to create a unit struct + --> $DIR/default_constructed_unit_structs.rs:108:23 + | +LL | let _ = UnitStruct::default(); + | ^^^^^^^^^^^ help: remove this call to `default` + +error: aborting due to 5 previous errors + diff --git a/src/tools/clippy/tests/ui/explicit_deref_methods.fixed b/src/tools/clippy/tests/ui/explicit_deref_methods.fixed index 77e9f5fc1fd..60482c66da7 100644 --- a/src/tools/clippy/tests/ui/explicit_deref_methods.fixed +++ b/src/tools/clippy/tests/ui/explicit_deref_methods.fixed @@ -3,7 +3,7 @@ #![allow(unused_variables)] #![allow( clippy::borrow_deref_ref, - clippy::clone_double_ref, + suspicious_double_ref_op, clippy::explicit_auto_deref, clippy::needless_borrow, clippy::uninlined_format_args diff --git a/src/tools/clippy/tests/ui/explicit_deref_methods.rs b/src/tools/clippy/tests/ui/explicit_deref_methods.rs index 0c2cc7c2c3a..e3613e216bb 100644 --- a/src/tools/clippy/tests/ui/explicit_deref_methods.rs +++ b/src/tools/clippy/tests/ui/explicit_deref_methods.rs @@ -3,7 +3,7 @@ #![allow(unused_variables)] #![allow( clippy::borrow_deref_ref, - clippy::clone_double_ref, + suspicious_double_ref_op, clippy::explicit_auto_deref, clippy::needless_borrow, clippy::uninlined_format_args diff --git a/src/tools/clippy/tests/ui/floating_point_arithmetic_nostd.rs b/src/tools/clippy/tests/ui/floating_point_arithmetic_nostd.rs new file mode 100644 index 00000000000..a42c6383cce --- /dev/null +++ b/src/tools/clippy/tests/ui/floating_point_arithmetic_nostd.rs @@ -0,0 +1,31 @@ +#![feature(lang_items, start)] +#![warn(clippy::imprecise_flops)] +#![warn(clippy::suboptimal_flops)] +#![no_std] + +// The following should not lint, as the suggested methods {f32,f64}.mul_add() +// and {f32,f64}::abs() are not available in no_std + +pub fn mul_add() { + let a: f64 = 1234.567; + let b: f64 = 45.67834; + let c: f64 = 0.0004; + let _ = a * b + c; +} + +fn fake_abs1(num: f64) -> f64 { + if num >= 0.0 { num } else { -num } +} + +#[start] +fn main(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed index fc6d937060d..d18f9387565 100644 --- a/src/tools/clippy/tests/ui/from_over_into.fixed +++ b/src/tools/clippy/tests/ui/from_over_into.fixed @@ -32,7 +32,7 @@ struct SelfKeywords; impl From<X> for SelfKeywords { fn from(val: X) -> Self { - let _ = X::default(); + let _ = X; let _ = X::FOO; let _: X = val; diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs index fe1ebee35f1..de8ff0b06bd 100644 --- a/src/tools/clippy/tests/ui/from_over_into.rs +++ b/src/tools/clippy/tests/ui/from_over_into.rs @@ -32,7 +32,7 @@ struct SelfKeywords; impl Into<SelfKeywords> for X { fn into(self) -> SelfKeywords { - let _ = Self::default(); + let _ = Self; let _ = Self::FOO; let _: Self = self; diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr index 3c4d011d6fb..6039f86fe67 100644 --- a/src/tools/clippy/tests/ui/from_over_into.stderr +++ b/src/tools/clippy/tests/ui/from_over_into.stderr @@ -5,7 +5,7 @@ LL | impl Into<StringWrapper> for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::from-over-into` implied by `-D warnings` -help: replace the `Into` implentation with `From<std::string::String>` +help: replace the `Into` implementation with `From<std::string::String>` | LL ~ impl From<String> for StringWrapper { LL ~ fn from(val: String) -> Self { @@ -18,7 +18,7 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into<SelfType> for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace the `Into` implentation with `From<std::string::String>` +help: replace the `Into` implementation with `From<std::string::String>` | LL ~ impl From<String> for SelfType { LL ~ fn from(val: String) -> Self { @@ -31,11 +31,11 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into<SelfKeywords> for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace the `Into` implentation with `From<X>` +help: replace the `Into` implementation with `From<X>` | LL ~ impl From<X> for SelfKeywords { LL ~ fn from(val: X) -> Self { -LL ~ let _ = X::default(); +LL ~ let _ = X; LL ~ let _ = X::FOO; LL ~ let _: X = val; | @@ -48,7 +48,7 @@ LL | impl core::convert::Into<bool> for crate::ExplicitPaths { | = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence -help: replace the `Into` implentation with `From<ExplicitPaths>` +help: replace the `Into` implementation with `From<ExplicitPaths>` | LL ~ impl core::convert::From<crate::ExplicitPaths> for bool { LL ~ fn from(mut val: crate::ExplicitPaths) -> Self { @@ -64,7 +64,7 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl<T> Into<FromOverInto<T>> for Vec<T> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace the `Into` implentation with `From<std::vec::Vec<T>>` +help: replace the `Into` implementation with `From<std::vec::Vec<T>>` | LL ~ impl<T> From<Vec<T>> for FromOverInto<T> { LL ~ fn from(val: Vec<T>) -> Self { diff --git a/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr b/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr index 6f6ce351921..251f1d84e74 100644 --- a/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr +++ b/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr @@ -4,7 +4,7 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into<InMacro> for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: replace the `Into` implentation with `From<std::string::String>` + = help: replace the `Into` implementation with `From<std::string::String>` = note: `-D clippy::from-over-into` implied by `-D warnings` error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true @@ -13,7 +13,7 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into<WeirdUpperSelf> for &'static [u8] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: replace the `Into` implentation with `From<&'static [u8]>` + = help: replace the `Into` implementation with `From<&'static [u8]>` error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true --> $DIR/from_over_into_unfixable.rs:28:1 @@ -23,7 +23,7 @@ LL | impl Into<u8> for ContainsVal { | = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence - = help: replace the `Into` implentation with `From<ContainsVal>` + = help: replace the `Into` implementation with `From<ContainsVal>` error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/tests.rs b/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/tests.rs new file mode 100644 index 00000000000..f328e4d9d04 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/tests.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/src/tools/clippy/tests/ui/items_after_test_module.rs b/src/tools/clippy/tests/ui/items_after_test_module/block_module.rs index 5136b2557ec..5136b2557ec 100644 --- a/src/tools/clippy/tests/ui/items_after_test_module.rs +++ b/src/tools/clippy/tests/ui/items_after_test_module/block_module.rs diff --git a/src/tools/clippy/tests/ui/items_after_test_module.stderr b/src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr index 8f1616dabc1..597f1b9510c 100644 --- a/src/tools/clippy/tests/ui/items_after_test_module.stderr +++ b/src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr @@ -1,5 +1,5 @@ error: items were found after the testing module - --> $DIR/items_after_test_module.rs:13:1 + --> $DIR/block_module.rs:13:1 | LL | / mod tests { LL | | #[test] diff --git a/src/tools/clippy/tests/ui/items_after_test_module/imported_module.rs b/src/tools/clippy/tests/ui/items_after_test_module/imported_module.rs new file mode 100644 index 00000000000..6a757aef48e --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/imported_module.rs @@ -0,0 +1,20 @@ +//@compile-flags: --test +#![allow(unused)] +#![warn(clippy::items_after_test_module)] + +// Nothing here should lint, as `tests` is an imported module (that has no body). + +fn main() {} + +fn should_not_lint() {} + +#[path = "auxiliary/tests.rs"] +#[cfg(test)] +mod tests; // Should not lint + +fn should_not_lint2() {} + +const SHOULD_ALSO_NOT_LINT: usize = 1; +macro_rules! should_not_lint { + () => {}; +} diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.stderr b/src/tools/clippy/tests/ui/let_underscore_untyped.stderr index 47e76ea1d04..6844cb998f7 100644 --- a/src/tools/clippy/tests/ui/let_underscore_untyped.stderr +++ b/src/tools/clippy/tests/ui/let_underscore_untyped.stderr @@ -4,7 +4,11 @@ error: non-binding `let` without a type annotation LL | let _ = a(); | ^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:36:10 + | +LL | let _ = a(); + | ^ = note: `-D clippy::let-underscore-untyped` implied by `-D warnings` error: non-binding `let` without a type annotation @@ -13,7 +17,11 @@ error: non-binding `let` without a type annotation LL | let _ = b(1); | ^^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:37:10 + | +LL | let _ = b(1); + | ^ error: non-binding `let` without a type annotation --> $DIR/let_underscore_untyped.rs:39:5 @@ -21,7 +29,11 @@ error: non-binding `let` without a type annotation LL | let _ = d(&1); | ^^^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:39:10 + | +LL | let _ = d(&1); + | ^ error: non-binding `let` without a type annotation --> $DIR/let_underscore_untyped.rs:40:5 @@ -29,7 +41,11 @@ error: non-binding `let` without a type annotation LL | let _ = e(); | ^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:40:10 + | +LL | let _ = e(); + | ^ error: non-binding `let` without a type annotation --> $DIR/let_underscore_untyped.rs:41:5 @@ -37,7 +53,11 @@ error: non-binding `let` without a type annotation LL | let _ = f(); | ^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:41:10 + | +LL | let _ = f(); + | ^ error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/let_with_type_underscore.rs b/src/tools/clippy/tests/ui/let_with_type_underscore.rs index 175718b94c8..7c1835e8cd1 100644 --- a/src/tools/clippy/tests/ui/let_with_type_underscore.rs +++ b/src/tools/clippy/tests/ui/let_with_type_underscore.rs @@ -12,7 +12,7 @@ fn main() { let _: _ = 2; let x: _ = func(); - let x = 1; // Will not lint, Rust inferres this to an integer before Clippy + let x = 1; // Will not lint, Rust infers this to an integer before Clippy let x = func(); let x: Vec<_> = Vec::<u32>::new(); let x: [_; 1] = [1]; diff --git a/src/tools/clippy/tests/ui/manual_retain.fixed b/src/tools/clippy/tests/ui/manual_retain.fixed index d3cac666763..09fb0d75852 100644 --- a/src/tools/clippy/tests/ui/manual_retain.fixed +++ b/src/tools/clippy/tests/ui/manual_retain.fixed @@ -23,8 +23,8 @@ fn main() { } fn binary_heap_retain() { - // NOTE: Do not lint now, because binary_heap_retain is nighyly API. - // And we need to add a test case for msrv if we update this implmention. + // NOTE: Do not lint now, because binary_heap_retain is nightly API. + // And we need to add a test case for msrv if we update this implementation. // https://github.com/rust-lang/rust/issues/71503 let mut heap = BinaryHeap::from([1, 2, 3]); heap = heap.into_iter().filter(|x| x % 2 == 0).collect(); diff --git a/src/tools/clippy/tests/ui/manual_retain.rs b/src/tools/clippy/tests/ui/manual_retain.rs index 34f0c4d5029..7fee4c95cea 100644 --- a/src/tools/clippy/tests/ui/manual_retain.rs +++ b/src/tools/clippy/tests/ui/manual_retain.rs @@ -23,8 +23,8 @@ fn main() { } fn binary_heap_retain() { - // NOTE: Do not lint now, because binary_heap_retain is nighyly API. - // And we need to add a test case for msrv if we update this implmention. + // NOTE: Do not lint now, because binary_heap_retain is nightly API. + // And we need to add a test case for msrv if we update this implementation. // https://github.com/rust-lang/rust/issues/71503 let mut heap = BinaryHeap::from([1, 2, 3]); heap = heap.into_iter().filter(|x| x % 2 == 0).collect(); diff --git a/src/tools/clippy/tests/ui/manual_while_let_some.fixed b/src/tools/clippy/tests/ui/manual_while_let_some.fixed new file mode 100644 index 00000000000..8b610919536 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_while_let_some.fixed @@ -0,0 +1,93 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_while_let_some)] + +struct VecInStruct { + numbers: Vec<i32>, + unrelated: String, +} + +struct Foo { + a: i32, + b: i32, +} + +fn accept_i32(_: i32) {} +fn accept_optional_i32(_: Option<i32>) {} +fn accept_i32_tuple(_: (i32, i32)) {} + +fn main() { + let mut numbers = vec![1, 2, 3, 4, 5]; + while let Some(number) = numbers.pop() { + + } + + let mut val = VecInStruct { + numbers: vec![1, 2, 3, 4, 5], + unrelated: String::new(), + }; + while let Some(number) = val.numbers.pop() { + + } + + while let Some(element) = numbers.pop() { + accept_i32(element); + } + + while let Some(element) = numbers.pop() { + accept_i32(element); + } + + // This should not warn. It "conditionally" pops elements. + while !numbers.is_empty() { + if true { + accept_i32(numbers.pop().unwrap()); + } + } + + // This should also not warn. It conditionally pops elements. + while !numbers.is_empty() { + if false { + continue; + } + accept_i32(numbers.pop().unwrap()); + } + + // This should not warn. It pops elements, but does not unwrap it. + // Might handle the Option in some other arbitrary way. + while !numbers.is_empty() { + accept_optional_i32(numbers.pop()); + } + + let unrelated_vec: Vec<String> = Vec::new(); + // This should not warn. It pops elements from a different vector. + while !unrelated_vec.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + + macro_rules! generate_loop { + () => { + while !numbers.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + }; + } + // Do not warn if the loop comes from a macro. + generate_loop!(); + + // Try other kinds of patterns + let mut numbers = vec![(0, 0), (1, 1), (2, 2)]; + while let Some((a, b)) = numbers.pop() { + + } + + while let Some(element) = numbers.pop() { + accept_i32_tuple(element); + } + + let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }]; + while let Some(Foo { a, b }) = results.pop() { + + } +} diff --git a/src/tools/clippy/tests/ui/manual_while_let_some.rs b/src/tools/clippy/tests/ui/manual_while_let_some.rs new file mode 100644 index 00000000000..85a0a084a42 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_while_let_some.rs @@ -0,0 +1,93 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_while_let_some)] + +struct VecInStruct { + numbers: Vec<i32>, + unrelated: String, +} + +struct Foo { + a: i32, + b: i32, +} + +fn accept_i32(_: i32) {} +fn accept_optional_i32(_: Option<i32>) {} +fn accept_i32_tuple(_: (i32, i32)) {} + +fn main() { + let mut numbers = vec![1, 2, 3, 4, 5]; + while !numbers.is_empty() { + let number = numbers.pop().unwrap(); + } + + let mut val = VecInStruct { + numbers: vec![1, 2, 3, 4, 5], + unrelated: String::new(), + }; + while !val.numbers.is_empty() { + let number = val.numbers.pop().unwrap(); + } + + while !numbers.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + + while !numbers.is_empty() { + accept_i32(numbers.pop().expect("")); + } + + // This should not warn. It "conditionally" pops elements. + while !numbers.is_empty() { + if true { + accept_i32(numbers.pop().unwrap()); + } + } + + // This should also not warn. It conditionally pops elements. + while !numbers.is_empty() { + if false { + continue; + } + accept_i32(numbers.pop().unwrap()); + } + + // This should not warn. It pops elements, but does not unwrap it. + // Might handle the Option in some other arbitrary way. + while !numbers.is_empty() { + accept_optional_i32(numbers.pop()); + } + + let unrelated_vec: Vec<String> = Vec::new(); + // This should not warn. It pops elements from a different vector. + while !unrelated_vec.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + + macro_rules! generate_loop { + () => { + while !numbers.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + }; + } + // Do not warn if the loop comes from a macro. + generate_loop!(); + + // Try other kinds of patterns + let mut numbers = vec![(0, 0), (1, 1), (2, 2)]; + while !numbers.is_empty() { + let (a, b) = numbers.pop().unwrap(); + } + + while !numbers.is_empty() { + accept_i32_tuple(numbers.pop().unwrap()); + } + + let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }]; + while !results.is_empty() { + let Foo { a, b } = results.pop().unwrap(); + } +} diff --git a/src/tools/clippy/tests/ui/manual_while_let_some.stderr b/src/tools/clippy/tests/ui/manual_while_let_some.stderr new file mode 100644 index 00000000000..633fe05c49b --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_while_let_some.stderr @@ -0,0 +1,87 @@ +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:23:9 + | +LL | let number = numbers.pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::manual-while-let-some` implied by `-D warnings` +help: consider using a `while..let` loop + | +LL ~ while let Some(number) = numbers.pop() { +LL ~ + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:31:9 + | +LL | let number = val.numbers.pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(number) = val.numbers.pop() { +LL ~ + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:35:20 + | +LL | accept_i32(numbers.pop().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(element) = numbers.pop() { +LL ~ accept_i32(element); + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:39:20 + | +LL | accept_i32(numbers.pop().expect("")); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(element) = numbers.pop() { +LL ~ accept_i32(element); + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:82:9 + | +LL | let (a, b) = numbers.pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some((a, b)) = numbers.pop() { +LL ~ + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:86:26 + | +LL | accept_i32_tuple(numbers.pop().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(element) = numbers.pop() { +LL ~ accept_i32_tuple(element); + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:91:9 + | +LL | let Foo { a, b } = results.pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(Foo { a, b }) = results.pop() { +LL ~ + | + +error: aborting due to 7 previous errors + diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.fixed b/src/tools/clippy/tests/ui/needless_bool_assign.fixed new file mode 100644 index 00000000000..3ed31d4d711 --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_bool_assign.fixed @@ -0,0 +1,33 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::needless_bool_assign)] + +fn random() -> bool { + true +} + +fn main() { + struct Data { + field: bool, + }; + let mut a = Data { field: false }; + a.field = random() && random(); + a.field = !(random() && random()); + // Do not lint… + if random() { + a.field = false; + } else { + // …to avoid losing this comment + a.field = true + } + // This one also triggers lint `clippy::if_same_then_else` + // which does not suggest a rewrite. + random(); a.field = true; + let mut b = false; + if random() { + a.field = false; + } else { + b = true; + } +} diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.rs b/src/tools/clippy/tests/ui/needless_bool_assign.rs new file mode 100644 index 00000000000..efaeb67fa45 --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_bool_assign.rs @@ -0,0 +1,45 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::needless_bool_assign)] + +fn random() -> bool { + true +} + +fn main() { + struct Data { + field: bool, + }; + let mut a = Data { field: false }; + if random() && random() { + a.field = true; + } else { + a.field = false + } + if random() && random() { + a.field = false; + } else { + a.field = true + } + // Do not lint… + if random() { + a.field = false; + } else { + // …to avoid losing this comment + a.field = true + } + // This one also triggers lint `clippy::if_same_then_else` + // which does not suggest a rewrite. + if random() { + a.field = true; + } else { + a.field = true; + } + let mut b = false; + if random() { + a.field = false; + } else { + b = true; + } +} diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.stderr b/src/tools/clippy/tests/ui/needless_bool_assign.stderr new file mode 100644 index 00000000000..601bbed5493 --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_bool_assign.stderr @@ -0,0 +1,53 @@ +error: this if-then-else expression assigns a bool literal + --> $DIR/needless_bool_assign.rs:15:5 + | +LL | / if random() && random() { +LL | | a.field = true; +LL | | } else { +LL | | a.field = false +LL | | } + | |_____^ help: you can reduce it to: `a.field = random() && random();` + | + = note: `-D clippy::needless-bool-assign` implied by `-D warnings` + +error: this if-then-else expression assigns a bool literal + --> $DIR/needless_bool_assign.rs:20:5 + | +LL | / if random() && random() { +LL | | a.field = false; +LL | | } else { +LL | | a.field = true +LL | | } + | |_____^ help: you can reduce it to: `a.field = !(random() && random());` + +error: this if-then-else expression assigns a bool literal + --> $DIR/needless_bool_assign.rs:34:5 + | +LL | / if random() { +LL | | a.field = true; +LL | | } else { +LL | | a.field = true; +LL | | } + | |_____^ help: you can reduce it to: `random(); a.field = true;` + +error: this `if` has identical blocks + --> $DIR/needless_bool_assign.rs:34:17 + | +LL | if random() { + | _________________^ +LL | | a.field = true; +LL | | } else { + | |_____^ + | +note: same as this + --> $DIR/needless_bool_assign.rs:36:12 + | +LL | } else { + | ____________^ +LL | | a.field = true; +LL | | } + | |_____^ + = note: `#[deny(clippy::if_same_then_else)]` on by default + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed index a04f9ec651e..92572942bc0 100644 --- a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed +++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed @@ -110,7 +110,7 @@ fn should_not_lint() { }), } - // `for_each` is in a let bingind. + // `for_each` is in a let binding. let _ = v.iter().for_each(|elem| { acc += elem; }); diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs index 4975c705081..95acbdff8cc 100644 --- a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs +++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs @@ -110,7 +110,7 @@ fn should_not_lint() { }), } - // `for_each` is in a let bingind. + // `for_each` is in a let binding. let _ = v.iter().for_each(|elem| { acc += elem; }); diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs index b32e721110e..818119f7be5 100644 --- a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs +++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs @@ -25,7 +25,7 @@ fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lin 0 } -// Must not run on functions that explicitly opt in to Rust ABI with `extern "Rust"` +// Must not run on functions that explicitly opt in to using the Rust ABI with `extern "Rust"` #[no_mangle] #[rustfmt::skip] extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {} diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed index 9aebcf47100..57f341e0276 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.fixed +++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed @@ -97,7 +97,7 @@ enum DummyEnum { Two, } -// should not warn since there is a compled complex subpat +// should not warn since there is a complex subpat // see #7991 fn complex_subpat() -> DummyEnum { let x = Some(DummyEnum::One(1)); diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs index b40b324902a..19f9f704517 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.rs +++ b/src/tools/clippy/tests/ui/option_if_let_else.rs @@ -120,7 +120,7 @@ enum DummyEnum { Two, } -// should not warn since there is a compled complex subpat +// should not warn since there is a complex subpat // see #7991 fn complex_subpat() -> DummyEnum { let x = Some(DummyEnum::One(1)); diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed index 87100b97288..d62f7d26a35 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed @@ -54,6 +54,8 @@ fn main() { } else { 3 }; + + if gen_opt().is_some() {} } fn gen_opt() -> Option<()> { diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs index 0b69e13f655..d6429426573 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs @@ -63,6 +63,8 @@ fn main() { } else { 3 }; + + if let Some(..) = gen_opt() {} } fn gen_opt() -> Option<()> { diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr index 27ff812ba45..7c5a047e455 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr @@ -89,31 +89,37 @@ LL | } else if let None = gen_opt() { | -------^^^^------------ help: try this: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:80:12 + --> $DIR/redundant_pattern_matching_option.rs:67:12 + | +LL | if let Some(..) = gen_opt() {} + | -------^^^^^^^^------------ help: try this: `if gen_opt().is_some()` + +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching_option.rs:82:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:82:12 + --> $DIR/redundant_pattern_matching_option.rs:84:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try this: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:84:15 + --> $DIR/redundant_pattern_matching_option.rs:86:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try this: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:86:15 + --> $DIR/redundant_pattern_matching_option.rs:88:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try this: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:88:5 + --> $DIR/redundant_pattern_matching_option.rs:90:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -122,7 +128,7 @@ LL | | }; | |_____^ help: try this: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:93:5 + --> $DIR/redundant_pattern_matching_option.rs:95:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -131,16 +137,16 @@ LL | | }; | |_____^ help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:101:12 + --> $DIR/redundant_pattern_matching_option.rs:103:12 | LL | if let None = *(&None::<()>) {} | -------^^^^----------------- help: try this: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:102:12 + --> $DIR/redundant_pattern_matching_option.rs:104:12 | LL | if let None = *&None::<()> {} | -------^^^^--------------- help: try this: `if (&None::<()>).is_none()` -error: aborting due to 21 previous errors +error: aborting due to 22 previous errors diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index e8a00a9e7f7..42a59f6d43d 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -27,6 +27,7 @@ #![allow(clippy::module_name_repetitions)] #![allow(clippy::recursive_format_impl)] #![allow(clippy::invisible_characters)] +#![allow(suspicious_double_ref_op)] #![allow(drop_bounds)] #![allow(for_loops_over_fallibles)] #![allow(array_into_iter)] @@ -36,6 +37,7 @@ #![allow(enum_intrinsics_non_enums)] #![allow(non_fmt_panics)] #![allow(named_arguments_used_positionally)] +#![allow(suspicious_double_ref_op)] #![allow(temporary_cstring_as_ptr)] #![allow(unknown_lints)] #![allow(unused_labels)] @@ -67,6 +69,7 @@ #![warn(clippy::module_name_repetitions)] #![warn(clippy::recursive_format_impl)] #![warn(clippy::invisible_characters)] +#![warn(suspicious_double_ref_op)] #![warn(drop_bounds)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index c8ea70c2bcb..4d173e8cbbf 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -27,6 +27,7 @@ #![allow(clippy::module_name_repetitions)] #![allow(clippy::recursive_format_impl)] #![allow(clippy::invisible_characters)] +#![allow(suspicious_double_ref_op)] #![allow(drop_bounds)] #![allow(for_loops_over_fallibles)] #![allow(array_into_iter)] @@ -36,6 +37,7 @@ #![allow(enum_intrinsics_non_enums)] #![allow(non_fmt_panics)] #![allow(named_arguments_used_positionally)] +#![allow(suspicious_double_ref_op)] #![allow(temporary_cstring_as_ptr)] #![allow(unknown_lints)] #![allow(unused_labels)] @@ -67,6 +69,7 @@ #![warn(clippy::stutter)] #![warn(clippy::to_string_in_display)] #![warn(clippy::zero_width_space)] +#![warn(clippy::clone_double_ref)] #![warn(clippy::drop_bounds)] #![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_result)] diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 27a0263292e..0da4ed7520c 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:42:9 + --> $DIR/rename.rs:44:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -7,250 +7,256 @@ LL | #![warn(clippy::almost_complete_letter_range)] = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:43:9 + --> $DIR/rename.rs:45:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:44:9 + --> $DIR/rename.rs:46:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:45:9 + --> $DIR/rename.rs:47:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:46:9 + --> $DIR/rename.rs:48:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:47:9 + --> $DIR/rename.rs:49:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:48:9 + --> $DIR/rename.rs:50:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:49:9 + --> $DIR/rename.rs:51:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:50:9 + --> $DIR/rename.rs:52:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:51:9 + --> $DIR/rename.rs:53:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:52:9 + --> $DIR/rename.rs:54:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:53:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` +error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` + --> $DIR/rename.rs:72:9 + | +LL | #![warn(clippy::clone_double_ref)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` + error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:71:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:72:9 + --> $DIR/rename.rs:75:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:73:9 + --> $DIR/rename.rs:76:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:74:9 + --> $DIR/rename.rs:77:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:75:9 + --> $DIR/rename.rs:78:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:76:9 + --> $DIR/rename.rs:79:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:77:9 + --> $DIR/rename.rs:80:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:78:9 + --> $DIR/rename.rs:81:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:79:9 + --> $DIR/rename.rs:82:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:80:9 + --> $DIR/rename.rs:83:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:81:9 + --> $DIR/rename.rs:84:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:82:9 + --> $DIR/rename.rs:85:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:83:9 + --> $DIR/rename.rs:86:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 42 previous errors +error: aborting due to 43 previous errors diff --git a/src/tools/clippy/tests/ui/same_name_method.rs b/src/tools/clippy/tests/ui/same_name_method.rs index daef95a425c..f31a7e33c4b 100644 --- a/src/tools/clippy/tests/ui/same_name_method.rs +++ b/src/tools/clippy/tests/ui/same_name_method.rs @@ -62,7 +62,7 @@ mod should_lint { impl T1 for S {} } - mod multiply_conflicit_trait { + mod multiple_conflicting_traits { use crate::{T1, T2}; struct S; diff --git a/src/tools/clippy/tests/ui/shadow.rs b/src/tools/clippy/tests/ui/shadow.rs index 03337ec3564..2c0fc3e3fd8 100644 --- a/src/tools/clippy/tests/ui/shadow.rs +++ b/src/tools/clippy/tests/ui/shadow.rs @@ -8,6 +8,12 @@ extern crate proc_macro_derive; #[derive(proc_macro_derive::ShadowDerive)] pub struct Nothing; +macro_rules! reuse { + ($v:ident) => { + let $v = $v + 1; + }; +} + fn shadow_same() { let x = 1; let x = x; @@ -33,6 +39,12 @@ fn shadow_reuse() -> Option<()> { None } +fn shadow_reuse_macro() { + let x = 1; + // this should not warn + reuse!(x); +} + fn shadow_unrelated() { let x = 1; let x = 2; diff --git a/src/tools/clippy/tests/ui/shadow.stderr b/src/tools/clippy/tests/ui/shadow.stderr index 92bb937d086..8321f6df224 100644 --- a/src/tools/clippy/tests/ui/shadow.stderr +++ b/src/tools/clippy/tests/ui/shadow.stderr @@ -1,278 +1,278 @@ error: `x` is shadowed by itself in `x` - --> $DIR/shadow.rs:13:9 + --> $DIR/shadow.rs:19:9 | LL | let x = x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:12:9 + --> $DIR/shadow.rs:18:9 | LL | let x = 1; | ^ = note: `-D clippy::shadow-same` implied by `-D warnings` error: `mut x` is shadowed by itself in `&x` - --> $DIR/shadow.rs:14:13 + --> $DIR/shadow.rs:20:13 | LL | let mut x = &x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:13:9 + --> $DIR/shadow.rs:19:9 | LL | let x = x; | ^ error: `x` is shadowed by itself in `&mut x` - --> $DIR/shadow.rs:15:9 + --> $DIR/shadow.rs:21:9 | LL | let x = &mut x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:14:9 + --> $DIR/shadow.rs:20:9 | LL | let mut x = &x; | ^^^^^ error: `x` is shadowed by itself in `*x` - --> $DIR/shadow.rs:16:9 + --> $DIR/shadow.rs:22:9 | LL | let x = *x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:15:9 + --> $DIR/shadow.rs:21:9 | LL | let x = &mut x; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:21:9 + --> $DIR/shadow.rs:27:9 | LL | let x = x.0; | ^ | note: previous binding is here - --> $DIR/shadow.rs:20:9 + --> $DIR/shadow.rs:26:9 | LL | let x = ([[0]], ()); | ^ = note: `-D clippy::shadow-reuse` implied by `-D warnings` error: `x` is shadowed - --> $DIR/shadow.rs:22:9 + --> $DIR/shadow.rs:28:9 | LL | let x = x[0]; | ^ | note: previous binding is here - --> $DIR/shadow.rs:21:9 + --> $DIR/shadow.rs:27:9 | LL | let x = x.0; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:23:10 + --> $DIR/shadow.rs:29:10 | LL | let [x] = x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:22:9 + --> $DIR/shadow.rs:28:9 | LL | let x = x[0]; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:24:9 + --> $DIR/shadow.rs:30:9 | LL | let x = Some(x); | ^ | note: previous binding is here - --> $DIR/shadow.rs:23:10 + --> $DIR/shadow.rs:29:10 | LL | let [x] = x; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:25:9 + --> $DIR/shadow.rs:31:9 | LL | let x = foo(x); | ^ | note: previous binding is here - --> $DIR/shadow.rs:24:9 + --> $DIR/shadow.rs:30:9 | LL | let x = Some(x); | ^ error: `x` is shadowed - --> $DIR/shadow.rs:26:9 + --> $DIR/shadow.rs:32:9 | LL | let x = || x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:25:9 + --> $DIR/shadow.rs:31:9 | LL | let x = foo(x); | ^ error: `x` is shadowed - --> $DIR/shadow.rs:27:9 + --> $DIR/shadow.rs:33:9 | LL | let x = Some(1).map(|_| x)?; | ^ | note: previous binding is here - --> $DIR/shadow.rs:26:9 + --> $DIR/shadow.rs:32:9 | LL | let x = || x; | ^ error: `y` is shadowed - --> $DIR/shadow.rs:29:9 + --> $DIR/shadow.rs:35:9 | LL | let y = match y { | ^ | note: previous binding is here - --> $DIR/shadow.rs:28:9 + --> $DIR/shadow.rs:34:9 | LL | let y = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:38:9 + --> $DIR/shadow.rs:50:9 | LL | let x = 2; | ^ | note: previous binding is here - --> $DIR/shadow.rs:37:9 + --> $DIR/shadow.rs:49:9 | LL | let x = 1; | ^ = note: `-D clippy::shadow-unrelated` implied by `-D warnings` error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:43:13 + --> $DIR/shadow.rs:55:13 | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:42:10 + --> $DIR/shadow.rs:54:10 | LL | fn f(x: u32) { | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:48:14 + --> $DIR/shadow.rs:60:14 | LL | Some(x) => { | ^ | note: previous binding is here - --> $DIR/shadow.rs:45:9 + --> $DIR/shadow.rs:57:9 | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:49:17 + --> $DIR/shadow.rs:61:17 | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:48:14 + --> $DIR/shadow.rs:60:14 | LL | Some(x) => { | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:53:17 + --> $DIR/shadow.rs:65:17 | LL | if let Some(x) = Some(1) {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:45:9 + --> $DIR/shadow.rs:57:9 | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:54:20 + --> $DIR/shadow.rs:66:20 | LL | while let Some(x) = Some(1) {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:45:9 + --> $DIR/shadow.rs:57:9 | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:55:15 + --> $DIR/shadow.rs:67:15 | LL | let _ = |[x]: [u32; 1]| { | ^ | note: previous binding is here - --> $DIR/shadow.rs:45:9 + --> $DIR/shadow.rs:57:9 | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:56:13 + --> $DIR/shadow.rs:68:13 | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:55:15 + --> $DIR/shadow.rs:67:15 | LL | let _ = |[x]: [u32; 1]| { | ^ error: `y` is shadowed - --> $DIR/shadow.rs:59:17 + --> $DIR/shadow.rs:71:17 | LL | if let Some(y) = y {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:58:9 + --> $DIR/shadow.rs:70:9 | LL | let y = Some(1); | ^ error: `_b` shadows a previous, unrelated binding - --> $DIR/shadow.rs:95:9 + --> $DIR/shadow.rs:107:9 | LL | let _b = _a; | ^^ | note: previous binding is here - --> $DIR/shadow.rs:94:28 + --> $DIR/shadow.rs:106:28 | LL | pub async fn foo2(_a: i32, _b: i64) { | ^^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:101:21 + --> $DIR/shadow.rs:113:21 | LL | if let Some(x) = Some(1) { x } else { 1 } | ^ | note: previous binding is here - --> $DIR/shadow.rs:100:13 + --> $DIR/shadow.rs:112:13 | LL | let x = 1; | ^ diff --git a/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed b/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed index 058f2aa54da..3fc11b8b088 100644 --- a/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed +++ b/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed @@ -1,8 +1,18 @@ //@run-rustfix +//@aux-build:macro_rules.rs #![allow(dead_code, unused_variables)] #![warn(clippy::string_lit_as_bytes)] +#[macro_use] +extern crate macro_rules; + +macro_rules! b { + ($b:literal) => { + const B: &[u8] = b"warning"; + }; +} + fn str_lit_as_bytes() { let bs = b"hello there"; @@ -11,6 +21,10 @@ fn str_lit_as_bytes() { let bs = b"lit to string".to_vec(); let bs = b"lit to owned".to_vec(); + b!("warning"); + + string_lit_as_bytes!("no warning"); + // no warning, because these cannot be written as byte string literals: let ubs = "☃".as_bytes(); let ubs = "hello there! this is a very long string".as_bytes(); diff --git a/src/tools/clippy/tests/ui/string_lit_as_bytes.rs b/src/tools/clippy/tests/ui/string_lit_as_bytes.rs index b550bea001f..7d54acf630e 100644 --- a/src/tools/clippy/tests/ui/string_lit_as_bytes.rs +++ b/src/tools/clippy/tests/ui/string_lit_as_bytes.rs @@ -1,8 +1,18 @@ //@run-rustfix +//@aux-build:macro_rules.rs #![allow(dead_code, unused_variables)] #![warn(clippy::string_lit_as_bytes)] +#[macro_use] +extern crate macro_rules; + +macro_rules! b { + ($b:literal) => { + const B: &[u8] = $b.as_bytes(); + }; +} + fn str_lit_as_bytes() { let bs = "hello there".as_bytes(); @@ -11,6 +21,10 @@ fn str_lit_as_bytes() { let bs = "lit to string".to_string().into_bytes(); let bs = "lit to owned".to_owned().into_bytes(); + b!("warning"); + + string_lit_as_bytes!("no warning"); + // no warning, because these cannot be written as byte string literals: let ubs = "☃".as_bytes(); let ubs = "hello there! this is a very long string".as_bytes(); diff --git a/src/tools/clippy/tests/ui/string_lit_as_bytes.stderr b/src/tools/clippy/tests/ui/string_lit_as_bytes.stderr index f47d6161c6c..61b4e210e0f 100644 --- a/src/tools/clippy/tests/ui/string_lit_as_bytes.stderr +++ b/src/tools/clippy/tests/ui/string_lit_as_bytes.stderr @@ -1,5 +1,5 @@ error: calling `as_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:7:14 + --> $DIR/string_lit_as_bytes.rs:17:14 | LL | let bs = "hello there".as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"hello there"` @@ -7,34 +7,45 @@ LL | let bs = "hello there".as_bytes(); = note: `-D clippy::string-lit-as-bytes` implied by `-D warnings` error: calling `as_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:9:14 + --> $DIR/string_lit_as_bytes.rs:19:14 | LL | let bs = r###"raw string with 3# plus " ""###.as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###"raw string with 3# plus " ""###` error: calling `into_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:11:14 + --> $DIR/string_lit_as_bytes.rs:21:14 | LL | let bs = "lit to string".to_string().into_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to string".to_vec()` error: calling `into_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:12:14 + --> $DIR/string_lit_as_bytes.rs:22:14 | LL | let bs = "lit to owned".to_owned().into_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to owned".to_vec()` +error: calling `as_bytes()` on a string literal + --> $DIR/string_lit_as_bytes.rs:12:26 + | +LL | const B: &[u8] = $b.as_bytes(); + | ^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"warning"` +... +LL | b!("warning"); + | ------------- in this macro invocation + | + = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + error: calling `as_bytes()` on `include_str!(..)` - --> $DIR/string_lit_as_bytes.rs:25:22 + --> $DIR/string_lit_as_bytes.rs:39:22 | LL | let includestr = include_str!("string_lit_as_bytes.rs").as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("string_lit_as_bytes.rs")` error: calling `as_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:27:13 + --> $DIR/string_lit_as_bytes.rs:41:13 | LL | let _ = "string with newline/t/n".as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"string with newline/t/n"` -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/trailing_empty_array.rs b/src/tools/clippy/tests/ui/trailing_empty_array.rs index 8e3749eef35..928475b5f35 100644 --- a/src/tools/clippy/tests/ui/trailing_empty_array.rs +++ b/src/tools/clippy/tests/ui/trailing_empty_array.rs @@ -144,7 +144,7 @@ struct ReprCAlign { // NOTE: because of https://doc.rust-lang.org/stable/reference/type-layout.html#primitive-representation-of-enums-with-fields and I'm not sure when in the compilation pipeline that would happen #[repr(C)] -enum DontLintAnonymousStructsFromDesuraging { +enum DontLintAnonymousStructsFromDesugaring { A(u32), B(f32, [u64; 0]), C { x: u32, y: [u64; 0] }, diff --git a/src/tools/clippy/tests/ui/uninit.rs b/src/tools/clippy/tests/ui/uninit.rs index c996de89422..2d567630e15 100644 --- a/src/tools/clippy/tests/ui/uninit.rs +++ b/src/tools/clippy/tests/ui/uninit.rs @@ -17,10 +17,10 @@ fn main() { // This is OK, because `MaybeUninit` allows uninitialized data. let _: MaybeUninit<usize> = unsafe { MaybeUninit::uninit().assume_init() }; - // This is OK, because all constitutent types are uninit-compatible. + // This is OK, because all constituent types are uninit-compatible. let _: (MaybeUninit<usize>, MaybeUninit<bool>) = unsafe { MaybeUninit::uninit().assume_init() }; - // This is OK, because all constitutent types are uninit-compatible. + // This is OK, because all constituent types are uninit-compatible. let _: (MaybeUninit<usize>, [MaybeUninit<bool>; 2]) = unsafe { MaybeUninit::uninit().assume_init() }; // This is OK, because our own MaybeUninit is just as fine as the one from core. diff --git a/src/tools/clippy/tests/ui/unnecessary_clone.rs b/src/tools/clippy/tests/ui/unnecessary_clone.rs index 8b1629b19a7..7ceed3c75fd 100644 --- a/src/tools/clippy/tests/ui/unnecessary_clone.rs +++ b/src/tools/clippy/tests/ui/unnecessary_clone.rs @@ -42,14 +42,6 @@ fn clone_on_copy_generic<T: Copy>(t: T) { Some(t).clone(); } -fn clone_on_double_ref() { - let x = vec![1]; - let y = &&x; - let z: &Vec<_> = y.clone(); - - println!("{:p} {:p}", *y, z); -} - mod many_derefs { struct A; struct B; @@ -84,11 +76,6 @@ mod many_derefs { let _: E = a.clone(); let _: E = *****a; } - - fn check(mut encoded: &[u8]) { - let _ = &mut encoded.clone(); - let _ = &encoded.clone(); - } } mod issue2076 { diff --git a/src/tools/clippy/tests/ui/unnecessary_clone.stderr b/src/tools/clippy/tests/ui/unnecessary_clone.stderr index 6022d9fa4c5..5686ab6b453 100644 --- a/src/tools/clippy/tests/ui/unnecessary_clone.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_clone.stderr @@ -44,63 +44,17 @@ error: using `clone` on type `Option<T>` which implements the `Copy` trait LL | Some(t).clone(); | ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)` -error: using `clone` on a double-reference; this will copy the reference of type `&Vec<i32>` instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:48:22 - | -LL | let z: &Vec<_> = y.clone(); - | ^^^^^^^^^ - | - = note: `#[deny(clippy::clone_double_ref)]` on by default -help: try dereferencing it - | -LL | let z: &Vec<_> = &(*y).clone(); - | ~~~~~~~~~~~~~ -help: or try being explicit if you are sure, that you want to clone a reference - | -LL | let z: &Vec<_> = <&Vec<i32>>::clone(y); - | ~~~~~~~~~~~~~~~~~~~~~ - error: using `clone` on type `E` which implements the `Copy` trait - --> $DIR/unnecessary_clone.rs:84:20 + --> $DIR/unnecessary_clone.rs:76:20 | LL | let _: E = a.clone(); | ^^^^^^^^^ help: try dereferencing it: `*****a` -error: using `clone` on a double-reference; this will copy the reference of type `&[u8]` instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:89:22 - | -LL | let _ = &mut encoded.clone(); - | ^^^^^^^^^^^^^^^ - | -help: try dereferencing it - | -LL | let _ = &mut &(*encoded).clone(); - | ~~~~~~~~~~~~~~~~~~~ -help: or try being explicit if you are sure, that you want to clone a reference - | -LL | let _ = &mut <&[u8]>::clone(encoded); - | ~~~~~~~~~~~~~~~~~~~~~~~ - -error: using `clone` on a double-reference; this will copy the reference of type `&[u8]` instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:90:18 - | -LL | let _ = &encoded.clone(); - | ^^^^^^^^^^^^^^^ - | -help: try dereferencing it - | -LL | let _ = &&(*encoded).clone(); - | ~~~~~~~~~~~~~~~~~~~ -help: or try being explicit if you are sure, that you want to clone a reference - | -LL | let _ = &<&[u8]>::clone(encoded); - | ~~~~~~~~~~~~~~~~~~~~~~~ - error: using `.clone()` on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:108:14 + --> $DIR/unnecessary_clone.rs:95:14 | LL | Some(try_opt!(Some(rc)).clone()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Rc::<u8>::clone(&try_opt!(Some(rc)))` -error: aborting due to 12 previous errors +error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/use_self_trait.fixed b/src/tools/clippy/tests/ui/use_self_trait.fixed index 4623aeeb0eb..20138a29fd1 100644 --- a/src/tools/clippy/tests/ui/use_self_trait.fixed +++ b/src/tools/clippy/tests/ui/use_self_trait.fixed @@ -33,7 +33,7 @@ impl SelfTrait for Bad { fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {} fn vals(_: Self) -> Self { - Self::default() + Self } } @@ -70,7 +70,7 @@ impl SelfTrait for Good { fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {} fn vals(_: Self) -> Self { - Self::default() + Self } } diff --git a/src/tools/clippy/tests/ui/use_self_trait.rs b/src/tools/clippy/tests/ui/use_self_trait.rs index d7d76dd9623..bf697b01a42 100644 --- a/src/tools/clippy/tests/ui/use_self_trait.rs +++ b/src/tools/clippy/tests/ui/use_self_trait.rs @@ -33,7 +33,7 @@ impl SelfTrait for Bad { fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {} fn vals(_: Bad) -> Bad { - Bad::default() + Bad } } @@ -70,7 +70,7 @@ impl SelfTrait for Good { fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {} fn vals(_: Self) -> Self { - Self::default() + Self } } diff --git a/src/tools/clippy/tests/ui/use_self_trait.stderr b/src/tools/clippy/tests/ui/use_self_trait.stderr index 090729b9c3d..6257f802dd8 100644 --- a/src/tools/clippy/tests/ui/use_self_trait.stderr +++ b/src/tools/clippy/tests/ui/use_self_trait.stderr @@ -63,7 +63,7 @@ LL | fn vals(_: Bad) -> Bad { error: unnecessary structure name repetition --> $DIR/use_self_trait.rs:36:9 | -LL | Bad::default() +LL | Bad | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition diff --git a/src/tools/clippy/util/gh-pages/index.html b/src/tools/clippy/util/gh-pages/index.html index e46ad2c6e0e..8791debad72 100644 --- a/src/tools/clippy/util/gh-pages/index.html +++ b/src/tools/clippy/util/gh-pages/index.html @@ -564,7 +564,7 @@ Otherwise, have a great day =^.^= </div> <a href="https://github.com/rust-lang/rust-clippy"> - <img style="position: absolute; top: 0; right: 0; border: 0; clip-path: polygon(0% 0%, 100% 0%, 100% 100%);" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on Github"/> + <img style="position: absolute; top: 0; right: 0; border: 0; clip-path: polygon(0% 0%, 100% 0%, 100% 100%);" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"/> </a> <script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/12.3.2/markdown-it.min.js"></script> diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 81179480ed8..4a57c61406c 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -116,6 +116,11 @@ pub(super) fn handle_needs( ignore_reason: "ignored when dlltool for x86_64 is not present", }, Need { + name: "needs-dlltool", + condition: cache.dlltool, + ignore_reason: "ignored when dlltool for the current architecture is not present", + }, + Need { name: "needs-git-hash", condition: config.git_hash, ignore_reason: "ignored when git hashes have been omitted for building", @@ -183,6 +188,7 @@ pub(super) struct CachedNeedsConditions { rust_lld: bool, i686_dlltool: bool, x86_64_dlltool: bool, + dlltool: bool, } impl CachedNeedsConditions { @@ -190,6 +196,17 @@ impl CachedNeedsConditions { let path = std::env::var_os("PATH").expect("missing PATH environment variable"); let path = std::env::split_paths(&path).collect::<Vec<_>>(); + // On Windows, dlltool.exe is used for all architectures. + #[cfg(windows)] + let dlltool = path.iter().any(|dir| dir.join("dlltool.exe").is_file()); + + // For non-Windows, there are architecture specific dlltool binaries. + #[cfg(not(windows))] + let i686_dlltool = path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file()); + #[cfg(not(windows))] + let x86_64_dlltool = + path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file()); + let target = &&*config.target; Self { sanitizer_support: std::env::var_os("RUSTC_SANITIZER_SUPPORT").is_some(), @@ -225,17 +242,26 @@ impl CachedNeedsConditions { .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" }) .exists(), - // On Windows, dlltool.exe is used for all architectures. #[cfg(windows)] - i686_dlltool: path.iter().any(|dir| dir.join("dlltool.exe").is_file()), + i686_dlltool: dlltool, #[cfg(windows)] - x86_64_dlltool: path.iter().any(|dir| dir.join("dlltool.exe").is_file()), + x86_64_dlltool: dlltool, + #[cfg(windows)] + dlltool, // For non-Windows, there are architecture specific dlltool binaries. #[cfg(not(windows))] - i686_dlltool: path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file()), + i686_dlltool, + #[cfg(not(windows))] + x86_64_dlltool, #[cfg(not(windows))] - x86_64_dlltool: path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file()), + dlltool: if config.matches_arch("x86") { + i686_dlltool + } else if config.matches_arch("x86_64") { + x86_64_dlltool + } else { + false + }, } } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 0fd9f3ae3f4..4ede4603789 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1385,7 +1385,9 @@ impl<'test> TestCx<'test> { let actual_errors = json::parse_output(&diagnostic_file_name, &proc_res.stderr, proc_res); let mut unexpected = Vec::new(); let mut found = vec![false; expected_errors.len()]; - for actual_error in &actual_errors { + for mut actual_error in actual_errors { + actual_error.msg = self.normalize_output(&actual_error.msg, &[]); + let opt_index = expected_errors.iter().enumerate().position(|(index, expected_error)| { !found[index] @@ -1404,7 +1406,8 @@ impl<'test> TestCx<'test> { None => { // If the test is a known bug, don't require that the error is annotated - if self.is_unexpected_compiler_message(actual_error, expect_help, expect_note) { + if self.is_unexpected_compiler_message(&actual_error, expect_help, expect_note) + { self.error(&format!( "{}:{}: unexpected {}: '{}'", file_name, @@ -1480,7 +1483,16 @@ impl<'test> TestCx<'test> { } fn compile_test(&self, will_execute: WillExecute, emit: Emit) -> ProcRes { - self.compile_test_general(will_execute, emit, self.props.local_pass_mode()) + self.compile_test_general(will_execute, emit, self.props.local_pass_mode(), Vec::new()) + } + + fn compile_test_with_passes( + &self, + will_execute: WillExecute, + emit: Emit, + passes: Vec<String>, + ) -> ProcRes { + self.compile_test_general(will_execute, emit, self.props.local_pass_mode(), passes) } fn compile_test_general( @@ -1488,6 +1500,7 @@ impl<'test> TestCx<'test> { will_execute: WillExecute, emit: Emit, local_pm: Option<PassMode>, + passes: Vec<String>, ) -> ProcRes { // Only use `make_exe_name` when the test ends up being executed. let output_file = match will_execute { @@ -1524,6 +1537,7 @@ impl<'test> TestCx<'test> { emit, allow_unused, LinkToAux::Yes, + passes, ); self.compose_and_run_compiler(rustc, None) @@ -1774,6 +1788,7 @@ impl<'test> TestCx<'test> { Emit::None, AllowUnused::No, LinkToAux::No, + Vec::new(), ); for key in &aux_props.unset_rustc_env { @@ -1905,6 +1920,7 @@ impl<'test> TestCx<'test> { emit: Emit, allow_unused: AllowUnused, link_to_aux: LinkToAux, + passes: Vec<String>, // Vec of passes under mir-opt test to be dumped ) -> Command { let is_aux = input_file.components().map(|c| c.as_os_str()).any(|c| c == "auxiliary"); let is_rustdoc = self.is_rustdoc() && !is_aux; @@ -2005,9 +2021,18 @@ impl<'test> TestCx<'test> { rustc.arg("-Cstrip=debuginfo"); } MirOpt => { + // We check passes under test to minimize the mir-opt test dump + // if files_for_miropt_test parses the passes, we dump only those passes + // otherwise we conservatively pass -Zdump-mir=all + let zdump_arg = if !passes.is_empty() { + format!("-Zdump-mir={}", passes.join(" | ")) + } else { + "-Zdump-mir=all".to_string() + }; + rustc.args(&[ "-Copt-level=1", - "-Zdump-mir=all", + &zdump_arg, "-Zvalidate-mir", "-Zdump-mir-exclude-pass-number", "-Zmir-pretty-relative-line-numbers=yes", @@ -2330,6 +2355,7 @@ impl<'test> TestCx<'test> { Emit::LlvmIr, AllowUnused::No, LinkToAux::Yes, + Vec::new(), ); self.compose_and_run_compiler(rustc, None) @@ -2361,8 +2387,14 @@ impl<'test> TestCx<'test> { None => self.fatal("missing 'assembly-output' header"), } - let rustc = - self.make_compile_args(input_file, output_file, emit, AllowUnused::No, LinkToAux::Yes); + let rustc = self.make_compile_args( + input_file, + output_file, + emit, + AllowUnused::No, + LinkToAux::Yes, + Vec::new(), + ); (self.compose_and_run_compiler(rustc, None), output_path) } @@ -2493,6 +2525,7 @@ impl<'test> TestCx<'test> { Emit::None, AllowUnused::Yes, LinkToAux::Yes, + Vec::new(), ); new_rustdoc.build_all_auxiliary(&mut rustc); @@ -3307,7 +3340,8 @@ impl<'test> TestCx<'test> { if let Some(FailMode::Build) = self.props.fail_mode { // Make sure a build-fail test cannot fail due to failing analysis (e.g. typeck). let pm = Some(PassMode::Check); - let proc_res = self.compile_test_general(WillExecute::No, Emit::Metadata, pm); + let proc_res = + self.compile_test_general(WillExecute::No, Emit::Metadata, pm, Vec::new()); self.check_if_test_should_compile(&proc_res, pm); } @@ -3476,6 +3510,7 @@ impl<'test> TestCx<'test> { emit_metadata, AllowUnused::No, LinkToAux::Yes, + Vec::new(), ); let res = self.compose_and_run_compiler(rustc, None); if !res.status.success() { @@ -3494,14 +3529,14 @@ impl<'test> TestCx<'test> { let pm = self.pass_mode(); let should_run = self.should_run(pm); let emit_metadata = self.should_emit_metadata(pm); - let proc_res = self.compile_test(should_run, emit_metadata); + let passes = self.get_passes(); + let proc_res = self.compile_test_with_passes(should_run, emit_metadata, passes); + self.check_mir_dump(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); } - self.check_mir_dump(); - if let WillExecute::Yes = should_run { let proc_res = self.exec_compiled_test(); @@ -3511,6 +3546,26 @@ impl<'test> TestCx<'test> { } } + fn get_passes(&self) -> Vec<String> { + let files = miropt_test_tools::files_for_miropt_test( + &self.testpaths.file, + self.config.get_pointer_width(), + ); + + let mut out = Vec::new(); + + for miropt_test_tools::MiroptTestFiles { + from_file: _, + to_file: _, + expected_file: _, + passes, + } in files + { + out.extend(passes); + } + out + } + fn check_mir_dump(&self) { let test_file_contents = fs::read_to_string(&self.testpaths.file).unwrap(); @@ -3540,8 +3595,9 @@ impl<'test> TestCx<'test> { &self.testpaths.file, self.config.get_pointer_width(), ); - - for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file } in files { + for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file, passes: _ } in + files + { let dumped_string = if let Some(after) = to_file { self.diff_mir_files(from_file.into(), after.into()) } else { diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 46deebf2cdd..10079ba85b6 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -27,6 +27,12 @@ dependencies = [ ] [[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" + +[[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -292,9 +298,9 @@ dependencies = [ [[package]] name = "libffi-sys" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc65067b78c0fc069771e8b9a9e02df71e08858bec92c1f101377c67b9dca7c7" +checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c" dependencies = [ "cc", ] @@ -571,6 +577,18 @@ dependencies = [ ] [[package]] +name = "rustfix" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd2853d9e26988467753bd9912c3a126f642d05d229a4b53f5752ee36c56481" +dependencies = [ + "anyhow", + "log", + "serde", + "serde_json", +] + +[[package]] name = "ryu" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -744,11 +762,12 @@ dependencies = [ [[package]] name = "ui_test" -version = "0.5.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ddb6f31025943e2f9d59237f433711c461a43d9415974c3eb3a4902edc1c1f" +checksum = "3e10f5f88ce8c331a388deda1e6e2bd533c73ca89cc5f539a3df02ed35c8efba" dependencies = [ "bstr", + "cargo-platform", "cargo_metadata", "color-eyre", "colored", @@ -757,6 +776,7 @@ dependencies = [ "lazy_static", "regex", "rustc_version", + "rustfix", "serde", "serde_json", "tempfile", diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 6705bf7b007..b962d0c1096 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -39,7 +39,7 @@ libloading = "0.7" [dev-dependencies] colored = "2" -ui_test = "0.5" +ui_test = "0.6.2" rustc_version = "0.4" # Features chosen to match those required by env_logger, to avoid rebuilds regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] } diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 04a1d939d2e..640a953dac9 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -407,7 +407,7 @@ to Miri failing to detect cases of undefined behavior in a program. * `-Zmiri-retag-fields=<all|none|scalar>` controls when Stacked Borrows retagging recurses into fields. `all` means it always recurses (like `-Zmiri-retag-fields`), `none` means it never recurses, `scalar` (the default) means it only recurses for types where we would also emit - `noalias` annotations in the generated LLVM IR (types passed as indivudal scalars or pairs of + `noalias` annotations in the generated LLVM IR (types passed as individual scalars or pairs of scalars). Setting this to `none` is **unsound**. * `-Zmiri-tag-gc=<blocks>` configures how often the pointer tag garbage collector runs. The default is to search for and remove unreachable tags once every `10000` basic blocks. Setting this to diff --git a/src/tools/miri/cargo-miri/src/main.rs b/src/tools/miri/cargo-miri/src/main.rs index 9b5fa7ae873..85c9cdad7df 100644 --- a/src/tools/miri/cargo-miri/src/main.rs +++ b/src/tools/miri/cargo-miri/src/main.rs @@ -81,7 +81,7 @@ fn main() { "miri" => phase_cargo_miri(args), "runner" => phase_runner(args, RunnerPhase::Cargo), arg if arg == env::var("RUSTC").unwrap() => { - // If the first arg is equal to the RUSTC env ariable (which should be set at this + // If the first arg is equal to the RUSTC env variable (which should be set at this // point), then we need to behave as rustc. This is the somewhat counter-intuitive // behavior of having both RUSTC and RUSTC_WRAPPER set // (see https://github.com/rust-lang/cargo/issues/10886). diff --git a/src/tools/miri/miri b/src/tools/miri/miri index 1073ff499ba..4be970b398d 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -121,10 +121,10 @@ rustc-pull) # Update rust-version file. As a separate commit, since making it part of # the merge has confused the heck out of josh in the past. echo "$FETCH_COMMIT" > rust-version - git commit rust-version -m "Preparing for merge from rustc" + git commit rust-version -m "Preparing for merge from rustc" || (echo "FAILED to commit rust-version file, something went wrong"; exit 1) # Fetch given rustc commit and note down which one that was - git fetch http://localhost:8000/rust-lang/rust.git@$FETCH_COMMIT$JOSH_FILTER.git - git merge FETCH_HEAD --no-ff -m "Merge from rustc" + git fetch http://localhost:8000/rust-lang/rust.git@$FETCH_COMMIT$JOSH_FILTER.git || (echo "FAILED to fetch new commits, something went wrong"; exit 1) + git merge FETCH_HEAD --no-ff -m "Merge from rustc" || (echo "FAILED to merge new commits, something went wrong"; exit 1) exit 0 ;; rustc-push) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index f1ed3be2edd..d4bffe5f945 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -d4be8efc6296bace5b1e165f1b34d3c6da76aa8e +eb62877597000ccf8bb99ab131b5977344afdfa3 diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 3aa71bb7e3c..65bc004fc4a 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -120,7 +120,7 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { #[allow(rustc::potential_query_instability)] // rustc_codegen_ssa (where this code is copied from) also allows this lint fn config(&mut self, config: &mut Config) { if config.opts.prints.is_empty() && self.target_crate { - // Queries overriden here affect the data stored in `rmeta` files of dependencies, + // Queries overridden here affect the data stored in `rmeta` files of dependencies, // which will be used later in non-`MIRI_BE_RUSTC` mode. config.override_queries = Some(|_, local_providers, _| { // `exported_symbols` and `reachable_non_generics` provided by rustc always returns @@ -286,11 +286,10 @@ fn main() { // (`install_ice_hook` might change `RUST_BACKTRACE`.) let env_snapshot = env::vars_os().collect::<Vec<_>>(); - // Earliest rustc setup. - rustc_driver::install_ice_hook(); - // If the environment asks us to actually be rustc, then do that. if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") { + // Earliest rustc setup. + rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ()); rustc_driver::init_rustc_env_logger(); let target_crate = if crate_kind == "target" { @@ -309,6 +308,9 @@ fn main() { ) } + // Add an ICE bug report hook. + rustc_driver::install_ice_hook("https://github.com/rust-lang/miri/issues/new", |_| ()); + // Init loggers the Miri way. init_early_loggers(); diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index d54adb72887..ffc49eedb5a 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -238,7 +238,7 @@ pub enum BorrowTrackerMethod { } impl BorrowTrackerMethod { - pub fn instanciate_global_state(self, config: &MiriConfig) -> GlobalState { + pub fn instantiate_global_state(self, config: &MiriConfig) -> GlobalState { RefCell::new(GlobalStateInner::new( self, config.tracked_pointer_tags.clone(), diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs index 2cc8f035466..c9674e0a2fe 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs @@ -292,7 +292,7 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { .rev() .find_map(|event| { // First, look for a Creation event where the tag and the offset matches. This - // ensrues that we pick the right Creation event when a retag isn't uniform due to + // ensures that we pick the right Creation event when a retag isn't uniform due to // Freeze. let range = event.retag.range; if event.retag.new_tag == tag diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index b766916402e..4d7bbb643b8 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -433,7 +433,7 @@ impl<'tcx> Stack { let (Some(granting_idx), ProvenanceExtra::Concrete(_)) = (granting_idx, derived_from) else { // The parent is a wildcard pointer or matched the unknown bottom. // This is approximate. Nobody knows what happened, so forget everything. - // The new thing is SRW anyway, so we cannot push it "on top of the unkown part" + // The new thing is SRW anyway, so we cannot push it "on top of the unknown part" // (for all we know, it might join an SRW group inside the unknown). trace!("reborrow: forgetting stack entirely due to SharedReadWrite reborrow from wildcard or unknown"); self.set_unknown_bottom(global.next_ptr_tag); @@ -825,7 +825,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' Ok(Some(alloc_id)) } - /// Retags an indidual pointer, returning the retagged version. + /// Retags an individual pointer, returning the retagged version. /// `kind` indicates what kind of reference is being created. fn sb_retag_reference( &mut self, diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs index 1d5cfec3500..064dbe025af 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs @@ -51,7 +51,7 @@ impl Stack { // Note that the algorithm below is based on considering the tag at read_idx - 1, // so precisely considering the tag at index 0 for removal when we have an unknown // bottom would complicate the implementation. The simplification of not considering - // it does not have a significant impact on the degree to which the GC mititages + // it does not have a significant impact on the degree to which the GC mitigates // memory growth. let mut read_idx = 1; let mut write_idx = read_idx; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index 97bbdee1d44..2c6d27ced01 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -1,14 +1,90 @@ -use rustc_data_structures::fx::FxHashMap; - use std::fmt; use std::ops::Range; +use rustc_data_structures::fx::FxHashMap; +use rustc_span::{Span, SpanData}; +use rustc_target::abi::Size; + use crate::borrow_tracker::tree_borrows::{ - err_tb_ub, perms::Permission, tree::LocationState, unimap::UniIndex, + perms::{PermTransition, Permission}, + tree::LocationState, + unimap::UniIndex, }; use crate::borrow_tracker::{AccessKind, ProtectorKind}; use crate::*; +/// Complete data for an event: +/// - `kind` is what happened to the permissions +/// - `access_kind` and `access_range` describe the access that caused the event +/// - `offset` allows filtering only the relevant events for a given memory location +/// (see how we perform the filtering in `History::extract_relevant`. +/// - `span` is the line of code in question +#[derive(Clone, Debug)] +pub struct Event { + pub transition: PermTransition, + pub access_kind: AccessKind, + pub is_foreign: bool, + pub access_range: AllocRange, + pub offset: Size, + pub span: Span, +} + +/// List of all events that affected a tag. +/// NOTE: not all of these events are relevant for a particular location, +/// the events should be filtered before the generation of diagnostics. +/// Available filtering methods include `History::forget` and `History::extract_relevant`. +#[derive(Clone, Debug)] +pub struct History { + pub tag: BorTag, + pub created: (Span, Permission), + pub events: Vec<Event>, +} + +/// History formatted for use by `src/diagnostics.rs`. +/// +/// NOTE: needs to be `Send` because of a bound on `MachineStopType`, hence +/// the use of `SpanData` rather than `Span`. +#[derive(Debug, Clone, Default)] +pub struct HistoryData { + pub events: Vec<(Option<SpanData>, String)>, // includes creation +} + +impl History { + /// Record an additional event to the history. + pub fn push(&mut self, event: Event) { + self.events.push(event); + } +} + +impl HistoryData { + // Format events from `new_history` into those recorded by `self`. + // + // NOTE: also converts `Span` to `SpanData`. + pub fn extend( + &mut self, + new_history: History, + tag_name: &'static str, + show_initial_state: bool, + ) { + let History { tag, created, events } = new_history; + let this = format!("the {tag_name} tag {tag:?}"); + let msg_initial_state = format!(", in the initial state {}", created.1); + let msg_creation = format!( + "{this} was created here{maybe_msg_initial_state}", + maybe_msg_initial_state = if show_initial_state { &msg_initial_state } else { "" }, + ); + + self.events.push((Some(created.0.data()), msg_creation)); + for &Event { transition, access_kind, is_foreign, access_range, span, offset: _ } in &events + { + // NOTE: `offset` is explicitly absent from the error message, it has no significance + // to the user. The meaningful one is `access_range`. + self.events.push((Some(span.data()), format!("{this} then transitioned {transition} due to a {rel} {access_kind} at offsets {access_range:?}", rel = if is_foreign { "foreign" } else { "child" }))); + self.events.push((None, format!("this corresponds to {}", transition.summary()))); + } + } +} + /// Some information that is irrelevant for the algorithm but very /// convenient to know about a tag for debugging and testing. #[derive(Clone, Debug)] @@ -20,18 +96,29 @@ pub struct NodeDebugInfo { /// pointer in the source code. /// Helps match tag numbers to human-readable names. pub name: Option<String>, + /// Notable events in the history of this tag, used for + /// diagnostics. + /// + /// NOTE: by virtue of being part of `NodeDebugInfo`, + /// the history is automatically cleaned up by the GC. + /// NOTE: this is `!Send`, it needs to be converted before displaying + /// the actual diagnostics because `src/diagnostics.rs` requires `Send`. + pub history: History, } + impl NodeDebugInfo { - /// New node info with a name. - pub fn new(tag: BorTag) -> Self { - Self { tag, name: None } + /// Information for a new node. By default it has no + /// name and an empty history. + pub fn new(tag: BorTag, initial: Permission, span: Span) -> Self { + let history = History { tag, created: (span, initial), events: Vec::new() }; + Self { tag, name: None, history } } /// Add a name to the tag. If a same tag is associated to several pointers, /// it can have several names which will be separated by commas. - fn add_name(&mut self, name: &str) { + pub fn add_name(&mut self, name: &str) { if let Some(ref mut prev_name) = &mut self.name { - prev_name.push(','); + prev_name.push_str(", "); prev_name.push_str(name); } else { self.name = Some(String::from(name)); @@ -42,7 +129,7 @@ impl NodeDebugInfo { impl fmt::Display for NodeDebugInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(ref name) = self.name { - write!(f, "{tag:?} (also named '{name}')", tag = self.tag) + write!(f, "{tag:?} ({name})", tag = self.tag) } else { write!(f, "{tag:?}", tag = self.tag) } @@ -86,7 +173,7 @@ impl<'tcx> Tree { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub(super) enum TransitionError { /// This access is not allowed because some parent tag has insufficient permissions. /// For example, if a tag is `Frozen` and encounters a child write this will @@ -96,63 +183,145 @@ pub(super) enum TransitionError { /// A protector was triggered due to an invalid transition that loses /// too much permissions. /// For example, if a protected tag goes from `Active` to `Frozen` due - /// to a foreign write this will produce a `ProtectedTransition(Active, Frozen)`. + /// to a foreign write this will produce a `ProtectedTransition(PermTransition(Active, Frozen))`. /// This kind of error can only occur on foreign accesses. - ProtectedTransition(Permission, Permission), + ProtectedTransition(PermTransition), /// Cannot deallocate because some tag in the allocation is strongly protected. /// This kind of error can only occur on deallocations. ProtectedDealloc, } +impl History { + /// Keep only the tag and creation + fn forget(&self) -> Self { + History { events: Vec::new(), created: self.created, tag: self.tag } + } + + /// Reconstruct the history relevant to `error_offset` knowing that + /// its permission followed `complete_transition`. + /// + /// Here's how we do this: + /// - we know `full := complete_transition` the transition of the permission from + /// its initialization to the state just before the error was caused, + /// we want to find a chain of events that produces `full` + /// - we decompose `full` into `pre o post` where + /// `pre` is the best applicable transition from recorded events + /// - we select the event that caused `pre` and iterate + /// to find the chain of events that produces `full := post` + /// + /// To find the "best applicable transition" for full: + /// - eliminate events that cannot be applied because their offset is too big + /// - eliminate events that cannot be applied because their starting point is wrong + /// - select the one that happened closest to the range of interest + fn extract_relevant(&self, complete_transition: PermTransition, error_offset: Size) -> Self { + let mut selected_events: Vec<Event> = Vec::new(); + let mut full = complete_transition; + while !full.is_noop() { + let (pre, post) = self + .events + .iter() + .filter(|e| e.offset <= error_offset) + .filter_map(|pre_canditate| { + full.apply_start(pre_canditate.transition) + .map(|post_canditate| (pre_canditate, post_canditate)) + }) + .max_by_key(|(pre_canditate, _post_candidate)| pre_canditate.offset) + .unwrap(); + // If this occurs we will loop infinitely ! + // Make sure to only put non-noop transitions in `History`. + assert!(!pre.transition.is_noop()); + full = post; + selected_events.push(pre.clone()); + } + + History { events: selected_events, created: self.created, tag: self.tag } + } +} + /// Failures that can occur during the execution of Tree Borrows procedures. pub(super) struct TbError<'node> { /// What failure occurred. pub error_kind: TransitionError, + /// The byte at which the conflict occured. + pub error_offset: Size, /// The tag on which the error was triggered. /// On protector violations, this is the tag that was protected. /// On accesses rejected due to insufficient permissions, this is the /// tag that lacked those permissions. - pub faulty_tag: &'node NodeDebugInfo, + pub conflicting_info: &'node NodeDebugInfo, /// Whether this was a Read or Write access. This field is ignored /// when the error was triggered by a deallocation. pub access_kind: AccessKind, /// Which tag the access that caused this error was made through, i.e. /// which tag was used to read/write/deallocate. - pub tag_of_access: &'node NodeDebugInfo, + pub accessed_info: &'node NodeDebugInfo, } impl TbError<'_> { /// Produce a UB error. - pub fn build<'tcx>(self) -> InterpErrorInfo<'tcx> { + pub fn build<'tcx>(self) -> InterpError<'tcx> { use TransitionError::*; - err_tb_ub(match self.error_kind { + let started_as = self.conflicting_info.history.created.1; + let kind = self.access_kind; + let accessed = self.accessed_info; + let conflicting = self.conflicting_info; + let accessed_is_conflicting = accessed.tag == conflicting.tag; + let (pre_error, title, details, conflicting_tag_name) = match self.error_kind { ChildAccessForbidden(perm) => { - format!( - "{kind} through {initial} is forbidden because it is a child of {current} which is {perm}.", - kind=self.access_kind, - initial=self.tag_of_access, - current=self.faulty_tag, - perm=perm, - ) + let conflicting_tag_name = + if accessed_is_conflicting { "accessed" } else { "conflicting" }; + let title = format!("{kind} through {accessed} is forbidden"); + let mut details = Vec::new(); + if !accessed_is_conflicting { + details.push(format!( + "the accessed tag {accessed} is a child of the conflicting tag {conflicting}" + )); + } + details.push(format!( + "the {conflicting_tag_name} tag {conflicting} has state {perm} which forbids child {kind}es" + )); + (perm, title, details, conflicting_tag_name) } - ProtectedTransition(start, end) => { - format!( - "{kind} through {initial} is forbidden because it is a foreign tag for {current}, which would hence change from {start} to {end}, but {current} is protected", - current=self.faulty_tag, - start=start, - end=end, - kind=self.access_kind, - initial=self.tag_of_access, - ) + ProtectedTransition(transition) => { + let conflicting_tag_name = "protected"; + let title = format!("{kind} through {accessed} is forbidden"); + let details = vec![ + format!( + "the accessed tag {accessed} is foreign to the {conflicting_tag_name} tag {conflicting} (i.e., it is not a child)" + ), + format!( + "the access would cause the {conflicting_tag_name} tag {conflicting} to transition {transition}" + ), + format!( + "this is {loss}, which is not allowed for protected tags", + loss = transition.summary(), + ), + ]; + (transition.started(), title, details, conflicting_tag_name) } ProtectedDealloc => { - format!( - "the allocation of {initial} also contains {current} which is strongly protected, cannot deallocate", - initial=self.tag_of_access, - current=self.faulty_tag, - ) + let conflicting_tag_name = "strongly protected"; + let title = format!("deallocation through {accessed} is forbidden"); + let details = vec![ + format!( + "the allocation of the accessed tag {accessed} also contains the {conflicting_tag_name} tag {conflicting}" + ), + format!("the {conflicting_tag_name} tag {conflicting} disallows deallocations"), + ]; + (started_as, title, details, conflicting_tag_name) } - }).into() + }; + let pre_transition = PermTransition::from(started_as, pre_error).unwrap(); + let mut history = HistoryData::default(); + if !accessed_is_conflicting { + history.extend(self.accessed_info.history.forget(), "accessed", false); + } + history.extend( + self.conflicting_info.history.extract_relevant(pre_transition, self.error_offset), + conflicting_tag_name, + true, + ); + err_machine_stop!(TerminationInfo::TreeBorrowsUb { title, details, history }) } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 2297ceb1259..3361d212f2c 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -14,7 +14,7 @@ use rustc_middle::{ use crate::*; -mod diagnostics; +pub mod diagnostics; mod perms; mod tree; mod unimap; @@ -23,10 +23,6 @@ pub use tree::Tree; pub type AllocState = Tree; -pub fn err_tb_ub<'tcx>(msg: String) -> InterpError<'tcx> { - err_machine_stop!(TerminationInfo::TreeBorrowsUb { msg }) -} - impl<'tcx> Tree { /// Create a new allocation, i.e. a new tree pub fn new_allocation( @@ -37,7 +33,8 @@ impl<'tcx> Tree { machine: &MiriMachine<'_, 'tcx>, ) -> Self { let tag = state.base_ptr_tag(id, machine); // Fresh tag for the root - Tree::new(tag, size) + let span = machine.current_span(); + Tree::new(tag, size, span) } /// Check that an access on the entire range is permitted, and update @@ -64,7 +61,8 @@ impl<'tcx> Tree { ProvenanceExtra::Wildcard => return Ok(()), }; let global = machine.borrow_tracker.as_ref().unwrap(); - self.perform_access(access_kind, tag, range, global) + let span = machine.current_span(); + self.perform_access(access_kind, tag, range, global, span) } /// Check that this pointer has permission to deallocate this range. @@ -82,7 +80,8 @@ impl<'tcx> Tree { ProvenanceExtra::Wildcard => return Ok(()), }; let global = machine.borrow_tracker.as_ref().unwrap(); - self.dealloc(tag, range, global) + let span = machine.current_span(); + self.dealloc(tag, range, global, span) } pub fn expose_tag(&mut self, _tag: BorTag) { @@ -265,6 +264,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' .insert(new_tag, protect); } + let span = this.machine.current_span(); let alloc_extra = this.get_alloc_extra(alloc_id)?; let range = alloc_range(base_offset, ptr_size); let mut tree_borrows = alloc_extra.borrow_tracker_tb().borrow_mut(); @@ -272,18 +272,19 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' if new_perm.perform_read_access { // Count this reborrow as a read access let global = &this.machine.borrow_tracker.as_ref().unwrap(); - tree_borrows.perform_access(AccessKind::Read, orig_tag, range, global)?; + let span = this.machine.current_span(); + tree_borrows.perform_access(AccessKind::Read, orig_tag, range, global, span)?; if let Some(data_race) = alloc_extra.data_race.as_ref() { data_race.read(alloc_id, range, &this.machine)?; } } // Record the parent-child pair in the tree. - tree_borrows.new_child(orig_tag, new_tag, new_perm.initial_state, range)?; + tree_borrows.new_child(orig_tag, new_tag, new_perm.initial_state, range, span)?; Ok(Some((alloc_id, new_tag))) } - /// Retags an indidual pointer, returning the retagged version. + /// Retags an individual pointer, returning the retagged version. fn tb_retag_reference( &mut self, val: &ImmTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs index 04b8e1df576..7e3e587db72 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs @@ -4,7 +4,7 @@ use std::fmt; use crate::borrow_tracker::tree_borrows::tree::AccessRelatedness; use crate::borrow_tracker::AccessKind; -/// The activation states of a pointer +/// The activation states of a pointer. #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum PermissionPriv { /// represents: a local reference that has not yet been written to; @@ -112,47 +112,14 @@ mod transition { } } -impl PermissionPriv { - /// Determines whether a transition that occured is compatible with the presence - /// of a Protector. This is not included in the `transition` functions because - /// it would distract from the few places where the transition is modified - /// because of a protector, but not forbidden. - fn protector_allows_transition(self, new: Self) -> bool { - match (self, new) { - _ if self == new => true, - // It is always a protector violation to not be readable anymore - (_, Disabled) => false, - // In the case of a `Reserved` under a protector, both transitions - // `Reserved => Active` and `Reserved => Frozen` can legitimately occur. - // The first is standard (Child Write), the second is for Foreign Writes - // on protected Reserved where we must ensure that the pointer is not - // written to in the future. - (Reserved { .. }, Active) | (Reserved { .. }, Frozen) => true, - // This pointer should have stayed writeable for the whole function - (Active, Frozen) => false, - _ => unreachable!("Transition from {self:?} to {new:?} should never be possible"), - } - } -} - /// Public interface to the state machine that controls read-write permissions. +/// This is the "private `enum`" pattern. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Permission(PermissionPriv); -impl fmt::Display for Permission { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{}", - match self.0 { - PermissionPriv::Reserved { .. } => "Reserved", - PermissionPriv::Active => "Active", - PermissionPriv::Frozen => "Frozen", - PermissionPriv::Disabled => "Disabled", - } - ) - } -} +/// Transition from one permission to the next. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct PermTransition(PermissionPriv, PermissionPriv); impl Permission { /// Default initial permission of the root of a new tree. @@ -170,43 +137,148 @@ impl Permission { Self(Frozen) } - /// Pretty-printing. Needs to be here and not in diagnostics.rs - /// because `Self` is private. - pub fn short_name(self) -> &'static str { - // Make sure there are all of the same length as each other - // and also as `diagnostics::DisplayFmtPermission.uninit` otherwise - // alignment will be incorrect. - match self.0 { - Reserved { ty_is_freeze: true } => "Res", - Reserved { ty_is_freeze: false } => "Re*", - Active => "Act", - Frozen => "Frz", - Disabled => "Dis", - } + /// Apply the transition to the inner PermissionPriv. + pub fn perform_access( + kind: AccessKind, + rel_pos: AccessRelatedness, + old_perm: Self, + protected: bool, + ) -> Option<PermTransition> { + let old_state = old_perm.0; + transition::perform_access(kind, rel_pos, old_state, protected) + .map(|new_state| PermTransition(old_state, new_state)) } +} - /// Check that there are no complaints from a possible protector. +impl PermTransition { + /// All transitions created through normal means (using `perform_access`) + /// should be possible, but the same is not guaranteed by construction of + /// transitions inferred by diagnostics. This checks that a transition + /// reconstructed by diagnostics is indeed one that could happen. + fn is_possible(old: PermissionPriv, new: PermissionPriv) -> bool { + old <= new + } + + pub fn from(old: Permission, new: Permission) -> Option<Self> { + Self::is_possible(old.0, new.0).then_some(Self(old.0, new.0)) + } + + pub fn is_noop(self) -> bool { + self.0 == self.1 + } + + /// Extract result of a transition (checks that the starting point matches). + pub fn applied(self, starting_point: Permission) -> Option<Permission> { + (starting_point.0 == self.0).then_some(Permission(self.1)) + } + + /// Extract starting point of a transition + pub fn started(self) -> Permission { + Permission(self.0) + } + + /// Determines whether a transition that occured is compatible with the presence + /// of a Protector. This is not included in the `transition` functions because + /// it would distract from the few places where the transition is modified + /// because of a protector, but not forbidden. /// /// Note: this is not in charge of checking that there *is* a protector, /// it should be used as /// ``` /// let no_protector_error = if is_protected(tag) { - /// old_perm.protector_allows_transition(new_perm) + /// transition.is_allowed_by_protector() /// }; /// ``` - pub fn protector_allows_transition(self, new: Self) -> bool { - self.0.protector_allows_transition(new.0) + pub fn is_allowed_by_protector(&self) -> bool { + let &Self(old, new) = self; + assert!(Self::is_possible(old, new)); + match (old, new) { + _ if old == new => true, + // It is always a protector violation to not be readable anymore + (_, Disabled) => false, + // In the case of a `Reserved` under a protector, both transitions + // `Reserved => Active` and `Reserved => Frozen` can legitimately occur. + // The first is standard (Child Write), the second is for Foreign Writes + // on protected Reserved where we must ensure that the pointer is not + // written to in the future. + (Reserved { .. }, Active) | (Reserved { .. }, Frozen) => true, + // This pointer should have stayed writeable for the whole function + (Active, Frozen) => false, + _ => unreachable!("Transition from {old:?} to {new:?} should never be possible"), + } } - /// Apply the transition to the inner PermissionPriv. - pub fn perform_access( - kind: AccessKind, - rel_pos: AccessRelatedness, - old_perm: Self, - protected: bool, - ) -> Option<Self> { - let old_state = old_perm.0; - transition::perform_access(kind, rel_pos, old_state, protected).map(Self) + /// Composition function: get the transition that can be added after `app` to + /// produce `self`. + pub fn apply_start(self, app: Self) -> Option<Self> { + let new_start = app.applied(Permission(self.0))?; + Self::from(new_start, Permission(self.1)) + } +} + +pub mod diagnostics { + use super::*; + impl fmt::Display for PermissionPriv { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + PermissionPriv::Reserved { .. } => "Reserved", + PermissionPriv::Active => "Active", + PermissionPriv::Frozen => "Frozen", + PermissionPriv::Disabled => "Disabled", + } + ) + } + } + + impl fmt::Display for PermTransition { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "from {} to {}", self.0, self.1) + } + } + + impl fmt::Display for Permission { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } + } + + impl Permission { + /// Abbreviated name of the permission (uniformly 3 letters for nice alignment). + pub fn short_name(self) -> &'static str { + // Make sure there are all of the same length as each other + // and also as `diagnostics::DisplayFmtPermission.uninit` otherwise + // alignment will be incorrect. + match self.0 { + Reserved { ty_is_freeze: true } => "Res", + Reserved { ty_is_freeze: false } => "Re*", + Active => "Act", + Frozen => "Frz", + Disabled => "Dis", + } + } + } + + impl PermTransition { + /// Readable explanation of the consequences of an event. + /// Fits in the sentence "This accessed caused {trans.summary()}". + /// + /// Important: for the purposes of this explanation, `Reserved` is considered + /// to have write permissions, because that's what the diagnostics care about + /// (otherwise `Reserved -> Frozen` would be considered a noop). + pub fn summary(&self) -> &'static str { + assert!(Self::is_possible(self.0, self.1)); + match (self.0, self.1) { + (_, Active) => "an activation", + (_, Frozen) => "a loss of write permissions", + (Frozen, Disabled) => "a loss of read permissions", + (_, Disabled) => "a loss of read and write permissions", + (old, new) => + unreachable!("Transition from {old:?} to {new:?} should never be possible"), + } + } } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 86416a0eb1b..6392f5101ad 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -14,10 +14,11 @@ use smallvec::SmallVec; use rustc_const_eval::interpret::InterpResult; use rustc_data_structures::fx::FxHashSet; +use rustc_span::Span; use rustc_target::abi::Size; use crate::borrow_tracker::tree_borrows::{ - diagnostics::{NodeDebugInfo, TbError, TransitionError}, + diagnostics::{self, NodeDebugInfo, TbError, TransitionError}, unimap::{UniEntry, UniIndex, UniKeyMap, UniValMap}, Permission, }; @@ -34,7 +35,7 @@ pub(super) struct LocationState { /// Before initialization we still apply some preemptive transitions on /// `permission` to know what to do in case it ever gets initialized, /// but these can never cause any immediate UB. There can however be UB - /// the moment we attempt to initalize (i.e. child-access) because some + /// the moment we attempt to initialize (i.e. child-access) because some /// foreign access done between the creation and the initialization is /// incompatible with child accesses. initialized: bool, @@ -118,7 +119,7 @@ pub(super) struct Node { /// Data given to the transition function struct NodeAppArgs<'node> { /// Node on which the transition is currently being applied - node: &'node Node, + node: &'node mut Node, /// Mutable access to its permissions perm: UniEntry<'node, LocationState>, /// Relative position of the access @@ -131,14 +132,17 @@ struct ErrHandlerArgs<'node, InErr> { /// Tag that triggered the error (not the tag that was accessed, /// rather the parent tag that had insufficient permissions or the /// non-parent tag that had a protector). - faulty_tag: &'node NodeDebugInfo, + conflicting_info: &'node NodeDebugInfo, + /// Information about the tag that was accessed just before the + /// error was triggered. + accessed_info: &'node NodeDebugInfo, } /// Internal contents of `Tree` with the minimum of mutable access for /// the purposes of the tree traversal functions: the permissions (`perms`) can be /// updated but not the tree structure (`tag_mapping` and `nodes`) struct TreeVisitor<'tree> { tag_mapping: &'tree UniKeyMap<BorTag>, - nodes: &'tree UniValMap<Node>, + nodes: &'tree mut UniValMap<Node>, perms: &'tree mut UniValMap<LocationState>, } @@ -167,6 +171,7 @@ impl<'tree> TreeVisitor<'tree> { ) -> Result<(), OutErr> where { struct TreeVisitAux<NodeApp, ErrHandler> { + accessed_tag: UniIndex, f_propagate: NodeApp, err_builder: ErrHandler, stack: Vec<(UniIndex, AccessRelatedness)>, @@ -190,15 +195,21 @@ where { rel_pos: AccessRelatedness, ) -> Result<(), OutErr> { // 1. apply the propagation function - let node = this.nodes.get(tag).unwrap(); + let node = this.nodes.get_mut(tag).unwrap(); let recurse = (self.f_propagate)(NodeAppArgs { node, perm: this.perms.entry(tag), rel_pos }) .map_err(|error_kind| { (self.err_builder)(ErrHandlerArgs { error_kind, - faulty_tag: &node.debug_info, + conflicting_info: &this.nodes.get(tag).unwrap().debug_info, + accessed_info: &this + .nodes + .get(self.accessed_tag) + .unwrap() + .debug_info, }) })?; + let node = this.nodes.get(tag).unwrap(); // 2. add the children to the stack for future traversal if matches!(recurse, ContinueTraversal::Recurse) { let child_rel = rel_pos.for_child(); @@ -214,7 +225,8 @@ where { } let start_idx = self.tag_mapping.get(&start).unwrap(); - let mut stack = TreeVisitAux { f_propagate, err_builder, stack: Vec::new() }; + let mut stack = + TreeVisitAux { accessed_tag: start_idx, f_propagate, err_builder, stack: Vec::new() }; { let mut path_ascend = Vec::new(); // First climb to the root while recording the path @@ -262,12 +274,15 @@ where { impl Tree { /// Create a new tree, with only a root pointer. - pub fn new(root_tag: BorTag, size: Size) -> Self { + pub fn new(root_tag: BorTag, size: Size, span: Span) -> Self { let root_perm = Permission::new_root(); let mut tag_mapping = UniKeyMap::default(); let root_idx = tag_mapping.insert(root_tag); let nodes = { let mut nodes = UniValMap::<Node>::default(); + let mut debug_info = NodeDebugInfo::new(root_tag, root_perm, span); + // name the root so that all allocations contain one named pointer + debug_info.add_name("root of the allocation"); nodes.insert( root_idx, Node { @@ -275,7 +290,7 @@ impl Tree { parent: None, children: SmallVec::default(), default_initial_perm: root_perm, - debug_info: NodeDebugInfo::new(root_tag), + debug_info, }, ); nodes @@ -297,6 +312,7 @@ impl<'tcx> Tree { new_tag: BorTag, default_initial_perm: Permission, range: AllocRange, + span: Span, ) -> InterpResult<'tcx> { assert!(!self.tag_mapping.contains_key(&new_tag)); let idx = self.tag_mapping.insert(new_tag); @@ -309,7 +325,7 @@ impl<'tcx> Tree { parent: Some(parent_idx), children: SmallVec::default(), default_initial_perm, - debug_info: NodeDebugInfo::new(new_tag), + debug_info: NodeDebugInfo::new(new_tag, default_initial_perm, span), }, ); // Register new_tag as a child of parent_tag @@ -330,11 +346,11 @@ impl<'tcx> Tree { tag: BorTag, range: AllocRange, global: &GlobalState, + span: Span, // diagnostics ) -> InterpResult<'tcx> { - self.perform_access(AccessKind::Write, tag, range, global)?; - let access_info = &self.nodes.get(self.tag_mapping.get(&tag).unwrap()).unwrap().debug_info; - for (_range, perms) in self.rperms.iter_mut(range.start, range.size) { - TreeVisitor { nodes: &self.nodes, tag_mapping: &self.tag_mapping, perms } + self.perform_access(AccessKind::Write, tag, range, global, span)?; + for (offset, perms) in self.rperms.iter_mut(range.start, range.size) { + TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } .traverse_parents_this_children_others( tag, |args: NodeAppArgs<'_>| -> Result<ContinueTraversal, TransitionError> { @@ -347,13 +363,14 @@ impl<'tcx> Tree { Ok(ContinueTraversal::Recurse) } }, - |args: ErrHandlerArgs<'_, TransitionError>| -> InterpErrorInfo<'tcx> { - let ErrHandlerArgs { error_kind, faulty_tag } = args; + |args: ErrHandlerArgs<'_, TransitionError>| -> InterpError<'tcx> { + let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args; TbError { - faulty_tag, + conflicting_info, access_kind: AccessKind::Write, + error_offset: offset, error_kind, - tag_of_access: access_info, + accessed_info, } .build() }, @@ -373,10 +390,10 @@ impl<'tcx> Tree { tag: BorTag, range: AllocRange, global: &GlobalState, + span: Span, // diagnostics ) -> InterpResult<'tcx> { - let access_info = &self.nodes.get(self.tag_mapping.get(&tag).unwrap()).unwrap().debug_info; - for (_range, perms) in self.rperms.iter_mut(range.start, range.size) { - TreeVisitor { nodes: &self.nodes, tag_mapping: &self.tag_mapping, perms } + for (offset, perms) in self.rperms.iter_mut(range.start, range.size) { + TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } .traverse_parents_this_children_others( tag, |args: NodeAppArgs<'_>| -> Result<ContinueTraversal, TransitionError> { @@ -424,24 +441,42 @@ impl<'tcx> Tree { let old_perm = old_state.permission; let protected = global.borrow().protected_tags.contains_key(&node.tag); - let new_perm = + let transition = Permission::perform_access(access_kind, rel_pos, old_perm, protected) .ok_or(TransitionError::ChildAccessForbidden(old_perm))?; if protected // Can't trigger Protector on uninitialized locations && old_state.initialized - && !old_perm.protector_allows_transition(new_perm) + && !transition.is_allowed_by_protector() { - return Err(TransitionError::ProtectedTransition(old_perm, new_perm)); + return Err(TransitionError::ProtectedTransition(transition)); + } + // Record the event as part of the history + if !transition.is_noop() { + node.debug_info.history.push(diagnostics::Event { + transition, + access_kind, + access_range: range, + is_foreign: rel_pos.is_foreign(), + offset, + span, + }); + old_state.permission = + transition.applied(old_state.permission).unwrap(); } - old_state.permission = new_perm; old_state.initialized |= !rel_pos.is_foreign(); Ok(ContinueTraversal::Recurse) }, - |args: ErrHandlerArgs<'_, TransitionError>| -> InterpErrorInfo<'tcx> { - let ErrHandlerArgs { error_kind, faulty_tag } = args; - TbError { faulty_tag, access_kind, error_kind, tag_of_access: access_info } - .build() + |args: ErrHandlerArgs<'_, TransitionError>| -> InterpError<'tcx> { + let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args; + TbError { + conflicting_info, + access_kind, + error_offset: offset, + error_kind, + accessed_info, + } + .build() }, )?; } diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 1f67b91569c..13306b4809c 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -1199,7 +1199,7 @@ pub struct GlobalState { /// A flag to mark we are currently performing /// a data race free action (such as atomic access) - /// to supress the race detector + /// to suppress the race detector ongoing_action_data_race_free: Cell<bool>, /// Mapping of a vector index to a known set of thread diff --git a/src/tools/miri/src/concurrency/init_once.rs b/src/tools/miri/src/concurrency/init_once.rs index 7a6b8da4082..1f57e8b2b0a 100644 --- a/src/tools/miri/src/concurrency/init_once.rs +++ b/src/tools/miri/src/concurrency/init_once.rs @@ -151,7 +151,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!( init_once.status, InitOnceStatus::Uninitialized, - "begining already begun or complete init once" + "beginning already begun or complete init once" ); init_once.status = InitOnceStatus::Begun; } diff --git a/src/tools/miri/src/concurrency/range_object_map.rs b/src/tools/miri/src/concurrency/range_object_map.rs index dfe2e9f05da..89c009933bb 100644 --- a/src/tools/miri/src/concurrency/range_object_map.rs +++ b/src/tools/miri/src/concurrency/range_object_map.rs @@ -25,9 +25,9 @@ pub struct RangeObjectMap<T> { #[derive(Clone, Debug, PartialEq)] pub enum AccessType { - /// The access perfectly overlaps (same offset and range) with the exsiting allocation + /// The access perfectly overlaps (same offset and range) with the existing allocation PerfectlyOverlapping(Position), - /// The access does not touch any exising allocation + /// The access does not touch any existing allocation Empty(Position), /// The access overlaps with one or more existing allocations ImperfectlyOverlapping(Range<Position>), @@ -115,7 +115,7 @@ impl<T> RangeObjectMap<T> { // want to repeat the binary search on each time, so we ask the caller to supply Position pub fn insert_at_pos(&mut self, pos: Position, range: AllocRange, data: T) { self.v.insert(pos, Elem { range, data }); - // If we aren't the first element, then our start must be greater than the preivous element's end + // If we aren't the first element, then our start must be greater than the previous element's end if pos > 0 { assert!(self.v[pos - 1].range.end() <= range.start); } diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index 662dff62c88..f37a2fd2cd5 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -143,7 +143,7 @@ struct Condvar { waiters: VecDeque<CondvarWaiter>, /// Tracks the happens-before relationship /// between a cond-var signal and a cond-var - /// wait during a non-suprious signal event. + /// wait during a non-spurious signal event. /// Contains the clock of the last thread to /// perform a futex-signal. data_race: VClock, @@ -373,7 +373,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { .expect("invariant violation: lock_count == 0 iff the thread is unlocked"); if mutex.lock_count == 0 { mutex.owner = None; - // The mutex is completely unlocked. Try transfering ownership + // The mutex is completely unlocked. Try transferring ownership // to another thread. if let Some(data_race) = &this.machine.data_race { data_race.validate_lock_release( diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 5f2bc2ec558..e9bbae4d504 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -272,9 +272,8 @@ impl Time { fn get_wait_time(&self, clock: &Clock) -> Duration { match self { Time::Monotonic(instant) => instant.duration_since(clock.now()), - Time::RealTime(time) => { - time.duration_since(SystemTime::now()).unwrap_or(Duration::new(0, 0)) - } + Time::RealTime(time) => + time.duration_since(SystemTime::now()).unwrap_or(Duration::new(0, 0)), } } } @@ -823,7 +822,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // Write the current thread-id, switch to the next thread later - // to treat this write operation as occuring on the current thread. + // to treat this write operation as occurring on the current thread. if let Some(thread_info_place) = thread { this.write_scalar( Scalar::from_uint(new_thread_id.to_u32(), thread_info_place.layout.size), @@ -832,7 +831,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // Finally switch to new thread so that we can push the first stackframe. - // After this all accesses will be treated as occuring in the new thread. + // After this all accesses will be treated as occurring in the new thread. let old_thread_id = this.set_active_thread(new_thread_id); // Perform the function pointer load in the new thread frame. diff --git a/src/tools/miri/src/concurrency/vector_clock.rs b/src/tools/miri/src/concurrency/vector_clock.rs index b36c6be5a72..a6e67ef8699 100644 --- a/src/tools/miri/src/concurrency/vector_clock.rs +++ b/src/tools/miri/src/concurrency/vector_clock.rs @@ -212,16 +212,14 @@ impl PartialOrd for VClock { for (l, r) in iter { match order { Ordering::Equal => order = l.cmp(r), - Ordering::Less => { + Ordering::Less => if l > r { return None; - } - } - Ordering::Greater => { + }, + Ordering::Greater => if l < r { return None; - } - } + }, } } @@ -236,16 +234,18 @@ impl PartialOrd for VClock { Ordering::Equal => Some(order), // Right has at least 1 element > than the implicit 0, // so the only valid values are Ordering::Less or None. - Ordering::Less => match order { - Ordering::Less | Ordering::Equal => Some(Ordering::Less), - Ordering::Greater => None, - }, + Ordering::Less => + match order { + Ordering::Less | Ordering::Equal => Some(Ordering::Less), + Ordering::Greater => None, + }, // Left has at least 1 element > than the implicit 0, // so the only valid values are Ordering::Greater or None. - Ordering::Greater => match order { - Ordering::Greater | Ordering::Equal => Some(Ordering::Greater), - Ordering::Less => None, - }, + Ordering::Greater => + match order { + Ordering::Greater | Ordering::Equal => Some(Ordering::Greater), + Ordering::Less => None, + }, } } diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs index 2a48c9e6cd0..c1395468fee 100644 --- a/src/tools/miri/src/concurrency/weak_memory.rs +++ b/src/tools/miri/src/concurrency/weak_memory.rs @@ -24,7 +24,7 @@ //! However, this model lacks SC accesses and is therefore unusable by Miri (SC accesses are everywhere in library code). //! //! If you find anything that proposes a relaxed memory model that is C++20-consistent, supports all orderings Rust's atomic accesses -//! and fences accept, and is implementable (with operational semanitcs), please open a GitHub issue! +//! and fences accept, and is implementable (with operational semantics), please open a GitHub issue! //! //! One characteristic of this implementation, in contrast to some other notable operational models such as ones proposed in //! Taming Release-Acquire Consistency by Ori Lahav et al. (<https://plv.mpi-sws.org/sra/paper.pdf>) or Promising Semantics noted above, @@ -32,8 +32,8 @@ //! and shared across all threads. This is more memory efficient but does require store elements (representing writes to a location) to record //! information about reads, whereas in the other two models it is the other way round: reads points to the write it got its value from. //! Additionally, writes in our implementation do not have globally unique timestamps attached. In the other two models this timestamp is -//! used to make sure a value in a thread's view is not overwritten by a write that occured earlier than the one in the existing view. -//! In our implementation, this is detected using read information attached to store elements, as there is no data strucutre representing reads. +//! used to make sure a value in a thread's view is not overwritten by a write that occurred earlier than the one in the existing view. +//! In our implementation, this is detected using read information attached to store elements, as there is no data structure representing reads. //! //! The C++ memory model is built around the notion of an 'atomic object', so it would be natural //! to attach store buffers to atomic objects. However, Rust follows LLVM in that it only has @@ -48,7 +48,7 @@ //! One consequence of this difference is that safe/sound Rust allows for more operations on atomic locations //! than the C++20 atomic API was intended to allow, such as non-atomically accessing //! a previously atomically accessed location, or accessing previously atomically accessed locations with a differently sized operation -//! (such as accessing the top 16 bits of an AtomicU32). These senarios are generally undiscussed in formalisations of C++ memory model. +//! (such as accessing the top 16 bits of an AtomicU32). These scenarios are generally undiscussed in formalisations of C++ memory model. //! In Rust, these operations can only be done through a `&mut AtomicFoo` reference or one derived from it, therefore these operations //! can only happen after all previous accesses on the same locations. This implementation is adapted to allow these operations. //! A mixed atomicity read that races with writes, or a write that races with reads or writes will still cause UBs to be thrown. @@ -61,7 +61,7 @@ // // 2. In the operational semantics, each store element keeps the timestamp of a thread when it loads from the store. // If the same thread loads from the same store element multiple times, then the timestamps at all loads are saved in a list of load elements. -// This is not necessary as later loads by the same thread will always have greater timetstamp values, so we only need to record the timestamp of the first +// This is not necessary as later loads by the same thread will always have greater timestamp values, so we only need to record the timestamp of the first // load by each thread. This optimisation is done in tsan11 // (https://github.com/ChrisLidbury/tsan11/blob/ecbd6b81e9b9454e01cba78eb9d88684168132c7/lib/tsan/rtl/tsan_relaxed.h#L35-L37) // and here. @@ -193,7 +193,7 @@ impl StoreBufferAlloc { buffers.remove_pos_range(pos_range); } AccessType::Empty(_) => { - // The range had no weak behaivours attached, do nothing + // The range had no weak behaviours attached, do nothing } } } @@ -336,7 +336,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer { let mut found_sc = false; // FIXME: we want an inclusive take_while (stops after a false predicate, but // includes the element that gave the false), but such function doesn't yet - // exist in the standard libary https://github.com/rust-lang/rust/issues/62208 + // exist in the standard library https://github.com/rust-lang/rust/issues/62208 // so we have to hack around it with keep_searching let mut keep_searching = true; let candidates = self diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 7a726be00da..a93f3eb84f2 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -7,6 +7,7 @@ use rustc_span::{source_map::DUMMY_SP, SpanData, Symbol}; use rustc_target::abi::{Align, Size}; use crate::borrow_tracker::stacked_borrows::diagnostics::TagHistory; +use crate::borrow_tracker::tree_borrows::diagnostics as tree_diagnostics; use crate::*; /// Details of premature program termination. @@ -23,8 +24,9 @@ pub enum TerminationInfo { history: Option<TagHistory>, }, TreeBorrowsUb { - msg: String, - // FIXME: incomplete + title: String, + details: Vec<String>, + history: tree_diagnostics::HistoryData, }, Int2PtrWithStrictProvenance, Deadlock, @@ -65,7 +67,7 @@ impl fmt::Display for TerminationInfo { "integer-to-pointer casts and `ptr::from_exposed_addr` are not supported with `-Zmiri-strict-provenance`" ), StackedBorrowsUb { msg, .. } => write!(f, "{msg}"), - TreeBorrowsUb { msg } => write!(f, "{msg}"), + TreeBorrowsUb { title, .. } => write!(f, "{title}"), Deadlock => write!(f, "the evaluated program deadlocked"), MultipleSymbolDefinitions { link_name, .. } => write!(f, "multiple definitions of symbol `{link_name}`"), @@ -219,10 +221,16 @@ pub fn report_error<'tcx, 'mir>( } helps }, - TreeBorrowsUb { .. } => { - let helps = vec![ - (None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental")), + TreeBorrowsUb { title: _, details, history } => { + let mut helps = vec![ + (None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental")) ]; + for m in details { + helps.push((None, m.clone())); + } + for event in history.events.clone() { + helps.push(event); + } helps } MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } => @@ -401,14 +409,15 @@ pub fn report_msg<'tcx>( } else { // Make sure we show the message even when it is a dummy span. for line in span_msg { - err.note(&line); + err.note(line); } err.note("(no span available)"); } // Show note and help messages. let mut extra_span = false; - for (span_data, note) in ¬es { + let notes_len = notes.len(); + for (span_data, note) in notes { if let Some(span_data) = span_data { err.span_note(span_data.span(), note); extra_span = true; @@ -416,7 +425,8 @@ pub fn report_msg<'tcx>( err.note(note); } } - for (span_data, help) in &helps { + let helps_len = helps.len(); + for (span_data, help) in helps { if let Some(span_data) = span_data { err.span_help(span_data.span(), help); extra_span = true; @@ -424,7 +434,7 @@ pub fn report_msg<'tcx>( err.help(help); } } - if notes.len() + helps.len() > 0 { + if notes_len + helps_len > 0 { // Add visual separator before backtrace. err.note(if extra_span { "BACKTRACE (of the first span):" } else { "BACKTRACE:" }); } @@ -433,7 +443,7 @@ pub fn report_msg<'tcx>( let is_local = machine.is_local(frame_info); // No span for non-local frames and the first frame (which is the error site). if is_local && idx > 0 { - err.span_note(frame_info.span, &frame_info.to_string()); + err.span_note(frame_info.span, frame_info.to_string()); } else { let sm = sess.source_map(); let span = sm.span_to_embeddable_string(frame_info.span); diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index defd37c3775..43d8f221ce3 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -376,7 +376,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( // Inlining of `DEFAULT` from // https://github.com/rust-lang/rust/blob/master/compiler/rustc_session/src/config/sigpipe.rs. - // Alaways using DEFAULT is okay since we don't support signals in Miri anyway. + // Always using DEFAULT is okay since we don't support signals in Miri anyway. let sigpipe = 2; ecx.call_function( @@ -460,7 +460,7 @@ pub fn eval_entry<'tcx>( return None; } // Check for memory leaks. - info!("Additonal static roots: {:?}", ecx.machine.static_roots); + info!("Additional static roots: {:?}", ecx.machine.static_roots); let leaks = ecx.find_leaked_allocations(&ecx.machine.static_roots); if !leaks.is_empty() { report_leaks(&ecx, leaks); diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 8f6ae729491..a2b49e6f219 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -524,7 +524,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } - // Make sure we visit aggregrates in increasing offset order. + // Make sure we visit aggregates in increasing offset order. fn visit_aggregate( &mut self, place: &MPlaceTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/intptrcast.rs b/src/tools/miri/src/intptrcast.rs index 2ba18293121..4fd0af35304 100644 --- a/src/tools/miri/src/intptrcast.rs +++ b/src/tools/miri/src/intptrcast.rs @@ -77,7 +77,7 @@ impl<'mir, 'tcx> GlobalStateInner { Ok(pos) => Some(global_state.int_to_ptr_map[pos].1), Err(0) => None, Err(pos) => { - // This is the largest of the adresses smaller than `int`, + // This is the largest of the addresses smaller than `int`, // i.e. the greatest lower bound (glb) let (glb, alloc_id) = global_state.int_to_ptr_map[pos - 1]; // This never overflows because `addr >= glb` diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ecb3e13dd54..21c5a9c1b70 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -32,8 +32,14 @@ use crate::{ *, }; -/// The number of the available real-time signal with the lowest priority. -/// Dummy constant related to epoll, must be between 32 and 64. +/// First real-time signal. +/// `signal(7)` says this must be between 32 and 64 and specifies 34 or 35 +/// as typical values. +pub const SIGRTMIN: i32 = 34; + +/// Last real-time signal. +/// `signal(7)` says it must be between 32 and 64 and specifies +/// `SIGRTMAX` - `SIGRTMIN` >= 8 (which is the value of `_POSIX_RTSIG_MAX`) pub const SIGRTMAX: i32 = 42; /// Extra data stored with each stack frame @@ -495,9 +501,9 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { measureme::Profiler::new(out).expect("Couldn't create `measureme` profiler") }); let rng = StdRng::seed_from_u64(config.seed.unwrap_or(0)); - let borrow_tracker = config.borrow_tracker.map(|bt| bt.instanciate_global_state(config)); + let borrow_tracker = config.borrow_tracker.map(|bt| bt.instantiate_global_state(config)); let data_race = config.data_race_detector.then(|| data_race::GlobalState::new(config)); - // Determinine page size, stack address, and stack size. + // Determine page size, stack address, and stack size. // These values are mostly meaningless, but the stack address is also where we start // allocating physical integer addresses for all allocations. let page_size = if let Some(page_size) = config.page_size { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index fcee381ff71..44bca3796f9 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -46,7 +46,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // This list should be kept in sync with the one from libstd. let min_align = match this.tcx.sess.target.arch.as_ref() { "x86" | "arm" | "mips" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8, - "x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" => 16, + "x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" | "loongarch64" => 16, arch => bug!("unsupported target architecture for malloc: `{}`", arch), }; // Windows always aligns, even small allocations. @@ -744,6 +744,44 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { dest, )?; } + "memcpy" => { + let [ptr_dest, ptr_src, n] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let ptr_dest = this.read_pointer(ptr_dest)?; + let ptr_src = this.read_pointer(ptr_src)?; + let n = this.read_target_usize(n)?; + this.mem_copy( + ptr_src, + Align::ONE, + ptr_dest, + Align::ONE, + Size::from_bytes(n), + true, + )?; + this.write_pointer(ptr_dest, dest)?; + } + "strcpy" => { + let [ptr_dest, ptr_src] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let ptr_dest = this.read_pointer(ptr_dest)?; + let ptr_src = this.read_pointer(ptr_src)?; + + // We use `read_c_str` to determine the amount of data to copy, + // and then use `mem_copy` for the actual copy. This means + // pointer provenance is preserved by this implementation of `strcpy`. + // That is probably overly cautious, but there also is no fundamental + // reason to have `strcpy` destroy pointer provenance. + let n = this.read_c_str(ptr_src)?.len().checked_add(1).unwrap(); + this.mem_copy( + ptr_src, + Align::ONE, + ptr_dest, + Align::ONE, + Size::from_bytes(n), + true, + )?; + this.write_pointer(ptr_dest, dest)?; + } // math functions (note that there are also intrinsics for some other functions) #[rustfmt::skip] diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index f2e16521290..d101f8d3111 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -585,9 +585,9 @@ fn simd_element_to_bool(elem: ImmTy<'_, Provenance>) -> InterpResult<'_, bool> { }) } -fn simd_bitmask_index(idx: u32, vec_len: u32, endianess: Endian) -> u32 { +fn simd_bitmask_index(idx: u32, vec_len: u32, endianness: Endian) -> u32 { assert!(idx < vec_len); - match endianess { + match endianness { Endian::Little => idx, #[allow(clippy::integer_arithmetic)] // idx < vec_len Endian::Big => vec_len - 1 - idx, // reverse order of bits diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs index f010d4251f4..6bc5b8f39d5 100644 --- a/src/tools/miri/src/shims/os_str.rs +++ b/src/tools/miri/src/shims/os_str.rs @@ -329,7 +329,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { match direction { PathConversion::HostToTarget => { // If this start withs a `\`, we add `\\?` so it starts with `\\?\` which is - // some magic path on Windos that *is* considered absolute. + // some magic path on Windows that *is* considered absolute. if converted.get(0).copied() == Some(b'\\') { converted.splice(0..0, b"\\\\?".iter().copied()); } diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index ef411eb8aa7..2f24c00ce14 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -40,7 +40,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.eval_libc_i32("CLOCK_REALTIME_COARSE"), ]; // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are - // never allowed to go backwards. We don't need to do any additonal monotonicity + // never allowed to go backwards. We don't need to do any additional monotonicity // enforcement because std::time::Instant already guarantees that it is monotonic. relative_clocks = vec![ this.eval_libc_i32("CLOCK_MONOTONIC"), diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index e9119f9e1ec..685feeaf892 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -79,7 +79,7 @@ impl<'tcx> TlsData<'tcx> { trace!("TLS key {} removed", key); Ok(()) } - None => throw_ub_format!("removing a non-existig TLS key: {}", key), + None => throw_ub_format!("removing a nonexistent TLS key: {}", key), } } @@ -175,7 +175,7 @@ impl<'tcx> TlsData<'tcx> { Some(key) => Excluded(key), None => Unbounded, }; - // We interpret the documentaion above (taken from POSIX) as saying that we need to iterate + // We interpret the documentation above (taken from POSIX) as saying that we need to iterate // over all keys and run each destructor at least once before running any destructor a 2nd // time. That's why we have `key` to indicate how far we got in the current iteration. If we // return `None`, `schedule_next_pthread_tls_dtor` will re-try with `ket` set to `None` to diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index de271548217..abec782b4f0 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -11,6 +11,7 @@ use std::time::SystemTime; use log::trace; use rustc_data_structures::fx::FxHashMap; +use rustc_middle::ty::TyCtxt; use rustc_target::abi::{Align, Size}; use crate::shims::os_str::bytes_to_os_str; @@ -31,6 +32,7 @@ pub trait FileDescriptor: std::fmt::Debug + helpers::AsAny { &mut self, _communicate_allowed: bool, _bytes: &mut [u8], + _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { throw_unsup_format!("cannot read from {}", self.name()); } @@ -39,6 +41,7 @@ pub trait FileDescriptor: std::fmt::Debug + helpers::AsAny { &self, _communicate_allowed: bool, _bytes: &[u8], + _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { throw_unsup_format!("cannot write to {}", self.name()); } @@ -79,6 +82,7 @@ impl FileDescriptor for FileHandle { &mut self, communicate_allowed: bool, bytes: &mut [u8], + _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); Ok(self.file.read(bytes)) @@ -88,6 +92,7 @@ impl FileDescriptor for FileHandle { &self, communicate_allowed: bool, bytes: &[u8], + _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); Ok((&mut &self.file).write(bytes)) @@ -153,6 +158,7 @@ impl FileDescriptor for io::Stdin { &mut self, communicate_allowed: bool, bytes: &mut [u8], + _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { if !communicate_allowed { // We want isolation mode to be deterministic, so we have to disallow all reads, even stdin. @@ -184,6 +190,7 @@ impl FileDescriptor for io::Stdout { &self, _communicate_allowed: bool, bytes: &[u8], + _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { // We allow writing to stderr even with isolation enabled. let result = Write::write(&mut { self }, bytes); @@ -220,6 +227,7 @@ impl FileDescriptor for io::Stderr { &self, _communicate_allowed: bool, bytes: &[u8], + _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { // We allow writing to stderr even with isolation enabled. // No need to flush, stderr is not buffered. @@ -252,6 +260,7 @@ impl FileDescriptor for NullOutput { &self, _communicate_allowed: bool, bytes: &[u8], + _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { // We just don't write anything, but report to the user that we did. Ok(Ok(bytes.len())) @@ -756,8 +765,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let mut bytes = vec![0; usize::try_from(count).unwrap()]; // `File::read` never returns a value larger than `count`, // so this cannot fail. - let result = - file_descriptor.read(communicate, &mut bytes)?.map(|c| i64::try_from(c).unwrap()); + let result = file_descriptor + .read(communicate, &mut bytes, *this.tcx)? + .map(|c| i64::try_from(c).unwrap()); match result { Ok(read_bytes) => { @@ -803,8 +813,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) { let bytes = this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(count))?; - let result = - file_descriptor.write(communicate, bytes)?.map(|c| i64::try_from(c).unwrap()); + let result = file_descriptor + .write(communicate, bytes, *this.tcx)? + .map(|c| i64::try_from(c).unwrap()); this.try_unwrap_io_result(result) } else { this.handle_not_found() @@ -1015,8 +1026,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let path = this.read_path_from_c_str(pathname_ptr)?.into_owned(); // See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes. - let at_ampty_path = this.eval_libc_i32("AT_EMPTY_PATH"); - let empty_path_flag = flags & at_ampty_path == at_ampty_path; + let at_empty_path = this.eval_libc_i32("AT_EMPTY_PATH"); + let empty_path_flag = flags & at_empty_path == at_empty_path; // We only support: // * interpreting `path` as an absolute directory, // * interpreting `path` as a path relative to `dirfd` when the latter is `AT_FDCWD`, or @@ -1053,7 +1064,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return Ok(-1); } - // the `_mask_op` paramter specifies the file information that the caller requested. + // the `_mask_op` parameter specifies the file information that the caller requested. // However `statx` is allowed to return information that was not requested or to not // return information that was requested. This `mask` represents the information we can // actually provide for any target. diff --git a/src/tools/miri/src/shims/unix/linux/fd.rs b/src/tools/miri/src/shims/unix/linux/fd.rs index 3c4a678e598..3c263e4df92 100644 --- a/src/tools/miri/src/shims/unix/linux/fd.rs +++ b/src/tools/miri/src/shims/unix/linux/fd.rs @@ -152,7 +152,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let _maxevents = this.read_scalar(maxevents)?.to_i32()?; let _timeout = this.read_scalar(timeout)?.to_i32()?; - let numevents = 0; if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) { let _epfd = epfd .as_any_mut() @@ -160,7 +159,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { .ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_wait`"))?; // FIXME return number of events ready when scheme for marking events ready exists - Ok(Scalar::from_i32(numevents)) + throw_unsup_format!("returning ready events from epoll_wait is not yet implemented"); } else { Ok(Scalar::from_i32(this.handle_not_found()?)) } diff --git a/src/tools/miri/src/shims/unix/linux/fd/event.rs b/src/tools/miri/src/shims/unix/linux/fd/event.rs index 1db020bb7b6..1f17ffb88c8 100644 --- a/src/tools/miri/src/shims/unix/linux/fd/event.rs +++ b/src/tools/miri/src/shims/unix/linux/fd/event.rs @@ -1,6 +1,8 @@ use crate::shims::unix::fs::FileDescriptor; use rustc_const_eval::interpret::InterpResult; +use rustc_middle::ty::TyCtxt; +use rustc_target::abi::Endian; use std::cell::Cell; use std::io; @@ -36,7 +38,7 @@ impl FileDescriptor for Event { } /// A write call adds the 8-byte integer value supplied in - /// its buffer to the counter. The maximum value that may be + /// its buffer (in native endianess) to the counter. The maximum value that may be /// stored in the counter is the largest unsigned 64-bit value /// minus 1 (i.e., 0xfffffffffffffffe). If the addition would /// cause the counter's value to exceed the maximum, then the @@ -47,17 +49,22 @@ impl FileDescriptor for Event { /// A write fails with the error EINVAL if the size of the /// supplied buffer is less than 8 bytes, or if an attempt is /// made to write the value 0xffffffffffffffff. - /// - /// FIXME: use endianness fn write<'tcx>( &self, _communicate_allowed: bool, bytes: &[u8], + tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result<usize>> { let v1 = self.val.get(); + let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size + // Convert from target endianess to host endianess. + let num = match tcx.sess.target.endian { + Endian::Little => u64::from_le_bytes(bytes), + Endian::Big => u64::from_be_bytes(bytes), + }; // FIXME handle blocking when addition results in exceeding the max u64 value // or fail with EAGAIN if the file descriptor is nonblocking. - let v2 = v1.checked_add(u64::from_be_bytes(bytes.try_into().unwrap())).unwrap(); + let v2 = v1.checked_add(num).unwrap(); self.val.set(v2); assert_eq!(8, bytes.len()); Ok(Ok(8)) diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index f4e7824d91d..4cb7ee8efca 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -2,6 +2,7 @@ use rustc_span::Symbol; use rustc_target::spec::abi::Abi; use crate::machine::SIGRTMAX; +use crate::machine::SIGRTMIN; use crate::*; use shims::foreign_items::EmulateByNameResult; use shims::unix::fs::EvalContextExt as _; @@ -74,6 +75,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let result = this.socketpair(domain, type_, protocol, sv)?; this.write_scalar(result, dest)?; } + "__libc_current_sigrtmin" => { + let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + this.write_scalar(Scalar::from_i32(SIGRTMIN), dest)?; + } "__libc_current_sigrtmax" => { let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; @@ -163,7 +169,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.linux_statx(&args[1], &args[2], &args[3], &args[4], &args[5])?; this.write_scalar(Scalar::from_target_isize(result.into(), this), dest)?; } - // `futex` is used by some synchonization primitives. + // `futex` is used by some synchronization primitives. id if id == sys_futex => { futex(this, &args[1..], dest)?; } @@ -174,7 +180,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } - // Miscelanneous + // Miscellaneous "getrandom" => { let [ptr, len, flags] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index b3c474dd3c9..05feeac45b5 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -242,7 +242,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // // To distinguish these two cases in already constructed mutexes, we // use the same trick as glibc: for the case when - // `pthread_mutexattr_settype` is caled explicitly, we set the + // `pthread_mutexattr_settype` is called explicitly, we set the // `PTHREAD_MUTEX_NORMAL_FLAG` flag. let normal_kind = kind | PTHREAD_MUTEX_NORMAL_FLAG; // Check that after setting the flag, the kind is distinguishable diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 665c7ed438f..f72ba5cca7a 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -96,7 +96,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { if byte_offset != 0 { throw_unsup_format!( - "`NtWriteFile` `ByteOffset` paremeter is non-null, which is unsupported" + "`NtWriteFile` `ByteOffset` parameter is non-null, which is unsupported" ); } diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs index 21eaeabe6ad..52deba9108c 100644 --- a/src/tools/miri/tests/compiletest.rs +++ b/src/tools/miri/tests/compiletest.rs @@ -2,7 +2,7 @@ use colored::*; use regex::bytes::Regex; use std::path::{Path, PathBuf}; use std::{env, process::Command}; -use ui_test::{color_eyre::Result, Config, Mode, OutputConflictHandling}; +use ui_test::{color_eyre::Result, Config, Match, Mode, OutputConflictHandling}; fn miri_path() -> PathBuf { PathBuf::from(option_env!("MIRI").unwrap_or(env!("CARGO_BIN_EXE_miri"))) @@ -52,14 +52,13 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R mode, program: miri_path(), quiet: false, + edition: Some("2018".into()), ..Config::default() }; let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some(); // Add some flags we always want. - config.args.push("--edition".into()); - config.args.push("2018".into()); if in_rustc_test_suite { // Less aggressive warnings to make the rustc toolstate management less painful. // (We often get warnings when e.g. a feature gets stabilized or some lint gets added/improved.) @@ -100,12 +99,24 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R }; // Handle command-line arguments. + let mut after_dashdash = false; config.path_filter.extend(std::env::args().skip(1).filter(|arg| { + if after_dashdash { + // Just propagate everything. + return true; + } match &**arg { "--quiet" => { config.quiet = true; false } + "--" => { + after_dashdash = true; + false + } + s if s.starts_with('-') => { + panic!("unknown compiletest flag `{s}`"); + } _ => true, } })); @@ -129,8 +140,8 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R macro_rules! regexes { ($name:ident: $($regex:expr => $replacement:expr,)*) => {lazy_static::lazy_static! { - static ref $name: Vec<(Regex, &'static [u8])> = vec![ - $((Regex::new($regex).unwrap(), $replacement.as_bytes()),)* + static ref $name: Vec<(Match, &'static [u8])> = vec![ + $((Regex::new($regex).unwrap().into(), $replacement.as_bytes()),)* ]; }}; } diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs index c00344b6de2..21344208130 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs @@ -7,5 +7,5 @@ fn main() { // Also not assigning directly as that's array initialization, not assignment. let zst_val = [1u8; 0]; unsafe { std::ptr::null_mut::<[u8; 0]>().write(zst_val) }; - //~^ERROR: memory access failed: null pointer is a dangling pointer + //~^ERROR: dereferencing pointer failed: null pointer is a dangling pointer } diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.stderr b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.stderr index 2953d85c25f..a4e0ebe38f6 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_write_zst.rs:LL:CC | LL | unsafe { std::ptr::null_mut::<[u8; 0]>().write(zst_val) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/exact_div1.rs b/src/tools/miri/tests/fail/intrinsics/exact_div1.rs index 3dda9d1090d..e11d8937fe4 100644 --- a/src/tools/miri/tests/fail/intrinsics/exact_div1.rs +++ b/src/tools/miri/tests/fail/intrinsics/exact_div1.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { - // divison by 0 + // division by 0 unsafe { std::intrinsics::exact_div(2, 0) }; //~ ERROR: divisor of zero } diff --git a/src/tools/miri/tests/fail/intrinsics/exact_div2.rs b/src/tools/miri/tests/fail/intrinsics/exact_div2.rs index 00064fa0b9c..7914de403a7 100644 --- a/src/tools/miri/tests/fail/intrinsics/exact_div2.rs +++ b/src/tools/miri/tests/fail/intrinsics/exact_div2.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { - // divison with a remainder + // division with a remainder unsafe { std::intrinsics::exact_div(2u16, 3) }; //~ ERROR: 2_u16 cannot be divided by 3_u16 without remainder } diff --git a/src/tools/miri/tests/fail/intrinsics/exact_div3.rs b/src/tools/miri/tests/fail/intrinsics/exact_div3.rs index a61abcd137e..50ee5386465 100644 --- a/src/tools/miri/tests/fail/intrinsics/exact_div3.rs +++ b/src/tools/miri/tests/fail/intrinsics/exact_div3.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { - // signed divison with a remainder + // signed division with a remainder unsafe { std::intrinsics::exact_div(-19i8, 2) }; //~ ERROR: -19_i8 cannot be divided by 2_i8 without remainder } diff --git a/src/tools/miri/tests/fail/intrinsics/exact_div4.rs b/src/tools/miri/tests/fail/intrinsics/exact_div4.rs index b5b60190b4e..48c55208238 100644 --- a/src/tools/miri/tests/fail/intrinsics/exact_div4.rs +++ b/src/tools/miri/tests/fail/intrinsics/exact_div4.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { - // divison of MIN by -1 + // division of MIN by -1 unsafe { std::intrinsics::exact_div(i64::MIN, -1) }; //~ ERROR: overflow in signed remainder (dividing MIN by -1) } diff --git a/src/tools/miri/tests/fail/layout_cycle.rs b/src/tools/miri/tests/fail/layout_cycle.rs new file mode 100644 index 00000000000..d050310bd80 --- /dev/null +++ b/src/tools/miri/tests/fail/layout_cycle.rs @@ -0,0 +1,28 @@ +//@error-pattern: a cycle occurred during layout computation +//~^ ERROR: cycle detected when computing layout of + +use std::mem; + +pub struct S<T: Tr> { + pub f: <T as Tr>::I, +} + +pub trait Tr { + type I: Tr; +} + +impl<T: Tr> Tr for S<T> { + type I = S<S<T>>; +} + +impl Tr for () { + type I = (); +} + +fn foo<T: Tr>() -> usize { + mem::size_of::<S<T>>() +} + +fn main() { + println!("{}", foo::<S<()>>()); +} diff --git a/src/tools/miri/tests/fail/layout_cycle.stderr b/src/tools/miri/tests/fail/layout_cycle.stderr new file mode 100644 index 00000000000..62b7d5fb77d --- /dev/null +++ b/src/tools/miri/tests/fail/layout_cycle.stderr @@ -0,0 +1,28 @@ +error[E0391]: cycle detected when computing layout of `S<S<()>>` + | + = note: ...which requires computing layout of `<S<()> as Tr>::I`... + = note: ...which again requires computing layout of `S<S<()>>`, completing the cycle + +error: post-monomorphization error: a cycle occurred during layout computation + --> RUSTLIB/core/src/mem/mod.rs:LL:CC + | +LL | intrinsics::size_of::<T>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation + | + = note: inside `std::mem::size_of::<S<S<()>>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC +note: inside `foo::<S<()>>` + --> $DIR/layout_cycle.rs:LL:CC + | +LL | mem::size_of::<S<T>>() + | ^^^^^^^^^^^^^^^^^^^^^^ +note: inside `main` + --> $DIR/layout_cycle.rs:LL:CC + | +LL | println!("{}", foo::<S<()>>()); + | ^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/tools/miri/tests/fail/panic/double_panic.rs b/src/tools/miri/tests/fail/panic/double_panic.rs index 8919d51bb2f..c9501d90b3b 100644 --- a/src/tools/miri/tests/fail/panic/double_panic.rs +++ b/src/tools/miri/tests/fail/panic/double_panic.rs @@ -1,6 +1,8 @@ //@error-pattern: the program aborted //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();" +//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1" +//@normalize-stderr-test: "\n at [^\n]+" -> "$1" struct Foo; impl Drop for Foo { diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr index f04dfab36ca..5384f6f6716 100644 --- a/src/tools/miri/tests/fail/panic/double_panic.stderr +++ b/src/tools/miri/tests/fail/panic/double_panic.stderr @@ -2,70 +2,6 @@ thread 'main' panicked at 'first', $DIR/double_panic.rs:LL:CC note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace thread 'main' panicked at 'second', $DIR/double_panic.rs:LL:CC stack backtrace: - 0: std::backtrace_rs::backtrace::miri::trace_unsynchronized - at RUSTLIB/std/src/../../backtrace/src/backtrace/miri.rs:LL:CC - 1: std::backtrace_rs::backtrace::miri::trace - at RUSTLIB/std/src/../../backtrace/src/backtrace/miri.rs:LL:CC - 2: std::backtrace_rs::backtrace::trace_unsynchronized - at RUSTLIB/std/src/../../backtrace/src/backtrace/mod.rs:LL:CC - 3: std::sys_common::backtrace::_print_fmt - at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC - 4: <std::sys_common::backtrace::_print::DisplayBacktrace as std::fmt::Display>::fmt - at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC - 5: core::fmt::rt::Argument::fmt - at RUSTLIB/core/src/fmt/rt.rs:LL:CC - 6: std::fmt::write - at RUSTLIB/core/src/fmt/mod.rs:LL:CC - 7: <std::sys::PLATFORM::stdio::Stderr as std::io::Write>::write_fmt - at RUSTLIB/std/src/io/mod.rs:LL:CC - 8: std::sys_common::backtrace::_print - at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC - 9: std::sys_common::backtrace::print - at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC - 10: std::panicking::default_hook::{closure#1} - at RUSTLIB/std/src/panicking.rs:LL:CC - 11: std::panicking::default_hook - at RUSTLIB/std/src/panicking.rs:LL:CC - 12: std::panicking::rust_panic_with_hook - at RUSTLIB/std/src/panicking.rs:LL:CC - 13: std::rt::begin_panic::{closure#0} - at RUSTLIB/std/src/panicking.rs:LL:CC - 14: std::sys_common::backtrace::__rust_end_short_backtrace - at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC - 15: std::rt::begin_panic - at RUSTLIB/std/src/panicking.rs:LL:CC - 16: <Foo as std::ops::Drop>::drop - at $DIR/double_panic.rs:LL:CC - 17: std::ptr::drop_in_place - shim(Some(Foo)) - at RUSTLIB/core/src/ptr/mod.rs:LL:CC - 18: main - at $DIR/double_panic.rs:LL:CC - 19: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn()) - at RUSTLIB/core/src/ops/function.rs:LL:CC - 20: std::sys_common::backtrace::__rust_begin_short_backtrace - at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC - 21: std::rt::lang_start::{closure#0} - at RUSTLIB/std/src/rt.rs:LL:CC - 22: std::ops::function::impls::call_once - at RUSTLIB/core/src/ops/function.rs:LL:CC - 23: std::panicking::r#try::do_call - at RUSTLIB/std/src/panicking.rs:LL:CC - 24: std::panicking::r#try - at RUSTLIB/std/src/panicking.rs:LL:CC - 25: std::panic::catch_unwind - at RUSTLIB/std/src/panic.rs:LL:CC - 26: std::rt::lang_start_internal::{closure#2} - at RUSTLIB/std/src/rt.rs:LL:CC - 27: std::panicking::r#try::do_call - at RUSTLIB/std/src/panicking.rs:LL:CC - 28: std::panicking::r#try - at RUSTLIB/std/src/panicking.rs:LL:CC - 29: std::panic::catch_unwind - at RUSTLIB/std/src/panic.rs:LL:CC - 30: std::rt::lang_start_internal - at RUSTLIB/std/src/rt.rs:LL:CC - 31: std::rt::lang_start - at RUSTLIB/std/src/rt.rs:LL:CC thread panicked while panicking. aborting. error: abnormal termination: the program aborted execution --> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read3.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_read3.rs index 43ea0a0e84d..9c0c974223b 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read3.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read3.rs @@ -1,5 +1,5 @@ // A callee may not read the destination of our `&mut` without us noticing. -// Thise code got carefully checked to not introduce any reborrows +// This code got carefully checked to not introduce any reborrows // that are not explicit in the source. Let's hope the compiler does not break this later! use std::mem; diff --git a/src/tools/miri/tests/fail/terminate-terminator.rs b/src/tools/miri/tests/fail/terminate-terminator.rs index f4931659fc8..22ffa1b2711 100644 --- a/src/tools/miri/tests/fail/terminate-terminator.rs +++ b/src/tools/miri/tests/fail/terminate-terminator.rs @@ -12,14 +12,13 @@ impl Drop for Foo { #[inline(always)] fn has_cleanup() { - //~^ ERROR: panic in a function that cannot unwind - // FIXME(nbdd0121): The error should be reported at the call site. let _f = Foo; panic!(); } extern "C" fn panic_abort() { has_cleanup(); + //~^ ERROR: panic in a function that cannot unwind } fn main() { diff --git a/src/tools/miri/tests/fail/terminate-terminator.stderr b/src/tools/miri/tests/fail/terminate-terminator.stderr index c046678f73f..8ce4bb7cbb5 100644 --- a/src/tools/miri/tests/fail/terminate-terminator.stderr +++ b/src/tools/miri/tests/fail/terminate-terminator.stderr @@ -6,8 +6,6 @@ error: abnormal termination: panic in a function that cannot unwind --> $DIR/terminate-terminator.rs:LL:CC | LL | / fn has_cleanup() { -LL | | -LL | | // FIXME(nbdd0121): The error should be reported at the call site. LL | | let _f = Foo; LL | | panic!(); LL | | } diff --git a/src/tools/miri/tests/pass-dep/tokio/sleep.rs b/src/tools/miri/tests/fail/tokio/sleep.rs index 00cc68eba3e..6fdfbc9913a 100644 --- a/src/tools/miri/tests/pass-dep/tokio/sleep.rs +++ b/src/tools/miri/tests/fail/tokio/sleep.rs @@ -1,5 +1,7 @@ //@compile-flags: -Zmiri-permissive-provenance -Zmiri-backtrace=full //@only-target-x86_64-unknown-linux: support for tokio only on linux and x86 +//@error-pattern: returning ready events from epoll_wait is not yet implemented +//@normalize-stderr-test: " += note:.*\n" -> "" use tokio::time::{sleep, Duration, Instant}; diff --git a/src/tools/miri/tests/fail/tokio/sleep.stderr b/src/tools/miri/tests/fail/tokio/sleep.stderr new file mode 100644 index 00000000000..ac2a984ed51 --- /dev/null +++ b/src/tools/miri/tests/fail/tokio/sleep.stderr @@ -0,0 +1,15 @@ +error: unsupported operation: returning ready events from epoll_wait is not yet implemented + --> CARGO_REGISTRY/.../epoll.rs:LL:CC + | +LL | / syscall!(epoll_wait( +LL | | self.ep, +LL | | events.as_mut_ptr(), +LL | | events.capacity() as i32, +LL | | timeout, +LL | | )) + | |__________^ returning ready events from epoll_wait is not yet implemented + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/tree-borrows/alternate-read-write.stderr b/src/tools/miri/tests/fail/tree-borrows/alternate-read-write.stderr index 7c5bcd4e7b0..bb601fc8835 100644 --- a/src/tools/miri/tests/fail/tree-borrows/alternate-read-write.stderr +++ b/src/tools/miri/tests/fail/tree-borrows/alternate-read-write.stderr @@ -1,11 +1,35 @@ -error: Undefined Behavior: write access through <TAG> is forbidden because it is a child of <TAG> which is Frozen. +error: Undefined Behavior: write access through <TAG> is forbidden --> $DIR/alternate-read-write.rs:LL:CC | LL | *y += 1; // Failure - | ^^^^^^^ write access through <TAG> is forbidden because it is a child of <TAG> which is Frozen. + | ^^^^^^^ write access through <TAG> is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = note: BACKTRACE: + = help: the accessed tag <TAG> is a child of the conflicting tag <TAG> + = help: the conflicting tag <TAG> has state Frozen which forbids child write accesses +help: the accessed tag <TAG> was created here + --> $DIR/alternate-read-write.rs:LL:CC + | +LL | let y = unsafe { &mut *(x as *mut u8) }; + | ^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag <TAG> was created here, in the initial state Reserved + --> $DIR/alternate-read-write.rs:LL:CC + | +LL | let y = unsafe { &mut *(x as *mut u8) }; + | ^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag <TAG> then transitioned from Reserved to Active due to a child write access at offsets [0x0..0x1] + --> $DIR/alternate-read-write.rs:LL:CC + | +LL | *y += 1; // Success + | ^^^^^^^ + = help: this corresponds to an activation +help: the conflicting tag <TAG> then transitioned from Active to Frozen due to a foreign read access at offsets [0x0..0x1] + --> $DIR/alternate-read-write.rs:LL:CC + | +LL | let _val = *x; + | ^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): = note: inside `main` at $DIR/alternate-read-write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree-borrows/error-range.rs b/src/tools/miri/tests/fail/tree-borrows/error-range.rs new file mode 100644 index 00000000000..d9980e75d60 --- /dev/null +++ b/src/tools/miri/tests/fail/tree-borrows/error-range.rs @@ -0,0 +1,27 @@ +//@compile-flags: -Zmiri-tree-borrows + +use core::ptr::addr_of_mut; + +// Check that the diagnostics correctly report the exact range at fault +// and trim irrelevant events. +fn main() { + unsafe { + let data = &mut [0u8; 16]; + + // Create and activate a few bytes + let rmut = &mut *addr_of_mut!(data[0..6]); + rmut[3] += 1; + rmut[4] += 1; + rmut[5] += 1; + + // Now make them lose some perms + let _v = data[3]; + let _v = data[4]; + let _v = data[5]; + data[4] = 1; + data[5] = 1; + + // Final test + rmut[5] += 1; //~ ERROR: /read access through .* is forbidden/ + } +} diff --git a/src/tools/miri/tests/fail/tree-borrows/error-range.stderr b/src/tools/miri/tests/fail/tree-borrows/error-range.stderr new file mode 100644 index 00000000000..bc829fd86d3 --- /dev/null +++ b/src/tools/miri/tests/fail/tree-borrows/error-range.stderr @@ -0,0 +1,44 @@ +error: Undefined Behavior: read access through <TAG> is forbidden + --> $DIR/error-range.rs:LL:CC + | +LL | rmut[5] += 1; + | ^^^^^^^^^^^^ read access through <TAG> is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag <TAG> is a child of the conflicting tag <TAG> + = help: the conflicting tag <TAG> has state Disabled which forbids child read accesses +help: the accessed tag <TAG> was created here + --> $DIR/error-range.rs:LL:CC + | +LL | let rmut = &mut *addr_of_mut!(data[0..6]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag <TAG> was created here, in the initial state Reserved + --> $DIR/error-range.rs:LL:CC + | +LL | let rmut = &mut *addr_of_mut!(data[0..6]); + | ^^^^ +help: the conflicting tag <TAG> then transitioned from Reserved to Active due to a child write access at offsets [0x5..0x6] + --> $DIR/error-range.rs:LL:CC + | +LL | rmut[5] += 1; + | ^^^^^^^^^^^^ + = help: this corresponds to an activation +help: the conflicting tag <TAG> then transitioned from Active to Frozen due to a foreign read access at offsets [0x5..0x6] + --> $DIR/error-range.rs:LL:CC + | +LL | let _v = data[5]; + | ^^^^^^^ + = help: this corresponds to a loss of write permissions +help: the conflicting tag <TAG> then transitioned from Frozen to Disabled due to a foreign write access at offsets [0x5..0x6] + --> $DIR/error-range.rs:LL:CC + | +LL | data[5] = 1; + | ^^^^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/error-range.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/tree-borrows/fragile-data-race.stderr b/src/tools/miri/tests/fail/tree-borrows/fragile-data-race.stderr index a078d18d3b0..79744964a8b 100644 --- a/src/tools/miri/tests/fail/tree-borrows/fragile-data-race.stderr +++ b/src/tools/miri/tests/fail/tree-borrows/fragile-data-race.stderr @@ -1,11 +1,29 @@ -error: Undefined Behavior: write access through <TAG> is forbidden because it is a child of <TAG> which is Frozen. +error: Undefined Behavior: write access through <TAG> is forbidden --> $DIR/fragile-data-race.rs:LL:CC | LL | unsafe { *p = 1 }; - | ^^^^^^ write access through <TAG> is forbidden because it is a child of <TAG> which is Frozen. + | ^^^^^^ write access through <TAG> is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = note: BACKTRACE: + = help: the accessed tag <TAG> is a child of the conflicting tag <TAG> + = help: the conflicting tag <TAG> has state Frozen which forbids child write accesses +help: the accessed tag <TAG> was created here + --> $DIR/fragile-data-race.rs:LL:CC + | +LL | fn thread_1(x: &mut u8) -> SendPtr { + | ^ +help: the conflicting tag <TAG> was created here, in the initial state Reserved + --> RUSTLIB/std/src/panic.rs:LL:CC + | +LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> { + | ^ +help: the conflicting tag <TAG> then transitioned from Reserved to Frozen due to a foreign read access at offsets [0x0..0x1] + --> RUSTLIB/core/src/ptr/mod.rs:LL:CC + | +LL | crate::intrinsics::read_via_copy(src) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): = note: inside `main` at $DIR/fragile-data-race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree-borrows/outside-range.stderr b/src/tools/miri/tests/fail/tree-borrows/outside-range.stderr index 4396c63679e..14696c704fc 100644 --- a/src/tools/miri/tests/fail/tree-borrows/outside-range.stderr +++ b/src/tools/miri/tests/fail/tree-borrows/outside-range.stderr @@ -1,11 +1,24 @@ -error: Undefined Behavior: write access through <TAG> is forbidden because it is a foreign tag for <TAG>, which would hence change from Reserved to Disabled, but <TAG> is protected +error: Undefined Behavior: write access through <TAG> is forbidden --> $DIR/outside-range.rs:LL:CC | LL | *y.add(3) = 42; - | ^^^^^^^^^^^^^^ write access through <TAG> is forbidden because it is a foreign tag for <TAG>, which would hence change from Reserved to Disabled, but <TAG> is protected + | ^^^^^^^^^^^^^^ write access through <TAG> is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = note: BACKTRACE: + = help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child) + = help: the access would cause the protected tag <TAG> to transition from Reserved to Disabled + = help: this is a loss of read and write permissions, which is not allowed for protected tags +help: the accessed tag <TAG> was created here + --> $DIR/outside-range.rs:LL:CC + | +LL | let raw = data.as_mut_ptr(); + | ^^^^^^^^^^^^^^^^^ +help: the protected tag <TAG> was created here, in the initial state Reserved + --> $DIR/outside-range.rs:LL:CC + | +LL | unsafe fn stuff(x: &mut u8, y: *mut u8) { + | ^ + = note: BACKTRACE (of the first span): = note: inside `stuff` at $DIR/outside-range.rs:LL:CC note: inside `main` --> $DIR/outside-range.rs:LL:CC diff --git a/src/tools/miri/tests/fail/tree-borrows/read-to-local.stderr b/src/tools/miri/tests/fail/tree-borrows/read-to-local.stderr index 7d9367c87d0..8c9c2f8f965 100644 --- a/src/tools/miri/tests/fail/tree-borrows/read-to-local.stderr +++ b/src/tools/miri/tests/fail/tree-borrows/read-to-local.stderr @@ -1,12 +1,31 @@ -error: Undefined Behavior: write access through <TAG> is forbidden because it is a child of <TAG> which is Frozen. +error: Undefined Behavior: write access through <TAG> is forbidden --> $DIR/read-to-local.rs:LL:CC | LL | *ptr = 0; - | ^^^^^^^^ write access through <TAG> is forbidden because it is a child of <TAG> which is Frozen. + | ^^^^^^^^ write access through <TAG> is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = note: BACKTRACE: + = help: the accessed tag <TAG> has state Frozen which forbids child write accesses +help: the accessed tag <TAG> was created here, in the initial state Reserved + --> $DIR/read-to-local.rs:LL:CC + | +LL | let mref = &mut root; + | ^^^^^^^^^ +help: the accessed tag <TAG> then transitioned from Reserved to Active due to a child write access at offsets [0x0..0x1] + --> $DIR/read-to-local.rs:LL:CC + | +LL | *ptr = 0; // Write + | ^^^^^^^^ + = help: this corresponds to an activation +help: the accessed tag <TAG> then transitioned from Active to Frozen due to a foreign read access at offsets [0x0..0x1] + --> $DIR/read-to-local.rs:LL:CC + | +LL | assert_eq!(root, 0); // Parent Read + | ^^^^^^^^^^^^^^^^^^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): = note: inside `main` at $DIR/read-to-local.rs:LL:CC + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree-borrows/reserved/cell-protected-write.stderr b/src/tools/miri/tests/fail/tree-borrows/reserved/cell-protected-write.stderr index 8ae1c09470a..b85793ff063 100644 --- a/src/tools/miri/tests/fail/tree-borrows/reserved/cell-protected-write.stderr +++ b/src/tools/miri/tests/fail/tree-borrows/reserved/cell-protected-write.stderr @@ -1,20 +1,34 @@ ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Re*| └─┬──<TAG=base> -| Re*| ├─┬──<TAG=x> -| Re*| │ └─┬──<TAG=caller:x> -| Re*| │ └────<TAG=callee:x> Strongly protected -| Re*| └────<TAG=y,callee:y,caller:y> +| Act| └─┬──<TAG=root of the allocation> +| Re*| └─┬──<TAG=base> +| Re*| ├─┬──<TAG=x> +| Re*| │ └─┬──<TAG=caller:x> +| Re*| │ └────<TAG=callee:x> Strongly protected +| Re*| └────<TAG=y, callee:y, caller:y> ────────────────────────────────────────────────────────────────────── -error: Undefined Behavior: write access through <TAG> (also named 'y,callee:y,caller:y') is forbidden because it is a foreign tag for <TAG> (also named 'callee:x'), which would hence change from Reserved to Disabled, but <TAG> (also named 'callee:x') is protected +error: Undefined Behavior: write access through <TAG> (y, callee:y, caller:y) is forbidden --> $DIR/cell-protected-write.rs:LL:CC | LL | *y = 1; - | ^^^^^^ write access through <TAG> (also named 'y,callee:y,caller:y') is forbidden because it is a foreign tag for <TAG> (also named 'callee:x'), which would hence change from Reserved to Disabled, but <TAG> (also named 'callee:x') is protected + | ^^^^^^ write access through <TAG> (y, callee:y, caller:y) is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = note: BACKTRACE: + = help: the accessed tag <TAG> (y, callee:y, caller:y) is foreign to the protected tag <TAG> (callee:x) (i.e., it is not a child) + = help: the access would cause the protected tag <TAG> (callee:x) to transition from Reserved to Disabled + = help: this is a loss of read and write permissions, which is not allowed for protected tags +help: the accessed tag <TAG> was created here + --> $DIR/cell-protected-write.rs:LL:CC + | +LL | let y = (&mut *n).get(); + | ^^^^^^^^^ +help: the protected tag <TAG> was created here, in the initial state Reserved + --> $DIR/cell-protected-write.rs:LL:CC + | +LL | unsafe fn write_second(x: &mut UnsafeCell<u8>, y: *mut u8) { + | ^ + = note: BACKTRACE (of the first span): = note: inside `main::write_second` at $DIR/cell-protected-write.rs:LL:CC note: inside `main` --> $DIR/cell-protected-write.rs:LL:CC diff --git a/src/tools/miri/tests/fail/tree-borrows/reserved/int-protected-write.stderr b/src/tools/miri/tests/fail/tree-borrows/reserved/int-protected-write.stderr index a199fc0f0da..5de7dc0c7c5 100644 --- a/src/tools/miri/tests/fail/tree-borrows/reserved/int-protected-write.stderr +++ b/src/tools/miri/tests/fail/tree-borrows/reserved/int-protected-write.stderr @@ -1,20 +1,34 @@ ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Res| └─┬──<TAG=n> -| Res| ├─┬──<TAG=x> -| Res| │ └─┬──<TAG=caller:x> -| Res| │ └────<TAG=callee:x> Strongly protected -| Res| └────<TAG=y,callee:y,caller:y> +| Act| └─┬──<TAG=root of the allocation> +| Res| └─┬──<TAG=n> +| Res| ├─┬──<TAG=x> +| Res| │ └─┬──<TAG=caller:x> +| Res| │ └────<TAG=callee:x> Strongly protected +| Res| └────<TAG=y, callee:y, caller:y> ────────────────────────────────────────────────────────────────────── -error: Undefined Behavior: write access through <TAG> (also named 'y,callee:y,caller:y') is forbidden because it is a foreign tag for <TAG> (also named 'callee:x'), which would hence change from Reserved to Disabled, but <TAG> (also named 'callee:x') is protected +error: Undefined Behavior: write access through <TAG> (y, callee:y, caller:y) is forbidden --> $DIR/int-protected-write.rs:LL:CC | LL | *y = 0; - | ^^^^^^ write access through <TAG> (also named 'y,callee:y,caller:y') is forbidden because it is a foreign tag for <TAG> (also named 'callee:x'), which would hence change from Reserved to Disabled, but <TAG> (also named 'callee:x') is protected + | ^^^^^^ write access through <TAG> (y, callee:y, caller:y) is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = note: BACKTRACE: + = help: the accessed tag <TAG> (y, callee:y, caller:y) is foreign to the protected tag <TAG> (callee:x) (i.e., it is not a child) + = help: the access would cause the protected tag <TAG> (callee:x) to transition from Reserved to Disabled + = help: this is a loss of read and write permissions, which is not allowed for protected tags +help: the accessed tag <TAG> was created here + --> $DIR/int-protected-write.rs:LL:CC + | +LL | let y = (&mut *n) as *mut _; + | ^^^^^^^^^ +help: the protected tag <TAG> was created here, in the initial state Reserved + --> $DIR/int-protected-write.rs:LL:CC + | +LL | unsafe fn write_second(x: &mut u8, y: *mut u8) { + | ^ + = note: BACKTRACE (of the first span): = note: inside `main::write_second` at $DIR/int-protected-write.rs:LL:CC note: inside `main` --> $DIR/int-protected-write.rs:LL:CC diff --git a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs new file mode 100644 index 00000000000..a68efea890c --- /dev/null +++ b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs @@ -0,0 +1,14 @@ +//@compile-flags: -Zmiri-tree-borrows +//@error-pattern: /deallocation through .* is forbidden/ + +fn inner(x: &mut i32, f: fn(&mut i32)) { + // `f` may mutate, but it may not deallocate! + f(x) +} + +fn main() { + inner(Box::leak(Box::new(0)), |x| { + let raw = x as *mut _; + drop(unsafe { Box::from_raw(raw) }); + }); +} diff --git a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr new file mode 100644 index 00000000000..97088d5854c --- /dev/null +++ b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr @@ -0,0 +1,49 @@ +error: Undefined Behavior: deallocation through <TAG> is forbidden + --> RUSTLIB/alloc/src/alloc.rs:LL:CC + | +LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through <TAG> is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the allocation of the accessed tag <TAG> also contains the strongly protected tag <TAG> + = help: the strongly protected tag <TAG> disallows deallocations +help: the accessed tag <TAG> was created here + --> $DIR/strongly-protected.rs:LL:CC + | +LL | drop(unsafe { Box::from_raw(raw) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the strongly protected tag <TAG> was created here, in the initial state Reserved + --> $DIR/strongly-protected.rs:LL:CC + | +LL | fn inner(x: &mut i32, f: fn(&mut i32)) { + | ^ + = note: BACKTRACE (of the first span): + = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `<std::alloc::Global as std::alloc::Allocator>::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::box_free::<i32, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::ptr::drop_in_place::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: inside `std::mem::drop::<std::boxed::Box<i32>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC +note: inside closure + --> $DIR/strongly-protected.rs:LL:CC + | +LL | drop(unsafe { Box::from_raw(raw) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `<[closure@$DIR/strongly-protected.rs:LL:CC] as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC +note: inside `inner` + --> $DIR/strongly-protected.rs:LL:CC + | +LL | f(x) + | ^^^^ +note: inside `main` + --> $DIR/strongly-protected.rs:LL:CC + | +LL | / inner(Box::leak(Box::new(0)), |x| { +LL | | let raw = x as *mut _; +LL | | drop(unsafe { Box::from_raw(raw) }); +LL | | }); + | |______^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/tree-borrows/write-during-2phase.stderr b/src/tools/miri/tests/fail/tree-borrows/write-during-2phase.stderr index e511eb9cf8f..f6285bdcf16 100644 --- a/src/tools/miri/tests/fail/tree-borrows/write-during-2phase.stderr +++ b/src/tools/miri/tests/fail/tree-borrows/write-during-2phase.stderr @@ -1,11 +1,30 @@ -error: Undefined Behavior: read access through <TAG> is forbidden because it is a child of <TAG> which is Disabled. +error: Undefined Behavior: read access through <TAG> is forbidden --> $DIR/write-during-2phase.rs:LL:CC | LL | fn add(&mut self, n: u64) -> u64 { - | ^^^^^^^^^ read access through <TAG> is forbidden because it is a child of <TAG> which is Disabled. + | ^^^^^^^^^ read access through <TAG> is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = note: BACKTRACE: + = help: the accessed tag <TAG> has state Disabled which forbids child read accesses +help: the accessed tag <TAG> was created here, in the initial state Reserved + --> $DIR/write-during-2phase.rs:LL:CC + | +LL | let _res = f.add(unsafe { + | ________________^ +LL | | let n = f.0; +LL | | // This is the access at fault, but it's not immediately apparent because +LL | | // the reference that got invalidated is not under a Protector. +LL | | *inner = 42; +LL | | n +LL | | }); + | |______^ +help: the accessed tag <TAG> then transitioned from Reserved to Disabled due to a foreign write access at offsets [0x0..0x8] + --> $DIR/write-during-2phase.rs:LL:CC + | +LL | *inner = 42; + | ^^^^^^^^^^^ + = help: this corresponds to a loss of read and write permissions + = note: BACKTRACE (of the first span): = note: inside `Foo::add` at $DIR/write-during-2phase.rs:LL:CC note: inside `main` --> $DIR/write-during-2phase.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs index c1041ee32a4..ed43e552506 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs @@ -1,7 +1,7 @@ //@compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance -Cdebug-assertions=no // With the symbolic alignment check, even with intptrcast and without // validation, we want to be *sure* to catch bugs that arise from pointers being -// insufficiently aligned. The only way to achieve that is not not let programs +// insufficiently aligned. The only way to achieve that is not to let programs // exploit integer information for alignment, so here we test that this is // indeed the case. // diff --git a/src/tools/miri/tests/panic/oob_subslice.rs b/src/tools/miri/tests/panic/oob_subslice.rs new file mode 100644 index 00000000000..4e79b6a99e9 --- /dev/null +++ b/src/tools/miri/tests/panic/oob_subslice.rs @@ -0,0 +1,7 @@ +// This once failed with "unwinding past a stack frame that does not allow unwinding", +// fixed by https://github.com/rust-lang/rust/issues/110233. + +fn main() { + let x = [1, 2, 3, 4]; + let _val = &x[..=4]; +} diff --git a/src/tools/miri/tests/panic/oob_subslice.stderr b/src/tools/miri/tests/panic/oob_subslice.stderr new file mode 100644 index 00000000000..4c6deaeccf6 --- /dev/null +++ b/src/tools/miri/tests/panic/oob_subslice.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'range end index 5 out of range for slice of length 4', $DIR/oob_subslice.rs:LL:CC +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs b/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs index 6516396ac54..ae874740f2b 100644 --- a/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs +++ b/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs @@ -14,7 +14,7 @@ static mut RECORD: usize = 0; static mut KEYS: [Key; 2] = [0; 2]; static mut GLOBALS: [u64; 2] = [1, 0]; -static mut CANNARY: *mut u64 = ptr::null_mut(); // this serves as a cannary: if TLS dtors are not run properly, this will not get deallocated, making the test fail. +static mut CANARY: *mut u64 = ptr::null_mut(); // this serves as a canary: if TLS dtors are not run properly, this will not get deallocated, making the test fail. pub unsafe fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key { let mut key = 0; @@ -33,7 +33,7 @@ pub fn record(r: usize) { } unsafe extern "C" fn dtor(ptr: *mut u64) { - assert!(CANNARY != ptr::null_mut()); // make sure we do not get run too often + assert!(CANARY != ptr::null_mut()); // make sure we do not get run too often let val = *ptr; let which_key = @@ -45,15 +45,15 @@ unsafe extern "C" fn dtor(ptr: *mut u64) { set(KEYS[which_key], ptr as *mut _); } - // Check if the records matches what we expect. If yes, clear the cannary. - // If the record is wrong, the cannary will never get cleared, leading to a leak -> test fails. + // Check if the records matches what we expect. If yes, clear the canary. + // If the record is wrong, the canary will never get cleared, leading to a leak -> test fails. // If the record is incomplete (i.e., more dtor calls happen), the check at the beginning of this function will fail -> test fails. // The correct sequence is: First key 0, then key 1, then key 0. // Note that this relies on dtor order, which is not specified by POSIX, but seems to be // consistent between Miri and Linux currently (as of Aug 2022). if RECORD == 0_1_0 { - drop(Box::from_raw(CANNARY)); - CANNARY = ptr::null_mut(); + drop(Box::from_raw(CANARY)); + CANARY = ptr::null_mut(); } } @@ -67,7 +67,7 @@ fn main() { set(*key, global as *mut _ as *mut u8); } - // Initialize cannary - CANNARY = Box::into_raw(Box::new(0u64)); + // Initialize canary + CANARY = Box::into_raw(Box::new(0u64)); } } diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs index cd071a7f32a..fbdf27688a9 100644 --- a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs @@ -130,7 +130,7 @@ fn test_readlink() { let mut large_buf = vec![0xFF; expected_path.len() + 1]; let res = unsafe { libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len()) }; - // Check that the resovled path was properly written into the buf. + // Check that the resolved path was properly written into the buf. assert_eq!(&large_buf[..(large_buf.len() - 1)], expected_path); assert_eq!(large_buf.last(), Some(&0xFF)); assert_eq!(res, large_buf.len() as isize - 1); diff --git a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs index 98e1c3a0adb..82ef59427ae 100644 --- a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs +++ b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs @@ -90,7 +90,7 @@ fn test_posix_realpath_errors() { use std::ffi::CString; use std::io::ErrorKind; - // Test non-existent path returns an error. + // Test nonexistent path returns an error. let c_path = CString::new("./nothing_to_see_here").expect("CString::new failed"); let r = unsafe { libc::realpath(c_path.as_ptr(), std::ptr::null_mut()) }; assert!(r.is_null()); @@ -302,6 +302,101 @@ fn test_posix_mkstemp() { } } +fn test_memcpy() { + unsafe { + let src = [1i8, 2, 3]; + let dest = libc::calloc(3, 1); + libc::memcpy(dest, src.as_ptr() as *const libc::c_void, 3); + let slc = std::slice::from_raw_parts(dest as *const i8, 3); + assert_eq!(*slc, [1i8, 2, 3]); + libc::free(dest); + } + + unsafe { + let src = [1i8, 2, 3]; + let dest = libc::calloc(4, 1); + libc::memcpy(dest, src.as_ptr() as *const libc::c_void, 3); + let slc = std::slice::from_raw_parts(dest as *const i8, 4); + assert_eq!(*slc, [1i8, 2, 3, 0]); + libc::free(dest); + } + + unsafe { + let src = 123_i32; + let mut dest = 0_i32; + libc::memcpy( + &mut dest as *mut i32 as *mut libc::c_void, + &src as *const i32 as *const libc::c_void, + std::mem::size_of::<i32>(), + ); + assert_eq!(dest, src); + } + + unsafe { + let src = Some(123); + let mut dest: Option<i32> = None; + libc::memcpy( + &mut dest as *mut Option<i32> as *mut libc::c_void, + &src as *const Option<i32> as *const libc::c_void, + std::mem::size_of::<Option<i32>>(), + ); + assert_eq!(dest, src); + } + + unsafe { + let src = &123; + let mut dest = &42; + libc::memcpy( + &mut dest as *mut &'static i32 as *mut libc::c_void, + &src as *const &'static i32 as *const libc::c_void, + std::mem::size_of::<&'static i32>(), + ); + assert_eq!(*dest, 123); + } +} + +fn test_strcpy() { + use std::ffi::{CStr, CString}; + + // case: src_size equals dest_size + unsafe { + let src = CString::new("rust").unwrap(); + let size = src.as_bytes_with_nul().len(); + let dest = libc::malloc(size); + libc::strcpy(dest as *mut libc::c_char, src.as_ptr()); + assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref()); + libc::free(dest); + } + + // case: src_size is less than dest_size + unsafe { + let src = CString::new("rust").unwrap(); + let size = src.as_bytes_with_nul().len(); + let dest = libc::malloc(size + 1); + libc::strcpy(dest as *mut libc::c_char, src.as_ptr()); + assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref()); + libc::free(dest); + } +} + +#[cfg(target_os = "linux")] +fn test_sigrt() { + let min = libc::SIGRTMIN(); + let max = libc::SIGRTMAX(); + + // "The Linux kernel supports a range of 33 different real-time + // signals, numbered 32 to 64" + assert!(min >= 32); + assert!(max >= 32); + assert!(min <= 64); + assert!(max <= 64); + + // "POSIX.1-2001 requires that an implementation support at least + // _POSIX_RTSIG_MAX (8) real-time signals." + assert!(min < max); + assert!(max - min >= 8) +} + fn main() { test_posix_gettimeofday(); test_posix_mkstemp(); @@ -315,9 +410,13 @@ fn main() { test_isatty(); test_clocks(); + test_memcpy(); + test_strcpy(); + #[cfg(target_os = "linux")] { test_posix_fadvise(); test_sync_file_range(); + test_sigrt(); } } diff --git a/src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs b/src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs index 0ed2a941bc4..769a7a7d384 100644 --- a/src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs +++ b/src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs @@ -1,5 +1,5 @@ // Need to disable preemption to stay on the supported MVP codepath in mio. -//@compile-flags: -Zmiri-permissive-provenance +//@compile-flags: -Zmiri-permissive-provenance -Zmiri-preemption-rate=0 //@only-target-x86_64-unknown-linux: support for tokio exists only on linux and x86 #[tokio::main] diff --git a/src/tools/miri/tests/pass/0weak_memory_consistency.rs b/src/tools/miri/tests/pass/0weak_memory_consistency.rs index f3820bd660d..3a531eede67 100644 --- a/src/tools/miri/tests/pass/0weak_memory_consistency.rs +++ b/src/tools/miri/tests/pass/0weak_memory_consistency.rs @@ -10,7 +10,7 @@ // the RNG and never observed in our tests. // // To mitigate this, each test is ran enough times such that the chance -// of spurious success is very low. These tests never supriously fail. +// of spurious success is very low. These tests never spuriously fail. // Test cases and their consistent outcomes are from // http://svr-pes20-cppmem.cl.cam.ac.uk/cppmem/ diff --git a/src/tools/miri/tests/pass/dyn-arbitrary-self.rs b/src/tools/miri/tests/pass/dyn-arbitrary-self.rs index fc58775a195..6be13b155f4 100644 --- a/src/tools/miri/tests/pass/dyn-arbitrary-self.rs +++ b/src/tools/miri/tests/pass/dyn-arbitrary-self.rs @@ -93,7 +93,7 @@ fn pointers_and_wrappers() { trait Trait { // This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable - // without unsized_locals), but wrappers arond `Self` currently are not. + // without unsized_locals), but wrappers around `Self` currently are not. // FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented // fn wrapper(self: Wrapper<Self>) -> i32; fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32; diff --git a/src/tools/miri/tests/pass/global_allocator.rs b/src/tools/miri/tests/pass/global_allocator.rs index 24a56c663f0..9a40c322b36 100644 --- a/src/tools/miri/tests/pass/global_allocator.rs +++ b/src/tools/miri/tests/pass/global_allocator.rs @@ -19,7 +19,7 @@ unsafe impl GlobalAlloc for Allocator { unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { if layout.size() == 123 { - println!("Dellocated!") + println!("Deallocated!") } System.dealloc(ptr, layout) diff --git a/src/tools/miri/tests/pass/global_allocator.stdout b/src/tools/miri/tests/pass/global_allocator.stdout index 411a4cdd146..30c61946407 100644 --- a/src/tools/miri/tests/pass/global_allocator.stdout +++ b/src/tools/miri/tests/pass/global_allocator.stdout @@ -1,2 +1,2 @@ Allocated! -Dellocated! +Deallocated! diff --git a/src/tools/miri/tests/pass/issues/issue-29746.rs b/src/tools/miri/tests/pass/issues/issue-29746.rs index 43bed4464b9..6b971c5217b 100644 --- a/src/tools/miri/tests/pass/issues/issue-29746.rs +++ b/src/tools/miri/tests/pass/issues/issue-29746.rs @@ -7,7 +7,7 @@ macro_rules! zip { }; // Intermediate steps to build the zipped expression, the match pattern, and - // and the output tuple of the closure, using macro hygene to repeatedly + // and the output tuple of the closure, using macro hygiene to repeatedly // introduce new variables named 'x'. ([$a:expr, $($rest:expr),*], $zip:expr, $pat:pat, [$($flat:expr),*]) => { zip!([$($rest),*], $zip.zip($a), ($pat,x), [$($flat),*, x]) diff --git a/src/tools/miri/tests/pass/packed_struct.rs b/src/tools/miri/tests/pass/packed_struct.rs index 85acab858aa..0b06167aec2 100644 --- a/src/tools/miri/tests/pass/packed_struct.rs +++ b/src/tools/miri/tests/pass/packed_struct.rs @@ -36,7 +36,7 @@ fn test_basic() { let b = x.b; assert_eq!(a, 42); assert_eq!(b, 99); - assert_eq!(&x.fill, &0); // `fill` just requirs 1-byte-align, so this is fine + assert_eq!(&x.fill, &0); // `fill` just requires 1-byte-align, so this is fine // can't do `assert_eq!(x.a, 42)`, because `assert_eq!` takes a reference assert_eq!({ x.a }, 42); assert_eq!({ x.b }, 99); diff --git a/src/tools/miri/tests/pass/ptr_offset.rs b/src/tools/miri/tests/pass/ptr_offset.rs index 95eac8522fb..92b275b0032 100644 --- a/src/tools/miri/tests/pass/ptr_offset.rs +++ b/src/tools/miri/tests/pass/ptr_offset.rs @@ -63,7 +63,7 @@ fn ptr_arith_offset_overflow() { let v = [1i16, 2]; let x = &mut ptr::null(); // going through memory as there are more sanity checks along that path *x = v.as_ptr().wrapping_offset(1); // ptr to the 2nd element - // Adding 2*isize::max and then 1 is like substracting 1 + // Adding 2*isize::max and then 1 is like subtracting 1 *x = x.wrapping_offset(isize::MAX); *x = x.wrapping_offset(isize::MAX); *x = x.wrapping_offset(1); diff --git a/src/tools/miri/tests/pass/rfc1623.rs b/src/tools/miri/tests/pass/rfc1623.rs index 76e2c01e745..8f1ef1b75cf 100644 --- a/src/tools/miri/tests/pass/rfc1623.rs +++ b/src/tools/miri/tests/pass/rfc1623.rs @@ -58,7 +58,7 @@ fn main() { STATIC_SIMPLE_FN(x); CONST_SIMPLE_FN(x); - STATIC_BAZ(BYTES); // neees static lifetime + STATIC_BAZ(BYTES); // needs static lifetime CONST_BAZ(BYTES); // make sure this works with different lifetimes diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index e379288de01..af245aa89aa 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -365,7 +365,7 @@ fn test_directory() { // Deleting the directory should succeed. remove_dir(&dir_path).unwrap(); - // Reading the metadata of a non-existent directory should fail with a "not found" error. + // Reading the metadata of a nonexistent directory should fail with a "not found" error. assert_eq!(ErrorKind::NotFound, check_metadata(&[], &dir_path).unwrap_err().kind()); // To test remove_dir_all, re-create the directory with a file and a directory in it. diff --git a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs index c3e30627a7c..9e604f9abb8 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs @@ -23,17 +23,17 @@ fn example(variant: bool) { let mut c = 42u32; let x_unique1 = &mut c; - // [..., Unique(1)] + // stack: [..., Unique(1)] let x_raw2 = x_unique1 as *mut u32; let x_raw2_addr = x_raw2.expose_addr(); - // [..., Unique(1), SharedRW(2)] + // stack: [..., Unique(1), SharedRW(2)] let x_unique3 = &mut *x_raw2; - // [.., Unique(1), SharedRW(2), Unique(3)] + // stack: [.., Unique(1), SharedRW(2), Unique(3)] assert_eq!(not_so_innocent(x_unique3), x_raw2_addr); - // [.., Unique(1), SharedRW(2), Unique(3), ..., SharedRW(4)] + // stack: [.., Unique(1), SharedRW(2), Unique(3), ..., SharedRW(4)] // Do an int2ptr cast. This can pick tag 2 or 4 (the two previously exposed tags). // 4 is the "obvious" choice (topmost tag, what we used to do with untagged pointers). diff --git a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs index 8e78efa73c7..d7d7d1f97d6 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs @@ -90,7 +90,7 @@ fn mut_raw_mut() { assert_eq!(unsafe { *xraw }, 4); assert_eq!(*xref1, 4); assert_eq!(unsafe { *xraw }, 4); - // we cannot use xref2; see `compile-fail/stacked-borows/illegal_read4.rs` + // we cannot use xref2; see `compile-fail/stacked-borrows/illegal_read4.rs` } assert_eq!(x, 4); } @@ -104,7 +104,7 @@ fn partially_invalidate_mut() { assert_eq!(*data, (1, 1)); } -// Make sure that we can handle the situation where a loaction is frozen when being dropped. +// Make sure that we can handle the situation where a location is frozen when being dropped. fn drop_after_sharing() { let x = String::from("hello!"); let _len = x.len(); @@ -224,7 +224,7 @@ fn wide_raw_ptr_in_tuple() { fn not_unpin_not_protected() { // `&mut !Unpin`, at least for now, does not get `noalias` nor `dereferenceable`, so we also // don't add protectors. (We could, but until we have a better idea for where we want to go with - // the self-referntial-generator situation, it does not seem worth the potential trouble.) + // the self-referential-generator situation, it does not seem worth the potential trouble.) use std::marker::PhantomPinned; pub struct NotUnpin(i32, PhantomPinned); diff --git a/src/tools/miri/tests/pass/strings.rs b/src/tools/miri/tests/pass/strings.rs index 5e2d2e9b5b5..72cdbe7ed5d 100644 --- a/src/tools/miri/tests/pass/strings.rs +++ b/src/tools/miri/tests/pass/strings.rs @@ -29,7 +29,7 @@ fn unique_aliasing() { // This is a regression test for the aliasing rules of a `Unique<T>` pointer. // At the time of writing this test case, Miri does not treat `Unique<T>` // pointers as a special case, these are treated like any other raw pointer. - // However, there are existing Github issues which may lead to `Unique<T>` + // However, there are existing GitHub issues which may lead to `Unique<T>` // becoming a special case through asserting unique ownership over the pointee: // - https://github.com/rust-lang/unsafe-code-guidelines/issues/258 // - https://github.com/rust-lang/unsafe-code-guidelines/issues/262 diff --git a/src/tools/miri/tests/pass/tree-borrows/cell-alternate-writes.stderr b/src/tools/miri/tests/pass/tree-borrows/cell-alternate-writes.stderr index d4bc822b4bb..1eab4685a35 100644 --- a/src/tools/miri/tests/pass/tree-borrows/cell-alternate-writes.stderr +++ b/src/tools/miri/tests/pass/tree-borrows/cell-alternate-writes.stderr @@ -1,10 +1,12 @@ ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Re*| └────<TAG=data,x,y> +| Act| └─┬──<TAG=root of the allocation> +| Re*| └────<TAG=data, x, y> ────────────────────────────────────────────────────────────────────── ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Act| └────<TAG=data,x,y> +| Act| └─┬──<TAG=root of the allocation> +| Act| └────<TAG=data, x, y> ────────────────────────────────────────────────────────────────────── diff --git a/src/tools/miri/tests/pass/tree-borrows/end-of-protector.stderr b/src/tools/miri/tests/pass/tree-borrows/end-of-protector.stderr index d08d6948320..c20da1a593f 100644 --- a/src/tools/miri/tests/pass/tree-borrows/end-of-protector.stderr +++ b/src/tools/miri/tests/pass/tree-borrows/end-of-protector.stderr @@ -1,32 +1,36 @@ ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Res| └─┬──<TAG=data> -| Res| └────<TAG=x> +| Act| └─┬──<TAG=root of the allocation> +| Res| └─┬──<TAG=data> +| Res| └────<TAG=x> ────────────────────────────────────────────────────────────────────── ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Res| └─┬──<TAG=data> -| Res| └─┬──<TAG=x> -| Res| └─┬──<TAG=caller:x> -| Res| └────<TAG=callee:x> Strongly protected +| Act| └─┬──<TAG=root of the allocation> +| Res| └─┬──<TAG=data> +| Res| └─┬──<TAG=x> +| Res| └─┬──<TAG=caller:x> +| Res| └────<TAG=callee:x> Strongly protected ────────────────────────────────────────────────────────────────────── ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Res| └─┬──<TAG=data> -| Res| ├─┬──<TAG=x> -| Res| │ └─┬──<TAG=caller:x> -| Res| │ └────<TAG=callee:x> -| Res| └────<TAG=y> +| Act| └─┬──<TAG=root of the allocation> +| Res| └─┬──<TAG=data> +| Res| ├─┬──<TAG=x> +| Res| │ └─┬──<TAG=caller:x> +| Res| │ └────<TAG=callee:x> +| Res| └────<TAG=y> ────────────────────────────────────────────────────────────────────── ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Act| └─┬──<TAG=data> -| Dis| ├─┬──<TAG=x> -| Dis| │ └─┬──<TAG=caller:x> -| Dis| │ └────<TAG=callee:x> -| Act| └────<TAG=y> +| Act| └─┬──<TAG=root of the allocation> +| Act| └─┬──<TAG=data> +| Dis| ├─┬──<TAG=x> +| Dis| │ └─┬──<TAG=caller:x> +| Dis| │ └────<TAG=callee:x> +| Act| └────<TAG=y> ────────────────────────────────────────────────────────────────────── diff --git a/src/tools/miri/tests/pass/tree-borrows/formatting.stderr b/src/tools/miri/tests/pass/tree-borrows/formatting.stderr index a59775cf21f..8c3779fe1f7 100644 --- a/src/tools/miri/tests/pass/tree-borrows/formatting.stderr +++ b/src/tools/miri/tests/pass/tree-borrows/formatting.stderr @@ -1,29 +1,31 @@ -───────────────────────────────────────────────────────────────────────────── +─────────────────────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1.. 2.. 10.. 11..100..101..1000..1001..1024 -| Res| Act| Res| Act| Res| Act| Res| Act| Res| └─┬──<TAG=data> -|----| Act|----|?Dis|----|?Dis| ----| ?Dis| ----| ├────<TAG=data[1]> -|----|----|----| Act|----|?Dis| ----| ?Dis| ----| ├────<TAG=data[10]> -|----|----|----|----|----| Frz| ----| ?Dis| ----| ├────<TAG=data[100]> -|----|----|----|----|----|----| ----| Act| ----| └────<TAG=data[1000]> -───────────────────────────────────────────────────────────────────────────── +| Act| Act| Act| Act| Act| Act| Act| Act| Act| └─┬──<TAG=root of the allocation> +| Res| Act| Res| Act| Res| Act| Res| Act| Res| └─┬──<TAG=data> +|----| Act|----|?Dis|----|?Dis| ----| ?Dis| ----| ├────<TAG=data[1]> +|----|----|----| Act|----|?Dis| ----| ?Dis| ----| ├────<TAG=data[10]> +|----|----|----|----|----| Frz| ----| ?Dis| ----| ├────<TAG=data[100]> +|----|----|----|----|----|----| ----| Act| ----| └────<TAG=data[1000]> +─────────────────────────────────────────────────────────────────────────────────────── ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Frz| └─┬──<TAG=x> -| Frz| ├─┬──<TAG=xa> -| Frz| │ ├────<TAG=xaa> -| Frz| │ └────<TAG=xab> -| Frz| ├─┬──<TAG=xb> -| Frz| │ └─┬──<TAG=xba> -| Frz| │ └─┬──<TAG=xbaa> -| Frz| │ └─┬──<TAG=xbaaa> -| Frz| │ └────<TAG=xbaaaa> -| Frz| └─┬──<TAG=xc> -| Frz| ├─┬──<TAG=xca> -| Frz| │ ├────<TAG=xcaa> -| Frz| │ └────<TAG=xcab> -| Frz| └─┬──<TAG=xcb> -| Frz| ├────<TAG=xcba> -| Frz| └────<TAG=xcbb> +| Act| └─┬──<TAG=root of the allocation> +| Frz| └─┬──<TAG=x> +| Frz| ├─┬──<TAG=xa> +| Frz| │ ├────<TAG=xaa> +| Frz| │ └────<TAG=xab> +| Frz| ├─┬──<TAG=xb> +| Frz| │ └─┬──<TAG=xba> +| Frz| │ └─┬──<TAG=xbaa> +| Frz| │ └─┬──<TAG=xbaaa> +| Frz| │ └────<TAG=xbaaaa> +| Frz| └─┬──<TAG=xc> +| Frz| ├─┬──<TAG=xca> +| Frz| │ ├────<TAG=xcaa> +| Frz| │ └────<TAG=xcab> +| Frz| └─┬──<TAG=xcb> +| Frz| ├────<TAG=xcba> +| Frz| └────<TAG=xcbb> ────────────────────────────────────────────────────────────────────── diff --git a/src/tools/miri/tests/pass/tree-borrows/read-only-from-mut.rs b/src/tools/miri/tests/pass/tree-borrows/read-only-from-mut.rs deleted file mode 100644 index 4daf06c777e..00000000000 --- a/src/tools/miri/tests/pass/tree-borrows/read-only-from-mut.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@compile-flags: -Zmiri-tree-borrows - -// Tree Borrows has no issue with several mutable references existing -// at the same time, as long as they are used only immutably. -// I.e. multiple Reserved can coexist. -pub fn main() { - unsafe { - let base = &mut 42u64; - let r1 = &mut *(base as *mut u64); - let r2 = &mut *(base as *mut u64); - let _l = *r1; - let _l = *r2; - } -} diff --git a/src/tools/miri/tests/pass/tree-borrows/reborrow-is-read.stderr b/src/tools/miri/tests/pass/tree-borrows/reborrow-is-read.stderr index b9c52c20640..8c4323b2f7f 100644 --- a/src/tools/miri/tests/pass/tree-borrows/reborrow-is-read.stderr +++ b/src/tools/miri/tests/pass/tree-borrows/reborrow-is-read.stderr @@ -1,13 +1,15 @@ ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Act| └─┬──<TAG=parent> -| Act| └────<TAG=x> +| Act| └─┬──<TAG=root of the allocation> +| Act| └─┬──<TAG=parent> +| Act| └────<TAG=x> ────────────────────────────────────────────────────────────────────── ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Act| └─┬──<TAG=parent> -| Frz| ├────<TAG=x> -| Res| └────<TAG=y> +| Act| └─┬──<TAG=root of the allocation> +| Act| └─┬──<TAG=parent> +| Frz| ├────<TAG=x> +| Res| └────<TAG=y> ────────────────────────────────────────────────────────────────────── diff --git a/src/tools/miri/tests/pass/tree-borrows/reserved.stderr b/src/tools/miri/tests/pass/tree-borrows/reserved.stderr index d76ee0f8266..afb91700222 100644 --- a/src/tools/miri/tests/pass/tree-borrows/reserved.stderr +++ b/src/tools/miri/tests/pass/tree-borrows/reserved.stderr @@ -2,51 +2,57 @@ ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Re*| └─┬──<TAG=base> -| Re*| ├─┬──<TAG=x> -| Re*| │ └─┬──<TAG=caller:x> -| Frz| │ └────<TAG=callee:x> -| Re*| └────<TAG=y,caller:y,callee:y> +| Act| └─┬──<TAG=root of the allocation> +| Re*| └─┬──<TAG=base> +| Re*| ├─┬──<TAG=x> +| Re*| │ └─┬──<TAG=caller:x> +| Frz| │ └────<TAG=callee:x> +| Re*| └────<TAG=y, caller:y, callee:y> ────────────────────────────────────────────────────────────────────── [interior mut] Foreign Read: Re* -> Re* ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 8 -| Re*| └─┬──<TAG=base> -| Re*| ├────<TAG=x> -| Re*| └────<TAG=y> +| Act| └─┬──<TAG=root of the allocation> +| Re*| └─┬──<TAG=base> +| Re*| ├────<TAG=x> +| Re*| └────<TAG=y> ────────────────────────────────────────────────────────────────────── [interior mut] Foreign Write: Re* -> Re* ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 8 -| Act| └─┬──<TAG=base> -| Re*| ├────<TAG=x> -| Act| └────<TAG=y> +| Act| └─┬──<TAG=root of the allocation> +| Act| └─┬──<TAG=base> +| Re*| ├────<TAG=x> +| Act| └────<TAG=y> ────────────────────────────────────────────────────────────────────── [protected] Foreign Read: Res -> Frz ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Res| └─┬──<TAG=base> -| Res| ├─┬──<TAG=x> -| Res| │ └─┬──<TAG=caller:x> -| Frz| │ └────<TAG=callee:x> -| Res| └────<TAG=y,caller:y,callee:y> +| Act| └─┬──<TAG=root of the allocation> +| Res| └─┬──<TAG=base> +| Res| ├─┬──<TAG=x> +| Res| │ └─┬──<TAG=caller:x> +| Frz| │ └────<TAG=callee:x> +| Res| └────<TAG=y, caller:y, callee:y> ────────────────────────────────────────────────────────────────────── [] Foreign Read: Res -> Res ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Res| └─┬──<TAG=base> -| Res| ├────<TAG=x> -| Res| └────<TAG=y> +| Act| └─┬──<TAG=root of the allocation> +| Res| └─┬──<TAG=base> +| Res| ├────<TAG=x> +| Res| └────<TAG=y> ────────────────────────────────────────────────────────────────────── [] Foreign Write: Res -> Dis ────────────────────────────────────────────────────────────────────── Warning: this tree is indicative only. Some tags may have been hidden. 0.. 1 -| Act| └─┬──<TAG=base> -| Dis| ├────<TAG=x> -| Act| └────<TAG=y> +| Act| └─┬──<TAG=root of the allocation> +| Act| └─┬──<TAG=base> +| Dis| ├────<TAG=x> +| Act| └────<TAG=y> ────────────────────────────────────────────────────────────────────── diff --git a/src/tools/miri/tests/pass/tree-borrows/tree-borrows.rs b/src/tools/miri/tests/pass/tree-borrows/tree-borrows.rs new file mode 100644 index 00000000000..aa6f7078890 --- /dev/null +++ b/src/tools/miri/tests/pass/tree-borrows/tree-borrows.rs @@ -0,0 +1,280 @@ +//@compile-flags: -Zmiri-tree-borrows +#![feature(allocator_api)] + +use std::mem; +use std::ptr; + +fn main() { + aliasing_read_only_mutable_refs(); + string_as_mut_ptr(); + + // Stacked Borrows tests + read_does_not_invalidate1(); + read_does_not_invalidate2(); + mut_raw_then_mut_shr(); + mut_shr_then_mut_raw(); + mut_raw_mut(); + partially_invalidate_mut(); + drop_after_sharing(); + direct_mut_to_const_raw(); + two_raw(); + shr_and_raw(); + disjoint_mutable_subborrows(); + raw_ref_to_part(); + array_casts(); + mut_below_shr(); + wide_raw_ptr_in_tuple(); + not_unpin_not_protected(); +} + +// Tree Borrows has no issue with several mutable references existing +// at the same time, as long as they are used only immutably. +// I.e. multiple Reserved can coexist. +pub fn aliasing_read_only_mutable_refs() { + unsafe { + let base = &mut 42u64; + let r1 = &mut *(base as *mut u64); + let r2 = &mut *(base as *mut u64); + let _l = *r1; + let _l = *r2; + } +} + +pub fn string_as_mut_ptr() { + // This errors in Stacked Borrows since as_mut_ptr restricts the provenance, + // but with Tree Borrows it should work. + unsafe { + let mut s = String::from("hello"); + s.reserve(1); // make the `str` that `s` derefs to not cover the entire `s`. + + // Prevent automatically dropping the String's data + let mut s = mem::ManuallyDrop::new(s); + + let ptr = s.as_mut_ptr(); + let len = s.len(); + let capacity = s.capacity(); + + let s = String::from_raw_parts(ptr, len, capacity); + + assert_eq!(String::from("hello"), s); + } +} + +// ----- The tests below were taken from Stacked Borrows ---- + +// Make sure that reading from an `&mut` does, like reborrowing to `&`, +// NOT invalidate other reborrows. +fn read_does_not_invalidate1() { + fn foo(x: &mut (i32, i32)) -> &i32 { + let xraw = x as *mut (i32, i32); + let ret = unsafe { &(*xraw).1 }; + let _val = x.1; // we just read, this does NOT invalidate the reborrows. + ret + } + assert_eq!(*foo(&mut (1, 2)), 2); +} +// Same as above, but this time we first create a raw, then read from `&mut` +// and then freeze from the raw. +fn read_does_not_invalidate2() { + fn foo(x: &mut (i32, i32)) -> &i32 { + let xraw = x as *mut (i32, i32); + let _val = x.1; // we just read, this does NOT invalidate the raw reborrow. + let ret = unsafe { &(*xraw).1 }; + ret + } + assert_eq!(*foo(&mut (1, 2)), 2); +} + +// Escape a mut to raw, then share the same mut and use the share, then the raw. +// That should work. +fn mut_raw_then_mut_shr() { + let mut x = 2; + let xref = &mut x; + let xraw = &mut *xref as *mut _; + let xshr = &*xref; + assert_eq!(*xshr, 2); + unsafe { + *xraw = 4; + } + assert_eq!(x, 4); +} + +// Create first a shared reference and then a raw pointer from a `&mut` +// should permit mutation through that raw pointer. +fn mut_shr_then_mut_raw() { + let xref = &mut 2; + let _xshr = &*xref; + let xraw = xref as *mut _; + unsafe { + *xraw = 3; + } + assert_eq!(*xref, 3); +} + +// Ensure that if we derive from a mut a raw, and then from that a mut, +// and then read through the original mut, that does not invalidate the raw. +// This shows that the read-exception for `&mut` applies even if the `Shr` item +// on the stack is not at the top. +fn mut_raw_mut() { + let mut x = 2; + { + let xref1 = &mut x; + let xraw = xref1 as *mut _; + let _xref2 = unsafe { &mut *xraw }; + let _val = *xref1; + unsafe { + *xraw = 4; + } + // we can now use both xraw and xref1, for reading + assert_eq!(*xref1, 4); + assert_eq!(unsafe { *xraw }, 4); + assert_eq!(*xref1, 4); + assert_eq!(unsafe { *xraw }, 4); + // we cannot use xref2; see `compile-fail/stacked-borrows/illegal_read4.rs` + } + assert_eq!(x, 4); +} + +fn partially_invalidate_mut() { + let data = &mut (0u8, 0u8); + let reborrow = &mut *data as *mut (u8, u8); + let shard = unsafe { &mut (*reborrow).0 }; + data.1 += 1; // the deref overlaps with `shard`, but that is ok; the access does not overlap. + *shard += 1; // so we can still use `shard`. + assert_eq!(*data, (1, 1)); +} + +// Make sure that we can handle the situation where a location is frozen when being dropped. +fn drop_after_sharing() { + let x = String::from("hello!"); + let _len = x.len(); +} + +// Make sure that coercing &mut T to *const T produces a writeable pointer. +fn direct_mut_to_const_raw() { + // TODO: This is currently disabled, waiting on a decision on <https://github.com/rust-lang/rust/issues/56604> + /*let x = &mut 0; + let y: *const i32 = x; + unsafe { *(y as *mut i32) = 1; } + assert_eq!(*x, 1); + */ +} + +// Make sure that we can create two raw pointers from a mutable reference and use them both. +fn two_raw() { + unsafe { + let x = &mut 0; + let y1 = x as *mut _; + let y2 = x as *mut _; + *y1 += 2; + *y2 += 1; + } +} + +// Make sure that creating a *mut does not invalidate existing shared references. +fn shr_and_raw() { + unsafe { + let x = &mut 0; + let y1: &i32 = mem::transmute(&*x); // launder lifetimes + let y2 = x as *mut _; + let _val = *y1; + *y2 += 1; + } +} + +fn disjoint_mutable_subborrows() { + struct Foo { + a: String, + b: Vec<u32>, + } + + unsafe fn borrow_field_a<'a>(this: *mut Foo) -> &'a mut String { + &mut (*this).a + } + + unsafe fn borrow_field_b<'a>(this: *mut Foo) -> &'a mut Vec<u32> { + &mut (*this).b + } + + let mut foo = Foo { a: "hello".into(), b: vec![0, 1, 2] }; + + let ptr = &mut foo as *mut Foo; + + let a = unsafe { borrow_field_a(ptr) }; + let b = unsafe { borrow_field_b(ptr) }; + b.push(4); + a.push_str(" world"); + assert_eq!(format!("{:?} {:?}", a, b), r#""hello world" [0, 1, 2, 4]"#); +} + +fn raw_ref_to_part() { + struct Part { + _lame: i32, + } + + #[repr(C)] + struct Whole { + part: Part, + extra: i32, + } + + let it = Box::new(Whole { part: Part { _lame: 0 }, extra: 42 }); + let whole = ptr::addr_of_mut!(*Box::leak(it)); + let part = unsafe { ptr::addr_of_mut!((*whole).part) }; + let typed = unsafe { &mut *(part as *mut Whole) }; + assert!(typed.extra == 42); + drop(unsafe { Box::from_raw(whole) }); +} + +/// When casting an array reference to a raw element ptr, that should cover the whole array. +fn array_casts() { + let mut x: [usize; 2] = [0, 0]; + let p = &mut x as *mut usize; + unsafe { + *p.add(1) = 1; + } + + let x: [usize; 2] = [0, 1]; + let p = &x as *const usize; + assert_eq!(unsafe { *p.add(1) }, 1); +} + +/// Transmuting &&i32 to &&mut i32 is fine. +fn mut_below_shr() { + let x = 0; + let y = &x; + let p = unsafe { core::mem::transmute::<&&i32, &&mut i32>(&y) }; + let r = &**p; + let _val = *r; +} + +fn wide_raw_ptr_in_tuple() { + let mut x: Box<dyn std::any::Any> = Box::new("ouch"); + let r = &mut *x as *mut dyn std::any::Any; + // This triggers the visitor-based recursive retagging. It is *not* supposed to retag raw + // pointers, but then the visitor might recurse into the "fields" of a wide raw pointer and + // finds a reference (to a vtable) there that it wants to retag... and that would be Wrong. + let pair = (r, &0); + let r = unsafe { &mut *pair.0 }; + // Make sure the fn ptr part of the vtable is still fine. + r.type_id(); +} + +fn not_unpin_not_protected() { + // `&mut !Unpin`, at least for now, does not get `noalias` nor `dereferenceable`, so we also + // don't add protectors. (We could, but until we have a better idea for where we want to go with + // the self-referential-generator situation, it does not seem worth the potential trouble.) + use std::marker::PhantomPinned; + + pub struct NotUnpin(i32, PhantomPinned); + + fn inner(x: &mut NotUnpin, f: fn(&mut NotUnpin)) { + // `f` may mutate, but it may not deallocate! + f(x) + } + + inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| { + let raw = x as *mut _; + drop(unsafe { Box::from_raw(raw) }); + }); +} diff --git a/src/tools/miri/tests/pass/weak_memory/extra_cpp.rs b/src/tools/miri/tests/pass/weak_memory/extra_cpp.rs index 07cbb4a803f..94df7308080 100644 --- a/src/tools/miri/tests/pass/weak_memory/extra_cpp.rs +++ b/src/tools/miri/tests/pass/weak_memory/extra_cpp.rs @@ -1,6 +1,6 @@ //@compile-flags: -Zmiri-ignore-leaks -// Tests operations not perfomable through C++'s atomic API +// Tests operations not performable through C++'s atomic API // but doable in safe (at least sound) Rust. #![feature(atomic_from_mut)] diff --git a/src/tools/miri/tests/pass/weak_memory/extra_cpp_unsafe.rs b/src/tools/miri/tests/pass/weak_memory/extra_cpp_unsafe.rs index f7e2748408f..48b15191b38 100644 --- a/src/tools/miri/tests/pass/weak_memory/extra_cpp_unsafe.rs +++ b/src/tools/miri/tests/pass/weak_memory/extra_cpp_unsafe.rs @@ -1,6 +1,6 @@ //@compile-flags: -Zmiri-ignore-leaks -// Tests operations not perfomable through C++'s atomic API +// Tests operations not performable through C++'s atomic API // but doable in unsafe Rust which we think *should* be fine. // Nonetheless they may be determined as inconsistent with the // memory model in the future. diff --git a/src/tools/miropt-test-tools/src/lib.rs b/src/tools/miropt-test-tools/src/lib.rs index cfba7d583b1..f86c3ce0afe 100644 --- a/src/tools/miropt-test-tools/src/lib.rs +++ b/src/tools/miropt-test-tools/src/lib.rs @@ -4,6 +4,8 @@ pub struct MiroptTestFiles { pub expected_file: std::path::PathBuf, pub from_file: String, pub to_file: Option<String>, + /// Vec of passes under test to be dumped + pub passes: Vec<String>, } pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec<MiroptTestFiles> { @@ -28,9 +30,11 @@ pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec< let mut expected_file; let from_file; let to_file; + let mut passes = Vec::new(); if test_name.ends_with(".diff") { let trimmed = test_name.trim_end_matches(".diff"); + passes.push(trimmed.split('.').last().unwrap().to_owned()); let test_against = format!("{}.after.mir", trimmed); from_file = format!("{}.before.mir", trimmed); expected_file = format!("{}{}.diff", trimmed, bit_width); @@ -38,7 +42,14 @@ pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec< to_file = Some(test_against); } else if let Some(first_pass) = test_names.next() { let second_pass = test_names.next().unwrap(); + if let Some((first_pass_name, _)) = first_pass.split_once('.') { + passes.push(first_pass_name.to_owned()); + } + if let Some((second_pass_name, _)) = second_pass.split_once('.') { + passes.push(second_pass_name.to_owned()); + } assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff"); + expected_file = format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass); let second_file = format!("{}.{}.mir", test_name, second_pass); @@ -51,18 +62,24 @@ pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec< .next() .expect("test_name has an invalid extension"); let extension = cap.get(1).unwrap().as_str(); + expected_file = format!("{}{}{}", test_name.trim_end_matches(extension), bit_width, extension,); from_file = test_name.to_string(); assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump"); to_file = None; + // the pass name is the third to last string in the test name + // this gets pushed into passes + passes.push( + test_name.split('.').rev().nth(2).expect("invalid test format").to_string(), + ); }; if !expected_file.starts_with(&test_crate) { expected_file = format!("{}.{}", test_crate, expected_file); } let expected_file = test_dir.join(expected_file); - out.push(MiroptTestFiles { expected_file, from_file, to_file }); + out.push(MiroptTestFiles { expected_file, from_file, to_file, passes }); } } diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 6b9a9b66a7d..270704ebffd 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -226,6 +226,24 @@ function runSearch(query, expected, doSearch, loadedFile, queryName) { return error_text; } +function runCorrections(query, corrections, getCorrections, loadedFile) { + const qc = getCorrections(query, loadedFile.FILTER_CRATE); + const error_text = []; + + if (corrections === null) { + if (qc !== null) { + error_text.push(`==> expected = null, found = ${qc}`); + } + return error_text; + } + + if (qc !== corrections.toLowerCase()) { + error_text.push(`==> expected = ${corrections}, found = ${qc}`); + } + + return error_text; +} + function checkResult(error_text, loadedFile, displaySuccess) { if (error_text.length === 0 && loadedFile.should_fail === true) { console.log("FAILED"); @@ -272,9 +290,10 @@ function runCheck(loadedFile, key, callback) { return 0; } -function runChecks(testFile, doSearch, parseQuery) { +function runChecks(testFile, doSearch, parseQuery, getCorrections) { let checkExpected = false; let checkParsed = false; + let checkCorrections = false; let testFileContent = readFile(testFile) + "exports.QUERY = QUERY;"; if (testFileContent.indexOf("FILTER_CRATE") !== -1) { @@ -291,9 +310,13 @@ function runChecks(testFile, doSearch, parseQuery) { testFileContent += "exports.PARSED = PARSED;"; checkParsed = true; } - if (!checkParsed && !checkExpected) { + if (testFileContent.indexOf("\nconst CORRECTIONS") !== -1) { + testFileContent += "exports.CORRECTIONS = CORRECTIONS;"; + checkCorrections = true; + } + if (!checkParsed && !checkExpected && !checkCorrections) { console.log("FAILED"); - console.log("==> At least `PARSED` or `EXPECTED` is needed!"); + console.log("==> At least `PARSED`, `EXPECTED`, or `CORRECTIONS` is needed!"); return 1; } @@ -310,6 +333,11 @@ function runChecks(testFile, doSearch, parseQuery) { return runParser(query, expected, parseQuery, text); }); } + if (checkCorrections) { + res += runCheck(loadedFile, "CORRECTIONS", (query, expected) => { + return runCorrections(query, expected, getCorrections, loadedFile); + }); + } return res; } @@ -318,9 +346,10 @@ function runChecks(testFile, doSearch, parseQuery) { * * @param {string} doc_folder - Path to a folder generated by running rustdoc * @param {string} resource_suffix - Version number between filename and .js, e.g. "1.59.0" - * @returns {Object} - Object containing two keys: `doSearch`, which runs a search - * with the loaded index and returns a table of results; and `parseQuery`, which is the - * `parseQuery` function exported from the search module. + * @returns {Object} - Object containing keys: `doSearch`, which runs a search + * with the loaded index and returns a table of results; `parseQuery`, which is the + * `parseQuery` function exported from the search module; and `getCorrections`, which runs + * a search but returns type name corrections instead of results. */ function loadSearchJS(doc_folder, resource_suffix) { const searchIndexJs = path.join(doc_folder, "search-index" + resource_suffix + ".js"); @@ -336,6 +365,12 @@ function loadSearchJS(doc_folder, resource_suffix) { return searchModule.execQuery(searchModule.parseQuery(queryStr), searchWords, filterCrate, currentCrate); }, + getCorrections: function(queryStr, filterCrate, currentCrate) { + const parsedQuery = searchModule.parseQuery(queryStr); + searchModule.execQuery(parsedQuery, searchWords, + filterCrate, currentCrate); + return parsedQuery.correction; + }, parseQuery: searchModule.parseQuery, }; } @@ -417,11 +452,14 @@ function main(argv) { const doSearch = function(queryStr, filterCrate) { return parseAndSearch.doSearch(queryStr, filterCrate, opts["crate_name"]); }; + const getCorrections = function(queryStr, filterCrate) { + return parseAndSearch.getCorrections(queryStr, filterCrate, opts["crate_name"]); + }; if (opts["test_file"].length !== 0) { opts["test_file"].forEach(file => { process.stdout.write(`Testing ${file} ... `); - errors += runChecks(file, doSearch, parseAndSearch.parseQuery); + errors += runChecks(file, doSearch, parseAndSearch.parseQuery, getCorrections); }); } else if (opts["test_folder"].length !== 0) { fs.readdirSync(opts["test_folder"]).forEach(file => { @@ -430,7 +468,7 @@ function main(argv) { } process.stdout.write(`Testing ${file} ... `); errors += runChecks(path.join(opts["test_folder"], file), doSearch, - parseAndSearch.parseQuery); + parseAndSearch.parseQuery, getCorrections); }); } return errors > 0 ? 1 : 0; diff --git a/src/tools/rustfmt/src/bin/main.rs b/src/tools/rustfmt/src/bin/main.rs index be64559e877..47846424b06 100644 --- a/src/tools/rustfmt/src/bin/main.rs +++ b/src/tools/rustfmt/src/bin/main.rs @@ -1,3 +1,5 @@ +#![feature(rustc_private)] + use anyhow::{format_err, Result}; use io::Error as IoError; @@ -19,7 +21,14 @@ use crate::rustfmt::{ FormatReportFormatterBuilder, Input, Session, Verbosity, }; +const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rustfmt/issues/new?labels=bug"; + +// N.B. these crates are loaded from the sysroot, so they need extern crate. +extern crate rustc_driver; + fn main() { + rustc_driver::install_ice_hook(BUG_REPORT_URL, |_| ()); + env_logger::Builder::from_env("RUSTFMT_LOG").init(); let opts = make_opts(); diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 01e2fb6e61e..f548388ed8b 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -552,6 +552,12 @@ impl Rewrite for ast::GenericBound { ast::TraitBoundModifier::MaybeConstMaybe => poly_trait_ref .rewrite(context, shape.offset_left(8)?) .map(|s| format!("~const ?{}", s)), + ast::TraitBoundModifier::Negative => poly_trait_ref + .rewrite(context, shape.offset_left(1)?) + .map(|s| format!("!{}", s)), + ast::TraitBoundModifier::MaybeConstNegative => poly_trait_ref + .rewrite(context, shape.offset_left(8)?) + .map(|s| format!("~const !{}", s)), }; rewrite.map(|s| if has_paren { format!("({})", s) } else { s }) } diff --git a/src/tools/rustfmt/tests/source/type-ascription.rs b/src/tools/rustfmt/tests/source/type-ascription.rs deleted file mode 100644 index 4874094ccc4..00000000000 --- a/src/tools/rustfmt/tests/source/type-ascription.rs +++ /dev/null @@ -1,10 +0,0 @@ - -fn main() { - let xxxxxxxxxxx = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy : SomeTrait<AA, BB, CC>; - - let xxxxxxxxxxxxxxx = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; - - let z = funk(yyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, wwwwww): AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; - - x : u32 - 1u32 / 10f32 : u32 -} diff --git a/src/tools/rustfmt/tests/target/configs/format_macro_bodies/true.rs b/src/tools/rustfmt/tests/target/configs/format_macro_bodies/true.rs index 9dc2524c389..17ac1498c93 100644 --- a/src/tools/rustfmt/tests/target/configs/format_macro_bodies/true.rs +++ b/src/tools/rustfmt/tests/target/configs/format_macro_bodies/true.rs @@ -1,10 +1,6 @@ // rustfmt-format_macro_bodies: true macro_rules! foo { - ($a: ident : $b: ty) => { - $a(42): $b; - }; - ($a: ident $b: ident $c: ident) => { - $a = $b + $c; - }; + ($a: ident : $b: ty) => { $a(42): $b; }; + ($a: ident $b: ident $c: ident) => { $a=$b+$c; }; } diff --git a/src/tools/rustfmt/tests/target/configs/format_macro_matchers/false.rs b/src/tools/rustfmt/tests/target/configs/format_macro_matchers/false.rs index 3966d21be75..01ecac9879d 100644 --- a/src/tools/rustfmt/tests/target/configs/format_macro_matchers/false.rs +++ b/src/tools/rustfmt/tests/target/configs/format_macro_matchers/false.rs @@ -1,10 +1,6 @@ // rustfmt-format_macro_matchers: false macro_rules! foo { - ($a: ident : $b: ty) => { - $a(42): $b; - }; - ($a: ident $b: ident $c: ident) => { - $a = $b + $c; - }; + ($a: ident : $b: ty) => { $a(42): $b; }; + ($a: ident $b: ident $c: ident) => { $a=$b+$c; }; } diff --git a/src/tools/rustfmt/tests/target/configs/format_macro_matchers/true.rs b/src/tools/rustfmt/tests/target/configs/format_macro_matchers/true.rs index e113af96f26..fa0442e228a 100644 --- a/src/tools/rustfmt/tests/target/configs/format_macro_matchers/true.rs +++ b/src/tools/rustfmt/tests/target/configs/format_macro_matchers/true.rs @@ -1,10 +1,6 @@ // rustfmt-format_macro_matchers: true macro_rules! foo { - ($a:ident : $b:ty) => { - $a(42): $b; - }; - ($a:ident $b:ident $c:ident) => { - $a = $b + $c; - }; + ($a: ident : $b: ty) => { $a(42): $b; }; + ($a: ident $b: ident $c: ident) => { $a=$b+$c; }; } diff --git a/src/tools/rustfmt/tests/target/macros.rs b/src/tools/rustfmt/tests/target/macros.rs index e930b5037d9..7b4574349df 100644 --- a/src/tools/rustfmt/tests/target/macros.rs +++ b/src/tools/rustfmt/tests/target/macros.rs @@ -122,7 +122,7 @@ fn main() { 20, 21, 22); // #1092 - chain!(input, a: take!(max_size), || []); + chain!(input, a:take!(max_size), || []); // #2727 foo!("bar"); @@ -156,17 +156,13 @@ fn issue1178() { } fn issue1739() { - sql_function!( - add_rss_item, - add_rss_item_t, - ( - a: types::Integer, - b: types::Timestamptz, - c: types::Text, - d: types::Text, - e: types::Text - ) - ); + sql_function!(add_rss_item, + add_rss_item_t, + (a: types::Integer, + b: types::Timestamptz, + c: types::Text, + d: types::Text, + e: types::Text)); w.slice_mut(s![ .., @@ -232,7 +228,7 @@ fn issue_3174() { "debugMessage": debug.message, }) } else { - json!({ "errorKind": format!("{:?}", error.err_kind()) }) + json!({"errorKind": format!("{:?}", error.err_kind())}) }; } diff --git a/src/tools/rustfmt/tests/target/negative-bounds.rs b/src/tools/rustfmt/tests/target/negative-bounds.rs new file mode 100644 index 00000000000..4fb35cccf66 --- /dev/null +++ b/src/tools/rustfmt/tests/target/negative-bounds.rs @@ -0,0 +1,11 @@ +fn negative() +where + i32: !Copy, +{ +} + +fn maybe_const_negative() +where + i32: ~const !Copy, +{ +} diff --git a/src/tools/rustfmt/tests/target/type-ascription.rs b/src/tools/rustfmt/tests/target/type-ascription.rs deleted file mode 100644 index a2f082ba4b4..00000000000 --- a/src/tools/rustfmt/tests/target/type-ascription.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn main() { - let xxxxxxxxxxx = - yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: SomeTrait<AA, BB, CC>; - - let xxxxxxxxxxxxxxx = - yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; - - let z = funk(yyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, wwwwww): - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; - - x: u32 - 1u32 / 10f32: u32 -} diff --git a/src/tools/rustfmt/tests/target/type.rs b/src/tools/rustfmt/tests/target/type.rs index 38cf909c258..c789ecb055a 100644 --- a/src/tools/rustfmt/tests/target/type.rs +++ b/src/tools/rustfmt/tests/target/type.rs @@ -129,7 +129,7 @@ fn issue3117() { fn issue3139() { assert_eq!( to_json_value(&None::<i32>).unwrap(), - json!({ "test": None::<i32> }) + json!( { "test": None :: <i32> } ) ); } diff --git a/src/tools/suggest-tests/src/static_suggestions.rs b/src/tools/suggest-tests/src/static_suggestions.rs index d8166ead8c4..a84e78254f2 100644 --- a/src/tools/suggest-tests/src/static_suggestions.rs +++ b/src/tools/suggest-tests/src/static_suggestions.rs @@ -15,7 +15,7 @@ static_suggestions! { "compiler/*" => [ sug!("check"), - sug!("test", 1, ["src/test/ui", "src/test/run-make"]) + sug!("test", 1, ["tests/ui", "tests/run-make"]) ], "src/librustdoc/*" => [ diff --git a/src/tools/suggest-tests/src/tests.rs b/src/tools/suggest-tests/src/tests.rs index 5bc1a7df7ca..b4149136fa3 100644 --- a/src/tools/suggest-tests/src/tests.rs +++ b/src/tools/suggest-tests/src/tests.rs @@ -12,7 +12,7 @@ macro_rules! sugg_test { sugg_test! { test_error_code_docs: ["compiler/rustc_error_codes/src/error_codes/E0000.md"] => - ["check N/A", "test compiler/rustc_error_codes N/A", "test linkchecker 0", "test src/test/ui src/test/run-make 1"], + ["check N/A", "test compiler/rustc_error_codes N/A", "test linkchecker 0", "test tests/ui tests/run-make 1"], test_rustdoc: ["src/librustdoc/src/lib.rs"] => ["test rustdoc 1"], diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index c19fa8e9656..a2f7b8ba7be 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -7,10 +7,10 @@ use std::collections::HashMap; use std::fs; use std::path::{Path, PathBuf}; +const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. -const ENTRY_LIMIT: usize = 885; -const ROOT_ENTRY_LIMIT: usize = 894; const ISSUES_ENTRY_LIMIT: usize = 1953; +const ROOT_ENTRY_LIMIT: usize = 894; fn check_entries(tests_path: &Path, bad: &mut bool) { let mut directories: HashMap<PathBuf, usize> = HashMap::new(); @@ -46,9 +46,6 @@ fn check_entries(tests_path: &Path, bad: &mut bool) { ); } } - if ENTRY_LIMIT > max { - tidy_error!(bad, "`ENTRY_LIMIT` is too high (is {ENTRY_LIMIT}, should be {max})"); - } if ROOT_ENTRY_LIMIT > max_root { tidy_error!( bad, diff --git a/tests/assembly/slice-is_ascii.rs b/tests/assembly/slice-is_ascii.rs new file mode 100644 index 00000000000..b3e1fee15a7 --- /dev/null +++ b/tests/assembly/slice-is_ascii.rs @@ -0,0 +1,35 @@ +// revisions: WIN LIN +// [WIN] only-windows +// [LIN] only-linux +// assembly-output: emit-asm +// compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel +// min-llvm-version: 14 +// only-x86_64 +// ignore-sgx +// ignore-debug + +#![feature(str_internals)] + +// CHECK-LABEL: is_ascii_simple_demo: +#[no_mangle] +pub fn is_ascii_simple_demo(bytes: &[u8]) -> bool { + // Linux (System V): pointer is rdi; length is rsi + // Windows: pointer is rcx; length is rdx. + + // CHECK-NOT: mov + // CHECK-NOT: test + // CHECK-NOT: cmp + + // CHECK: .[[LOOPHEAD:.+]]: + // CHECK-NEXT: mov [[TEMP:.+]], [[LEN:rsi|rdx]] + // CHECK-NEXT: sub [[LEN]], 1 + // CHECK-NEXT: jb .[[LOOPEXIT:.+]] + // CHECK-NEXT: cmp byte ptr [{{rdi|rcx}} + [[TEMP]] - 1], 0 + // CHECK-NEXT: jns .[[LOOPHEAD]] + + // CHECK-NEXT: .[[LOOPEXIT]]: + // CHECK-NEXT: test [[TEMP]], [[TEMP]] + // CHECK-NEXT: sete al + // CHECK-NEXT: ret + core::slice::is_ascii_simple(bytes) +} diff --git a/tests/codegen/abi-main-signature-16bit-c-int.rs b/tests/codegen/abi-main-signature-16bit-c-int.rs index 3548cc06a5b..353e7489b55 100644 --- a/tests/codegen/abi-main-signature-16bit-c-int.rs +++ b/tests/codegen/abi-main-signature-16bit-c-int.rs @@ -17,6 +17,7 @@ // ignore-wasm32 // ignore-x86 // ignore-x86_64 +// ignore-loongarch64 fn main() { } diff --git a/tests/codegen/align-offset.rs b/tests/codegen/align-offset.rs new file mode 100644 index 00000000000..7c7660c5a55 --- /dev/null +++ b/tests/codegen/align-offset.rs @@ -0,0 +1,78 @@ +// compile-flags: -O +// min-llvm-version: 15.0 (because we're using opaque pointers) +// ignore-debug (debug assertions in `slice::from_raw_parts` block optimizations) + +#![crate_type = "lib"] + +// CHECK-LABEL: @align8 +#[no_mangle] +pub fn align8(p: *const u8) -> bool { + // CHECK: ret i1 true + p.align_offset(8) < 8 +} + +#[repr(align(4))] +pub struct Align4([u8; 4]); + +// CHECK-LABEL: @align_to4 +#[no_mangle] +pub fn align_to4(x: &[u8]) -> bool { + // CHECK: ret i1 true + let (prefix, _middle, suffix) = unsafe { x.align_to::<Align4>() }; + prefix.len() < 4 && suffix.len() < 4 +} + +// CHECK-LABEL: @align_offset_byte_ptr(ptr{{.+}}%ptr) +#[no_mangle] +pub fn align_offset_byte_ptr(ptr: *const u8) -> usize { + // CHECK: %[[ADDR:.+]] = ptrtoint ptr %ptr to [[USIZE:i[0-9]+]] + // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], 31 + // CHECK: %[[ALIGNED:.+]] = and [[USIZE]] %[[UP]], -32 + // CHECK: %[[OFFSET:.+]] = sub [[USIZE]] %[[ALIGNED]], %[[ADDR]] + + // Since we're offsetting a byte pointer, there's no further fixups + // CHECK-NOT: shr + // CHECK-NOT: div + // CHECK-NOT: select + + // CHECK: ret [[USIZE]] %[[OFFSET]] + ptr.align_offset(32) +} + +// CHECK-LABEL: @align_offset_word_slice(ptr{{.+}}align 4{{.+}}%slice.0 +#[no_mangle] +pub fn align_offset_word_slice(slice: &[Align4]) -> usize { + // CHECK: %[[ADDR:.+]] = ptrtoint ptr %slice.0 to [[USIZE]] + // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], 31 + // CHECK: %[[ALIGNED:.+]] = and [[USIZE]] %[[UP]], -32 + // CHECK: %[[BOFFSET:.+]] = sub [[USIZE]] %[[ALIGNED]], %[[ADDR]] + // CHECK: %[[OFFSET:.+]] = lshr exact [[USIZE]] %[[BOFFSET]], 2 + + // Slices are known to be aligned, so we don't need the "maybe -1" path + // CHECK-NOT: select + + // CHECK: ret [[USIZE]] %[[OFFSET]] + slice.as_ptr().align_offset(32) +} + + +// CHECK-LABEL: @align_offset_word_ptr(ptr{{.+}}%ptr +#[no_mangle] +pub fn align_offset_word_ptr(ptr: *const Align4) -> usize { + // CHECK: %[[ADDR:.+]] = ptrtoint ptr %ptr to [[USIZE]] + // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], 31 + // CHECK: %[[ALIGNED:.+]] = and [[USIZE]] %[[UP]], -32 + // CHECK: %[[BOFFSET:.+]] = sub [[USIZE]] %[[ALIGNED]], %[[ADDR]] + + // While we can always get a *byte* offset that will work, if the original + // pointer is unaligned it might be impossible to return an *element* offset + // that will make it aligned. We want it to be a `select`, not a `br`, so + // that the assembly will be branchless. + // CHECK: %[[LOW:.+]] = and [[USIZE]] %[[ADDR]], 3 + // CHECK: %[[ORIGINAL_ALIGNED:.+]] = icmp eq [[USIZE]] %[[LOW]], 0 + // CHECK: %[[OFFSET:.+]] = lshr exact [[USIZE]] %[[BOFFSET]], 2 + // CHECK: %[[R:.+]] = select i1 %[[ORIGINAL_ALIGNED]], [[USIZE]] %[[OFFSET]], [[USIZE]] -1 + + // CHECK: ret [[USIZE]] %[[R]] + ptr.align_offset(32) +} diff --git a/tests/codegen/ascii-char.rs b/tests/codegen/ascii-char.rs new file mode 100644 index 00000000000..4167becf5e9 --- /dev/null +++ b/tests/codegen/ascii-char.rs @@ -0,0 +1,37 @@ +// compile-flags: -C opt-level=1 +// ignore-debug (the extra assertions get in the way) + +#![crate_type = "lib"] +#![feature(ascii_char)] + +use std::ascii::Char as AsciiChar; + +// CHECK-LABEL: i8 @unwrap_digit_from_remainder(i32 +#[no_mangle] +pub fn unwrap_digit_from_remainder(v: u32) -> AsciiChar { + // CHECK-NOT: icmp + // CHECK-NOT: panic + + // CHECK: %[[R:.+]] = urem i32 %v, 10 + // CHECK-NEXT: %[[T:.+]] = trunc i32 %[[R]] to i8 + // CHECK-NEXT: %[[D:.+]] = or i8 %[[T]], 48 + // CHECK-NEXT: ret i8 %[[D]] + + // CHECK-NOT: icmp + // CHECK-NOT: panic + AsciiChar::digit((v % 10) as u8).unwrap() +} + +// CHECK-LABEL: i8 @unwrap_from_masked(i8 +#[no_mangle] +pub fn unwrap_from_masked(b: u8) -> AsciiChar { + // CHECK-NOT: icmp + // CHECK-NOT: panic + + // CHECK: %[[M:.+]] = and i8 %b, 127 + // CHECK-NEXT: ret i8 %[[M]] + + // CHECK-NOT: icmp + // CHECK-NOT: panic + AsciiChar::from_u8(b & 0x7f).unwrap() +} diff --git a/tests/codegen/call-llvm-intrinsics.rs b/tests/codegen/call-llvm-intrinsics.rs index cb8abae198e..11f2917717c 100644 --- a/tests/codegen/call-llvm-intrinsics.rs +++ b/tests/codegen/call-llvm-intrinsics.rs @@ -1,6 +1,7 @@ // compile-flags: -C no-prepopulate-passes -Copt-level=0 // ignore-riscv64 +// ignore-loongarch64 #![feature(link_llvm_intrinsics)] #![crate_type = "lib"] diff --git a/tests/codegen/catch-unwind.rs b/tests/codegen/catch-unwind.rs index b90ef104ce7..6b63b83ef45 100644 --- a/tests/codegen/catch-unwind.rs +++ b/tests/codegen/catch-unwind.rs @@ -10,6 +10,8 @@ // ignore-riscv64 FIXME // On s390x the closure is also in another function // ignore-s390x FIXME +// On loongarch64 the closure is also in another function +// ignore-loongarch64 FIXME #![crate_type = "lib"] #![feature(c_unwind)] diff --git a/tests/codegen/enable-lto-unit-splitting.rs b/tests/codegen/enable-lto-unit-splitting.rs new file mode 100644 index 00000000000..7daa05f69d1 --- /dev/null +++ b/tests/codegen/enable-lto-unit-splitting.rs @@ -0,0 +1,10 @@ +// Verifies that "EnableSplitLTOUnit" module flag is added. +// +// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsplit-lto-unit + +#![crate_type="lib"] + +pub fn foo() { +} + +// CHECK: !{{[0-9]+}} = !{i32 4, !"EnableSplitLTOUnit", i32 1} diff --git a/tests/codegen/global_asm.rs b/tests/codegen/global_asm.rs index 9912b1e75bf..41a99530ad2 100644 --- a/tests/codegen/global_asm.rs +++ b/tests/codegen/global_asm.rs @@ -18,6 +18,7 @@ // ignore-wasm32 // ignore-wasm64 // ignore-emscripten +// ignore-loongarch64 // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/tests/codegen/global_asm_include.rs b/tests/codegen/global_asm_include.rs index b68c5ad3b9d..e25c164f407 100644 --- a/tests/codegen/global_asm_include.rs +++ b/tests/codegen/global_asm_include.rs @@ -18,6 +18,7 @@ // ignore-wasm32 // ignore-wasm64 // ignore-emscripten +// ignore-loongarch64 // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/tests/codegen/global_asm_x2.rs b/tests/codegen/global_asm_x2.rs index d87e02befb9..71ecef124f1 100644 --- a/tests/codegen/global_asm_x2.rs +++ b/tests/codegen/global_asm_x2.rs @@ -18,6 +18,7 @@ // ignore-wasm32 // ignore-wasm64 // ignore-emscripten +// ignore-loongarch64 // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/tests/codegen/loongarch-abi/call-llvm-intrinsics.rs b/tests/codegen/loongarch-abi/call-llvm-intrinsics.rs new file mode 100644 index 00000000000..4b78f6e24f7 --- /dev/null +++ b/tests/codegen/loongarch-abi/call-llvm-intrinsics.rs @@ -0,0 +1,31 @@ +// compile-flags: -C no-prepopulate-passes + +// only-loongarch64 + +#![feature(link_llvm_intrinsics)] +#![crate_type = "lib"] + +struct A; + +impl Drop for A { + fn drop(&mut self) { + println!("A"); + } +} + +extern "C" { + #[link_name = "llvm.sqrt.f32"] + fn sqrt(x: f32) -> f32; +} + +pub fn do_call() { + let _a = A; + + unsafe { + // Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them + // CHECK: store float 4.000000e+00, ptr %{{.}}, align 4 + // CHECK: load float, ptr %{{.}}, align 4 + // CHECK: call float @llvm.sqrt.f32(float %{{.}} + sqrt(4.0); + } +} diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs new file mode 100644 index 00000000000..7555553c2c5 --- /dev/null +++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs @@ -0,0 +1,293 @@ +// compile-flags: -C no-prepopulate-passes +// only-loongarch64 +// only-linux + +#![crate_type = "lib"] + +// CHECK: define void @f_fpr_tracking(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, i8 noundef zeroext %i) +#[no_mangle] +pub extern "C" fn f_fpr_tracking( + a: f64, + b: f64, + c: f64, + d: f64, + e: f64, + f: f64, + g: f64, + h: f64, + i: u8, +) { +} + +#[repr(C)] +pub struct Double { + f: f64, +} + +#[repr(C)] +pub struct DoubleDouble { + f: f64, + g: f64, +} + +#[repr(C)] +pub struct DoubleFloat { + f: f64, + g: f32, +} + +// CHECK: define void @f_double_s_arg(double %0) +#[no_mangle] +pub extern "C" fn f_double_s_arg(a: Double) {} + +// CHECK: define double @f_ret_double_s() +#[no_mangle] +pub extern "C" fn f_ret_double_s() -> Double { + Double { f: 1. } +} + +// CHECK: define void @f_double_double_s_arg({ double, double } %0) +#[no_mangle] +pub extern "C" fn f_double_double_s_arg(a: DoubleDouble) {} + +// CHECK: define { double, double } @f_ret_double_double_s() +#[no_mangle] +pub extern "C" fn f_ret_double_double_s() -> DoubleDouble { + DoubleDouble { f: 1., g: 2. } +} + +// CHECK: define void @f_double_float_s_arg({ double, float } %0) +#[no_mangle] +pub extern "C" fn f_double_float_s_arg(a: DoubleFloat) {} + +// CHECK: define { double, float } @f_ret_double_float_s() +#[no_mangle] +pub extern "C" fn f_ret_double_float_s() -> DoubleFloat { + DoubleFloat { f: 1., g: 2. } +} + +// CHECK: define void @f_double_double_s_arg_insufficient_fprs(double %0, double %1, double %2, double %3, double %4, double %5, double %6, [2 x i64] %7) +#[no_mangle] +pub extern "C" fn f_double_double_s_arg_insufficient_fprs( + a: f64, + b: f64, + c: f64, + d: f64, + e: f64, + f: f64, + g: f64, + h: DoubleDouble, +) { +} + +#[repr(C)] +pub struct DoubleInt8 { + f: f64, + i: i8, +} + +#[repr(C)] +pub struct DoubleUInt8 { + f: f64, + i: u8, +} + +#[repr(C)] +pub struct DoubleInt32 { + f: f64, + i: i32, +} + +#[repr(C)] +pub struct DoubleInt64 { + f: f64, + i: i64, +} + +// CHECK: define void @f_double_int8_s_arg({ double, i8 } %0) +#[no_mangle] +pub extern "C" fn f_double_int8_s_arg(a: DoubleInt8) {} + +// CHECK: define { double, i8 } @f_ret_double_int8_s() +#[no_mangle] +pub extern "C" fn f_ret_double_int8_s() -> DoubleInt8 { + DoubleInt8 { f: 1., i: 2 } +} + +// CHECK: define void @f_double_int32_s_arg({ double, i32 } %0) +#[no_mangle] +pub extern "C" fn f_double_int32_s_arg(a: DoubleInt32) {} + +// CHECK: define { double, i32 } @f_ret_double_int32_s() +#[no_mangle] +pub extern "C" fn f_ret_double_int32_s() -> DoubleInt32 { + DoubleInt32 { f: 1., i: 2 } +} + +// CHECK: define void @f_double_uint8_s_arg({ double, i8 } %0) +#[no_mangle] +pub extern "C" fn f_double_uint8_s_arg(a: DoubleUInt8) {} + +// CHECK: define { double, i8 } @f_ret_double_uint8_s() +#[no_mangle] +pub extern "C" fn f_ret_double_uint8_s() -> DoubleUInt8 { + DoubleUInt8 { f: 1., i: 2 } +} + +// CHECK: define void @f_double_int64_s_arg({ double, i64 } %0) +#[no_mangle] +pub extern "C" fn f_double_int64_s_arg(a: DoubleInt64) {} + +// CHECK: define { double, i64 } @f_ret_double_int64_s() +#[no_mangle] +pub extern "C" fn f_ret_double_int64_s() -> DoubleInt64 { + DoubleInt64 { f: 1., i: 2 } +} + +// CHECK: define void @f_double_int8_s_arg_insufficient_gprs(i32 noundef signext %a, i32 noundef signext %b, i32 noundef signext %c, i32 noundef signext %d, i32 noundef signext %e, i32 noundef signext %f, i32 noundef signext %g, i32 noundef signext %h, [2 x i64] %0) +#[no_mangle] +pub extern "C" fn f_double_int8_s_arg_insufficient_gprs( + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: DoubleInt8, +) { +} + +// CHECK: define void @f_struct_double_int8_insufficient_fprs(float %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, [2 x i64] %8) +#[no_mangle] +pub extern "C" fn f_struct_double_int8_insufficient_fprs( + a: f32, + b: f64, + c: f64, + d: f64, + e: f64, + f: f64, + g: f64, + h: f64, + i: DoubleInt8, +) { +} + +#[repr(C)] +pub struct DoubleArr1 { + a: [f64; 1], +} + +// CHECK: define void @f_doublearr1_s_arg(double %0) +#[no_mangle] +pub extern "C" fn f_doublearr1_s_arg(a: DoubleArr1) {} + +// CHECK: define double @f_ret_doublearr1_s() +#[no_mangle] +pub extern "C" fn f_ret_doublearr1_s() -> DoubleArr1 { + DoubleArr1 { a: [1.] } +} + +#[repr(C)] +pub struct DoubleArr2 { + a: [f64; 2], +} + +// CHECK: define void @f_doublearr2_s_arg({ double, double } %0) +#[no_mangle] +pub extern "C" fn f_doublearr2_s_arg(a: DoubleArr2) {} + +// CHECK: define { double, double } @f_ret_doublearr2_s() +#[no_mangle] +pub extern "C" fn f_ret_doublearr2_s() -> DoubleArr2 { + DoubleArr2 { a: [1., 2.] } +} + +#[repr(C)] +pub struct Tricky1 { + f: [f64; 1], +} + +#[repr(C)] +pub struct DoubleArr2Tricky1 { + g: [Tricky1; 2], +} + +// CHECK: define void @f_doublearr2_tricky1_s_arg({ double, double } %0) +#[no_mangle] +pub extern "C" fn f_doublearr2_tricky1_s_arg(a: DoubleArr2Tricky1) {} + +// CHECK: define { double, double } @f_ret_doublearr2_tricky1_s() +#[no_mangle] +pub extern "C" fn f_ret_doublearr2_tricky1_s() -> DoubleArr2Tricky1 { + DoubleArr2Tricky1 { g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] } +} + +#[repr(C)] +pub struct EmptyStruct {} + +#[repr(C)] +pub struct DoubleArr2Tricky2 { + s: EmptyStruct, + g: [Tricky1; 2], +} + +// CHECK: define void @f_doublearr2_tricky2_s_arg({ double, double } %0) +#[no_mangle] +pub extern "C" fn f_doublearr2_tricky2_s_arg(a: DoubleArr2Tricky2) {} + +// CHECK: define { double, double } @f_ret_doublearr2_tricky2_s() +#[no_mangle] +pub extern "C" fn f_ret_doublearr2_tricky2_s() -> DoubleArr2Tricky2 { + DoubleArr2Tricky2 { s: EmptyStruct {}, g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] } +} + +#[repr(C)] +pub struct IntDoubleInt { + a: i32, + b: f64, + c: i32, +} + +// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef dereferenceable(24) %a) +#[no_mangle] +pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {} + +// CHECK: define void @f_ret_int_double_int_s(ptr noalias nocapture noundef sret(%IntDoubleInt) dereferenceable(24) %0) +#[no_mangle] +pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt { + IntDoubleInt { a: 1, b: 2., c: 3 } +} + +#[repr(C)] +pub struct CharCharDouble { + a: u8, + b: u8, + c: f64, +} + +// CHECK: define void @f_char_char_double_s_arg([2 x i64] %0) +#[no_mangle] +pub extern "C" fn f_char_char_double_s_arg(a: CharCharDouble) {} + +// CHECK: define [2 x i64] @f_ret_char_char_double_s() +#[no_mangle] +pub extern "C" fn f_ret_char_char_double_s() -> CharCharDouble { + CharCharDouble { a: 1, b: 2, c: 3. } +} + +#[repr(C)] +pub union DoubleU { + a: f64, +} + +// CHECK: define void @f_double_u_arg(i64 %0) +#[no_mangle] +pub extern "C" fn f_double_u_arg(a: DoubleU) {} + +// CHECK: define i64 @f_ret_double_u() +#[no_mangle] +pub extern "C" fn f_ret_double_u() -> DoubleU { + unsafe { DoubleU { a: 1. } } +} diff --git a/tests/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs index f6898e2f758..81e56b5490d 100644 --- a/tests/codegen/mem-replace-big-type.rs +++ b/tests/codegen/mem-replace-big-type.rs @@ -11,7 +11,9 @@ #[repr(C, align(8))] pub struct Big([u64; 7]); pub fn replace_big(dst: &mut Big, src: Big) -> Big { - // Before the `read_via_copy` intrinsic, this emitted six `memcpy`s. + // Back in 1.68, this emitted six `memcpy`s. + // `read_via_copy` in 1.69 got that down to three. + // `write_via_move` has it down to just the two essential ones. std::mem::replace(dst, src) } @@ -20,17 +22,13 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big { // CHECK-NOT: call void @llvm.memcpy -// For a large type, we expect exactly three `memcpy`s +// For a large type, we expect exactly two `memcpy`s // CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big) // CHECK-NOT: alloca - // CHECK: alloca %Big - // CHECK-NOT: alloca - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false) // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false) // CHECK-NOT: call void @llvm.memcpy // CHECK-NOT: call void @llvm.memcpy diff --git a/tests/codegen/mem-replace-direct-memcpy.rs b/tests/codegen/mem-replace-direct-memcpy.rs deleted file mode 100644 index 83babab4f84..00000000000 --- a/tests/codegen/mem-replace-direct-memcpy.rs +++ /dev/null @@ -1,33 +0,0 @@ -// This test ensures that `mem::replace::<T>` only ever calls `@llvm.memcpy` -// with `size_of::<T>()` as the size, and never goes through any wrapper that -// may e.g. multiply `size_of::<T>()` with a variable "count" (which is only -// known to be `1` after inlining). - -// compile-flags: -C no-prepopulate-passes -Zinline-mir=no -// ignore-debug: the debug assertions get in the way - -#![crate_type = "lib"] - -pub fn replace_byte(dst: &mut u8, src: u8) -> u8 { - std::mem::replace(dst, src) -} - -// NOTE(eddyb) the `CHECK-NOT`s ensure that the only calls of `@llvm.memcpy` in -// the entire output, are the direct calls we want, from `ptr::replace`. - -// CHECK-NOT: call void @llvm.memcpy - -// For a small type, we expect one each of `load`/`store`/`memcpy` instead -// CHECK-LABEL: define internal noundef i8 @{{.+}}mem{{.+}}replace - // CHECK-NOT: alloca - // CHECK: alloca i8 - // CHECK-NOT: alloca - // CHECK-NOT: call void @llvm.memcpy - // CHECK: load i8 - // CHECK-NOT: call void @llvm.memcpy - // CHECK: store i8 - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{.*}} 1, i1 false) - // CHECK-NOT: call void @llvm.memcpy - -// CHECK-NOT: call void @llvm.memcpy diff --git a/tests/codegen/mem-replace-simple-type.rs b/tests/codegen/mem-replace-simple-type.rs new file mode 100644 index 00000000000..4253ef13666 --- /dev/null +++ b/tests/codegen/mem-replace-simple-type.rs @@ -0,0 +1,34 @@ +// compile-flags: -O -C no-prepopulate-passes +// min-llvm-version: 15.0 (for opaque pointers) +// only-x86_64 (to not worry about usize differing) +// ignore-debug (the debug assertions get in the way) + +#![crate_type = "lib"] + +#[no_mangle] +// CHECK-LABEL: @replace_usize( +pub fn replace_usize(r: &mut usize, v: usize) -> usize { + // CHECK-NOT: alloca + // CHECK: %[[R:.+]] = load i64, ptr %r + // CHECK: store i64 %v, ptr %r + // CHECK: ret i64 %[[R]] + std::mem::replace(r, v) +} + +#[no_mangle] +// CHECK-LABEL: @replace_ref_str( +pub fn replace_ref_str<'a>(r: &mut &'a str, v: &'a str) -> &'a str { + // CHECK-NOT: alloca + // CHECK: %[[A:.+]] = load ptr + // CHECK: %[[B:.+]] = load i64 + // CHECK-NOT: store + // CHECK-NOT: load + // CHECK: store ptr + // CHECK: store i64 + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK: %[[P1:.+]] = insertvalue { ptr, i64 } poison, ptr %[[A]], 0 + // CHECK: %[[P2:.+]] = insertvalue { ptr, i64 } %[[P1]], i64 %[[B]], 1 + // CHECK: ret { ptr, i64 } %[[P2]] + std::mem::replace(r, v) +} diff --git a/tests/codegen/repr-transparent-aggregates-1.rs b/tests/codegen/repr-transparent-aggregates-1.rs index f733de12b35..9c4b0e58e71 100644 --- a/tests/codegen/repr-transparent-aggregates-1.rs +++ b/tests/codegen/repr-transparent-aggregates-1.rs @@ -10,6 +10,7 @@ // ignore-riscv64 see codegen/riscv-abi // ignore-s390x // ignore-windows +// ignore-loongarch64 // See repr-transparent.rs #![feature(transparent_unions)] diff --git a/tests/codegen/repr-transparent-aggregates-2.rs b/tests/codegen/repr-transparent-aggregates-2.rs index e9fa5143b18..a7bde2d05c3 100644 --- a/tests/codegen/repr-transparent-aggregates-2.rs +++ b/tests/codegen/repr-transparent-aggregates-2.rs @@ -12,6 +12,7 @@ // ignore-sparc64 // ignore-x86 // ignore-x86_64 +// ignore-loongarch64 // See repr-transparent.rs #![feature(transparent_unions)] diff --git a/tests/codegen/repr-transparent.rs b/tests/codegen/repr-transparent.rs index 311cbfbaa09..759ddea67a5 100644 --- a/tests/codegen/repr-transparent.rs +++ b/tests/codegen/repr-transparent.rs @@ -3,6 +3,7 @@ // ignore-riscv64 riscv64 has an i128 type used with test_Vector // see codegen/riscv-abi for riscv functiona call tests // ignore-s390x s390x with default march passes vector types per reference +// ignore-loongarch64 see codegen/loongarch-abi for loongarch function call tests #![crate_type="lib"] #![feature(repr_simd, transparent_unions)] diff --git a/tests/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs b/tests/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs index c42fbba7425..1ee8bdfc3ab 100644 --- a/tests/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs +++ b/tests/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs @@ -8,4 +8,4 @@ pub fn foo() { } -// CHECK: !{{[0-9]+}} = !{i32 2, !"CFI Canonical Jump Tables", i32 1} +// CHECK: !{{[0-9]+}} = !{i32 4, !"CFI Canonical Jump Tables", i32 1} diff --git a/tests/codegen/sanitizer-cfi-add-enable-split-lto-unit-flag.rs b/tests/codegen/sanitizer-cfi-add-enable-split-lto-unit-flag.rs new file mode 100644 index 00000000000..68c91384b82 --- /dev/null +++ b/tests/codegen/sanitizer-cfi-add-enable-split-lto-unit-flag.rs @@ -0,0 +1,11 @@ +// Verifies that "EnableSplitLTOUnit" module flag is added. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![crate_type="lib"] + +pub fn foo() { +} + +// CHECK: !{{[0-9]+}} = !{i32 4, !"EnableSplitLTOUnit", i32 1} diff --git a/tests/codegen/sanitizer-cfi-emit-type-checks-attr-no-sanitize.rs b/tests/codegen/sanitizer-cfi-emit-type-checks-attr-no-sanitize.rs new file mode 100644 index 00000000000..2b61c9078fd --- /dev/null +++ b/tests/codegen/sanitizer-cfi-emit-type-checks-attr-no-sanitize.rs @@ -0,0 +1,18 @@ +// Verifies that pointer type membership tests for indirect calls are omitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 + +#![crate_type="lib"] +#![feature(no_sanitize)] + +#[no_sanitize(cfi)] +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: sanitizer_cfi_emit_type_checks_attr_no_sanitize::foo + // CHECK: Function Attrs: {{.*}} + // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: start: + // CHECK-NEXT: {{%.+}} = call i32 %f(i32 %arg) + // CHECK-NEXT: ret i32 {{%.+}} + f(arg) +} diff --git a/tests/codegen/sanitizer-cfi-emit-type-checks.rs b/tests/codegen/sanitizer-cfi-emit-type-checks.rs index 597b867ebad..cea6aac8b8b 100644 --- a/tests/codegen/sanitizer-cfi-emit-type-checks.rs +++ b/tests/codegen/sanitizer-cfi-emit-type-checks.rs @@ -6,13 +6,12 @@ #![crate_type="lib"] pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { - // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} + // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: start: // CHECK: [[TT:%.+]] = call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"{{[[:print:]]+}}") // CHECK-NEXT: br i1 [[TT]], label %type_test.pass, label %type_test.fail // CHECK: type_test.pass: // CHECK-NEXT: {{%.+}} = call i32 %f(i32 %arg) - // CHECK-NEXT: br label %bb1 // CHECK: type_test.fail: // CHECK-NEXT: call void @llvm.trap() // CHECK-NEXT: unreachable diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-attr-cfi-encoding.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-attr-cfi-encoding.rs new file mode 100644 index 00000000000..084d8bf803c --- /dev/null +++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-attr-cfi-encoding.rs @@ -0,0 +1,48 @@ +// Verifies that user-defined CFI encoding for types are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![crate_type="lib"] +#![feature(cfi_encoding, extern_types)] + +#[cfi_encoding = "3Foo"] +pub struct Type1(i32); + +extern { + #[cfi_encoding = "3Bar"] + type Type2; +} + +#[cfi_encoding = "3Baz"] +#[repr(transparent)] +pub struct Type3(i32); + +pub fn foo0(_: Type1) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo1(_: Type1, _: Type1) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo2(_: Type1, _: Type1, _: Type1) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo3(_: *mut Type2) { } +// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo4(_: *mut Type2, _: *mut Type2) { } +// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo5(_: *mut Type2, _: *mut Type2, _: *mut Type2) { } +// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo6(_: *mut Type3) { } +// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo7(_: *mut Type3, _: *mut Type3) { } +// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo8(_: *mut Type3, _: *mut Type3, _: *mut Type3) { } +// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + +// CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFv3FooE"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFv3FooS_E"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFv3FooS_S_E"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvP3BarE"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvP3BarS0_E"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvP3BarS0_S0_E"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvP3BazE"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvP3BazS0_E"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvP3BazS0_S0_E"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs index b9c33914360..71e26e3fe8a 100644 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs @@ -10,7 +10,7 @@ #![feature(adt_const_params, extern_types, inline_const, type_alias_impl_trait)] extern crate core; -use core::ffi::c_void; +use core::ffi::*; use std::marker::PhantomData; // User-defined type (structure) @@ -113,9 +113,10 @@ pub fn fn1<'a>() { let _: Type11 = Quuux; } -// repr(transparent) user-defined type +// Helper type to make Type12 have an unique id struct Foo(i32); +// repr(transparent) user-defined type #[repr(transparent)] pub struct Type12 { member1: (), @@ -131,313 +132,313 @@ pub struct Type13<'a> { member3: &'a Type13<'a>, } -// Helper type to allow `Type14<Bar>` to be a unique ID +// Helper type to make Type14 have an unique id pub struct Bar; -// repr(transparent) parameterized type +// repr(transparent) user-defined generic type #[repr(transparent)] pub struct Type14<T>(T); pub fn foo0(_: ()) { } -// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] -pub fn foo1(_: c_void, _: ()) { } -// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo1(_: (), _: c_void) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo2(_: (), _: c_void, _: c_void) { } -// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] -pub fn foo3(_: *mut c_void) { } -// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] -pub fn foo4(_: *mut c_void, _: *mut ()) { } -// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo3(_: *mut ()) { } +// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo4(_: *mut (), _: *mut c_void) { } +// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo5(_: *mut (), _: *mut c_void, _: *mut c_void) { } -// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] -pub fn foo6(_: *const c_void) { } -// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] -pub fn foo7(_: *const c_void, _: *const ()) { } -// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] +// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo6(_: *const ()) { } +// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo7(_: *const (), _: *const c_void) { } +// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo8(_: *const (), _: *const c_void, _: *const c_void) { } -// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] +// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo9(_: bool) { } -// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] +// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo10(_: bool, _: bool) { } -// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] +// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo11(_: bool, _: bool, _: bool) { } -// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] +// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo12(_: i8) { } -// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] +// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo13(_: i8, _: i8) { } -// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] +// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo14(_: i8, _: i8, _: i8) { } -// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] +// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo15(_: i16) { } -// CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]] +// CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo16(_: i16, _: i16) { } -// CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]] +// CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo17(_: i16, _: i16, _: i16) { } -// CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]] +// CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo18(_: i32) { } -// CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]] +// CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo19(_: i32, _: i32) { } -// CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]] +// CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo20(_: i32, _: i32, _: i32) { } -// CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]] +// CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo21(_: i64) { } -// CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]] +// CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo22(_: i64, _: i64) { } -// CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]] +// CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo23(_: i64, _: i64, _: i64) { } -// CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]] +// CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo24(_: i128) { } -// CHECK: define{{.*}}foo24{{.*}}!type ![[TYPE24:[0-9]+]] +// CHECK: define{{.*}}foo24{{.*}}!type ![[TYPE24:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo25(_: i128, _: i128) { } -// CHECK: define{{.*}}foo25{{.*}}!type ![[TYPE25:[0-9]+]] +// CHECK: define{{.*}}foo25{{.*}}!type ![[TYPE25:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo26(_: i128, _: i128, _: i128) { } -// CHECK: define{{.*}}foo26{{.*}}!type ![[TYPE26:[0-9]+]] +// CHECK: define{{.*}}foo26{{.*}}!type ![[TYPE26:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo27(_: isize) { } -// CHECK: define{{.*}}foo27{{.*}}!type ![[TYPE27:[0-9]+]] +// CHECK: define{{.*}}foo27{{.*}}!type ![[TYPE27:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo28(_: isize, _: isize) { } -// CHECK: define{{.*}}foo28{{.*}}!type ![[TYPE28:[0-9]+]] +// CHECK: define{{.*}}foo28{{.*}}!type ![[TYPE28:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo29(_: isize, _: isize, _: isize) { } -// CHECK: define{{.*}}foo29{{.*}}!type ![[TYPE29:[0-9]+]] +// CHECK: define{{.*}}foo29{{.*}}!type ![[TYPE29:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo30(_: u8) { } -// CHECK: define{{.*}}foo30{{.*}}!type ![[TYPE30:[0-9]+]] +// CHECK: define{{.*}}foo30{{.*}}!type ![[TYPE30:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo31(_: u8, _: u8) { } -// CHECK: define{{.*}}foo31{{.*}}!type ![[TYPE31:[0-9]+]] +// CHECK: define{{.*}}foo31{{.*}}!type ![[TYPE31:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo32(_: u8, _: u8, _: u8) { } -// CHECK: define{{.*}}foo32{{.*}}!type ![[TYPE32:[0-9]+]] +// CHECK: define{{.*}}foo32{{.*}}!type ![[TYPE32:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo33(_: u16) { } -// CHECK: define{{.*}}foo33{{.*}}!type ![[TYPE33:[0-9]+]] +// CHECK: define{{.*}}foo33{{.*}}!type ![[TYPE33:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo34(_: u16, _: u16) { } -// CHECK: define{{.*}}foo34{{.*}}!type ![[TYPE34:[0-9]+]] +// CHECK: define{{.*}}foo34{{.*}}!type ![[TYPE34:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo35(_: u16, _: u16, _: u16) { } -// CHECK: define{{.*}}foo35{{.*}}!type ![[TYPE35:[0-9]+]] +// CHECK: define{{.*}}foo35{{.*}}!type ![[TYPE35:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo36(_: u32) { } -// CHECK: define{{.*}}foo36{{.*}}!type ![[TYPE36:[0-9]+]] +// CHECK: define{{.*}}foo36{{.*}}!type ![[TYPE36:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo37(_: u32, _: u32) { } -// CHECK: define{{.*}}foo37{{.*}}!type ![[TYPE37:[0-9]+]] +// CHECK: define{{.*}}foo37{{.*}}!type ![[TYPE37:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo38(_: u32, _: u32, _: u32) { } -// CHECK: define{{.*}}foo38{{.*}}!type ![[TYPE38:[0-9]+]] +// CHECK: define{{.*}}foo38{{.*}}!type ![[TYPE38:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo39(_: u64) { } -// CHECK: define{{.*}}foo39{{.*}}!type ![[TYPE39:[0-9]+]] +// CHECK: define{{.*}}foo39{{.*}}!type ![[TYPE39:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo40(_: u64, _: u64) { } -// CHECK: define{{.*}}foo40{{.*}}!type ![[TYPE40:[0-9]+]] +// CHECK: define{{.*}}foo40{{.*}}!type ![[TYPE40:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo41(_: u64, _: u64, _: u64) { } -// CHECK: define{{.*}}foo41{{.*}}!type ![[TYPE41:[0-9]+]] +// CHECK: define{{.*}}foo41{{.*}}!type ![[TYPE41:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo42(_: u128) { } -// CHECK: define{{.*}}foo42{{.*}}!type ![[TYPE42:[0-9]+]] +// CHECK: define{{.*}}foo42{{.*}}!type ![[TYPE42:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo43(_: u128, _: u128) { } -// CHECK: define{{.*}}foo43{{.*}}!type ![[TYPE43:[0-9]+]] +// CHECK: define{{.*}}foo43{{.*}}!type ![[TYPE43:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo44(_: u128, _: u128, _: u128) { } -// CHECK: define{{.*}}foo44{{.*}}!type ![[TYPE44:[0-9]+]] +// CHECK: define{{.*}}foo44{{.*}}!type ![[TYPE44:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo45(_: usize) { } -// CHECK: define{{.*}}foo45{{.*}}!type ![[TYPE45:[0-9]+]] +// CHECK: define{{.*}}foo45{{.*}}!type ![[TYPE45:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo46(_: usize, _: usize) { } -// CHECK: define{{.*}}foo46{{.*}}!type ![[TYPE46:[0-9]+]] +// CHECK: define{{.*}}foo46{{.*}}!type ![[TYPE46:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo47(_: usize, _: usize, _: usize) { } -// CHECK: define{{.*}}foo47{{.*}}!type ![[TYPE47:[0-9]+]] +// CHECK: define{{.*}}foo47{{.*}}!type ![[TYPE47:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo48(_: f32) { } -// CHECK: define{{.*}}foo48{{.*}}!type ![[TYPE48:[0-9]+]] +// CHECK: define{{.*}}foo48{{.*}}!type ![[TYPE48:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo49(_: f32, _: f32) { } -// CHECK: define{{.*}}foo49{{.*}}!type ![[TYPE49:[0-9]+]] +// CHECK: define{{.*}}foo49{{.*}}!type ![[TYPE49:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo50(_: f32, _: f32, _: f32) { } -// CHECK: define{{.*}}foo50{{.*}}!type ![[TYPE50:[0-9]+]] +// CHECK: define{{.*}}foo50{{.*}}!type ![[TYPE50:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo51(_: f64) { } -// CHECK: define{{.*}}foo51{{.*}}!type ![[TYPE51:[0-9]+]] +// CHECK: define{{.*}}foo51{{.*}}!type ![[TYPE51:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo52(_: f64, _: f64) { } -// CHECK: define{{.*}}foo52{{.*}}!type ![[TYPE52:[0-9]+]] +// CHECK: define{{.*}}foo52{{.*}}!type ![[TYPE52:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo53(_: f64, _: f64, _: f64) { } -// CHECK: define{{.*}}foo53{{.*}}!type ![[TYPE53:[0-9]+]] +// CHECK: define{{.*}}foo53{{.*}}!type ![[TYPE53:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo54(_: char) { } -// CHECK: define{{.*}}foo54{{.*}}!type ![[TYPE54:[0-9]+]] +// CHECK: define{{.*}}foo54{{.*}}!type ![[TYPE54:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo55(_: char, _: char) { } -// CHECK: define{{.*}}foo55{{.*}}!type ![[TYPE55:[0-9]+]] +// CHECK: define{{.*}}foo55{{.*}}!type ![[TYPE55:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo56(_: char, _: char, _: char) { } -// CHECK: define{{.*}}foo56{{.*}}!type ![[TYPE56:[0-9]+]] +// CHECK: define{{.*}}foo56{{.*}}!type ![[TYPE56:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo57(_: &str) { } -// CHECK: define{{.*}}foo57{{.*}}!type ![[TYPE57:[0-9]+]] +// CHECK: define{{.*}}foo57{{.*}}!type ![[TYPE57:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo58(_: &str, _: &str) { } -// CHECK: define{{.*}}foo58{{.*}}!type ![[TYPE58:[0-9]+]] +// CHECK: define{{.*}}foo58{{.*}}!type ![[TYPE58:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo59(_: &str, _: &str, _: &str) { } -// CHECK: define{{.*}}foo59{{.*}}!type ![[TYPE59:[0-9]+]] +// CHECK: define{{.*}}foo59{{.*}}!type ![[TYPE59:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo60(_: (i32, i32)) { } -// CHECK: define{{.*}}foo60{{.*}}!type ![[TYPE60:[0-9]+]] +// CHECK: define{{.*}}foo60{{.*}}!type ![[TYPE60:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo61(_: (i32, i32), _: (i32, i32)) { } -// CHECK: define{{.*}}foo61{{.*}}!type ![[TYPE61:[0-9]+]] +// CHECK: define{{.*}}foo61{{.*}}!type ![[TYPE61:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo62(_: (i32, i32), _: (i32, i32), _: (i32, i32)) { } -// CHECK: define{{.*}}foo62{{.*}}!type ![[TYPE62:[0-9]+]] +// CHECK: define{{.*}}foo62{{.*}}!type ![[TYPE62:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo63(_: [i32; 32]) { } -// CHECK: define{{.*}}foo63{{.*}}!type ![[TYPE63:[0-9]+]] +// CHECK: define{{.*}}foo63{{.*}}!type ![[TYPE63:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo64(_: [i32; 32], _: [i32; 32]) { } -// CHECK: define{{.*}}foo64{{.*}}!type ![[TYPE64:[0-9]+]] +// CHECK: define{{.*}}foo64{{.*}}!type ![[TYPE64:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo65(_: [i32; 32], _: [i32; 32], _: [i32; 32]) { } -// CHECK: define{{.*}}foo65{{.*}}!type ![[TYPE65:[0-9]+]] +// CHECK: define{{.*}}foo65{{.*}}!type ![[TYPE65:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo66(_: &[i32]) { } -// CHECK: define{{.*}}foo66{{.*}}!type ![[TYPE66:[0-9]+]] +// CHECK: define{{.*}}foo66{{.*}}!type ![[TYPE66:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo67(_: &[i32], _: &[i32]) { } -// CHECK: define{{.*}}foo67{{.*}}!type ![[TYPE67:[0-9]+]] +// CHECK: define{{.*}}foo67{{.*}}!type ![[TYPE67:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo68(_: &[i32], _: &[i32], _: &[i32]) { } -// CHECK: define{{.*}}foo68{{.*}}!type ![[TYPE68:[0-9]+]] +// CHECK: define{{.*}}foo68{{.*}}!type ![[TYPE68:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo69(_: &Struct1::<i32>) { } -// CHECK: define{{.*}}foo69{{.*}}!type ![[TYPE69:[0-9]+]] +// CHECK: define{{.*}}foo69{{.*}}!type ![[TYPE69:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo70(_: &Struct1::<i32>, _: &Struct1::<i32>) { } -// CHECK: define{{.*}}foo70{{.*}}!type ![[TYPE70:[0-9]+]] +// CHECK: define{{.*}}foo70{{.*}}!type ![[TYPE70:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo71(_: &Struct1::<i32>, _: &Struct1::<i32>, _: &Struct1::<i32>) { } -// CHECK: define{{.*}}foo71{{.*}}!type ![[TYPE71:[0-9]+]] +// CHECK: define{{.*}}foo71{{.*}}!type ![[TYPE71:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo72(_: &Enum1::<i32>) { } -// CHECK: define{{.*}}foo72{{.*}}!type ![[TYPE72:[0-9]+]] +// CHECK: define{{.*}}foo72{{.*}}!type ![[TYPE72:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo73(_: &Enum1::<i32>, _: &Enum1::<i32>) { } -// CHECK: define{{.*}}foo73{{.*}}!type ![[TYPE73:[0-9]+]] +// CHECK: define{{.*}}foo73{{.*}}!type ![[TYPE73:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo74(_: &Enum1::<i32>, _: &Enum1::<i32>, _: &Enum1::<i32>) { } -// CHECK: define{{.*}}foo74{{.*}}!type ![[TYPE74:[0-9]+]] +// CHECK: define{{.*}}foo74{{.*}}!type ![[TYPE74:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo75(_: &Union1::<i32>) { } -// CHECK: define{{.*}}foo75{{.*}}!type ![[TYPE75:[0-9]+]] +// CHECK: define{{.*}}foo75{{.*}}!type ![[TYPE75:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo76(_: &Union1::<i32>, _: &Union1::<i32>) { } -// CHECK: define{{.*}}foo76{{.*}}!type ![[TYPE76:[0-9]+]] +// CHECK: define{{.*}}foo76{{.*}}!type ![[TYPE76:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo77(_: &Union1::<i32>, _: &Union1::<i32>, _: &Union1::<i32>) { } -// CHECK: define{{.*}}foo77{{.*}}!type ![[TYPE77:[0-9]+]] +// CHECK: define{{.*}}foo77{{.*}}!type ![[TYPE77:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo78(_: *mut type1) { } -// CHECK: define{{.*}}foo78{{.*}}!type ![[TYPE78:[0-9]+]] +// CHECK: define{{.*}}foo78{{.*}}!type ![[TYPE78:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo79(_: *mut type1, _: *mut type1) { } -// CHECK: define{{.*}}foo79{{.*}}!type ![[TYPE79:[0-9]+]] +// CHECK: define{{.*}}foo79{{.*}}!type ![[TYPE79:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo80(_: *mut type1, _: *mut type1, _: *mut type1) { } -// CHECK: define{{.*}}foo80{{.*}}!type ![[TYPE80:[0-9]+]] +// CHECK: define{{.*}}foo80{{.*}}!type ![[TYPE80:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo81(_: &mut i32) { } -// CHECK: define{{.*}}foo81{{.*}}!type ![[TYPE81:[0-9]+]] +// CHECK: define{{.*}}foo81{{.*}}!type ![[TYPE81:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo82(_: &mut i32, _: &i32) { } -// CHECK: define{{.*}}foo82{{.*}}!type ![[TYPE82:[0-9]+]] +// CHECK: define{{.*}}foo82{{.*}}!type ![[TYPE82:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo83(_: &mut i32, _: &i32, _: &i32) { } -// CHECK: define{{.*}}foo83{{.*}}!type ![[TYPE83:[0-9]+]] +// CHECK: define{{.*}}foo83{{.*}}!type ![[TYPE83:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo84(_: &i32) { } -// CHECK: define{{.*}}foo84{{.*}}!type ![[TYPE84:[0-9]+]] +// CHECK: define{{.*}}foo84{{.*}}!type ![[TYPE84:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo85(_: &i32, _: &mut i32) { } -// CHECK: define{{.*}}foo85{{.*}}!type ![[TYPE85:[0-9]+]] +// CHECK: define{{.*}}foo85{{.*}}!type ![[TYPE85:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo86(_: &i32, _: &mut i32, _: &mut i32) { } -// CHECK: define{{.*}}foo86{{.*}}!type ![[TYPE86:[0-9]+]] +// CHECK: define{{.*}}foo86{{.*}}!type ![[TYPE86:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo87(_: *mut i32) { } -// CHECK: define{{.*}}foo87{{.*}}!type ![[TYPE87:[0-9]+]] +// CHECK: define{{.*}}foo87{{.*}}!type ![[TYPE87:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo88(_: *mut i32, _: *const i32) { } -// CHECK: define{{.*}}foo88{{.*}}!type ![[TYPE88:[0-9]+]] +// CHECK: define{{.*}}foo88{{.*}}!type ![[TYPE88:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo89(_: *mut i32, _: *const i32, _: *const i32) { } -// CHECK: define{{.*}}foo89{{.*}}!type ![[TYPE89:[0-9]+]] +// CHECK: define{{.*}}foo89{{.*}}!type ![[TYPE89:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo90(_: *const i32) { } -// CHECK: define{{.*}}foo90{{.*}}!type ![[TYPE90:[0-9]+]] +// CHECK: define{{.*}}foo90{{.*}}!type ![[TYPE90:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo91(_: *const i32, _: *mut i32) { } -// CHECK: define{{.*}}foo91{{.*}}!type ![[TYPE91:[0-9]+]] +// CHECK: define{{.*}}foo91{{.*}}!type ![[TYPE91:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo92(_: *const i32, _: *mut i32, _: *mut i32) { } -// CHECK: define{{.*}}foo92{{.*}}!type ![[TYPE92:[0-9]+]] +// CHECK: define{{.*}}foo92{{.*}}!type ![[TYPE92:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo93(_: fn(i32) -> i32) { } -// CHECK: define{{.*}}foo93{{.*}}!type ![[TYPE93:[0-9]+]] +// CHECK: define{{.*}}foo93{{.*}}!type ![[TYPE93:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo94(_: fn(i32) -> i32, _: fn(i32) -> i32) { } -// CHECK: define{{.*}}foo94{{.*}}!type ![[TYPE94:[0-9]+]] +// CHECK: define{{.*}}foo94{{.*}}!type ![[TYPE94:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo95(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) { } -// CHECK: define{{.*}}foo95{{.*}}!type ![[TYPE95:[0-9]+]] +// CHECK: define{{.*}}foo95{{.*}}!type ![[TYPE95:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo96(_: &dyn Fn(i32) -> i32) { } -// CHECK: define{{.*}}foo96{{.*}}!type ![[TYPE96:[0-9]+]] +// CHECK: define{{.*}}foo96{{.*}}!type ![[TYPE96:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo97(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } -// CHECK: define{{.*}}foo97{{.*}}!type ![[TYPE97:[0-9]+]] +// CHECK: define{{.*}}foo97{{.*}}!type ![[TYPE97:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo98(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } -// CHECK: define{{.*}}foo98{{.*}}!type ![[TYPE98:[0-9]+]] +// CHECK: define{{.*}}foo98{{.*}}!type ![[TYPE98:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo99(_: &dyn FnMut(i32) -> i32) { } -// CHECK: define{{.*}}foo99{{.*}}!type ![[TYPE99:[0-9]+]] +// CHECK: define{{.*}}foo99{{.*}}!type ![[TYPE99:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo100(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } -// CHECK: define{{.*}}foo100{{.*}}!type ![[TYPE100:[0-9]+]] +// CHECK: define{{.*}}foo100{{.*}}!type ![[TYPE100:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo101(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } -// CHECK: define{{.*}}foo101{{.*}}!type ![[TYPE101:[0-9]+]] +// CHECK: define{{.*}}foo101{{.*}}!type ![[TYPE101:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo102(_: &dyn FnOnce(i32) -> i32) { } -// CHECK: define{{.*}}foo102{{.*}}!type ![[TYPE102:[0-9]+]] +// CHECK: define{{.*}}foo102{{.*}}!type ![[TYPE102:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo103(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) { } -// CHECK: define{{.*}}foo103{{.*}}!type ![[TYPE103:[0-9]+]] +// CHECK: define{{.*}}foo103{{.*}}!type ![[TYPE103:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo104(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) {} -// CHECK: define{{.*}}foo104{{.*}}!type ![[TYPE104:[0-9]+]] +// CHECK: define{{.*}}foo104{{.*}}!type ![[TYPE104:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo105(_: &dyn Send) { } -// CHECK: define{{.*}}foo105{{.*}}!type ![[TYPE105:[0-9]+]] +// CHECK: define{{.*}}foo105{{.*}}!type ![[TYPE105:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo106(_: &dyn Send, _: &dyn Send) { } -// CHECK: define{{.*}}foo106{{.*}}!type ![[TYPE106:[0-9]+]] +// CHECK: define{{.*}}foo106{{.*}}!type ![[TYPE106:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo107(_: &dyn Send, _: &dyn Send, _: &dyn Send) { } -// CHECK: define{{.*}}foo107{{.*}}!type ![[TYPE107:[0-9]+]] +// CHECK: define{{.*}}foo107{{.*}}!type ![[TYPE107:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo108(_: Type1) { } -// CHECK: define{{.*}}foo108{{.*}}!type ![[TYPE108:[0-9]+]] +// CHECK: define{{.*}}foo108{{.*}}!type ![[TYPE108:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo109(_: Type1, _: Type1) { } -// CHECK: define{{.*}}foo109{{.*}}!type ![[TYPE109:[0-9]+]] +// CHECK: define{{.*}}foo109{{.*}}!type ![[TYPE109:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo110(_: Type1, _: Type1, _: Type1) { } -// CHECK: define{{.*}}foo110{{.*}}!type ![[TYPE110:[0-9]+]] +// CHECK: define{{.*}}foo110{{.*}}!type ![[TYPE110:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo111(_: Type2) { } -// CHECK: define{{.*}}foo111{{.*}}!type ![[TYPE111:[0-9]+]] +// CHECK: define{{.*}}foo111{{.*}}!type ![[TYPE111:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo112(_: Type2, _: Type2) { } -// CHECK: define{{.*}}foo112{{.*}}!type ![[TYPE112:[0-9]+]] +// CHECK: define{{.*}}foo112{{.*}}!type ![[TYPE112:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo113(_: Type2, _: Type2, _: Type2) { } -// CHECK: define{{.*}}foo113{{.*}}!type ![[TYPE113:[0-9]+]] +// CHECK: define{{.*}}foo113{{.*}}!type ![[TYPE113:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo114(_: Type3) { } -// CHECK: define{{.*}}foo114{{.*}}!type ![[TYPE114:[0-9]+]] +// CHECK: define{{.*}}foo114{{.*}}!type ![[TYPE114:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo115(_: Type3, _: Type3) { } -// CHECK: define{{.*}}foo115{{.*}}!type ![[TYPE115:[0-9]+]] +// CHECK: define{{.*}}foo115{{.*}}!type ![[TYPE115:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo116(_: Type3, _: Type3, _: Type3) { } -// CHECK: define{{.*}}foo116{{.*}}!type ![[TYPE116:[0-9]+]] +// CHECK: define{{.*}}foo116{{.*}}!type ![[TYPE116:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo117(_: Type4) { } -// CHECK: define{{.*}}foo117{{.*}}!type ![[TYPE117:[0-9]+]] +// CHECK: define{{.*}}foo117{{.*}}!type ![[TYPE117:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo118(_: Type4, _: Type4) { } -// CHECK: define{{.*}}foo118{{.*}}!type ![[TYPE118:[0-9]+]] +// CHECK: define{{.*}}foo118{{.*}}!type ![[TYPE118:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo119(_: Type4, _: Type4, _: Type4) { } -// CHECK: define{{.*}}foo119{{.*}}!type ![[TYPE119:[0-9]+]] +// CHECK: define{{.*}}foo119{{.*}}!type ![[TYPE119:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo120(_: Type5) { } -// CHECK: define{{.*}}foo120{{.*}}!type ![[TYPE120:[0-9]+]] +// CHECK: define{{.*}}foo120{{.*}}!type ![[TYPE120:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo121(_: Type5, _: Type5) { } -// CHECK: define{{.*}}foo121{{.*}}!type ![[TYPE121:[0-9]+]] +// CHECK: define{{.*}}foo121{{.*}}!type ![[TYPE121:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo122(_: Type5, _: Type5, _: Type5) { } -// CHECK: define{{.*}}foo122{{.*}}!type ![[TYPE122:[0-9]+]] +// CHECK: define{{.*}}foo122{{.*}}!type ![[TYPE122:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo123(_: Type6) { } -// CHECK: define{{.*}}foo123{{.*}}!type ![[TYPE123:[0-9]+]] +// CHECK: define{{.*}}foo123{{.*}}!type ![[TYPE123:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo124(_: Type6, _: Type6) { } -// CHECK: define{{.*}}foo124{{.*}}!type ![[TYPE124:[0-9]+]] +// CHECK: define{{.*}}foo124{{.*}}!type ![[TYPE124:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo125(_: Type6, _: Type6, _: Type6) { } -// CHECK: define{{.*}}foo125{{.*}}!type ![[TYPE125:[0-9]+]] +// CHECK: define{{.*}}foo125{{.*}}!type ![[TYPE125:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo126(_: Type7) { } -// CHECK: define{{.*}}foo126{{.*}}!type ![[TYPE126:[0-9]+]] +// CHECK: define{{.*}}foo126{{.*}}!type ![[TYPE126:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo127(_: Type7, _: Type7) { } -// CHECK: define{{.*}}foo127{{.*}}!type ![[TYPE127:[0-9]+]] +// CHECK: define{{.*}}foo127{{.*}}!type ![[TYPE127:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo128(_: Type7, _: Type7, _: Type7) { } -// CHECK: define{{.*}}foo128{{.*}}!type ![[TYPE128:[0-9]+]] +// CHECK: define{{.*}}foo128{{.*}}!type ![[TYPE128:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo129(_: Type8) { } -// CHECK: define{{.*}}foo129{{.*}}!type ![[TYPE129:[0-9]+]] +// CHECK: define{{.*}}foo129{{.*}}!type ![[TYPE129:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo130(_: Type8, _: Type8) { } -// CHECK: define{{.*}}foo130{{.*}}!type ![[TYPE130:[0-9]+]] +// CHECK: define{{.*}}foo130{{.*}}!type ![[TYPE130:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo131(_: Type8, _: Type8, _: Type8) { } -// CHECK: define{{.*}}foo131{{.*}}!type ![[TYPE131:[0-9]+]] +// CHECK: define{{.*}}foo131{{.*}}!type ![[TYPE131:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo132(_: Type9) { } -// CHECK: define{{.*}}foo132{{.*}}!type ![[TYPE132:[0-9]+]] +// CHECK: define{{.*}}foo132{{.*}}!type ![[TYPE132:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo133(_: Type9, _: Type9) { } -// CHECK: define{{.*}}foo133{{.*}}!type ![[TYPE133:[0-9]+]] +// CHECK: define{{.*}}foo133{{.*}}!type ![[TYPE133:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo134(_: Type9, _: Type9, _: Type9) { } -// CHECK: define{{.*}}foo134{{.*}}!type ![[TYPE134:[0-9]+]] +// CHECK: define{{.*}}foo134{{.*}}!type ![[TYPE134:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo135(_: Type10) { } -// CHECK: define{{.*}}foo135{{.*}}!type ![[TYPE135:[0-9]+]] +// CHECK: define{{.*}}foo135{{.*}}!type ![[TYPE135:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo136(_: Type10, _: Type10) { } -// CHECK: define{{.*}}foo136{{.*}}!type ![[TYPE136:[0-9]+]] +// CHECK: define{{.*}}foo136{{.*}}!type ![[TYPE136:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo137(_: Type10, _: Type10, _: Type10) { } -// CHECK: define{{.*}}foo137{{.*}}!type ![[TYPE137:[0-9]+]] +// CHECK: define{{.*}}foo137{{.*}}!type ![[TYPE137:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo138(_: Type11) { } -// CHECK: define{{.*}}foo138{{.*}}!type ![[TYPE138:[0-9]+]] +// CHECK: define{{.*}}foo138{{.*}}!type ![[TYPE138:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo139(_: Type11, _: Type11) { } -// CHECK: define{{.*}}foo139{{.*}}!type ![[TYPE139:[0-9]+]] +// CHECK: define{{.*}}foo139{{.*}}!type ![[TYPE139:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo140(_: Type11, _: Type11, _: Type11) { } -// CHECK: define{{.*}}foo140{{.*}}!type ![[TYPE140:[0-9]+]] +// CHECK: define{{.*}}foo140{{.*}}!type ![[TYPE140:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo141(_: Type12) { } -// CHECK: define{{.*}}foo141{{.*}}!type ![[TYPE141:[0-9]+]] +// CHECK: define{{.*}}foo141{{.*}}!type ![[TYPE141:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo142(_: Type12, _: Type12) { } -// CHECK: define{{.*}}foo142{{.*}}!type ![[TYPE142:[0-9]+]] +// CHECK: define{{.*}}foo142{{.*}}!type ![[TYPE142:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo143(_: Type12, _: Type12, _: Type12) { } -// CHECK: define{{.*}}foo143{{.*}}!type ![[TYPE143:[0-9]+]] +// CHECK: define{{.*}}foo143{{.*}}!type ![[TYPE143:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo144(_: Type13) { } -// CHECK: define{{.*}}foo144{{.*}}!type ![[TYPE144:[0-9]+]] +// CHECK: define{{.*}}foo144{{.*}}!type ![[TYPE144:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo145(_: Type13, _: Type13) { } -// CHECK: define{{.*}}foo145{{.*}}!type ![[TYPE145:[0-9]+]] +// CHECK: define{{.*}}foo145{{.*}}!type ![[TYPE145:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo146(_: Type13, _: Type13, _: Type13) { } -// CHECK: define{{.*}}foo146{{.*}}!type ![[TYPE146:[0-9]+]] +// CHECK: define{{.*}}foo146{{.*}}!type ![[TYPE146:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo147(_: Type14<Bar>) { } -// CHECK: define{{.*}}foo147{{.*}}!type ![[TYPE147:[0-9]+]] +// CHECK: define{{.*}}foo147{{.*}}!type ![[TYPE147:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo148(_: Type14<Bar>, _: Type14<Bar>) { } -// CHECK: define{{.*}}foo148{{.*}}!type ![[TYPE148:[0-9]+]] +// CHECK: define{{.*}}foo148{{.*}}!type ![[TYPE148:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { } -// CHECK: define{{.*}}foo149{{.*}}!type ![[TYPE149:[0-9]+]] +// CHECK: define{{.*}}foo149{{.*}}!type ![[TYPE149:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvvE"} // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvvvE"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs new file mode 100644 index 00000000000..78ef0c2c7d6 --- /dev/null +++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs @@ -0,0 +1,31 @@ +// Verifies that generalized type metadata for functions are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers + +#![crate_type="lib"] + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.generalized") + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.generalized") + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.generalized") + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PKvS_E.generalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PKvS_S_E.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PKvS_S_S_E.generalized"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs new file mode 100644 index 00000000000..3b72459c4b0 --- /dev/null +++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs @@ -0,0 +1,31 @@ +// Verifies that normalized and generalized type metadata for functions are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers + +#![crate_type="lib"] + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}![[TYPE1:[0-9]+]] + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized.generalized") + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}![[TYPE2:[0-9]+]] + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized.generalized") + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}![[TYPE3:[0-9]+]] + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized.generalized") + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PKvS_E.normalized.generalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PKvS_S_E.normalized.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PKvS_S_S_E.normalized.generalized"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs new file mode 100644 index 00000000000..9218e9947bf --- /dev/null +++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs @@ -0,0 +1,31 @@ +// Verifies that normalized type metadata for functions are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers + +#![crate_type="lib"] + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized") + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized") + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized") + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PFS_S_ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_S_ES_S_S_E.normalized"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs index bafc4c6592f..f9fd816dedb 100644 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs @@ -7,21 +7,21 @@ pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo - // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E") f(arg) } pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { // CHECK-LABEL: define{{.*}}bar - // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] + // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E") f(arg1, arg2) } pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { // CHECK-LABEL: define{{.*}}baz - // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E") f(arg1, arg2, arg3) } diff --git a/tests/codegen/sanitizer-cfi-generalize-pointers.rs b/tests/codegen/sanitizer-cfi-generalize-pointers.rs new file mode 100644 index 00000000000..677ebdb27ec --- /dev/null +++ b/tests/codegen/sanitizer-cfi-generalize-pointers.rs @@ -0,0 +1,46 @@ +// Verifies that pointer types are generalized. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers + +#![crate_type="lib"] + +extern crate core; + +pub fn foo0(_: &mut i32) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo1(_: &mut i32, _: &mut i32) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo2(_: &mut i32, _: &mut i32, _: &mut i32) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo3(_: &i32) { } +// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo4(_: &i32, _: &i32) { } +// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo5(_: &i32, _: &i32, _: &i32) { } +// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo6(_: *mut i32) { } +// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo7(_: *mut i32, _: *mut i32) { } +// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo8(_: *mut i32, _: *mut i32, _: *mut i32) { } +// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo9(_: *const i32) { } +// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo10(_: *const i32, _: *const i32) { } +// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo11(_: *const i32, _: *const i32, _: *const i32) { } +// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} + +// CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvU3mutu3refIvEE.generalized"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvU3mutu3refIvES0_E.generalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvU3mutu3refIvES0_S0_E.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIvEE.generalized"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIvES_E.generalized"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIvES_S_E.generalized"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvPvE.generalized"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvPvS_E.generalized"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvPvS_S_E.generalized"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvPKvE.generalized"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvPKvS0_E.generalized"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvPKvS0_S0_E.generalized"} diff --git a/tests/codegen/sanitizer-cfi-normalize-integers.rs b/tests/codegen/sanitizer-cfi-normalize-integers.rs new file mode 100644 index 00000000000..aa3913cb8e7 --- /dev/null +++ b/tests/codegen/sanitizer-cfi-normalize-integers.rs @@ -0,0 +1,83 @@ +// Verifies that integer types are normalized. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers + +#![crate_type="lib"] + +extern crate core; +use core::ffi::*; + +pub fn foo0(_: bool) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} +pub fn foo1(_: bool, _: c_uchar) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +pub fn foo2(_: bool, _: c_uchar, _: c_uchar) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +pub fn foo3(_: isize) { } +// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +pub fn foo4(_: isize, _: c_long) { } +// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} +pub fn foo5(_: isize, _: c_long, _: c_longlong) { } +// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} +pub fn foo6(_: usize) { } +// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} +pub fn foo7(_: usize, _: c_ulong) { } +// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} +pub fn foo8(_: usize, _: c_ulong, _: c_ulonglong) { } +// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} +pub fn foo9(_: c_schar) { } +// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} +pub fn foo10(_: c_char, _: c_schar) { } +// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} +pub fn foo11(_: c_char, _: c_schar, _: c_schar) { } +// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} +pub fn foo12(_: c_int) { } +// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} +pub fn foo13(_: c_int, _: c_int) { } +// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} +pub fn foo14(_: c_int, _: c_int, _: c_int) { } +// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} +pub fn foo15(_: c_short) { } +// CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}} +pub fn foo16(_: c_short, _: c_short) { } +// CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]] !type !{{[0-9]+}} +pub fn foo17(_: c_short, _: c_short, _: c_short) { } +// CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]] !type !{{[0-9]+}} +pub fn foo18(_: c_uint) { } +// CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]] !type !{{[0-9]+}} +pub fn foo19(_: c_uint, _: c_uint) { } +// CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]] !type !{{[0-9]+}} +pub fn foo20(_: c_uint, _: c_uint, _: c_uint) { } +// CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]] !type !{{[0-9]+}} +pub fn foo21(_: c_ushort) { } +// CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]] !type !{{[0-9]+}} +pub fn foo22(_: c_ushort, _: c_ushort) { } +// CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]] !type !{{[0-9]+}} +pub fn foo23(_: c_ushort, _: c_ushort, _: c_ushort) { } +// CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]] !type !{{[0-9]+}} + +// CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvu2u8E.normalized"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu2u8S_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu2u8S_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}E.normalized"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}{{u3i32|u3i64|S_}}E.normalized"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}{{u3i32|u3i64|S_}}{{u3i64|S_|S0_}}E.normalized"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}E.normalized"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}{{u3u32|u3u64|S_}}E.normalized"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}{{u3u32|u3u64|S_}}{{u3u64|S_|S0_}}E.normalized"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu2i8E.normalized"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFv{{u2i8S_|u2u8u2i8}}E.normalized"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFv{{u2i8S_S_|u2u8u2i8S0_}}E.normalized"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}E.normalized"} +// CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}S_E.normalized"} +// CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}S_S_E.normalized"} +// CHECK: ![[TYPE15]] = !{i64 0, !"_ZTSFvu3i16E.normalized"} +// CHECK: ![[TYPE16]] = !{i64 0, !"_ZTSFvu3i16S_E.normalized"} +// CHECK: ![[TYPE17]] = !{i64 0, !"_ZTSFvu3i16S_S_E.normalized"} +// CHECK: ![[TYPE18]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}E.normalized"} +// CHECK: ![[TYPE19]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}S_E.normalized"} +// CHECK: ![[TYPE20]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}S_S_E.normalized"} +// CHECK: ![[TYPE21]] = !{i64 0, !"_ZTSFvu3u16E.normalized"} +// CHECK: ![[TYPE22]] = !{i64 0, !"_ZTSFvu3u16S_E.normalized"} +// CHECK: ![[TYPE23]] = !{i64 0, !"_ZTSFvu3u16S_S_E.normalized"} diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs new file mode 100644 index 00000000000..bb317e4a2fa --- /dev/null +++ b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs @@ -0,0 +1,30 @@ +// Verifies that KCFI operand bundles are omitted. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 + +#![crate_type="lib"] +#![feature(no_core, no_sanitize, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } + +impl Copy for i32 {} + +#[no_sanitize(kcfi)] +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: sanitizer_kcfi_emit_kcfi_operand_bundle_attr_no_sanitize::foo + // CHECK: Function Attrs: {{.*}} + // CHECK-LABEL: define{{.*}}foo{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: start: + // CHECK-NOT: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg){{.*}}[ "kcfi"(i32 {{[-0-9]+}}) ] + // CHECK: ret i32 {{%.+}} + f(arg) +} diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs new file mode 100644 index 00000000000..29e4df3511f --- /dev/null +++ b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs @@ -0,0 +1,44 @@ +// Verifies that generalized KCFI type metadata for functions are emitted. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-generalize-pointers + +#![crate_type="lib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } + +impl Copy for i32 {} + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE1:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg){{.*}}[ "kcfi"(i32 233085384) ] + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE2:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg1, i32 {{(noundef )*}}%arg2){{.*}}[ "kcfi"(i32 435418021) ] + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE3:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg1, i32 {{(noundef )*}}%arg2, i32 {{(noundef )*}}%arg3){{.*}}[ "kcfi"(i32 -1003721339) ] + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i32 -1741689296} +// CHECK: ![[TYPE2]] = !{i32 489439372} +// CHECK: ![[TYPE3]] = !{i32 2026563871} diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs new file mode 100644 index 00000000000..84d678a33ba --- /dev/null +++ b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs @@ -0,0 +1,44 @@ +// Verifies that normalized and generalized KCFI type metadata for functions are emitted. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers + +#![crate_type="lib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } + +impl Copy for i32 {} + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE1:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg){{.*}}[ "kcfi"(i32 -686570305) ] + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE2:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg1, i32 {{(noundef )*}}%arg2){{.*}}[ "kcfi"(i32 1281038450) ] + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE3:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg1, i32 {{(noundef )*}}%arg2, i32 {{(noundef )*}}%arg3){{.*}}[ "kcfi"(i32 -1751512973) ] + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i32 975484707} +// CHECK: ![[TYPE2]] = !{i32 1658833102} +// CHECK: ![[TYPE3]] = !{i32 230429758} diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs new file mode 100644 index 00000000000..761c37a9e06 --- /dev/null +++ b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs @@ -0,0 +1,44 @@ +// Verifies that normalized KCFI type metadata for functions are emitted. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers + +#![crate_type="lib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } + +impl Copy for i32 {} + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE1:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg){{.*}}[ "kcfi"(i32 -841055669) ] + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE2:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg1, i32 {{(noundef )*}}%arg2){{.*}}[ "kcfi"(i32 1390819368) ] + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE3:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg1, i32 {{(noundef )*}}%arg2, i32 {{(noundef )*}}%arg3){{.*}}[ "kcfi"(i32 586925835) ] + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i32 -458317079} +// CHECK: ![[TYPE2]] = !{i32 1737138182} +// CHECK: ![[TYPE3]] = !{i32 197182412} diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs index 2537df80a90..83cda0ef136 100644 --- a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs @@ -20,22 +20,22 @@ impl Copy for i32 {} pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo - // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE1:[0-9]+]] - // CHECK: call i32 %f(i32 %arg){{.*}}[ "kcfi"(i32 -1666898348) ] + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE1:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg){{.*}}[ "kcfi"(i32 -1666898348) ] f(arg) } pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { // CHECK-LABEL: define{{.*}}bar - // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE2:[0-9]+]] - // CHECK: call i32 %f(i32 %arg1, i32 %arg2){{.*}}[ "kcfi"(i32 -1789026986) ] + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE2:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg1, i32 {{(noundef )*}}%arg2){{.*}}[ "kcfi"(i32 -1789026986) ] f(arg1, arg2) } pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { // CHECK-LABEL: define{{.*}}baz - // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE3:[0-9]+]] - // CHECK: call i32 %f(i32 %arg1, i32 %arg2, i32 %arg3){{.*}}[ "kcfi"(i32 1248878270) ] + // CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE3:[0-9]+]] + // CHECK: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg1, i32 {{(noundef )*}}%arg2, i32 {{(noundef )*}}%arg3){{.*}}[ "kcfi"(i32 1248878270) ] f(arg1, arg2, arg3) } diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle.rs b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle.rs new file mode 100644 index 00000000000..e1d617b5ee1 --- /dev/null +++ b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle.rs @@ -0,0 +1,27 @@ +// Verifies that KCFI operand bundles are emitted. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 + +#![crate_type="lib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } + +impl Copy for i32 {} + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: start: + // CHECK-NEXT: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg){{.*}}[ "kcfi"(i32 {{[-0-9]+}}) ] + // CHECK-NEXT: ret i32 {{%.+}} + f(arg) +} diff --git a/tests/codegen/split-lto-unit.rs b/tests/codegen/split-lto-unit.rs new file mode 100644 index 00000000000..dc6570be32b --- /dev/null +++ b/tests/codegen/split-lto-unit.rs @@ -0,0 +1,11 @@ +// Verifies that "EnableSplitLTOUnit" module flag is added. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsplit-lto-unit + +#![crate_type="lib"] + +pub fn foo() { +} + +// CHECK: !{{[0-9]+}} = !{i32 4, !"EnableSplitLTOUnit", i32 1} diff --git a/tests/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs b/tests/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs index 327515b10af..c187df637fd 100644 --- a/tests/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs +++ b/tests/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs @@ -2,7 +2,6 @@ // ignore-lldb // no-prefer-dynamic -#![feature(debugger_visualizer)] #![debugger_visualizer(natvis_file = "dependency-with-embedded-visualizers.natvis")] #![debugger_visualizer(gdb_script_file = "dependency-with-embedded-visualizers.py")] #![crate_type = "rlib"] diff --git a/tests/debuginfo/embedded-visualizer.rs b/tests/debuginfo/embedded-visualizer.rs index 2898e75e0ee..ac421092839 100644 --- a/tests/debuginfo/embedded-visualizer.rs +++ b/tests/debuginfo/embedded-visualizer.rs @@ -60,7 +60,6 @@ // gdb-check:$4 = "Person A" is 10 years old. #![allow(unused_variables)] -#![feature(debugger_visualizer)] #![debugger_visualizer(natvis_file = "embedded-visualizer.natvis")] #![debugger_visualizer(gdb_script_file = "embedded-visualizer.py")] diff --git a/tests/incremental/change_crate_dep_kind.rs b/tests/incremental/change_crate_dep_kind.rs index 8c35f6ca000..f518266016e 100644 --- a/tests/incremental/change_crate_dep_kind.rs +++ b/tests/incremental/change_crate_dep_kind.rs @@ -2,6 +2,7 @@ // detected then -Zincremental-verify-ich will trigger an assertion. // ignore-wasm32-bare compiled with panic=abort by default +// needs-unwind // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph -Cpanic=unwind // build-pass (FIXME(62277): could be check-pass?) diff --git a/tests/incremental/issue-80691-bad-eval-cache.rs b/tests/incremental/issue-80691-bad-eval-cache.rs index 1a644fd88d6..ad8a338a796 100644 --- a/tests/incremental/issue-80691-bad-eval-cache.rs +++ b/tests/incremental/issue-80691-bad-eval-cache.rs @@ -1,6 +1,7 @@ // revisions: rfail1 rfail2 // failure-status: 101 // error-pattern: not implemented +// needs-unwind -Cpanic=abort causes abort instead of exit(101) pub trait Interner { type InternedVariableKinds; diff --git a/tests/mir-opt/bool_compare.opt1.InstCombine.diff b/tests/mir-opt/bool_compare.opt1.InstSimplify.diff index 0af5d82d315..6c9df8f042b 100644 --- a/tests/mir-opt/bool_compare.opt1.InstCombine.diff +++ b/tests/mir-opt/bool_compare.opt1.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `opt1` before InstCombine -+ // MIR for `opt1` after InstCombine +- // MIR for `opt1` before InstSimplify ++ // MIR for `opt1` after InstSimplify fn opt1(_1: bool) -> u32 { debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10 diff --git a/tests/mir-opt/bool_compare.opt2.InstCombine.diff b/tests/mir-opt/bool_compare.opt2.InstSimplify.diff index f5d1febd991..9fb3982654a 100644 --- a/tests/mir-opt/bool_compare.opt2.InstCombine.diff +++ b/tests/mir-opt/bool_compare.opt2.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `opt2` before InstCombine -+ // MIR for `opt2` after InstCombine +- // MIR for `opt2` before InstSimplify ++ // MIR for `opt2` after InstSimplify fn opt2(_1: bool) -> u32 { debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10 diff --git a/tests/mir-opt/bool_compare.opt3.InstCombine.diff b/tests/mir-opt/bool_compare.opt3.InstSimplify.diff index e7432adac7d..3a47da86735 100644 --- a/tests/mir-opt/bool_compare.opt3.InstCombine.diff +++ b/tests/mir-opt/bool_compare.opt3.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `opt3` before InstCombine -+ // MIR for `opt3` after InstCombine +- // MIR for `opt3` before InstSimplify ++ // MIR for `opt3` after InstSimplify fn opt3(_1: bool) -> u32 { debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10 diff --git a/tests/mir-opt/bool_compare.opt4.InstCombine.diff b/tests/mir-opt/bool_compare.opt4.InstSimplify.diff index 6b3e27772f7..5319c987d41 100644 --- a/tests/mir-opt/bool_compare.opt4.InstCombine.diff +++ b/tests/mir-opt/bool_compare.opt4.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `opt4` before InstCombine -+ // MIR for `opt4` after InstCombine +- // MIR for `opt4` before InstSimplify ++ // MIR for `opt4` after InstSimplify fn opt4(_1: bool) -> u32 { debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10 diff --git a/tests/mir-opt/bool_compare.rs b/tests/mir-opt/bool_compare.rs index 4435bf5b0f2..080f7f72d11 100644 --- a/tests/mir-opt/bool_compare.rs +++ b/tests/mir-opt/bool_compare.rs @@ -1,21 +1,21 @@ -// unit-test: InstCombine +// unit-test: InstSimplify -// EMIT_MIR bool_compare.opt1.InstCombine.diff +// EMIT_MIR bool_compare.opt1.InstSimplify.diff fn opt1(x: bool) -> u32 { if x != true { 0 } else { 1 } } -// EMIT_MIR bool_compare.opt2.InstCombine.diff +// EMIT_MIR bool_compare.opt2.InstSimplify.diff fn opt2(x: bool) -> u32 { if true != x { 0 } else { 1 } } -// EMIT_MIR bool_compare.opt3.InstCombine.diff +// EMIT_MIR bool_compare.opt3.InstSimplify.diff fn opt3(x: bool) -> u32 { if x == false { 0 } else { 1 } } -// EMIT_MIR bool_compare.opt4.InstCombine.diff +// EMIT_MIR bool_compare.opt4.InstSimplify.diff fn opt4(x: bool) -> u32 { if false == x { 0 } else { 1 } } diff --git a/tests/mir-opt/casts.redundant.InstCombine.diff b/tests/mir-opt/casts.redundant.InstSimplify.diff index 528a8e5a90f..a641b69deb0 100644 --- a/tests/mir-opt/casts.redundant.InstCombine.diff +++ b/tests/mir-opt/casts.redundant.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `redundant` before InstCombine -+ // MIR for `redundant` after InstCombine +- // MIR for `redundant` before InstSimplify ++ // MIR for `redundant` after InstSimplify fn redundant(_1: *const &u8) -> *const &u8 { debug x => _1; // in scope 0 at $DIR/casts.rs:+0:30: +0:31 diff --git a/tests/mir-opt/casts.rs b/tests/mir-opt/casts.rs index 259c462da3d..413b0e09d3f 100644 --- a/tests/mir-opt/casts.rs +++ b/tests/mir-opt/casts.rs @@ -1,6 +1,6 @@ #![crate_type = "lib"] -// EMIT_MIR casts.redundant.InstCombine.diff +// EMIT_MIR casts.redundant.InstSimplify.diff // EMIT_MIR casts.redundant.PreCodegen.after.mir pub fn redundant<'a, 'b: 'a>(x: *const &'a u8) -> *const &'a u8 { generic_cast::<&'a u8, &'b u8>(x) as *const &'a u8 diff --git a/tests/mir-opt/combine_array_len.norm2.InstCombine.diff b/tests/mir-opt/combine_array_len.norm2.InstSimplify.diff index c73150f947d..0777007cefa 100644 --- a/tests/mir-opt/combine_array_len.norm2.InstCombine.diff +++ b/tests/mir-opt/combine_array_len.norm2.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `norm2` before InstCombine -+ // MIR for `norm2` after InstCombine +- // MIR for `norm2` before InstSimplify ++ // MIR for `norm2` after InstSimplify fn norm2(_1: [f32; 2]) -> f32 { debug x => _1; // in scope 0 at $DIR/combine_array_len.rs:+0:10: +0:11 diff --git a/tests/mir-opt/combine_array_len.rs b/tests/mir-opt/combine_array_len.rs index 08c5f1a1fc5..970cafafcf0 100644 --- a/tests/mir-opt/combine_array_len.rs +++ b/tests/mir-opt/combine_array_len.rs @@ -1,6 +1,6 @@ // ignore-wasm32 compiled with panic=abort by default -// unit-test: InstCombine -// EMIT_MIR combine_array_len.norm2.InstCombine.diff +// unit-test: InstSimplify +// EMIT_MIR combine_array_len.norm2.InstSimplify.diff fn norm2(x: [f32; 2]) -> f32 { let a = x[0]; diff --git a/tests/mir-opt/combine_clone_of_primitives.rs b/tests/mir-opt/combine_clone_of_primitives.rs index 7cc50a86e21..1deee9dd6d2 100644 --- a/tests/mir-opt/combine_clone_of_primitives.rs +++ b/tests/mir-opt/combine_clone_of_primitives.rs @@ -1,7 +1,7 @@ -// unit-test: InstCombine +// unit-test: InstSimplify // ignore-wasm32 compiled with panic=abort by default -// EMIT_MIR combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff +// EMIT_MIR combine_clone_of_primitives.{impl#0}-clone.InstSimplify.diff #[derive(Clone)] struct MyThing<T> { diff --git a/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.diff index b715a544ffe..bb0811a7abb 100644 --- a/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff +++ b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `<impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone` before InstCombine -+ // MIR for `<impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone` after InstCombine +- // MIR for `<impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone` before InstSimplify ++ // MIR for `<impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone` after InstSimplify fn <impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone(_1: &MyThing<T>) -> MyThing<T> { debug self => _1; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 diff --git a/tests/mir-opt/combine_transmutes.adt_transmutes.InstCombine.diff b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff index 168e8c61031..c5907e7cf18 100644 --- a/tests/mir-opt/combine_transmutes.adt_transmutes.InstCombine.diff +++ b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `adt_transmutes` before InstCombine -+ // MIR for `adt_transmutes` after InstCombine +- // MIR for `adt_transmutes` before InstSimplify ++ // MIR for `adt_transmutes` after InstSimplify fn adt_transmutes() -> () { let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:32: +0:32 diff --git a/tests/mir-opt/combine_transmutes.identity_transmutes.InstCombine.diff b/tests/mir-opt/combine_transmutes.identity_transmutes.InstSimplify.diff index ae1185c7f71..57d9f4b1402 100644 --- a/tests/mir-opt/combine_transmutes.identity_transmutes.InstCombine.diff +++ b/tests/mir-opt/combine_transmutes.identity_transmutes.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `identity_transmutes` before InstCombine -+ // MIR for `identity_transmutes` after InstCombine +- // MIR for `identity_transmutes` before InstSimplify ++ // MIR for `identity_transmutes` after InstSimplify fn identity_transmutes() -> () { let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:37: +0:37 diff --git a/tests/mir-opt/combine_transmutes.integer_transmutes.InstCombine.diff b/tests/mir-opt/combine_transmutes.integer_transmutes.InstSimplify.diff index 8de7c34e6b2..ec7c982c151 100644 --- a/tests/mir-opt/combine_transmutes.integer_transmutes.InstCombine.diff +++ b/tests/mir-opt/combine_transmutes.integer_transmutes.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `integer_transmutes` before InstCombine -+ // MIR for `integer_transmutes` after InstCombine +- // MIR for `integer_transmutes` before InstSimplify ++ // MIR for `integer_transmutes` after InstSimplify fn integer_transmutes() -> () { let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:36: +0:36 diff --git a/tests/mir-opt/combine_transmutes.rs b/tests/mir-opt/combine_transmutes.rs index de9b9c35c03..7088488c1b8 100644 --- a/tests/mir-opt/combine_transmutes.rs +++ b/tests/mir-opt/combine_transmutes.rs @@ -1,4 +1,4 @@ -// unit-test: InstCombine +// unit-test: InstSimplify // compile-flags: -C panic=abort #![crate_type = "lib"] @@ -8,7 +8,7 @@ use std::intrinsics::mir::*; use std::mem::{MaybeUninit, ManuallyDrop, transmute}; -// EMIT_MIR combine_transmutes.identity_transmutes.InstCombine.diff +// EMIT_MIR combine_transmutes.identity_transmutes.InstSimplify.diff pub unsafe fn identity_transmutes() { // These are nops and should be removed let _a = transmute::<i32, i32>(1); @@ -16,7 +16,7 @@ pub unsafe fn identity_transmutes() { } #[custom_mir(dialect = "runtime", phase = "initial")] -// EMIT_MIR combine_transmutes.integer_transmutes.InstCombine.diff +// EMIT_MIR combine_transmutes.integer_transmutes.InstSimplify.diff pub unsafe fn integer_transmutes() { mir! { { @@ -30,7 +30,7 @@ pub unsafe fn integer_transmutes() { } } -// EMIT_MIR combine_transmutes.adt_transmutes.InstCombine.diff +// EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify.diff pub unsafe fn adt_transmutes() { let _a: u8 = transmute(EnumNoRepr::A); let _a: i8 = transmute(EnumNoRepr::B); diff --git a/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir index 9b69f79c28e..169e99deee7 100644 --- a/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir +++ b/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir @@ -21,42 +21,42 @@ fn main() -> () { } alloc1 (static: FOO, size: 8, align: 4) { - ╾─alloc18─╼ 03 00 00 00 │ ╾──╼.... + ╾─alloc19─╼ 03 00 00 00 │ ╾──╼.... } -alloc18 (size: 48, align: 4) { - 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc5──╼ 00 00 00 00 │ ....░░░░╾──╼.... - 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc8──╼ 02 00 00 00 │ ....░░░░╾──╼.... - 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc13─╼ 03 00 00 00 │ ....*...╾──╼.... +alloc19 (size: 48, align: 4) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc6──╼ 00 00 00 00 │ ....░░░░╾──╼.... + 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc9──╼ 02 00 00 00 │ ....░░░░╾──╼.... + 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc14─╼ 03 00 00 00 │ ....*...╾──╼.... } -alloc5 (size: 0, align: 4) {} +alloc6 (size: 0, align: 4) {} -alloc8 (size: 16, align: 4) { - ╾─alloc9──╼ 03 00 00 00 ╾─alloc10─╼ 03 00 00 00 │ ╾──╼....╾──╼.... +alloc9 (size: 16, align: 4) { + ╾─alloc10─╼ 03 00 00 00 ╾─alloc11─╼ 03 00 00 00 │ ╾──╼....╾──╼.... } -alloc9 (size: 3, align: 1) { +alloc10 (size: 3, align: 1) { 66 6f 6f │ foo } -alloc10 (size: 3, align: 1) { +alloc11 (size: 3, align: 1) { 62 61 72 │ bar } -alloc13 (size: 24, align: 4) { - 0x00 │ ╾─alloc14─╼ 03 00 00 00 ╾─alloc15─╼ 03 00 00 00 │ ╾──╼....╾──╼.... - 0x10 │ ╾─alloc16─╼ 04 00 00 00 │ ╾──╼.... +alloc14 (size: 24, align: 4) { + 0x00 │ ╾─alloc15─╼ 03 00 00 00 ╾─alloc16─╼ 03 00 00 00 │ ╾──╼....╾──╼.... + 0x10 │ ╾─alloc17─╼ 04 00 00 00 │ ╾──╼.... } -alloc14 (size: 3, align: 1) { +alloc15 (size: 3, align: 1) { 6d 65 68 │ meh } -alloc15 (size: 3, align: 1) { +alloc16 (size: 3, align: 1) { 6d 6f 70 │ mop } -alloc16 (size: 4, align: 1) { +alloc17 (size: 4, align: 1) { 6d c3 b6 70 │ m..p } diff --git a/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir index d0f196e7245..db1f9648843 100644 --- a/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir +++ b/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir @@ -21,46 +21,46 @@ fn main() -> () { } alloc1 (static: FOO, size: 16, align: 8) { - ╾───────alloc18───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾───────alloc19───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ } -alloc18 (size: 72, align: 8) { - 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc5────────╼ │ ....░░░░╾──────╼ +alloc19 (size: 72, align: 8) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc6────────╼ │ ....░░░░╾──────╼ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░ - 0x20 │ ╾───────alloc8────────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc13───────╼ │ ....*...╾──────╼ + 0x20 │ ╾───────alloc9────────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc14───────╼ │ ....*...╾──────╼ 0x40 │ 03 00 00 00 00 00 00 00 │ ........ } -alloc5 (size: 0, align: 8) {} +alloc6 (size: 0, align: 8) {} -alloc8 (size: 32, align: 8) { - 0x00 │ ╾───────alloc9────────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x10 │ ╾───────alloc10───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ +alloc9 (size: 32, align: 8) { + 0x00 │ ╾───────alloc10───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x10 │ ╾───────alloc11───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ } -alloc9 (size: 3, align: 1) { +alloc10 (size: 3, align: 1) { 66 6f 6f │ foo } -alloc10 (size: 3, align: 1) { +alloc11 (size: 3, align: 1) { 62 61 72 │ bar } -alloc13 (size: 48, align: 8) { - 0x00 │ ╾───────alloc14───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x10 │ ╾───────alloc15───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x20 │ ╾───────alloc16───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ +alloc14 (size: 48, align: 8) { + 0x00 │ ╾───────alloc15───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x10 │ ╾───────alloc16───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x20 │ ╾───────alloc17───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } -alloc14 (size: 3, align: 1) { +alloc15 (size: 3, align: 1) { 6d 65 68 │ meh } -alloc15 (size: 3, align: 1) { +alloc16 (size: 3, align: 1) { 6d 6f 70 │ mop } -alloc16 (size: 4, align: 1) { +alloc17 (size: 4, align: 1) { 6d c3 b6 70 │ m..p } diff --git a/tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir index aab005c52d6..999acb48afe 100644 --- a/tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir +++ b/tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir @@ -21,41 +21,41 @@ fn main() -> () { } alloc1 (static: FOO, size: 8, align: 4) { - ╾─alloc22─╼ 03 00 00 00 │ ╾──╼.... + ╾─alloc23─╼ 03 00 00 00 │ ╾──╼.... } -alloc22 (size: 48, align: 4) { - 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc9──╼ 00 00 00 00 │ ....░░░░╾──╼.... - 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc14─╼ 02 00 00 00 │ ....░░░░╾──╼.... - 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc20─╼ 03 00 00 00 │ ....*...╾──╼.... +alloc23 (size: 48, align: 4) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc10─╼ 00 00 00 00 │ ....░░░░╾──╼.... + 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc15─╼ 02 00 00 00 │ ....░░░░╾──╼.... + 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc21─╼ 03 00 00 00 │ ....*...╾──╼.... } -alloc9 (size: 0, align: 4) {} +alloc10 (size: 0, align: 4) {} -alloc14 (size: 8, align: 4) { - ╾─alloc12─╼ ╾─alloc13─╼ │ ╾──╼╾──╼ +alloc15 (size: 8, align: 4) { + ╾─alloc13─╼ ╾─alloc14─╼ │ ╾──╼╾──╼ } -alloc12 (size: 1, align: 1) { +alloc13 (size: 1, align: 1) { 05 │ . } -alloc13 (size: 1, align: 1) { +alloc14 (size: 1, align: 1) { 06 │ . } -alloc20 (size: 12, align: 4) { - ╾─a17+0x3─╼ ╾─alloc18─╼ ╾─a19+0x2─╼ │ ╾──╼╾──╼╾──╼ +alloc21 (size: 12, align: 4) { + ╾─a18+0x3─╼ ╾─alloc19─╼ ╾─a20+0x2─╼ │ ╾──╼╾──╼╾──╼ } -alloc17 (size: 4, align: 1) { +alloc18 (size: 4, align: 1) { 2a 45 15 6f │ *E.o } -alloc18 (size: 1, align: 1) { +alloc19 (size: 1, align: 1) { 2a │ * } -alloc19 (size: 4, align: 1) { +alloc20 (size: 4, align: 1) { 2a 45 15 6f │ *E.o } diff --git a/tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir index 0eff9474c20..30311890eee 100644 --- a/tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir +++ b/tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir @@ -21,44 +21,44 @@ fn main() -> () { } alloc1 (static: FOO, size: 16, align: 8) { - ╾───────alloc22───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾───────alloc23───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ } -alloc22 (size: 72, align: 8) { - 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc9────────╼ │ ....░░░░╾──────╼ +alloc23 (size: 72, align: 8) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc10───────╼ │ ....░░░░╾──────╼ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░ - 0x20 │ ╾───────alloc14───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc20───────╼ │ ....*...╾──────╼ + 0x20 │ ╾───────alloc15───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc21───────╼ │ ....*...╾──────╼ 0x40 │ 03 00 00 00 00 00 00 00 │ ........ } -alloc9 (size: 0, align: 8) {} +alloc10 (size: 0, align: 8) {} -alloc14 (size: 16, align: 8) { - ╾───────alloc12───────╼ ╾───────alloc13───────╼ │ ╾──────╼╾──────╼ +alloc15 (size: 16, align: 8) { + ╾───────alloc13───────╼ ╾───────alloc14───────╼ │ ╾──────╼╾──────╼ } -alloc12 (size: 1, align: 1) { +alloc13 (size: 1, align: 1) { 05 │ . } -alloc13 (size: 1, align: 1) { +alloc14 (size: 1, align: 1) { 06 │ . } -alloc20 (size: 24, align: 8) { - 0x00 │ ╾─────alloc17+0x3─────╼ ╾───────alloc18───────╼ │ ╾──────╼╾──────╼ - 0x10 │ ╾─────alloc19+0x2─────╼ │ ╾──────╼ +alloc21 (size: 24, align: 8) { + 0x00 │ ╾─────alloc18+0x3─────╼ ╾───────alloc19───────╼ │ ╾──────╼╾──────╼ + 0x10 │ ╾─────alloc20+0x2─────╼ │ ╾──────╼ } -alloc17 (size: 4, align: 1) { +alloc18 (size: 4, align: 1) { 2a 45 15 6f │ *E.o } -alloc18 (size: 1, align: 1) { +alloc19 (size: 1, align: 1) { 2a │ * } -alloc19 (size: 4, align: 1) { +alloc20 (size: 4, align: 1) { 2a 45 15 6f │ *E.o } diff --git a/tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir index 55c6db5d0ce..d592e59fafd 100644 --- a/tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir +++ b/tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir @@ -21,30 +21,30 @@ fn main() -> () { } alloc1 (static: FOO, size: 4, align: 4) { - ╾─alloc11─╼ │ ╾──╼ + ╾─alloc12─╼ │ ╾──╼ } -alloc11 (size: 168, align: 1) { +alloc12 (size: 168, align: 1) { 0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................ - 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc6──╼ │ ............╾──╼ + 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc7──╼ │ ............╾──╼ 0x20 │ 01 ef cd ab 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ - 0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾─alloc8──╼ 00 00 │ ..........╾──╼.. - 0x90 │ ╾─a9+0x63─╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............ + 0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾─alloc9──╼ 00 00 │ ..........╾──╼.. + 0x90 │ ╾a10+0x63─╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............ 0xa0 │ 00 00 00 00 00 00 00 00 │ ........ } -alloc6 (size: 4, align: 4) { +alloc7 (size: 4, align: 4) { 2a 00 00 00 │ *... } -alloc8 (fn: main) +alloc9 (fn: main) -alloc9 (size: 100, align: 1) { +alloc10 (size: 100, align: 1) { 0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ diff --git a/tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir index 27492a7fd22..ca53b28be7c 100644 --- a/tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir +++ b/tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir @@ -21,12 +21,12 @@ fn main() -> () { } alloc1 (static: FOO, size: 8, align: 8) { - ╾───────alloc11───────╼ │ ╾──────╼ + ╾───────alloc12───────╼ │ ╾──────╼ } -alloc11 (size: 180, align: 1) { +alloc12 (size: 180, align: 1) { 0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................ - 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾──alloc6── │ ............╾─── + 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾──alloc7── │ ............╾─── 0x20 │ ──────────╼ 01 ef cd ab 00 00 00 00 00 00 00 00 │ ───╼............ 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ @@ -34,18 +34,18 @@ alloc11 (size: 180, align: 1) { 0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x80 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ╾──── │ ..............╾─ - 0x90 │ ─────alloc8─────╼ 00 00 ╾─────alloc9+0x63─────╼ │ ─────╼..╾──────╼ + 0x90 │ ─────alloc9─────╼ 00 00 ╾────alloc10+0x63─────╼ │ ─────╼..╾──────╼ 0xa0 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0xb0 │ 00 00 00 00 │ .... } -alloc6 (size: 4, align: 4) { +alloc7 (size: 4, align: 4) { 2a 00 00 00 │ *... } -alloc8 (fn: main) +alloc9 (fn: main) -alloc9 (size: 100, align: 1) { +alloc10 (size: 100, align: 1) { 0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ diff --git a/tests/mir-opt/const_prop/address_of_pair.fn0.ConstProp.diff b/tests/mir-opt/const_prop/address_of_pair.fn0.ConstProp.diff new file mode 100644 index 00000000000..d50b12044ce --- /dev/null +++ b/tests/mir-opt/const_prop/address_of_pair.fn0.ConstProp.diff @@ -0,0 +1,46 @@ +- // MIR for `fn0` before ConstProp ++ // MIR for `fn0` after ConstProp + + fn fn0() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/address_of_pair.rs:+0:17: +0:21 + let mut _1: !; // in scope 0 at $DIR/address_of_pair.rs:+0:22: +9:2 + let mut _2: (i32, bool); // in scope 0 at $DIR/address_of_pair.rs:+1:9: +1:17 + let _4: (); // in scope 0 at $DIR/address_of_pair.rs:+4:5: +6:6 + let mut _6: bool; // in scope 0 at $DIR/address_of_pair.rs:+7:16: +7:22 + scope 1 { + debug pair => _2; // in scope 1 at $DIR/address_of_pair.rs:+1:9: +1:17 + let _3: *mut bool; // in scope 1 at $DIR/address_of_pair.rs:+2:9: +2:12 + scope 2 { + debug ptr => _3; // in scope 2 at $DIR/address_of_pair.rs:+2:9: +2:12 + let _5: bool; // in scope 2 at $DIR/address_of_pair.rs:+7:9: +7:12 + scope 3 { + } + scope 4 { + debug ret => _5; // in scope 4 at $DIR/address_of_pair.rs:+7:9: +7:12 + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/address_of_pair.rs:+1:9: +1:17 + _2 = (const 1_i32, const false); // scope 0 at $DIR/address_of_pair.rs:+1:20: +1:30 + StorageLive(_3); // scope 1 at $DIR/address_of_pair.rs:+2:9: +2:12 + _3 = &raw mut (_2.1: bool); // scope 1 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + _2 = (const 1_i32, const false); // scope 2 at $DIR/address_of_pair.rs:+3:5: +3:22 + StorageLive(_4); // scope 2 at $DIR/address_of_pair.rs:+4:5: +6:6 + (*_3) = const true; // scope 3 at $DIR/address_of_pair.rs:+5:9: +5:20 + _4 = const (); // scope 3 at $DIR/address_of_pair.rs:+4:5: +6:6 + StorageDead(_4); // scope 2 at $DIR/address_of_pair.rs:+6:5: +6:6 + StorageLive(_5); // scope 2 at $DIR/address_of_pair.rs:+7:9: +7:12 + StorageLive(_6); // scope 2 at $DIR/address_of_pair.rs:+7:16: +7:22 + _6 = (_2.1: bool); // scope 2 at $DIR/address_of_pair.rs:+7:16: +7:22 + _5 = Not(move _6); // scope 2 at $DIR/address_of_pair.rs:+7:15: +7:22 + StorageDead(_6); // scope 2 at $DIR/address_of_pair.rs:+7:21: +7:22 + _0 = _5; // scope 4 at $DIR/address_of_pair.rs:+8:12: +8:15 + StorageDead(_5); // scope 2 at $DIR/address_of_pair.rs:+9:1: +9:2 + StorageDead(_3); // scope 1 at $DIR/address_of_pair.rs:+9:1: +9:2 + StorageDead(_2); // scope 0 at $DIR/address_of_pair.rs:+9:1: +9:2 + return; // scope 0 at $DIR/address_of_pair.rs:+9:2: +9:2 + } + } + diff --git a/tests/mir-opt/const_prop/address_of_pair.rs b/tests/mir-opt/const_prop/address_of_pair.rs new file mode 100644 index 00000000000..43dc9bae625 --- /dev/null +++ b/tests/mir-opt/const_prop/address_of_pair.rs @@ -0,0 +1,17 @@ +// unit-test: ConstProp + +// EMIT_MIR address_of_pair.fn0.ConstProp.diff +pub fn fn0() -> bool { + let mut pair = (1, false); + let ptr = core::ptr::addr_of_mut!(pair.1); + pair = (1, false); + unsafe { + *ptr = true; + } + let ret = !pair.1; + return ret; +} + +pub fn main() { + println!("{}", fn0()); +} diff --git a/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff index bedfa5992ad..85d6b5e3d00 100644 --- a/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff @@ -18,29 +18,35 @@ } bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10 _1 = const 0_i32; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:13: +1:14 StorageLive(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11 -- _4 = Eq(_1, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + StorageLive(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 +- _3 = _1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 +- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 - assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 + _4 = const true; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 } bb1: { -- _5 = Eq(_1, const -1_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 - _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 - _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 -- assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _1) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + _5 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + _6 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + _7 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 -+ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 } bb2: { -- _2 = Rem(const 1_i32, _1); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 -+ _2 = Rem(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + _2 = Rem(const 1_i32, move _3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + StorageDead(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 + _0 = const (); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +3:2 StorageDead(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2 return; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:2: +3:2 } } diff --git a/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs b/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs index a1078472cbf..93d558250ea 100644 --- a/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs +++ b/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs @@ -1,3 +1,4 @@ +// unit-test: ConstProp // ignore-wasm32 compiled with panic=abort by default // EMIT_MIR bad_op_mod_by_zero.main.ConstProp.diff #[allow(unconditional_panic)] diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff index e711babf035..f63ee705d92 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff @@ -6,16 +6,17 @@ let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - let _5: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - let mut _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - let mut _7: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - let mut _8: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35 + let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 scope 1 { debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 scope 2 { - let _4: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 scope 3 { - debug _b => _4; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 } } } @@ -23,27 +24,31 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - _8 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 // mir::Constant - // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:6:25: 6:35 + // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:9:25: 9:35 // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } - _2 = &raw const (*_8); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _3 = &(*_9); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35 - StorageLive(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 - StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - _5 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -- _7 = Lt(_5, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -+ _7 = const false; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _7 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _8 = const false; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 } bb1: { - _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 - StorageDead(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 + _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + _0 = const (); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 } diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff index e711babf035..f63ee705d92 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff @@ -6,16 +6,17 @@ let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - let _5: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - let mut _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - let mut _7: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - let mut _8: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35 + let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 scope 1 { debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 scope 2 { - let _4: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 scope 3 { - debug _b => _4; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 } } } @@ -23,27 +24,31 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - _8 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 // mir::Constant - // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:6:25: 6:35 + // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:9:25: 9:35 // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } - _2 = &raw const (*_8); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _3 = &(*_9); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35 - StorageLive(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 - StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - _5 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -- _7 = Lt(_5, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -+ _7 = const false; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _7 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _8 = const false; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 } bb1: { - _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 - StorageDead(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 + _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + _0 = const (); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 } diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs index 3d252f2d221..ef148d16dc2 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs @@ -1,4 +1,7 @@ +// unit-test: ConstProp // ignore-wasm32 compiled with panic=abort by default +// compile-flags: -Zmir-enable-passes=+NormalizeArrayLen + // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR bad_op_unsafe_oob_for_slices.main.ConstProp.diff #[allow(unconditional_panic)] diff --git a/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff index 85dedf68ce9..1752d222fe7 100644 --- a/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff @@ -7,13 +7,17 @@ let mut _2: main::InvalidChar; // in scope 0 at $DIR/invalid_constant.rs:+6:34: +6:63 let mut _4: E; // in scope 0 at $DIR/invalid_constant.rs:+13:25: +13:59 let mut _5: main::InvalidTag; // in scope 0 at $DIR/invalid_constant.rs:+13:34: +13:55 + let mut _7: Empty; // in scope 0 at $DIR/invalid_constant.rs:+20:35: +20:73 + let mut _8: main::NoVariants; // in scope 0 at $DIR/invalid_constant.rs:+20:44: +20:65 scope 1 { debug _invalid_char => _1; // in scope 1 at $DIR/invalid_constant.rs:+6:9: +6:22 let _3: [E; 1]; // in scope 1 at $DIR/invalid_constant.rs:+13:9: +13:21 scope 3 { debug _invalid_tag => _3; // in scope 3 at $DIR/invalid_constant.rs:+13:9: +13:21 + let _6: [Empty; 1]; // in scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31 scope 5 { debug _enum_without_variants => const [ZeroSized: Empty]; // in scope 5 at $DIR/invalid_constant.rs:+20:9: +20:31 + let _9: main::Str<"���">; // in scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 scope 7 { debug _non_utf8_str => const Str::<"���">; // in scope 7 at $DIR/invalid_constant.rs:+24:9: +24:22 } @@ -39,17 +43,25 @@ StorageLive(_5); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55 _5 = InvalidTag { int: const 4_u32 }; // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55 - _4 = (_5.1: E); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:57 -- _3 = [move _4]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60 + _4 = const Scalar(0x00000004): E; // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:57 + // mir::Constant + // + span: no-location + // + literal: Const { ty: E, val: Value(Scalar(0x00000004)) } -+ _3 = [const Scalar(0x00000004): E]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60 -+ // mir::Constant -+ // + span: no-location -+ // + literal: Const { ty: E, val: Value(Scalar(0x00000004)) } + _3 = [move _4]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60 StorageDead(_4); // scope 1 at $DIR/invalid_constant.rs:+13:59: +13:60 StorageDead(_5); // scope 1 at $DIR/invalid_constant.rs:+13:60: +13:61 + nop; // scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31 + nop; // scope 3 at $DIR/invalid_constant.rs:+20:35: +20:73 + StorageLive(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65 + _8 = NoVariants { int: const 0_u32 }; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65 + nop; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:71 + nop; // scope 3 at $DIR/invalid_constant.rs:+20:34: +20:74 + nop; // scope 3 at $DIR/invalid_constant.rs:+20:73: +20:74 + StorageDead(_8); // scope 3 at $DIR/invalid_constant.rs:+20:74: +20:75 + nop; // scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 + nop; // scope 0 at $DIR/invalid_constant.rs:+0:11: +27:2 + nop; // scope 5 at $DIR/invalid_constant.rs:+27:1: +27:2 + nop; // scope 3 at $DIR/invalid_constant.rs:+27:1: +27:2 StorageDead(_3); // scope 1 at $DIR/invalid_constant.rs:+27:1: +27:2 StorageDead(_1); // scope 0 at $DIR/invalid_constant.rs:+27:1: +27:2 return; // scope 0 at $DIR/invalid_constant.rs:+27:2: +27:2 diff --git a/tests/mir-opt/const_prop/invalid_constant.rs b/tests/mir-opt/const_prop/invalid_constant.rs index eb6172cdff9..bdbc5a1990e 100644 --- a/tests/mir-opt/const_prop/invalid_constant.rs +++ b/tests/mir-opt/const_prop/invalid_constant.rs @@ -1,3 +1,5 @@ +// unit-test: ConstProp +// compile-flags: -Zmir-enable-passes=+RemoveZsts // Verify that we can pretty print invalid constants. #![feature(adt_const_params)] diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff index 5331e5b8212..36336d967a9 100644 --- a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff +++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff @@ -18,17 +18,19 @@ _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 - _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- _4 = Len(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 - _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 - assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 } bb1: { _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + _0 = const (); // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2 return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2 } diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff index 5331e5b8212..36336d967a9 100644 --- a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff +++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff @@ -18,17 +18,19 @@ _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 - _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- _4 = Len(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 - _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 - assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 } bb1: { _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + _0 = const (); // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2 return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2 } diff --git a/tests/mir-opt/const_prop/large_array_index.rs b/tests/mir-opt/const_prop/large_array_index.rs index 073f9849568..0876445bf2c 100644 --- a/tests/mir-opt/const_prop/large_array_index.rs +++ b/tests/mir-opt/const_prop/large_array_index.rs @@ -1,4 +1,6 @@ +// unit-test: ConstProp // ignore-wasm32 compiled with panic=abort by default +// compile-flags: -Zmir-enable-passes=+NormalizeArrayLen // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR large_array_index.main.ConstProp.diff diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff index 15c93f270d7..077b9bf8304 100644 --- a/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff @@ -3,21 +3,26 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +0:11 - let mut _1: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 - let mut _2: fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + let mut _1: *const fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 + let mut _2: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + let mut _3: fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 scope 1 { } bb0: { - StorageLive(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 - StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 - _2 = main as fn() (Pointer(ReifyFnPointer)); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + StorageLive(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 + StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + StorageLive(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + _3 = main as fn() (Pointer(ReifyFnPointer)); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 // mir::Constant - // + span: $DIR/reify_fn_ptr.rs:4:13: 4:17 + // + span: $DIR/reify_fn_ptr.rs:5:13: 5:17 // + literal: Const { ty: fn() {main}, val: Value(<ZST>) } - _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 - StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26 - StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41 + _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + StorageDead(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26 + _1 = move _2 as *const fn() (PointerFromExposedAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 + StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41 + StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:41: +1:42 + _0 = const (); // scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +2:2 return; // scope 0 at $DIR/reify_fn_ptr.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.rs b/tests/mir-opt/const_prop/reify_fn_ptr.rs index bfe2563ad8a..5f63820669b 100644 --- a/tests/mir-opt/const_prop/reify_fn_ptr.rs +++ b/tests/mir-opt/const_prop/reify_fn_ptr.rs @@ -1,3 +1,4 @@ +// unit-test: ConstProp // EMIT_MIR reify_fn_ptr.main.ConstProp.diff fn main() { diff --git a/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff index 636032adb81..6641220db69 100644 --- a/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff +++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff @@ -20,11 +20,12 @@ _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25 StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27 _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27 - _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _5 = Len(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 - _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 - assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 } bb1: { @@ -35,6 +36,7 @@ StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32 StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + _0 = const (); // scope 0 at $DIR/repeat.rs:+0:11: +2:2 StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2 return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff index 636032adb81..6641220db69 100644 --- a/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff +++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff @@ -20,11 +20,12 @@ _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25 StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27 _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27 - _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _5 = Len(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 - _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 - assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 } bb1: { @@ -35,6 +36,7 @@ StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32 StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + _0 = const (); // scope 0 at $DIR/repeat.rs:+0:11: +2:2 StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2 return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/const_prop/repeat.rs b/tests/mir-opt/const_prop/repeat.rs index 2f3b7d2c502..9c11dbc5b66 100644 --- a/tests/mir-opt/const_prop/repeat.rs +++ b/tests/mir-opt/const_prop/repeat.rs @@ -1,7 +1,8 @@ +// unit-test: ConstProp // ignore-wasm32 compiled with panic=abort by default -// compile-flags: -O - +// compile-flags: -Zmir-enable-passes=+NormalizeArrayLen // EMIT_MIR_FOR_EACH_BIT_WIDTH + // EMIT_MIR repeat.main.ConstProp.diff fn main() { let x: u32 = [42; 8][2] + 0; diff --git a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir index ececd994283..b12d84fa479 100644 --- a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir +++ b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir @@ -2,8 +2,14 @@ fn add() -> u32 { let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16 + let mut _1: (u32, bool); // in scope 0 at $DIR/return_place.rs:+1:5: +1:10 bb0: { + _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + } + + bb1: { _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/const_prop/return_place.rs b/tests/mir-opt/const_prop/return_place.rs index ae119df8518..0e68309f036 100644 --- a/tests/mir-opt/const_prop/return_place.rs +++ b/tests/mir-opt/const_prop/return_place.rs @@ -1,3 +1,4 @@ +// unit-test: ConstProp // ignore-wasm32 compiled with panic=abort by default // compile-flags: -C overflow-checks=on diff --git a/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff index a091b4ace20..c2f97a0f622 100644 --- a/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff @@ -11,15 +11,23 @@ } bb0: { + StorageLive(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10 _1 = const 1_u32; // scope 0 at $DIR/scalar_literal_propagation.rs:+1:13: +1:14 -- _2 = consume(_1) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 -+ _2 = consume(const 1_u32) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 + StorageLive(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 + StorageLive(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 +- _3 = _1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 ++ _3 = const 1_u32; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 + _2 = consume(move _3) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 // mir::Constant - // + span: $DIR/scalar_literal_propagation.rs:5:5: 5:12 + // + span: $DIR/scalar_literal_propagation.rs:6:5: 6:12 // + literal: Const { ty: fn(u32) {consume}, val: Value(<ZST>) } } bb1: { + StorageDead(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:14: +2:15 + StorageDead(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:15: +2:16 + _0 = const (); // scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+3:1: +3:2 return; // scope 0 at $DIR/scalar_literal_propagation.rs:+3:2: +3:2 } } diff --git a/tests/mir-opt/const_prop/scalar_literal_propagation.rs b/tests/mir-opt/const_prop/scalar_literal_propagation.rs index e13e352f8a1..fc33cc2d021 100644 --- a/tests/mir-opt/const_prop/scalar_literal_propagation.rs +++ b/tests/mir-opt/const_prop/scalar_literal_propagation.rs @@ -1,3 +1,4 @@ +// unit-test: ConstProp // ignore-wasm32 compiled with panic=abort by default // EMIT_MIR scalar_literal_propagation.main.ConstProp.diff fn main() { diff --git a/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs index 4499c54f264..9821d1b1e92 100644 --- a/tests/mir-opt/const_prop/slice_len.rs +++ b/tests/mir-opt/const_prop/slice_len.rs @@ -1,6 +1,6 @@ // ignore-wasm32 compiled with panic=abort by default // unit-test: ConstProp -// compile-flags: -Zmir-enable-passes=+InstCombine +// compile-flags: -Zmir-enable-passes=+InstSimplify // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR slice_len.main.ConstProp.diff diff --git a/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff b/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff index 85704c48a2c..664b7839ffc 100644 --- a/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff @@ -15,14 +15,14 @@ bb1: { _0 = foo(const -1_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21 // mir::Constant - // + span: $DIR/switch_int.rs:10:14: 10:17 + // + span: $DIR/switch_int.rs:12:14: 12:17 // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } } bb2: { _0 = foo(const 0_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20 // mir::Constant - // + span: $DIR/switch_int.rs:9:14: 9:17 + // + span: $DIR/switch_int.rs:11:14: 11:17 // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } } diff --git a/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff index 0864db22523..ef2c4d5faa6 100644 --- a/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff +++ b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff @@ -15,14 +15,14 @@ bb1: { _0 = foo(const -1_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21 // mir::Constant - // + span: $DIR/switch_int.rs:10:14: 10:17 + // + span: $DIR/switch_int.rs:12:14: 12:17 // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } } bb2: { _0 = foo(const 0_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20 // mir::Constant - // + span: $DIR/switch_int.rs:9:14: 9:17 + // + span: $DIR/switch_int.rs:11:14: 11:17 // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } } diff --git a/tests/mir-opt/const_prop/switch_int.rs b/tests/mir-opt/const_prop/switch_int.rs index 2a2322e43a9..7158ea4d2bd 100644 --- a/tests/mir-opt/const_prop/switch_int.rs +++ b/tests/mir-opt/const_prop/switch_int.rs @@ -1,3 +1,5 @@ +// unit-test: ConstProp +// compile-flags: -Zmir-enable-passes=+SimplifyConstCondition-after-const-prop // ignore-wasm32 compiled with panic=abort by default #[inline(never)] fn foo(_: i32) { } diff --git a/tests/mir-opt/const_prop/transmute.from_char.ConstProp.diff b/tests/mir-opt/const_prop/transmute.from_char.ConstProp.32bit.diff index 933dfbb5166..933dfbb5166 100644 --- a/tests/mir-opt/const_prop/transmute.from_char.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.from_char.ConstProp.32bit.diff diff --git a/tests/mir-opt/const_prop/transmute.from_char.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.from_char.ConstProp.64bit.diff new file mode 100644 index 00000000000..933dfbb5166 --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.from_char.ConstProp.64bit.diff @@ -0,0 +1,15 @@ +- // MIR for `from_char` before ConstProp ++ // MIR for `from_char` after ConstProp + + fn from_char() -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/transmute.rs:+0:23: +0:26 + scope 1 { + } + + bb0: { +- _0 = const 'R' as i32 (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:28 ++ _0 = const 82_i32; // scope 1 at $DIR/transmute.rs:+1:14: +1:28 + return; // scope 0 at $DIR/transmute.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.diff b/tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.32bit.diff index f3474855f02..4a31194de6e 100644 --- a/tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.32bit.diff @@ -7,7 +7,8 @@ } bb0: { - _0 = const -1_i8 as bool (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:30 +- _0 = const -1_i8 as bool (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:30 ++ _0 = const {transmute(0xff): bool}; // scope 1 at $DIR/transmute.rs:+1:14: +1:30 return; // scope 0 at $DIR/transmute.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.64bit.diff new file mode 100644 index 00000000000..4a31194de6e --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.64bit.diff @@ -0,0 +1,15 @@ +- // MIR for `invalid_bool` before ConstProp ++ // MIR for `invalid_bool` after ConstProp + + fn invalid_bool() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/transmute.rs:+0:33: +0:37 + scope 1 { + } + + bb0: { +- _0 = const -1_i8 as bool (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:30 ++ _0 = const {transmute(0xff): bool}; // scope 1 at $DIR/transmute.rs:+1:14: +1:30 + return; // scope 0 at $DIR/transmute.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.diff b/tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.32bit.diff index ba087e226c9..2c541f2f6a0 100644 --- a/tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.32bit.diff @@ -7,7 +7,8 @@ } bb0: { - _0 = const _ as char (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:33 +- _0 = const _ as char (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:33 ++ _0 = const {transmute(0x7fffffff): char}; // scope 1 at $DIR/transmute.rs:+1:14: +1:33 return; // scope 0 at $DIR/transmute.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.64bit.diff new file mode 100644 index 00000000000..2c541f2f6a0 --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.64bit.diff @@ -0,0 +1,15 @@ +- // MIR for `invalid_char` before ConstProp ++ // MIR for `invalid_char` after ConstProp + + fn invalid_char() -> char { + let mut _0: char; // return place in scope 0 at $DIR/transmute.rs:+0:33: +0:37 + scope 1 { + } + + bb0: { +- _0 = const _ as char (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:33 ++ _0 = const {transmute(0x7fffffff): char}; // scope 1 at $DIR/transmute.rs:+1:14: +1:33 + return; // scope 0 at $DIR/transmute.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.less_as_i8.ConstProp.diff b/tests/mir-opt/const_prop/transmute.less_as_i8.ConstProp.32bit.diff index 76d464789c1..76d464789c1 100644 --- a/tests/mir-opt/const_prop/transmute.less_as_i8.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.less_as_i8.ConstProp.32bit.diff diff --git a/tests/mir-opt/const_prop/transmute.less_as_i8.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.less_as_i8.ConstProp.64bit.diff new file mode 100644 index 00000000000..76d464789c1 --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.less_as_i8.ConstProp.64bit.diff @@ -0,0 +1,23 @@ +- // MIR for `less_as_i8` before ConstProp ++ // MIR for `less_as_i8` after ConstProp + + fn less_as_i8() -> i8 { + let mut _0: i8; // return place in scope 0 at $DIR/transmute.rs:+0:24: +0:26 + let mut _1: std::cmp::Ordering; // in scope 0 at $DIR/transmute.rs:+1:24: +1:48 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/transmute.rs:+1:24: +1:48 +- _1 = Less; // scope 1 at $DIR/transmute.rs:+1:24: +1:48 +- _0 = move _1 as i8 (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:49 ++ _1 = const Less; // scope 1 at $DIR/transmute.rs:+1:24: +1:48 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: std::cmp::Ordering, val: Value(Scalar(0xff)) } ++ _0 = const -1_i8; // scope 1 at $DIR/transmute.rs:+1:14: +1:49 + StorageDead(_1); // scope 1 at $DIR/transmute.rs:+1:48: +1:49 + return; // scope 0 at $DIR/transmute.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.rs b/tests/mir-opt/const_prop/transmute.rs index b753cdccd60..762c421715a 100644 --- a/tests/mir-opt/const_prop/transmute.rs +++ b/tests/mir-opt/const_prop/transmute.rs @@ -1,5 +1,7 @@ // unit-test: ConstProp // compile-flags: -O --crate-type=lib +// ignore-endian-big +// EMIT_MIR_FOR_EACH_BIT_WIDTH use std::mem::transmute; diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.ConstProp.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.ConstProp.32bit.diff index 538b1f26e4c..538b1f26e4c 100644 --- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.ConstProp.32bit.diff diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.ConstProp.64bit.diff new file mode 100644 index 00000000000..538b1f26e4c --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.ConstProp.64bit.diff @@ -0,0 +1,22 @@ +- // MIR for `undef_union_as_integer` before ConstProp ++ // MIR for `undef_union_as_integer` after ConstProp + + fn undef_union_as_integer() -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/transmute.rs:+0:43: +0:46 + let mut _1: undef_union_as_integer::Union32; // in scope 0 at $DIR/transmute.rs:+2:24: +2:44 + let mut _2: (); // in scope 0 at $DIR/transmute.rs:+2:40: +2:42 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/transmute.rs:+2:24: +2:44 + StorageLive(_2); // scope 1 at $DIR/transmute.rs:+2:40: +2:42 + _2 = (); // scope 1 at $DIR/transmute.rs:+2:40: +2:42 + _1 = Union32 { value: move _2 }; // scope 1 at $DIR/transmute.rs:+2:24: +2:44 + StorageDead(_2); // scope 1 at $DIR/transmute.rs:+2:43: +2:44 + _0 = move _1 as u32 (Transmute); // scope 1 at $DIR/transmute.rs:+2:14: +2:45 + StorageDead(_1); // scope 1 at $DIR/transmute.rs:+2:44: +2:45 + return; // scope 0 at $DIR/transmute.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff index 8bf97996a67..bc41b5d0813 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff @@ -15,7 +15,11 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/transmute.rs:+0:38: +3:2 StorageLive(_2); // scope 0 at $DIR/transmute.rs:+1:9: +1:10 - _2 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52 +- _2 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52 ++ _2 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global); // scope 2 at $DIR/transmute.rs:+1:34: +1:52 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: Box<Never>, val: Value(Scalar(0x00000001)) } StorageLive(_3); // scope 1 at $DIR/transmute.rs:+2:5: +2:16 unreachable; // scope 1 at $DIR/transmute.rs:+2:11: +2:13 } diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff new file mode 100644 index 00000000000..c4376e6e17a --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff @@ -0,0 +1,27 @@ +- // MIR for `unreachable_box` before ConstProp ++ // MIR for `unreachable_box` after ConstProp + + fn unreachable_box() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37 + let mut _1: !; // in scope 0 at $DIR/transmute.rs:+0:38: +3:2 + let _2: std::boxed::Box<Never>; // in scope 0 at $DIR/transmute.rs:+1:9: +1:10 + let mut _3: !; // in scope 0 at $DIR/transmute.rs:+2:5: +2:16 + scope 1 { + debug x => _2; // in scope 1 at $DIR/transmute.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/transmute.rs:+0:38: +3:2 + StorageLive(_2); // scope 0 at $DIR/transmute.rs:+1:9: +1:10 +- _2 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52 ++ _2 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global); // scope 2 at $DIR/transmute.rs:+1:34: +1:52 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: Box<Never>, val: Value(Scalar(0x0000000000000001)) } + StorageLive(_3); // scope 1 at $DIR/transmute.rs:+2:5: +2:16 + unreachable; // scope 1 at $DIR/transmute.rs:+2:11: +2:13 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.32bit.diff index 81b7b368993..81b7b368993 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.32bit.diff diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.64bit.diff new file mode 100644 index 00000000000..81b7b368993 --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.64bit.diff @@ -0,0 +1,25 @@ +- // MIR for `unreachable_direct` before ConstProp ++ // MIR for `unreachable_direct` after ConstProp + + fn unreachable_direct() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/transmute.rs:+0:39: +0:40 + let mut _1: !; // in scope 0 at $DIR/transmute.rs:+0:41: +3:2 + let _2: Never; // in scope 0 at $DIR/transmute.rs:+1:9: +1:10 + let mut _3: (); // in scope 0 at $DIR/transmute.rs:+1:39: +1:41 + let mut _4: !; // in scope 0 at $DIR/transmute.rs:+2:5: +2:15 + scope 1 { + debug x => _2; // in scope 1 at $DIR/transmute.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/transmute.rs:+0:41: +3:2 + StorageLive(_2); // scope 0 at $DIR/transmute.rs:+1:9: +1:10 + StorageLive(_3); // scope 2 at $DIR/transmute.rs:+1:39: +1:41 + _3 = (); // scope 2 at $DIR/transmute.rs:+1:39: +1:41 + _2 = move _3 as Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:29: +1:42 + unreachable; // scope 2 at $DIR/transmute.rs:+1:29: +1:42 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.diff b/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.32bit.diff index 34f7aea8ed2..47f023cd93d 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.32bit.diff @@ -17,7 +17,11 @@ StorageLive(_1); // scope 0 at $DIR/transmute.rs:+0:38: +3:2 StorageLive(_2); // scope 0 at $DIR/transmute.rs:+1:9: +1:10 StorageLive(_3); // scope 0 at $DIR/transmute.rs:+1:34: +1:52 - _3 = const 1_usize as &mut Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52 +- _3 = const 1_usize as &mut Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52 ++ _3 = const {0x1 as &mut Never}; // scope 2 at $DIR/transmute.rs:+1:34: +1:52 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: &mut Never, val: Value(Scalar(0x00000001)) } _2 = &mut (*_3); // scope 0 at $DIR/transmute.rs:+1:34: +1:52 StorageDead(_3); // scope 0 at $DIR/transmute.rs:+1:54: +1:55 StorageLive(_4); // scope 1 at $DIR/transmute.rs:+2:5: +2:16 diff --git a/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.64bit.diff new file mode 100644 index 00000000000..62300d2e313 --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.64bit.diff @@ -0,0 +1,31 @@ +- // MIR for `unreachable_mut` before ConstProp ++ // MIR for `unreachable_mut` after ConstProp + + fn unreachable_mut() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37 + let mut _1: !; // in scope 0 at $DIR/transmute.rs:+0:38: +3:2 + let _2: &mut Never; // in scope 0 at $DIR/transmute.rs:+1:9: +1:10 + let mut _3: &mut Never; // in scope 0 at $DIR/transmute.rs:+1:34: +1:52 + let mut _4: !; // in scope 0 at $DIR/transmute.rs:+2:5: +2:16 + scope 1 { + debug x => _2; // in scope 1 at $DIR/transmute.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/transmute.rs:+0:38: +3:2 + StorageLive(_2); // scope 0 at $DIR/transmute.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/transmute.rs:+1:34: +1:52 +- _3 = const 1_usize as &mut Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52 ++ _3 = const {0x1 as &mut Never}; // scope 2 at $DIR/transmute.rs:+1:34: +1:52 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: &mut Never, val: Value(Scalar(0x0000000000000001)) } + _2 = &mut (*_3); // scope 0 at $DIR/transmute.rs:+1:34: +1:52 + StorageDead(_3); // scope 0 at $DIR/transmute.rs:+1:54: +1:55 + StorageLive(_4); // scope 1 at $DIR/transmute.rs:+2:5: +2:16 + unreachable; // scope 1 at $DIR/transmute.rs:+2:11: +2:13 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.diff b/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.32bit.diff index ff95f2a0b94..8578f898a7e 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.32bit.diff @@ -15,7 +15,11 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/transmute.rs:+0:38: +3:2 StorageLive(_2); // scope 0 at $DIR/transmute.rs:+1:9: +1:10 - _2 = const 1_usize as &Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:30: +1:48 +- _2 = const 1_usize as &Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:30: +1:48 ++ _2 = const {0x1 as &Never}; // scope 2 at $DIR/transmute.rs:+1:30: +1:48 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: &Never, val: Value(Scalar(0x00000001)) } StorageLive(_3); // scope 1 at $DIR/transmute.rs:+2:5: +2:16 unreachable; // scope 1 at $DIR/transmute.rs:+2:11: +2:13 } diff --git a/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.64bit.diff new file mode 100644 index 00000000000..8b11cea9365 --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.64bit.diff @@ -0,0 +1,27 @@ +- // MIR for `unreachable_ref` before ConstProp ++ // MIR for `unreachable_ref` after ConstProp + + fn unreachable_ref() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37 + let mut _1: !; // in scope 0 at $DIR/transmute.rs:+0:38: +3:2 + let _2: &Never; // in scope 0 at $DIR/transmute.rs:+1:9: +1:10 + let mut _3: !; // in scope 0 at $DIR/transmute.rs:+2:5: +2:16 + scope 1 { + debug x => _2; // in scope 1 at $DIR/transmute.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/transmute.rs:+0:38: +3:2 + StorageLive(_2); // scope 0 at $DIR/transmute.rs:+1:9: +1:10 +- _2 = const 1_usize as &Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:30: +1:48 ++ _2 = const {0x1 as &Never}; // scope 2 at $DIR/transmute.rs:+1:30: +1:48 ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: &Never, val: Value(Scalar(0x0000000000000001)) } + StorageLive(_3); // scope 1 at $DIR/transmute.rs:+2:5: +2:16 + unreachable; // scope 1 at $DIR/transmute.rs:+2:11: +2:13 + } + } + diff --git a/tests/mir-opt/const_prop/transmute.valid_char.ConstProp.diff b/tests/mir-opt/const_prop/transmute.valid_char.ConstProp.32bit.diff index eac33b73003..eac33b73003 100644 --- a/tests/mir-opt/const_prop/transmute.valid_char.ConstProp.diff +++ b/tests/mir-opt/const_prop/transmute.valid_char.ConstProp.32bit.diff diff --git a/tests/mir-opt/const_prop/transmute.valid_char.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.valid_char.ConstProp.64bit.diff new file mode 100644 index 00000000000..eac33b73003 --- /dev/null +++ b/tests/mir-opt/const_prop/transmute.valid_char.ConstProp.64bit.diff @@ -0,0 +1,15 @@ +- // MIR for `valid_char` before ConstProp ++ // MIR for `valid_char` after ConstProp + + fn valid_char() -> char { + let mut _0: char; // return place in scope 0 at $DIR/transmute.rs:+0:24: +0:28 + scope 1 { + } + + bb0: { +- _0 = const 82_u32 as char (Transmute); // scope 1 at $DIR/transmute.rs:+1:14: +1:33 ++ _0 = const 'R'; // scope 1 at $DIR/transmute.rs:+1:14: +1:33 + return; // scope 0 at $DIR/transmute.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff index 12313b6c58d..e4a7c0d1e72 100644 --- a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff @@ -11,15 +11,24 @@ } bb0: { + StorageLive(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10 - _1 = (const 1_u32, const 2_u32); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19 + _1 = const (1_u32, 2_u32); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19 - _2 = consume(_1) -> bb1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 + StorageLive(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 + StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 +- _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 ++ _3 = const (1_u32, 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 + _2 = consume(move _3) -> bb1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 // mir::Constant - // + span: $DIR/tuple_literal_propagation.rs:6:5: 6:12 + // + span: $DIR/tuple_literal_propagation.rs:7:5: 7:12 // + literal: Const { ty: fn((u32, u32)) {consume}, val: Value(<ZST>) } } bb1: { + StorageDead(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:14: +3:15 + StorageDead(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:15: +3:16 + _0 = const (); // scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+4:1: +4:2 return; // scope 0 at $DIR/tuple_literal_propagation.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.rs b/tests/mir-opt/const_prop/tuple_literal_propagation.rs index edd748d00ab..f342ae2700e 100644 --- a/tests/mir-opt/const_prop/tuple_literal_propagation.rs +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.rs @@ -1,3 +1,4 @@ +// unit-test: ConstProp // ignore-wasm32 compiled with panic=abort by default // EMIT_MIR tuple_literal_propagation.main.ConstProp.diff fn main() { diff --git a/tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff b/tests/mir-opt/const_prop/while_let_loops.change_loop_body.ConstProp.diff index a4f2d8c84d8..37732421870 100644 --- a/tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff +++ b/tests/mir-opt/const_prop/while_let_loops.change_loop_body.ConstProp.diff @@ -4,8 +4,13 @@ fn change_loop_body() -> () { let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27 let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 - let mut _2: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32 - let mut _3: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25 + let mut _2: (); // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2 + let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32 + let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25 + let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6 + let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + let _7: (); // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 scope 1 { debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15 scope 2 { @@ -15,29 +20,33 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19 - StorageLive(_2); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 - _2 = Option::<u32>::None; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 -- _3 = discriminant(_2); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 -- switchInt(move _3) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 -+ _3 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + StorageLive(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + _3 = Option::<u32>::None; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 +- _4 = discriminant(_3); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 +- switchInt(move _4) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ _4 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + switchInt(const 0_isize) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 } bb1: { - switchInt(((_2 as Some).0: u32)) -> [0: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + switchInt(((_3 as Some).0: u32)) -> [0: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 } bb2: { _1 = const 1_i32; // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15 + _0 = const (); // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 } bb3: { + StorageLive(_7); // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 + _0 = const (); // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 + StorageDead(_7); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 goto -> bb4; // scope 1 at no-location } bb4: { - StorageDead(_2); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 + StorageDead(_3); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2 return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2 } diff --git a/tests/mir-opt/while_let_loops.rs b/tests/mir-opt/const_prop/while_let_loops.rs index fc56cd6985d..595a94b88be 100644 --- a/tests/mir-opt/while_let_loops.rs +++ b/tests/mir-opt/const_prop/while_let_loops.rs @@ -1,5 +1,5 @@ +// unit-test: ConstProp // EMIT_MIR while_let_loops.change_loop_body.ConstProp.diff -// EMIT_MIR while_let_loops.change_loop_body.PreCodegen.after.mir pub fn change_loop_body() { let mut _x = 0; diff --git a/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff index def9fc6428f..a5f52d08957 100644 --- a/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff +++ b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff @@ -19,8 +19,7 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 -- _1 = (const 1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 -+ _1 = const (1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 + _1 = (const 1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +4:6 StorageLive(_3); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 _3 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 diff --git a/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff index b54c10a140f..42ddc2a5620 100644 --- a/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff +++ b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff @@ -16,8 +16,7 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 -- _1 = (const 1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 -+ _1 = const (1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 + _1 = (const 1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14 _2 = &mut (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14 (*_2) = const 5_i32; // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +2:18 diff --git a/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff new file mode 100644 index 00000000000..761c074ed94 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff @@ -0,0 +1,25 @@ +- // MIR for `main` before DeadStoreElimination ++ // MIR for `main` after DeadStoreElimination + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/place_mention.rs:+0:11: +0:11 + let mut _1: (&str, &str); // in scope 0 at $DIR/place_mention.rs:+3:18: +3:36 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 + _1 = (const "Hello", const "World"); // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 + // mir::Constant + // + span: $DIR/place_mention.rs:8:19: 8:26 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + // mir::Constant + // + span: $DIR/place_mention.rs:8:28: 8:35 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + PlaceMention(_1); // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 + StorageDead(_1); // scope 0 at $DIR/place_mention.rs:+3:36: +3:37 + _0 = const (); // scope 0 at $DIR/place_mention.rs:+0:11: +4:2 + return; // scope 0 at $DIR/place_mention.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dead-store-elimination/place_mention.rs b/tests/mir-opt/dead-store-elimination/place_mention.rs new file mode 100644 index 00000000000..59dc74454a4 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/place_mention.rs @@ -0,0 +1,9 @@ +// unit-test: DeadStoreElimination +// compile-flags: -Zmir-keep-place-mention + +// EMIT_MIR place_mention.main.DeadStoreElimination.diff +fn main() { + // Verify that we account for the `PlaceMention` statement as a use of the tuple, + // and don't remove it as a dead store. + let (_, _) = ("Hello", "World"); +} diff --git a/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff b/tests/mir-opt/dont_yeet_assert.generic.InstSimplify.diff index c0fc1fb1df3..cadf05152a4 100644 --- a/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff +++ b/tests/mir-opt/dont_yeet_assert.generic.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `generic` before InstCombine -+ // MIR for `generic` after InstCombine +- // MIR for `generic` before InstSimplify ++ // MIR for `generic` after InstSimplify fn generic() -> () { let mut _0: (); // return place in scope 0 at $DIR/dont_yeet_assert.rs:+0:21: +0:21 diff --git a/tests/mir-opt/dont_yeet_assert.rs b/tests/mir-opt/dont_yeet_assert.rs index 7cec761eaba..38cc5a293e8 100644 --- a/tests/mir-opt/dont_yeet_assert.rs +++ b/tests/mir-opt/dont_yeet_assert.rs @@ -1,11 +1,11 @@ // compile-flags: --crate-type=lib -// unit-test: InstCombine +// unit-test: InstSimplify #![feature(core_intrinsics)] // Want to make sure this assertion isn't compiled away in generic code. -// EMIT_MIR dont_yeet_assert.generic.InstCombine.diff +// EMIT_MIR dont_yeet_assert.generic.InstSimplify.diff pub fn generic<T>() { core::intrinsics::assert_mem_uninitialized_valid::<&T>(); } diff --git a/tests/mir-opt/equal_true.opt.InstCombine.diff b/tests/mir-opt/equal_true.opt.InstSimplify.diff index 8b542a7c19d..4ef4132008e 100644 --- a/tests/mir-opt/equal_true.opt.InstCombine.diff +++ b/tests/mir-opt/equal_true.opt.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `opt` before InstCombine -+ // MIR for `opt` after InstCombine +- // MIR for `opt` before InstSimplify ++ // MIR for `opt` after InstSimplify fn opt(_1: bool) -> i32 { debug x => _1; // in scope 0 at $DIR/equal_true.rs:+0:8: +0:9 diff --git a/tests/mir-opt/equal_true.rs b/tests/mir-opt/equal_true.rs index 717d10c6d76..fbb5d8d37db 100644 --- a/tests/mir-opt/equal_true.rs +++ b/tests/mir-opt/equal_true.rs @@ -1,6 +1,6 @@ -// unit-test InstCombine +// unit-test InstSimplify -// EMIT_MIR equal_true.opt.InstCombine.diff +// EMIT_MIR equal_true.opt.InstSimplify.diff fn opt(x: bool) -> i32 { if x == true { 0 } else { 1 } diff --git a/tests/mir-opt/instcombine_duplicate_switch_targets.assert_zero.InstCombine.diff b/tests/mir-opt/instsimplify_duplicate_switch_targets.assert_zero.InstSimplify.diff index e04079453d2..04ba8dd8e4d 100644 --- a/tests/mir-opt/instcombine_duplicate_switch_targets.assert_zero.InstCombine.diff +++ b/tests/mir-opt/instsimplify_duplicate_switch_targets.assert_zero.InstSimplify.diff @@ -1,21 +1,21 @@ -- // MIR for `assert_zero` before InstCombine -+ // MIR for `assert_zero` after InstCombine +- // MIR for `assert_zero` before InstSimplify ++ // MIR for `assert_zero` after InstSimplify fn assert_zero(_1: u8) -> u8 { - let mut _0: u8; // return place in scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+0:37: +0:39 + let mut _0: u8; // return place in scope 0 at $DIR/instsimplify_duplicate_switch_targets.rs:+0:37: +0:39 bb0: { -- switchInt(_1) -> [0: bb2, 1: bb1, otherwise: bb1]; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+3:13: +7:14 -+ switchInt(_1) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+3:13: +7:14 +- switchInt(_1) -> [0: bb2, 1: bb1, otherwise: bb1]; // scope 0 at $DIR/instsimplify_duplicate_switch_targets.rs:+3:13: +7:14 ++ switchInt(_1) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/instsimplify_duplicate_switch_targets.rs:+3:13: +7:14 } bb1: { - unreachable; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+10:13: +10:26 + unreachable; // scope 0 at $DIR/instsimplify_duplicate_switch_targets.rs:+10:13: +10:26 } bb2: { - _0 = _1; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+13:13: +13:20 - return; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+14:13: +14:21 + _0 = _1; // scope 0 at $DIR/instsimplify_duplicate_switch_targets.rs:+13:13: +13:20 + return; // scope 0 at $DIR/instsimplify_duplicate_switch_targets.rs:+14:13: +14:21 } } diff --git a/tests/mir-opt/instcombine_duplicate_switch_targets.rs b/tests/mir-opt/instsimplify_duplicate_switch_targets.rs index ef3b487afa3..3e280a40fda 100644 --- a/tests/mir-opt/instcombine_duplicate_switch_targets.rs +++ b/tests/mir-opt/instsimplify_duplicate_switch_targets.rs @@ -3,9 +3,9 @@ use std::intrinsics::mir::*; -// unit-test: InstCombine +// unit-test: InstSimplify -// EMIT_MIR instcombine_duplicate_switch_targets.assert_zero.InstCombine.diff +// EMIT_MIR instsimplify_duplicate_switch_targets.assert_zero.InstSimplify.diff #[custom_mir(dialect = "runtime", phase = "post-cleanup")] pub unsafe fn assert_zero(x: u8) -> u8 { mir!( diff --git a/tests/mir-opt/intrinsic_asserts.generic.InstCombine.diff b/tests/mir-opt/intrinsic_asserts.generic.InstSimplify.diff index 09fc145e734..a59f4a43aed 100644 --- a/tests/mir-opt/intrinsic_asserts.generic.InstCombine.diff +++ b/tests/mir-opt/intrinsic_asserts.generic.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `generic` before InstCombine -+ // MIR for `generic` after InstCombine +- // MIR for `generic` before InstSimplify ++ // MIR for `generic` after InstSimplify fn generic() -> () { let mut _0: (); // return place in scope 0 at $DIR/intrinsic_asserts.rs:+0:21: +0:21 diff --git a/tests/mir-opt/intrinsic_asserts.panics.InstCombine.diff b/tests/mir-opt/intrinsic_asserts.panics.InstSimplify.diff index c52174ef5ea..195e8bd4eae 100644 --- a/tests/mir-opt/intrinsic_asserts.panics.InstCombine.diff +++ b/tests/mir-opt/intrinsic_asserts.panics.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `panics` before InstCombine -+ // MIR for `panics` after InstCombine +- // MIR for `panics` before InstSimplify ++ // MIR for `panics` after InstSimplify fn panics() -> () { let mut _0: (); // return place in scope 0 at $DIR/intrinsic_asserts.rs:+0:17: +0:17 diff --git a/tests/mir-opt/intrinsic_asserts.removable.InstCombine.diff b/tests/mir-opt/intrinsic_asserts.removable.InstSimplify.diff index d059d47ee58..a4a65074caa 100644 --- a/tests/mir-opt/intrinsic_asserts.removable.InstCombine.diff +++ b/tests/mir-opt/intrinsic_asserts.removable.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `removable` before InstCombine -+ // MIR for `removable` after InstCombine +- // MIR for `removable` before InstSimplify ++ // MIR for `removable` after InstSimplify fn removable() -> () { let mut _0: (); // return place in scope 0 at $DIR/intrinsic_asserts.rs:+0:20: +0:20 diff --git a/tests/mir-opt/intrinsic_asserts.rs b/tests/mir-opt/intrinsic_asserts.rs index 8fb99cdf6e0..302d4bda188 100644 --- a/tests/mir-opt/intrinsic_asserts.rs +++ b/tests/mir-opt/intrinsic_asserts.rs @@ -2,7 +2,7 @@ #![feature(core_intrinsics)] // All these assertions pass, so all the intrinsic calls should be deleted. -// EMIT_MIR intrinsic_asserts.removable.InstCombine.diff +// EMIT_MIR intrinsic_asserts.removable.InstSimplify.diff pub fn removable() { core::intrinsics::assert_inhabited::<()>(); core::intrinsics::assert_zero_valid::<u8>(); @@ -12,7 +12,7 @@ pub fn removable() { enum Never {} // These assertions all diverge, so their target blocks should become None. -// EMIT_MIR intrinsic_asserts.panics.InstCombine.diff +// EMIT_MIR intrinsic_asserts.panics.InstSimplify.diff pub fn panics() { core::intrinsics::assert_inhabited::<Never>(); core::intrinsics::assert_zero_valid::<&u8>(); @@ -20,7 +20,7 @@ pub fn panics() { } // Whether or not these asserts pass isn't known, so they shouldn't be modified. -// EMIT_MIR intrinsic_asserts.generic.InstCombine.diff +// EMIT_MIR intrinsic_asserts.generic.InstSimplify.diff pub fn generic<T>() { core::intrinsics::assert_inhabited::<T>(); core::intrinsics::assert_zero_valid::<T>(); diff --git a/tests/mir-opt/issue_78192.f.InstCombine.diff b/tests/mir-opt/issue_78192.f.InstSimplify.diff index 116ca304c99..914d7ceb29a 100644 --- a/tests/mir-opt/issue_78192.f.InstCombine.diff +++ b/tests/mir-opt/issue_78192.f.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `f` before InstCombine -+ // MIR for `f` after InstCombine +- // MIR for `f` before InstSimplify ++ // MIR for `f` after InstSimplify fn f(_1: &T) -> *const T { debug a => _1; // in scope 0 at $DIR/issue_78192.rs:+0:13: +0:14 diff --git a/tests/mir-opt/issue_78192.rs b/tests/mir-opt/issue_78192.rs index 39f665402b0..95142a3e463 100644 --- a/tests/mir-opt/issue_78192.rs +++ b/tests/mir-opt/issue_78192.rs @@ -8,4 +8,4 @@ fn main() { f(&2); } -// EMIT_MIR issue_78192.f.InstCombine.diff +// EMIT_MIR issue_78192.f.InstSimplify.diff diff --git a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff index 93863fca344..b022e2ba42b 100644 --- a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff @@ -24,7 +24,7 @@ _4 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:55: +2:56 - _3 = option_payload_ptr::<usize>(move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:132:18: 132:54 +- // + span: $DIR/lower_intrinsics.rs:137:18: 137:54 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Option<usize>) -> *const usize {option_payload_ptr::<usize>}, val: Value(<ZST>) } + _3 = &raw const (((*_4) as Some).0: usize); // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 + goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 @@ -37,7 +37,7 @@ _6 = &raw const (*_2); // scope 2 at $DIR/lower_intrinsics.rs:+3:55: +3:56 - _5 = option_payload_ptr::<String>(move _6) -> [return: bb2, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:133:18: 133:54 +- // + span: $DIR/lower_intrinsics.rs:138:18: 138:54 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Option<String>) -> *const String {option_payload_ptr::<String>}, val: Value(<ZST>) } + _5 = &raw const (((*_6) as Some).0: std::string::String); // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 + goto -> bb2; // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 diff --git a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff index 37f1995a53a..60a1dd0ba7d 100644 --- a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff @@ -15,7 +15,7 @@ _4 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:33: +1:34 - _0 = offset::<*const i32, isize>(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:139:5: 139:29 +- // + span: $DIR/lower_intrinsics.rs:144:5: 144:29 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, isize) -> *const i32 {offset::<*const i32, isize>}, val: Value(<ZST>) } + _0 = Offset(move _3, move _4); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs index 2b1e67be2a9..0ca88a42e3f 100644 --- a/tests/mir-opt/lower_intrinsics.rs +++ b/tests/mir-opt/lower_intrinsics.rs @@ -124,6 +124,11 @@ pub fn read_via_copy_uninhabited(r: &Never) -> Never { unsafe { core::intrinsics::read_via_copy(r) } } +// EMIT_MIR lower_intrinsics.write_via_move_string.LowerIntrinsics.diff +pub fn write_via_move_string(r: &mut String, v: String) { + unsafe { core::intrinsics::write_via_move(r, v) } +} + pub enum Never {} // EMIT_MIR lower_intrinsics.option_payload.LowerIntrinsics.diff diff --git a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff new file mode 100644 index 00000000000..38d99f661dc --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff @@ -0,0 +1,36 @@ +- // MIR for `write_via_move_string` before LowerIntrinsics ++ // MIR for `write_via_move_string` after LowerIntrinsics + + fn write_via_move_string(_1: &mut String, _2: String) -> () { + debug r => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:30: +0:31 + debug v => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:46: +0:47 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:57: +0:57 + let mut _3: *mut std::string::String; // in scope 0 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + let mut _4: std::string::String; // in scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + scope 1 { + } + + bb0: { + StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + _3 = &raw mut (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + StorageLive(_4); // scope 1 at $DIR/lower_intrinsics.rs:+1:50: +1:51 + _4 = move _2; // scope 1 at $DIR/lower_intrinsics.rs:+1:50: +1:51 +- _0 = write_via_move::<String>(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:129:14: 129:46 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*mut String, String) {write_via_move::<String>}, val: Value(<ZST>) } ++ (*_3) = move _4; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/lower_intrinsics.rs:+1:51: +1:52 + StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:51: +1:52 + goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:1: +2:2 + } + + bb2: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/not_equal_false.opt.InstCombine.diff b/tests/mir-opt/not_equal_false.opt.InstSimplify.diff index b558c35ac1e..8e7776a0bbc 100644 --- a/tests/mir-opt/not_equal_false.opt.InstCombine.diff +++ b/tests/mir-opt/not_equal_false.opt.InstSimplify.diff @@ -1,5 +1,5 @@ -- // MIR for `opt` before InstCombine -+ // MIR for `opt` after InstCombine +- // MIR for `opt` before InstSimplify ++ // MIR for `opt` after InstSimplify fn opt(_1: bool) -> u32 { debug x => _1; // in scope 0 at $DIR/not_equal_false.rs:+0:8: +0:9 diff --git a/tests/mir-opt/not_equal_false.rs b/tests/mir-opt/not_equal_false.rs index 2ae03da40f8..e0560732900 100644 --- a/tests/mir-opt/not_equal_false.rs +++ b/tests/mir-opt/not_equal_false.rs @@ -1,5 +1,5 @@ -// unit-test: InstCombine -// EMIT_MIR not_equal_false.opt.InstCombine.diff +// unit-test: InstSimplify +// EMIT_MIR not_equal_false.opt.InstSimplify.diff fn opt(x: bool) -> u32 { if x != false { 0 } else { 1 } diff --git a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir new file mode 100644 index 00000000000..2b4971e2ef9 --- /dev/null +++ b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir @@ -0,0 +1,16 @@ +// MIR for `manual_replace` after PreCodegen + +fn manual_replace(_1: &mut u32, _2: u32) -> u32 { + debug r => _1; // in scope 0 at $DIR/mem_replace.rs:+0:23: +0:24 + debug v => _2; // in scope 0 at $DIR/mem_replace.rs:+0:36: +0:37 + let mut _0: u32; // return place in scope 0 at $DIR/mem_replace.rs:+1:9: +1:13 + scope 1 { + debug temp => _0; // in scope 1 at $DIR/mem_replace.rs:+1:9: +1:13 + } + + bb0: { + _0 = (*_1); // scope 0 at $DIR/mem_replace.rs:+1:16: +1:18 + (*_1) = _2; // scope 1 at $DIR/mem_replace.rs:+2:5: +2:11 + return; // scope 0 at $DIR/mem_replace.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir new file mode 100644 index 00000000000..50e0538c133 --- /dev/null +++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir @@ -0,0 +1,53 @@ +// MIR for `mem_replace` after PreCodegen + +fn mem_replace(_1: &mut u32, _2: u32) -> u32 { + debug r => _1; // in scope 0 at $DIR/mem_replace.rs:+0:20: +0:21 + debug v => _2; // in scope 0 at $DIR/mem_replace.rs:+0:33: +0:34 + let mut _0: u32; // return place in scope 0 at $DIR/mem_replace.rs:+0:44: +0:47 + scope 1 (inlined std::mem::replace::<u32>) { // at $DIR/mem_replace.rs:16:5: 16:28 + debug dest => _1; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + debug src => _2; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + let mut _3: *const u32; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + let mut _4: *mut u32; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + scope 2 { + scope 3 { + debug result => _0; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + scope 7 (inlined std::ptr::write::<u32>) { // at $SRC_DIR/core/src/mem/mod.rs:LL:COL + debug dst => _4; // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug src => _2; // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + let mut _6: *mut u32; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 8 { + scope 9 (inlined std::ptr::write::runtime::<u32>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug dst => _6; // in scope 9 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 4 (inlined std::ptr::read::<u32>) { // at $SRC_DIR/core/src/mem/mod.rs:LL:COL + debug src => _3; // in scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + let mut _5: *const u32; // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 5 { + scope 6 (inlined std::ptr::read::runtime::<u32>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug src => _5; // in scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + } + + bb0: { + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + _3 = &raw const (*_1); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + _0 = (*_3); // scope 5 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageLive(_4); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + _4 = &raw mut (*_1); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageLive(_6); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + (*_4) = _2; // scope 8 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_6); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageDead(_4); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + return; // scope 0 at $DIR/mem_replace.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/mem_replace.rs b/tests/mir-opt/pre-codegen/mem_replace.rs new file mode 100644 index 00000000000..e5066c38b96 --- /dev/null +++ b/tests/mir-opt/pre-codegen/mem_replace.rs @@ -0,0 +1,17 @@ +// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 +// only-64bit +// ignore-debug + +#![crate_type = "lib"] + +// EMIT_MIR mem_replace.manual_replace.PreCodegen.after.mir +pub fn manual_replace(r: &mut u32, v: u32) -> u32 { + let temp = *r; + *r = v; + temp +} + +// EMIT_MIR mem_replace.mem_replace.PreCodegen.after.mir +pub fn mem_replace(r: &mut u32, v: u32) -> u32 { + std::mem::replace(r, v) +} diff --git a/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir b/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir deleted file mode 100644 index 15b0aece8f5..00000000000 --- a/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir +++ /dev/null @@ -1,17 +0,0 @@ -// MIR for `change_loop_body` after PreCodegen - -fn change_loop_body() -> () { - let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27 - let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 - scope 1 { - debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15 - scope 2 { - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 - StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2 - return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2 - } -} diff --git a/tests/pretty/tests-are-sorted.pp b/tests/pretty/tests-are-sorted.pp index 58f746f2e0e..7d7f682130d 100644 --- a/tests/pretty/tests-are-sorted.pp +++ b/tests/pretty/tests-are-sorted.pp @@ -79,6 +79,7 @@ pub const a_test: test::TestDescAndFn = }; fn a_test() {} #[rustc_main] +#[no_coverage] pub fn main() -> () { extern crate test; test::test_main_static(&[&a_test, &m_test, &z_test]) diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 8dac53c2a62..7db100a08a1 100644 --- a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -67,7 +67,7 @@ impl CodegenBackend for TheBackend { let crate_name = codegen_results.crate_info.local_crate_name; for &crate_type in sess.opts.crate_types.iter() { if crate_type != CrateType::Rlib { - sess.fatal(&format!("Crate type is {:?}", crate_type)); + sess.fatal(format!("Crate type is {:?}", crate_type)); } let output_name = out_filename(sess, crate_type, &outputs, crate_name); let mut out_file = ::std::fs::File::create(output_name).unwrap(); diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile index 9c41a5a717e..b8e0e9483cd 100644 --- a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile +++ b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile @@ -1,4 +1,5 @@ # ignore-cross-compile +# needs-unwind include ../tools.mk all: archive diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/main.rs b/tests/run-make/c-unwind-abi-catch-lib-panic/main.rs index 78a71219c78..42d3efa82d6 100644 --- a/tests/run-make/c-unwind-abi-catch-lib-panic/main.rs +++ b/tests/run-make/c-unwind-abi-catch-lib-panic/main.rs @@ -2,7 +2,6 @@ //! //! This test triggers a panic in a Rust library that our foreign function invokes. This shows //! that we can unwind through the C code in that library, and catch the underlying panic. -#![feature(c_unwind)] use std::panic::{catch_unwind, AssertUnwindSafe}; diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/panic.rs b/tests/run-make/c-unwind-abi-catch-lib-panic/panic.rs index a99a04d5c6f..9e7bc3e53a1 100644 --- a/tests/run-make/c-unwind-abi-catch-lib-panic/panic.rs +++ b/tests/run-make/c-unwind-abi-catch-lib-panic/panic.rs @@ -1,5 +1,4 @@ #![crate_type = "staticlib"] -#![feature(c_unwind)] /// This function will panic if `x` is greater than 10. /// diff --git a/tests/run-make/c-unwind-abi-catch-panic/Makefile b/tests/run-make/c-unwind-abi-catch-panic/Makefile index 4398ac2ee24..1760ddb3061 100644 --- a/tests/run-make/c-unwind-abi-catch-panic/Makefile +++ b/tests/run-make/c-unwind-abi-catch-panic/Makefile @@ -1,4 +1,5 @@ # ignore-cross-compile +# needs-unwind include ../tools.mk all: $(call NATIVE_STATICLIB,add) diff --git a/tests/run-make/c-unwind-abi-catch-panic/main.rs b/tests/run-make/c-unwind-abi-catch-panic/main.rs index 15d38d72160..1903be9561c 100644 --- a/tests/run-make/c-unwind-abi-catch-panic/main.rs +++ b/tests/run-make/c-unwind-abi-catch-panic/main.rs @@ -1,7 +1,6 @@ //! A test for calling `C-unwind` functions across foreign function boundaries. //! //! This test triggers a panic when calling a foreign function that calls *back* into Rust. -#![feature(c_unwind)] use std::panic::{catch_unwind, AssertUnwindSafe}; diff --git a/tests/run-make/const_fn_mir/Makefile b/tests/run-make/const_fn_mir/Makefile index b2c268f0439..6d72c122723 100644 --- a/tests/run-make/const_fn_mir/Makefile +++ b/tests/run-make/const_fn_mir/Makefile @@ -1,3 +1,4 @@ +# needs-unwind -Cpanic=abort gives different MIR output include ../tools.mk all: diff --git a/tests/run-make/coverage-reports/expected_show_coverage.test_harness.txt b/tests/run-make/coverage-reports/expected_show_coverage.test_harness.txt new file mode 100644 index 00000000000..93bd1cfcb48 --- /dev/null +++ b/tests/run-make/coverage-reports/expected_show_coverage.test_harness.txt @@ -0,0 +1,11 @@ + 1| |// Verify that the entry point injected by the test harness doesn't cause + 2| |// weird artifacts in the coverage report (e.g. issue #10749). + 3| | + 4| |// compile-flags: --test + 5| | + 6| |#[allow(dead_code)] + 7| 0|fn unused() {} + 8| | + 9| 1|#[test] + 10| 1|fn my_test() {} + diff --git a/tests/run-make/coverage/test_harness.rs b/tests/run-make/coverage/test_harness.rs new file mode 100644 index 00000000000..12a755734c1 --- /dev/null +++ b/tests/run-make/coverage/test_harness.rs @@ -0,0 +1,10 @@ +// Verify that the entry point injected by the test harness doesn't cause +// weird artifacts in the coverage report (e.g. issue #10749). + +// compile-flags: --test + +#[allow(dead_code)] +fn unused() {} + +#[test] +fn my_test() {} diff --git a/tests/run-make/debug-assertions/Makefile b/tests/run-make/debug-assertions/Makefile index e83337c597f..4501459e9d1 100644 --- a/tests/run-make/debug-assertions/Makefile +++ b/tests/run-make/debug-assertions/Makefile @@ -1,4 +1,5 @@ # ignore-cross-compile +# needs-unwind include ../tools.mk all: diff --git a/tests/run-make/foreign-double-unwind/Makefile b/tests/run-make/foreign-double-unwind/Makefile index f20fe3ce66e..b5e52808d2f 100644 --- a/tests/run-make/foreign-double-unwind/Makefile +++ b/tests/run-make/foreign-double-unwind/Makefile @@ -1,4 +1,5 @@ # ignore-cross-compile +# needs-unwind include ../tools.mk all: foo diff --git a/tests/run-make/foreign-double-unwind/foo.rs b/tests/run-make/foreign-double-unwind/foo.rs index cae8aa9402d..c085480b4f8 100644 --- a/tests/run-make/foreign-double-unwind/foo.rs +++ b/tests/run-make/foreign-double-unwind/foo.rs @@ -1,8 +1,6 @@ // Tests that C++ double unwinding through Rust code will be properly guarded // against instead of exhibiting undefined behaviour. -#![feature(c_unwind)] - extern "C-unwind" { fn throw_cxx_exception(); fn cxx_catch_callback(cb: extern "C-unwind" fn()); diff --git a/tests/run-make/foreign-exceptions/Makefile b/tests/run-make/foreign-exceptions/Makefile index a8e20ffb1f4..56c41b274fb 100644 --- a/tests/run-make/foreign-exceptions/Makefile +++ b/tests/run-make/foreign-exceptions/Makefile @@ -1,4 +1,5 @@ # ignore-cross-compile +# needs-unwind include ../tools.mk all: foo diff --git a/tests/run-make/foreign-exceptions/foo.rs b/tests/run-make/foreign-exceptions/foo.rs index dd3b7c76f28..ccf858d8587 100644 --- a/tests/run-make/foreign-exceptions/foo.rs +++ b/tests/run-make/foreign-exceptions/foo.rs @@ -2,8 +2,6 @@ // are caught by catch_unwind. Also tests that Rust panics can unwind through // C++ code. -#![feature(c_unwind)] - use std::panic::{catch_unwind, AssertUnwindSafe}; struct DropCheck<'a>(&'a mut bool); diff --git a/tests/run-make/foreign-rust-exceptions/Makefile b/tests/run-make/foreign-rust-exceptions/Makefile index 0d007bf1c49..59cee284200 100644 --- a/tests/run-make/foreign-rust-exceptions/Makefile +++ b/tests/run-make/foreign-rust-exceptions/Makefile @@ -1,5 +1,6 @@ # ignore-cross-compile # ignore-i686-pc-windows-gnu +# needs-unwind # This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder # so cross-DLL unwinding does not work. diff --git a/tests/run-make/foreign-rust-exceptions/bar.rs b/tests/run-make/foreign-rust-exceptions/bar.rs index 5f9efe32360..1d865b429fa 100644 --- a/tests/run-make/foreign-rust-exceptions/bar.rs +++ b/tests/run-make/foreign-rust-exceptions/bar.rs @@ -1,5 +1,4 @@ #![crate_type = "cdylib"] -#![feature(c_unwind)] #[no_mangle] extern "C-unwind" fn panic() { diff --git a/tests/run-make/foreign-rust-exceptions/foo.rs b/tests/run-make/foreign-rust-exceptions/foo.rs index 266987c5b6d..38942c55b19 100644 --- a/tests/run-make/foreign-rust-exceptions/foo.rs +++ b/tests/run-make/foreign-rust-exceptions/foo.rs @@ -1,5 +1,3 @@ -#![feature(c_unwind)] - #[cfg_attr(not(windows), link(name = "bar"))] #[cfg_attr(windows, link(name = "bar.dll"))] extern "C-unwind" { diff --git a/tests/run-make/issue-109934-lto-debuginfo/Makefile b/tests/run-make/issue-109934-lto-debuginfo/Makefile new file mode 100644 index 00000000000..3b7a99d3dbc --- /dev/null +++ b/tests/run-make/issue-109934-lto-debuginfo/Makefile @@ -0,0 +1,12 @@ +# ignore-cross-compile +include ../tools.mk + +# With the upgrade to LLVM 16, this was getting: +# +# error: Cannot represent a difference across sections +# +# The error stemmed from DI function definitions under type scopes, fixed by +# only declaring in type scope and defining the subprogram elsewhere. + +all: + $(RUSTC) lib.rs --test -C lto=fat -C debuginfo=2 -C incremental=$(TMPDIR)/inc-fat diff --git a/tests/run-make/issue-109934-lto-debuginfo/lib.rs b/tests/run-make/issue-109934-lto-debuginfo/lib.rs new file mode 100644 index 00000000000..c405928bd18 --- /dev/null +++ b/tests/run-make/issue-109934-lto-debuginfo/lib.rs @@ -0,0 +1,9 @@ +extern crate alloc; + +#[cfg(test)] +mod tests { + #[test] + fn something_alloc() { + assert_eq!(Vec::<u32>::new(), Vec::<u32>::new()); + } +} diff --git a/tests/run-make/libtest-json/Makefile b/tests/run-make/libtest-json/Makefile index 417637cf072..c8bc7b5dd4a 100644 --- a/tests/run-make/libtest-json/Makefile +++ b/tests/run-make/libtest-json/Makefile @@ -1,4 +1,5 @@ # ignore-cross-compile +# needs-unwind include ../tools.mk # Test expected libtest's JSON output diff --git a/tests/run-make/libtest-junit/Makefile b/tests/run-make/libtest-junit/Makefile new file mode 100644 index 00000000000..d97cafccf1f --- /dev/null +++ b/tests/run-make/libtest-junit/Makefile @@ -0,0 +1,19 @@ +# ignore-cross-compile +include ../tools.mk + +# Test expected libtest's junit output + +OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-junit-output-default.xml +OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-junit-output-stdout-success.xml + +all: f.rs validate_junit.py output-default.xml output-stdout-success.xml + $(RUSTC) --test f.rs + RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=junit > $(OUTPUT_FILE_DEFAULT) || true + RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=junit --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true + + cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_junit.py + cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_junit.py + + # Normalize the actual output and compare to expected output file + cat $(OUTPUT_FILE_DEFAULT) | sed 's/time="[0-9.]*"/time="$$TIME"/g' | diff output-default.xml - + cat $(OUTPUT_FILE_STDOUT_SUCCESS) | sed 's/time="[0-9.]*"/time="$$TIME"/g' | diff output-stdout-success.xml - diff --git a/tests/run-make/libtest-junit/f.rs b/tests/run-make/libtest-junit/f.rs new file mode 100644 index 00000000000..d360d77317d --- /dev/null +++ b/tests/run-make/libtest-junit/f.rs @@ -0,0 +1,23 @@ +#[test] +fn a() { + println!("print from successful test"); + // Should pass +} + +#[test] +fn b() { + println!("print from failing test"); + assert!(false); +} + +#[test] +#[should_panic] +fn c() { + assert!(false); +} + +#[test] +#[ignore = "msg"] +fn d() { + assert!(false); +} diff --git a/tests/run-make/libtest-junit/output-default.xml b/tests/run-make/libtest-junit/output-default.xml new file mode 100644 index 00000000000..d59e07b8ad8 --- /dev/null +++ b/tests/run-make/libtest-junit/output-default.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="1" tests="4" skipped="1" ><testcase classname="unknown" name="a" time="$TIME"/><testcase classname="unknown" name="b" time="$TIME"><failure type="assert"/><system-out><![CDATA[print from failing test]]>
<![CDATA[thread 'b' panicked at 'assertion failed: false', f.rs:10:5]]>
<![CDATA[note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace]]>
<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="c" time="$TIME"/><system-out/><system-err/></testsuite></testsuites> diff --git a/tests/run-make/libtest-junit/output-stdout-success.xml b/tests/run-make/libtest-junit/output-stdout-success.xml new file mode 100644 index 00000000000..0c300611e1f --- /dev/null +++ b/tests/run-make/libtest-junit/output-stdout-success.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="1" tests="4" skipped="1" ><testcase classname="unknown" name="a" time="$TIME"><system-out><![CDATA[print from successful test]]>
<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="b" time="$TIME"><failure type="assert"/><system-out><![CDATA[print from failing test]]>
<![CDATA[thread 'b' panicked at 'assertion failed: false', f.rs:10:5]]>
<![CDATA[note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace]]>
<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="c" time="$TIME"><system-out><![CDATA[thread 'c' panicked at 'assertion failed: false', f.rs:16:5]]>
<![CDATA[]]></system-out></testcase><system-out/><system-err/></testsuite></testsuites> diff --git a/tests/run-make/libtest-junit/validate_junit.py b/tests/run-make/libtest-junit/validate_junit.py new file mode 100755 index 00000000000..47a8e70ccc3 --- /dev/null +++ b/tests/run-make/libtest-junit/validate_junit.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import sys +import xml.etree.ElementTree as ET + +# Try to decode line in order to ensure it is a valid XML document +for line in sys.stdin: + try: + ET.fromstring(line) + except ET.ParseError as pe: + print("Invalid xml: %r" % line) + raise diff --git a/tests/run-make/raw-dylib-alt-calling-convention/lib.rs b/tests/run-make/raw-dylib-alt-calling-convention/lib.rs index 22f222c12c3..dcb5fee9ecc 100644 --- a/tests/run-make/raw-dylib-alt-calling-convention/lib.rs +++ b/tests/run-make/raw-dylib-alt-calling-convention/lib.rs @@ -1,5 +1,4 @@ #![feature(abi_vectorcall)] -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] #[repr(C)] #[derive(Clone)] diff --git a/tests/run-make/raw-dylib-c/lib.rs b/tests/run-make/raw-dylib-c/lib.rs index 5fb1204037c..f17125f308c 100644 --- a/tests/run-make/raw-dylib-c/lib.rs +++ b/tests/run-make/raw-dylib-c/lib.rs @@ -1,5 +1,3 @@ -#![feature(raw_dylib)] - #[link(name = "extern_1.dll", kind = "raw-dylib", modifiers = "+verbatim")] extern { fn extern_fn_1(); diff --git a/tests/run-make/raw-dylib-cross-compilation/lib.rs b/tests/run-make/raw-dylib-cross-compilation/lib.rs index 51bf2ec6b6e..3338ac0a0b5 100644 --- a/tests/run-make/raw-dylib-cross-compilation/lib.rs +++ b/tests/run-make/raw-dylib-cross-compilation/lib.rs @@ -1,4 +1,3 @@ -#![feature(raw_dylib)] #![feature(no_core, lang_items)] #![no_std] #![no_core] diff --git a/tests/run-make/raw-dylib-custom-dlltool/Makefile b/tests/run-make/raw-dylib-custom-dlltool/Makefile new file mode 100644 index 00000000000..f5d5360a3fb --- /dev/null +++ b/tests/run-make/raw-dylib-custom-dlltool/Makefile @@ -0,0 +1,11 @@ +# Test using -Cdlltool to change where raw-dylib looks for the dlltool binary. + +# only-windows +# only-gnu +# needs-dlltool + +include ../tools.mk + +all: + $(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs -Cdlltool=$(CURDIR)/script.cmd + $(DIFF) output.txt "$(TMPDIR)"/output.txt diff --git a/tests/run-make/raw-dylib-custom-dlltool/lib.rs b/tests/run-make/raw-dylib-custom-dlltool/lib.rs new file mode 100644 index 00000000000..2f3f497a00d --- /dev/null +++ b/tests/run-make/raw-dylib-custom-dlltool/lib.rs @@ -0,0 +1,10 @@ +#[link(name = "extern_1", kind = "raw-dylib")] +extern { + fn extern_fn_1(); +} + +pub fn library_function() { + unsafe { + extern_fn_1(); + } +} diff --git a/tests/run-make/raw-dylib-custom-dlltool/output.txt b/tests/run-make/raw-dylib-custom-dlltool/output.txt new file mode 100644 index 00000000000..6dd9466d26d --- /dev/null +++ b/tests/run-make/raw-dylib-custom-dlltool/output.txt @@ -0,0 +1 @@ +Called dlltool via script.cmd diff --git a/tests/run-make/raw-dylib-custom-dlltool/script.cmd b/tests/run-make/raw-dylib-custom-dlltool/script.cmd new file mode 100644 index 00000000000..95f85c61c67 --- /dev/null +++ b/tests/run-make/raw-dylib-custom-dlltool/script.cmd @@ -0,0 +1,2 @@ +echo Called dlltool via script.cmd> %TMPDIR%\output.txt +dlltool.exe %* diff --git a/tests/run-make/raw-dylib-import-name-type/driver.rs b/tests/run-make/raw-dylib-import-name-type/driver.rs index 9a3cd9ebe1b..6c1c212f187 100644 --- a/tests/run-make/raw-dylib-import-name-type/driver.rs +++ b/tests/run-make/raw-dylib-import-name-type/driver.rs @@ -1,4 +1,3 @@ -#![feature(raw_dylib)] #![feature(abi_vectorcall)] #[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")] diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs b/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs index f72ded7d9f6..0c3125be6f5 100644 --- a/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs +++ b/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs @@ -1,5 +1,3 @@ -#![feature(raw_dylib)] - extern crate raw_dylib_test; extern crate raw_dylib_test_wrapper; diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs b/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs index 00c2c1c42d1..4877cb80aea 100644 --- a/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs +++ b/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs @@ -1,5 +1,3 @@ -#![feature(raw_dylib)] - #[link(name = "extern_1", kind = "raw-dylib")] extern { fn extern_fn_1(); diff --git a/tests/run-make/raw-dylib-link-ordinal/lib.rs b/tests/run-make/raw-dylib-link-ordinal/lib.rs index bb25ac64c61..1bbb45bbc77 100644 --- a/tests/run-make/raw-dylib-link-ordinal/lib.rs +++ b/tests/run-make/raw-dylib-link-ordinal/lib.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "exporter", kind = "raw-dylib")] extern { #[link_ordinal(13)] diff --git a/tests/run-make/raw-dylib-stdcall-ordinal/lib.rs b/tests/run-make/raw-dylib-stdcall-ordinal/lib.rs index b7921396a0f..74c5c7f8250 100644 --- a/tests/run-make/raw-dylib-stdcall-ordinal/lib.rs +++ b/tests/run-make/raw-dylib-stdcall-ordinal/lib.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "exporter", kind = "raw-dylib")] extern "stdcall" { #[link_ordinal(15)] diff --git a/tests/run-make/static-unwinding/Makefile b/tests/run-make/static-unwinding/Makefile index dec94fb16f4..4b093f93608 100644 --- a/tests/run-make/static-unwinding/Makefile +++ b/tests/run-make/static-unwinding/Makefile @@ -1,4 +1,5 @@ # ignore-cross-compile +# needs-unwind include ../tools.mk all: diff --git a/tests/run-make/test-benches/Makefile b/tests/run-make/test-benches/Makefile index 0253a52637f..11aed2e4c79 100644 --- a/tests/run-make/test-benches/Makefile +++ b/tests/run-make/test-benches/Makefile @@ -1,6 +1,7 @@ include ../tools.mk # ignore-cross-compile +# needs-unwind #[bench] and -Zpanic-abort-tests can't be combined all: # Smoke-test that `#[bench]` isn't entirely broken. diff --git a/tests/rustdoc-gui/search-corrections.goml b/tests/rustdoc-gui/search-corrections.goml new file mode 100644 index 00000000000..5d1b83b35c5 --- /dev/null +++ b/tests/rustdoc-gui/search-corrections.goml @@ -0,0 +1,56 @@ +// ignore-tidy-linelength + +// Checks that the search tab result tell the user about corrections +// First, try a search-by-name +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +// Intentionally wrong spelling of "NotableStructWithLongName" +write: (".search-input", "NotableStructWithLongNamr") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#search-tabs" + +// Corrections aren't shown on the "In Names" tab. +assert: "#search-tabs button.selected:first-child" +assert-css: (".search-corrections", { + "display": "none" +}) + +// Corrections do get shown on the "In Parameters" tab. +click: "#search-tabs button:nth-child(2)" +assert: "#search-tabs button.selected:nth-child(2)" +assert-css: (".search-corrections", { + "display": "block" +}) +assert-text: ( + ".search-corrections", + "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." +) + +// Corrections do get shown on the "In Return Type" tab. +click: "#search-tabs button:nth-child(3)" +assert: "#search-tabs button.selected:nth-child(3)" +assert-css: (".search-corrections", { + "display": "block" +}) +assert-text: ( + ".search-corrections", + "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." +) + +// Now, explicit return values +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +// Intentionally wrong spelling of "NotableStructWithLongName" +write: (".search-input", "-> NotableStructWithLongNamr") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#search-tabs" + +assert-css: (".search-corrections", { + "display": "block" +}) +assert-text: ( + ".search-corrections", + "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." +) diff --git a/tests/rustdoc-js/generics-trait.js b/tests/rustdoc-js/generics-trait.js index 7876622435b..0e84751603e 100644 --- a/tests/rustdoc-js/generics-trait.js +++ b/tests/rustdoc-js/generics-trait.js @@ -1,9 +1,21 @@ +// exact-check + const QUERY = [ 'Result<SomeTrait>', + 'Result<SomeTraiz>', + 'OtherThingxxxxxxxx', + 'OtherThingxxxxxxxy', +]; + +const CORRECTIONS = [ + null, + null, + null, 'OtherThingxxxxxxxx', ]; const EXPECTED = [ + // Result<SomeTrait> { 'in_args': [ { 'path': 'generics_trait', 'name': 'beta' }, @@ -12,6 +24,21 @@ const EXPECTED = [ { 'path': 'generics_trait', 'name': 'bet' }, ], }, + // Result<SomeTraiz> + { + 'in_args': [], + 'returned': [], + }, + // OtherThingxxxxxxxx + { + 'in_args': [ + { 'path': 'generics_trait', 'name': 'alpha' }, + ], + 'returned': [ + { 'path': 'generics_trait', 'name': 'alef' }, + ], + }, + // OtherThingxxxxxxxy { 'in_args': [ { 'path': 'generics_trait', 'name': 'alpha' }, diff --git a/tests/rustdoc-js/slice-array.js b/tests/rustdoc-js/slice-array.js new file mode 100644 index 00000000000..8c21e06dc4e --- /dev/null +++ b/tests/rustdoc-js/slice-array.js @@ -0,0 +1,65 @@ +// exact-check + +const QUERY = [ + 'R<primitive:slice<P>>', + 'primitive:slice<R<P>>', + 'R<primitive:slice<Q>>', + 'primitive:slice<R<Q>>', + 'R<primitive:array<Q>>', + 'primitive:array<R<Q>>', + 'primitive:array<TraitCat>', + 'primitive:array<TraitDog>', +]; + +const EXPECTED = [ + { + // R<primitive:slice<P>> + 'returned': [], + 'in_args': [ + { 'path': 'slice_array', 'name': 'alpha' }, + ], + }, + { + // primitive:slice<R<P>> + 'returned': [ + { 'path': 'slice_array', 'name': 'alef' }, + ], + 'in_args': [], + }, + { + // R<primitive:slice<Q>> + 'returned': [], + 'in_args': [], + }, + { + // primitive:slice<R<Q>> + 'returned': [], + 'in_args': [], + }, + { + // R<primitive:array<Q>> + 'returned': [ + { 'path': 'slice_array', 'name': 'bet' }, + ], + 'in_args': [], + }, + { + // primitive:array<R<Q>> + 'returned': [], + 'in_args': [ + { 'path': 'slice_array', 'name': 'beta' }, + ], + }, + { + // primitive::array<TraitCat> + 'in_args': [ + { 'path': 'slice_array', 'name': 'gamma' }, + ], + }, + { + // primitive::array<TraitDog> + 'in_args': [ + { 'path': 'slice_array', 'name': 'gamma' }, + ], + }, +]; diff --git a/tests/rustdoc-js/slice-array.rs b/tests/rustdoc-js/slice-array.rs new file mode 100644 index 00000000000..2523b21cfaa --- /dev/null +++ b/tests/rustdoc-js/slice-array.rs @@ -0,0 +1,16 @@ +pub struct P; +pub struct Q; +pub struct R<T>(T); + +// returns test +pub fn alef() -> &'static [R<P>] { loop {} } +pub fn bet() -> R<[Q; 32]> { loop {} } + +// in_args test +pub fn alpha(_x: R<&'static [P]>) { loop {} } +pub fn beta(_x: [R<Q>; 32]) { loop {} } + +pub trait TraitCat {} +pub trait TraitDog {} + +pub fn gamma<T: TraitCat + TraitDog>(t: [T; 32]) {} diff --git a/tests/rustdoc-json/fn_pointer/abi.rs b/tests/rustdoc-json/fn_pointer/abi.rs index 3c1a453d12d..6a30acc2cc3 100644 --- a/tests/rustdoc-json/fn_pointer/abi.rs +++ b/tests/rustdoc-json/fn_pointer/abi.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength #![feature(abi_vectorcall)] -#![feature(c_unwind)] // @is "$.index[*][?(@.name=='AbiRust')].inner.type.inner.header.abi" \"Rust\" pub type AbiRust = fn(); diff --git a/tests/rustdoc-json/fns/abi.rs b/tests/rustdoc-json/fns/abi.rs index 0e8b78bc0e6..7a5dbee730c 100644 --- a/tests/rustdoc-json/fns/abi.rs +++ b/tests/rustdoc-json/fns/abi.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength #![feature(abi_vectorcall)] -#![feature(c_unwind)] // @is "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\" pub fn abi_rust() {} diff --git a/tests/rustdoc-json/methods/abi.rs b/tests/rustdoc-json/methods/abi.rs index 4c97d97ceba..fd03d92d65b 100644 --- a/tests/rustdoc-json/methods/abi.rs +++ b/tests/rustdoc-json/methods/abi.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength #![feature(abi_vectorcall)] -#![feature(c_unwind)] #![feature(no_core)] #![no_core] diff --git a/tests/rustdoc-ui/check-cfg/check-cfg.stderr b/tests/rustdoc-ui/check-cfg/check-cfg.stderr index 1db8e1d91c2..03fb6f96fb5 100644 --- a/tests/rustdoc-ui/check-cfg/check-cfg.stderr +++ b/tests/rustdoc-ui/check-cfg/check-cfg.stderr @@ -2,7 +2,7 @@ warning: unexpected `cfg` condition name --> $DIR/check-cfg.rs:5:7 | LL | #[cfg(uniz)] - | ^^^^ help: did you mean: `unix` + | ^^^^ help: there is a config with a similar name: `unix` | = note: `#[warn(unexpected_cfgs)]` on by default diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.stderr b/tests/rustdoc-ui/doctest/check-cfg-test.stderr index 9770be2f191..f84543c2072 100644 --- a/tests/rustdoc-ui/doctest/check-cfg-test.stderr +++ b/tests/rustdoc-ui/doctest/check-cfg-test.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value LL | #[cfg(feature = "invalid")] | ^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: test + = note: expected values for `feature` are: `test` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs new file mode 100644 index 00000000000..cc066447d31 --- /dev/null +++ b/tests/rustdoc-ui/ice-bug-report-url.rs @@ -0,0 +1,14 @@ +// compile-flags: -Ztreat-err-as-bug +// failure-status: 101 +// error-pattern: aborting due to +// error-pattern: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md + +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" +// normalize-stderr-test "thread.*panicked at .*, compiler.*" -> "thread panicked at 'aborting due to `-Z treat-err-as-bug`'" +// normalize-stderr-test "\s*\d{1,}: .*\n" -> "" +// normalize-stderr-test "\s at .*\n" -> "" +// normalize-stderr-test ".*note: Some details are omitted.*\n" -> "" + +fn wrong() +//~^ ERROR expected one of diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr new file mode 100644 index 00000000000..cfb73a9b919 --- /dev/null +++ b/tests/rustdoc-ui/ice-bug-report-url.stderr @@ -0,0 +1,16 @@ +error: expected one of `->`, `where`, or `{`, found `<eof>` + --> $DIR/ice-bug-report-url.rs:13:10 + | +LL | fn wrong() + | ^ expected one of `->`, `where`, or `{` + +thread panicked at 'aborting due to `-Z treat-err-as-bug`' +stack backtrace: +error: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md + +note: rustc {version} running on {platform} + +query stack during panic: +end of query stack diff --git a/tests/rustdoc-ui/issues/issue-105742.rs b/tests/rustdoc-ui/issues/issue-105742.rs index 8f4172c0cbb..1fbb70c7808 100644 --- a/tests/rustdoc-ui/issues/issue-105742.rs +++ b/tests/rustdoc-ui/issues/issue-105742.rs @@ -19,6 +19,8 @@ pub trait SVec: Index< //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` Output = <Index<<Self as SVec>::Item, //~^ expected 1 lifetime argument //~| expected 1 generic argument @@ -26,6 +28,8 @@ pub trait SVec: Index< //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` Output = <Self as SVec>::Item> as SVec>::Item, //~^ expected 1 lifetime argument //~| expected 1 generic argument @@ -34,11 +38,15 @@ pub trait SVec: Index< //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` //~| expected 1 generic argument //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` > { type Item<'a, T>; diff --git a/tests/rustdoc-ui/issues/issue-105742.stderr b/tests/rustdoc-ui/issues/issue-105742.stderr index cd53762ef9b..b63176c9149 100644 --- a/tests/rustdoc-ui/issues/issue-105742.stderr +++ b/tests/rustdoc-ui/issues/issue-105742.stderr @@ -5,7 +5,7 @@ LL | <Self as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -21,7 +21,7 @@ LL | <Self as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -31,13 +31,13 @@ LL | <Self as SVec>::Item<T>, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:37 + --> $DIR/issue-105742.rs:24:37 | LL | Output = <Index<<Self as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -47,13 +47,13 @@ LL | Output = <Index<<Self as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:37 + --> $DIR/issue-105742.rs:24:37 | LL | Output = <Index<<Self as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -63,13 +63,13 @@ LL | Output = <Index<<Self as SVec>::Item<T>, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:29:30 + --> $DIR/issue-105742.rs:33:30 | LL | Output = <Self as SVec>::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -79,13 +79,13 @@ LL | Output = <Self as SVec>::Item<'a>> as SVec>::Item, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:29:30 + --> $DIR/issue-105742.rs:33:30 | LL | Output = <Self as SVec>::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -95,13 +95,13 @@ LL | Output = <Self as SVec>::Item<T>> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:29:46 + --> $DIR/issue-105742.rs:33:46 | LL | Output = <Self as SVec>::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -111,13 +111,13 @@ LL | Output = <Self as SVec>::Item> as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:29:46 + --> $DIR/issue-105742.rs:33:46 | LL | Output = <Self as SVec>::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -133,7 +133,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -149,7 +149,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -165,7 +165,7 @@ LL | <Self as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -181,7 +181,7 @@ LL | <Self as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -191,13 +191,13 @@ LL | <Self as SVec>::Item<T>, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:37 + --> $DIR/issue-105742.rs:24:37 | LL | Output = <Index<<Self as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -207,13 +207,13 @@ LL | Output = <Index<<Self as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:37 + --> $DIR/issue-105742.rs:24:37 | LL | Output = <Index<<Self as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -223,13 +223,13 @@ LL | Output = <Index<<Self as SVec>::Item<T>, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:29:30 + --> $DIR/issue-105742.rs:33:30 | LL | Output = <Self as SVec>::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -239,13 +239,13 @@ LL | Output = <Self as SVec>::Item<'a>> as SVec>::Item, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:29:30 + --> $DIR/issue-105742.rs:33:30 | LL | Output = <Self as SVec>::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -255,13 +255,13 @@ LL | Output = <Self as SVec>::Item<T>> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:29:46 + --> $DIR/issue-105742.rs:33:46 | LL | Output = <Self as SVec>::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -271,13 +271,13 @@ LL | Output = <Self as SVec>::Item> as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:29:46 + --> $DIR/issue-105742.rs:33:46 | LL | Output = <Self as SVec>::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -317,13 +317,141 @@ LL | | > { | |__^ ...because it uses `Self` as a type parameter error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:45:38 + --> $DIR/issue-105742.rs:15:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:51:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | <Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:15:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:51:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | <Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:24:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:51:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = <Index<<Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:24:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:51:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = <Index<<Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:33:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:51:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item<'a>> as SVec>::Item, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:33:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:51:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item<T>> as SVec>::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:33:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:51:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:33:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:51:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:53:38 | LL | fn len(&self) -> <Self as SVec>::Item; | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -333,13 +461,13 @@ LL | fn len(&self) -> <Self as SVec>::Item<'_>; | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:45:38 + --> $DIR/issue-105742.rs:53:38 | LL | fn len(&self) -> <Self as SVec>::Item; | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:43:10 + --> $DIR/issue-105742.rs:51:10 | LL | type Item<'a, T>; | ^^^^ - @@ -348,7 +476,7 @@ help: add missing generic argument LL | fn len(&self) -> <Self as SVec>::Item<T>; | +++ -error: aborting due to 21 previous errors +error: aborting due to 29 previous errors Some errors have detailed explanations: E0038, E0107. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui-fulldeps/deriving-encodable-decodable-box.rs b/tests/ui-fulldeps/deriving-encodable-decodable-box.rs deleted file mode 100644 index 1c376f59e51..00000000000 --- a/tests/ui-fulldeps/deriving-encodable-decodable-box.rs +++ /dev/null @@ -1,34 +0,0 @@ -// run-pass - -#![allow(unused_imports)] -#![feature(rustc_private)] - -extern crate rustc_macros; -extern crate rustc_serialize; - -// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta -// files. -#[allow(unused_extern_crates)] -extern crate rustc_driver; - -use rustc_macros::{Decodable, Encodable}; -use rustc_serialize::opaque::{MemDecoder, MemEncoder}; -use rustc_serialize::{Decodable, Encodable, Encoder}; - -#[derive(Encodable, Decodable)] -struct A { - foo: Box<[bool]>, -} - -fn main() { - let obj = A { foo: Box::new([true, false]) }; - - let mut encoder = MemEncoder::new(); - obj.encode(&mut encoder); - let data = encoder.finish(); - - let mut decoder = MemDecoder::new(&data, 0); - let obj2 = A::decode(&mut decoder); - - assert_eq!(obj.foo, obj2.foo); -} diff --git a/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs b/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs deleted file mode 100644 index 844d40f2ecd..00000000000 --- a/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs +++ /dev/null @@ -1,44 +0,0 @@ -// run-pass - -#![allow(unused_imports)] -// This briefly tests the capability of `Cell` and `RefCell` to implement the -// `Encodable` and `Decodable` traits via `#[derive(Encodable, Decodable)]` -#![feature(rustc_private)] - -extern crate rustc_macros; -extern crate rustc_serialize; - -// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta -// files. -#[allow(unused_extern_crates)] -extern crate rustc_driver; - -use rustc_macros::{Decodable, Encodable}; -use rustc_serialize::opaque::{MemDecoder, MemEncoder}; -use rustc_serialize::{Decodable, Encodable, Encoder}; -use std::cell::{Cell, RefCell}; - -#[derive(Encodable, Decodable)] -struct A { - baz: isize, -} - -#[derive(Encodable, Decodable)] -struct B { - foo: Cell<bool>, - bar: RefCell<A>, -} - -fn main() { - let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) }; - - let mut encoder = MemEncoder::new(); - obj.encode(&mut encoder); - let data = encoder.finish(); - - let mut decoder = MemDecoder::new(&data, 0); - let obj2 = B::decode(&mut decoder); - - assert_eq!(obj.foo.get(), obj2.foo.get()); - assert_eq!(obj.bar.borrow().baz, obj2.bar.borrow().baz); -} diff --git a/tests/ui-fulldeps/issue-14021.rs b/tests/ui-fulldeps/issue-14021.rs deleted file mode 100644 index 309b5c4a03d..00000000000 --- a/tests/ui-fulldeps/issue-14021.rs +++ /dev/null @@ -1,33 +0,0 @@ -// run-pass - -#![allow(unused_mut)] -#![allow(unused_imports)] -#![feature(rustc_private)] - -extern crate rustc_macros; -extern crate rustc_serialize; - -// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta -// files. -#[allow(unused_extern_crates)] -extern crate rustc_driver; - -use rustc_macros::{Decodable, Encodable}; -use rustc_serialize::opaque::{MemDecoder, MemEncoder}; -use rustc_serialize::{Decodable, Encodable, Encoder}; - -#[derive(Encodable, Decodable, PartialEq, Debug)] -struct UnitLikeStruct; - -pub fn main() { - let obj = UnitLikeStruct; - - let mut encoder = MemEncoder::new(); - obj.encode(&mut encoder); - let data = encoder.finish(); - - let mut decoder = MemDecoder::new(&data, 0); - let obj2 = UnitLikeStruct::decode(&mut decoder); - - assert_eq!(obj, obj2); -} diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 95f27efa771..1454d6dde6c 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -60,6 +60,24 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { stable_mir::mir::Terminator::Call { .. } => {} other => panic!("{other:?}"), } + + let drop = get_item(tcx, &items, (DefKind::Fn, "drop")).unwrap(); + let body = drop.body(); + assert_eq!(body.blocks.len(), 2); + let block = &body.blocks[0]; + match &block.terminator { + stable_mir::mir::Terminator::Drop { .. } => {} + other => panic!("{other:?}"), + } + + let assert = get_item(tcx, &items, (DefKind::Fn, "assert")).unwrap(); + let body = assert.body(); + assert_eq!(body.blocks.len(), 2); + let block = &body.blocks[0]; + match &block.terminator { + stable_mir::mir::Terminator::Assert { .. } => {} + other => panic!("{other:?}"), + } } // Use internal API to find a function in a crate. @@ -131,6 +149,12 @@ fn generate_input(path: &str) -> std::io::Result<()> { let x_64 = foo::bar(x); let y_64 = foo::bar(y); x_64.wrapping_add(y_64) + }} + + pub fn drop(_: String) {{}} + + pub fn assert(x: i32) -> i32 {{ + x + 1 }}"# )?; Ok(()) diff --git a/tests/ui/abi/stack-probes-lto.rs b/tests/ui/abi/stack-probes-lto.rs index 039507d5104..0dccb633df9 100644 --- a/tests/ui/abi/stack-probes-lto.rs +++ b/tests/ui/abi/stack-probes-lto.rs @@ -5,6 +5,7 @@ // ignore-mips64 // ignore-sparc // ignore-sparc64 +// ignore-loongarch64 // ignore-wasm // ignore-emscripten no processes // ignore-sgx no processes diff --git a/tests/ui/abi/stack-probes.rs b/tests/ui/abi/stack-probes.rs index 8dba54c3f81..8137c92304d 100644 --- a/tests/ui/abi/stack-probes.rs +++ b/tests/ui/abi/stack-probes.rs @@ -5,6 +5,7 @@ // ignore-mips64 // ignore-sparc // ignore-sparc64 +// ignore-loongarch64 // ignore-wasm // ignore-emscripten no processes // ignore-sgx no processes diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs index f67410986e5..4b8bf52c374 100644 --- a/tests/ui/associated-type-bounds/duplicate.rs +++ b/tests/ui/associated-type-bounds/duplicate.rs @@ -193,10 +193,13 @@ trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {} //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] trait TRS1: Iterator<Item: Copy, Item: Send> {} //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +//~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] trait TRS2: Iterator<Item: Copy, Item: Copy> {} //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +//~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] trait TRS3: Iterator<Item: 'static, Item: 'static> {} //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] +//~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] trait TRW1<T> where T: Iterator<Item: Copy, Item: Send>, diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr index c3061327f56..08721eff7b0 100644 --- a/tests/ui/associated-type-bounds/duplicate.stderr +++ b/tests/ui/associated-type-bounds/duplicate.stderr @@ -367,7 +367,23 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:196:34 + --> $DIR/duplicate.rs:194:34 + | +LL | trait TRS1: Iterator<Item: Copy, Item: Send> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:197:34 + | +LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:197:34 | LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {} | ---------- ^^^^^^^^^^ re-bound here @@ -375,7 +391,15 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:198:37 + --> $DIR/duplicate.rs:200:37 + | +LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:200:37 | LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -383,7 +407,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:202:29 + --> $DIR/duplicate.rs:205:29 | LL | T: Iterator<Item: Copy, Item: Send>, | ---------- ^^^^^^^^^^ re-bound here @@ -391,7 +415,7 @@ LL | T: Iterator<Item: Copy, Item: Send>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:208:29 + --> $DIR/duplicate.rs:211:29 | LL | T: Iterator<Item: Copy, Item: Copy>, | ---------- ^^^^^^^^^^ re-bound here @@ -399,7 +423,7 @@ LL | T: Iterator<Item: Copy, Item: Copy>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:214:32 + --> $DIR/duplicate.rs:217:32 | LL | T: Iterator<Item: 'static, Item: 'static>, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -407,7 +431,7 @@ LL | T: Iterator<Item: 'static, Item: 'static>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:220:32 + --> $DIR/duplicate.rs:223:32 | LL | Self: Iterator<Item: Copy, Item: Send>, | ---------- ^^^^^^^^^^ re-bound here @@ -415,7 +439,7 @@ LL | Self: Iterator<Item: Copy, Item: Send>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:220:32 + --> $DIR/duplicate.rs:223:32 | LL | Self: Iterator<Item: Copy, Item: Send>, | ---------- ^^^^^^^^^^ re-bound here @@ -423,7 +447,7 @@ LL | Self: Iterator<Item: Copy, Item: Send>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:227:32 + --> $DIR/duplicate.rs:230:32 | LL | Self: Iterator<Item: Copy, Item: Copy>, | ---------- ^^^^^^^^^^ re-bound here @@ -431,7 +455,7 @@ LL | Self: Iterator<Item: Copy, Item: Copy>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:227:32 + --> $DIR/duplicate.rs:230:32 | LL | Self: Iterator<Item: Copy, Item: Copy>, | ---------- ^^^^^^^^^^ re-bound here @@ -439,7 +463,7 @@ LL | Self: Iterator<Item: Copy, Item: Copy>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:234:35 + --> $DIR/duplicate.rs:237:35 | LL | Self: Iterator<Item: 'static, Item: 'static>, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -447,7 +471,7 @@ LL | Self: Iterator<Item: 'static, Item: 'static>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:234:35 + --> $DIR/duplicate.rs:237:35 | LL | Self: Iterator<Item: 'static, Item: 'static>, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -455,7 +479,7 @@ LL | Self: Iterator<Item: 'static, Item: 'static>, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:252:40 + --> $DIR/duplicate.rs:255:40 | LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>; | ---------- ^^^^^^^^^^ re-bound here @@ -463,7 +487,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:254:44 + --> $DIR/duplicate.rs:257:44 | LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>; | ---------- ^^^^^^^^^^ re-bound here @@ -471,7 +495,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:256:43 + --> $DIR/duplicate.rs:259:43 | LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -479,7 +503,7 @@ LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:240:34 + --> $DIR/duplicate.rs:243:34 | LL | type A: Iterator<Item: Copy, Item: Send>; | ---------- ^^^^^^^^^^ re-bound here @@ -487,7 +511,7 @@ LL | type A: Iterator<Item: Copy, Item: Send>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:244:34 + --> $DIR/duplicate.rs:247:34 | LL | type A: Iterator<Item: Copy, Item: Copy>; | ---------- ^^^^^^^^^^ re-bound here @@ -495,13 +519,13 @@ LL | type A: Iterator<Item: Copy, Item: Copy>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:248:37 + --> $DIR/duplicate.rs:251:37 | LL | type A: Iterator<Item: 'static, Item: 'static>; | ------------- ^^^^^^^^^^^^^ re-bound here | | | `Item` bound here first -error: aborting due to 63 previous errors +error: aborting due to 66 previous errors For more information about this error, try `rustc --explain E0719`. diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index 79cee55177b..58ce41d1a89 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -2,7 +2,6 @@ #![feature(return_type_notation, async_fn_in_trait)] //~^ WARN the feature `return_type_notation` is incomplete -//~| WARN the feature `async_fn_in_trait` is incomplete trait Trait { async fn method() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index b23e0f791ea..95ef7d82fca 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -1,11 +1,11 @@ error: return type notation uses `()` instead of `(..)` for elided arguments - --> $DIR/bad-inputs-and-output.rs:19:24 + --> $DIR/bad-inputs-and-output.rs:18:24 | LL | fn baz<T: Trait<method(..): Send>>() {} | ^^ help: remove the `..` error[E0658]: associated type bounds are unstable - --> $DIR/bad-inputs-and-output.rs:11:17 + --> $DIR/bad-inputs-and-output.rs:10:17 | LL | fn foo<T: Trait<method(i32): Send>>() {} | ^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | fn foo<T: Trait<method(i32): Send>>() {} = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/bad-inputs-and-output.rs:15:17 + --> $DIR/bad-inputs-and-output.rs:14:17 | LL | fn bar<T: Trait<method() -> (): Send>>() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -31,26 +31,18 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-inputs-and-output.rs:3:34 - | -LL | #![feature(return_type_notation, async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - error: argument types not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:11:23 + --> $DIR/bad-inputs-and-output.rs:10:23 | LL | fn foo<T: Trait<method(i32): Send>>() {} | ^^^^^ help: remove the input types: `()` error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:15:25 + --> $DIR/bad-inputs-and-output.rs:14:25 | LL | fn bar<T: Trait<method() -> (): Send>>() {} | ^^^^^^ help: remove the return type -error: aborting due to 5 previous errors; 2 warnings emitted +error: aborting due to 5 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.rs b/tests/ui/associated-type-bounds/return-type-notation/basic.rs index 0b7530b65d7..edc6a8e4caf 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.rs @@ -4,7 +4,6 @@ #![feature(return_type_notation, async_fn_in_trait)] //~^ WARN the feature `return_type_notation` is incomplete -//~| WARN the feature `async_fn_in_trait` is incomplete trait Foo { async fn method() -> Result<(), ()>; diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr index 722c774cb33..9962f4706b3 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr @@ -7,13 +7,5 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:5:34 - | -LL | #![feature(return_type_notation, async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr index 1645d8c2650..c2da4f57696 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr @@ -7,31 +7,23 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:5:34 - | -LL | #![feature(return_type_notation, async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - error: future cannot be sent between threads safely - --> $DIR/basic.rs:24:13 + --> $DIR/basic.rs:23:13 | LL | is_send(foo::<T>()); | ^^^^^^^^^^ future returned by `foo` is not `Send` | = help: within `impl Future<Output = Result<(), ()>>`, the trait `Send` is not implemented for `impl Future<Output = Result<(), ()>>` note: future is not `Send` as it awaits another future which is not `Send` - --> $DIR/basic.rs:14:5 + --> $DIR/basic.rs:13:5 | LL | T::method().await?; | ^^^^^^^^^^^ await occurs here on type `impl Future<Output = Result<(), ()>>`, which is not `Send` note: required by a bound in `is_send` - --> $DIR/basic.rs:18:20 + --> $DIR/basic.rs:17:20 | LL | fn is_send(_: impl Send) {} | ^^^^ required by this bound in `is_send` -error: aborting due to previous error; 2 warnings emitted +error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.rs b/tests/ui/associated-type-bounds/return-type-notation/equality.rs index 75f757e9025..6884305d7b3 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.rs @@ -2,7 +2,6 @@ #![feature(return_type_notation, async_fn_in_trait)] //~^ WARN the feature `return_type_notation` is incomplete -//~| WARN the feature `async_fn_in_trait` is incomplete use std::future::Future; diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr index c5b2e5710d4..490bfdc4c3c 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr @@ -7,19 +7,11 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality.rs:3:34 - | -LL | #![feature(return_type_notation, async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - error: return type notation is not allowed to use type equality - --> $DIR/equality.rs:13:18 + --> $DIR/equality.rs:12:18 | LL | fn test<T: Trait<method() = Box<dyn Future<Output = ()>>>>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error; 2 warnings emitted +error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.rs b/tests/ui/associated-type-bounds/return-type-notation/missing.rs index 7b98a5cdafd..a52562d78f8 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.rs @@ -2,13 +2,12 @@ #![feature(return_type_notation, async_fn_in_trait)] //~^ WARN the feature `return_type_notation` is incomplete -//~| WARN the feature `async_fn_in_trait` is incomplete trait Trait { async fn method() {} } fn bar<T: Trait<methid(): Send>>() {} -//~^ ERROR cannot find associated function `methid` in trait `Trait` +//~^ ERROR cannot find associated function `methid` for `Trait` fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr index 34f5bda884d..5b1c4cb0b2c 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr @@ -7,19 +7,11 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/missing.rs:3:34 - | -LL | #![feature(return_type_notation, async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - -error: cannot find associated function `methid` in trait `Trait` - --> $DIR/missing.rs:11:17 +error: cannot find associated function `methid` for `Trait` + --> $DIR/missing.rs:10:17 | LL | fn bar<T: Trait<methid(): Send>>() {} | ^^^^^^^^^^^^^^ -error: aborting due to previous error; 2 warnings emitted +error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/associated-type-bounds/supertrait-defines-ty.rs b/tests/ui/associated-type-bounds/supertrait-defines-ty.rs new file mode 100644 index 00000000000..b6f37cb908e --- /dev/null +++ b/tests/ui/associated-type-bounds/supertrait-defines-ty.rs @@ -0,0 +1,26 @@ +// check-pass + +// Make sure that we don't look into associated type bounds when looking for +// supertraits that define an associated type. Fixes #76593. + +#![feature(associated_type_bounds)] + +trait Load: Sized { + type Blob; +} + +trait Primitive: Load<Blob = Self> {} + +trait BlobPtr: Primitive {} + +trait CleanPtr: Load<Blob: BlobPtr> { + fn to_blob(&self) -> Self::Blob; +} + +impl Load for () { + type Blob = Self; +} +impl Primitive for () {} +impl BlobPtr for () {} + +fn main() {} diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr b/tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr deleted file mode 100644 index 2142ee232ca..00000000000 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/async-default-fn-overridden.rs:6:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr b/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr deleted file mode 100644 index 2142ee232ca..00000000000 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/async-default-fn-overridden.rs:6:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs index dd1af93d706..99c3ba6a3c2 100644 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs @@ -4,7 +4,6 @@ // revisions: current next #![feature(async_fn_in_trait)] -//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use use std::future::Future; diff --git a/tests/ui/async-await/in-trait/bad-signatures.current.stderr b/tests/ui/async-await/in-trait/bad-signatures.current.stderr index 5a05b080c3e..ae590fb057f 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.current.stderr +++ b/tests/ui/async-await/in-trait/bad-signatures.current.stderr @@ -1,11 +1,11 @@ error: expected identifier, found keyword `self` - --> $DIR/bad-signatures.rs:9:23 + --> $DIR/bad-signatures.rs:8:23 | LL | async fn bar(&abc self); | ^^^^ expected identifier, found keyword error: expected one of `:`, `@`, or `|`, found keyword `self` - --> $DIR/bad-signatures.rs:9:23 + --> $DIR/bad-signatures.rs:8:23 | LL | async fn bar(&abc self); | -----^^^^ @@ -13,14 +13,5 @@ LL | async fn bar(&abc self); | | expected one of `:`, `@`, or `|` | help: declare the type after the parameter binding: `<identifier>: <type>` -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-signatures.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/in-trait/bad-signatures.next.stderr b/tests/ui/async-await/in-trait/bad-signatures.next.stderr index 5a05b080c3e..ae590fb057f 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.next.stderr +++ b/tests/ui/async-await/in-trait/bad-signatures.next.stderr @@ -1,11 +1,11 @@ error: expected identifier, found keyword `self` - --> $DIR/bad-signatures.rs:9:23 + --> $DIR/bad-signatures.rs:8:23 | LL | async fn bar(&abc self); | ^^^^ expected identifier, found keyword error: expected one of `:`, `@`, or `|`, found keyword `self` - --> $DIR/bad-signatures.rs:9:23 + --> $DIR/bad-signatures.rs:8:23 | LL | async fn bar(&abc self); | -----^^^^ @@ -13,14 +13,5 @@ LL | async fn bar(&abc self); | | expected one of `:`, `@`, or `|` | help: declare the type after the parameter binding: `<identifier>: <type>` -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-signatures.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/in-trait/bad-signatures.rs b/tests/ui/async-await/in-trait/bad-signatures.rs index e0093be8cb3..4baddd8ccb8 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.rs +++ b/tests/ui/async-await/in-trait/bad-signatures.rs @@ -3,7 +3,6 @@ // revisions: current next #![feature(async_fn_in_trait)] -//~^ WARN the feature `async_fn_in_trait` is incomplete trait MyTrait { async fn bar(&abc self); diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr index 1e67cdca248..eec5ab06539 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr @@ -1,12 +1,3 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/dont-project-to-specializable-projection.rs:6:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error: async associated function in trait cannot be specialized --> $DIR/dont-project-to-specializable-projection.rs:16:5 | @@ -15,5 +6,5 @@ LL | default async fn foo(_: T) -> &'static str { | = note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr index fa89c6b77e0..25a7f3bb56a 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr @@ -1,12 +1,3 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/dont-project-to-specializable-projection.rs:6:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0053]: method `foo` has an incompatible type for trait --> $DIR/dont-project-to-specializable-projection.rs:16:35 | @@ -29,6 +20,6 @@ LL | default async fn foo(_: T) -> &'static str { | = note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr index 0e9477544a4..69e7c65ee3e 100644 --- a/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr +++ b/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr @@ -1,14 +1,5 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/lifetime-mismatch.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration - --> $DIR/lifetime-mismatch.rs:14:17 + --> $DIR/lifetime-mismatch.rs:13:17 | LL | async fn foo<'a>(&self); | ---- lifetimes in impl do not match this method in trait @@ -16,6 +7,6 @@ LL | async fn foo<'a>(&self); LL | async fn foo(&self) {} | ^ lifetimes do not match method in trait -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0195`. diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr index 0e9477544a4..69e7c65ee3e 100644 --- a/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr +++ b/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr @@ -1,14 +1,5 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/lifetime-mismatch.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration - --> $DIR/lifetime-mismatch.rs:14:17 + --> $DIR/lifetime-mismatch.rs:13:17 | LL | async fn foo<'a>(&self); | ---- lifetimes in impl do not match this method in trait @@ -16,6 +7,6 @@ LL | async fn foo<'a>(&self); LL | async fn foo(&self) {} | ^ lifetimes do not match method in trait -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0195`. diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.rs b/tests/ui/async-await/in-trait/lifetime-mismatch.rs index 5ff5a01a1ee..46183f72bce 100644 --- a/tests/ui/async-await/in-trait/lifetime-mismatch.rs +++ b/tests/ui/async-await/in-trait/lifetime-mismatch.rs @@ -3,7 +3,6 @@ // revisions: current next #![feature(async_fn_in_trait)] -//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes trait MyTrait { async fn foo<'a>(&self); diff --git a/tests/ui/async-await/in-trait/missing-send-bound.current.stderr b/tests/ui/async-await/in-trait/missing-send-bound.current.stderr index 319ed582e27..9aa37f7437e 100644 --- a/tests/ui/async-await/in-trait/missing-send-bound.current.stderr +++ b/tests/ui/async-await/in-trait/missing-send-bound.current.stderr @@ -1,29 +1,20 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/missing-send-bound.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error: future cannot be sent between threads safely - --> $DIR/missing-send-bound.rs:17:20 + --> $DIR/missing-send-bound.rs:16:20 | LL | assert_is_send(test::<T>()); | ^^^^^^^^^^^ future returned by `test` is not `Send` | = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>` note: future is not `Send` as it awaits another future which is not `Send` - --> $DIR/missing-send-bound.rs:13:5 + --> $DIR/missing-send-bound.rs:12:5 | LL | T::bar().await; | ^^^^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send` note: required by a bound in `assert_is_send` - --> $DIR/missing-send-bound.rs:21:27 + --> $DIR/missing-send-bound.rs:20:27 | LL | fn assert_is_send(_: impl Send) {} | ^^^^ required by this bound in `assert_is_send` -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/ui/async-await/in-trait/missing-send-bound.next.stderr b/tests/ui/async-await/in-trait/missing-send-bound.next.stderr index 319ed582e27..9aa37f7437e 100644 --- a/tests/ui/async-await/in-trait/missing-send-bound.next.stderr +++ b/tests/ui/async-await/in-trait/missing-send-bound.next.stderr @@ -1,29 +1,20 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/missing-send-bound.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error: future cannot be sent between threads safely - --> $DIR/missing-send-bound.rs:17:20 + --> $DIR/missing-send-bound.rs:16:20 | LL | assert_is_send(test::<T>()); | ^^^^^^^^^^^ future returned by `test` is not `Send` | = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>` note: future is not `Send` as it awaits another future which is not `Send` - --> $DIR/missing-send-bound.rs:13:5 + --> $DIR/missing-send-bound.rs:12:5 | LL | T::bar().await; | ^^^^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send` note: required by a bound in `assert_is_send` - --> $DIR/missing-send-bound.rs:21:27 + --> $DIR/missing-send-bound.rs:20:27 | LL | fn assert_is_send(_: impl Send) {} | ^^^^ required by this bound in `assert_is_send` -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/ui/async-await/in-trait/missing-send-bound.rs b/tests/ui/async-await/in-trait/missing-send-bound.rs index 705fcf322f9..b602865cbb1 100644 --- a/tests/ui/async-await/in-trait/missing-send-bound.rs +++ b/tests/ui/async-await/in-trait/missing-send-bound.rs @@ -3,7 +3,6 @@ // revisions: current next #![feature(async_fn_in_trait)] -//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes trait Foo { async fn bar(); diff --git a/tests/ui/async-await/in-trait/object-safety.current.stderr b/tests/ui/async-await/in-trait/object-safety.current.stderr index 90e049a9960..7f7ec39142c 100644 --- a/tests/ui/async-await/in-trait/object-safety.current.stderr +++ b/tests/ui/async-await/in-trait/object-safety.current.stderr @@ -1,20 +1,11 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/object-safety.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:13:12 + --> $DIR/object-safety.rs:12:12 | LL | let x: &dyn Foo = todo!(); | ^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety.rs:9:14 + --> $DIR/object-safety.rs:8:14 | LL | trait Foo { | --- this trait cannot be made into an object... @@ -22,6 +13,6 @@ LL | async fn foo(&self); | ^^^ ...because method `foo` is `async` = help: consider moving `foo` to another trait -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/in-trait/object-safety.next.stderr b/tests/ui/async-await/in-trait/object-safety.next.stderr index 90e049a9960..7f7ec39142c 100644 --- a/tests/ui/async-await/in-trait/object-safety.next.stderr +++ b/tests/ui/async-await/in-trait/object-safety.next.stderr @@ -1,20 +1,11 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/object-safety.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:13:12 + --> $DIR/object-safety.rs:12:12 | LL | let x: &dyn Foo = todo!(); | ^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety.rs:9:14 + --> $DIR/object-safety.rs:8:14 | LL | trait Foo { | --- this trait cannot be made into an object... @@ -22,6 +13,6 @@ LL | async fn foo(&self); | ^^^ ...because method `foo` is `async` = help: consider moving `foo` to another trait -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/in-trait/object-safety.rs b/tests/ui/async-await/in-trait/object-safety.rs index f67286a20a2..4edad1512e9 100644 --- a/tests/ui/async-await/in-trait/object-safety.rs +++ b/tests/ui/async-await/in-trait/object-safety.rs @@ -3,7 +3,6 @@ // revisions: current next #![feature(async_fn_in_trait)] -//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes trait Foo { async fn foo(&self); diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr index a5efc757156..6a107d7beb8 100644 --- a/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr +++ b/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr @@ -1,14 +1,5 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/return-type-suggestion.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/return-type-suggestion.rs:10:9 + --> $DIR/return-type-suggestion.rs:9:9 | LL | Ok(()) | ^^^^^^- help: consider using a semicolon here: `;` @@ -18,6 +9,6 @@ LL | Ok(()) = note: expected unit type `()` found enum `Result<(), _>` -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr index a5efc757156..6a107d7beb8 100644 --- a/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr +++ b/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr @@ -1,14 +1,5 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/return-type-suggestion.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/return-type-suggestion.rs:10:9 + --> $DIR/return-type-suggestion.rs:9:9 | LL | Ok(()) | ^^^^^^- help: consider using a semicolon here: `;` @@ -18,6 +9,6 @@ LL | Ok(()) = note: expected unit type `()` found enum `Result<(), _>` -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.rs b/tests/ui/async-await/in-trait/return-type-suggestion.rs index 3de66306d9a..d63bccefa9f 100644 --- a/tests/ui/async-await/in-trait/return-type-suggestion.rs +++ b/tests/ui/async-await/in-trait/return-type-suggestion.rs @@ -3,7 +3,6 @@ // revisions: current next #![feature(async_fn_in_trait)] -//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes trait A { async fn e() { diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr index b4a3924d8da..33e22dec3f7 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr @@ -7,14 +7,6 @@ LL | #![feature(return_type_notation)] = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-110963-early.rs:5:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - error: higher-ranked lifetime error --> $DIR/issue-110963-early.rs:15:5 | @@ -41,5 +33,5 @@ LL | | }); | = note: could not prove `[async block@$DIR/issue-110963-early.rs:15:11: 20:6]: Send` -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/async-await/return-type-notation/issue-110963-late.rs b/tests/ui/async-await/return-type-notation/issue-110963-late.rs index 2a35922eaa1..17b5d775d44 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-late.rs +++ b/tests/ui/async-await/return-type-notation/issue-110963-late.rs @@ -4,7 +4,6 @@ #![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete #![feature(async_fn_in_trait)] -//~^ WARN the feature `async_fn_in_trait` is incomplete trait HealthCheck { async fn check(&mut self) -> bool; diff --git a/tests/ui/async-await/return-type-notation/issue-110963-late.stderr b/tests/ui/async-await/return-type-notation/issue-110963-late.stderr index 36ef3ad0a4c..9c6966537a7 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-late.stderr +++ b/tests/ui/async-await/return-type-notation/issue-110963-late.stderr @@ -7,13 +7,5 @@ LL | #![feature(return_type_notation)] = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-110963-late.rs:6:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs new file mode 100644 index 00000000000..028e526b5f5 --- /dev/null +++ b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs @@ -0,0 +1,32 @@ +// edition:2021 + +#![feature(async_fn_in_trait, return_type_notation)] +//~^ WARN the feature `return_type_notation` is incomplete + +trait Super1<'a> { + async fn test(); +} +impl Super1<'_> for () { + async fn test() {} +} + +trait Super2 { + async fn test(); +} +impl Super2 for () { + async fn test() {} +} + +trait Foo: for<'a> Super1<'a> + Super2 {} +impl Foo for () {} + +fn test<T>() +where + T: Foo<test(): Send>, + //~^ ERROR ambiguous associated function `test` for `Foo` +{ +} + +fn main() { + test::<()>(); +} diff --git a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr new file mode 100644 index 00000000000..5bc8dbde4bc --- /dev/null +++ b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr @@ -0,0 +1,19 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/super-method-bound-ambig.rs:3:31 + | +LL | #![feature(async_fn_in_trait, return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: ambiguous associated function `test` for `Foo` + --> $DIR/super-method-bound-ambig.rs:25:12 + | +LL | T: Foo<test(): Send>, + | ^^^^^^^^^^^^ + | + = note: `test` is declared in two supertraits: `Super2` and `Super1<'a>` + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.rs b/tests/ui/async-await/return-type-notation/super-method-bound.rs new file mode 100644 index 00000000000..58ea3578db6 --- /dev/null +++ b/tests/ui/async-await/return-type-notation/super-method-bound.rs @@ -0,0 +1,25 @@ +// edition:2021 +// check-pass + +#![feature(async_fn_in_trait, return_type_notation)] +//~^ WARN the feature `return_type_notation` is incomplete + +trait Super<'a> { + async fn test(); +} +impl Super<'_> for () { + async fn test() {} +} + +trait Foo: for<'a> Super<'a> {} +impl Foo for () {} + +fn test<T>() +where + T: Foo<test(): Send>, +{ +} + +fn main() { + test::<()>(); +} diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.stderr b/tests/ui/async-await/return-type-notation/super-method-bound.stderr new file mode 100644 index 00000000000..ac0668d3c44 --- /dev/null +++ b/tests/ui/async-await/return-type-notation/super-method-bound.stderr @@ -0,0 +1,11 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/super-method-bound.rs:4:31 + | +LL | #![feature(async_fn_in_trait, return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.rs b/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.rs new file mode 100644 index 00000000000..c9e043577ed --- /dev/null +++ b/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.rs @@ -0,0 +1,11 @@ +type Lazy<T> = Box<dyn Fn() -> T + 'static>; + +fn test(x: &i32) -> Lazy<i32> { + Box::new(|| { + //~^ ERROR lifetime may not live long enough + //~| ERROR closure may outlive the current function + *x + }) +} + +fn main() {} diff --git a/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.stderr b/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.stderr new file mode 100644 index 00000000000..28b4b4aa290 --- /dev/null +++ b/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.stderr @@ -0,0 +1,43 @@ +error: lifetime may not live long enough + --> $DIR/suggest-lt-on-ty-alias-w-generics.rs:4:5 + | +LL | fn test(x: &i32) -> Lazy<i32> { + | - let's call the lifetime of this reference `'1` +LL | / Box::new(|| { +LL | | +LL | | +LL | | *x +LL | | }) + | |______^ returning this value requires that `'1` must outlive `'static` + | +help: to declare that the trait object captures data from argument `x`, you can add a lifetime parameter `'a` in the type alias + | +LL | type Lazy<'a, T> = Box<dyn Fn() -> T + 'a>; + | +++ ~~ + +error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function + --> $DIR/suggest-lt-on-ty-alias-w-generics.rs:4:14 + | +LL | Box::new(|| { + | ^^ may outlive borrowed value `x` +... +LL | *x + | -- `x` is borrowed here + | +note: closure is returned here + --> $DIR/suggest-lt-on-ty-alias-w-generics.rs:4:5 + | +LL | / Box::new(|| { +LL | | +LL | | +LL | | *x +LL | | }) + | |______^ +help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword + | +LL | Box::new(move || { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0373`. diff --git a/tests/ui/borrowck/tainted-promoteds.rs b/tests/ui/borrowck/tainted-promoteds.rs new file mode 100644 index 00000000000..2b6f0ddbd6c --- /dev/null +++ b/tests/ui/borrowck/tainted-promoteds.rs @@ -0,0 +1,12 @@ +// Regression test for issue #110856, where a borrowck error for a MIR tainted +// all promoteds within. This in turn generated a spurious "erroneous constant +// used" note when trying to evaluate a promoted. + +pub fn f() -> u32 { + let a = 0; + a = &0 * &1 * &2 * &3; + //~^ ERROR: cannot assign twice to immutable variable + a +} + +fn main() {} diff --git a/tests/ui/borrowck/tainted-promoteds.stderr b/tests/ui/borrowck/tainted-promoteds.stderr new file mode 100644 index 00000000000..b276ea9aceb --- /dev/null +++ b/tests/ui/borrowck/tainted-promoteds.stderr @@ -0,0 +1,14 @@ +error[E0384]: cannot assign twice to immutable variable `a` + --> $DIR/tainted-promoteds.rs:7:5 + | +LL | let a = 0; + | - + | | + | first assignment to `a` + | help: consider making this binding mutable: `mut a` +LL | a = &0 * &1 * &2 * &3; + | ^^^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0384`. diff --git a/tests/ui/cfg/conditional-compile-arch.rs b/tests/ui/cfg/conditional-compile-arch.rs index 7de561df136..e59e06f801b 100644 --- a/tests/ui/cfg/conditional-compile-arch.rs +++ b/tests/ui/cfg/conditional-compile-arch.rs @@ -39,3 +39,6 @@ pub fn main() { } #[cfg(target_arch = "riscv64")] pub fn main() { } + +#[cfg(target_arch = "loongarch64")] +pub fn main() { } diff --git a/tests/ui/check-cfg/compact-values.stderr b/tests/ui/check-cfg/compact-values.stderr index 5ca4d3b3de7..70a967c0e5f 100644 --- a/tests/ui/check-cfg/compact-values.stderr +++ b/tests/ui/check-cfg/compact-values.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value LL | #[cfg(target(os = "linux", arch = "X"))] | ^^^^^^^^^^ | - = note: expected values for `target_arch` are: aarch64, arm, avr, bpf, hexagon, loongarch64, m68k, mips, mips64, msp430, nvptx64, powerpc, powerpc64, riscv32, riscv64, s390x, sparc, sparc64, wasm32, wasm64, x86, x86_64 + = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips64`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/diagnotics.rs b/tests/ui/check-cfg/diagnotics.rs new file mode 100644 index 00000000000..49e127d079a --- /dev/null +++ b/tests/ui/check-cfg/diagnotics.rs @@ -0,0 +1,31 @@ +// check-pass +// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --check-cfg=values(no_values) -Z unstable-options + +#[cfg(featur)] +//~^ WARNING unexpected `cfg` condition name +fn feature() {} + +#[cfg(featur = "foo")] +//~^ WARNING unexpected `cfg` condition name +fn feature() {} + +#[cfg(featur = "fo")] +//~^ WARNING unexpected `cfg` condition name +fn feature() {} + +#[cfg(feature = "foo")] +fn feature() {} + +#[cfg(no_value)] +//~^ WARNING unexpected `cfg` condition name +fn no_values() {} + +#[cfg(no_value = "foo")] +//~^ WARNING unexpected `cfg` condition name +fn no_values() {} + +#[cfg(no_values = "bar")] +//~^ WARNING unexpected `cfg` condition value +fn no_values() {} + +fn main() {} diff --git a/tests/ui/check-cfg/diagnotics.stderr b/tests/ui/check-cfg/diagnotics.stderr new file mode 100644 index 00000000000..8b9fef09d09 --- /dev/null +++ b/tests/ui/check-cfg/diagnotics.stderr @@ -0,0 +1,62 @@ +warning: unexpected `cfg` condition name + --> $DIR/diagnotics.rs:4:7 + | +LL | #[cfg(featur)] + | ^^^^^^ help: there is a config with a similar name: `feature` + | + = help: expected values for `feature` are: `foo` + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name + --> $DIR/diagnotics.rs:8:7 + | +LL | #[cfg(featur = "foo")] + | ^^^^^^^^^^^^^^ + | + = help: expected values for `feature` are: `foo` +help: there is a config with a similar name and value + | +LL | #[cfg(feature = "foo")] + | ~~~~~~~ + +warning: unexpected `cfg` condition name + --> $DIR/diagnotics.rs:12:7 + | +LL | #[cfg(featur = "fo")] + | ^^^^^^^^^^^^^ + | + = help: expected values for `feature` are: `foo` +help: there is a config with a similar name and different values + | +LL | #[cfg(feature = "foo")] + | ~~~~~~~~~~~~~~~ + +warning: unexpected `cfg` condition name + --> $DIR/diagnotics.rs:19:7 + | +LL | #[cfg(no_value)] + | ^^^^^^^^ help: there is a config with a similar name: `no_values` + +warning: unexpected `cfg` condition name + --> $DIR/diagnotics.rs:23:7 + | +LL | #[cfg(no_value = "foo")] + | ^^^^^^^^^^^^^^^^ + | +help: there is a config with a similar name and no value + | +LL | #[cfg(no_values)] + | ~~~~~~~~~ + +warning: unexpected `cfg` condition value + --> $DIR/diagnotics.rs:27:7 + | +LL | #[cfg(no_values = "bar")] + | ^^^^^^^^^-------- + | | + | help: remove the value + | + = note: no expected value for `no_values` + +warning: 6 warnings emitted + diff --git a/tests/ui/check-cfg/invalid-cfg-name.stderr b/tests/ui/check-cfg/invalid-cfg-name.stderr index 2bd1821c942..ed09f8cb66d 100644 --- a/tests/ui/check-cfg/invalid-cfg-name.stderr +++ b/tests/ui/check-cfg/invalid-cfg-name.stderr @@ -2,7 +2,7 @@ warning: unexpected `cfg` condition name --> $DIR/invalid-cfg-name.rs:7:7 | LL | #[cfg(widnows)] - | ^^^^^^^ help: did you mean: `windows` + | ^^^^^^^ help: there is a config with a similar name: `windows` | = note: `#[warn(unexpected_cfgs)]` on by default diff --git a/tests/ui/check-cfg/invalid-cfg-value.stderr b/tests/ui/check-cfg/invalid-cfg-value.stderr index 83383ea61a4..776d264a7ad 100644 --- a/tests/ui/check-cfg/invalid-cfg-value.stderr +++ b/tests/ui/check-cfg/invalid-cfg-value.stderr @@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value LL | #[cfg(feature = "sedre")] | ^^^^^^^^^^------- | | - | help: did you mean: `"serde"` + | help: there is a expected value with a similar name: `"serde"` | - = note: expected values for `feature` are: full, serde + = note: expected values for `feature` are: `full`, `serde` = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value @@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value LL | #[cfg(feature = "rand")] | ^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: full, serde + = note: expected values for `feature` are: `full`, `serde` warning: unexpected condition value `rand` for condition name `feature` | diff --git a/tests/ui/check-cfg/mix.rs b/tests/ui/check-cfg/mix.rs index 4e488fc03ec..9adf5c46e43 100644 --- a/tests/ui/check-cfg/mix.rs +++ b/tests/ui/check-cfg/mix.rs @@ -12,6 +12,10 @@ fn do_windows_stuff() {} //~^ WARNING unexpected `cfg` condition name fn do_windows_stuff() {} +#[cfg(feature)] +//~^ WARNING unexpected `cfg` condition value +fn no_feature() {} + #[cfg(feature = "foo")] fn use_foo() {} diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 9cf887ec788..07c514aed52 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -2,28 +2,36 @@ warning: unexpected `cfg` condition name --> $DIR/mix.rs:11:7 | LL | #[cfg(widnows)] - | ^^^^^^^ help: did you mean: `windows` + | ^^^^^^^ help: there is a config with a similar name: `windows` | = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value - --> $DIR/mix.rs:18:7 + --> $DIR/mix.rs:15:7 + | +LL | #[cfg(feature)] + | ^^^^^^^- help: specify a config value: `= "foo"` + | + = note: expected values for `feature` are: `foo` + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:22:7 | LL | #[cfg(feature = "bar")] | ^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value - --> $DIR/mix.rs:22:7 + --> $DIR/mix.rs:26:7 | LL | #[cfg(feature = "zebra")] | ^^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name - --> $DIR/mix.rs:26:12 + --> $DIR/mix.rs:30:12 | LL | #[cfg_attr(uu, test)] | ^^ @@ -37,146 +45,146 @@ warning: unexpected `unknown_name` as condition name = help: was set with `--cfg` but isn't in the `--check-cfg` expected names warning: unexpected `cfg` condition name - --> $DIR/mix.rs:35:10 + --> $DIR/mix.rs:39:10 | LL | cfg!(widnows); - | ^^^^^^^ help: did you mean: `windows` + | ^^^^^^^ help: there is a config with a similar name: `windows` warning: unexpected `cfg` condition value - --> $DIR/mix.rs:38:10 + --> $DIR/mix.rs:42:10 | LL | cfg!(feature = "bar"); | ^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value - --> $DIR/mix.rs:40:10 + --> $DIR/mix.rs:44:10 | LL | cfg!(feature = "zebra"); | ^^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name - --> $DIR/mix.rs:42:10 + --> $DIR/mix.rs:46:10 | LL | cfg!(xxx = "foo"); | ^^^^^^^^^^^ warning: unexpected `cfg` condition name - --> $DIR/mix.rs:44:10 + --> $DIR/mix.rs:48:10 | LL | cfg!(xxx); | ^^^ warning: unexpected `cfg` condition name - --> $DIR/mix.rs:46:14 + --> $DIR/mix.rs:50:14 | LL | cfg!(any(xxx, windows)); | ^^^ warning: unexpected `cfg` condition value - --> $DIR/mix.rs:48:14 + --> $DIR/mix.rs:52:14 | LL | cfg!(any(feature = "bad", windows)); | ^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name - --> $DIR/mix.rs:50:23 + --> $DIR/mix.rs:54:23 | LL | cfg!(any(windows, xxx)); | ^^^ warning: unexpected `cfg` condition name - --> $DIR/mix.rs:52:20 + --> $DIR/mix.rs:56:20 | LL | cfg!(all(unix, xxx)); | ^^^ warning: unexpected `cfg` condition name - --> $DIR/mix.rs:54:14 + --> $DIR/mix.rs:58:14 | LL | cfg!(all(aa, bb)); | ^^ warning: unexpected `cfg` condition name - --> $DIR/mix.rs:54:18 + --> $DIR/mix.rs:58:18 | LL | cfg!(all(aa, bb)); | ^^ warning: unexpected `cfg` condition name - --> $DIR/mix.rs:57:14 + --> $DIR/mix.rs:61:14 | LL | cfg!(any(aa, bb)); | ^^ warning: unexpected `cfg` condition name - --> $DIR/mix.rs:57:18 + --> $DIR/mix.rs:61:18 | LL | cfg!(any(aa, bb)); | ^^ warning: unexpected `cfg` condition value - --> $DIR/mix.rs:60:20 + --> $DIR/mix.rs:64:20 | LL | cfg!(any(unix, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name - --> $DIR/mix.rs:62:14 + --> $DIR/mix.rs:66:14 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^ warning: unexpected `cfg` condition value - --> $DIR/mix.rs:62:19 + --> $DIR/mix.rs:66:19 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name - --> $DIR/mix.rs:65:14 + --> $DIR/mix.rs:69:14 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ warning: unexpected `cfg` condition name - --> $DIR/mix.rs:65:25 + --> $DIR/mix.rs:69:25 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ warning: unexpected `cfg` condition value - --> $DIR/mix.rs:68:14 + --> $DIR/mix.rs:72:14 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value - --> $DIR/mix.rs:68:33 + --> $DIR/mix.rs:72:33 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value - --> $DIR/mix.rs:68:52 + --> $DIR/mix.rs:72:52 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | - = note: expected values for `feature` are: foo + = note: expected values for `feature` are: `foo` -warning: 27 warnings emitted +warning: 28 warnings emitted diff --git a/tests/ui/check-cfg/no-values.stderr b/tests/ui/check-cfg/no-values.stderr index 8c926d187fe..ffa87dc58f2 100644 --- a/tests/ui/check-cfg/no-values.stderr +++ b/tests/ui/check-cfg/no-values.stderr @@ -2,7 +2,9 @@ warning: unexpected `cfg` condition value --> $DIR/no-values.rs:6:7 | LL | #[cfg(feature = "foo")] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^-------- + | | + | help: remove the value | = note: no expected value for `feature` = note: `#[warn(unexpected_cfgs)]` on by default diff --git a/tests/ui/check-cfg/values-target-json.stderr b/tests/ui/check-cfg/values-target-json.stderr index b58d2970773..eb81535e3ed 100644 --- a/tests/ui/check-cfg/values-target-json.stderr +++ b/tests/ui/check-cfg/values-target-json.stderr @@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value LL | #[cfg(target_os = "linuz")] | ^^^^^^^^^^^^------- | | - | help: did you mean: `"linux"` + | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: aix, android, cuda, dragonfly, emscripten, ericos, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vita, vxworks, wasi, watchos, windows, xous + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `ericos`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/well-known-names.stderr b/tests/ui/check-cfg/well-known-names.stderr index bdbe4d29d30..34c5d6172d9 100644 --- a/tests/ui/check-cfg/well-known-names.stderr +++ b/tests/ui/check-cfg/well-known-names.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name LL | #[cfg(target_oz = "linux")] | ---------^^^^^^^^^^ | | - | help: did you mean: `target_os` + | help: there is a config with a similar name: `target_os` | = note: `#[warn(unexpected_cfgs)]` on by default @@ -14,13 +14,13 @@ warning: unexpected `cfg` condition name LL | #[cfg(features = "foo")] | --------^^^^^^^^ | | - | help: did you mean: `feature` + | help: there is a config with a similar name: `feature` warning: unexpected `cfg` condition name --> $DIR/well-known-names.rs:20:7 | LL | #[cfg(uniw)] - | ^^^^ help: did you mean: `unix` + | ^^^^ help: there is a config with a similar name: `unix` warning: 3 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 69d799783a9..2d18cb82e03 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value LL | #[cfg(target_os = "linuz")] | ^^^^^^^^^^^^------- | | - | help: did you mean: `"linux"` + | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: aix, android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vita, vxworks, wasi, watchos, windows, xous + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous` = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value @@ -15,9 +15,9 @@ warning: unexpected `cfg` condition value LL | #[cfg(target_has_atomic = "0")] | ^^^^^^^^^^^^^^^^^^^^--- | | - | help: did you mean: `"8"` + | help: there is a expected value with a similar name: `"8"` | - = note: expected values for `target_has_atomic` are: 128, 16, 32, 64, 8, ptr + = note: expected values for `target_has_atomic` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` warning: unexpected `cfg` condition value --> $DIR/well-known-values.rs:21:7 diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.rs new file mode 100644 index 00000000000..0da68ae7573 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.rs @@ -0,0 +1,13 @@ +#![allow(incomplete_features)] +#![feature(adt_const_params)] + +fn check(_: impl std::marker::ConstParamTy) {} + +fn main() { + check(main); //~ error: `fn() {main}` can't be used as a const parameter type + check(|| {}); //~ error: `[closure@$DIR/const_param_ty_bad.rs:8:11: 8:13]` can't be used as a const parameter type + check(main as fn()); //~ error: `fn()` can't be used as a const parameter type + check(&mut ()); //~ error: `&mut ()` can't be used as a const parameter type + check(&mut () as *mut ()); //~ error: `*mut ()` can't be used as a const parameter type + check(&() as *const ()); //~ error: `*const ()` can't be used as a const parameter type +} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr new file mode 100644 index 00000000000..de5704ee429 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr @@ -0,0 +1,87 @@ +error[E0277]: `fn() {main}` can't be used as a const parameter type + --> $DIR/const_param_ty_bad.rs:7:11 + | +LL | check(main); + | ----- ^^^^ the trait `ConstParamTy` is not implemented for fn item `fn() {main}` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/const_param_ty_bad.rs:4:18 + | +LL | fn check(_: impl std::marker::ConstParamTy) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error[E0277]: `[closure@$DIR/const_param_ty_bad.rs:8:11: 8:13]` can't be used as a const parameter type + --> $DIR/const_param_ty_bad.rs:8:11 + | +LL | check(|| {}); + | ----- ^^^^^ the trait `ConstParamTy` is not implemented for closure `[closure@$DIR/const_param_ty_bad.rs:8:11: 8:13]` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/const_param_ty_bad.rs:4:18 + | +LL | fn check(_: impl std::marker::ConstParamTy) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error[E0277]: `fn()` can't be used as a const parameter type + --> $DIR/const_param_ty_bad.rs:9:11 + | +LL | check(main as fn()); + | ----- ^^^^^^^^^^^^ the trait `ConstParamTy` is not implemented for `fn()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/const_param_ty_bad.rs:4:18 + | +LL | fn check(_: impl std::marker::ConstParamTy) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error[E0277]: `&mut ()` can't be used as a const parameter type + --> $DIR/const_param_ty_bad.rs:10:11 + | +LL | check(&mut ()); + | ----- ^^^^^^^ the trait `ConstParamTy` is not implemented for `&mut ()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/const_param_ty_bad.rs:4:18 + | +LL | fn check(_: impl std::marker::ConstParamTy) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error[E0277]: `*mut ()` can't be used as a const parameter type + --> $DIR/const_param_ty_bad.rs:11:11 + | +LL | check(&mut () as *mut ()); + | ----- ^^^^^^^^^^^^^^^^^^ the trait `ConstParamTy` is not implemented for `*mut ()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/const_param_ty_bad.rs:4:18 + | +LL | fn check(_: impl std::marker::ConstParamTy) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error[E0277]: `*const ()` can't be used as a const parameter type + --> $DIR/const_param_ty_bad.rs:12:11 + | +LL | check(&() as *const ()); + | ----- ^^^^^^^^^^^^^^^^ the trait `ConstParamTy` is not implemented for `*const ()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/const_param_ty_bad.rs:4:18 + | +LL | fn check(_: impl std::marker::ConstParamTy) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.rs new file mode 100644 index 00000000000..b0e3b13cc1e --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.rs @@ -0,0 +1,12 @@ +#![allow(incomplete_features)] +#![feature(adt_const_params)] + +#[derive(PartialEq, Eq)] +struct NotParam; + +fn check<T: std::marker::ConstParamTy>() {} + +fn main() { + check::<[NotParam; 0]>(); + //~^ error: `NotParam` can't be used as a const parameter type +} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr new file mode 100644 index 00000000000..ef55242df87 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr @@ -0,0 +1,16 @@ +error[E0277]: `NotParam` can't be used as a const parameter type + --> $DIR/const_param_ty_bad_empty_array.rs:10:13 + | +LL | check::<[NotParam; 0]>(); + | ^^^^^^^^^^^^^ the trait `ConstParamTy` is not implemented for `NotParam` + | + = note: required for `[NotParam; 0]` to implement `ConstParamTy` +note: required by a bound in `check` + --> $DIR/const_param_ty_bad_empty_array.rs:7:13 + | +LL | fn check<T: std::marker::ConstParamTy>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.rs new file mode 100644 index 00000000000..e4dc76703a2 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.rs @@ -0,0 +1,13 @@ +#![allow(incomplete_features)] +#![feature(adt_const_params)] + +#[derive(PartialEq, Eq)] +struct NotParam; + +fn check<T: std::marker::ConstParamTy + ?Sized>() {} + +fn main() { + check::<&NotParam>(); //~ error: `NotParam` can't be used as a const parameter type + check::<[NotParam]>(); //~ error: `NotParam` can't be used as a const parameter type + check::<[NotParam; 17]>(); //~ error: `NotParam` can't be used as a const parameter type +} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr new file mode 100644 index 00000000000..86d1c94e87f --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr @@ -0,0 +1,42 @@ +error[E0277]: `NotParam` can't be used as a const parameter type + --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:10:13 + | +LL | check::<&NotParam>(); + | ^^^^^^^^^ the trait `ConstParamTy` is not implemented for `NotParam` + | + = note: required for `&NotParam` to implement `ConstParamTy` +note: required by a bound in `check` + --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13 + | +LL | fn check<T: std::marker::ConstParamTy + ?Sized>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error[E0277]: `NotParam` can't be used as a const parameter type + --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:11:13 + | +LL | check::<[NotParam]>(); + | ^^^^^^^^^^ the trait `ConstParamTy` is not implemented for `NotParam` + | + = note: required for `[NotParam]` to implement `ConstParamTy` +note: required by a bound in `check` + --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13 + | +LL | fn check<T: std::marker::ConstParamTy + ?Sized>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error[E0277]: `NotParam` can't be used as a const parameter type + --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:12:13 + | +LL | check::<[NotParam; 17]>(); + | ^^^^^^^^^^^^^^ the trait `ConstParamTy` is not implemented for `NotParam` + | + = note: required for `[NotParam; 17]` to implement `ConstParamTy` +note: required by a bound in `check` + --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13 + | +LL | fn check<T: std::marker::ConstParamTy + ?Sized>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs new file mode 100644 index 00000000000..a1b711a3024 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs @@ -0,0 +1,43 @@ +// check-pass +#![allow(incomplete_features)] +#![feature(adt_const_params)] +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq)] +struct S<T> { + field: u8, + gen: T, +} + +impl<T: ConstParamTy> ConstParamTy for S<T> {} + +fn check<T: ConstParamTy + ?Sized>() {} + +fn main() { + check::<u8>(); + check::<u16>(); + check::<u32>(); + check::<u64>(); + check::<u128>(); + + check::<i8>(); + check::<i16>(); + check::<i32>(); + check::<i64>(); + check::<i128>(); + + check::<char>(); + check::<bool>(); + check::<str>(); + + check::<&u8>(); + check::<&str>(); + check::<[usize]>(); + check::<[u16; 0]>(); + check::<[u8; 42]>(); + + check::<S<u8>>(); + check::<S<[&[bool]; 8]>>(); + + // FIXME: test tuples +} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs new file mode 100644 index 00000000000..07fd243737e --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs @@ -0,0 +1,13 @@ +#![allow(incomplete_features)] +#![feature(adt_const_params)] + +#[derive(PartialEq, Eq)] +struct NotParam; + +#[derive(PartialEq, Eq)] +struct CantParam(NotParam); + +impl std::marker::ConstParamTy for CantParam {} +//~^ error: the trait `ConstParamTy` cannot be implemented for this type + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr new file mode 100644 index 00000000000..c8e065848b1 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr @@ -0,0 +1,12 @@ +error[E0204]: the trait `ConstParamTy` cannot be implemented for this type + --> $DIR/const_param_ty_impl_bad_field.rs:10:36 + | +LL | struct CantParam(NotParam); + | -------- this field does not implement `ConstParamTy` +LL | +LL | impl std::marker::ConstParamTy for CantParam {} + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0204`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs new file mode 100644 index 00000000000..17ef396164e --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -0,0 +1,17 @@ +#![allow(incomplete_features)] +#![feature(adt_const_params)] + +#[derive(PartialEq, Eq)] +struct ImplementsConstParamTy; +impl std::marker::ConstParamTy for ImplementsConstParamTy {} + +struct CantParam(ImplementsConstParamTy); + +impl std::marker::ConstParamTy for CantParam {} +//~^ error: the type `CantParam` does not `#[derive(Eq)]` + +fn check<T: std::marker::ConstParamTy>() {} + +fn main() { + check::<ImplementsConstParamTy>(); +} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr new file mode 100644 index 00000000000..ca5abf5e254 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr @@ -0,0 +1,12 @@ +error[E0277]: the type `CantParam` does not `#[derive(Eq)]` + --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36 + | +LL | impl std::marker::ConstParamTy for CantParam {} + | ^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParam` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs b/tests/ui/const-generics/assoc_const_eq_diagnostic.rs index 4d0aaf88e40..bf8202ac152 100644 --- a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs +++ b/tests/ui/const-generics/assoc_const_eq_diagnostic.rs @@ -10,6 +10,7 @@ pub trait Parse { pub trait CoolStuff: Parse<MODE = Mode::Cool> {} //~^ ERROR expected associated constant bound +//~| ERROR expected associated constant bound //~| ERROR expected type fn no_help() -> Mode::Cool {} diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr index ba727ee0ea3..d7e5e50cba8 100644 --- a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr +++ b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr @@ -8,7 +8,7 @@ LL | pub trait CoolStuff: Parse<MODE = Mode::Cool> {} | help: try using the variant's enum: `Mode` error[E0573]: expected type, found variant `Mode::Cool` - --> $DIR/assoc_const_eq_diagnostic.rs:15:17 + --> $DIR/assoc_const_eq_diagnostic.rs:16:17 | LL | fn no_help() -> Mode::Cool {} | ^^^^^^^^^^ @@ -28,6 +28,18 @@ note: associated constant defined here LL | const MODE: Mode; | ^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: expected associated constant bound, found type + --> $DIR/assoc_const_eq_diagnostic.rs:11:28 + | +LL | pub trait CoolStuff: Parse<MODE = Mode::Cool> {} + | ^^^^^^^^^^^^^^^^^ help: if equating a const, try wrapping with braces: `MODE = { const }` + | +note: associated constant defined here + --> $DIR/assoc_const_eq_diagnostic.rs:8:5 + | +LL | const MODE: Mode; + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr index 6b3396a25cf..3a7f3cd0ba0 100644 --- a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr +++ b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr @@ -8,6 +8,9 @@ LL | let _ = const_evaluatable_lib::test1::<T>(); note: required by a bound in `test1` --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | +LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1] + | ----- required by a bound in this function +LL | where LL | [u8; std::mem::size_of::<T>() - 1]: Sized, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1` @@ -34,6 +37,9 @@ LL | let _ = const_evaluatable_lib::test1::<T>(); note: required by a bound in `test1` --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | +LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1] + | ----- required by a bound in this function +LL | where LL | [u8; std::mem::size_of::<T>() - 1]: Sized, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1` diff --git a/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs b/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs index d45a6465b76..18a99398622 100644 --- a/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs +++ b/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs @@ -2,28 +2,30 @@ #![feature(generic_const_exprs)] #![allow(incomplete_features, unused_parens, unused_braces)] -fn zero_init<const N: usize>() -> Substs1<{ (N) }> +fn zero_init<const N: usize>() -> Substs1<{{ N }}> where - [u8; { (N) }]: , + [u8; {{ N }}]: , { - Substs1([0; { (N) }]) + Substs1([0; {{ N }}]) } -struct Substs1<const N: usize>([u8; { (N) }]) +struct Substs1<const N: usize>([u8; {{ N }}]) where - [(); { (N) }]: ; + [(); {{ N }}]: ; -fn substs2<const M: usize>() -> Substs1<{ (M) }> { - zero_init::<{ (M) }>() +fn substs2<const M: usize>() -> Substs1<{{ M }}> { + zero_init::<{{ M }}>() } -fn substs3<const L: usize>() -> Substs1<{ (L) }> { - substs2::<{ (L) }>() +fn substs3<const L: usize>() -> Substs1<{{ L }}> { + substs2::<{{ L }}>() } fn main() { assert_eq!(substs3::<2>().0, [0; 2]); } -// Test that the implicit ``{ (L) }`` bound on ``substs3`` satisfies the -// ``{ (N) }`` bound on ``Substs1`` +// Test that the implicit ``{{ L }}`` bound on ``substs3`` satisfies the +// ``{{ N }}`` bound on ``Substs1`` +// FIXME(generic_const_exprs): come up with a less brittle test for this using assoc consts +// once normalization is implemented for them. diff --git a/tests/ui/const-generics/nested-type.rs b/tests/ui/const-generics/nested-type.rs index 5240f5c3b0b..ff95018065a 100644 --- a/tests/ui/const-generics/nested-type.rs +++ b/tests/ui/const-generics/nested-type.rs @@ -3,7 +3,7 @@ #![cfg_attr(full, feature(adt_const_params))] #![cfg_attr(full, allow(incomplete_features))] -struct Foo<const N: [u8; { //[min]~ ERROR `[u8; _]` is forbidden +struct Foo<const N: [u8; { struct Foo<const N: usize>; impl<const N: usize> Foo<N> { @@ -15,5 +15,9 @@ struct Foo<const N: [u8; { //[min]~ ERROR `[u8; _]` is forbidden Foo::<17>::value() //~^ ERROR cannot call non-const fn }]>; +//[min]~^^^^^^^^^^^^ ERROR `[u8; { + +// N.B. it is important that the comment above is not inside the array length, +// otherwise it may check for itself, instead of the actual error fn main() {} diff --git a/tests/ui/const-generics/sneaky-array-repeat-expr.rs b/tests/ui/const-generics/sneaky-array-repeat-expr.rs index b147c246bda..cd1607608a6 100644 --- a/tests/ui/const-generics/sneaky-array-repeat-expr.rs +++ b/tests/ui/const-generics/sneaky-array-repeat-expr.rs @@ -10,6 +10,7 @@ impl<const N: usize> Trait<N> for () { pub const fn foo<const N: usize>() where (): Trait<N> { let bar = [(); <()>::Assoc]; //~^ error: constant expression depends on a generic parameter + //~| error: constant expression depends on a generic parameter } trait Trait2<const N: usize> { @@ -24,6 +25,7 @@ impl<const N: usize> Trait2<N> for () { pub const fn foo2<const N: usize>() where (): Trait2<N> { let bar2 = [(); <()>::Assoc2]; //~^ error: constant expression depends on a generic parameter + //~| error: constant expression depends on a generic parameter } fn main() { diff --git a/tests/ui/const-generics/sneaky-array-repeat-expr.stderr b/tests/ui/const-generics/sneaky-array-repeat-expr.stderr index 5c77375d399..e532f27a10d 100644 --- a/tests/ui/const-generics/sneaky-array-repeat-expr.stderr +++ b/tests/ui/const-generics/sneaky-array-repeat-expr.stderr @@ -7,12 +7,28 @@ LL | let bar = [(); <()>::Assoc]; = note: this may fail depending on what value the parameter takes error: constant expression depends on a generic parameter - --> $DIR/sneaky-array-repeat-expr.rs:25:21 + --> $DIR/sneaky-array-repeat-expr.rs:11:15 + | +LL | let bar = [(); <()>::Assoc]; + | ^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/sneaky-array-repeat-expr.rs:26:21 | LL | let bar2 = [(); <()>::Assoc2]; | ^^^^^^^^^^^^ | = note: this may fail depending on what value the parameter takes -error: aborting due to 2 previous errors +error: constant expression depends on a generic parameter + --> $DIR/sneaky-array-repeat-expr.rs:26:16 + | +LL | let bar2 = [(); <()>::Assoc2]; + | ^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 4 previous errors diff --git a/tests/ui/consts/const-prop-ice.rs b/tests/ui/const_prop/const-prop-ice.rs index 5bffe020629..5bffe020629 100644 --- a/tests/ui/consts/const-prop-ice.rs +++ b/tests/ui/const_prop/const-prop-ice.rs diff --git a/tests/ui/consts/const-prop-ice.stderr b/tests/ui/const_prop/const-prop-ice.stderr index 3bcf2b2de7b..3bcf2b2de7b 100644 --- a/tests/ui/consts/const-prop-ice.stderr +++ b/tests/ui/const_prop/const-prop-ice.stderr diff --git a/tests/ui/consts/const-prop-ice2.rs b/tests/ui/const_prop/const-prop-ice2.rs index d533e394c06..d533e394c06 100644 --- a/tests/ui/consts/const-prop-ice2.rs +++ b/tests/ui/const_prop/const-prop-ice2.rs diff --git a/tests/ui/consts/const-prop-ice2.stderr b/tests/ui/const_prop/const-prop-ice2.stderr index 2b65ffc2db7..2b65ffc2db7 100644 --- a/tests/ui/consts/const-prop-ice2.stderr +++ b/tests/ui/const_prop/const-prop-ice2.stderr diff --git a/tests/ui/consts/const-prop-ice3.rs b/tests/ui/const_prop/const-prop-ice3.rs index 8ab011661e3..8ab011661e3 100644 --- a/tests/ui/consts/const-prop-ice3.rs +++ b/tests/ui/const_prop/const-prop-ice3.rs diff --git a/tests/ui/consts/const-prop-overflowing-casts.rs b/tests/ui/const_prop/const-prop-overflowing-casts.rs index 8cc5b98250b..8cc5b98250b 100644 --- a/tests/ui/consts/const-prop-overflowing-casts.rs +++ b/tests/ui/const_prop/const-prop-overflowing-casts.rs diff --git a/tests/ui/consts/const-prop-read-static-in-const.rs b/tests/ui/const_prop/const-prop-read-static-in-const.rs index 21426205955..21426205955 100644 --- a/tests/ui/consts/const-prop-read-static-in-const.rs +++ b/tests/ui/const_prop/const-prop-read-static-in-const.rs diff --git a/tests/ui/consts/const-prop-read-static-in-const.stderr b/tests/ui/const_prop/const-prop-read-static-in-const.stderr index 793da628587..793da628587 100644 --- a/tests/ui/consts/const-prop-read-static-in-const.stderr +++ b/tests/ui/const_prop/const-prop-read-static-in-const.stderr diff --git a/tests/ui/const_prop/unsized-local-ice.rs b/tests/ui/const_prop/unsized-local-ice.rs new file mode 100644 index 00000000000..c725b3238ea --- /dev/null +++ b/tests/ui/const_prop/unsized-local-ice.rs @@ -0,0 +1,9 @@ +// build-pass +//! Regression test for <https://github.com/rust-lang/rust/issues/68538>. +#![feature(unsized_fn_params)] + +pub fn take_unsized_slice(s: [u8]) { + s[0]; +} + +fn main() {} diff --git a/tests/ui/consts/auxiliary/external_macro.rs b/tests/ui/consts/auxiliary/external_macro.rs index d260634c996..fea24703dda 100644 --- a/tests/ui/consts/auxiliary/external_macro.rs +++ b/tests/ui/consts/auxiliary/external_macro.rs @@ -9,6 +9,6 @@ macro_rules! static_assert { ($test:expr) => { #[allow(dead_code)] - const _: () = [()][!($test: bool) as usize]; + const _: () = [()][!($test) as usize]; } } diff --git a/tests/ui/consts/const-block-const-bound.rs b/tests/ui/consts/const-block-const-bound.rs index 42aa0216b87..3704a1a5a39 100644 --- a/tests/ui/consts/const-block-const-bound.rs +++ b/tests/ui/consts/const-block-const-bound.rs @@ -11,15 +11,9 @@ impl Drop for UnconstDrop { fn drop(&mut self) {} } -struct NonDrop; - -impl !Drop for NonDrop {} - fn main() { const { f(UnconstDrop); //~^ ERROR can't drop - f(NonDrop); - //~^ ERROR can't drop } } diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr index fef4914fad5..caf24e7afcf 100644 --- a/tests/ui/consts/const-block-const-bound.stderr +++ b/tests/ui/consts/const-block-const-bound.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `UnconstDrop` in const contexts - --> $DIR/const-block-const-bound.rs:20:9 + --> $DIR/const-block-const-bound.rs:16:9 | LL | f(UnconstDrop); | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop` @@ -12,20 +12,6 @@ LL | &f(UnconstDrop); LL | &mut f(UnconstDrop); | ++++ -error[E0277]: can't drop `NonDrop` in const contexts - --> $DIR/const-block-const-bound.rs:22:9 - | -LL | f(NonDrop); - | ^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonDrop` - | - = note: the trait bound `NonDrop: ~const Destruct` is not satisfied -help: consider borrowing here - | -LL | &f(NonDrop); - | + -LL | &mut f(NonDrop); - | ++++ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/issue-50439.rs b/tests/ui/consts/issue-50439.rs index 0be7c405473..d42347e136e 100644 --- a/tests/ui/consts/issue-50439.rs +++ b/tests/ui/consts/issue-50439.rs @@ -22,7 +22,9 @@ impl<T: Sized> PinDropInternal for Bears<T> { where Self: ReflectDrop, { - let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize]; //~ ERROR constant expression depends on a generic parameter + let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize]; + //~^ ERROR constant expression depends on a generic parameter + //~| ERROR constant expression depends on a generic parameter } } diff --git a/tests/ui/consts/issue-50439.stderr b/tests/ui/consts/issue-50439.stderr index 3fbdf33b2d8..7a8cd45ecc7 100644 --- a/tests/ui/consts/issue-50439.stderr +++ b/tests/ui/consts/issue-50439.stderr @@ -6,5 +6,13 @@ LL | let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usi | = note: this may fail depending on what value the parameter takes -error: aborting due to previous error +error: constant expression depends on a generic parameter + --> $DIR/issue-50439.rs:25:17 + | +LL | let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors diff --git a/tests/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr b/tests/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr index a3c607b5903..6d92fa5e14e 100644 --- a/tests/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr +++ b/tests/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr @@ -65,6 +65,7 @@ error: unexpected `,` in pattern LL | let women, men: (Vec<Genome>, Vec<Genome>) = genomes.iter().cloned() | ^ | + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> help: try adding parentheses to match on a tuple | LL | let (women, men): (Vec<Genome>, Vec<Genome>) = genomes.iter().cloned() diff --git a/tests/ui/dropck/explicit-drop-bounds.bad1.stderr b/tests/ui/dropck/explicit-drop-bounds.bad1.stderr new file mode 100644 index 00000000000..3b506c7e7ec --- /dev/null +++ b/tests/ui/dropck/explicit-drop-bounds.bad1.stderr @@ -0,0 +1,35 @@ +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/explicit-drop-bounds.rs:27:18 + | +LL | impl<T> Drop for DropMe<T> + | ^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `DropMe` + --> $DIR/explicit-drop-bounds.rs:7:18 + | +LL | struct DropMe<T: Copy>(T); + | ^^^^ required by this bound in `DropMe` +help: consider further restricting type parameter `T` + | +LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy` + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/explicit-drop-bounds.rs:32:13 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `DropMe` + --> $DIR/explicit-drop-bounds.rs:7:18 + | +LL | struct DropMe<T: Copy>(T); + | ^^^^ required by this bound in `DropMe` +help: consider further restricting type parameter `T` + | +LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy` + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dropck/explicit-drop-bounds.bad2.stderr b/tests/ui/dropck/explicit-drop-bounds.bad2.stderr new file mode 100644 index 00000000000..832af3e521a --- /dev/null +++ b/tests/ui/dropck/explicit-drop-bounds.bad2.stderr @@ -0,0 +1,35 @@ +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/explicit-drop-bounds.rs:37:18 + | +LL | impl<T> Drop for DropMe<T> + | ^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `DropMe` + --> $DIR/explicit-drop-bounds.rs:7:18 + | +LL | struct DropMe<T: Copy>(T); + | ^^^^ required by this bound in `DropMe` +help: consider restricting type parameter `T` + | +LL | impl<T: std::marker::Copy> Drop for DropMe<T> + | +++++++++++++++++++ + +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/explicit-drop-bounds.rs:40:13 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `DropMe` + --> $DIR/explicit-drop-bounds.rs:7:18 + | +LL | struct DropMe<T: Copy>(T); + | ^^^^ required by this bound in `DropMe` +help: consider restricting type parameter `T` + | +LL | impl<T: std::marker::Copy> Drop for DropMe<T> + | +++++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dropck/explicit-drop-bounds.rs b/tests/ui/dropck/explicit-drop-bounds.rs new file mode 100644 index 00000000000..ab6f33c0999 --- /dev/null +++ b/tests/ui/dropck/explicit-drop-bounds.rs @@ -0,0 +1,44 @@ +// revisions: good1 good2 bad1 bad2 +//[good1] check-pass +//[good2] check-pass + +use std::ops::Drop; + +struct DropMe<T: Copy>(T); + +#[cfg(good1)] +impl<T> Drop for DropMe<T> +where + T: Copy + Clone, +{ + fn drop(&mut self) {} +} + +#[cfg(good2)] +impl<T> Drop for DropMe<T> +where + T: Copy, + [T; 1]: Copy, // Trivial bound implied by `T: Copy` +{ + fn drop(&mut self) {} +} + +#[cfg(bad1)] +impl<T> Drop for DropMe<T> +//[bad1]~^ ERROR the trait bound `T: Copy` is not satisfied +where + [T; 1]: Copy, // But `[T; 1]: Copy` does not imply `T: Copy` +{ + fn drop(&mut self) {} + //[bad1]~^ ERROR the trait bound `T: Copy` is not satisfied +} + +#[cfg(bad2)] +impl<T> Drop for DropMe<T> +//[bad2]~^ ERROR the trait bound `T: Copy` is not satisfied +{ + fn drop(&mut self) {} + //[bad2]~^ ERROR the trait bound `T: Copy` is not satisfied +} + +fn main() {} diff --git a/tests/ui/dropck/explicit-implied-outlives.bad1.stderr b/tests/ui/dropck/explicit-implied-outlives.bad1.stderr new file mode 100644 index 00000000000..bf6d70e7d37 --- /dev/null +++ b/tests/ui/dropck/explicit-implied-outlives.bad1.stderr @@ -0,0 +1,15 @@ +error[E0367]: `Drop` impl requires `T: 'static` but the struct it is implemented for does not + --> $DIR/explicit-implied-outlives.rs:28:8 + | +LL | T: 'static, + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/explicit-implied-outlives.rs:7:1 + | +LL | struct DropMe<'a, T>(&'a T); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0367`. diff --git a/tests/ui/dropck/explicit-implied-outlives.bad2.stderr b/tests/ui/dropck/explicit-implied-outlives.bad2.stderr new file mode 100644 index 00000000000..27a15170bdd --- /dev/null +++ b/tests/ui/dropck/explicit-implied-outlives.bad2.stderr @@ -0,0 +1,15 @@ +error[E0367]: `Drop` impl requires `'a: 'static` but the struct it is implemented for does not + --> $DIR/explicit-implied-outlives.rs:37:9 + | +LL | 'a: 'static, + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/explicit-implied-outlives.rs:7:1 + | +LL | struct DropMe<'a, T>(&'a T); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0367`. diff --git a/tests/ui/dropck/explicit-implied-outlives.rs b/tests/ui/dropck/explicit-implied-outlives.rs new file mode 100644 index 00000000000..fa446591f3d --- /dev/null +++ b/tests/ui/dropck/explicit-implied-outlives.rs @@ -0,0 +1,43 @@ +// revisions: good1 good2 bad1 bad2 +//[good1] check-pass +//[good2] check-pass + +use std::ops::Drop; + +struct DropMe<'a, T>(&'a T); + +#[cfg(good1)] +impl<'a, T> Drop for DropMe<'a, T> +where + T: 'a, // Implied by struct, explicit on impl +{ + fn drop(&mut self) {} +} + +#[cfg(good2)] +impl<'a, T> Drop for DropMe<'a, T> +where + 'static: 'a, // Trivial bound +{ + fn drop(&mut self) {} +} + +#[cfg(bad1)] +impl<'a, T> Drop for DropMe<'a, T> +where + T: 'static, + //[bad1]~^ ERROR `Drop` impl requires `T: 'static` +{ + fn drop(&mut self) {} +} + +#[cfg(bad2)] +impl<'a, T> Drop for DropMe<'a, T> +where + 'a: 'static, + //[bad2]~^ ERROR `Drop` impl requires `'a: 'static` +{ + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/dropck/negative.rs b/tests/ui/dropck/negative.rs new file mode 100644 index 00000000000..ae63632b55e --- /dev/null +++ b/tests/ui/dropck/negative.rs @@ -0,0 +1,7 @@ +#![feature(negative_impls)] + +struct NonDrop; +impl !Drop for NonDrop {} +//~^ ERROR negative `Drop` impls are not supported + +fn main() {} diff --git a/tests/ui/dropck/negative.stderr b/tests/ui/dropck/negative.stderr new file mode 100644 index 00000000000..d613e30b5ea --- /dev/null +++ b/tests/ui/dropck/negative.stderr @@ -0,0 +1,8 @@ +error: negative `Drop` impls are not supported + --> $DIR/negative.rs:4:1 + | +LL | impl !Drop for NonDrop {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/dropck/reservation.rs b/tests/ui/dropck/reservation.rs new file mode 100644 index 00000000000..f7199d4ec44 --- /dev/null +++ b/tests/ui/dropck/reservation.rs @@ -0,0 +1,10 @@ +#![feature(rustc_attrs)] + +struct ReservedDrop; +#[rustc_reservation_impl = "message"] +impl Drop for ReservedDrop { +//~^ ERROR reservation `Drop` impls are not supported + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/dropck/reservation.stderr b/tests/ui/dropck/reservation.stderr new file mode 100644 index 00000000000..19325d6ed44 --- /dev/null +++ b/tests/ui/dropck/reservation.stderr @@ -0,0 +1,8 @@ +error: reservation `Drop` impls are not supported + --> $DIR/reservation.rs:5:1 + | +LL | impl Drop for ReservedDrop { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/dropck/transitive-outlives-2.rs b/tests/ui/dropck/transitive-outlives-2.rs new file mode 100644 index 00000000000..87154e25d40 --- /dev/null +++ b/tests/ui/dropck/transitive-outlives-2.rs @@ -0,0 +1,18 @@ +// check-pass + +use std::marker::PhantomData; +use std::ops::Drop; + +// a >= b >= c >= a implies a = b = c +struct DropMe<'a: 'b, 'b: 'c, 'c: 'a>( + PhantomData<&'a ()>, + PhantomData<&'b ()>, + PhantomData<&'c ()>, +); + +// a >= b, a >= c, b >= a, c >= a implies a = b = c +impl<'a: 'b + 'c, 'b: 'a, 'c: 'a> Drop for DropMe<'a, 'b, 'c> { + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/dropck/transitive-outlives.bad.stderr b/tests/ui/dropck/transitive-outlives.bad.stderr new file mode 100644 index 00000000000..da5088b27b4 --- /dev/null +++ b/tests/ui/dropck/transitive-outlives.bad.stderr @@ -0,0 +1,15 @@ +error[E0367]: `Drop` impl requires `'a: 'c` but the struct it is implemented for does not + --> $DIR/transitive-outlives.rs:20:9 + | +LL | 'a: 'c, + | ^^ + | +note: the implementor must specify the same requirement + --> $DIR/transitive-outlives.rs:7:1 + | +LL | struct DropMe<'a, 'b: 'a, 'c: 'b>(PhantomData<&'a ()>, PhantomData<&'b ()>, PhantomData<&'c ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0367`. diff --git a/tests/ui/dropck/transitive-outlives.rs b/tests/ui/dropck/transitive-outlives.rs new file mode 100644 index 00000000000..d071664abde --- /dev/null +++ b/tests/ui/dropck/transitive-outlives.rs @@ -0,0 +1,26 @@ +// revisions: good bad +//[good] check-pass + +use std::marker::PhantomData; +use std::ops::Drop; + +struct DropMe<'a, 'b: 'a, 'c: 'b>(PhantomData<&'a ()>, PhantomData<&'b ()>, PhantomData<&'c ()>); + +#[cfg(good)] +impl<'a, 'b, 'c> Drop for DropMe<'a, 'b, 'c> +where + 'c: 'a, +{ + fn drop(&mut self) {} +} + +#[cfg(bad)] +impl<'a, 'b, 'c> Drop for DropMe<'a, 'b, 'c> +where + 'a: 'c, + //[bad]~^ ERROR `Drop` impl requires `'a: 'c` +{ + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/dropck/trivial-impl-bounds.rs b/tests/ui/dropck/trivial-impl-bounds.rs new file mode 100644 index 00000000000..a8f5d2c354b --- /dev/null +++ b/tests/ui/dropck/trivial-impl-bounds.rs @@ -0,0 +1,34 @@ +// revisions: good1 good2 good3 +// check-pass + +use std::ops::Drop; + +struct Foo; + +const X: usize = 1; + +#[cfg(good1)] +impl Drop for Foo +where + [(); X]:, // Trivial WF bound +{ + fn drop(&mut self) {} +} + +#[cfg(good2)] +impl Drop for Foo +where + for<'a> &'a (): Copy, // Trivial trait bound +{ + fn drop(&mut self) {} +} + +#[cfg(good3)] +impl Drop for Foo +where + for<'a> &'a (): 'a, // Trivial outlives bound +{ + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/error-codes/E0277.stderr b/tests/ui/error-codes/E0277.stderr index 2b4784d7ecc..440e43dff81 100644 --- a/tests/ui/error-codes/E0277.stderr +++ b/tests/ui/error-codes/E0277.stderr @@ -5,7 +5,8 @@ LL | fn f(p: Path) { } | ^ doesn't have a size known at compile-time | = help: within `Path`, the trait `Sized` is not implemented for `[u8]` - = note: required because it appears within the type `Path` +note: required because it appears within the type `Path` + --> $SRC_DIR/std/src/path.rs:LL:COL = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size | diff --git a/tests/ui/error-codes/E0719.rs b/tests/ui/error-codes/E0719.rs index 3311e190937..cbf1bb219a0 100644 --- a/tests/ui/error-codes/E0719.rs +++ b/tests/ui/error-codes/E0719.rs @@ -1,5 +1,6 @@ trait Foo: Iterator<Item = i32, Item = i32> {} //~^ ERROR is already specified +//~| ERROR is already specified type Unit = (); diff --git a/tests/ui/error-codes/E0719.stderr b/tests/ui/error-codes/E0719.stderr index b342d634334..e302f406d02 100644 --- a/tests/ui/error-codes/E0719.stderr +++ b/tests/ui/error-codes/E0719.stderr @@ -7,13 +7,21 @@ LL | trait Foo: Iterator<Item = i32, Item = i32> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/E0719.rs:6:42 + --> $DIR/E0719.rs:1:33 + | +LL | trait Foo: Iterator<Item = i32, Item = i32> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/E0719.rs:7:42 | LL | fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> { | --------- ^^^^^^^^^^^ re-bound here | | | `Item` bound here first -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0719`. diff --git a/tests/ui/extern-flag/auxiliary/panic_handler.rs b/tests/ui/extern-flag/auxiliary/panic_handler.rs new file mode 100644 index 00000000000..a625761a838 --- /dev/null +++ b/tests/ui/extern-flag/auxiliary/panic_handler.rs @@ -0,0 +1,17 @@ +#![feature(lang_items)] +#![no_std] + +// Since `rustc` generally passes `-nodefaultlibs` to the linker, +// Rust programs link necessary system libraries via `#[link()]` +// attributes in the `libc` crate. `libc` is a dependency of `std`, +// but as we are `#![no_std]`, we need to include it manually. +#![feature(rustc_private)] +extern crate libc; + +#[panic_handler] +pub fn begin_panic_handler(_info: &core::panic::PanicInfo<'_>) -> ! { + loop {} +} + +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} diff --git a/tests/ui/extern-flag/force-extern.rs b/tests/ui/extern-flag/force-extern.rs new file mode 100644 index 00000000000..f56b5378223 --- /dev/null +++ b/tests/ui/extern-flag/force-extern.rs @@ -0,0 +1,9 @@ +// check-pass +// ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header) +// aux-crate:force:panic_handler=panic_handler.rs +// compile-flags: -Zunstable-options --crate-type dylib +// edition:2018 + +#![no_std] + +fn foo() {} diff --git a/tests/ui/extern-flag/no-force-extern.rs b/tests/ui/extern-flag/no-force-extern.rs new file mode 100644 index 00000000000..ce9cbfe1cd2 --- /dev/null +++ b/tests/ui/extern-flag/no-force-extern.rs @@ -0,0 +1,10 @@ +// aux-crate:panic_handler=panic_handler.rs +// ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header) +// compile_flags: -Zunstable-options --crate-type dylib +// error-pattern: `#[panic_handler]` function required, but not found +// dont-check-compiler-stderr +// edition: 2018 + +#![no_std] + +fn foo() {} diff --git a/tests/ui/extern-flag/redundant-force-extern.rs b/tests/ui/extern-flag/redundant-force-extern.rs new file mode 100644 index 00000000000..a4091616dd5 --- /dev/null +++ b/tests/ui/extern-flag/redundant-force-extern.rs @@ -0,0 +1,11 @@ +// check-pass +// ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header) +// aux-crate:force:panic_handler=panic_handler.rs +// compile-flags: -Zunstable-options --crate-type dylib +// edition:2018 + +#![no_std] + +extern crate panic_handler; + +fn foo() {} diff --git a/tests/ui/feature-gates/feature-gate-cfi_encoding.rs b/tests/ui/feature-gates/feature-gate-cfi_encoding.rs new file mode 100644 index 00000000000..3cef8156014 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfi_encoding.rs @@ -0,0 +1,4 @@ +#![crate_type = "lib"] + +#[cfi_encoding = "3Bar"] //~ERROR 3:1: 3:25: the `#[cfi_encoding]` attribute is an experimental feature [E0658] +pub struct Foo(i32); diff --git a/tests/ui/feature-gates/feature-gate-cfi_encoding.stderr b/tests/ui/feature-gates/feature-gate-cfi_encoding.stderr new file mode 100644 index 00000000000..b10a1508881 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfi_encoding.stderr @@ -0,0 +1,12 @@ +error[E0658]: the `#[cfi_encoding]` attribute is an experimental feature + --> $DIR/feature-gate-cfi_encoding.rs:3:1 + | +LL | #[cfi_encoding = "3Bar"] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #89653 <https://github.com/rust-lang/rust/issues/89653> for more information + = help: add `#![feature(cfi_encoding)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-debugger-visualizer.rs b/tests/ui/feature-gates/feature-gate-debugger-visualizer.rs deleted file mode 100644 index 4c4dc450d18..00000000000 --- a/tests/ui/feature-gates/feature-gate-debugger-visualizer.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![debugger_visualizer(natvis_file = "auxiliary/debugger-visualizer.natvis")] //~ ERROR the `#[debugger_visualizer]` attribute is an experimental feature - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-debugger-visualizer.stderr b/tests/ui/feature-gates/feature-gate-debugger-visualizer.stderr deleted file mode 100644 index e9367fbc6c9..00000000000 --- a/tests/ui/feature-gates/feature-gate-debugger-visualizer.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: the `#[debugger_visualizer]` attribute is an experimental feature - --> $DIR/feature-gate-debugger-visualizer.rs:1:1 - | -LL | #![debugger_visualizer(natvis_file = "auxiliary/debugger-visualizer.natvis")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95939 <https://github.com/rust-lang/rust/issues/95939> for more information - = help: add `#![feature(debugger_visualizer)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-negative_bounds.rs b/tests/ui/feature-gates/feature-gate-negative_bounds.rs new file mode 100644 index 00000000000..533cb0ce5bc --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-negative_bounds.rs @@ -0,0 +1,4 @@ +fn test<T: !Copy>() {} +//~^ ERROR negative bounds are not supported + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-negative_bounds.stderr b/tests/ui/feature-gates/feature-gate-negative_bounds.stderr new file mode 100644 index 00000000000..ae010fdf3f8 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-negative_bounds.stderr @@ -0,0 +1,8 @@ +error: negative bounds are not supported + --> $DIR/feature-gate-negative_bounds.rs:1:12 + | +LL | fn test<T: !Copy>() {} + | ^ + +error: aborting due to previous error + diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-2.rs b/tests/ui/feature-gates/feature-gate-raw-dylib-2.rs deleted file mode 100644 index fc47a9061d3..00000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// only-x86 -#[link(name = "foo")] -extern "C" { - #[link_ordinal(42)] - //~^ ERROR: `#[link_ordinal]` is unstable on x86 - fn foo(); - #[link_ordinal(5)] - //~^ ERROR: `#[link_ordinal]` is unstable on x86 - static mut imported_variable: i32; -} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-2.stderr b/tests/ui/feature-gates/feature-gate-raw-dylib-2.stderr deleted file mode 100644 index 0e900760d24..00000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib-2.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: `#[link_ordinal]` is unstable on x86 - --> $DIR/feature-gate-raw-dylib-2.rs:4:5 - | -LL | #[link_ordinal(42)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error[E0658]: `#[link_ordinal]` is unstable on x86 - --> $DIR/feature-gate-raw-dylib-2.rs:7:5 - | -LL | #[link_ordinal(5)] - | ^^^^^^^^^^^^^^^^^^ - | - = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs b/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs deleted file mode 100644 index 295f502d6a3..00000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs +++ /dev/null @@ -1,8 +0,0 @@ -// only-windows -// only-x86 -#[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")] -//~^ ERROR link kind `raw-dylib` is unstable on x86 -//~| ERROR import name type is unstable -extern "C" {} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr b/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr deleted file mode 100644 index d6b165b7610..00000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: link kind `raw-dylib` is unstable on x86 - --> $DIR/feature-gate-raw-dylib-import-name-type.rs:3:29 - | -LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")] - | ^^^^^^^^^^^ - | - = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error[E0658]: import name type is unstable - --> $DIR/feature-gate-raw-dylib-import-name-type.rs:3:61 - | -LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")] - | ^^^^^^^^^^^ - | - = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib.rs b/tests/ui/feature-gates/feature-gate-raw-dylib.rs deleted file mode 100644 index 291cca8fd25..00000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib.rs +++ /dev/null @@ -1,7 +0,0 @@ -// only-windows -// only-x86 -#[link(name = "foo", kind = "raw-dylib")] -//~^ ERROR: link kind `raw-dylib` is unstable on x86 -extern "C" {} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib.stderr b/tests/ui/feature-gates/feature-gate-raw-dylib.stderr deleted file mode 100644 index f02241e4908..00000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: link kind `raw-dylib` is unstable on x86 - --> $DIR/feature-gate-raw-dylib.rs:3:29 - | -LL | #[link(name = "foo", kind = "raw-dylib")] - | ^^^^^^^^^^^ - | - = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr index c3a371e25e8..1bdb2574ead 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr @@ -1,5 +1,5 @@ error[E0658]: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:15:17 + --> $DIR/feature-gate-return_type_notation.rs:14:17 | LL | fn foo<T: Trait<m(): Send>>() {} | ^^^^^^^^^ @@ -7,17 +7,8 @@ LL | fn foo<T: Trait<m(): Send>>() {} = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = help: add `#![feature(return_type_notation)]` to the crate attributes to enable -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/feature-gate-return_type_notation.rs:7:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/feature-gate-return_type_notation.rs:15:17 + --> $DIR/feature-gate-return_type_notation.rs:14:17 | LL | fn foo<T: Trait<m(): Send>>() {} | ^-- @@ -25,12 +16,12 @@ LL | fn foo<T: Trait<m(): Send>>() {} | help: remove these parentheses error[E0220]: associated type `m` not found for `Trait` - --> $DIR/feature-gate-return_type_notation.rs:15:17 + --> $DIR/feature-gate-return_type_notation.rs:14:17 | LL | fn foo<T: Trait<m(): Send>>() {} | ^ associated type `m` not found -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors Some errors have detailed explanations: E0220, E0658. For more information about an error, try `rustc --explain E0220`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr index 52c90c1565c..dd6ebb61038 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr @@ -1,14 +1,5 @@ -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/feature-gate-return_type_notation.rs:7:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - warning: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:15:17 + --> $DIR/feature-gate-return_type_notation.rs:14:17 | LL | fn foo<T: Trait<m(): Send>>() {} | ^^^^^^^^^ @@ -18,5 +9,5 @@ LL | fn foo<T: Trait<m(): Send>>() {} = warning: unstable syntax can change at any point in the future, causing a hard error! = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860> -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.rs b/tests/ui/feature-gates/feature-gate-return_type_notation.rs index 5028b9ec9e3..d9bcb65feba 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.rs +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.rs @@ -5,7 +5,6 @@ // Since we're not adding new syntax, `cfg`'d out RTN must pass. #![feature(async_fn_in_trait)] -//~^ WARN the feature `async_fn_in_trait` is incomplete trait Trait { async fn m(); diff --git a/tests/ui/unwind-abis/feature-gate-thiscall-unwind.rs b/tests/ui/feature-gates/feature-gate-thiscall.rs index 0a323e50fcf..97a732bcff7 100644 --- a/tests/ui/unwind-abis/feature-gate-thiscall-unwind.rs +++ b/tests/ui/feature-gates/feature-gate-thiscall.rs @@ -1,5 +1,4 @@ // gate-test-abi_thiscall -// gate-test-c_unwind // needs-llvm-components: x86 // compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib #![no_core] @@ -7,8 +6,8 @@ #[lang="sized"] trait Sized { } -// Test that the "thiscall-unwind" ABI is feature-gated, and cannot be used when -// the `c_unwind` feature gate is not used. +// Test that the "thiscall" ABI is feature-gated, and cannot be used when +// the `abi_thiscall` feature gate is not used. extern "thiscall-unwind" fn fu() {} //~ ERROR thiscall-unwind ABI is experimental extern "thiscall" fn f() {} //~ ERROR thiscall is experimental diff --git a/tests/ui/unwind-abis/feature-gate-thiscall-unwind.stderr b/tests/ui/feature-gates/feature-gate-thiscall.stderr index 9ca00a55cd8..346e45952cd 100644 --- a/tests/ui/unwind-abis/feature-gate-thiscall-unwind.stderr +++ b/tests/ui/feature-gates/feature-gate-thiscall.stderr @@ -1,14 +1,13 @@ error[E0658]: thiscall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:13:8 + --> $DIR/feature-gate-thiscall.rs:12:8 | LL | extern "thiscall-unwind" fn fu() {} | ^^^^^^^^^^^^^^^^^ | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:14:8 + --> $DIR/feature-gate-thiscall.rs:13:8 | LL | extern "thiscall" fn f() {} | ^^^^^^^^^^ @@ -16,7 +15,7 @@ LL | extern "thiscall" fn f() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:17:12 + --> $DIR/feature-gate-thiscall.rs:16:12 | LL | extern "thiscall" fn m(); | ^^^^^^^^^^ @@ -24,16 +23,15 @@ LL | extern "thiscall" fn m(); = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:18:12 + --> $DIR/feature-gate-thiscall.rs:17:12 | LL | extern "thiscall-unwind" fn mu(); | ^^^^^^^^^^^^^^^^^ | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:20:12 + --> $DIR/feature-gate-thiscall.rs:19:12 | LL | extern "thiscall" fn dm() {} | ^^^^^^^^^^ @@ -41,16 +39,15 @@ LL | extern "thiscall" fn dm() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:21:12 + --> $DIR/feature-gate-thiscall.rs:20:12 | LL | extern "thiscall-unwind" fn dmu() {} | ^^^^^^^^^^^^^^^^^ | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:26:12 + --> $DIR/feature-gate-thiscall.rs:25:12 | LL | extern "thiscall" fn m() {} | ^^^^^^^^^^ @@ -58,16 +55,15 @@ LL | extern "thiscall" fn m() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:27:12 + --> $DIR/feature-gate-thiscall.rs:26:12 | LL | extern "thiscall-unwind" fn mu() {} | ^^^^^^^^^^^^^^^^^ | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:31:12 + --> $DIR/feature-gate-thiscall.rs:30:12 | LL | extern "thiscall" fn im() {} | ^^^^^^^^^^ @@ -75,16 +71,15 @@ LL | extern "thiscall" fn im() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:32:12 + --> $DIR/feature-gate-thiscall.rs:31:12 | LL | extern "thiscall-unwind" fn imu() {} | ^^^^^^^^^^^^^^^^^ | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:35:18 + --> $DIR/feature-gate-thiscall.rs:34:18 | LL | type TA = extern "thiscall" fn(); | ^^^^^^^^^^ @@ -92,16 +87,15 @@ LL | type TA = extern "thiscall" fn(); = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:36:19 + --> $DIR/feature-gate-thiscall.rs:35:19 | LL | type TAU = extern "thiscall-unwind" fn(); | ^^^^^^^^^^^^^^^^^ | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:38:8 + --> $DIR/feature-gate-thiscall.rs:37:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ @@ -109,13 +103,12 @@ LL | extern "thiscall" {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: thiscall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-thiscall-unwind.rs:39:8 + --> $DIR/feature-gate-thiscall.rs:38:8 | LL | extern "thiscall-unwind" {} | ^^^^^^^^^^^^^^^^^ | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error: aborting due to 14 previous errors diff --git a/tests/ui/feature-gates/feature-gate-type_ascription.rs b/tests/ui/feature-gates/feature-gate-type_ascription.rs index 7a597157300..5c3f0e37df6 100644 --- a/tests/ui/feature-gates/feature-gate-type_ascription.rs +++ b/tests/ui/feature-gates/feature-gate-type_ascription.rs @@ -1,5 +1,5 @@ // Type ascription is unstable fn main() { - let a = 10: u8; //~ ERROR type ascription is experimental + let a = type_ascribe!(10, u8); //~ ERROR use of unstable library feature 'type_ascription': placeholder syntax for type ascription } diff --git a/tests/ui/feature-gates/feature-gate-type_ascription.stderr b/tests/ui/feature-gates/feature-gate-type_ascription.stderr index 615d5b9a1e0..d747aea6d17 100644 --- a/tests/ui/feature-gates/feature-gate-type_ascription.stderr +++ b/tests/ui/feature-gates/feature-gate-type_ascription.stderr @@ -1,8 +1,8 @@ -error[E0658]: type ascription is experimental +error[E0658]: use of unstable library feature 'type_ascription': placeholder syntax for type ascription --> $DIR/feature-gate-type_ascription.rs:4:13 | -LL | let a = 10: u8; - | ^^^^^^ +LL | let a = type_ascribe!(10, u8); + | ^^^^^^^^^^^^ | = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information = help: add `#![feature(type_ascription)]` to the crate attributes to enable diff --git a/tests/ui/feature-gates/feature-gate-vectorcall.rs b/tests/ui/feature-gates/feature-gate-vectorcall.rs index 5a6c6d28804..706780dfd6c 100644 --- a/tests/ui/feature-gates/feature-gate-vectorcall.rs +++ b/tests/ui/feature-gates/feature-gate-vectorcall.rs @@ -6,8 +6,8 @@ #[lang="sized"] trait Sized { } -// Test that the "vectorcall-unwind" ABI is feature-gated, and cannot be used when -// the `c_unwind` feature gate is not used. +// Test that the "vectorcall" ABI is feature-gated, and cannot be used when +// the `vectorcall` feature gate is not used. extern "vectorcall" fn f() {} //~ ERROR vectorcall is experimental diff --git a/tests/ui/fmt/format-string-error.rs b/tests/ui/fmt/format-string-error.rs index eae4f3cb547..9b436e2c479 100644 --- a/tests/ui/fmt/format-string-error.rs +++ b/tests/ui/fmt/format-string-error.rs @@ -17,7 +17,7 @@ fn main() { let _ = format!("}"); //~^ ERROR invalid format string: unmatched `}` found let _ = format!("{\\}"); - //~^ ERROR invalid format string: expected `'}'`, found `'\\'` + //~^ ERROR invalid format string: expected `'}'`, found `'\'` let _ = format!("\n\n\n{\n\n\n"); //~^ ERROR invalid format string let _ = format!(r###" diff --git a/tests/ui/fmt/send-sync.stderr b/tests/ui/fmt/send-sync.stderr index b517a342e63..e3ebe6cdcb8 100644 --- a/tests/ui/fmt/send-sync.stderr +++ b/tests/ui/fmt/send-sync.stderr @@ -8,10 +8,12 @@ LL | send(format_args!("{:?}", c)); | = help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque` = note: required because it appears within the type `&core::fmt::rt::Opaque` - = note: required because it appears within the type `Argument<'_>` +note: required because it appears within the type `Argument<'_>` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL = note: required because it appears within the type `[Argument<'_>]` = note: required for `&[core::fmt::rt::Argument<'_>]` to implement `Send` - = note: required because it appears within the type `Arguments<'_>` +note: required because it appears within the type `Arguments<'_>` + --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL note: required by a bound in `send` --> $DIR/send-sync.rs:1:12 | @@ -28,10 +30,12 @@ LL | sync(format_args!("{:?}", c)); | = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque` = note: required because it appears within the type `&core::fmt::rt::Opaque` - = note: required because it appears within the type `Argument<'_>` +note: required because it appears within the type `Argument<'_>` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL = note: required because it appears within the type `[Argument<'_>]` = note: required because it appears within the type `&[Argument<'_>]` - = note: required because it appears within the type `Arguments<'_>` +note: required because it appears within the type `Arguments<'_>` + --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL note: required by a bound in `sync` --> $DIR/send-sync.rs:2:12 | diff --git a/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs index ecabf8943ea..b7b93ef1c44 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs +++ b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs @@ -5,9 +5,6 @@ trait X { const _: () = { fn f1<'a>(arg : Box<dyn X< : 32 >>) {} //~^ ERROR: expected one of `>`, a const expression, lifetime, or type, found `:` - //~| ERROR: expected parameter name, found `>` - //~| ERROR: expected one of `!`, `)`, `+`, `,`, or `::`, found `>` - //~| ERROR: constant provided when a type was expected }; const _: () = { diff --git a/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr index 10ceccedcac..bfddb6dc693 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr @@ -3,41 +3,14 @@ error: expected one of `>`, a const expression, lifetime, or type, found `:` | LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {} | ^ expected one of `>`, a const expression, lifetime, or type - | -help: expressions must be enclosed in braces to be used as const generic arguments - | -LL | fn f1<'a>(arg : Box<{ dyn X< : 32 } >>) {} - | + + - -error: expected parameter name, found `>` - --> $DIR/trait-path-missing-gen_arg.rs:6:36 - | -LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {} - | ^ expected parameter name - -error: expected one of `!`, `)`, `+`, `,`, or `::`, found `>` - --> $DIR/trait-path-missing-gen_arg.rs:6:36 - | -LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {} - | ^ - | | - | expected one of `!`, `)`, `+`, `,`, or `::` - | help: missing `,` error: expected one of `>`, a const expression, lifetime, or type, found `=` - --> $DIR/trait-path-missing-gen_arg.rs:14:30 + --> $DIR/trait-path-missing-gen_arg.rs:11:30 | LL | fn f1<'a>(arg : Box<dyn X< = 32 >>) {} | - ^ expected one of `>`, a const expression, lifetime, or type | | | maybe try to close unmatched angle bracket -error[E0747]: constant provided when a type was expected - --> $DIR/trait-path-missing-gen_arg.rs:6:23 - | -LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {} - | ^^^^^^^^^^^ - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/generics/single-colon-path-not-const-generics.rs b/tests/ui/generics/single-colon-path-not-const-generics.rs index 55a7ae0bb6d..dff00b0b720 100644 --- a/tests/ui/generics/single-colon-path-not-const-generics.rs +++ b/tests/ui/generics/single-colon-path-not-const-generics.rs @@ -6,8 +6,8 @@ pub mod foo { pub struct Foo { a: Vec<foo::bar:A>, - //~^ ERROR expected - //~| HELP path separator + //~^ ERROR path separator must be a double colon + //~| HELP use a double colon instead } fn main() {} diff --git a/tests/ui/generics/single-colon-path-not-const-generics.stderr b/tests/ui/generics/single-colon-path-not-const-generics.stderr index 3eafa9fa5a9..96f07e190c1 100644 --- a/tests/ui/generics/single-colon-path-not-const-generics.stderr +++ b/tests/ui/generics/single-colon-path-not-const-generics.stderr @@ -1,11 +1,12 @@ -error: expected one of `,` or `>`, found `:` +error: path separator must be a double colon --> $DIR/single-colon-path-not-const-generics.rs:8:18 | +LL | pub struct Foo { + | --- while parsing this struct LL | a: Vec<foo::bar:A>, - | ^ - | | - | expected one of `,` or `>` - | help: write a path separator here: `::` + | ^ help: use a double colon instead: `::` + | + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: aborting due to previous error diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs index ffeabe5c2ed..776006124dc 100644 --- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs +++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs @@ -5,10 +5,10 @@ use std::ops::Deref; pub trait Foo { - fn bar() -> impl Deref<Target = impl Sized>; + fn bar(self) -> impl Deref<Target = impl Sized>; } pub struct Foreign; impl Foo for Foreign { - fn bar() -> &'static () { &() } + fn bar(self) -> &'static () { &() } } diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr deleted file mode 100644 index 05c025cc169..00000000000 --- a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/box-coerce-span-in-default.rs:5:12 - | -LL | #![feature(return_position_impl_trait_in_trait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr deleted file mode 100644 index 05c025cc169..00000000000 --- a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/box-coerce-span-in-default.rs:5:12 - | -LL | #![feature(return_position_impl_trait_in_trait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs index 163bb4fcf77..f5290a5f4af 100644 --- a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs +++ b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs @@ -3,7 +3,6 @@ // revisions: current next #![feature(return_position_impl_trait_in_trait)] -//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete struct TestA {} struct TestB {} diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr deleted file mode 100644 index a0c0589b9a1..00000000000 --- a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-method-binder-shifting.rs:5:12 - | -LL | #![feature(return_position_impl_trait_in_trait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr deleted file mode 100644 index a0c0589b9a1..00000000000 --- a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-method-binder-shifting.rs:5:12 - | -LL | #![feature(return_position_impl_trait_in_trait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs index de82544f293..187039f449c 100644 --- a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs +++ b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs @@ -3,7 +3,6 @@ // revisions: current next #![feature(return_position_impl_trait_in_trait)] -//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete trait Trait { type Type; diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr b/tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr deleted file mode 100644 index 7bb79911f56..00000000000 --- a/tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-method-constraint.rs:7:12 - | -LL | #![feature(return_position_impl_trait_in_trait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr b/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr deleted file mode 100644 index 7bb79911f56..00000000000 --- a/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-method-constraint.rs:7:12 - | -LL | #![feature(return_position_impl_trait_in_trait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.rs b/tests/ui/impl-trait/in-trait/default-method-constraint.rs index e85fe3c8626..4f0bf2e7dfe 100644 --- a/tests/ui/impl-trait/in-trait/default-method-constraint.rs +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.rs @@ -5,7 +5,6 @@ // This didn't work in the previous default RPITIT method hack attempt #![feature(return_position_impl_trait_in_trait)] -//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete trait Foo { fn bar(x: bool) -> impl Sized { diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr index b8a793e1a7b..d4d0124a659 100644 --- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr +++ b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr @@ -1,14 +1,5 @@ -warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/dont-project-to-rpitit-with-no-value.rs:4:12 - | -LL | #![feature(return_position_impl_trait_in_trait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/dont-project-to-rpitit-with-no-value.rs:12:1 + --> $DIR/dont-project-to-rpitit-with-no-value.rs:11:1 | LL | fn foo(&self) -> impl Sized; | ---------------------------- `foo` from trait @@ -16,6 +7,6 @@ LL | fn foo(&self) -> impl Sized; LL | impl MyTrait for i32 { | ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr index b8a793e1a7b..d4d0124a659 100644 --- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr +++ b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr @@ -1,14 +1,5 @@ -warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/dont-project-to-rpitit-with-no-value.rs:4:12 - | -LL | #![feature(return_position_impl_trait_in_trait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/dont-project-to-rpitit-with-no-value.rs:12:1 + --> $DIR/dont-project-to-rpitit-with-no-value.rs:11:1 | LL | fn foo(&self) -> impl Sized; | ---------------------------- `foo` from trait @@ -16,6 +7,6 @@ LL | fn foo(&self) -> impl Sized; LL | impl MyTrait for i32 { | ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.rs b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.rs index 8329ce1f835..4d50b8c9278 100644 --- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.rs +++ b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.rs @@ -2,7 +2,6 @@ // revisions: current next #![feature(return_position_impl_trait_in_trait)] -//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete trait MyTrait { fn foo(&self) -> impl Sized; diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs b/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs new file mode 100644 index 00000000000..ecb5e62c433 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs @@ -0,0 +1,8 @@ +// aux-build: rpitit.rs + +extern crate rpitit; + +fn main() { + let _: &dyn rpitit::Foo = todo!(); + //~^ ERROR the trait `Foo` cannot be made into an object +} diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr new file mode 100644 index 00000000000..6eef392c05f --- /dev/null +++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr @@ -0,0 +1,15 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/foreign-dyn-error.rs:6:12 + | +LL | let _: &dyn rpitit::Foo = todo!(); + | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/auxiliary/rpitit.rs:8:21 + | +LL | fn bar(self) -> impl Deref<Target = impl Sized>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait cannot be made into an object because method `bar` references an `impl Trait` type in its return type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs index f4972d948b2..98417b343a1 100644 --- a/tests/ui/impl-trait/in-trait/foreign.rs +++ b/tests/ui/impl-trait/in-trait/foreign.rs @@ -5,17 +5,18 @@ extern crate rpitit; +use rpitit::{Foo, Foreign}; use std::sync::Arc; // Implement an RPITIT from another crate. struct Local; -impl rpitit::Foo for Local { - fn bar() -> Arc<String> { Arc::new(String::new()) } +impl Foo for Local { + fn bar(self) -> Arc<String> { Arc::new(String::new()) } } fn main() { // Witness an RPITIT from another crate. - let &() = <rpitit::Foreign as rpitit::Foo>::bar(); + let &() = Foreign.bar(); - let x: Arc<String> = <Local as rpitit::Foo>::bar(); + let x: Arc<String> = Local.bar(); } diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs index 351243c6727..ec4fda322d0 100644 --- a/tests/ui/impl-trait/issues/issue-86800.rs +++ b/tests/ui/impl-trait/issues/issue-86800.rs @@ -1,14 +1,12 @@ #![feature(type_alias_impl_trait)] // edition:2021 -// unset-rustc-env:RUST_BACKTRACE // compile-flags:-Z treat-err-as-bug=1 -// error-pattern:stack backtrace: +// error-pattern: aborting due to `-Z treat-err-as-bug=1` // failure-status:101 -// normalize-stderr-test "note: .*" -> "" -// normalize-stderr-test "thread 'rustc' .*" -> "" -// normalize-stderr-test " +[0-9]+:.*\n" -> "" -// normalize-stderr-test " +at .*\n" -> "" +// normalize-stderr-test ".*note: .*\n\n" -> "" +// normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +// rustc-env:RUST_BACKTRACE=0 use std::future::Future; diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr index f3a77383778..facab390d15 100644 --- a/tests/ui/impl-trait/issues/issue-86800.stderr +++ b/tests/ui/impl-trait/issues/issue-86800.stderr @@ -1,24 +1,12 @@ error: unconstrained opaque type - --> $DIR/issue-86800.rs:33:34 + --> $DIR/issue-86800.rs:31:34 | LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = - - -stack backtrace: - error: the compiler unexpectedly panicked. this is a bug. - - - - - - query stack during panic: #0 [type_of] computing type of `TransactionFuture::{opaque#0}` #1 [check_mod_item_types] checking item types in top-level module -#2 [analysis] running analysis passes on this crate end of query stack diff --git a/tests/ui/interior-mutability/interior-mutability.stderr b/tests/ui/interior-mutability/interior-mutability.stderr index 034d22591b3..0c3be7ca607 100644 --- a/tests/ui/interior-mutability/interior-mutability.stderr +++ b/tests/ui/interior-mutability/interior-mutability.stderr @@ -7,7 +7,8 @@ LL | catch_unwind(|| { x.set(23); }); | required by a bound introduced by this call | = help: within `Cell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>` - = note: required because it appears within the type `Cell<i32>` +note: required because it appears within the type `Cell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `&Cell<i32>` to implement `UnwindSafe` note: required because it's used within this closure --> $DIR/interior-mutability.rs:5:18 diff --git a/tests/ui/invalid/invalid-debugger-visualizer-option.rs b/tests/ui/invalid/invalid-debugger-visualizer-option.rs index 5645a30ccee..150723898bd 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-option.rs +++ b/tests/ui/invalid/invalid-debugger-visualizer-option.rs @@ -1,7 +1,6 @@ // normalize-stderr-test: "foo.random:.*\(" -> "foo.random: $$FILE_NOT_FOUND_MSG (" // normalize-stderr-test: "os error \d+" -> "os error $$FILE_NOT_FOUND_CODE" -#![feature(debugger_visualizer)] #![debugger_visualizer(random_file = "../foo.random")] //~ ERROR invalid argument #![debugger_visualizer(natvis_file = "../foo.random")] //~ ERROR fn main() {} diff --git a/tests/ui/invalid/invalid-debugger-visualizer-option.stderr b/tests/ui/invalid/invalid-debugger-visualizer-option.stderr index afb8d16ee96..6fbb4d641e6 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-option.stderr +++ b/tests/ui/invalid/invalid-debugger-visualizer-option.stderr @@ -1,5 +1,5 @@ error: invalid argument - --> $DIR/invalid-debugger-visualizer-option.rs:5:24 + --> $DIR/invalid-debugger-visualizer-option.rs:4:24 | LL | #![debugger_visualizer(random_file = "../foo.random")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | #![debugger_visualizer(random_file = "../foo.random")] = note: expected: `gdb_script_file = "..."` error: couldn't read $DIR/../foo.random: $FILE_NOT_FOUND_MSG (os error $FILE_NOT_FOUND_CODE) - --> $DIR/invalid-debugger-visualizer-option.rs:6:24 + --> $DIR/invalid-debugger-visualizer-option.rs:5:24 | LL | #![debugger_visualizer(natvis_file = "../foo.random")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/invalid/invalid-debugger-visualizer-target.rs b/tests/ui/invalid/invalid-debugger-visualizer-target.rs index f0aba6a75c4..f9dd20dbfed 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-target.rs +++ b/tests/ui/invalid/invalid-debugger-visualizer-target.rs @@ -1,4 +1,2 @@ -#![feature(debugger_visualizer)] - #[debugger_visualizer(natvis_file = "../foo.natvis")] //~ ERROR attribute should be applied to a module fn main() {} diff --git a/tests/ui/invalid/invalid-debugger-visualizer-target.stderr b/tests/ui/invalid/invalid-debugger-visualizer-target.stderr index 3555bbb169b..7944f751859 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-target.stderr +++ b/tests/ui/invalid/invalid-debugger-visualizer-target.stderr @@ -1,5 +1,5 @@ error: attribute should be applied to a module - --> $DIR/invalid-debugger-visualizer-target.rs:3:1 + --> $DIR/invalid-debugger-visualizer-target.rs:1:1 | LL | #[debugger_visualizer(natvis_file = "../foo.natvis")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-21763.rs b/tests/ui/issues/issue-21763.rs index 5beb1d8b8c4..38103ff4f9c 100644 --- a/tests/ui/issues/issue-21763.rs +++ b/tests/ui/issues/issue-21763.rs @@ -1,5 +1,7 @@ // Regression test for HashMap only impl'ing Send/Sync if its contents do +// normalize-stderr-test: "\S+hashbrown-\S+" -> "$$HASHBROWN_SRC_LOCATION" + use std::collections::HashMap; use std::rc::Rc; diff --git a/tests/ui/issues/issue-21763.stderr b/tests/ui/issues/issue-21763.stderr index 04379f07ba0..df50118ac47 100644 --- a/tests/ui/issues/issue-21763.stderr +++ b/tests/ui/issues/issue-21763.stderr @@ -1,5 +1,5 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely - --> $DIR/issue-21763.rs:9:11 + --> $DIR/issue-21763.rs:11:11 | LL | foo::<HashMap<Rc<()>, Rc<()>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely @@ -7,10 +7,15 @@ LL | foo::<HashMap<Rc<()>, Rc<()>>>(); = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>` = note: required because it appears within the type `(Rc<()>, Rc<()>)` = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send` - = note: required because it appears within the type `HashMap<Rc<()>, Rc<()>, RandomState>` - = note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>` +note: required because it appears within the type `HashMap<Rc<()>, Rc<()>, RandomState>` + --> $HASHBROWN_SRC_LOCATION + | +LL | pub struct HashMap<K, V, S = DefaultHashBuilder, A: Allocator + Clone = Global> { + | ^^^^^^^ +note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>` + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL note: required by a bound in `foo` - --> $DIR/issue-21763.rs:6:11 + --> $DIR/issue-21763.rs:8:11 | LL | fn foo<T: Send>() {} | ^^^^ required by this bound in `foo` diff --git a/tests/ui/issues/issue-22644.rs b/tests/ui/issues/issue-22644.rs index b1d69dcd862..e3ada65049d 100644 --- a/tests/ui/issues/issue-22644.rs +++ b/tests/ui/issues/issue-22644.rs @@ -1,18 +1,12 @@ -#![feature(type_ascription)] - fn main() { - let a : usize = 0; - let long_name : usize = 0; + let a: usize = 0; + let long_name: usize = 0; println!("{}", a as usize > long_name); println!("{}", a as usize < long_name); //~ ERROR `<` is interpreted as a start of generic println!("{}{}", a as usize < long_name, long_name); //~^ ERROR `<` is interpreted as a start of generic println!("{}", a as usize < 4); //~ ERROR `<` is interpreted as a start of generic - println!("{}", a: usize > long_name); - println!("{}{}", a: usize < long_name, long_name); - //~^ ERROR `<` is interpreted as a start of generic - println!("{}", a: usize < 4); //~ ERROR `<` is interpreted as a start of generic println!("{}", a as @@ -30,6 +24,4 @@ fn main() { 5); println!("{}", a as usize << long_name); //~ ERROR `<<` is interpreted as a start of generic - - println!("{}", a: &mut 4); //~ ERROR expected type, found `4` } diff --git a/tests/ui/issues/issue-22644.stderr b/tests/ui/issues/issue-22644.stderr index 45027afa7b6..0799e9ef11b 100644 --- a/tests/ui/issues/issue-22644.stderr +++ b/tests/ui/issues/issue-22644.stderr @@ -1,5 +1,5 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:8:31 + --> $DIR/issue-22644.rs:6:31 | LL | println!("{}", a as usize < long_name); | ^ --------- interpreted as generic arguments @@ -12,7 +12,7 @@ LL | println!("{}", (a as usize) < long_name); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:9:33 + --> $DIR/issue-22644.rs:7:33 | LL | println!("{}{}", a as usize < long_name, long_name); | ^ -------------------- interpreted as generic arguments @@ -25,7 +25,7 @@ LL | println!("{}{}", (a as usize) < long_name, long_name); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:11:31 + --> $DIR/issue-22644.rs:9:31 | LL | println!("{}", a as usize < 4); | ^ - interpreted as generic arguments @@ -38,33 +38,7 @@ LL | println!("{}", (a as usize) < 4); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:13:31 - | -LL | println!("{}{}", a: usize < long_name, long_name); - | ^ -------------------- interpreted as generic arguments - | | - | not interpreted as comparison - | -help: try comparing the cast value - | -LL | println!("{}{}", (a: usize) < long_name, long_name); - | + + - -error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:15:29 - | -LL | println!("{}", a: usize < 4); - | ^ - interpreted as generic arguments - | | - | not interpreted as comparison - | -help: try comparing the cast value - | -LL | println!("{}", (a: usize) < 4); - | + + - -error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:20:20 + --> $DIR/issue-22644.rs:14:20 | LL | < | ^ not interpreted as comparison @@ -79,7 +53,7 @@ LL ~ usize) | error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:29:20 + --> $DIR/issue-22644.rs:23:20 | LL | < | ^ not interpreted as comparison @@ -96,7 +70,7 @@ LL ~ usize) | error: `<<` is interpreted as a start of generic arguments for `usize`, not a shift - --> $DIR/issue-22644.rs:32:31 + --> $DIR/issue-22644.rs:26:31 | LL | println!("{}", a as usize << long_name); | ^^ --------- interpreted as generic arguments @@ -108,16 +82,5 @@ help: try shifting the cast value LL | println!("{}", (a as usize) << long_name); | + + -error: expected type, found `4` - --> $DIR/issue-22644.rs:34:28 - | -LL | println!("{}", a: &mut 4); - | - ^ expected type - | | - | tried to parse a type due to this type ascription - | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` - = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information - -error: aborting due to 9 previous errors +error: aborting due to 6 previous errors diff --git a/tests/ui/issues/issue-32709.stderr b/tests/ui/issues/issue-32709.stderr index 1d595ca5649..a4ba5da4d87 100644 --- a/tests/ui/issues/issue-32709.stderr +++ b/tests/ui/issues/issue-32709.stderr @@ -7,9 +7,16 @@ LL | Err(5)?; | ^ the trait `From<{integer}>` is not implemented for `()` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the following other types implement trait `FromResidual<R>`: - <Result<T, F> as FromResidual<Result<Infallible, E>>> - <Result<T, F> as FromResidual<Yeet<E>>> + = help: the following other types implement trait `From<T>`: + <(T, T) as From<[T; 2]>> + <(T, T, T) as From<[T; 3]>> + <(T, T, T, T) as From<[T; 4]>> + <(T, T, T, T, T) as From<[T; 5]>> + <(T, T, T, T, T, T) as From<[T; 6]>> + <(T, T, T, T, T, T, T) as From<[T; 7]>> + <(T, T, T, T, T, T, T, T) as From<[T; 8]>> + <(T, T, T, T, T, T, T, T, T) as From<[T; 9]>> + and 4 others = note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>` error: aborting due to previous error diff --git a/tests/ui/issues/issue-58857.stderr b/tests/ui/issues/issue-58857.stderr index e2acec47e5a..6aef35f0bb9 100644 --- a/tests/ui/issues/issue-58857.stderr +++ b/tests/ui/issues/issue-58857.stderr @@ -1,8 +1,8 @@ error: negative bounds are not supported - --> $DIR/issue-58857.rs:4:7 + --> $DIR/issue-58857.rs:4:9 | LL | impl<A: !Valid> Conj<A>{} - | ^^^^^^^^ negative bounds are not supported + | ^ error: aborting due to previous error diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr index aee73380f15..7449fe697ae 100644 --- a/tests/ui/issues/issue-7364.stderr +++ b/tests/ui/issues/issue-7364.stderr @@ -7,7 +7,8 @@ LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0)); = help: the trait `Sync` is not implemented for `RefCell<isize>` = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead = note: required for `Unique<RefCell<isize>>` to implement `Sync` - = note: required because it appears within the type `Box<RefCell<isize>>` +note: required because it appears within the type `Box<RefCell<isize>>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL = note: shared static variables must have a type that implements `Sync` error: aborting due to previous error diff --git a/tests/ui/kindck/kindck-send-object.stderr b/tests/ui/kindck/kindck-send-object.stderr index e9bbeeacd70..284d5dcec31 100644 --- a/tests/ui/kindck/kindck-send-object.stderr +++ b/tests/ui/kindck/kindck-send-object.stderr @@ -20,7 +20,8 @@ LL | assert_send::<Box<dyn Dummy>>(); | = help: the trait `Send` is not implemented for `dyn Dummy` = note: required for `Unique<dyn Dummy>` to implement `Send` - = note: required because it appears within the type `Box<dyn Dummy>` +note: required because it appears within the type `Box<dyn Dummy>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` --> $DIR/kindck-send-object.rs:5:18 | diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr index 19ef4f6fc68..269193f73b4 100644 --- a/tests/ui/kindck/kindck-send-object1.stderr +++ b/tests/ui/kindck/kindck-send-object1.stderr @@ -20,7 +20,8 @@ LL | assert_send::<Box<dyn Dummy + 'a>>(); | = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send` - = note: required because it appears within the type `Box<dyn Dummy>` +note: required because it appears within the type `Box<dyn Dummy>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` --> $DIR/kindck-send-object1.rs:5:18 | diff --git a/tests/ui/kindck/kindck-send-object2.stderr b/tests/ui/kindck/kindck-send-object2.stderr index b8af33d0dc1..6b8df60227f 100644 --- a/tests/ui/kindck/kindck-send-object2.stderr +++ b/tests/ui/kindck/kindck-send-object2.stderr @@ -20,7 +20,8 @@ LL | assert_send::<Box<dyn Dummy>>(); | = help: the trait `Send` is not implemented for `dyn Dummy` = note: required for `Unique<dyn Dummy>` to implement `Send` - = note: required because it appears within the type `Box<dyn Dummy>` +note: required because it appears within the type `Box<dyn Dummy>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` --> $DIR/kindck-send-object2.rs:3:18 | diff --git a/tests/ui/kindck/kindck-send-owned.stderr b/tests/ui/kindck/kindck-send-owned.stderr index b03f56465ce..dc1bb6206af 100644 --- a/tests/ui/kindck/kindck-send-owned.stderr +++ b/tests/ui/kindck/kindck-send-owned.stderr @@ -6,7 +6,8 @@ LL | assert_send::<Box<*mut u8>>(); | = help: the trait `Send` is not implemented for `*mut u8` = note: required for `Unique<*mut u8>` to implement `Send` - = note: required because it appears within the type `Box<*mut u8>` +note: required because it appears within the type `Box<*mut u8>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` --> $DIR/kindck-send-owned.rs:3:18 | diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index a282e71235c..46171880a6f 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -1,8 +1,9 @@ // normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" -#![feature(never_type, rustc_attrs, type_alias_impl_trait)] +#![feature(never_type, rustc_attrs, type_alias_impl_trait, repr_simd)] #![crate_type = "lib"] #[rustc_layout(debug)] +#[derive(Copy, Clone)] enum E { Foo, Bar(!, i32, i32) } //~ ERROR: layout_of #[rustc_layout(debug)] @@ -17,6 +18,51 @@ type Test = Result<i32, i32>; //~ ERROR: layout_of #[rustc_layout(debug)] type T = impl std::fmt::Debug; //~ ERROR: layout_of +#[rustc_layout(debug)] +pub union V { //~ ERROR: layout_of + a: [u16; 0], + b: u8, +} + +#[rustc_layout(debug)] +pub union W { //~ ERROR: layout_of + b: u8, + a: [u16; 0], +} + +#[rustc_layout(debug)] +pub union Y { //~ ERROR: layout_of + b: [u8; 0], + a: [u16; 0], +} + +#[rustc_layout(debug)] +#[repr(packed(1))] +union P1 { x: u32 } //~ ERROR: layout_of + +#[rustc_layout(debug)] +#[repr(packed(1))] +union P2 { x: (u32, u32) } //~ ERROR: layout_of + +#[repr(simd)] +#[derive(Copy, Clone)] +struct F32x4(f32, f32, f32, f32); + +#[rustc_layout(debug)] +#[repr(packed(1))] +union P3 { x: F32x4 } //~ ERROR: layout_of + +#[rustc_layout(debug)] +#[repr(packed(1))] +union P4 { x: E } //~ ERROR: layout_of + +#[rustc_layout(debug)] +#[repr(packed(1))] +union P5 { zst: [u16; 0], byte: u8 } //~ ERROR: layout_of + +#[rustc_layout(debug)] +type X = std::mem::MaybeUninit<u8>; //~ ERROR: layout_of + fn f() -> T { 0i32 } diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index c5e1c41d130..b9fa1b299e9 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -81,7 +81,7 @@ error: layout_of(E) = Layout { ], }, } - --> $DIR/debug.rs:6:1 + --> $DIR/debug.rs:7:1 | LL | enum E { Foo, Bar(!, i32, i32) } | ^^^^^^ @@ -125,7 +125,7 @@ error: layout_of(S) = Layout { index: 0, }, } - --> $DIR/debug.rs:9:1 + --> $DIR/debug.rs:10:1 | LL | struct S { f1: i32, f2: (), f3: i32 } | ^^^^^^^^ @@ -147,7 +147,7 @@ error: layout_of(U) = Layout { index: 0, }, } - --> $DIR/debug.rs:12:1 + --> $DIR/debug.rs:13:1 | LL | union U { f1: (i32, i32), f3: i32 } | ^^^^^^^ @@ -276,7 +276,7 @@ error: layout_of(std::result::Result<i32, i32>) = Layout { ], }, } - --> $DIR/debug.rs:15:1 + --> $DIR/debug.rs:16:1 | LL | type Test = Result<i32, i32>; | ^^^^^^^^^ @@ -302,10 +302,218 @@ error: layout_of(i32) = Layout { index: 0, }, } - --> $DIR/debug.rs:18:1 + --> $DIR/debug.rs:19:1 | LL | type T = impl std::fmt::Debug; | ^^^^^^ -error: aborting due to 5 previous errors +error: layout_of(V) = Layout { + size: Size(2 bytes), + align: AbiAndPrefAlign { + abi: Align(2 bytes), + pref: $PREF_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Union( + 2, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:22:1 + | +LL | pub union V { + | ^^^^^^^^^^^ + +error: layout_of(W) = Layout { + size: Size(2 bytes), + align: AbiAndPrefAlign { + abi: Align(2 bytes), + pref: $PREF_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Union( + 2, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:28:1 + | +LL | pub union W { + | ^^^^^^^^^^^ + +error: layout_of(Y) = Layout { + size: Size(0 bytes), + align: AbiAndPrefAlign { + abi: Align(2 bytes), + pref: $PREF_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Union( + 2, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:34:1 + | +LL | pub union Y { + | ^^^^^^^^^^^ + +error: layout_of(P1) = Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $PREF_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Union( + 1, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:41:1 + | +LL | union P1 { x: u32 } + | ^^^^^^^^ + +error: layout_of(P2) = Layout { + size: Size(8 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $PREF_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Union( + 1, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:45:1 + | +LL | union P2 { x: (u32, u32) } + | ^^^^^^^^ + +error: layout_of(P3) = Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $PREF_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Union( + 1, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:53:1 + | +LL | union P3 { x: F32x4 } + | ^^^^^^^^ + +error: layout_of(P4) = Layout { + size: Size(12 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $PREF_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Union( + 1, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:57:1 + | +LL | union P4 { x: E } + | ^^^^^^^^ + +error: layout_of(P5) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $PREF_ALIGN, + }, + abi: Scalar( + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Union( + 2, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:61:1 + | +LL | union P5 { zst: [u16; 0], byte: u8 } + | ^^^^^^^^ + +error: layout_of(std::mem::MaybeUninit<u8>) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $PREF_ALIGN, + }, + abi: Scalar( + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Union( + 2, + ), + largest_niche: None, + variants: Single { + index: 0, + }, + } + --> $DIR/debug.rs:64:1 + | +LL | type X = std::mem::MaybeUninit<u8>; + | ^^^^^^ + +error: aborting due to 14 previous errors diff --git a/tests/ui/lint/internal/trivial-diagnostics.rs b/tests/ui/lint/internal/trivial-diagnostics.rs new file mode 100644 index 00000000000..e536e1164fc --- /dev/null +++ b/tests/ui/lint/internal/trivial-diagnostics.rs @@ -0,0 +1,8 @@ +// compile-flags: -Zunstable-options + +pub fn issue_111280() { + struct_span_err(msg).emit(); //~ ERROR cannot find value `msg` + //~^ ERROR cannot find function `struct_span_err` +} + +fn main() {} diff --git a/tests/ui/lint/internal/trivial-diagnostics.stderr b/tests/ui/lint/internal/trivial-diagnostics.stderr new file mode 100644 index 00000000000..d47a7dae023 --- /dev/null +++ b/tests/ui/lint/internal/trivial-diagnostics.stderr @@ -0,0 +1,15 @@ +error[E0425]: cannot find value `msg` in this scope + --> $DIR/trivial-diagnostics.rs:4:21 + | +LL | struct_span_err(msg).emit(); + | ^^^ not found in this scope + +error[E0425]: cannot find function `struct_span_err` in this scope + --> $DIR/trivial-diagnostics.rs:4:5 + | +LL | struct_span_err(msg).emit(); + | ^^^^^^^^^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/lint/invalid_value-polymorphic.rs b/tests/ui/lint/invalid_value-polymorphic.rs index 055173e9842..98f82b792fc 100644 --- a/tests/ui/lint/invalid_value-polymorphic.rs +++ b/tests/ui/lint/invalid_value-polymorphic.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-type=lib -Zmir-enable-passes=+InstCombine +// compile-flags: --crate-type=lib -Zmir-enable-passes=+InstSimplify // build-pass #![feature(core_intrinsics)] diff --git a/tests/ui/lint/lint-missing-doc.rs b/tests/ui/lint/lint-missing-doc.rs index 4a234d2651a..e4c9f8f559b 100644 --- a/tests/ui/lint/lint-missing-doc.rs +++ b/tests/ui/lint/lint-missing-doc.rs @@ -3,6 +3,7 @@ #![deny(missing_docs)] #![allow(dead_code)] #![feature(associated_type_defaults, extern_types)] +#![feature(trait_alias)] //! Some garbage docs for the crate here #![doc="More garbage"] @@ -202,4 +203,6 @@ extern "C" { //~^ ERROR: missing documentation for a foreign type } +pub trait T = Sync; //~ ERROR: missing documentation for a trait alias + fn main() {} diff --git a/tests/ui/lint/lint-missing-doc.stderr b/tests/ui/lint/lint-missing-doc.stderr index 733d062a08b..c94bd3b8dfb 100644 --- a/tests/ui/lint/lint-missing-doc.stderr +++ b/tests/ui/lint/lint-missing-doc.stderr @@ -1,5 +1,5 @@ error: missing documentation for a type alias - --> $DIR/lint-missing-doc.rs:11:1 + --> $DIR/lint-missing-doc.rs:12:1 | LL | pub type PubTypedef = String; | ^^^^^^^^^^^^^^^^^^^ @@ -11,142 +11,148 @@ LL | #![deny(missing_docs)] | ^^^^^^^^^^^^ error: missing documentation for a struct - --> $DIR/lint-missing-doc.rs:18:1 + --> $DIR/lint-missing-doc.rs:19:1 | LL | pub struct PubFoo { | ^^^^^^^^^^^^^^^^^ error: missing documentation for a struct field - --> $DIR/lint-missing-doc.rs:19:5 + --> $DIR/lint-missing-doc.rs:20:5 | LL | pub a: isize, | ^^^^^^^^^^^^ error: missing documentation for a module - --> $DIR/lint-missing-doc.rs:30:1 + --> $DIR/lint-missing-doc.rs:31:1 | LL | pub mod pub_module_no_dox {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:34:1 + --> $DIR/lint-missing-doc.rs:35:1 | LL | pub fn foo2() {} | ^^^^^^^^^^^^^ error: missing documentation for a trait - --> $DIR/lint-missing-doc.rs:52:1 + --> $DIR/lint-missing-doc.rs:53:1 | LL | pub trait C { | ^^^^^^^^^^^ error: missing documentation for a method - --> $DIR/lint-missing-doc.rs:53:5 + --> $DIR/lint-missing-doc.rs:54:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ error: missing documentation for a method - --> $DIR/lint-missing-doc.rs:54:5 + --> $DIR/lint-missing-doc.rs:55:5 | LL | fn foo_with_impl(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated function - --> $DIR/lint-missing-doc.rs:55:5 + --> $DIR/lint-missing-doc.rs:56:5 | LL | fn foo_no_self(); | ^^^^^^^^^^^^^^^^^ error: missing documentation for an associated function - --> $DIR/lint-missing-doc.rs:56:5 + --> $DIR/lint-missing-doc.rs:57:5 | LL | fn foo_no_self_with_impl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated type - --> $DIR/lint-missing-doc.rs:66:5 + --> $DIR/lint-missing-doc.rs:67:5 | LL | type AssociatedType; | ^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated type - --> $DIR/lint-missing-doc.rs:67:5 + --> $DIR/lint-missing-doc.rs:68:5 | LL | type AssociatedTypeDef = Self; | ^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated function - --> $DIR/lint-missing-doc.rs:83:5 + --> $DIR/lint-missing-doc.rs:84:5 | LL | pub fn foo() {} | ^^^^^^^^^^^^ error: missing documentation for an enum - --> $DIR/lint-missing-doc.rs:120:1 + --> $DIR/lint-missing-doc.rs:121:1 | LL | pub enum PubBaz { | ^^^^^^^^^^^^^^^ error: missing documentation for a variant - --> $DIR/lint-missing-doc.rs:121:5 + --> $DIR/lint-missing-doc.rs:122:5 | LL | PubBazA { | ^^^^^^^ error: missing documentation for a struct field - --> $DIR/lint-missing-doc.rs:122:9 + --> $DIR/lint-missing-doc.rs:123:9 | LL | a: isize, | ^^^^^^^^ error: missing documentation for a constant - --> $DIR/lint-missing-doc.rs:153:1 + --> $DIR/lint-missing-doc.rs:154:1 | LL | pub const FOO4: u32 = 0; | ^^^^^^^^^^^^^^^^^^^ error: missing documentation for a static - --> $DIR/lint-missing-doc.rs:163:1 + --> $DIR/lint-missing-doc.rs:164:1 | LL | pub static BAR4: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:169:5 + --> $DIR/lint-missing-doc.rs:170:5 | LL | pub fn undocumented1() {} | ^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:170:5 + --> $DIR/lint-missing-doc.rs:171:5 | LL | pub fn undocumented2() {} | ^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:176:9 + --> $DIR/lint-missing-doc.rs:177:9 | LL | pub fn also_undocumented1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:191:5 + --> $DIR/lint-missing-doc.rs:192:5 | LL | pub fn extern_fn_undocumented(f: f32) -> f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a static - --> $DIR/lint-missing-doc.rs:196:5 + --> $DIR/lint-missing-doc.rs:197:5 | LL | pub static EXTERN_STATIC_UNDOCUMENTED: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a foreign type - --> $DIR/lint-missing-doc.rs:201:5 + --> $DIR/lint-missing-doc.rs:202:5 | LL | pub type ExternTyUndocumented; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 24 previous errors +error: missing documentation for a trait alias + --> $DIR/lint-missing-doc.rs:206:1 + | +LL | pub trait T = Sync; + | ^^^^^^^^^^^ + +error: aborting due to 25 previous errors diff --git a/tests/ui/lint/noop-method-call.rs b/tests/ui/lint/noop-method-call.rs index 89b29663595..dbcf2a5131b 100644 --- a/tests/ui/lint/noop-method-call.rs +++ b/tests/ui/lint/noop-method-call.rs @@ -19,18 +19,17 @@ fn main() { let clone_type_ref = &CloneType(1u32); let clone_type_ref_clone: CloneType<u32> = clone_type_ref.clone(); - // Calling clone on a double reference doesn't warn since the method call itself - // peels the outer reference off let clone_type_ref = &&CloneType(1u32); let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone(); + //~^ WARNING using `.clone()` on a double reference, which returns `&CloneType<u32>` let non_deref_type = &PlainType(1u32); let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref(); //~^ WARNING call to `.deref()` on a reference in this situation does nothing - // Dereferencing a &&T does not warn since it has collapsed the double reference let non_deref_type = &&PlainType(1u32); let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref(); + //~^ WARNING using `.deref()` on a double reference, which returns `&PlainType<u32>` let non_borrow_type = &PlainType(1u32); let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow(); @@ -41,7 +40,8 @@ fn main() { let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow(); let xs = ["a", "b", "c"]; - let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // ok, but could use `*x` instead + let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead + //~^ WARNING using `.clone()` on a double reference, which returns `&str` } fn generic<T>(non_clone_type: &PlainType<T>) { diff --git a/tests/ui/lint/noop-method-call.stderr b/tests/ui/lint/noop-method-call.stderr index 6a904d01abc..37cd1a0fc18 100644 --- a/tests/ui/lint/noop-method-call.stderr +++ b/tests/ui/lint/noop-method-call.stderr @@ -11,22 +11,42 @@ note: the lint level is defined here LL | #![warn(noop_method_call)] | ^^^^^^^^^^^^^^^^ +warning: using `.clone()` on a double reference, which returns `&CloneType<u32>` instead of cloning the inner type + --> $DIR/noop-method-call.rs:23:63 + | +LL | let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone(); + | ^^^^^^^^ + | + = note: `#[warn(suspicious_double_ref_op)]` on by default + warning: call to `.deref()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:28:63 + --> $DIR/noop-method-call.rs:27:63 | LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref(); | ^^^^^^^^ unnecessary method call | = note: the type `&PlainType<u32>` which `deref` is being called on is the same as the type returned from `deref`, so the method call does not do anything and can be removed +warning: using `.deref()` on a double reference, which returns `&PlainType<u32>` instead of dereferencing the inner type + --> $DIR/noop-method-call.rs:31:63 + | +LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref(); + | ^^^^^^^^ + warning: call to `.borrow()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:36:66 + --> $DIR/noop-method-call.rs:35:66 | LL | let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow(); | ^^^^^^^^^ unnecessary method call | = note: the type `&PlainType<u32>` which `borrow` is being called on is the same as the type returned from `borrow`, so the method call does not do anything and can be removed +warning: using `.clone()` on a double reference, which returns `&str` instead of cloning the inner type + --> $DIR/noop-method-call.rs:43:44 + | +LL | let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead + | ^^^^^^^^ + warning: call to `.clone()` on a reference in this situation does nothing --> $DIR/noop-method-call.rs:48:19 | @@ -43,5 +63,5 @@ LL | non_clone_type.clone(); | = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed -warning: 5 warnings emitted +warning: 8 warnings emitted diff --git a/tests/ui/lint/suspicious-double-ref-op.rs b/tests/ui/lint/suspicious-double-ref-op.rs new file mode 100644 index 00000000000..b9bcd31c2a8 --- /dev/null +++ b/tests/ui/lint/suspicious-double-ref-op.rs @@ -0,0 +1,30 @@ +#![feature(lazy_cell)] +#![deny(suspicious_double_ref_op, noop_method_call)] + +pub fn clone_on_double_ref() { + let x = vec![1]; + let y = &&x; + let z: &Vec<_> = y.clone(); + //~^ ERROR using `.clone()` on a double reference, which returns `&Vec<i32>` + + println!("{:p} {:p}", *y, z); +} + +use std::sync::LazyLock; + +pub static STRS: LazyLock<&str> = LazyLock::new(|| "First"); + +// https://github.com/rust-lang/rust-clippy/issues/9272 +fn rust_clippy_issue_9272() { + let str = STRS.clone(); + println!("{str}") +} + +fn check(mut encoded: &[u8]) { + let _ = &mut encoded.clone(); + //~^ ERROR call to `.clone()` on a reference in this situation does nothing + let _ = &encoded.clone(); + //~^ ERROR call to `.clone()` on a reference in this situation does nothing +} + +fn main() {} diff --git a/tests/ui/lint/suspicious-double-ref-op.stderr b/tests/ui/lint/suspicious-double-ref-op.stderr new file mode 100644 index 00000000000..d15487ca238 --- /dev/null +++ b/tests/ui/lint/suspicious-double-ref-op.stderr @@ -0,0 +1,35 @@ +error: using `.clone()` on a double reference, which returns `&Vec<i32>` instead of cloning the inner type + --> $DIR/suspicious-double-ref-op.rs:7:23 + | +LL | let z: &Vec<_> = y.clone(); + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/suspicious-double-ref-op.rs:2:9 + | +LL | #![deny(suspicious_double_ref_op, noop_method_call)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: call to `.clone()` on a reference in this situation does nothing + --> $DIR/suspicious-double-ref-op.rs:24:25 + | +LL | let _ = &mut encoded.clone(); + | ^^^^^^^^ unnecessary method call + | + = note: the type `&[u8]` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed +note: the lint level is defined here + --> $DIR/suspicious-double-ref-op.rs:2:35 + | +LL | #![deny(suspicious_double_ref_op, noop_method_call)] + | ^^^^^^^^^^^^^^^^ + +error: call to `.clone()` on a reference in this situation does nothing + --> $DIR/suspicious-double-ref-op.rs:26:21 + | +LL | let _ = &encoded.clone(); + | ^^^^^^^^ unnecessary method call + | + = note: the type `&[u8]` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed + +error: aborting due to 3 previous errors + diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 79d8cd75716..816f99baa84 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -134,8 +134,7 @@ fn test_expr() { assert_eq!(stringify_expr!(expr as T<u8>), "expr as T<u8>"); // ExprKind::Type - assert_eq!(stringify_expr!(expr: T), "expr: T"); - assert_eq!(stringify_expr!(expr: T<u8>), "expr: T<u8>"); + // There is no syntax for type ascription. // ExprKind::If assert_eq!(stringify_expr!(if true {}), "if true {}"); diff --git a/tests/ui/not-panic/not-panic-safe-2.stderr b/tests/ui/not-panic/not-panic-safe-2.stderr index 3b0f83b3b9a..0c399f15a25 100644 --- a/tests/ui/not-panic/not-panic-safe-2.stderr +++ b/tests/ui/not-panic/not-panic-safe-2.stderr @@ -5,7 +5,8 @@ LL | assert::<Rc<RefCell<i32>>>(); | ^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>` - = note: required because it appears within the type `RefCell<i32>` +note: required because it appears within the type `RefCell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `Rc<RefCell<i32>>` to implement `UnwindSafe` note: required by a bound in `assert` --> $DIR/not-panic-safe-2.rs:7:14 @@ -20,8 +21,10 @@ LL | assert::<Rc<RefCell<i32>>>(); | ^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>` - = note: required because it appears within the type `Cell<isize>` - = note: required because it appears within the type `RefCell<i32>` +note: required because it appears within the type `Cell<isize>` + --> $SRC_DIR/core/src/cell.rs:LL:COL +note: required because it appears within the type `RefCell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `Rc<RefCell<i32>>` to implement `UnwindSafe` note: required by a bound in `assert` --> $DIR/not-panic-safe-2.rs:7:14 diff --git a/tests/ui/not-panic/not-panic-safe-3.stderr b/tests/ui/not-panic/not-panic-safe-3.stderr index 9e9a12764a4..53028d6a337 100644 --- a/tests/ui/not-panic/not-panic-safe-3.stderr +++ b/tests/ui/not-panic/not-panic-safe-3.stderr @@ -5,7 +5,8 @@ LL | assert::<Arc<RefCell<i32>>>(); | ^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>` - = note: required because it appears within the type `RefCell<i32>` +note: required because it appears within the type `RefCell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `Arc<RefCell<i32>>` to implement `UnwindSafe` note: required by a bound in `assert` --> $DIR/not-panic-safe-3.rs:7:14 @@ -20,8 +21,10 @@ LL | assert::<Arc<RefCell<i32>>>(); | ^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>` - = note: required because it appears within the type `Cell<isize>` - = note: required because it appears within the type `RefCell<i32>` +note: required because it appears within the type `Cell<isize>` + --> $SRC_DIR/core/src/cell.rs:LL:COL +note: required because it appears within the type `RefCell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `Arc<RefCell<i32>>` to implement `UnwindSafe` note: required by a bound in `assert` --> $DIR/not-panic-safe-3.rs:7:14 diff --git a/tests/ui/not-panic/not-panic-safe-4.stderr b/tests/ui/not-panic/not-panic-safe-4.stderr index 9428c125651..b1361cfd87e 100644 --- a/tests/ui/not-panic/not-panic-safe-4.stderr +++ b/tests/ui/not-panic/not-panic-safe-4.stderr @@ -5,7 +5,8 @@ LL | assert::<&RefCell<i32>>(); | ^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>` - = note: required because it appears within the type `RefCell<i32>` +note: required because it appears within the type `RefCell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `&RefCell<i32>` to implement `UnwindSafe` note: required by a bound in `assert` --> $DIR/not-panic-safe-4.rs:6:14 @@ -25,8 +26,10 @@ LL | assert::<&RefCell<i32>>(); | ^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>` - = note: required because it appears within the type `Cell<isize>` - = note: required because it appears within the type `RefCell<i32>` +note: required because it appears within the type `Cell<isize>` + --> $SRC_DIR/core/src/cell.rs:LL:COL +note: required because it appears within the type `RefCell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `&RefCell<i32>` to implement `UnwindSafe` note: required by a bound in `assert` --> $DIR/not-panic-safe-4.rs:6:14 diff --git a/tests/ui/not-panic/not-panic-safe-6.stderr b/tests/ui/not-panic/not-panic-safe-6.stderr index 7986e341eb0..47f28257409 100644 --- a/tests/ui/not-panic/not-panic-safe-6.stderr +++ b/tests/ui/not-panic/not-panic-safe-6.stderr @@ -5,7 +5,8 @@ LL | assert::<*mut RefCell<i32>>(); | ^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>` - = note: required because it appears within the type `RefCell<i32>` +note: required because it appears within the type `RefCell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `*mut RefCell<i32>` to implement `UnwindSafe` note: required by a bound in `assert` --> $DIR/not-panic-safe-6.rs:6:14 @@ -20,8 +21,10 @@ LL | assert::<*mut RefCell<i32>>(); | ^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>` - = note: required because it appears within the type `Cell<isize>` - = note: required because it appears within the type `RefCell<i32>` +note: required because it appears within the type `Cell<isize>` + --> $SRC_DIR/core/src/cell.rs:LL:COL +note: required because it appears within the type `RefCell<i32>` + --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `*mut RefCell<i32>` to implement `UnwindSafe` note: required by a bound in `assert` --> $DIR/not-panic-safe-6.rs:6:14 diff --git a/tests/ui/optimization-remark.rs b/tests/ui/optimization-remark.rs index 4f651b1dcbc..8fd30466f43 100644 --- a/tests/ui/optimization-remark.rs +++ b/tests/ui/optimization-remark.rs @@ -13,7 +13,7 @@ // [merge1] compile-flags: -Cremark=all -Cremark=giraffe // [merge2] compile-flags: -Cremark=inline -Cremark=giraffe // -// error-pattern: inline: 'f' not inlined into 'g' +// error-pattern: inline (missed): 'f' not inlined into 'g' // dont-check-compiler-stderr #[no_mangle] diff --git a/tests/ui/or-patterns/or-patterns-syntactic-fail.rs b/tests/ui/or-patterns/or-patterns-syntactic-fail.rs index 358e9d034c4..23dbb57cbcf 100644 --- a/tests/ui/or-patterns/or-patterns-syntactic-fail.rs +++ b/tests/ui/or-patterns/or-patterns-syntactic-fail.rs @@ -8,9 +8,12 @@ use E::*; fn no_top_level_or_patterns() { // We do *not* allow or-patterns at the top level of lambdas... - let _ = |A | B: E| (); //~ ERROR no implementation for `E | ()` + let _ = |A | B: E| (); + //~^ ERROR expected identifier, found // -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`. +} +fn no_top_level_or_patterns_2() { // ...and for now neither do we allow or-patterns at the top level of functions. fn fun1(A | B: E) {} //~^ ERROR top-level or-patterns are not allowed diff --git a/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr b/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr index 604bba417e6..c16a90368e1 100644 --- a/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr +++ b/tests/ui/or-patterns/or-patterns-syntactic-fail.stderr @@ -1,43 +1,34 @@ +error: expected identifier, found `:` + --> $DIR/or-patterns-syntactic-fail.rs:11:19 + | +LL | let _ = |A | B: E| (); + | ^ expected identifier + | + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> + error: top-level or-patterns are not allowed in function parameters - --> $DIR/or-patterns-syntactic-fail.rs:15:13 + --> $DIR/or-patterns-syntactic-fail.rs:18:13 | LL | fn fun1(A | B: E) {} | ^^^^^ help: wrap the pattern in parentheses: `(A | B)` error: top-level or-patterns are not allowed in function parameters - --> $DIR/or-patterns-syntactic-fail.rs:18:13 + --> $DIR/or-patterns-syntactic-fail.rs:21:13 | LL | fn fun2(| A | B: E) {} | ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)` error: top-level or-patterns are not allowed in `let` bindings - --> $DIR/or-patterns-syntactic-fail.rs:23:9 + --> $DIR/or-patterns-syntactic-fail.rs:26:9 | LL | let A | B: E = A; | ^^^^^ help: wrap the pattern in parentheses: `(A | B)` error: top-level or-patterns are not allowed in `let` bindings - --> $DIR/or-patterns-syntactic-fail.rs:26:9 + --> $DIR/or-patterns-syntactic-fail.rs:29:9 | LL | let | A | B: E = A; | ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)` -error[E0369]: no implementation for `E | ()` - --> $DIR/or-patterns-syntactic-fail.rs:11:22 - | -LL | let _ = |A | B: E| (); - | ----^ -- () - | | - | E - | -note: an implementation of `BitOr<()>` might be missing for `E` - --> $DIR/or-patterns-syntactic-fail.rs:6:1 - | -LL | enum E { A, B } - | ^^^^^^ must implement `BitOr<()>` -note: the trait `BitOr` must be implemented - --> $SRC_DIR/core/src/ops/bit.rs:LL:COL - error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/panic-runtime/auxiliary/needs-unwind.rs b/tests/ui/panic-runtime/auxiliary/needs-unwind.rs index d555b531986..ba917b52d9a 100644 --- a/tests/ui/panic-runtime/auxiliary/needs-unwind.rs +++ b/tests/ui/panic-runtime/auxiliary/needs-unwind.rs @@ -3,7 +3,6 @@ #![crate_type = "rlib"] #![no_std] -#![feature(c_unwind)] extern "C-unwind" fn foo() {} diff --git a/tests/ui/panics/default-backtrace-ice.rs b/tests/ui/panics/default-backtrace-ice.rs index fd86a3f9dfa..b40203c339d 100644 --- a/tests/ui/panics/default-backtrace-ice.rs +++ b/tests/ui/panics/default-backtrace-ice.rs @@ -2,8 +2,20 @@ // compile-flags:-Z treat-err-as-bug=1 // error-pattern:stack backtrace: // failure-status:101 +// ignore-msvc // normalize-stderr-test "note: .*" -> "" // normalize-stderr-test "thread 'rustc' .*" -> "" -// normalize-stderr-test " .*\n" -> "" +// normalize-stderr-test " +\d+:.*__rust_begin_short_backtrace.*" -> "(begin_short_backtrace)" +// normalize-stderr-test " +\d+:.*__rust_end_short_backtrace.*" -> "(end_short_backtrace)" +// normalize-stderr-test " +\d+:.*\n" -> "" +// normalize-stderr-test " +at .*\n" -> "" +// +// This test makes sure that full backtraces are used for ICEs when +// RUST_BACKTRACE is not set. It does this by checking for the presence of +// `__rust_{begin,end}_short_backtrace` markers, which only appear in full +// backtraces. The rest of the backtrace is filtered out. +// +// Ignored on msvc becaue the `__rust_{begin,end}_short_backtrace` symbols +// aren't reliable. fn main() { missing_ident; } diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr index 4bd4780e25f..ddbfc4e7f3a 100644 --- a/tests/ui/panics/default-backtrace-ice.stderr +++ b/tests/ui/panics/default-backtrace-ice.stderr @@ -1,8 +1,13 @@ error[E0425]: cannot find value `missing_ident` in this scope + --> $DIR/default-backtrace-ice.rs:21:13 + | LL | fn main() { missing_ident; } + | ^^^^^^^^^^^^^ not found in this scope stack backtrace: +(end_short_backtrace) +(begin_short_backtrace) error: the compiler unexpectedly panicked. this is a bug. diff --git a/tests/ui/parser/attr-stmt-expr-attr-bad.rs b/tests/ui/parser/attr-stmt-expr-attr-bad.rs index c94a32146b9..d1950087c4c 100644 --- a/tests/ui/parser/attr-stmt-expr-attr-bad.rs +++ b/tests/ui/parser/attr-stmt-expr-attr-bad.rs @@ -6,6 +6,7 @@ fn main() {} //~^ ERROR expected one of #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } //~^ ERROR an inner attribute is not permitted in this context +//~| ERROR an inner attribute is not permitted in this context //~| ERROR expected expression, found `)` #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } //~^ ERROR an inner attribute is not permitted in this context diff --git a/tests/ui/parser/attr-stmt-expr-attr-bad.stderr b/tests/ui/parser/attr-stmt-expr-attr-bad.stderr index a857f11fd18..96899fd3fc5 100644 --- a/tests/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/tests/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -19,6 +19,15 @@ LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files = note: outer attributes, like `#[test]`, annotate the item following them +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:7:36 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + error: expected expression, found `)` --> $DIR/attr-stmt-expr-attr-bad.rs:7:44 | @@ -26,7 +35,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } | ^ expected expression error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:10:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:11:38 | LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } | ^^^^^^^^ @@ -35,13 +44,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `)` - --> $DIR/attr-stmt-expr-attr-bad.rs:10:46 + --> $DIR/attr-stmt-expr-attr-bad.rs:11:46 | LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } | ^ expected expression error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:13:36 + --> $DIR/attr-stmt-expr-attr-bad.rs:14:36 | LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } | ^^^^^^^^ @@ -50,7 +59,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:15:33 + --> $DIR/attr-stmt-expr-attr-bad.rs:16:33 | LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } | ^^^^^^^^ @@ -59,7 +68,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:17:33 + --> $DIR/attr-stmt-expr-attr-bad.rs:18:33 | LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } | ^^^^^^^^ @@ -68,13 +77,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:19:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:20:34 | LL | #[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } | ^ expected one of 8 possible tokens error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:21:35 + --> $DIR/attr-stmt-expr-attr-bad.rs:22:35 | LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } | ^^^^^^^^ @@ -83,7 +92,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:23:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:24:40 | LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } | ^^^^^^^^ @@ -92,7 +101,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:25:35 + --> $DIR/attr-stmt-expr-attr-bad.rs:26:35 | LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } | ^^^^^^^^ @@ -101,7 +110,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:27:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:28:40 | LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } | ^^^^^^^^ @@ -110,19 +119,19 @@ LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `..` - --> $DIR/attr-stmt-expr-attr-bad.rs:29:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:30:40 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } | ^^ expected expression error: expected expression, found `..` - --> $DIR/attr-stmt-expr-attr-bad.rs:31:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:32:40 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } | ^^ expected expression error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:33:41 + --> $DIR/attr-stmt-expr-attr-bad.rs:34:41 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } | ^^^^^^^^ @@ -131,7 +140,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:35:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:36:45 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } | ^^^^^^^^ @@ -140,7 +149,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:37:37 + --> $DIR/attr-stmt-expr-attr-bad.rs:38:37 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } | -- ^^^^^^^ -- the attributes are attached to this branch @@ -149,7 +158,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } | the branch belongs to this `if` error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:39:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:40:38 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } | ^^^^^^^^ @@ -158,13 +167,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:41:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:42:40 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } | ^ expected one of `.`, `;`, `?`, `else`, or an operator error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:43:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:44:45 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } | ---- ^^^^^^^ -- the attributes are attached to this branch @@ -173,7 +182,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } | the branch belongs to this `else` error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:45:46 + --> $DIR/attr-stmt-expr-attr-bad.rs:46:46 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } | ^^^^^^^^ @@ -182,7 +191,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:47:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:48:45 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } | ---- ^^^^^^^ ------- the attributes are attached to this branch @@ -191,7 +200,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } | the branch belongs to this `else` error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:49:50 + --> $DIR/attr-stmt-expr-attr-bad.rs:50:50 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } | -- ^^^^^^^ -- the attributes are attached to this branch @@ -200,7 +209,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } | the branch belongs to this `if` error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:51:51 + --> $DIR/attr-stmt-expr-attr-bad.rs:52:51 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } | ^^^^^^^^ @@ -209,7 +218,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:53:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:54:45 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } | -- ^^^^^^^ -- the attributes are attached to this branch @@ -218,7 +227,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } | the branch belongs to this `if` error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:55:46 + --> $DIR/attr-stmt-expr-attr-bad.rs:56:46 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } | ^^^^^^^^ @@ -227,13 +236,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:57:48 + --> $DIR/attr-stmt-expr-attr-bad.rs:58:48 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } | ^ expected one of `.`, `;`, `?`, `else`, or an operator error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:59:53 + --> $DIR/attr-stmt-expr-attr-bad.rs:60:53 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } | ---- ^^^^^^^ -- the attributes are attached to this branch @@ -242,7 +251,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } | the branch belongs to this `else` error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:61:54 + --> $DIR/attr-stmt-expr-attr-bad.rs:62:54 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } | ^^^^^^^^ @@ -251,7 +260,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:63:53 + --> $DIR/attr-stmt-expr-attr-bad.rs:64:53 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } | ---- ^^^^^^^ --------------- the attributes are attached to this branch @@ -260,7 +269,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {} | the branch belongs to this `else` error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:65:66 + --> $DIR/attr-stmt-expr-attr-bad.rs:66:66 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } | -- ^^^^^^^ -- the attributes are attached to this branch @@ -269,7 +278,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {} | the branch belongs to this `if` error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:67:67 + --> $DIR/attr-stmt-expr-attr-bad.rs:68:67 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } | ^^^^^^^^ @@ -278,7 +287,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]} = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:70:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:71:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } | ------- ^^^^^^^^ not permitted following an outer attribute @@ -289,7 +298,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:72:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:73:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } | ------- ^^^^^^^^ not permitted following an outer attribute @@ -300,7 +309,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:74:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:75:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation @@ -316,7 +325,7 @@ LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); } | error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:76:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:77:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation @@ -332,7 +341,7 @@ LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; } | error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:78:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:79:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } | ------- ^^^^^^^^ ------ the inner attribute doesn't annotate this item macro invocation @@ -348,7 +357,7 @@ LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; } | error[E0586]: inclusive range with no end - --> $DIR/attr-stmt-expr-attr-bad.rs:84:35 + --> $DIR/attr-stmt-expr-attr-bad.rs:85:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } | ^^^ help: use `..` instead @@ -356,13 +365,13 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:84:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:85:38 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } | ^ expected one of `=>`, `if`, or `|` error[E0586]: inclusive range with no end - --> $DIR/attr-stmt-expr-attr-bad.rs:87:35 + --> $DIR/attr-stmt-expr-attr-bad.rs:88:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } | ^^^ help: use `..` instead @@ -370,19 +379,19 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:87:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:88:38 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } | ^ expected one of `=>`, `if`, or `|` error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:90:39 + --> $DIR/attr-stmt-expr-attr-bad.rs:91:39 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } | ^ error[E0586]: inclusive range with no end - --> $DIR/attr-stmt-expr-attr-bad.rs:92:35 + --> $DIR/attr-stmt-expr-attr-bad.rs:93:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } | ^^^ help: use `..` instead @@ -390,47 +399,47 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:92:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:93:38 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } | ^ expected one of `=>`, `if`, or `|` error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:96:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:97:34 | LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } | ^ error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:96:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:97:34 | LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } | ^ expected one of `.`, `;`, `?`, `else`, or an operator error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:99:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 | LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } | ^ error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:99:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 | LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } | ^ expected one of `.`, `;`, `?`, `else`, or an operator error: expected statement after outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:104:37 + --> $DIR/attr-stmt-expr-attr-bad.rs:105:37 | LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } | ^^^^^^^ error: expected statement after outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:106:37 + --> $DIR/attr-stmt-expr-attr-bad.rs:107:37 | LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } | ^^^^^^^ -error: aborting due to 52 previous errors +error: aborting due to 53 previous errors For more information about this error, try `rustc --explain E0586`. diff --git a/tests/ui/parser/eq-less-to-less-eq.rs b/tests/ui/parser/eq-less-to-less-eq.rs new file mode 100644 index 00000000000..23c6c59d7a6 --- /dev/null +++ b/tests/ui/parser/eq-less-to-less-eq.rs @@ -0,0 +1,33 @@ +fn foo() { + let a = 0; + let b = 4; + if a =< b { //~ERROR + println!("yay!"); + } +} + +fn bar() { + let a = 0; + let b = 4; + if a = <b { //~ERROR + println!("yay!"); + } +} + +fn baz() { + let a = 0; + let b = 4; + if a = < b { //~ERROR + println!("yay!"); + } +} + +fn qux() { + let a = 0; + let b = 4; + if a =< i32>::abs(-4) { //~ERROR: mismatched types + println!("yay!"); + } +} + +fn main() {} diff --git a/tests/ui/parser/eq-less-to-less-eq.stderr b/tests/ui/parser/eq-less-to-less-eq.stderr new file mode 100644 index 00000000000..4717d8287ff --- /dev/null +++ b/tests/ui/parser/eq-less-to-less-eq.stderr @@ -0,0 +1,34 @@ +error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `{` + --> $DIR/eq-less-to-less-eq.rs:4:15 + | +LL | if a =< b { + | -- ^ expected one of 7 possible tokens + | | + | help: did you mean: `<=` + +error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `{` + --> $DIR/eq-less-to-less-eq.rs:12:15 + | +LL | if a = <b { + | ^ expected one of 7 possible tokens + +error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `{` + --> $DIR/eq-less-to-less-eq.rs:20:16 + | +LL | if a = < b { + | ^ expected one of 7 possible tokens + +error[E0308]: mismatched types + --> $DIR/eq-less-to-less-eq.rs:28:8 + | +LL | if a =< i32>::abs(-4) { + | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if a ==< i32>::abs(-4) { + | + + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/issue-103869.rs b/tests/ui/parser/issue-103869.rs index 28c442bdd63..9213437458a 100644 --- a/tests/ui/parser/issue-103869.rs +++ b/tests/ui/parser/issue-103869.rs @@ -2,7 +2,6 @@ enum VecOrMap{ vec: Vec<usize>, //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `:` //~| HELP: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` - //~| ERROR expected item, found `:` map: HashMap<String,usize> } diff --git a/tests/ui/parser/issue-103869.stderr b/tests/ui/parser/issue-103869.stderr index 0b8cd919a9d..9eb20e2005a 100644 --- a/tests/ui/parser/issue-103869.stderr +++ b/tests/ui/parser/issue-103869.stderr @@ -1,16 +1,12 @@ error: expected one of `(`, `,`, `=`, `{`, or `}`, found `:` --> $DIR/issue-103869.rs:2:8 | +LL | enum VecOrMap{ + | -------- while parsing this enum LL | vec: Vec<usize>, | ^ expected one of `(`, `,`, `=`, `{`, or `}` | = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` -error: expected item, found `:` - --> $DIR/issue-103869.rs:2:8 - | -LL | vec: Vec<usize>, - | ^ expected item - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/parser/issues/issue-33418.fixed b/tests/ui/parser/issues/issue-33418.fixed deleted file mode 100644 index ed885ae1435..00000000000 --- a/tests/ui/parser/issues/issue-33418.fixed +++ /dev/null @@ -1,19 +0,0 @@ -// run-rustfix - -trait Tr {} -//~^ ERROR negative bounds are not supported -trait Tr2: SuperA {} -//~^ ERROR negative bounds are not supported -trait Tr3: SuperB {} -//~^ ERROR negative bounds are not supported -trait Tr4: SuperB + SuperD {} -//~^ ERROR negative bounds are not supported -trait Tr5 {} -//~^ ERROR negative bounds are not supported - -trait SuperA {} -trait SuperB {} -trait SuperC {} -trait SuperD {} - -fn main() {} diff --git a/tests/ui/parser/issues/issue-33418.rs b/tests/ui/parser/issues/issue-33418.rs index 9934284abfb..4ebd5871e53 100644 --- a/tests/ui/parser/issues/issue-33418.rs +++ b/tests/ui/parser/issues/issue-33418.rs @@ -1,5 +1,3 @@ -// run-rustfix - trait Tr: !SuperA {} //~^ ERROR negative bounds are not supported trait Tr2: SuperA + !SuperB {} @@ -7,10 +5,12 @@ trait Tr2: SuperA + !SuperB {} trait Tr3: !SuperA + SuperB {} //~^ ERROR negative bounds are not supported trait Tr4: !SuperA + SuperB - + !SuperC + SuperD {} +//~^ ERROR negative bounds are not supported ++ !SuperC + SuperD {} //~^ ERROR negative bounds are not supported trait Tr5: !SuperA - + !SuperB {} +//~^ ERROR negative bounds are not supported ++ !SuperB {} //~^ ERROR negative bounds are not supported trait SuperA {} diff --git a/tests/ui/parser/issues/issue-33418.stderr b/tests/ui/parser/issues/issue-33418.stderr index 9a8733e8929..b111bcfd240 100644 --- a/tests/ui/parser/issues/issue-33418.stderr +++ b/tests/ui/parser/issues/issue-33418.stderr @@ -1,36 +1,44 @@ error: negative bounds are not supported - --> $DIR/issue-33418.rs:3:9 + --> $DIR/issue-33418.rs:1:11 | LL | trait Tr: !SuperA {} - | ^^^^^^^^^ negative bounds are not supported + | ^ error: negative bounds are not supported - --> $DIR/issue-33418.rs:5:19 + --> $DIR/issue-33418.rs:3:21 | LL | trait Tr2: SuperA + !SuperB {} - | ^^^^^^^^^ negative bounds are not supported + | ^ error: negative bounds are not supported - --> $DIR/issue-33418.rs:7:10 + --> $DIR/issue-33418.rs:5:12 | LL | trait Tr3: !SuperA + SuperB {} - | ^^^^^^^^^ negative bounds are not supported + | ^ error: negative bounds are not supported - --> $DIR/issue-33418.rs:9:10 + --> $DIR/issue-33418.rs:7:12 | LL | trait Tr4: !SuperA + SuperB - | ^^^^^^^^^ -LL | + !SuperC + SuperD {} - | ^^^^^^^^^ negative bounds are not supported + | ^ error: negative bounds are not supported - --> $DIR/issue-33418.rs:12:10 + --> $DIR/issue-33418.rs:9:3 + | +LL | + !SuperC + SuperD {} + | ^ + +error: negative bounds are not supported + --> $DIR/issue-33418.rs:11:12 | LL | trait Tr5: !SuperA - | ^^^^^^^^^ -LL | + !SuperB {} - | ^^^^^^^^^ negative bounds are not supported + | ^ + +error: negative bounds are not supported + --> $DIR/issue-33418.rs:13:3 + | +LL | + !SuperB {} + | ^ -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs b/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs index 7bd4b3a165c..3d110adef3e 100644 --- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs +++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs @@ -10,14 +10,14 @@ pub fn index_after_as_cast() { vec![1, 2, 3] as Vec<i32>[0]; //~^ ERROR: cast cannot be followed by indexing vec![1, 2, 3]: Vec<i32>[0]; - //~^ ERROR: type ascription cannot be followed by indexing + //~^ ERROR: expected one of } pub fn index_after_cast_to_index() { (&[0]) as &[i32][0]; //~^ ERROR: cast cannot be followed by indexing (&[0i32]): &[i32; 1][0]; - //~^ ERROR: type ascription cannot be followed by indexing + //~^ ERROR: expected one of } pub fn cast_after_cast() { @@ -25,7 +25,7 @@ pub fn cast_after_cast() { } if 5u64: u64: u64 == 0u64 { - + //~^ ERROR expected `{`, found `:` } let _ = 5u64: u64: u64 as u8 as i8 == 9i8; let _ = 0i32: i32: i32; @@ -36,26 +36,46 @@ pub fn cast_after_cast() { } pub fn cast_cast_method_call() { - let _ = 0i32: i32: i32.count_ones(); - //~^ ERROR: type ascription cannot be followed by a method call - let _ = 0 as i32: i32.count_ones(); - //~^ ERROR: type ascription cannot be followed by a method call - let _ = 0i32: i32 as i32.count_ones(); - //~^ ERROR: cast cannot be followed by a method call + let _ = 0i32: i32: i32.count_ones(); //~ ERROR expected one of +} + +pub fn cast_cast_method_call_2() { + let _ = 0 as i32: i32.count_ones(); //~ ERROR expected one of +} + +pub fn cast_cast_method_call_3() { + let _ = 0i32: i32 as i32.count_ones(); //~ ERROR expected one of +} + +pub fn cast_cast_method_call_4() { let _ = 0 as i32 as i32.count_ones(); //~^ ERROR: cast cannot be followed by a method call - let _ = 0i32: i32: i32 as u32 as i32.count_ones(); - //~^ ERROR: cast cannot be followed by a method call - let _ = 0i32: i32.count_ones(): u32; - //~^ ERROR: type ascription cannot be followed by a method call - let _ = 0 as i32.count_ones(): u32; +} + +pub fn cast_cast_method_call_5() { + let _ = 0i32: i32: i32 as u32 as i32.count_ones(); //~ ERROR expected one of +} + +pub fn cast_cast_method_call_6() { + let _ = 0i32: i32.count_ones(): u32; //~ ERROR expected one of +} + +pub fn cast_cast_method_call_7() { + let _ = 0 as i32.count_ones(): u32; //~ ERROR expected one of //~^ ERROR: cast cannot be followed by a method call - let _ = 0i32: i32.count_ones() as u32; - //~^ ERROR: type ascription cannot be followed by a method call +} + +pub fn cast_cast_method_call_8() { + let _ = 0i32: i32.count_ones() as u32; //~ ERROR expected one of +} + +pub fn cast_cast_method_call_9() { let _ = 0 as i32.count_ones() as u32; //~^ ERROR: cast cannot be followed by a method call - let _ = 0i32: i32: i32.count_ones() as u32 as i32; - //~^ ERROR: type ascription cannot be followed by a method call +} + +pub fn cast_cast_method_call_10() { + let _ = 0i32: i32: i32.count_ones() as u32 as i32; //~ ERROR expected one of } pub fn multiline_error() { @@ -74,8 +94,7 @@ pub fn precedence() { pub fn method_calls() { 0 as i32.max(0); //~^ ERROR: cast cannot be followed by a method call - 0: i32.max(0); - //~^ ERROR: type ascription cannot be followed by a method call + 0: i32.max(0); //~ ERROR expected one of } pub fn complex() { @@ -84,7 +103,7 @@ pub fn complex() { if true { 33 } else { 44 } as i32.max(0), //~^ ERROR: cast cannot be followed by a method call if true { 33 } else { 44 }: i32.max(0) - //~^ ERROR: type ascription cannot be followed by a method call + //~^ ERROR: expected one of ); } @@ -93,7 +112,7 @@ pub fn in_condition() { //~^ ERROR: cast cannot be followed by a method call } if 5u64: u64.max(0) == 0 { - //~^ ERROR: type ascription cannot be followed by a method call + //~^ ERROR: expected `{`, found `:` } } @@ -104,7 +123,7 @@ pub fn inside_block() { } else { false }; let _ = if true { 5u64: u64.max(0) == 0 - //~^ ERROR: type ascription cannot be followed by a method call + //~^ ERROR: expected one of } else { false }; } @@ -112,14 +131,14 @@ static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); //~^ ERROR: cast cannot be followed by indexing static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); -//~^ ERROR: type ascription cannot be followed by indexing +//~^ ERROR: expected one of pub fn cast_then_try() -> Result<u64,u64> { Err(0u64) as Result<u64,u64>?; //~^ ERROR: cast cannot be followed by `?` Err(0u64): Result<u64,u64>?; - //~^ ERROR: type ascription cannot be followed by `?` + //~^ ERROR: expected one of Ok(1) } @@ -131,13 +150,14 @@ pub fn cast_then_call() { drop as F(); //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214] drop_ptr: F(); - //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214] + //~^ ERROR: expected identifier, found `:` } pub fn cast_to_fn_should_work() { let drop_ptr = drop as fn(u8); drop as fn(u8); drop_ptr: fn(u8); + //~^ ERROR expected one of } pub fn parens_after_cast_error() { @@ -145,7 +165,7 @@ pub fn parens_after_cast_error() { drop as fn(u8)(0); //~^ ERROR: cast cannot be followed by a function call drop_ptr: fn(u8)(0); - //~^ ERROR: type ascription cannot be followed by a function call + //~^ ERROR: expected one of } pub async fn cast_then_await() { @@ -153,7 +173,7 @@ pub async fn cast_then_await() { //~^ ERROR: cast cannot be followed by `.await` Box::pin(noop()): Pin<Box<_>>.await; - //~^ ERROR: type ascription cannot be followed by `.await` + //~^ ERROR: expected one of } pub async fn noop() {} @@ -167,5 +187,5 @@ pub fn struct_field() { Foo::default() as Foo.bar; //~^ ERROR: cannot be followed by a field access Foo::default(): Foo.bar; - //~^ ERROR: type ascription cannot be followed by a field access + //~^ ERROR expected one of } diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr index 0c328bde285..d313c888e51 100644 --- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr +++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr @@ -9,21 +9,11 @@ help: try surrounding the expression in parentheses LL | (vec![1, 2, 3] as Vec<i32>)[0]; | + + -error: type ascription cannot be followed by indexing - --> $DIR/issue-35813-postfix-after-cast.rs:12:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:12:18 | LL | vec![1, 2, 3]: Vec<i32>[0]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | (vec![1, 2, 3]: Vec<i32>)[0]; - | + + -help: alternatively, remove the type ascription - | -LL - vec![1, 2, 3]: Vec<i32>[0]; -LL + vec![1, 2, 3][0]; - | + | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: cast cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:17:5 @@ -36,67 +26,50 @@ help: try surrounding the expression in parentheses LL | ((&[0]) as &[i32])[0]; | + + -error: type ascription cannot be followed by indexing - --> $DIR/issue-35813-postfix-after-cast.rs:19:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:19:14 | LL | (&[0i32]): &[i32; 1][0]; - | ^^^^^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses + | ^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: expected `{`, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:27:12 | -LL | ((&[0i32]): &[i32; 1])[0]; - | + + -help: alternatively, remove the type ascription +LL | if 5u64: u64: u64 == 0u64 { + | ^ expected `{` | -LL - (&[0i32]): &[i32; 1][0]; -LL + (&[0i32])[0]; +note: the `if` expression is missing a block after this condition + --> $DIR/issue-35813-postfix-after-cast.rs:27:8 | +LL | if 5u64: u64: u64 == 0u64 { + | ^^^^ -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:39:13 +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:39:17 | LL | let _ = 0i32: i32: i32.count_ones(); - | ^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | let _ = (0i32: i32: i32).count_ones(); - | + + -help: alternatively, remove the type ascription - | -LL - let _ = 0i32: i32: i32.count_ones(); -LL + let _ = 0i32: i32.count_ones(); + | ^ expected one of `.`, `;`, `?`, `else`, or an operator | + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:41:13 +error: expected one of `!`, `(`, `.`, `::`, `;`, `<`, `?`, or `else`, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:43:21 | LL | let _ = 0 as i32: i32.count_ones(); - | ^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | let _ = (0 as i32: i32).count_ones(); - | + + -help: alternatively, remove the type ascription - | -LL - let _ = 0 as i32: i32.count_ones(); -LL + let _ = 0 as i32.count_ones(); + | ^ expected one of 8 possible tokens | + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> -error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:43:13 +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:47:17 | LL | let _ = 0i32: i32 as i32.count_ones(); - | ^^^^^^^^^^^^^^^^ + | ^ expected one of `.`, `;`, `?`, `else`, or an operator | -help: try surrounding the expression in parentheses - | -LL | let _ = (0i32: i32 as i32).count_ones(); - | + + + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:45:13 + --> $DIR/issue-35813-postfix-after-cast.rs:51:13 | LL | let _ = 0 as i32 as i32.count_ones(); | ^^^^^^^^^^^^^^^ @@ -106,35 +79,24 @@ help: try surrounding the expression in parentheses LL | let _ = (0 as i32 as i32).count_ones(); | + + -error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:47:13 +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:56:17 | LL | let _ = 0i32: i32: i32 as u32 as i32.count_ones(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses + | ^ expected one of `.`, `;`, `?`, `else`, or an operator | -LL | let _ = (0i32: i32: i32 as u32 as i32).count_ones(); - | + + + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:49:13 +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:60:17 | LL | let _ = 0i32: i32.count_ones(): u32; - | ^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | let _ = (0i32: i32).count_ones(): u32; - | + + -help: alternatively, remove the type ascription - | -LL - let _ = 0i32: i32.count_ones(): u32; -LL + let _ = 0i32.count_ones(): u32; + | ^ expected one of `.`, `;`, `?`, `else`, or an operator | + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:51:13 + --> $DIR/issue-35813-postfix-after-cast.rs:64:13 | LL | let _ = 0 as i32.count_ones(): u32; | ^^^^^^^^ @@ -144,24 +106,24 @@ help: try surrounding the expression in parentheses LL | let _ = (0 as i32).count_ones(): u32; | + + -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:53:13 +error: expected one of `.`, `;`, `?`, or `else`, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:64:34 | -LL | let _ = 0i32: i32.count_ones() as u32; - | ^^^^^^^^^ - | -help: try surrounding the expression in parentheses +LL | let _ = 0 as i32.count_ones(): u32; + | ^ expected one of `.`, `;`, `?`, or `else` | -LL | let _ = (0i32: i32).count_ones() as u32; - | + + -help: alternatively, remove the type ascription + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:69:17 | -LL - let _ = 0i32: i32.count_ones() as u32; -LL + let _ = 0i32.count_ones() as u32; +LL | let _ = 0i32: i32.count_ones() as u32; + | ^ expected one of `.`, `;`, `?`, `else`, or an operator | + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:55:13 + --> $DIR/issue-35813-postfix-after-cast.rs:73:13 | LL | let _ = 0 as i32.count_ones() as u32; | ^^^^^^^^ @@ -171,24 +133,16 @@ help: try surrounding the expression in parentheses LL | let _ = (0 as i32).count_ones() as u32; | + + -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:57:13 +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:78:17 | LL | let _ = 0i32: i32: i32.count_ones() as u32 as i32; - | ^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | let _ = (0i32: i32: i32).count_ones() as u32 as i32; - | + + -help: alternatively, remove the type ascription - | -LL - let _ = 0i32: i32: i32.count_ones() as u32 as i32; -LL + let _ = 0i32: i32.count_ones() as u32 as i32; + | ^ expected one of `.`, `;`, `?`, `else`, or an operator | + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:62:13 + --> $DIR/issue-35813-postfix-after-cast.rs:82:13 | LL | let _ = 0 | _____________^ @@ -202,7 +156,7 @@ LL ~ as i32) | error: cast cannot be followed by indexing - --> $DIR/issue-35813-postfix-after-cast.rs:70:18 + --> $DIR/issue-35813-postfix-after-cast.rs:90:18 | LL | let x: i32 = &vec![1, 2, 3] as &Vec<i32>[0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -213,7 +167,7 @@ LL | let x: i32 = (&vec![1, 2, 3] as &Vec<i32>)[0]; | + + error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:75:5 + --> $DIR/issue-35813-postfix-after-cast.rs:95:5 | LL | 0 as i32.max(0); | ^^^^^^^^ @@ -223,24 +177,14 @@ help: try surrounding the expression in parentheses LL | (0 as i32).max(0); | + + -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:77:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:97:6 | LL | 0: i32.max(0); - | ^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | (0: i32).max(0); - | + + -help: alternatively, remove the type ascription - | -LL - 0: i32.max(0); -LL + 0.max(0); - | + | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:92:8 + --> $DIR/issue-35813-postfix-after-cast.rs:111:8 | LL | if 5u64 as i32.max(0) == 0 { | ^^^^^^^^^^^ @@ -250,24 +194,20 @@ help: try surrounding the expression in parentheses LL | if (5u64 as i32).max(0) == 0 { | + + -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:95:8 +error: expected `{`, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:114:12 | LL | if 5u64: u64.max(0) == 0 { - | ^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | if (5u64: u64).max(0) == 0 { - | + + -help: alternatively, remove the type ascription + | ^ expected `{` | -LL - if 5u64: u64.max(0) == 0 { -LL + if 5u64.max(0) == 0 { +note: the `if` expression is missing a block after this condition + --> $DIR/issue-35813-postfix-after-cast.rs:114:8 | +LL | if 5u64: u64.max(0) == 0 { + | ^^^^ error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:102:9 + --> $DIR/issue-35813-postfix-after-cast.rs:121:9 | LL | 5u64 as u32.max(0) == 0 | ^^^^^^^^^^^ @@ -277,24 +217,14 @@ help: try surrounding the expression in parentheses LL | (5u64 as u32).max(0) == 0 | + + -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:106:9 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:125:13 | LL | 5u64: u64.max(0) == 0 - | ^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | (5u64: u64).max(0) == 0 - | + + -help: alternatively, remove the type ascription - | -LL - 5u64: u64.max(0) == 0 -LL + 5u64.max(0) == 0 - | + | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: cast cannot be followed by indexing - --> $DIR/issue-35813-postfix-after-cast.rs:111:24 + --> $DIR/issue-35813-postfix-after-cast.rs:130:24 | LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); | ^^^^^^^^^^^^^^^^^^ @@ -304,24 +234,14 @@ help: try surrounding the expression in parentheses LL | static bar: &[i32] = &((&[1,2,3] as &[i32])[0..1]); | + + -error: type ascription cannot be followed by indexing - --> $DIR/issue-35813-postfix-after-cast.rs:114:25 +error: expected one of `)`, `,`, `.`, `?`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:133:36 | LL | static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]); - | + + -help: alternatively, remove the type ascription - | -LL - static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); -LL + static bar2: &[i32] = &(&[1i32,2,3][0..1]); - | + | ^ expected one of `)`, `,`, `.`, `?`, or an operator error: cast cannot be followed by `?` - --> $DIR/issue-35813-postfix-after-cast.rs:119:5 + --> $DIR/issue-35813-postfix-after-cast.rs:138:5 | LL | Err(0u64) as Result<u64,u64>?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -331,24 +251,28 @@ help: try surrounding the expression in parentheses LL | (Err(0u64) as Result<u64,u64>)?; | + + -error: type ascription cannot be followed by `?` - --> $DIR/issue-35813-postfix-after-cast.rs:121:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:140:14 | LL | Err(0u64): Result<u64,u64>?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses + | ^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: expected identifier, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:152:13 | -LL | (Err(0u64): Result<u64,u64>)?; - | + + -help: alternatively, remove the type ascription +LL | drop_ptr: F(); + | ^ expected identifier | -LL - Err(0u64): Result<u64,u64>?; -LL + Err(0u64)?; + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:159:13 | +LL | drop_ptr: fn(u8); + | ^ expected one of 8 possible tokens error: cast cannot be followed by a function call - --> $DIR/issue-35813-postfix-after-cast.rs:145:5 + --> $DIR/issue-35813-postfix-after-cast.rs:165:5 | LL | drop as fn(u8)(0); | ^^^^^^^^^^^^^^ @@ -358,24 +282,14 @@ help: try surrounding the expression in parentheses LL | (drop as fn(u8))(0); | + + -error: type ascription cannot be followed by a function call - --> $DIR/issue-35813-postfix-after-cast.rs:147:5 +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:167:13 | LL | drop_ptr: fn(u8)(0); - | ^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | (drop_ptr: fn(u8))(0); - | + + -help: alternatively, remove the type ascription - | -LL - drop_ptr: fn(u8)(0); -LL + drop_ptr(0); - | + | ^ expected one of 8 possible tokens error: cast cannot be followed by `.await` - --> $DIR/issue-35813-postfix-after-cast.rs:152:5 + --> $DIR/issue-35813-postfix-after-cast.rs:172:5 | LL | Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -385,24 +299,14 @@ help: try surrounding the expression in parentheses LL | (Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>).await; | + + -error: type ascription cannot be followed by `.await` - --> $DIR/issue-35813-postfix-after-cast.rs:155:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:175:21 | LL | Box::pin(noop()): Pin<Box<_>>.await; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | (Box::pin(noop()): Pin<Box<_>>).await; - | + + -help: alternatively, remove the type ascription - | -LL - Box::pin(noop()): Pin<Box<_>>.await; -LL + Box::pin(noop()).await; - | + | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: cast cannot be followed by a field access - --> $DIR/issue-35813-postfix-after-cast.rs:167:5 + --> $DIR/issue-35813-postfix-after-cast.rs:187:5 | LL | Foo::default() as Foo.bar; | ^^^^^^^^^^^^^^^^^^^^^ @@ -412,24 +316,14 @@ help: try surrounding the expression in parentheses LL | (Foo::default() as Foo).bar; | + + -error: type ascription cannot be followed by a field access - --> $DIR/issue-35813-postfix-after-cast.rs:169:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:189:19 | LL | Foo::default(): Foo.bar; - | ^^^^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | (Foo::default(): Foo).bar; - | + + -help: alternatively, remove the type ascription - | -LL - Foo::default(): Foo.bar; -LL + Foo::default().bar; - | + | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: cast cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:84:9 + --> $DIR/issue-35813-postfix-after-cast.rs:103:9 | LL | if true { 33 } else { 44 } as i32.max(0), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -439,34 +333,18 @@ help: try surrounding the expression in parentheses LL | (if true { 33 } else { 44 } as i32).max(0), | + + -error: type ascription cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:86:9 +error: expected one of `,`, `.`, `?`, or an operator, found `:` + --> $DIR/issue-35813-postfix-after-cast.rs:105:35 | LL | if true { 33 } else { 44 }: i32.max(0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try surrounding the expression in parentheses - | -LL | (if true { 33 } else { 44 }: i32).max(0) - | + + -help: alternatively, remove the type ascription - | -LL - if true { 33 } else { 44 }: i32.max(0) -LL + if true { 33 } else { 44 }.max(0) - | + | ^ expected one of `,`, `.`, `?`, or an operator error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/issue-35813-postfix-after-cast.rs:131:13 + --> $DIR/issue-35813-postfix-after-cast.rs:150:13 | LL | drop as F(); | ^^^ only `Fn` traits may use parentheses -error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/issue-35813-postfix-after-cast.rs:133:15 - | -LL | drop_ptr: F(); - | ^^^ only `Fn` traits may use parentheses - -error: aborting due to 36 previous errors +error: aborting due to 39 previous errors For more information about this error, try `rustc --explain E0214`. diff --git a/tests/ui/parser/issues/issue-44406.rs b/tests/ui/parser/issues/issue-44406.rs index a5b7e83a016..6719e582848 100644 --- a/tests/ui/parser/issues/issue-44406.rs +++ b/tests/ui/parser/issues/issue-44406.rs @@ -6,5 +6,4 @@ macro_rules! foo { fn main() { foo!(true); - //~^ ERROR expected identifier, found keyword } diff --git a/tests/ui/parser/issues/issue-44406.stderr b/tests/ui/parser/issues/issue-44406.stderr index de02ea85b27..69ff64c2772 100644 --- a/tests/ui/parser/issues/issue-44406.stderr +++ b/tests/ui/parser/issues/issue-44406.stderr @@ -1,14 +1,3 @@ -error: expected identifier, found keyword `true` - --> $DIR/issue-44406.rs:8:10 - | -LL | foo!(true); - | ^^^^ expected identifier, found keyword - | -help: escape `true` to use it as an identifier - | -LL | foo!(r#true); - | ++ - error: invalid `struct` delimiters or `fn` call arguments --> $DIR/issue-44406.rs:3:9 | @@ -29,5 +18,5 @@ LL - bar(baz: $rest) LL + bar(: $rest) | -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/parser/issues/issue-62913.rs b/tests/ui/parser/issues/issue-62913.rs index 0db06f636c3..a55ef5ac710 100644 --- a/tests/ui/parser/issues/issue-62913.rs +++ b/tests/ui/parser/issues/issue-62913.rs @@ -1,4 +1,4 @@ "\u\\" //~^ ERROR incorrect unicode escape sequence //~| ERROR invalid trailing slash in literal -//~| ERROR expected item, found `"\u\\"` +//~| ERROR expected item, found `"\u\"` diff --git a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed index 95019b27869..2c42f973174 100644 --- a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed +++ b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed @@ -6,9 +6,12 @@ fn main() {} -pub fn f1<T>() {} +pub fn f1<T: 'static>() {} //~^ ERROR negative bounds are not supported -pub fn f2<'a, T: Ord>() {} +//~| ERROR `!` may only modify trait bounds, not lifetime bound +pub fn f2<'a, T: Ord + 'a>() {} //~^ ERROR negative bounds are not supported -pub fn f3<'a, T: Ord>() {} +//~| ERROR `!` may only modify trait bounds, not lifetime bound +pub fn f3<'a, T: 'a + Ord>() {} //~^ ERROR negative bounds are not supported +//~| ERROR `!` may only modify trait bounds, not lifetime bound diff --git a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs index 82f54f8faa9..e510efaae5b 100644 --- a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs +++ b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs @@ -8,7 +8,10 @@ fn main() {} pub fn f1<T: !'static>() {} //~^ ERROR negative bounds are not supported +//~| ERROR `!` may only modify trait bounds, not lifetime bound pub fn f2<'a, T: Ord + !'a>() {} //~^ ERROR negative bounds are not supported +//~| ERROR `!` may only modify trait bounds, not lifetime bound pub fn f3<'a, T: !'a + Ord>() {} //~^ ERROR negative bounds are not supported +//~| ERROR `!` may only modify trait bounds, not lifetime bound diff --git a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr index a4a422948ac..91fe02db3a6 100644 --- a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr +++ b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr @@ -1,20 +1,38 @@ +error: `!` may only modify trait bounds, not lifetime bounds + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:14 + | +LL | pub fn f1<T: !'static>() {} + | ^ + +error: `!` may only modify trait bounds, not lifetime bounds + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:12:24 + | +LL | pub fn f2<'a, T: Ord + !'a>() {} + | ^ + +error: `!` may only modify trait bounds, not lifetime bounds + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:15:18 + | +LL | pub fn f3<'a, T: !'a + Ord>() {} + | ^ + error: negative bounds are not supported - --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:12 + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:14 | LL | pub fn f1<T: !'static>() {} - | ^^^^^^^^^^ negative bounds are not supported + | ^ error: negative bounds are not supported - --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:11:22 + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:12:24 | LL | pub fn f2<'a, T: Ord + !'a>() {} - | ^^^^^ negative bounds are not supported + | ^ error: negative bounds are not supported - --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:13:16 + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:15:18 | LL | pub fn f3<'a, T: !'a + Ord>() {} - | ^^^^^ negative bounds are not supported + | ^ -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors diff --git a/tests/ui/parser/issues/issue-91461.rs b/tests/ui/parser/issues/issue-91461.rs index 3e3c411c478..80e0940ad8f 100644 --- a/tests/ui/parser/issues/issue-91461.rs +++ b/tests/ui/parser/issues/issue-91461.rs @@ -1,6 +1,5 @@ fn main() { a(_:b:,) - //~^ ERROR: expected identifier, found reserved identifier `_` - //~| ERROR: expected type, found `,` - //~| ERROR: expected type, found `,` + //~^ ERROR expected identifier, found reserved identifier + //~| ERROR: expected one of } diff --git a/tests/ui/parser/issues/issue-91461.stderr b/tests/ui/parser/issues/issue-91461.stderr index 94fcf1721d8..27e1b5cdc17 100644 --- a/tests/ui/parser/issues/issue-91461.stderr +++ b/tests/ui/parser/issues/issue-91461.stderr @@ -4,28 +4,11 @@ error: expected identifier, found reserved identifier `_` LL | a(_:b:,) | ^ expected identifier, found reserved identifier -error: expected type, found `,` - --> $DIR/issue-91461.rs:2:11 +error: expected one of `)`, `,`, `.`, `?`, or an operator, found `:` + --> $DIR/issue-91461.rs:2:8 | LL | a(_:b:,) - | - -^ expected type - | | | - | | tried to parse a type due to this type ascription - | while parsing this struct - | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` - = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information - -error: expected type, found `,` - --> $DIR/issue-91461.rs:2:11 - | -LL | a(_:b:,) - | -^ expected type - | | - | tried to parse a type due to this type ascription - | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` - = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + | ^ expected one of `)`, `,`, `.`, `?`, or an operator -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs b/tests/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs index a709e34b501..01a978d5557 100644 --- a/tests/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs +++ b/tests/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs @@ -22,8 +22,7 @@ fn case_1() { #[cfg(FALSE)] fn case_2() { let a @ (b: u8); - //~^ ERROR expected one of `!` - //~| ERROR expected one of `)` + //~^ ERROR expected one of `)` } #[cfg(FALSE)] diff --git a/tests/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr b/tests/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr index 27660ae406e..0c109ff6bba 100644 --- a/tests/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr +++ b/tests/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.stderr @@ -9,18 +9,14 @@ error: expected one of `)`, `,`, `@`, or `|`, found `:` | LL | let a @ (b: u8); | ^ expected one of `)`, `,`, `@`, or `|` - -error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found `)` - --> $DIR/nested-type-ascription-syntactically-invalid.rs:24:19 | -LL | let a @ (b: u8); - | ^ expected one of 7 possible tokens + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found `@` - --> $DIR/nested-type-ascription-syntactically-invalid.rs:31:15 + --> $DIR/nested-type-ascription-syntactically-invalid.rs:30:15 | LL | let a: T1 @ Outer(b: T2); | ^ expected one of 7 possible tokens -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/phantom-auto-trait.stderr b/tests/ui/phantom-auto-trait.stderr index 4769d53eb35..5af648f6a0c 100644 --- a/tests/ui/phantom-auto-trait.stderr +++ b/tests/ui/phantom-auto-trait.stderr @@ -11,7 +11,8 @@ note: required for `&T` to implement `Zen` | LL | unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {} | ^^^ ^^^^^ ---- unsatisfied trait bound introduced here - = note: required because it appears within the type `PhantomData<&T>` +note: required because it appears within the type `PhantomData<&T>` + --> $SRC_DIR/core/src/marker.rs:LL:COL note: required because it appears within the type `Guard<'_, T>` --> $DIR/phantom-auto-trait.rs:12:8 | @@ -40,7 +41,8 @@ note: required for `&T` to implement `Zen` | LL | unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {} | ^^^ ^^^^^ ---- unsatisfied trait bound introduced here - = note: required because it appears within the type `PhantomData<&T>` +note: required because it appears within the type `PhantomData<&T>` + --> $SRC_DIR/core/src/marker.rs:LL:COL note: required because it appears within the type `Guard<'_, T>` --> $DIR/phantom-auto-trait.rs:12:8 | diff --git a/tests/ui/recursion/recursive-requirements.stderr b/tests/ui/recursion/recursive-requirements.stderr index 8ee154ce57b..bb63f7cd0dc 100644 --- a/tests/ui/recursion/recursive-requirements.stderr +++ b/tests/ui/recursion/recursive-requirements.stderr @@ -28,7 +28,8 @@ note: required because it appears within the type `Bar` | LL | pub struct Bar { | ^^^ - = note: required because it appears within the type `PhantomData<Bar>` +note: required because it appears within the type `PhantomData<Bar>` + --> $SRC_DIR/core/src/marker.rs:LL:COL note: required because it appears within the type `Foo` --> $DIR/recursive-requirements.rs:5:12 | diff --git a/tests/ui/repr/invalid_repr_list_help.rs b/tests/ui/repr/invalid_repr_list_help.rs index c320984536c..785ffb1e0f4 100644 --- a/tests/ui/repr/invalid_repr_list_help.rs +++ b/tests/ui/repr/invalid_repr_list_help.rs @@ -15,3 +15,8 @@ pub struct OwO3 { pub enum OwO4 { UwU = 1, } + +#[repr(uwu)] //~ERROR: unrecognized representation hint +#[doc(owo)] //~WARN: unknown `doc` attribute + //~^ WARN: this was previously +pub struct Owo5; diff --git a/tests/ui/repr/invalid_repr_list_help.stderr b/tests/ui/repr/invalid_repr_list_help.stderr index 2acd56d9a32..48a6af3dd4c 100644 --- a/tests/ui/repr/invalid_repr_list_help.stderr +++ b/tests/ui/repr/invalid_repr_list_help.stderr @@ -30,6 +30,24 @@ LL | #[repr(uwu, u8)] | = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` -error: aborting due to 4 previous errors +warning: unknown `doc` attribute `owo` + --> $DIR/invalid_repr_list_help.rs:20:7 + | +LL | #[doc(owo)] + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: `#[warn(invalid_doc_attributes)]` on by default + +error[E0552]: unrecognized representation hint + --> $DIR/invalid_repr_list_help.rs:19:8 + | +LL | #[repr(uwu)] + | ^^^ + | + = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` + +error: aborting due to 5 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0552`. diff --git a/tests/ui/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfc-2627-raw-dylib/dlltool-failed.rs new file mode 100644 index 00000000000..d7a418959bf --- /dev/null +++ b/tests/ui/rfc-2627-raw-dylib/dlltool-failed.rs @@ -0,0 +1,19 @@ +// Tests that dlltool failing to generate an import library will raise an error. + +// only-gnu +// only-windows +// needs-dlltool +// compile-flags: --crate-type lib --emit link +// normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL" +// normalize-stderr-test: "[^ ]*/foo.def" -> "$$DEF_FILE" +#[link(name = "foo", kind = "raw-dylib")] +extern "C" { + // `@1` is an invalid name to export, as it usually indicates that something + // is being exported via ordinal. + #[link_name = "@1"] + fn f(x: i32); +} + +pub fn lib_main() { + unsafe { f(42); } +} diff --git a/tests/ui/rfc-2627-raw-dylib/dlltool-failed.stderr b/tests/ui/rfc-2627-raw-dylib/dlltool-failed.stderr new file mode 100644 index 00000000000..020ac6a2b67 --- /dev/null +++ b/tests/ui/rfc-2627-raw-dylib/dlltool-failed.stderr @@ -0,0 +1,5 @@ +error: Dlltool could not create import library: + $DLLTOOL: Syntax error in def file $DEF_FILE:1 + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs b/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs index 22d57f8bedd..7bc44d65be9 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs @@ -1,7 +1,5 @@ // only-windows // only-x86 -#![feature(raw_dylib)] - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] //~^ ERROR import name type must be of the form `import_name_type = "string"` extern "C" { } diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr b/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr index 0e95fec29d2..fb70b987fc7 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr @@ -1,5 +1,5 @@ error: import name type must be of the form `import_name_type = "string"` - --> $DIR/import-name-type-invalid-format.rs:5:42 + --> $DIR/import-name-type-invalid-format.rs:3:42 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs b/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs index 7ccb0082fb9..b96f61a26da 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs @@ -1,8 +1,6 @@ // ignore-tidy-linelength // only-windows // only-x86 -#![feature(raw_dylib)] - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] //~^ ERROR multiple `import_name_type` arguments in a single `#[link]` attribute extern "C" { } diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr b/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr index 7c0e0be911f..9533061892f 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr @@ -1,5 +1,5 @@ error: multiple `import_name_type` arguments in a single `#[link]` attribute - --> $DIR/import-name-type-multiple.rs:6:74 + --> $DIR/import-name-type-multiple.rs:4:74 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs b/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs index f728a578d3b..067e82a17fd 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs @@ -1,7 +1,5 @@ // only-windows // only-x86 -#![feature(raw_dylib)] - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] //~^ ERROR unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated extern "C" { } diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr b/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr index 2b299f2fea3..2bce9758e99 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr @@ -1,5 +1,5 @@ error: unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated - --> $DIR/import-name-type-unknown-value.rs:5:42 + --> $DIR/import-name-type-unknown-value.rs:3:42 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs b/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs index ae9207864a2..34e907bde83 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs @@ -1,7 +1,5 @@ // only-windows // only-x86 -#![feature(raw_dylib)] - #[link(name = "foo", import_name_type = "decorated")] //~^ ERROR import name type can only be used with link kind `raw-dylib` extern "C" { } diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr b/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr index 5898cd875a1..75cadc471c4 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr @@ -1,11 +1,11 @@ error: import name type can only be used with link kind `raw-dylib` - --> $DIR/import-name-type-unsupported-link-kind.rs:5:22 + --> $DIR/import-name-type-unsupported-link-kind.rs:3:22 | LL | #[link(name = "foo", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: import name type can only be used with link kind `raw-dylib` - --> $DIR/import-name-type-unsupported-link-kind.rs:9:39 + --> $DIR/import-name-type-unsupported-link-kind.rs:7:39 | LL | #[link(name = "bar", kind = "static", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.rs b/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.rs new file mode 100644 index 00000000000..a07be9d92b4 --- /dev/null +++ b/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.rs @@ -0,0 +1,13 @@ +// Tests that failing to run dlltool will raise an error. + +// only-gnu +// only-windows +// compile-flags: --crate-type lib --emit link -Cdlltool=does_not_exit.exe +#[link(name = "foo", kind = "raw-dylib")] +extern "C" { + fn f(x: i32); +} + +pub fn lib_main() { + unsafe { f(42); } +} diff --git a/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.stderr b/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.stderr new file mode 100644 index 00000000000..3ae901e0dbc --- /dev/null +++ b/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.stderr @@ -0,0 +1,4 @@ +error: Error calling dlltool 'does_not_exit.exe': program not found + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs index 1a128c87a0c..b04c2facbcd 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name="foo")] extern "C" { #[link_name="foo"] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr index 481a06d2797..f1e54d37827 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr @@ -1,11 +1,11 @@ error: cannot use `#[link_name]` with `#[link_ordinal]` - --> $DIR/link-ordinal-and-name.rs:6:5 + --> $DIR/link-ordinal-and-name.rs:4:5 | LL | #[link_ordinal(42)] | ^^^^^^^^^^^^^^^^^^^ error: cannot use `#[link_name]` with `#[link_ordinal]` - --> $DIR/link-ordinal-and-name.rs:10:5 + --> $DIR/link-ordinal-and-name.rs:8:5 | LL | #[link_ordinal(5)] | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs index 7c8da050cf6..9b7e8d70743 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal("JustMonika")] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr index 55cdcad75a4..6341e57a0be 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr @@ -1,5 +1,5 @@ error: illegal ordinal format in `link_ordinal` - --> $DIR/link-ordinal-invalid-format.rs:5:5 + --> $DIR/link-ordinal-invalid-format.rs:3:5 | LL | #[link_ordinal("JustMonika")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[link_ordinal("JustMonika")] = note: an unsuffixed integer value, e.g., `1`, is expected error: illegal ordinal format in `link_ordinal` - --> $DIR/link-ordinal-invalid-format.rs:8:5 + --> $DIR/link-ordinal-invalid-format.rs:6:5 | LL | #[link_ordinal("JustMonika")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs index 9feed394110..6b8cd49566d 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal()] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr index 853cdad8c1c..1b04bb228e7 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr @@ -1,5 +1,5 @@ error: incorrect number of arguments to `#[link_ordinal]` - --> $DIR/link-ordinal-missing-argument.rs:5:5 + --> $DIR/link-ordinal-missing-argument.rs:3:5 | LL | #[link_ordinal()] | ^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[link_ordinal()] = note: the attribute requires exactly one argument error: incorrect number of arguments to `#[link_ordinal]` - --> $DIR/link-ordinal-missing-argument.rs:8:5 + --> $DIR/link-ordinal-missing-argument.rs:6:5 | LL | #[link_ordinal()] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs index 631c363d4ba..8842cb94404 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs @@ -1,6 +1,4 @@ // only-windows -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo", kind = "raw-dylib")] extern "C" { #[link_ordinal(1)] //~ ERROR multiple `link_ordinal` attributes diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr index c0453d2bf01..2e6cf3761c2 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr @@ -1,23 +1,23 @@ error: multiple `link_ordinal` attributes - --> $DIR/link-ordinal-multiple.rs:6:5 + --> $DIR/link-ordinal-multiple.rs:4:5 | LL | #[link_ordinal(1)] | ^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/link-ordinal-multiple.rs:7:5 + --> $DIR/link-ordinal-multiple.rs:5:5 | LL | #[link_ordinal(2)] | ^^^^^^^^^^^^^^^^^^ error: multiple `link_ordinal` attributes - --> $DIR/link-ordinal-multiple.rs:9:5 + --> $DIR/link-ordinal-multiple.rs:7:5 | LL | #[link_ordinal(1)] | ^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/link-ordinal-multiple.rs:10:5 + --> $DIR/link-ordinal-multiple.rs:8:5 | LL | #[link_ordinal(2)] | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs index 54e614164b3..f33a3d62e26 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link_ordinal(123)] //~^ ERROR attribute should be applied to a foreign function or static struct Foo {} diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr index ec4104fbe50..8f279508720 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr @@ -1,17 +1,17 @@ error: attribute should be applied to a foreign function or static - --> $DIR/link-ordinal-not-foreign-fn.rs:3:1 + --> $DIR/link-ordinal-not-foreign-fn.rs:1:1 | LL | #[link_ordinal(123)] | ^^^^^^^^^^^^^^^^^^^^ error: attribute should be applied to a foreign function or static - --> $DIR/link-ordinal-not-foreign-fn.rs:7:1 + --> $DIR/link-ordinal-not-foreign-fn.rs:5:1 | LL | #[link_ordinal(123)] | ^^^^^^^^^^^^^^^^^^^^ error: attribute should be applied to a foreign function or static - --> $DIR/link-ordinal-not-foreign-fn.rs:11:1 + --> $DIR/link-ordinal-not-foreign-fn.rs:9:1 | LL | #[link_ordinal(42)] | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs index 46731581ebc..9d741630fc9 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal(72436)] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr index fef6de6aedf..811145e77ee 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr @@ -1,5 +1,5 @@ error: ordinal value in `link_ordinal` is too large: `72436` - --> $DIR/link-ordinal-too-large.rs:5:5 + --> $DIR/link-ordinal-too-large.rs:3:5 | LL | #[link_ordinal(72436)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[link_ordinal(72436)] = note: the value may not exceed `u16::MAX` error: ordinal value in `link_ordinal` is too large: `72436` - --> $DIR/link-ordinal-too-large.rs:8:5 + --> $DIR/link-ordinal-too-large.rs:6:5 | LL | #[link_ordinal(72436)] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs index 71e0ac9f3ee..9988115fd8b 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal(3, 4)] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr index 7e0fcd845cb..d5ce8aff34f 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr @@ -1,5 +1,5 @@ error: incorrect number of arguments to `#[link_ordinal]` - --> $DIR/link-ordinal-too-many-arguments.rs:5:5 + --> $DIR/link-ordinal-too-many-arguments.rs:3:5 | LL | #[link_ordinal(3, 4)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[link_ordinal(3, 4)] = note: the attribute requires exactly one argument error: incorrect number of arguments to `#[link_ordinal]` - --> $DIR/link-ordinal-too-many-arguments.rs:8:5 + --> $DIR/link-ordinal-too-many-arguments.rs:6:5 | LL | #[link_ordinal(3, 4)] | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs index 329c93fc196..14e915d602a 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal(3)] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr index 5fbffbda570..200b8f62874 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr @@ -1,11 +1,11 @@ error: `#[link_ordinal]` is only supported if link kind is `raw-dylib` - --> $DIR/link-ordinal-unsupported-link-kind.rs:5:5 + --> $DIR/link-ordinal-unsupported-link-kind.rs:3:5 | LL | #[link_ordinal(3)] | ^^^^^^^^^^^^^^^^^^ error: `#[link_ordinal]` is only supported if link kind is `raw-dylib` - --> $DIR/link-ordinal-unsupported-link-kind.rs:12:5 + --> $DIR/link-ordinal-unsupported-link-kind.rs:10:5 | LL | #[link_ordinal(3)] | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/multiple-declarations.rs b/tests/ui/rfc-2627-raw-dylib/multiple-declarations.rs index 6542faad264..b4173f3b60b 100644 --- a/tests/ui/rfc-2627-raw-dylib/multiple-declarations.rs +++ b/tests/ui/rfc-2627-raw-dylib/multiple-declarations.rs @@ -2,7 +2,6 @@ // only-windows // compile-flags: --crate-type lib --emit link #![allow(clashing_extern_declarations)] -#![feature(raw_dylib)] #[link(name = "foo", kind = "raw-dylib")] extern "C" { fn f(x: i32); diff --git a/tests/ui/rfc-2627-raw-dylib/multiple-declarations.stderr b/tests/ui/rfc-2627-raw-dylib/multiple-declarations.stderr index c6808bec7b5..51010840548 100644 --- a/tests/ui/rfc-2627-raw-dylib/multiple-declarations.stderr +++ b/tests/ui/rfc-2627-raw-dylib/multiple-declarations.stderr @@ -1,5 +1,5 @@ error: multiple declarations of external function `f` from library `foo.dll` have different calling conventions - --> $DIR/multiple-declarations.rs:14:9 + --> $DIR/multiple-declarations.rs:13:9 | LL | fn f(x: i32); | ^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs b/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs index 4efffbd532e..d4c6658a330 100644 --- a/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs +++ b/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs @@ -1,6 +1,5 @@ // ignore-windows // compile-flags: --crate-type lib -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] #[link(name = "foo", kind = "raw-dylib")] //~^ ERROR: link kind `raw-dylib` is only supported on Windows targets extern "C" {} diff --git a/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr b/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr index 14e791f1fb9..b635a09afba 100644 --- a/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr +++ b/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr @@ -1,5 +1,5 @@ error[E0455]: link kind `raw-dylib` is only supported on Windows targets - --> $DIR/raw-dylib-windows-only.rs:4:29 + --> $DIR/raw-dylib-windows-only.rs:3:29 | LL | #[link(name = "foo", kind = "raw-dylib")] | ^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr index d4f42b787e4..97f346e8c1d 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr @@ -4,5 +4,11 @@ error: ~const can only be applied to `#[const_trait]` traits LL | trait Bar: ~const Foo {} | ^^^ -error: aborting due to previous error +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:11:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr index d4f42b787e4..97f346e8c1d 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -4,5 +4,11 @@ error: ~const can only be applied to `#[const_trait]` traits LL | trait Bar: ~const Foo {} | ^^^ -error: aborting due to previous error +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:11:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs index d183efde2df..ecb06271cd9 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -10,6 +10,7 @@ trait Foo { #[cfg_attr(any(yy, ny), const_trait)] trait Bar: ~const Foo {} //[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` +//[ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]` const fn foo<T: Bar>(x: &T) { x.a(); diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr index 13fc719f28c..c9fa1955498 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:15:7 + --> $DIR/super-traits-fail-2.rs:16:7 | LL | x.a(); | ^ the trait `~const Foo` is not implemented for `T` | note: the trait `Foo` is implemented for `T`, but that implementation is not `const` - --> $DIR/super-traits-fail-2.rs:15:5 + --> $DIR/super-traits-fail-2.rs:16:5 | LL | x.a(); | ^ diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr index 13fc719f28c..c9fa1955498 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:15:7 + --> $DIR/super-traits-fail-2.rs:16:7 | LL | x.a(); | ^ the trait `~const Foo` is not implemented for `T` | note: the trait `Foo` is implemented for `T`, but that implementation is not `const` - --> $DIR/super-traits-fail-2.rs:15:5 + --> $DIR/super-traits-fail-2.rs:16:5 | LL | x.a(); | ^ diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index d433e1cfa69..fdc6b805889 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -5,10 +5,16 @@ LL | trait Bar: ~const Foo {} | ^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:15:24 + --> $DIR/super-traits-fail-3.rs:12:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:16:24 | LL | const fn foo<T: ~const Bar>(x: &T) { | ^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index 2a7e8e00bc7..7375b8c819c 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -4,5 +4,11 @@ error: ~const can only be applied to `#[const_trait]` traits LL | trait Bar: ~const Foo {} | ^^^ -error: aborting due to previous error +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:12:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs index 70d2936d3b2..8cf64944ac1 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -11,6 +11,7 @@ trait Foo { #[cfg_attr(any(yy, ny), const_trait)] trait Bar: ~const Foo {} //[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` +//[ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]` const fn foo<T: ~const Bar>(x: &T) { //[yn,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index e5978c12a09..7a152914b69 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -1,5 +1,5 @@ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:15:24 + --> $DIR/super-traits-fail-3.rs:16:24 | LL | const fn foo<T: ~const Bar>(x: &T) { | ^^^ diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs new file mode 100644 index 00000000000..e4b07ab8108 --- /dev/null +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs @@ -0,0 +1,7 @@ +// run-pass + +#![feature(c_str_literals)] + +fn main() { + assert_eq!(b"test\0", c"test".to_bytes_with_nul()); +} diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs new file mode 100644 index 00000000000..b27da26ed23 --- /dev/null +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs @@ -0,0 +1,13 @@ +// gate-test-c_str_literals + +macro_rules! m { + ($t:tt) => {} +} + +fn main() { + c"foo"; + //~^ ERROR: `c".."` literals are experimental + + m!(c"test"); + //~^ ERROR: `c".."` literals are experimental +} diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr b/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr new file mode 100644 index 00000000000..bc0c537aada --- /dev/null +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr @@ -0,0 +1,21 @@ +error[E0658]: `c".."` literals are experimental + --> $DIR/gate.rs:8:5 + | +LL | c"foo"; + | ^^^^^^ + | + = note: see issue #105723 <https://github.com/rust-lang/rust/issues/105723> for more information + = help: add `#![feature(c_str_literals)]` to the crate attributes to enable + +error[E0658]: `c".."` literals are experimental + --> $DIR/gate.rs:11:8 + | +LL | m!(c"test"); + | ^^^^^^^ + | + = note: see issue #105723 <https://github.com/rust-lang/rust/issues/105723> for more information + = help: add `#![feature(c_str_literals)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs new file mode 100644 index 00000000000..7bc6097f124 --- /dev/null +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs Binary files differdiff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr new file mode 100644 index 00000000000..ff9006f6f97 --- /dev/null +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr Binary files differdiff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs new file mode 100644 index 00000000000..82e8e2090d7 --- /dev/null +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs @@ -0,0 +1,10 @@ +// run-pass + +#![feature(c_str_literals)] + +fn main() { + assert_eq!( + c"\xEF\x80🦀\u{1F980}".to_bytes_with_nul(), + &[0xEF, 0x80, 0xF0, 0x9F, 0xA6, 0x80, 0xF0, 0x9F, 0xA6, 0x80, 0x00], + ); +} diff --git a/tests/ui/sanitize/cfg.rs b/tests/ui/sanitize/cfg.rs index 79dfe58f04d..c0f08a6d1e5 100644 --- a/tests/ui/sanitize/cfg.rs +++ b/tests/ui/sanitize/cfg.rs @@ -3,12 +3,16 @@ // needs-sanitizer-support // needs-sanitizer-address +// needs-sanitizer-cfi +// needs-sanitizer-kcfi // needs-sanitizer-leak // needs-sanitizer-memory // needs-sanitizer-thread // check-pass // revisions: address leak memory thread //[address]compile-flags: -Zsanitizer=address --cfg address +//[cfi]compile-flags: -Zsanitizer=cfi --cfg cfi +//[kcfi]compile-flags: -Zsanitizer=kcfi --cfg kcfi //[leak]compile-flags: -Zsanitizer=leak --cfg leak //[memory]compile-flags: -Zsanitizer=memory --cfg memory //[thread]compile-flags: -Zsanitizer=thread --cfg thread @@ -18,6 +22,12 @@ #[cfg(all(sanitize = "address", address))] fn main() {} +#[cfg(all(sanitize = "cfi", cfi))] +fn main() {} + +#[cfg(all(sanitize = "kcfi", kcfi))] +fn main() {} + #[cfg(all(sanitize = "leak", leak))] fn main() {} diff --git a/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.rs b/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.rs new file mode 100644 index 00000000000..462a3f661ef --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.rs @@ -0,0 +1,8 @@ +// Verifies that `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`. +// +// needs-sanitizer-cfi +// compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer-cfi-canonical-jump-tables=false + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.stderr b/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.stderr new file mode 100644 index 00000000000..3ee95634b16 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi` + +error: aborting due to previous error + diff --git a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-attr-cfg.rs b/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-attr-cfg.rs new file mode 100644 index 00000000000..3a0fc143da6 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-attr-cfg.rs @@ -0,0 +1,9 @@ +// Verifies that when compiling with `-Zsanitizer-cfi-generalize-pointers` the +// `#[cfg(sanitizer_cfi_generalize_pointers)]` attribute is configured. +// +// needs-sanitizer-cfi +// check-pass +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers + +#[cfg(sanitizer_cfi_generalize_pointers)] +fn main() {} diff --git a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.rs b/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.rs new file mode 100644 index 00000000000..f31b8bde7ae --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.rs @@ -0,0 +1,9 @@ +// Verifies that `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or +// `-Zsanitizer=kcfi`. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer-cfi-generalize-pointers + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.stderr b/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.stderr new file mode 100644 index 00000000000..6eb09a53b48 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` + +error: aborting due to previous error + diff --git a/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.rs b/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.rs new file mode 100644 index 00000000000..fe044f50a21 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.rs @@ -0,0 +1,11 @@ +// Verifies that invalid user-defined CFI encodings can't be used. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![feature(cfi_encoding, no_core)] +#![no_core] +#![no_main] + +#[cfi_encoding] //~ERROR 10:1: 10:16: malformed `cfi_encoding` attribute input +pub struct Type1(i32); diff --git a/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.stderr b/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.stderr new file mode 100644 index 00000000000..e23bafb1814 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.stderr @@ -0,0 +1,8 @@ +error: malformed `cfi_encoding` attribute input + --> $DIR/sanitizer-cfi-invalid-attr-cfi-encoding.rs:10:1 + | +LL | #[cfi_encoding] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` + +error: aborting due to previous error + diff --git a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.aarch64.stderr b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.aarch64.stderr new file mode 100644 index 00000000000..8328178e8d0 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.aarch64.stderr @@ -0,0 +1,8 @@ +error: cfi sanitizer is not supported for this target + +error: `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi` + +error: `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.rs b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.rs new file mode 100644 index 00000000000..9a5b0f38990 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.rs @@ -0,0 +1,12 @@ +// Verifies that `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi`. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: x86 +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer=kcfi + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.x86_64.stderr b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.x86_64.stderr new file mode 100644 index 00000000000..8328178e8d0 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.x86_64.stderr @@ -0,0 +1,8 @@ +error: cfi sanitizer is not supported for this target + +error: `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi` + +error: `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-attr-cfg.rs b/tests/ui/sanitize/sanitizer-cfi-normalize-integers-attr-cfg.rs new file mode 100644 index 00000000000..dafc20162ab --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-normalize-integers-attr-cfg.rs @@ -0,0 +1,9 @@ +// Verifies that when compiling with `-Zsanitizer-cfi-normalize-integers` the +// `#[cfg(sanitizer_cfi_normalize_integers)]` attribute is configured. +// +// needs-sanitizer-cfi +// check-pass +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers + +#[cfg(sanitizer_cfi_normalize_integers)] +fn main() {} diff --git a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.rs b/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.rs new file mode 100644 index 00000000000..b25a60d3494 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.rs @@ -0,0 +1,9 @@ +// Verifies that `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or +// `-Zsanitizer=kcfi` +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer-cfi-normalize-integers + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.stderr b/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.stderr new file mode 100644 index 00000000000..e3164205434 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` + +error: aborting due to previous error + diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs b/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs new file mode 100644 index 00000000000..29e32889fcc --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs @@ -0,0 +1,8 @@ +// Verifies that `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`. +// +// needs-sanitizer-cfi +// compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr b/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr new file mode 100644 index 00000000000..5e706b513b9 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` + +error: aborting due to previous error + diff --git a/tests/ui/sanitize/split-lto-unit-requires-lto.rs b/tests/ui/sanitize/split-lto-unit-requires-lto.rs new file mode 100644 index 00000000000..3c497260e85 --- /dev/null +++ b/tests/ui/sanitize/split-lto-unit-requires-lto.rs @@ -0,0 +1,8 @@ +// Verifies that `-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`. +// +// needs-sanitizer-cfi +// compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsplit-lto-unit + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitize/split-lto-unit-requires-lto.stderr b/tests/ui/sanitize/split-lto-unit-requires-lto.stderr new file mode 100644 index 00000000000..ab8f4f4f351 --- /dev/null +++ b/tests/ui/sanitize/split-lto-unit-requires-lto.stderr @@ -0,0 +1,4 @@ +error: `-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` + +error: aborting due to previous error + diff --git a/tests/ui/self/elision/nested-item.rs b/tests/ui/self/elision/nested-item.rs new file mode 100644 index 00000000000..4bcb645c60e --- /dev/null +++ b/tests/ui/self/elision/nested-item.rs @@ -0,0 +1,13 @@ +// Regression test for #110899. +// When looking for the elided lifetime for `wrap`, +// we must not consider the lifetimes in `bar` as candidates. + +fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { + //~^ ERROR `self` parameter is only allowed in associated functions + //~| ERROR `self` parameter is only allowed in associated functions + //~| ERROR missing lifetime specifier + //~| ERROR cannot find type `Wrap` in this scope + &() +} + +fn main() {} diff --git a/tests/ui/self/elision/nested-item.stderr b/tests/ui/self/elision/nested-item.stderr new file mode 100644 index 00000000000..752fd82332c --- /dev/null +++ b/tests/ui/self/elision/nested-item.stderr @@ -0,0 +1,38 @@ +error: `self` parameter is only allowed in associated functions + --> $DIR/nested-item.rs:5:9 + | +LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/nested-item.rs:5:29 + | +LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { + | ^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error[E0106]: missing lifetime specifier + --> $DIR/nested-item.rs:5:46 + | +LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime + | +LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &'static () { + | +++++++ + +error[E0412]: cannot find type `Wrap` in this scope + --> $DIR/nested-item.rs:5:15 + | +LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { + | ^^^^ not found in this scope + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0106, E0412. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/self/self-ctor-inner-const.rs b/tests/ui/self/self-ctor-inner-const.rs new file mode 100644 index 00000000000..b015397a5bc --- /dev/null +++ b/tests/ui/self/self-ctor-inner-const.rs @@ -0,0 +1,17 @@ +// Verify that we ban usage of `Self` as constructor from inner items. + +struct S0<T>(T); + +impl<T> S0<T> { + fn foo() { + const C: S0<u8> = Self(0); + //~^ ERROR can't use generic parameters from outer function + fn bar() -> Self { + //~^ ERROR can't use generic parameters from outer function + Self(0) + //~^ ERROR can't use generic parameters from outer function + } + } +} + +fn main() {} diff --git a/tests/ui/self/self-ctor-inner-const.stderr b/tests/ui/self/self-ctor-inner-const.stderr new file mode 100644 index 00000000000..7287c64c659 --- /dev/null +++ b/tests/ui/self/self-ctor-inner-const.stderr @@ -0,0 +1,33 @@ +error[E0401]: can't use generic parameters from outer function + --> $DIR/self-ctor-inner-const.rs:7:27 + | +LL | const C: S0<u8> = Self(0); + | ^^^^ + | | + | use of generic parameter from outer function + | can't use `Self` here + +error[E0401]: can't use generic parameters from outer function + --> $DIR/self-ctor-inner-const.rs:9:21 + | +LL | impl<T> S0<T> { + | ---- `Self` type implicitly declared here, by this `impl` +... +LL | fn bar() -> Self { + | ^^^^ + | | + | use of generic parameter from outer function + | use a type here instead + +error[E0401]: can't use generic parameters from outer function + --> $DIR/self-ctor-inner-const.rs:11:13 + | +LL | Self(0) + | ^^^^ + | | + | use of generic parameter from outer function + | can't use `Self` here + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0401`. diff --git a/tests/ui/simd/issue-105439.rs b/tests/ui/simd/issue-105439.rs new file mode 100644 index 00000000000..35ca76e989b --- /dev/null +++ b/tests/ui/simd/issue-105439.rs @@ -0,0 +1,25 @@ +// run-pass +// compile-flags: -O -Zverify-llvm-ir + +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(simd)] +struct i32x4([i32; 4]); + +extern "platform-intrinsic" { + pub(crate) fn simd_add<T>(x: T, y: T) -> T; +} + +#[inline(always)] +fn to_array(a: i32x4) -> [i32; 4] { + a.0 +} + +fn main() { + let a = i32x4([1, 2, 3, 4]); + let b = unsafe { simd_add(a, a) }; + assert_eq!(to_array(b), [2, 4, 6, 8]); +} diff --git a/tests/ui/specialization/issue-111232.rs b/tests/ui/specialization/issue-111232.rs new file mode 100644 index 00000000000..3ed3c580e6d --- /dev/null +++ b/tests/ui/specialization/issue-111232.rs @@ -0,0 +1,11 @@ +#![feature(min_specialization)] + +struct S; + +impl From<S> for S { + fn from(s: S) -> S { //~ ERROR `from` specializes an item from a parent `impl`, but that item is not marked `default` + s + } +} + +fn main() {} diff --git a/tests/ui/specialization/issue-111232.stderr b/tests/ui/specialization/issue-111232.stderr new file mode 100644 index 00000000000..27ee42fc00c --- /dev/null +++ b/tests/ui/specialization/issue-111232.stderr @@ -0,0 +1,11 @@ +error[E0520]: `from` specializes an item from a parent `impl`, but that item is not marked `default` + --> $DIR/issue-111232.rs:6:5 + | +LL | fn from(s: S) -> S { + | ^^^^^^^^^^^^^^^^^^ + | + = note: parent implementation is in crate `core` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0520`. diff --git a/tests/ui/stability-attribute/stability-attribute-trait-impl.rs b/tests/ui/stability-attribute/stability-attribute-trait-impl.rs index 0c771ae8795..1d138e26408 100644 --- a/tests/ui/stability-attribute/stability-attribute-trait-impl.rs +++ b/tests/ui/stability-attribute/stability-attribute-trait-impl.rs @@ -1,4 +1,4 @@ -#![feature(staged_api, never_type, c_unwind)] +#![feature(staged_api, never_type, rust_cold_cc)] //~^ ERROR module has missing stability attribute #[stable(feature = "a", since = "1")] @@ -25,9 +25,9 @@ impl UnstableTrait for StableType {} #[unstable(feature = "h", issue = "none")] impl StableTrait for ! {} -// Note: If C-unwind is stabilized, switch this to another (unstable) ABI. +// Note: If rust_cold_cc is stabilized, switch this to another (unstable) ABI. #[unstable(feature = "i", issue = "none")] -impl StableTrait for extern "C-unwind" fn() {} +impl StableTrait for extern "rust-cold" fn() {} #[unstable(feature = "j", issue = "none")] //~^ ERROR an `#[unstable]` annotation here has no effect [ineffective_unstable_trait_impl] diff --git a/tests/ui/stability-attribute/stability-attribute-trait-impl.stderr b/tests/ui/stability-attribute/stability-attribute-trait-impl.stderr index b91a1d2e11a..96322c2c945 100644 --- a/tests/ui/stability-attribute/stability-attribute-trait-impl.stderr +++ b/tests/ui/stability-attribute/stability-attribute-trait-impl.stderr @@ -18,7 +18,7 @@ LL | #[unstable(feature = "k", issue = "none")] error: module has missing stability attribute --> $DIR/stability-attribute-trait-impl.rs:1:1 | -LL | / #![feature(staged_api, never_type, c_unwind)] +LL | / #![feature(staged_api, never_type, rust_cold_cc)] LL | | LL | | LL | | #[stable(feature = "a", since = "1")] diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr index 5c36a385a46..ea57992b483 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr @@ -6,8 +6,14 @@ LL | let _: &[i8] = data.into(); | = help: the following other types implement trait `From<T>`: <&'input [u8] as From<gimli::read::endian_slice::EndianSlice<'input, Endian>>> - <[T; LANES] as From<Simd<T, LANES>>> - <[bool; LANES] as From<Mask<T, LANES>>> + <[T; 10] as From<(T, T, T, T, T, T, T, T, T, T)>> + <[T; 11] as From<(T, T, T, T, T, T, T, T, T, T, T)>> + <[T; 12] as From<(T, T, T, T, T, T, T, T, T, T, T, T)>> + <[T; 1] as From<(T,)>> + <[T; 2] as From<(T, T)>> + <[T; 3] as From<(T, T, T)>> + <[T; 4] as From<(T, T, T, T)>> + and 7 others = note: required for `&[u8]` to implement `Into<&[i8]>` error: aborting due to previous error diff --git a/tests/ui/suggestions/many-type-ascription.rs b/tests/ui/suggestions/many-type-ascription.rs index 31ac556b944..cc2406d6690 100644 --- a/tests/ui/suggestions/many-type-ascription.rs +++ b/tests/ui/suggestions/many-type-ascription.rs @@ -1,4 +1,4 @@ fn main() { - let _ = 0: i32; //~ ERROR: type ascription is experimental + let _ = 0: i32; //~ ERROR: expected one of let _ = 0: i32; // (error only emitted once) } diff --git a/tests/ui/suggestions/many-type-ascription.stderr b/tests/ui/suggestions/many-type-ascription.stderr index 3706bbae9df..e36919c82f8 100644 --- a/tests/ui/suggestions/many-type-ascription.stderr +++ b/tests/ui/suggestions/many-type-ascription.stderr @@ -1,12 +1,10 @@ -error[E0658]: type ascription is experimental - --> $DIR/many-type-ascription.rs:2:13 +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `:` + --> $DIR/many-type-ascription.rs:2:14 | LL | let _ = 0: i32; - | ^^^^^^ + | ^ expected one of `.`, `;`, `?`, `else`, or an operator | - = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information - = help: add `#![feature(type_ascription)]` to the crate attributes to enable + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/suggestions/path-by-value.stderr b/tests/ui/suggestions/path-by-value.stderr index bbeaa26a93a..fd3646b8c3c 100644 --- a/tests/ui/suggestions/path-by-value.stderr +++ b/tests/ui/suggestions/path-by-value.stderr @@ -5,7 +5,8 @@ LL | fn f(p: Path) { } | ^ doesn't have a size known at compile-time | = help: within `Path`, the trait `Sized` is not implemented for `[u8]` - = note: required because it appears within the type `Path` +note: required because it appears within the type `Path` + --> $SRC_DIR/std/src/path.rs:LL:COL = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size | diff --git a/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr b/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr index 6ce9bfd9dca..365c1016eb3 100644 --- a/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr +++ b/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr @@ -5,7 +5,8 @@ LL | check(s); | ^ doesn't have a size known at compile-time | = help: within `OsStr`, the trait `Sized` is not implemented for `[u8]` - = note: required because it appears within the type `OsStr` +note: required because it appears within the type `OsStr` + --> $SRC_DIR/std/src/ffi/os_str.rs:LL:COL = note: required for the cast from `OsStr` to the object type `dyn AsRef<Path>` help: consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>` | diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.rs b/tests/ui/suggestions/type-ascription-instead-of-let.rs index 0e1c3075027..5ad60243298 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-let.rs +++ b/tests/ui/suggestions/type-ascription-instead-of-let.rs @@ -3,8 +3,7 @@ fn fun(x: i32) -> i32 { x } fn main() { let closure_annotated = |value: i32| -> i32 { temp: i32 = fun(5i32); - //~^ ERROR cannot find value `temp` in this scope + //~^ ERROR expected identifier, found `:` temp + value + 1 - //~^ ERROR cannot find value `temp` in this scope }; } diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.stderr b/tests/ui/suggestions/type-ascription-instead-of-let.stderr index 92e4b5798c8..fb697b0ccfd 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-let.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-let.stderr @@ -1,18 +1,8 @@ -error[E0425]: cannot find value `temp` in this scope - --> $DIR/type-ascription-instead-of-let.rs:5:9 +error: expected identifier, found `:` + --> $DIR/type-ascription-instead-of-let.rs:5:13 | LL | temp: i32 = fun(5i32); - | ^^^^ - | | - | not found in this scope - | help: maybe you meant to write an assignment here: `let temp` + | ^ expected identifier -error[E0425]: cannot find value `temp` in this scope - --> $DIR/type-ascription-instead-of-let.rs:7:9 - | -LL | temp + value + 1 - | ^^^^ not found in this scope - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/suggestions/type-ascription-instead-of-method.fixed b/tests/ui/suggestions/type-ascription-instead-of-method.fixed index 56b740b0d5c..02e316b264e 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-method.fixed +++ b/tests/ui/suggestions/type-ascription-instead-of-method.fixed @@ -1,5 +1,5 @@ // run-rustfix fn main() { let _ = Box::new("foo".to_string()); - //~^ ERROR expected type, found + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/suggestions/type-ascription-instead-of-method.rs b/tests/ui/suggestions/type-ascription-instead-of-method.rs index a603e09e7e8..6f893ee89b2 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-method.rs +++ b/tests/ui/suggestions/type-ascription-instead-of-method.rs @@ -1,5 +1,5 @@ // run-rustfix fn main() { let _ = Box:new("foo".to_string()); - //~^ ERROR expected type, found + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/suggestions/type-ascription-instead-of-method.stderr b/tests/ui/suggestions/type-ascription-instead-of-method.stderr index 83bc33f410a..b3799101cf0 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-method.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-method.stderr @@ -1,12 +1,10 @@ -error: expected type, found `"foo"` - --> $DIR/type-ascription-instead-of-method.rs:3:21 +error: path separator must be a double colon + --> $DIR/type-ascription-instead-of-method.rs:3:16 | LL | let _ = Box:new("foo".to_string()); - | - ^^^^^ expected type - | | - | help: maybe write a path separator here: `::` + | ^ help: use a double colon instead: `::` | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: aborting due to previous error diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-2.fixed b/tests/ui/suggestions/type-ascription-instead-of-path-2.fixed index 787fcc1208e..4cec58be856 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-2.fixed +++ b/tests/ui/suggestions/type-ascription-instead-of-path-2.fixed @@ -1,6 +1,6 @@ // run-rustfix fn main() -> Result<(), ()> { let _ = vec![Ok(2)].into_iter().collect::<Result<Vec<_>,_>>()?; - //~^ ERROR expected `::`, found `(` + //~^ ERROR expected one of Ok(()) } diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-2.rs b/tests/ui/suggestions/type-ascription-instead-of-path-2.rs index 934016b3b81..5695d5a7f72 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-2.rs +++ b/tests/ui/suggestions/type-ascription-instead-of-path-2.rs @@ -1,6 +1,6 @@ // run-rustfix fn main() -> Result<(), ()> { let _ = vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; - //~^ ERROR expected `::`, found `(` + //~^ ERROR expected one of Ok(()) } diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-2.stderr b/tests/ui/suggestions/type-ascription-instead-of-path-2.stderr index 970b220b737..43d00591e74 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-2.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-path-2.stderr @@ -1,12 +1,14 @@ -error: expected `::`, found `(` - --> $DIR/type-ascription-instead-of-path-2.rs:3:63 +error: expected one of `(`, `.`, `::`, `;`, `?`, `else`, or an operator, found `:` + --> $DIR/type-ascription-instead-of-path-2.rs:3:44 | LL | let _ = vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; - | - ^ expected `::` - | | - | help: maybe write a path separator here: `::` + | ^ expected one of 7 possible tokens | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> +help: maybe write a path separator here + | +LL | let _ = vec![Ok(2)].into_iter().collect::<Result<Vec<_>,_>>()?; + | ~~ error: aborting due to previous error diff --git a/tests/ui/suggestions/type-ascription-instead-of-path.rs b/tests/ui/suggestions/type-ascription-instead-of-path.rs index ce40b55f1ee..69647887afc 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path.rs +++ b/tests/ui/suggestions/type-ascription-instead-of-path.rs @@ -1,5 +1,4 @@ fn main() { std:io::stdin(); - //~^ ERROR failed to resolve: use of undeclared crate or module `io` - //~| ERROR expected value, found crate + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/suggestions/type-ascription-instead-of-path.stderr b/tests/ui/suggestions/type-ascription-instead-of-path.stderr index 518660cfa16..849630218da 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-path.stderr @@ -1,18 +1,10 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `io` - --> $DIR/type-ascription-instead-of-path.rs:2:9 +error: path separator must be a double colon + --> $DIR/type-ascription-instead-of-path.rs:2:8 | LL | std:io::stdin(); - | ^^ use of undeclared crate or module `io` - -error[E0423]: expected value, found crate `std` - --> $DIR/type-ascription-instead-of-path.rs:2:5 + | ^ help: use a double colon instead: `::` | -LL | std:io::stdin(); - | ^^^- help: maybe you meant to write a path separator here: `::` - | | - | not a value + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0423, E0433. -For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/suggestions/type-ascription-instead-of-variant.fixed b/tests/ui/suggestions/type-ascription-instead-of-variant.fixed index b3247e1287d..04cb2068624 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-variant.fixed +++ b/tests/ui/suggestions/type-ascription-instead-of-variant.fixed @@ -1,5 +1,5 @@ // run-rustfix fn main() { let _ = Option::Some(""); - //~^ ERROR expected type, found + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/suggestions/type-ascription-instead-of-variant.rs b/tests/ui/suggestions/type-ascription-instead-of-variant.rs index 6fd2c19541c..2cce69bfec8 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-variant.rs +++ b/tests/ui/suggestions/type-ascription-instead-of-variant.rs @@ -1,5 +1,5 @@ // run-rustfix fn main() { let _ = Option:Some(""); - //~^ ERROR expected type, found + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/suggestions/type-ascription-instead-of-variant.stderr b/tests/ui/suggestions/type-ascription-instead-of-variant.stderr index f59ba78d4d3..11d0f5f527e 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-variant.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-variant.stderr @@ -1,12 +1,10 @@ -error: expected type, found `""` - --> $DIR/type-ascription-instead-of-variant.rs:3:25 +error: path separator must be a double colon + --> $DIR/type-ascription-instead-of-variant.rs:3:19 | LL | let _ = Option:Some(""); - | - ^^ expected type - | | - | help: maybe write a path separator here: `::` + | ^ help: use a double colon instead: `::` | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: aborting due to previous error diff --git a/tests/ui/target-feature/gate.rs b/tests/ui/target-feature/gate.rs index 2eea087c705..8d1765eb8e9 100644 --- a/tests/ui/target-feature/gate.rs +++ b/tests/ui/target-feature/gate.rs @@ -10,6 +10,7 @@ // ignore-sparc // ignore-sparc64 // ignore-s390x +// ignore-loongarch64 // gate-test-sse4a_target_feature // gate-test-powerpc_target_feature // gate-test-avx512_target_feature diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr index 2d6abcc0a01..ee542b60a26 100644 --- a/tests/ui/target-feature/gate.stderr +++ b/tests/ui/target-feature/gate.stderr @@ -1,5 +1,5 @@ error[E0658]: the target feature `avx512bw` is currently unstable - --> $DIR/gate.rs:31:18 + --> $DIR/gate.rs:32:18 | LL | #[target_feature(enable = "avx512bw")] | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/invalid-attribute.rs b/tests/ui/target-feature/invalid-attribute.rs index b59ed076f93..77fd8b85f3f 100644 --- a/tests/ui/target-feature/invalid-attribute.rs +++ b/tests/ui/target-feature/invalid-attribute.rs @@ -10,6 +10,7 @@ // ignore-s390x // ignore-sparc // ignore-sparc64 +// ignore-loongarch64 #![warn(unused_attributes)] diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr index c36392d430f..6d37d0917bc 100644 --- a/tests/ui/target-feature/invalid-attribute.stderr +++ b/tests/ui/target-feature/invalid-attribute.stderr @@ -1,11 +1,11 @@ error: malformed `target_feature` attribute input - --> $DIR/invalid-attribute.rs:31:1 + --> $DIR/invalid-attribute.rs:32:1 | LL | #[target_feature = "+sse2"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]` error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:16:1 + --> $DIR/invalid-attribute.rs:17:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | extern crate alloc; | ------------------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:21:1 + --> $DIR/invalid-attribute.rs:22:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | use alloc::alloc::alloc; | ------------------------ not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:26:1 + --> $DIR/invalid-attribute.rs:27:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | extern "Rust" {} | ---------------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:48:1 + --> $DIR/invalid-attribute.rs:49:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | mod another {} | -------------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:53:1 + --> $DIR/invalid-attribute.rs:54:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | const FOO: usize = 7; | --------------------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:58:1 + --> $DIR/invalid-attribute.rs:59:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | struct Foo; | ----------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:63:1 + --> $DIR/invalid-attribute.rs:64:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | enum Bar {} | ----------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:68:1 + --> $DIR/invalid-attribute.rs:69:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | | } | |_- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:76:1 + --> $DIR/invalid-attribute.rs:77:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | type Uwu = (); | -------------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:81:1 + --> $DIR/invalid-attribute.rs:82:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | trait Baz {} | ------------ not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:91:1 + --> $DIR/invalid-attribute.rs:92:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | static A: () = (); | ------------------ not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:96:1 + --> $DIR/invalid-attribute.rs:97:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,7 +117,7 @@ LL | impl Quux for u8 {} | ------------------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:101:1 + --> $DIR/invalid-attribute.rs:102:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -126,7 +126,7 @@ LL | impl Foo {} | ----------- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:119:5 + --> $DIR/invalid-attribute.rs:120:5 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,7 +138,7 @@ LL | | } | |_____- not a function definition error: attribute should be applied to a function definition - --> $DIR/invalid-attribute.rs:127:5 + --> $DIR/invalid-attribute.rs:128:5 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -147,25 +147,25 @@ LL | || {}; | ----- not a function definition error: the feature named `foo` is not valid for this target - --> $DIR/invalid-attribute.rs:33:18 + --> $DIR/invalid-attribute.rs:34:18 | LL | #[target_feature(enable = "foo")] | ^^^^^^^^^^^^^^ `foo` is not valid for this target error: malformed `target_feature` attribute input - --> $DIR/invalid-attribute.rs:36:18 + --> $DIR/invalid-attribute.rs:37:18 | LL | #[target_feature(bar)] | ^^^ help: must be of the form: `enable = ".."` error: malformed `target_feature` attribute input - --> $DIR/invalid-attribute.rs:38:18 + --> $DIR/invalid-attribute.rs:39:18 | LL | #[target_feature(disable = "baz")] | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."` error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions - --> $DIR/invalid-attribute.rs:42:1 + --> $DIR/invalid-attribute.rs:43:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,13 +177,13 @@ LL | fn bar() {} = help: add `#![feature(target_feature_11)]` to the crate attributes to enable error: cannot use `#[inline(always)]` with `#[target_feature]` - --> $DIR/invalid-attribute.rs:86:1 + --> $DIR/invalid-attribute.rs:87:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions - --> $DIR/invalid-attribute.rs:111:5 + --> $DIR/invalid-attribute.rs:112:5 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/test-attrs/test-type.rs b/tests/ui/test-attrs/test-type.rs index f99e476eaba..8416270fd81 100644 --- a/tests/ui/test-attrs/test-type.rs +++ b/tests/ui/test-attrs/test-type.rs @@ -3,6 +3,7 @@ // check-run-results // normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" // ignore-emscripten no threads support +// needs-unwind // run-pass #[test] diff --git a/tests/ui/traits/issue-38404.rs b/tests/ui/traits/issue-38404.rs index 1a92acc3404..05921b2c36e 100644 --- a/tests/ui/traits/issue-38404.rs +++ b/tests/ui/traits/issue-38404.rs @@ -2,5 +2,6 @@ trait A<T>: std::ops::Add<Self> + Sized {} trait B<T>: A<T> {} trait C<T>: A<dyn B<T, Output=usize>> {} //~^ ERROR the trait `B` cannot be made into an object +//~| ERROR the trait `B` cannot be made into an object fn main() {} diff --git a/tests/ui/traits/issue-38404.stderr b/tests/ui/traits/issue-38404.stderr index d7721d7e69c..f8625f53b78 100644 --- a/tests/ui/traits/issue-38404.stderr +++ b/tests/ui/traits/issue-38404.stderr @@ -12,6 +12,20 @@ LL | trait A<T>: std::ops::Add<Self> + Sized {} LL | trait B<T>: A<T> {} | - this trait cannot be made into an object... -error: aborting due to previous error +error[E0038]: the trait `B` cannot be made into an object + --> $DIR/issue-38404.rs:3:15 + | +LL | trait C<T>: A<dyn B<T, Output=usize>> {} + | ^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-38404.rs:1:13 + | +LL | trait A<T>: std::ops::Add<Self> + Sized {} + | ^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter +LL | trait B<T>: A<T> {} + | - this trait cannot be made into an object... + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/issue-7013.stderr b/tests/ui/traits/issue-7013.stderr index 4575f4dbae6..9ac5c4725ab 100644 --- a/tests/ui/traits/issue-7013.stderr +++ b/tests/ui/traits/issue-7013.stderr @@ -5,7 +5,8 @@ LL | let a = A {v: Box::new(B{v: None}) as Box<dyn Foo + Send>}; | ^^^^^^^^^^^^^^^^^^^^ `Rc<RefCell<A>>` cannot be sent between threads safely | = help: within `B`, the trait `Send` is not implemented for `Rc<RefCell<A>>` - = note: required because it appears within the type `Option<Rc<RefCell<A>>>` +note: required because it appears within the type `Option<Rc<RefCell<A>>>` + --> $SRC_DIR/core/src/option.rs:LL:COL note: required because it appears within the type `B` --> $DIR/issue-7013.rs:8:8 | diff --git a/tests/ui/traits/negative-bounds/associated-constraints.rs b/tests/ui/traits/negative-bounds/associated-constraints.rs new file mode 100644 index 00000000000..bc1a0ef1708 --- /dev/null +++ b/tests/ui/traits/negative-bounds/associated-constraints.rs @@ -0,0 +1,20 @@ +#![feature(negative_bounds, associated_type_bounds)] +//~^ WARN the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes + +trait Trait { + type Assoc; +} + +fn test<T: !Trait<Assoc = i32>>() {} +//~^ ERROR associated type constraints not allowed on negative bounds + +fn test2<T>() where T: !Trait<Assoc = i32> {} +//~^ ERROR associated type constraints not allowed on negative bounds + +fn test3<T: !Trait<Assoc: Send>>() {} +//~^ ERROR associated type constraints not allowed on negative bounds + +fn test4<T>() where T: !Trait<Assoc: Send> {} +//~^ ERROR associated type constraints not allowed on negative bounds + +fn main() {} diff --git a/tests/ui/traits/negative-bounds/associated-constraints.stderr b/tests/ui/traits/negative-bounds/associated-constraints.stderr new file mode 100644 index 00000000000..335ac7e5ad9 --- /dev/null +++ b/tests/ui/traits/negative-bounds/associated-constraints.stderr @@ -0,0 +1,34 @@ +error: associated type constraints not allowed on negative bounds + --> $DIR/associated-constraints.rs:8:19 + | +LL | fn test<T: !Trait<Assoc = i32>>() {} + | ^^^^^^^^^^^ + +error: associated type constraints not allowed on negative bounds + --> $DIR/associated-constraints.rs:11:31 + | +LL | fn test2<T>() where T: !Trait<Assoc = i32> {} + | ^^^^^^^^^^^ + +error: associated type constraints not allowed on negative bounds + --> $DIR/associated-constraints.rs:14:20 + | +LL | fn test3<T: !Trait<Assoc: Send>>() {} + | ^^^^^^^^^^^ + +error: associated type constraints not allowed on negative bounds + --> $DIR/associated-constraints.rs:17:31 + | +LL | fn test4<T>() where T: !Trait<Assoc: Send> {} + | ^^^^^^^^^^^ + +warning: the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/associated-constraints.rs:1:12 + | +LL | #![feature(negative_bounds, associated_type_bounds)] + | ^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 4 previous errors; 1 warning emitted + diff --git a/tests/ui/traits/negative-bounds/simple.rs b/tests/ui/traits/negative-bounds/simple.rs new file mode 100644 index 00000000000..f6d1d5169c4 --- /dev/null +++ b/tests/ui/traits/negative-bounds/simple.rs @@ -0,0 +1,42 @@ +#![feature(negative_bounds, negative_impls)] +//~^ WARN the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes + +fn not_copy<T: !Copy>() {} + +fn neg_param_env<T: !Copy>() { + not_copy::<T>(); +} + +fn pos_param_env<T: Copy>() { + not_copy::<T>(); + //~^ ERROR the trait bound `T: !Copy` is not satisfied +} + +fn unknown<T>() { + not_copy::<T>(); + //~^ ERROR the trait bound `T: !Copy` is not satisfied +} + +struct NotCopyable; +impl !Copy for NotCopyable {} + +fn neg_impl() { + not_copy::<NotCopyable>(); +} + +#[derive(Copy, Clone)] +struct Copyable; + +fn pos_impl() { + not_copy::<Copyable>(); + //~^ ERROR the trait bound `Copyable: !Copy` is not satisfied +} + +struct NotNecessarilyCopyable; + +fn unknown_impl() { + not_copy::<NotNecessarilyCopyable>(); + //~^ ERROR the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/negative-bounds/simple.stderr b/tests/ui/traits/negative-bounds/simple.stderr new file mode 100644 index 00000000000..a3cab41a2ce --- /dev/null +++ b/tests/ui/traits/negative-bounds/simple.stderr @@ -0,0 +1,70 @@ +warning: the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/simple.rs:1:12 + | +LL | #![feature(negative_bounds, negative_impls)] + | ^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `T: !Copy` is not satisfied + --> $DIR/simple.rs:11:16 + | +LL | not_copy::<T>(); + | ^ the trait `!Copy` is not implemented for `T` + | +note: required by a bound in `not_copy` + --> $DIR/simple.rs:4:16 + | +LL | fn not_copy<T: !Copy>() {} + | ^^^^^ required by this bound in `not_copy` + +error[E0277]: the trait bound `T: !Copy` is not satisfied + --> $DIR/simple.rs:16:16 + | +LL | not_copy::<T>(); + | ^ the trait `!Copy` is not implemented for `T` + | +note: required by a bound in `not_copy` + --> $DIR/simple.rs:4:16 + | +LL | fn not_copy<T: !Copy>() {} + | ^^^^^ required by this bound in `not_copy` + +error[E0277]: the trait bound `Copyable: !Copy` is not satisfied + --> $DIR/simple.rs:31:16 + | +LL | not_copy::<Copyable>(); + | ^^^^^^^^ the trait `!Copy` is not implemented for `Copyable` + | + = help: the trait `Copy` is implemented for `Copyable` +note: required by a bound in `not_copy` + --> $DIR/simple.rs:4:16 + | +LL | fn not_copy<T: !Copy>() {} + | ^^^^^ required by this bound in `not_copy` +help: consider annotating `Copyable` with `#[derive(Copy)]` + | +LL + #[derive(Copy)] +LL | struct Copyable; + | + +error[E0277]: the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied + --> $DIR/simple.rs:38:16 + | +LL | not_copy::<NotNecessarilyCopyable>(); + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `!Copy` is not implemented for `NotNecessarilyCopyable` + | +note: required by a bound in `not_copy` + --> $DIR/simple.rs:4:16 + | +LL | fn not_copy<T: !Copy>() {} + | ^^^^^ required by this bound in `not_copy` +help: consider annotating `NotNecessarilyCopyable` with `#[derive(Copy)]` + | +LL + #[derive(Copy)] +LL | struct NotNecessarilyCopyable; + | + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr index b680ce7f990..a53879657f5 100644 --- a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -67,7 +67,8 @@ LL | is_send(Box::new(TestType)); | = note: the trait bound `Unique<dummy2::TestType>: Send` is not satisfied = note: required for `Unique<dummy2::TestType>` to implement `Send` - = note: required because it appears within the type `Box<TestType>` +note: required because it appears within the type `Box<TestType>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `is_send` --> $DIR/negated-auto-traits-error.rs:16:15 | @@ -93,7 +94,8 @@ note: required because it appears within the type `Outer2<TestType>` LL | struct Outer2<T>(T); | ^^^^^^ = note: required for `Unique<Outer2<dummy3::TestType>>` to implement `Send` - = note: required because it appears within the type `Box<Outer2<TestType>>` +note: required because it appears within the type `Box<Outer2<TestType>>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `is_send` --> $DIR/negated-auto-traits-error.rs:16:15 | diff --git a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.no.stderr b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.no.stderr new file mode 100644 index 00000000000..a985b1a6e12 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.no.stderr @@ -0,0 +1,24 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/drop-impl-pred.rs:6:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0367]: `Drop` impl requires `H: Foo` but the struct it is implemented for does not + --> $DIR/drop-impl-pred.rs:19:15 + | +LL | for<H> H: Foo, + | ^^^ + | +note: the implementor must specify the same requirement + --> $DIR/drop-impl-pred.rs:12:1 + | +LL | struct Bar<T>(T) where T: Foo; + | ^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0367`. diff --git a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.rs b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.rs new file mode 100644 index 00000000000..c65b5ea9ba4 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.rs @@ -0,0 +1,25 @@ +// revisions: no yes +//[yes] check-pass + +// Issue 110557 + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +pub trait Foo {} + +#[cfg(no)] +struct Bar<T>(T) where T: Foo; + +#[cfg(yes)] +struct Bar<T>(T) where for<H> H: Foo; + +impl<T> Drop for Bar<T> +where + for<H> H: Foo, +//[no]~^ ERROR `Drop` impl requires `H: Foo` but the struct it is implemented for does not +{ + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.yes.stderr b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.yes.stderr new file mode 100644 index 00000000000..165cf2ee13d --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.yes.stderr @@ -0,0 +1,11 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/drop-impl-pred.rs:6:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/type/ascription/issue-34255-1.rs b/tests/ui/type/ascription/issue-34255-1.rs index 44b47cc4eb2..7436f83593d 100644 --- a/tests/ui/type/ascription/issue-34255-1.rs +++ b/tests/ui/type/ascription/issue-34255-1.rs @@ -1,13 +1,12 @@ +// rustfix + struct Reactor { input_cells: Vec<usize>, } impl Reactor { - pub fn new() -> Self { + pub fn new() -> Self { //~ ERROR struct literal body without path input_cells: Vec::new() - //~^ ERROR cannot find value `input_cells` in this scope - //~| ERROR parenthesized type parameters may only be used with a `Fn` trait - //~| ERROR missing generics for struct `Vec` } } diff --git a/tests/ui/type/ascription/issue-34255-1.stderr b/tests/ui/type/ascription/issue-34255-1.stderr index fafff19f8f6..254d36cb947 100644 --- a/tests/ui/type/ascription/issue-34255-1.stderr +++ b/tests/ui/type/ascription/issue-34255-1.stderr @@ -1,36 +1,18 @@ -error[E0425]: cannot find value `input_cells` in this scope - --> $DIR/issue-34255-1.rs:7:9 +error: struct literal body without path + --> $DIR/issue-34255-1.rs:8:26 | -LL | input_cells: Vec::new() - | ^^^^^^^^^^^ a field by this name exists in `Self` +LL | pub fn new() -> Self { + | __________________________^ +LL | | input_cells: Vec::new() +LL | | } + | |_____^ | -help: you might have meant to write a `struct` literal +help: you might have forgotten to add the struct literal inside the block | LL ~ pub fn new() -> Self { SomeStruct { LL | input_cells: Vec::new() - ... -LL | -LL ~ }} - | - -error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/issue-34255-1.rs:7:27 - | -LL | input_cells: Vec::new() - | ^^^^^ only `Fn` traits may use parentheses - -error[E0107]: missing generics for struct `Vec` - --> $DIR/issue-34255-1.rs:7:22 - | -LL | input_cells: Vec::new() - | ^^^ expected at least 1 generic argument - | -help: add missing generic argument +LL ~ } } | -LL | input_cells: Vec<T>::new() - | +++ -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0107, E0214, E0425. -For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/type/ascription/issue-47666.fixed b/tests/ui/type/ascription/issue-47666.fixed index c4db747551e..027c692f900 100644 --- a/tests/ui/type/ascription/issue-47666.fixed +++ b/tests/ui/type/ascription/issue-47666.fixed @@ -1,4 +1,4 @@ // run-rustfix fn main() { - let _ = Option::Some(vec![0, 1]); //~ ERROR expected type, found + let _ = Option::Some(vec![0, 1]); //~ ERROR path separator must be a double colon } diff --git a/tests/ui/type/ascription/issue-47666.rs b/tests/ui/type/ascription/issue-47666.rs index c67202e2157..e2f5d03ef74 100644 --- a/tests/ui/type/ascription/issue-47666.rs +++ b/tests/ui/type/ascription/issue-47666.rs @@ -1,4 +1,4 @@ // run-rustfix fn main() { - let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found + let _ = Option:Some(vec![0, 1]); //~ ERROR path separator must be a double colon } diff --git a/tests/ui/type/ascription/issue-47666.stderr b/tests/ui/type/ascription/issue-47666.stderr index 0f90fce3a42..74d85a75c85 100644 --- a/tests/ui/type/ascription/issue-47666.stderr +++ b/tests/ui/type/ascription/issue-47666.stderr @@ -1,16 +1,10 @@ -error: expected type, found `<[_]>::into_vec(#[rustc_box] ::alloc::boxed::Box::new([0, 1]))` - --> $DIR/issue-47666.rs:3:25 +error: path separator must be a double colon + --> $DIR/issue-47666.rs:3:19 | LL | let _ = Option:Some(vec![0, 1]); - | - ^^^^^^^^^^ - | | | - | | expected type - | | in this macro invocation - | | this macro call doesn't expand to a type - | help: maybe write a path separator here: `::` + | ^ help: use a double colon instead: `::` | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` - = note: this error originates in the macro `$crate::__rust_force_expr` which comes from the expansion of the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: aborting due to previous error diff --git a/tests/ui/type/ascription/issue-54516.fixed b/tests/ui/type/ascription/issue-54516.fixed index f78268894da..48622663b4d 100644 --- a/tests/ui/type/ascription/issue-54516.fixed +++ b/tests/ui/type/ascription/issue-54516.fixed @@ -3,5 +3,5 @@ use std::collections::BTreeMap; fn main() { println!("{}", std::mem::size_of::<BTreeMap<u32, u32>>()); - //~^ ERROR type ascription cannot be followed by a function call + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/type/ascription/issue-54516.rs b/tests/ui/type/ascription/issue-54516.rs index 1f34e6943ba..9e71d2af1d3 100644 --- a/tests/ui/type/ascription/issue-54516.rs +++ b/tests/ui/type/ascription/issue-54516.rs @@ -3,5 +3,5 @@ use std::collections::BTreeMap; fn main() { println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); - //~^ ERROR type ascription cannot be followed by a function call + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/type/ascription/issue-54516.stderr b/tests/ui/type/ascription/issue-54516.stderr index 1ab9093e584..a1371432f5a 100644 --- a/tests/ui/type/ascription/issue-54516.stderr +++ b/tests/ui/type/ascription/issue-54516.stderr @@ -1,12 +1,10 @@ -error: type ascription cannot be followed by a function call - --> $DIR/issue-54516.rs:5:20 +error: path separator must be a double colon + --> $DIR/issue-54516.rs:5:28 | LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); - | ^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | help: maybe write a path separator here: `::` + | ^ help: use a double colon instead: `::` | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: aborting due to previous error diff --git a/tests/ui/type/ascription/issue-60933.fixed b/tests/ui/type/ascription/issue-60933.fixed index 3e8be3875b3..016ad4a7e6a 100644 --- a/tests/ui/type/ascription/issue-60933.fixed +++ b/tests/ui/type/ascription/issue-60933.fixed @@ -1,5 +1,5 @@ // run-rustfix fn main() { let _: usize = std::mem::size_of::<u32>(); - //~^ ERROR type ascription cannot be followed by a function call + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/type/ascription/issue-60933.rs b/tests/ui/type/ascription/issue-60933.rs index 2a4ad7bdc4e..972bf2827f9 100644 --- a/tests/ui/type/ascription/issue-60933.rs +++ b/tests/ui/type/ascription/issue-60933.rs @@ -1,5 +1,5 @@ // run-rustfix fn main() { let _: usize = std::mem:size_of::<u32>(); - //~^ ERROR type ascription cannot be followed by a function call + //~^ ERROR path separator must be a double colon } diff --git a/tests/ui/type/ascription/issue-60933.stderr b/tests/ui/type/ascription/issue-60933.stderr index 0b7f8edf624..0ec527ff5a9 100644 --- a/tests/ui/type/ascription/issue-60933.stderr +++ b/tests/ui/type/ascription/issue-60933.stderr @@ -1,12 +1,10 @@ -error: type ascription cannot be followed by a function call - --> $DIR/issue-60933.rs:3:20 +error: path separator must be a double colon + --> $DIR/issue-60933.rs:3:28 | LL | let _: usize = std::mem:size_of::<u32>(); - | ^^^^^^^^-^^^^^^^^^^^^^^ - | | - | help: maybe write a path separator here: `::` + | ^ help: use a double colon instead: `::` | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: aborting due to previous error diff --git a/tests/ui/type/missing-let-in-binding.fixed b/tests/ui/type/missing-let-in-binding.fixed index d1787688950..4301fed2312 100644 --- a/tests/ui/type/missing-let-in-binding.fixed +++ b/tests/ui/type/missing-let-in-binding.fixed @@ -1,5 +1,5 @@ // run-rustfix fn main() { let mut _foo: i32 = 1; - let _foo: i32 = 4; //~ ERROR type ascription is experimental + let _foo: i32 = 4; //~ ERROR expected identifier, found `:` } diff --git a/tests/ui/type/missing-let-in-binding.rs b/tests/ui/type/missing-let-in-binding.rs index ca42f2e6eac..c0f91d98ff3 100644 --- a/tests/ui/type/missing-let-in-binding.rs +++ b/tests/ui/type/missing-let-in-binding.rs @@ -1,5 +1,5 @@ // run-rustfix fn main() { let mut _foo: i32 = 1; - _foo: i32 = 4; //~ ERROR type ascription is experimental + _foo: i32 = 4; //~ ERROR expected identifier, found `:` } diff --git a/tests/ui/type/missing-let-in-binding.stderr b/tests/ui/type/missing-let-in-binding.stderr index 12759c5096e..fc094e8cbad 100644 --- a/tests/ui/type/missing-let-in-binding.stderr +++ b/tests/ui/type/missing-let-in-binding.stderr @@ -1,11 +1,10 @@ -error[E0658]: type ascription is experimental - --> $DIR/missing-let-in-binding.rs:4:5 +error: expected identifier, found `:` + --> $DIR/missing-let-in-binding.rs:4:9 | LL | _foo: i32 = 4; - | ^^^^^^^^^ + | ^ expected identifier | - = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information - = help: add `#![feature(type_ascription)]` to the crate attributes to enable + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> help: you might have meant to introduce a new binding | LL | let _foo: i32 = 4; @@ -13,4 +12,3 @@ LL | let _foo: i32 = 4; error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/type/type-ascription-instead-of-statement-end.rs b/tests/ui/type/type-ascription-instead-of-statement-end.rs index 1d5565ab583..e30e571386b 100644 --- a/tests/ui/type/type-ascription-instead-of-statement-end.rs +++ b/tests/ui/type/type-ascription-instead-of-statement-end.rs @@ -1,10 +1,8 @@ -#![feature(type_ascription)] - fn main() { - println!("test"): - 0; //~ ERROR expected type, found `0` + println!("test"): //~ ERROR statements are terminated with a semicolon + 0; } fn foo() { - println!("test"): 0; //~ ERROR expected type, found `0` + println!("test"): 0; //~ ERROR expected one of } diff --git a/tests/ui/type/type-ascription-instead-of-statement-end.stderr b/tests/ui/type/type-ascription-instead-of-statement-end.stderr index 521ebcdf192..8c09e78bc5f 100644 --- a/tests/ui/type/type-ascription-instead-of-statement-end.stderr +++ b/tests/ui/type/type-ascription-instead-of-statement-end.stderr @@ -1,24 +1,16 @@ -error: expected type, found `0` - --> $DIR/type-ascription-instead-of-statement-end.rs:5:5 +error: statements are terminated with a semicolon + --> $DIR/type-ascription-instead-of-statement-end.rs:2:21 | LL | println!("test"): - | - help: try using a semicolon: `;` -LL | 0; - | ^ expected type + | ^ help: use a semicolon instead: `;` | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` - = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> -error: expected type, found `0` - --> $DIR/type-ascription-instead-of-statement-end.rs:9:23 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/type-ascription-instead-of-statement-end.rs:7:21 | LL | println!("test"): 0; - | - ^ expected type - | | - | tried to parse a type due to this type ascription - | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` - = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: aborting due to 2 previous errors diff --git a/tests/ui/type/type-ascription-precedence.rs b/tests/ui/type/type-ascription-precedence.rs index d3aef929b9f..1527bb7aa17 100644 --- a/tests/ui/type/type-ascription-precedence.rs +++ b/tests/ui/type/type-ascription-precedence.rs @@ -1,10 +1,8 @@ // Operator precedence of type ascription // Type ascription has very high precedence, the same as operator `as` - #![feature(type_ascription)] use std::ops::*; - struct S; struct Z; @@ -25,30 +23,34 @@ impl Deref for S { fn deref(&self) -> &Z { panic!() } } -fn main() { - &S: &S; // OK - (&S): &S; // OK - &(S: &S); //~ ERROR mismatched types +fn test1() { + &S: &S; //~ ERROR expected one of + (&S): &S; + &(S: &S); +} + +fn test2() { + *(S: Z); //~ ERROR expected identifier +} - *S: Z; // OK - (*S): Z; // OK - *(S: Z); //~ ERROR mismatched types - //~^ ERROR type `Z` cannot be dereferenced +fn test3() { + -(S: Z); //~ ERROR expected identifier +} - -S: Z; // OK - (-S): Z; // OK - -(S: Z); //~ ERROR mismatched types - //~^ ERROR cannot apply unary operator `-` to type `Z` +fn test4() { + (S + Z): Z; //~ ERROR expected one of +} - S + Z: Z; // OK - S + (Z: Z); // OK - (S + Z): Z; //~ ERROR mismatched types +fn test5() { + (S * Z): Z; //~ ERROR expected one of +} - S * Z: Z; // OK - S * (Z: Z); // OK - (S * Z): Z; //~ ERROR mismatched types +fn test6() { + S .. S: S; //~ ERROR expected identifier, found `:` +} - S .. S: S; // OK - S .. (S: S); // OK - (S .. S): S; //~ ERROR mismatched types +fn test7() { + (S .. S): S; //~ ERROR expected one of } + +fn main() {} diff --git a/tests/ui/type/type-ascription-precedence.stderr b/tests/ui/type/type-ascription-precedence.stderr index d6d1e1d7d02..09cdc370309 100644 --- a/tests/ui/type/type-ascription-precedence.stderr +++ b/tests/ui/type/type-ascription-precedence.stderr @@ -1,63 +1,46 @@ -error[E0308]: mismatched types - --> $DIR/type-ascription-precedence.rs:31:7 +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `:` + --> $DIR/type-ascription-precedence.rs:27:7 | -LL | &(S: &S); - | ^ expected `&S`, found `S` +LL | &S: &S; + | ^ expected one of 8 possible tokens -error[E0308]: mismatched types - --> $DIR/type-ascription-precedence.rs:35:7 +error: expected identifier, found `:` + --> $DIR/type-ascription-precedence.rs:33:8 | LL | *(S: Z); - | ^ expected `Z`, found `S` + | ^ expected identifier -error[E0614]: type `Z` cannot be dereferenced - --> $DIR/type-ascription-precedence.rs:35:5 - | -LL | *(S: Z); - | ^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/type-ascription-precedence.rs:40:7 - | -LL | -(S: Z); - | ^ expected `Z`, found `S` - -error[E0600]: cannot apply unary operator `-` to type `Z` - --> $DIR/type-ascription-precedence.rs:40:5 +error: expected identifier, found `:` + --> $DIR/type-ascription-precedence.rs:37:8 | LL | -(S: Z); - | ^^^^^^^ cannot apply unary operator `-` - | -note: an implementation of `std::ops::Neg` might be missing for `Z` - --> $DIR/type-ascription-precedence.rs:9:1 - | -LL | struct Z; - | ^^^^^^^^ must implement `std::ops::Neg` -note: the trait `std::ops::Neg` must be implemented - --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | ^ expected identifier -error[E0308]: mismatched types - --> $DIR/type-ascription-precedence.rs:45:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/type-ascription-precedence.rs:41:12 | LL | (S + Z): Z; - | ^^^^^^^ expected `Z`, found `S` + | ^ expected one of `.`, `;`, `?`, `}`, or an operator -error[E0308]: mismatched types - --> $DIR/type-ascription-precedence.rs:49:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/type-ascription-precedence.rs:45:12 | LL | (S * Z): Z; - | ^^^^^^^ expected `Z`, found `S` + | ^ expected one of `.`, `;`, `?`, `}`, or an operator -error[E0308]: mismatched types - --> $DIR/type-ascription-precedence.rs:53:5 +error: expected identifier, found `:` + --> $DIR/type-ascription-precedence.rs:49:11 | -LL | (S .. S): S; - | ^^^^^^^^ expected `S`, found `Range<S>` +LL | S .. S: S; + | ^ expected identifier | - = note: expected struct `S` - found struct `std::ops::Range<S>` + = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` + --> $DIR/type-ascription-precedence.rs:53:13 + | +LL | (S .. S): S; + | ^ expected one of `.`, `;`, `?`, `}`, or an operator -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0308, E0600, E0614. -For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/type/type-ascription-with-fn-call.fixed b/tests/ui/type/type-ascription-with-fn-call.fixed index 6d96c4303c3..847f3309973 100644 --- a/tests/ui/type/type-ascription-with-fn-call.fixed +++ b/tests/ui/type/type-ascription-with-fn-call.fixed @@ -1,9 +1,7 @@ // run-rustfix -#![feature(type_ascription)] - fn main() { - f() ; - f(); //~ ERROR expected type, found function + f() ; //~ ERROR statements are terminated with a semicolon + f(); } fn f() {} diff --git a/tests/ui/type/type-ascription-with-fn-call.rs b/tests/ui/type/type-ascription-with-fn-call.rs index ed4f7c9041c..1db48b0adc4 100644 --- a/tests/ui/type/type-ascription-with-fn-call.rs +++ b/tests/ui/type/type-ascription-with-fn-call.rs @@ -1,9 +1,7 @@ // run-rustfix -#![feature(type_ascription)] - fn main() { - f() : - f(); //~ ERROR expected type, found function + f() : //~ ERROR statements are terminated with a semicolon + f(); } fn f() {} diff --git a/tests/ui/type/type-ascription-with-fn-call.stderr b/tests/ui/type/type-ascription-with-fn-call.stderr index d78fd08fd60..e3afa497ac2 100644 --- a/tests/ui/type/type-ascription-with-fn-call.stderr +++ b/tests/ui/type/type-ascription-with-fn-call.stderr @@ -1,11 +1,10 @@ -error[E0573]: expected type, found function `f` - --> $DIR/type-ascription-with-fn-call.rs:6:5 +error: statements are terminated with a semicolon + --> $DIR/type-ascription-with-fn-call.rs:3:10 | LL | f() : - | - help: maybe you meant to write `;` here -LL | f(); - | ^^^ expecting a type here because of type ascription + | ^ help: use a semicolon instead: `;` + | + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> error: aborting due to previous error -For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/typeck/bad-index-due-to-nested.stderr b/tests/ui/typeck/bad-index-due-to-nested.stderr index e03b06b336e..cdb23372c4b 100644 --- a/tests/ui/typeck/bad-index-due-to-nested.stderr +++ b/tests/ui/typeck/bad-index-due-to-nested.stderr @@ -4,11 +4,14 @@ error[E0277]: the trait bound `K: Hash` is not satisfied LL | map[k] | ^^^ the trait `Hash` is not implemented for `K` | -note: required by a bound in `<HashMap<K, V> as Index<&K>>` - --> $DIR/bad-index-due-to-nested.rs:9:8 +note: required for `HashMap<K, V>` to implement `Index<&K>` + --> $DIR/bad-index-due-to-nested.rs:7:12 | +LL | impl<K, V> Index<&K> for HashMap<K, V> + | ^^^^^^^^^ ^^^^^^^^^^^^^ +LL | where LL | K: Hash, - | ^^^^ required by this bound in `<HashMap<K, V> as Index<&K>>` + | ---- unsatisfied trait bound introduced here help: consider restricting type parameter `K` | LL | fn index<'a, K: std::hash::Hash, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { @@ -20,11 +23,14 @@ error[E0277]: the trait bound `V: Copy` is not satisfied LL | map[k] | ^^^ the trait `Copy` is not implemented for `V` | -note: required by a bound in `<HashMap<K, V> as Index<&K>>` - --> $DIR/bad-index-due-to-nested.rs:10:8 +note: required for `HashMap<K, V>` to implement `Index<&K>` + --> $DIR/bad-index-due-to-nested.rs:7:12 | +LL | impl<K, V> Index<&K> for HashMap<K, V> + | ^^^^^^^^^ ^^^^^^^^^^^^^ +... LL | V: Copy, - | ^^^^ required by this bound in `<HashMap<K, V> as Index<&K>>` + | ---- unsatisfied trait bound introduced here help: consider restricting type parameter `V` | LL | fn index<'a, K, V: std::marker::Copy>(map: &'a HashMap<K, V>, k: K) -> &'a V { diff --git a/tests/ui/typeck/repeat-expr-checks-wf.rs b/tests/ui/typeck/repeat-expr-checks-wf.rs new file mode 100644 index 00000000000..b8a2a0ceb58 --- /dev/null +++ b/tests/ui/typeck/repeat-expr-checks-wf.rs @@ -0,0 +1,10 @@ +trait Foo { + const ASSOC: [u8]; +} + +fn bar<T: Foo>() { + let a = [T::ASSOC; 2]; + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time +} + +fn main() {} diff --git a/tests/ui/typeck/repeat-expr-checks-wf.stderr b/tests/ui/typeck/repeat-expr-checks-wf.stderr new file mode 100644 index 00000000000..a821088a4b3 --- /dev/null +++ b/tests/ui/typeck/repeat-expr-checks-wf.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/repeat-expr-checks-wf.rs:6:13 + | +LL | let a = [T::ASSOC; 2]; + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: slice and array elements must have `Sized` type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs index 7ff9199f63c..e7e62c07739 100644 --- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs +++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs @@ -3,6 +3,7 @@ fn foo1<T:Copy<U>, U>(x: T) {} trait Trait: Copy<dyn Send> {} //~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied +//~| ERROR trait takes 0 generic arguments but 1 generic argument was supplied struct MyStruct1<T: Copy<T>>; //~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr index a71fd953658..a3517af877c 100644 --- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr +++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr @@ -15,7 +15,15 @@ LL | trait Trait: Copy<dyn Send> {} | expected 0 generic arguments error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/typeck-builtin-bound-type-parameters.rs:7:21 + --> $DIR/typeck-builtin-bound-type-parameters.rs:4:14 + | +LL | trait Trait: Copy<dyn Send> {} + | ^^^^---------- help: remove these generics + | | + | expected 0 generic arguments + +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/typeck-builtin-bound-type-parameters.rs:8:21 | LL | struct MyStruct1<T: Copy<T>>; | ^^^^--- help: remove these generics @@ -23,7 +31,7 @@ LL | struct MyStruct1<T: Copy<T>>; | expected 0 generic arguments error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/typeck-builtin-bound-type-parameters.rs:10:25 + --> $DIR/typeck-builtin-bound-type-parameters.rs:11:25 | LL | struct MyStruct2<'a, T: Copy<'a>>; | ^^^^---- help: remove these generics @@ -31,7 +39,7 @@ LL | struct MyStruct2<'a, T: Copy<'a>>; | expected 0 lifetime arguments error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15 + --> $DIR/typeck-builtin-bound-type-parameters.rs:14:15 | LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} | ^^^^ -- help: remove this lifetime argument @@ -39,13 +47,13 @@ LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} | expected 0 lifetime arguments error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15 + --> $DIR/typeck-builtin-bound-type-parameters.rs:14:15 | LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} | ^^^^ - help: remove this generic argument | | | expected 0 generic arguments -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/union/union-sized-field.stderr b/tests/ui/union/union-sized-field.stderr index 771e8f26199..bf1ff9c8bc1 100644 --- a/tests/ui/union/union-sized-field.stderr +++ b/tests/ui/union/union-sized-field.stderr @@ -6,7 +6,8 @@ LL | union Foo<T: ?Sized> { LL | value: ManuallyDrop<T>, | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = note: required because it appears within the type `ManuallyDrop<T>` +note: required because it appears within the type `ManuallyDrop<T>` + --> $SRC_DIR/core/src/mem/manually_drop.rs:LL:COL = note: no field of a union may have a dynamically sized type = help: change the field's type to have a statically known size help: consider removing the `?Sized` bound to make the type parameter `Sized` @@ -31,7 +32,8 @@ LL | struct Foo2<T: ?Sized> { LL | value: ManuallyDrop<T>, | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = note: required because it appears within the type `ManuallyDrop<T>` +note: required because it appears within the type `ManuallyDrop<T>` + --> $SRC_DIR/core/src/mem/manually_drop.rs:LL:COL = note: only the last field of a struct may have a dynamically sized type = help: change the field's type to have a statically known size help: consider removing the `?Sized` bound to make the type parameter `Sized` @@ -56,7 +58,8 @@ LL | enum Foo3<T: ?Sized> { LL | Value(ManuallyDrop<T>), | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = note: required because it appears within the type `ManuallyDrop<T>` +note: required because it appears within the type `ManuallyDrop<T>` + --> $SRC_DIR/core/src/mem/manually_drop.rs:LL:COL = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size help: consider removing the `?Sized` bound to make the type parameter `Sized` diff --git a/tests/ui/unwind-abis/feature-gate-c-unwind-enabled.rs b/tests/ui/unwind-abis/feature-gate-c-unwind-enabled.rs deleted file mode 100644 index 6ff5dbda2d5..00000000000 --- a/tests/ui/unwind-abis/feature-gate-c-unwind-enabled.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Test that the "C-unwind" ABI is feature-gated, and *can* be used when the -// `c_unwind` feature gate is enabled. - -// check-pass - -#![feature(c_unwind)] - -extern "C-unwind" fn f() {} - -fn main() { - f(); -} diff --git a/tests/ui/unwind-abis/feature-gate-c-unwind.rs b/tests/ui/unwind-abis/feature-gate-c-unwind.rs deleted file mode 100644 index ba72f74f20c..00000000000 --- a/tests/ui/unwind-abis/feature-gate-c-unwind.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Test that the "C-unwind" ABI is feature-gated, and cannot be used when the -// `c_unwind` feature gate is not used. - -#![allow(ffi_unwind_calls)] -//~^ WARNING unknown lint: `ffi_unwind_calls` -//~| WARNING unknown lint: `ffi_unwind_calls` - -extern "C-unwind" fn f() {} -//~^ ERROR C-unwind ABI is experimental and subject to change [E0658] - -fn main() { - f(); -} diff --git a/tests/ui/unwind-abis/feature-gate-c-unwind.stderr b/tests/ui/unwind-abis/feature-gate-c-unwind.stderr deleted file mode 100644 index 214ddc45ce9..00000000000 --- a/tests/ui/unwind-abis/feature-gate-c-unwind.stderr +++ /dev/null @@ -1,33 +0,0 @@ -warning: unknown lint: `ffi_unwind_calls` - --> $DIR/feature-gate-c-unwind.rs:4:1 - | -LL | #![allow(ffi_unwind_calls)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `ffi_unwind_calls` lint is unstable - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - = note: `#[warn(unknown_lints)]` on by default - -error[E0658]: C-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-c-unwind.rs:8:8 - | -LL | extern "C-unwind" fn f() {} - | ^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -warning: unknown lint: `ffi_unwind_calls` - --> $DIR/feature-gate-c-unwind.rs:4:1 - | -LL | #![allow(ffi_unwind_calls)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `ffi_unwind_calls` lint is unstable - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error: aborting due to previous error; 2 warnings emitted - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/unwind-abis/feature-gate-c_unwind.rs b/tests/ui/unwind-abis/feature-gate-c_unwind.rs new file mode 100644 index 00000000000..d73fe3e0bda --- /dev/null +++ b/tests/ui/unwind-abis/feature-gate-c_unwind.rs @@ -0,0 +1,4 @@ +// ignore-test + +// After partial stabilisation, `c_unwind` only contains codegen behaviour changes +// and are tested in `src/test/codegen/unwind-abis` diff --git a/tests/ui/unwind-abis/feature-gate-stdcall-unwind.rs b/tests/ui/unwind-abis/feature-gate-stdcall-unwind.rs deleted file mode 100644 index cfa8eb3cad0..00000000000 --- a/tests/ui/unwind-abis/feature-gate-stdcall-unwind.rs +++ /dev/null @@ -1,30 +0,0 @@ -// gate-test-c_unwind -// needs-llvm-components: x86 -// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -#![no_core] -#![feature(no_core, lang_items)] -#[lang="sized"] -trait Sized { } - -// Test that the "stdcall-unwind" ABI is feature-gated, and cannot be used when -// the `c_unwind` feature gate is not used. - -extern "stdcall-unwind" fn fu() {} //~ ERROR stdcall-unwind ABI is experimental - -trait T { - extern "stdcall-unwind" fn mu(); //~ ERROR stdcall-unwind ABI is experimental - extern "stdcall-unwind" fn dmu() {} //~ ERROR stdcall-unwind ABI is experimental -} - -struct S; -impl T for S { - extern "stdcall-unwind" fn mu() {} //~ ERROR stdcall-unwind ABI is experimental -} - -impl S { - extern "stdcall-unwind" fn imu() {} //~ ERROR stdcall-unwind ABI is experimental -} - -type TAU = extern "stdcall-unwind" fn(); //~ ERROR stdcall-unwind ABI is experimental - -extern "stdcall-unwind" {} //~ ERROR stdcall-unwind ABI is experimental diff --git a/tests/ui/unwind-abis/feature-gate-stdcall-unwind.stderr b/tests/ui/unwind-abis/feature-gate-stdcall-unwind.stderr deleted file mode 100644 index c2cce0e1193..00000000000 --- a/tests/ui/unwind-abis/feature-gate-stdcall-unwind.stderr +++ /dev/null @@ -1,66 +0,0 @@ -error[E0658]: stdcall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-stdcall-unwind.rs:12:8 - | -LL | extern "stdcall-unwind" fn fu() {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error[E0658]: stdcall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-stdcall-unwind.rs:15:12 - | -LL | extern "stdcall-unwind" fn mu(); - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error[E0658]: stdcall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-stdcall-unwind.rs:16:12 - | -LL | extern "stdcall-unwind" fn dmu() {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error[E0658]: stdcall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-stdcall-unwind.rs:21:12 - | -LL | extern "stdcall-unwind" fn mu() {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error[E0658]: stdcall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-stdcall-unwind.rs:25:12 - | -LL | extern "stdcall-unwind" fn imu() {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error[E0658]: stdcall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-stdcall-unwind.rs:28:19 - | -LL | type TAU = extern "stdcall-unwind" fn(); - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error[E0658]: stdcall-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-stdcall-unwind.rs:30:8 - | -LL | extern "stdcall-unwind" {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error: aborting due to 7 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/unwind-abis/feature-gate-system-unwind.rs b/tests/ui/unwind-abis/feature-gate-system-unwind.rs deleted file mode 100644 index 26c2de4e817..00000000000 --- a/tests/ui/unwind-abis/feature-gate-system-unwind.rs +++ /dev/null @@ -1,9 +0,0 @@ -// Test that the "system-unwind" ABI is feature-gated, and cannot be used when -// the `c_unwind` feature gate is not used. - -extern "system-unwind" fn f() {} -//~^ ERROR system-unwind ABI is experimental and subject to change [E0658] - -fn main() { - f(); -} diff --git a/tests/ui/unwind-abis/feature-gate-system-unwind.stderr b/tests/ui/unwind-abis/feature-gate-system-unwind.stderr deleted file mode 100644 index 87877336475..00000000000 --- a/tests/ui/unwind-abis/feature-gate-system-unwind.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: system-unwind ABI is experimental and subject to change - --> $DIR/feature-gate-system-unwind.rs:4:8 - | -LL | extern "system-unwind" fn f() {} - | ^^^^^^^^^^^^^^^ - | - = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information - = help: add `#![feature(c_unwind)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/unwind-abis/ffi-unwind-calls-lint.rs b/tests/ui/unwind-abis/ffi-unwind-calls-lint.rs index 9a324f00435..8f000737656 100644 --- a/tests/ui/unwind-abis/ffi-unwind-calls-lint.rs +++ b/tests/ui/unwind-abis/ffi-unwind-calls-lint.rs @@ -1,7 +1,6 @@ // build-pass // needs-unwind -#![feature(c_unwind)] #![warn(ffi_unwind_calls)] mod foo { diff --git a/tests/ui/unwind-abis/ffi-unwind-calls-lint.stderr b/tests/ui/unwind-abis/ffi-unwind-calls-lint.stderr index 937a2b3dff8..cf8a7782e35 100644 --- a/tests/ui/unwind-abis/ffi-unwind-calls-lint.stderr +++ b/tests/ui/unwind-abis/ffi-unwind-calls-lint.stderr @@ -1,17 +1,17 @@ warning: call to foreign function with FFI-unwind ABI - --> $DIR/ffi-unwind-calls-lint.rs:20:14 + --> $DIR/ffi-unwind-calls-lint.rs:19:14 | LL | unsafe { foo(); } | ^^^^^ call to foreign function with FFI-unwind ABI | note: the lint level is defined here - --> $DIR/ffi-unwind-calls-lint.rs:5:9 + --> $DIR/ffi-unwind-calls-lint.rs:4:9 | LL | #![warn(ffi_unwind_calls)] | ^^^^^^^^^^^^^^^^ warning: call to function pointer with FFI-unwind ABI - --> $DIR/ffi-unwind-calls-lint.rs:24:5 + --> $DIR/ffi-unwind-calls-lint.rs:23:5 | LL | ptr(); | ^^^^^ call to function pointer with FFI-unwind ABI diff --git a/triagebot.toml b/triagebot.toml index 89867b63d64..54c8b2060c5 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -475,10 +475,10 @@ cc = ["@rust-lang/style"] [mentions."Cargo.lock"] message = """ -These commits modify the `Cargo.lock` file. Random changes to `Cargo.lock` can be introduced when switching branches and rebasing PRs. -This was probably unintentional and should be reverted before this PR is merged. +These commits modify the `Cargo.lock` file. Unintentional changes to `Cargo.lock` can be introduced when switching branches and rebasing PRs. -If this was intentional then you can ignore this comment. +If this was unintentional then you should revert the changes before this PR is merged. +Otherwise, you can ignore this comment. """ [mentions."src/tools/x"] @@ -489,6 +489,14 @@ message = "This PR changes src/bootstrap/defaults/config.compiler.toml. If appro [mentions."src/bootstrap/defaults/config.codegen.toml"] message = "This PR changes src/bootstrap/defaults/config.codegen.toml. If appropriate, please also update `config.compiler.toml` so the defaults are in sync." +[mentions."tests/ui/deriving/deriving-all-codegen.stdout"] +message = "Changes to the code generated for builtin derived traits." +cc = ["@nnethercote"] + +[mentions."tests/ui/stats/hir-stats.stderr"] +message = "Changes to the size of AST and/or HIR nodes." +cc = ["@nnethercote"] + [assign] warn_non_default_branch = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" diff --git a/x b/x index 4309b82627c..d967988e1c4 100755 --- a/x +++ b/x @@ -7,9 +7,12 @@ set -eu +# syntax check +sh -n $0 + realpath() { if [ -d "$1" ]; then - CDPATH='' command cd "$1" && pwd -P + CDPATH='' command cd "$1" && pwd -P else echo "$(realpath "$(dirname "$1")")/$(basename "$1")" fi diff --git a/x.ps1 b/x.ps1 index f324a4676c8..a156017628d 100755 --- a/x.ps1 +++ b/x.ps1 @@ -2,6 +2,11 @@ # See ./x for why these scripts exist. +$ErrorActionPreference = "Stop" + +# syntax check +Get-Command -syntax ${PSCommandPath} + $xpy = Join-Path $PSScriptRoot x.py # Start-Process for some reason splits arguments on spaces. (Isn't powershell supposed to be simpler than bash?) # Double-quote all the arguments so it doesn't do that. @@ -16,7 +21,14 @@ function Get-Application($app) { function Invoke-Application($application, $arguments) { $process = Start-Process -NoNewWindow -PassThru $application $arguments + # WORKAROUND: Caching the handle is necessary to make ExitCode work. + # See https://stackoverflow.com/a/23797762 + $handle = $process.Handle $process.WaitForExit() + if ($null -eq $process.ExitCode) { + Write-Error "Unable to read the exit code" + Exit 1 + } Exit $process.ExitCode } diff --git a/x.py b/x.py index 5dee953a318..b8cdf67712c 100755 --- a/x.py +++ b/x.py @@ -4,26 +4,29 @@ # This file is only a "symlink" to bootstrap.py, all logic should go there. -import os -import sys +# Parts of `bootstrap.py` use the `multiprocessing` module, so this entry point +# must use the normal `if __name__ == '__main__':` convention to avoid problems. +if __name__ == '__main__': + import os + import sys -# If this is python2, check if python3 is available and re-execute with that -# interpreter. Only python3 allows downloading CI LLVM. -# -# This matters if someone's system `python` is python2. -if sys.version_info.major < 3: - try: - os.execvp("py", ["py", "-3"] + sys.argv) - except OSError: + # If this is python2, check if python3 is available and re-execute with that + # interpreter. Only python3 allows downloading CI LLVM. + # + # This matters if someone's system `python` is python2. + if sys.version_info.major < 3: try: - os.execvp("python3", ["python3"] + sys.argv) + os.execvp("py", ["py", "-3"] + sys.argv) except OSError: - # Python 3 isn't available, fall back to python 2 - pass + try: + os.execvp("python3", ["python3"] + sys.argv) + except OSError: + # Python 3 isn't available, fall back to python 2 + pass -rust_dir = os.path.dirname(os.path.abspath(__file__)) -# For the import below, have Python search in src/bootstrap first. -sys.path.insert(0, os.path.join(rust_dir, "src", "bootstrap")) + rust_dir = os.path.dirname(os.path.abspath(__file__)) + # For the import below, have Python search in src/bootstrap first. + sys.path.insert(0, os.path.join(rust_dir, "src", "bootstrap")) -import bootstrap -bootstrap.main() + import bootstrap + bootstrap.main() |
