From dbee24d94992df4c1888ebc2095d251fac22c05f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 13 Jun 2023 20:41:15 +0000 Subject: [PATCH 01/11] Suggest correct signature on missing fn returning RPITIT/AFIT --- compiler/rustc_hir_analysis/src/check/mod.rs | 31 +++++++++++++++++-- .../in-trait/suggest-missing-item.fixed | 22 +++++++++++++ .../in-trait/suggest-missing-item.rs | 19 ++++++++++++ .../in-trait/suggest-missing-item.stderr | 18 +++++++++++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 tests/ui/impl-trait/in-trait/suggest-missing-item.fixed create mode 100644 tests/ui/impl-trait/in-trait/suggest-missing-item.rs create mode 100644 tests/ui/impl-trait/in-trait/suggest-missing-item.stderr diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index c9e74896ac08e..d8e9e5a01528e 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -403,7 +403,32 @@ fn fn_sig_suggestion<'tcx>( .flatten() .collect::>() .join(", "); - let output = sig.output(); + let mut output = sig.output(); + + let asyncness = if tcx.asyncness(assoc.def_id).is_async() { + output = if let ty::Alias(_, alias_ty) = *output.kind() { + tcx.explicit_item_bounds(alias_ty.def_id) + .subst_iter_copied(tcx, alias_ty.substs) + .find_map(|(bound, _)| { + bound.to_opt_poly_projection_pred()?.no_bound_vars()?.term.ty() + }) + .unwrap_or_else(|| { + span_bug!( + ident.span, + "expected async fn to have `impl Future` output, but it returns {output}" + ) + }) + } else { + span_bug!( + ident.span, + "expected async fn to have `impl Future` output, but it returns {output}" + ) + }; + "async " + } else { + "" + }; + let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() }; let unsafety = sig.unsafety.prefix_str(); @@ -414,7 +439,9 @@ fn fn_sig_suggestion<'tcx>( // lifetimes between the `impl` and the `trait`, but this should be good enough to // fill in a significant portion of the missing code, and other subsequent // suggestions can help the user fix the code. - format!("{unsafety}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}") + format!( + "{unsafety}{asyncness}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}" + ) } pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> { diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed new file mode 100644 index 0000000000000..16c4d15ddcd60 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed @@ -0,0 +1,22 @@ +// edition:2021 +// run-rustfix + +#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] + +trait Trait { + async fn foo(); + + async fn bar() -> i32; + + fn test(&self) -> impl Sized + '_; +} + +struct S; + +impl Trait for S {fn test(&self) -> impl Sized + '_ { todo!() } +async fn bar() -> i32 { todo!() } +async fn foo() { todo!() } +} +//~^ ERROR not all trait items implemented + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs new file mode 100644 index 0000000000000..f218e6cb581e3 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs @@ -0,0 +1,19 @@ +// edition:2021 +// run-rustfix + +#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] + +trait Trait { + async fn foo(); + + async fn bar() -> i32; + + fn test(&self) -> impl Sized + '_; +} + +struct S; + +impl Trait for S {} +//~^ ERROR not all trait items implemented + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr new file mode 100644 index 0000000000000..d96641fe16335 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr @@ -0,0 +1,18 @@ +error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `test` + --> $DIR/suggest-missing-item.rs:16:1 + | +LL | async fn foo(); + | --------------- `foo` from trait +LL | +LL | async fn bar() -> i32; + | ---------------------- `bar` from trait +LL | +LL | fn test(&self) -> impl Sized + '_; + | ---------------------------------- `test` from trait +... +LL | impl Trait for S {} + | ^^^^^^^^^^^^^^^^ missing `foo`, `bar`, `test` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. From 3a9a8d4abf440eab3465b18ed65a1bade78666d5 Mon Sep 17 00:00:00 2001 From: ltdk Date: Tue, 13 Jun 2023 22:30:38 -0400 Subject: [PATCH 02/11] Alter `Display` for `Ipv6Addr` for IPv4-compatible addresses --- library/core/src/net/ip_addr.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index 954d88d548e82..c51913fa8ab8d 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -1770,14 +1770,8 @@ impl fmt::Display for Ipv6Addr { f.write_str("::") } else if self.is_loopback() { f.write_str("::1") - } else if let Some(ipv4) = self.to_ipv4() { - match segments[5] { - // IPv4 Compatible address - 0 => write!(f, "::{}", ipv4), - // IPv4 Mapped address - 0xffff => write!(f, "::ffff:{}", ipv4), - _ => unreachable!(), - } + } else if let Some(ipv4) = self.to_ipv4_mapped() { + write!(f, "::ffff:{}", ipv4) } else { #[derive(Copy, Clone, Default)] struct Span { From 2f2c3f55a967dc8e48f3a9755980757f06233bef Mon Sep 17 00:00:00 2001 From: ltdk Date: Wed, 14 Jun 2023 14:25:25 -0400 Subject: [PATCH 03/11] Fix `Ipv6Addr: Display` tests --- library/core/tests/net/ip_addr.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/tests/net/ip_addr.rs b/library/core/tests/net/ip_addr.rs index 5a6ac08c08815..7530fc084874d 100644 --- a/library/core/tests/net/ip_addr.rs +++ b/library/core/tests/net/ip_addr.rs @@ -139,7 +139,7 @@ fn ipv6_addr_to_string() { // ipv4-compatible address let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280); - assert_eq!(a1.to_string(), "::192.0.2.128"); + assert_eq!(a1.to_string(), "::c000:280"); // v6 address with no zero segments assert_eq!(Ipv6Addr::new(8, 9, 10, 11, 12, 13, 14, 15).to_string(), "8:9:a:b:c:d:e:f"); @@ -316,7 +316,7 @@ fn ip_properties() { check!("::", unspec); check!("::1", loopback); - check!("::0.0.0.2", global); + check!("::2", global); check!("1::", global); check!("fc00::"); check!("fdff:ffff::"); @@ -607,7 +607,7 @@ fn ipv6_properties() { check!("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], loopback); - check!("::0.0.0.2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], global | unicast_global); + check!("::2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], global | unicast_global); check!("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global); From 2dce58d0f624b20633f4e6d22335b4681ec48089 Mon Sep 17 00:00:00 2001 From: ltdk Date: Wed, 14 Jun 2023 14:59:11 -0400 Subject: [PATCH 04/11] Fix `SocketAddrV6: Display` tests --- library/core/tests/net/socket_addr.rs | 2 +- library/std/src/net/socket_addr/tests.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/tests/net/socket_addr.rs b/library/core/tests/net/socket_addr.rs index 68c7cd94d322f..35a69cead4826 100644 --- a/library/core/tests/net/socket_addr.rs +++ b/library/core/tests/net/socket_addr.rs @@ -34,7 +34,7 @@ fn ipv6_socket_addr_to_string() { // IPv4-compatible address. assert_eq!( SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280), 8080, 0, 0).to_string(), - "[::192.0.2.128]:8080" + "[::c000:280]:8080" ); // IPv6 address with no zero segments. diff --git a/library/std/src/net/socket_addr/tests.rs b/library/std/src/net/socket_addr/tests.rs index dfc6dabbed1ed..6a065cfba2105 100644 --- a/library/std/src/net/socket_addr/tests.rs +++ b/library/std/src/net/socket_addr/tests.rs @@ -85,7 +85,7 @@ fn ipv6_socket_addr_to_string() { // IPv4-compatible address. assert_eq!( SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280), 8080, 0, 0).to_string(), - "[::192.0.2.128]:8080" + "[::c000:280]:8080" ); // IPv6 address with no zero segments. From 22d00dcd47e0b8e18eb254966750fb523c726e4e Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 10 Jun 2023 12:06:17 -0400 Subject: [PATCH 05/11] Apply changes to fix python linting errors --- .../tools/generate_intrinsics.py | 3 +-- library/core/src/unicode/printable.py | 2 +- src/bootstrap/bootstrap.py | 4 ++-- src/bootstrap/configure.py | 10 +++++----- src/ci/cpu-usage-over-time.py | 0 .../test-various/uefi_qemu_test/run.py | 0 src/ci/docker/scripts/android-sdk-manager.py | 17 ++++++++-------- src/ci/docker/scripts/fuchsia-test-runner.py | 4 ++-- src/ci/stage-build.py | 4 ++-- src/etc/dec2flt_table.py | 4 +--- src/etc/gdb_load_rust_pretty_printers.py | 1 + src/etc/generate-deriving-span-tests.py | 4 +++- src/etc/htmldocck.py | 8 +++++--- src/etc/lldb_batchmode.py | 2 +- src/etc/lldb_providers.py | 2 +- src/etc/test-float-parse/runtests.py | 0 src/tools/miri/test-cargo-miri/run-test.py | 20 +++++++++++++------ src/tools/publish_toolstate.py | 16 +++++++-------- .../coverage-reports/sort_subviews.py | 0 .../run-make/libtest-junit/validate_junit.py | 2 +- .../rustdoc-map-file/validate_json.py | 2 +- .../sysroot-crates-are-unstable/test.py | 2 +- 22 files changed, 58 insertions(+), 49 deletions(-) mode change 100644 => 100755 src/ci/cpu-usage-over-time.py mode change 100644 => 100755 src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py mode change 100644 => 100755 src/ci/stage-build.py mode change 100644 => 100755 src/etc/dec2flt_table.py mode change 100644 => 100755 src/etc/htmldocck.py mode change 100644 => 100755 src/etc/test-float-parse/runtests.py mode change 100644 => 100755 tests/run-make/coverage-reports/sort_subviews.py diff --git a/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py b/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py index 6188924b0d50a..83abe145e64f0 100644 --- a/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py +++ b/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py @@ -3,7 +3,6 @@ import re import sys import subprocess -from os import walk def run_command(command, cwd=None): @@ -180,7 +179,7 @@ def update_intrinsics(llvm_path, llvmint, llvmint2): intrinsics[arch].sort(key=lambda x: (x[0], x[2])) out.write(' // {}\n'.format(arch)) for entry in intrinsics[arch]: - if entry[2] == True: # if it is a duplicate + if entry[2] is True: # if it is a duplicate out.write(' // [DUPLICATE]: "{}" => "{}",\n'.format(entry[0], entry[1])) elif "_round_mask" in entry[1]: out.write(' // [INVALID CONVERSION]: "{}" => "{}",\n'.format(entry[0], entry[1])) diff --git a/library/core/src/unicode/printable.py b/library/core/src/unicode/printable.py index 7c37f5f099c7f..4d39ace066c46 100755 --- a/library/core/src/unicode/printable.py +++ b/library/core/src/unicode/printable.py @@ -119,7 +119,7 @@ def print_singletons(uppers, lowers, uppersname, lowersname): print("#[rustfmt::skip]") print("const {}: &[u8] = &[".format(lowersname)) for i in range(0, len(lowers), 8): - print(" {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8]))) + print(" {}".format(" ".join("{:#04x},".format(x) for x in lowers[i:i+8]))) print("];") def print_normal(normal, normalname): diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 473fdbe1edc27..5714613cdf512 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -620,7 +620,7 @@ def get_answer(): # The latter one does not exist on NixOS when using tmpfs as root. try: with open("/etc/os-release", "r") as f: - if not any(l.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"') for l in f): + if not any(ln.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"') for ln in f): return False except FileNotFoundError: return False @@ -872,7 +872,7 @@ def build_bootstrap(self, color, warnings, verbose_count): } for var_name, toml_key in var_data.items(): toml_val = self.get_toml(toml_key, build_section) - if toml_val != None: + if toml_val is not None: env["{}_{}".format(var_name, host_triple_sanitized)] = toml_val # preserve existing RUSTFLAGS diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 4481e1668b60f..a16f77317c82b 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -9,7 +9,7 @@ rust_dir = os.path.dirname(rust_dir) rust_dir = os.path.dirname(rust_dir) sys.path.append(os.path.join(rust_dir, "src", "bootstrap")) -import bootstrap +import bootstrap # noqa: E402 class Option(object): @@ -319,7 +319,7 @@ def apply_args(known_args, option_checking, config): for key in known_args: # The `set` option is special and can be passed a bunch of times if key == 'set': - for option, value in known_args[key]: + for _option, value in known_args[key]: keyval = value.split('=', 1) if len(keyval) == 1 or keyval[1] == "true": value = True @@ -401,7 +401,7 @@ def parse_example_config(known_args, config): top_level_keys = [] for line in open(rust_dir + '/config.example.toml').read().split("\n"): - if cur_section == None: + if cur_section is None: if line.count('=') == 1: top_level_key = line.split('=')[0] top_level_key = top_level_key.strip(' #') @@ -523,8 +523,8 @@ def write_uncommented(target, f): block.append(line) if len(line) == 0: if not is_comment: - for l in block: - f.write(l + "\n") + for ln in block: + f.write(ln + "\n") block = [] is_comment = True continue diff --git a/src/ci/cpu-usage-over-time.py b/src/ci/cpu-usage-over-time.py old mode 100644 new mode 100755 diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py old mode 100644 new mode 100755 diff --git a/src/ci/docker/scripts/android-sdk-manager.py b/src/ci/docker/scripts/android-sdk-manager.py index c9e2961f6eb15..66cba58427bad 100755 --- a/src/ci/docker/scripts/android-sdk-manager.py +++ b/src/ci/docker/scripts/android-sdk-manager.py @@ -2,6 +2,14 @@ # Simpler reimplementation of Android's sdkmanager # Extra features of this implementation are pinning and mirroring +import argparse +import hashlib +import os +import subprocess +import tempfile +import urllib.request +import xml.etree.ElementTree as ET + # These URLs are the Google repositories containing the list of available # packages and their versions. The list has been generated by listing the URLs # fetched while executing `tools/bin/sdkmanager --list` @@ -27,15 +35,6 @@ MIRROR_BUCKET_REGION = "us-west-1" MIRROR_BASE_DIR = "rustc/android/" -import argparse -import hashlib -import os -import subprocess -import sys -import tempfile -import urllib.request -import xml.etree.ElementTree as ET - class Package: def __init__(self, path, url, sha1, deps=None): if deps is None: diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index ecef56f56f1d5..77144b7499634 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -568,8 +568,8 @@ def log(msg): env_vars += f'\n "{var_name}={var_value}",' # Default to no backtrace for test suite - if os.getenv("RUST_BACKTRACE") == None: - env_vars += f'\n "RUST_BACKTRACE=0",' + if os.getenv("RUST_BACKTRACE") is None: + env_vars += '\n "RUST_BACKTRACE=0",' cml.write( self.CML_TEMPLATE.format(env_vars=env_vars, exe_name=exe_name) diff --git a/src/ci/stage-build.py b/src/ci/stage-build.py old mode 100644 new mode 100755 index febc0492b9433..3f30b69e8f472 --- a/src/ci/stage-build.py +++ b/src/ci/stage-build.py @@ -440,7 +440,7 @@ def retry_action(action, name: str, max_fails: int = 5): try: action() return - except: + except BaseException: # also catch ctrl+c/sysexit LOGGER.error(f"Action `{name}` has failed\n{traceback.format_exc()}") raise Exception(f"Action `{name}` has failed after {max_fails} attempts") @@ -818,7 +818,7 @@ def extract_dist_dir(name: str) -> Path: # Extract rustc, libstd, cargo and src archives to create the optimized sysroot rustc_dir = extract_dist_dir(f"rustc-nightly-{PGO_HOST}") / "rustc" libstd_dir = extract_dist_dir(f"rust-std-nightly-{PGO_HOST}") / f"rust-std-{PGO_HOST}" - cargo_dir = extract_dist_dir(f"cargo-nightly-{PGO_HOST}") / f"cargo" + cargo_dir = extract_dist_dir(f"cargo-nightly-{PGO_HOST}") / "cargo" extracted_src_dir = extract_dist_dir("rust-src-nightly") / "rust-src" # We need to manually copy libstd to the extracted rustc sysroot diff --git a/src/etc/dec2flt_table.py b/src/etc/dec2flt_table.py old mode 100644 new mode 100755 index aa5188d96c3e7..9264a8439bb71 --- a/src/etc/dec2flt_table.py +++ b/src/etc/dec2flt_table.py @@ -14,8 +14,7 @@ available here: . """ from __future__ import print_function -from math import ceil, floor, log, log2 -from fractions import Fraction +from math import ceil, floor, log from collections import deque HEADER = """ @@ -97,7 +96,6 @@ def print_proper_powers(min_exp, max_exp, bias): print('#[rustfmt::skip]') typ = '[(u64, u64); N_POWERS_OF_FIVE]' print('pub static POWER_OF_FIVE_128: {} = ['.format(typ)) - lo_mask = (1 << 64) - 1 for c, exp in powers: hi = '0x{:x}'.format(c // (1 << 64)) lo = '0x{:x}'.format(c % (1 << 64)) diff --git a/src/etc/gdb_load_rust_pretty_printers.py b/src/etc/gdb_load_rust_pretty_printers.py index 491b6ba9e9e69..e05039ce47447 100644 --- a/src/etc/gdb_load_rust_pretty_printers.py +++ b/src/etc/gdb_load_rust_pretty_printers.py @@ -4,6 +4,7 @@ self_dir = path.dirname(path.realpath(__file__)) sys.path.append(self_dir) +# ruff: noqa: E402 import gdb import gdb_lookup diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index d38f5add7474d..d61693460bc1f 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -102,7 +102,9 @@ def write_file(name, string): traits[trait] = (ALL, supers, errs) for (trait, (types, super_traits, error_count)) in traits.items(): - mk = lambda ty: create_test_case(ty, trait, super_traits, error_count) + def mk(ty, t=trait, st=super_traits, ec=error_count): + return create_test_case(ty, t, st, ec) + if types & ENUM: write_file(trait + '-enum', mk(ENUM_TUPLE)) write_file(trait + '-enum-struct-variant', mk(ENUM_STRUCT)) diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py old mode 100644 new mode 100755 index c97fb4b805473..eade9e0455912 --- a/src/etc/htmldocck.py +++ b/src/etc/htmldocck.py @@ -144,7 +144,7 @@ # Python 2 -> 3 compatibility try: - unichr + unichr # noqa: B018 FIXME: py2 except NameError: unichr = chr @@ -348,7 +348,9 @@ def get_tree(self, path): try: tree = ET.fromstringlist(f.readlines(), CustomHTMLParser()) except Exception as e: - raise RuntimeError('Cannot parse an HTML file {!r}: {}'.format(path, e)) + raise RuntimeError( # noqa: B904 FIXME: py2 + 'Cannot parse an HTML file {!r}: {}'.format(path, e) + ) self.trees[path] = tree return self.trees[path] @@ -422,7 +424,7 @@ def check_snapshot(snapshot_name, actual_tree, normalize_to_text): if bless: expected_str = None else: - raise FailedCheck('No saved snapshot value') + raise FailedCheck('No saved snapshot value') # noqa: B904 FIXME: py2 if not normalize_to_text: actual_str = ET.tostring(actual_tree).decode('utf-8') diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py index fc355c87b52a2..db1e0035ea063 100644 --- a/src/etc/lldb_batchmode.py +++ b/src/etc/lldb_batchmode.py @@ -124,7 +124,7 @@ def listen(): breakpoint = lldb.SBBreakpoint.GetBreakpointFromEvent(event) print_debug("breakpoint added, id = " + str(breakpoint.id)) new_breakpoints.append(breakpoint.id) - except: + except BaseException: # explicitly catch ctrl+c/sysexit print_debug("breakpoint listener shutting down") # Start the listener and let it run as a daemon diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index c4381e202b945..4c86b2146463d 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -1,6 +1,6 @@ import sys -from lldb import SBValue, SBData, SBError, eBasicTypeLong, eBasicTypeUnsignedLong, \ +from lldb import SBData, SBError, eBasicTypeLong, eBasicTypeUnsignedLong, \ eBasicTypeUnsignedChar # from lldb.formatters import Logger diff --git a/src/etc/test-float-parse/runtests.py b/src/etc/test-float-parse/runtests.py old mode 100644 new mode 100755 diff --git a/src/tools/miri/test-cargo-miri/run-test.py b/src/tools/miri/test-cargo-miri/run-test.py index 9df90c725e40f..f022c51e59fa8 100755 --- a/src/tools/miri/test-cargo-miri/run-test.py +++ b/src/tools/miri/test-cargo-miri/run-test.py @@ -5,7 +5,11 @@ and the working directory to contain the cargo-miri-test project. ''' -import sys, subprocess, os, re, difflib +import difflib +import os +import re +import sys +import subprocess CGREEN = '\33[32m' CBOLD = '\33[1m' @@ -46,7 +50,9 @@ def check_output(actual, path, name): print(f"--- END diff {name} ---") return False -def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}): +def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env=None): + if env is None: + env = {} print("Testing {}...".format(name)) ## Call `cargo miri`, capture all output p_env = os.environ.copy() @@ -64,13 +70,15 @@ def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}): stdout_matches = check_output(stdout, stdout_ref, "stdout") stderr_matches = check_output(stderr, stderr_ref, "stderr") - + if p.returncode == 0 and stdout_matches and stderr_matches: # All good! return fail("exit code was {}".format(p.returncode)) -def test_no_rebuild(name, cmd, env={}): +def test_no_rebuild(name, cmd, env=None): + if env is None: + env = {} print("Testing {}...".format(name)) p_env = os.environ.copy() p_env.update(env) @@ -84,13 +92,13 @@ def test_no_rebuild(name, cmd, env={}): stdout = stdout.decode("UTF-8") stderr = stderr.decode("UTF-8") if p.returncode != 0: - fail("rebuild failed"); + fail("rebuild failed") # Also check for 'Running' as a sanity check. if stderr.count(" Compiling ") > 0 or stderr.count(" Running ") == 0: print("--- BEGIN stderr ---") print(stderr, end="") print("--- END stderr ---") - fail("Something was being rebuilt when it should not be (or we got no output)"); + fail("Something was being rebuilt when it should not be (or we got no output)") def test_cargo_miri_run(): test("`cargo miri run` (no isolation)", diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 2018c239ba068..f9421117eaa2e 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -22,7 +22,7 @@ import urllib.request as urllib2 from urllib.error import HTTPError try: - import typing + import typing # noqa: F401 FIXME: py2 except ImportError: pass @@ -152,8 +152,8 @@ def update_latest( latest = json.load(f, object_pairs_hook=collections.OrderedDict) current_status = { - os: read_current_status(current_commit, 'history/' + os + '.tsv') - for os in ['windows', 'linux'] + os_: read_current_status(current_commit, 'history/' + os_ + '.tsv') + for os_ in ['windows', 'linux'] } slug = 'rust-lang/rust' @@ -170,10 +170,10 @@ def update_latest( changed = False create_issue_for_status = None # set to the status that caused the issue - for os, s in current_status.items(): - old = status[os] + for os_, s in current_status.items(): + old = status[os_] new = s.get(tool, old) - status[os] = new + status[os_] = new maintainers = ' '.join('@'+name for name in MAINTAINERS.get(tool, ())) # comparing the strings, but they are ordered appropriately: # "test-pass" > "test-fail" > "build-fail" @@ -181,12 +181,12 @@ def update_latest( # things got fixed or at least the status quo improved changed = True message += '🎉 {} on {}: {} → {} (cc {}).\n' \ - .format(tool, os, old, new, maintainers) + .format(tool, os_, old, new, maintainers) elif new < old: # tests or builds are failing and were not failing before changed = True title = '💔 {} on {}: {} → {}' \ - .format(tool, os, old, new) + .format(tool, os_, old, new) message += '{} (cc {}).\n' \ .format(title, maintainers) # See if we need to create an issue. diff --git a/tests/run-make/coverage-reports/sort_subviews.py b/tests/run-make/coverage-reports/sort_subviews.py old mode 100644 new mode 100755 diff --git a/tests/run-make/libtest-junit/validate_junit.py b/tests/run-make/libtest-junit/validate_junit.py index 47a8e70ccc38c..0d9b34a3cf7e0 100755 --- a/tests/run-make/libtest-junit/validate_junit.py +++ b/tests/run-make/libtest-junit/validate_junit.py @@ -7,6 +7,6 @@ for line in sys.stdin: try: ET.fromstring(line) - except ET.ParseError as pe: + except ET.ParseError: print("Invalid xml: %r" % line) raise diff --git a/tests/run-make/rustdoc-map-file/validate_json.py b/tests/run-make/rustdoc-map-file/validate_json.py index 5c14c90b70d37..912dea3791bbf 100755 --- a/tests/run-make/rustdoc-map-file/validate_json.py +++ b/tests/run-make/rustdoc-map-file/validate_json.py @@ -6,7 +6,7 @@ def find_redirect_map_file(folder, errors): - for root, dirs, files in os.walk(folder): + for root, _dirs, files in os.walk(folder): for name in files: if not name.endswith("redirect-map.json"): continue diff --git a/tests/run-make/sysroot-crates-are-unstable/test.py b/tests/run-make/sysroot-crates-are-unstable/test.py index cab4faa4e645a..45cfdd195b4e2 100644 --- a/tests/run-make/sysroot-crates-are-unstable/test.py +++ b/tests/run-make/sysroot-crates-are-unstable/test.py @@ -46,7 +46,7 @@ def check_lib(lib): '--target', os.environ['TARGET'], '--extern', '{}={}'.format(lib['name'], lib['path'])], to_input=('extern crate {};'.format(lib['name'])).encode('utf-8')) - if not 'use of unstable library feature' in '{}{}'.format(stdout, stderr): + if 'use of unstable library feature' not in '{}{}'.format(stdout, stderr): print('crate {} "{}" is not unstable'.format(lib['name'], lib['path'])) print('{}{}'.format(stdout, stderr)) print('') From 89c24af133ddc3e5ee2bee03222da935b50d10e8 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 18 Jun 2023 05:24:38 +0000 Subject: [PATCH 06/11] Better error for non const `PartialEq` call generated by `match` --- .../src/diagnostics/conflict_errors.rs | 7 +- .../src/diagnostics/explain_borrow.rs | 6 +- .../rustc_borrowck/src/diagnostics/mod.rs | 16 +++- compiler/rustc_borrowck/src/invalidation.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 8 +- compiler/rustc_codegen_cranelift/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_const_eval/messages.ftl | 3 + compiler/rustc_const_eval/src/errors.rs | 12 +++ .../src/interpret/terminator.rs | 2 +- .../src/transform/check_consts/check.rs | 12 +-- .../src/transform/check_consts/ops.rs | 94 +++++++++++-------- .../src/transform/promote_consts.rs | 6 +- compiler/rustc_middle/src/mir/syntax.rs | 32 ++++++- compiler/rustc_middle/src/mir/visit.rs | 2 +- .../src/build/custom/parse/instruction.rs | 4 +- .../src/build/expr/as_rvalue.rs | 2 +- .../rustc_mir_build/src/build/expr/into.rs | 6 +- .../rustc_mir_build/src/build/matches/test.rs | 4 +- .../rustc_mir_dataflow/src/elaborate_drops.rs | 2 +- .../src/framework/direction.rs | 10 +- .../rustc_mir_dataflow/src/framework/tests.rs | 4 +- .../src/move_paths/builder.rs | 2 +- .../rustc_mir_transform/src/coverage/tests.rs | 2 +- .../src/function_item_references.rs | 2 +- compiler/rustc_mir_transform/src/generator.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 6 +- .../src/lower_slice_len.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 4 +- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- .../match-non-const-eq.gated.stderr | 26 +++++ .../match-non-const-eq.rs | 12 +++ .../match-non-const-eq.stock.stderr | 13 +++ 35 files changed, 213 insertions(+), 102 deletions(-) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 15d73ed732f50..fd5c21cfdf627 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -14,7 +14,7 @@ use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ - self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, + self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, }; @@ -2579,7 +2579,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diagnostic) { let tcx = self.infcx.tcx; if let ( - Some(Terminator { kind: TerminatorKind::Call { from_hir_call: false, .. }, .. }), + Some(Terminator { + kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. }, + .. + }), Some((method_did, method_substs)), ) = ( &self.body[loan.reserve_location.block].terminator, diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 1d430a93a876d..6c01fd63b1ec7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -6,8 +6,8 @@ use rustc_hir::intravisit::Visitor; use rustc_index::IndexSlice; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::{ - Body, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, Operand, Place, - Rvalue, Statement, StatementKind, TerminatorKind, + Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, + Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind, }; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::{self, RegionVid, TyCtxt}; @@ -494,7 +494,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else if self.was_captured_by_trait_object(borrow) { LaterUseKind::TraitCapture } else if location.statement_index == block.statements.len() { - if let TerminatorKind::Call { func, from_hir_call: true, .. } = + if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } = &block.terminator().kind { // Just point to the function, to reduce the chance of overlapping spans. diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 20370e4c6ac3c..1d3cc851888cf 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -13,8 +13,9 @@ use rustc_index::IndexSlice; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ - AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place, - PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, + AggregateKind, CallSource, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, + Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, + TerminatorKind, }; use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; @@ -414,7 +415,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if !is_terminator { continue; } else if let Some(Terminator { - kind: TerminatorKind::Call { func, from_hir_call: false, .. }, + kind: + TerminatorKind::Call { + func, + call_source: CallSource::OverloadedOperator, + .. + }, .. }) = &bbd.terminator { @@ -839,7 +845,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!("move_spans: target_temp = {:?}", target_temp); if let Some(Terminator { - kind: TerminatorKind::Call { fn_span, from_hir_call, .. }, .. + kind: TerminatorKind::Call { fn_span, call_source, .. }, .. }) = &self.body[location.block].terminator { let Some((method_did, method_substs)) = @@ -859,7 +865,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { method_did, method_substs, *fn_span, - *from_hir_call, + call_source.from_hir_call(), Some(self.infcx.tcx.fn_arg_names(method_did)[0]), ); diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index b2ff25ecb96f4..e4fbe6ea4f438 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -128,7 +128,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { destination, target: _, unwind: _, - from_hir_call: _, + call_source: _, fn_span: _, } => { self.consume_operand(location, func); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 99a988f2c629e..4fcdda311bfd3 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -710,7 +710,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro destination, target: _, unwind: _, - from_hir_call: _, + call_source: _, fn_span: _, } => { self.consume_operand(loc, (func, span), flow_state); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6697e1aff7dd0..dba1993a8c356 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1370,7 +1370,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // FIXME: check the values } - TerminatorKind::Call { func, args, destination, from_hir_call, target, .. } => { + TerminatorKind::Call { func, args, destination, call_source, target, .. } => { self.check_operand(func, term_location); for arg in args { self.check_operand(arg, term_location); @@ -1444,7 +1444,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .add_element(region_vid, term_location); } - self.check_call_inputs(body, term, &sig, args, term_location, *from_hir_call); + self.check_call_inputs(body, term, &sig, args, term_location, *call_source); } TerminatorKind::Assert { cond, msg, .. } => { self.check_operand(cond, term_location); @@ -1571,7 +1571,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { sig: &ty::FnSig<'tcx>, args: &[Operand<'tcx>], term_location: Location, - from_hir_call: bool, + call_source: CallSource, ) { debug!("check_call_inputs({:?}, {:?})", sig, args); if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { @@ -1589,7 +1589,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let op_arg_ty = op_arg.ty(body, self.tcx()); let op_arg_ty = self.normalize(op_arg_ty, term_location); - let category = if from_hir_call { + let category = if call_source.from_hir_call() { ConstraintCategory::CallArgument(self.infcx.tcx.erase_regions(func_ty)) } else { ConstraintCategory::Boring diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 5abb4644e1b09..ce10780f9de12 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -421,7 +421,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { target, fn_span, unwind: _, - from_hir_call: _, + call_source: _, } => { fx.tcx.prof.generic_activity("codegen call").run(|| { crate::abi::codegen_terminator_call( diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index a4a8aad87269d..0cec560ba4518 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1280,7 +1280,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { destination, target, unwind, - from_hir_call: _, + call_source: _, fn_span, } => self.codegen_call_terminator( helper, diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index bf660c59cabda..e99005316b3fd 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -210,6 +210,9 @@ const_eval_long_running = .label = the const evaluator is currently interpreting this expression .help = the constant being evaluated +const_eval_match_eq_non_const = cannot match on `{$ty}` in {const_eval_const_context}s + .note = `{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es + const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id} const_eval_memory_access_test = memory access failed diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index eed3091d481e3..ca38cce710e60 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -271,6 +271,18 @@ pub struct RawBytesNote { pub bytes: String, } +// FIXME(fee1-dead) do not use stringly typed `ConstContext` + +#[derive(Diagnostic)] +#[diag(const_eval_match_eq_non_const, code = "E0015")] +#[note] +pub struct NonConstMatchEq<'tcx> { + #[primary_span] + pub span: Span, + pub ty: Ty<'tcx>, + pub kind: ConstContext, +} + #[derive(Diagnostic)] #[diag(const_eval_for_loop_into_iter_non_const, code = "E0015")] pub struct NonConstForLoopIntoIter<'tcx> { diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 7269ff8d53cdf..719d8a14b4134 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -62,7 +62,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { destination, target, unwind, - from_hir_call: _, + call_source: _, fn_span: _, } => { let old_stack = self.frame_idx(); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 106cf1114749a..2aaf1340eb409 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -702,7 +702,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { self.super_terminator(terminator, location); match &terminator.kind { - TerminatorKind::Call { func, args, fn_span, from_hir_call, .. } => { + TerminatorKind::Call { func, args, fn_span, call_source, .. } => { let ConstCx { tcx, body, param_env, .. } = *self.ccx; let caller = self.def_id(); @@ -755,7 +755,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee, substs, span: *fn_span, - from_hir_call: *from_hir_call, + call_source: *call_source, feature: Some(sym::const_trait_impl), }); return; @@ -797,7 +797,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee, substs, span: *fn_span, - from_hir_call: *from_hir_call, + call_source: *call_source, feature: None, }); @@ -823,7 +823,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee, substs, span: *fn_span, - from_hir_call: *from_hir_call, + call_source: *call_source, feature: None, }); return; @@ -866,7 +866,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee, substs, span: *fn_span, - from_hir_call: *from_hir_call, + call_source: *call_source, feature: None, }); return; @@ -926,7 +926,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee, substs, span: *fn_span, - from_hir_call: *from_hir_call, + call_source: *call_source, feature: None, }); return; 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 236e43bdfcc71..32bd9cda6f2b4 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -7,7 +7,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; -use rustc_middle::mir; +use rustc_middle::mir::{self, CallSource}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty}; @@ -100,7 +100,7 @@ pub struct FnCallNonConst<'tcx> { pub callee: DefId, pub substs: SubstsRef<'tcx>, pub span: Span, - pub from_hir_call: bool, + pub call_source: CallSource, pub feature: Option, } @@ -110,7 +110,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ccx: &ConstCx<'_, 'tcx>, _: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - let FnCallNonConst { caller, callee, substs, span, from_hir_call, feature } = *self; + let FnCallNonConst { caller, callee, substs, span, call_source, feature } = *self; let ConstCx { tcx, param_env, .. } = *ccx; let diag_trait = |err, self_ty: Ty<'_>, trait_id| { @@ -157,7 +157,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { } }; - let call_kind = call_kind(tcx, ccx.param_env, callee, substs, span, from_hir_call, None); + let call_kind = + call_kind(tcx, ccx.param_env, callee, substs, span, call_source.from_hir_call(), None); debug!(?call_kind); @@ -219,48 +220,59 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { err } CallKind::Operator { trait_id, self_ty, .. } => { - let mut sugg = None; - - if Some(trait_id) == ccx.tcx.lang_items().eq_trait() { - match (substs[0].unpack(), substs[1].unpack()) { - (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty)) - if self_ty == rhs_ty - && self_ty.is_ref() - && self_ty.peel_refs().is_primitive() => - { - let mut num_refs = 0; - let mut tmp_ty = self_ty; - while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() { - num_refs += 1; - tmp_ty = *inner_ty; - } - let deref = "*".repeat(num_refs); - - if let Ok(call_str) = ccx.tcx.sess.source_map().span_to_snippet(span) { - if let Some(eq_idx) = call_str.find("==") { - if let Some(rhs_idx) = - call_str[(eq_idx + 2)..].find(|c: char| !c.is_whitespace()) - { - let rhs_pos = - span.lo() + BytePos::from_usize(eq_idx + 2 + rhs_idx); - let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos); - sugg = Some(errors::ConsiderDereferencing { - deref, - span: span.shrink_to_lo(), - rhs_span, - }); + let mut err = if let CallSource::MatchCmp = call_source { + tcx.sess.create_err(errors::NonConstMatchEq { + span, + kind: ccx.const_kind(), + ty: self_ty, + }) + } else { + let mut sugg = None; + + if Some(trait_id) == ccx.tcx.lang_items().eq_trait() { + match (substs[0].unpack(), substs[1].unpack()) { + (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty)) + if self_ty == rhs_ty + && self_ty.is_ref() + && self_ty.peel_refs().is_primitive() => + { + let mut num_refs = 0; + let mut tmp_ty = self_ty; + while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() { + num_refs += 1; + tmp_ty = *inner_ty; + } + let deref = "*".repeat(num_refs); + + if let Ok(call_str) = + ccx.tcx.sess.source_map().span_to_snippet(span) + { + if let Some(eq_idx) = call_str.find("==") { + if let Some(rhs_idx) = call_str[(eq_idx + 2)..] + .find(|c: char| !c.is_whitespace()) + { + let rhs_pos = span.lo() + + BytePos::from_usize(eq_idx + 2 + rhs_idx); + let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos); + sugg = Some(errors::ConsiderDereferencing { + deref, + span: span.shrink_to_lo(), + rhs_span, + }); + } } } } + _ => {} } - _ => {} } - } - let mut err = tcx.sess.create_err(errors::NonConstOperator { - span, - kind: ccx.const_kind(), - sugg, - }); + tcx.sess.create_err(errors::NonConstOperator { + span, + kind: ccx.const_kind(), + sugg, + }) + }; + diag_trait(&mut err, self_ty, trait_id); err } diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 0e2d9ee8fb2fb..809cf62d8142d 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -795,7 +795,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { }; match terminator.kind { - TerminatorKind::Call { mut func, mut args, from_hir_call, fn_span, .. } => { + TerminatorKind::Call { + mut func, mut args, call_source: desugar, fn_span, .. + } => { self.visit_operand(&mut func, loc); for arg in &mut args { self.visit_operand(arg, loc); @@ -811,7 +813,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { unwind: UnwindAction::Continue, destination: Place::from(new_temp), target: Some(new_target), - from_hir_call, + call_source: desugar, fn_span, }, source_info: SourceInfo::outermost(terminator.source_info.span), diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 1a65f74f4fe22..fb3841f877687 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -512,6 +512,31 @@ pub struct CopyNonOverlapping<'tcx> { pub count: Operand<'tcx>, } +/// Represents how a `TerminatorKind::Call` was constructed, used for diagnostics +#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub enum CallSource { + /// This came from something such as `a > b` or `a + b`. In THIR, if `from_hir_call` + /// is false then this is the desugaring. + OverloadedOperator, + /// This was from comparison generated by a match, used by const-eval for better errors + /// when the comparison cannot be done in compile time. + /// + /// See https://github.com/rust-lang/rust/issues/90237. + MatchCmp, + /// Other types of desugaring that did not come from the HIR, but we don't care about + /// for diagnostics (yet). + Misc, + /// Normal function call, no special source + Normal, +} + +impl CallSource { + pub fn from_hir_call(self) -> bool { + matches!(self, CallSource::Normal) + } +} + /////////////////////////////////////////////////////////////////////////// // Terminators @@ -638,11 +663,10 @@ pub enum TerminatorKind<'tcx> { target: Option, /// Action to be taken if the call unwinds. unwind: UnwindAction, - /// `true` if this is from a call in HIR rather than from an overloaded - /// operator. True for overloaded function call. - from_hir_call: bool, + /// Where this call came from in HIR/THIR. + call_source: CallSource, /// This `Span` is the span of the function, without the dot and receiver - /// (e.g. `foo(a, b)` in `x.foo(a, b)` + /// e.g. `foo(a, b)` in `x.foo(a, b)` fn_span: Span, }, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 8d44e929afde3..ce55b770cbcb4 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -519,7 +519,7 @@ macro_rules! make_mir_visitor { destination, target: _, unwind: _, - from_hir_call: _, + call_source: _, fn_span: _ } => { self.visit_operand(func, location); diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index ebf830cb9c1f6..4cb9d7babe14f 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -128,7 +128,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { destination, target: Some(target), unwind: UnwindAction::Continue, - from_hir_call: *from_hir_call, + call_source: if *from_hir_call { CallSource::Normal } else { + CallSource::OverloadedOperator + }, fn_span: *fn_span, }) }, diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 3742d640e3b58..fd08b32807c40 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -173,7 +173,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: storage, target: Some(success), unwind: UnwindAction::Continue, - from_hir_call: false, + call_source: CallSource::Misc, fn_span: expr_span, }, ); diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 29ff916d2cc9c..731f3996244ca 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -277,7 +277,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .ty .is_inhabited_from(this.tcx, this.parent_module, this.param_env) .then_some(success), - from_hir_call, + call_source: if from_hir_call { + CallSource::Normal + } else { + CallSource::OverloadedOperator + }, fn_span, }, ); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index dbdb5b4a9a179..f431023f2b669 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: ref_str, target: Some(eq_block), unwind: UnwindAction::Continue, - from_hir_call: false, + call_source: CallSource::Misc, fn_span: source_info.span } ); @@ -496,7 +496,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: eq_result, target: Some(eq_block), unwind: UnwindAction::Continue, - from_hir_call: false, + call_source: CallSource::MatchCmp, fn_span: source_info.span, }, ); diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 4fc45eaf5220d..27232b70d960b 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -654,7 +654,7 @@ where destination: unit_temp, target: Some(succ), unwind: unwind.into_action(), - from_hir_call: true, + call_source: CallSource::Misc, fn_span: self.source_info.span, }, source_info: self.source_info, diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 0c379288a0962..804b44a6bf05d 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -502,15 +502,7 @@ impl Direction for Forward { propagate(target, exit_state); } - Call { - unwind, - destination, - target, - func: _, - args: _, - from_hir_call: _, - fn_span: _, - } => { + Call { unwind, destination, target, func: _, args: _, call_source: _, fn_span: _ } => { if let UnwindAction::Cleanup(unwind) = unwind { propagate(unwind, exit_state); } diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index 45c2fe55aca9f..cb0ec144ef0b7 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -40,7 +40,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { destination: dummy_place.clone(), target: Some(mir::START_BLOCK), unwind: mir::UnwindAction::Continue, - from_hir_call: false, + call_source: mir::CallSource::Misc, fn_span: DUMMY_SP, }, ); @@ -54,7 +54,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { destination: dummy_place.clone(), target: Some(mir::START_BLOCK), unwind: mir::UnwindAction::Continue, - from_hir_call: false, + call_source: mir::CallSource::Misc, fn_span: DUMMY_SP, }, ); diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 096bc0acfccb9..fe9631653ea72 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -399,7 +399,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { destination, target, unwind: _, - from_hir_call: _, + call_source: _, fn_span: _, } => { self.gather_operand(func); diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 90b58933df7c0..25891d3ca0f88 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -140,7 +140,7 @@ impl<'tcx> MockBlocks<'tcx> { destination: self.dummy_place.clone(), target: Some(TEMP_BLOCK), unwind: UnwindAction::Continue, - from_hir_call: false, + call_source: CallSource::Misc, fn_span: DUMMY_SP, }, ) diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index b1c9c4acc40e4..7f631cccddf54 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -34,7 +34,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> { destination: _, target: _, unwind: _, - from_hir_call: _, + call_source: _, fn_span: _, } = &terminator.kind { diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index fe3f8ed047a70..04134eb2fb169 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1692,7 +1692,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { destination, target: Some(_), unwind: _, - from_hir_call: _, + call_source: _, fn_span: _, } => { self.check_assigned_place(*destination, |this| { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9c8c0ea0be004..fa8257cf9849c 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -30,8 +30,8 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_index::IndexVec; use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{ - traversal, AnalysisPhase, Body, ClearCrossCrate, ConstQualifs, Constant, LocalDecl, MirPass, - MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo, + traversal, AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstQualifs, Constant, LocalDecl, + MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo, Statement, StatementKind, TerminatorKind, START_BLOCK, }; use rustc_middle::query::Providers; @@ -189,7 +189,7 @@ fn remap_mir_for_const_eval_select<'tcx>( }; method(place) }).collect(); - terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, unwind, from_hir_call: false, fn_span }; + terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, unwind, call_source: CallSource::Misc, fn_span }; } _ => {} } diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs index 6e40dfa0d1382..b7cc0db95597d 100644 --- a/compiler/rustc_mir_transform/src/lower_slice_len.rs +++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs @@ -54,7 +54,7 @@ fn lower_slice_len_call<'tcx>( args, destination, target: Some(bb), - from_hir_call: true, + call_source: CallSource::Normal, .. } => { // some heuristics for fast rejection diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 5f12f1937c06c..9d6ef9db4ea1b 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -500,7 +500,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { destination: dest, target: Some(next), unwind: UnwindAction::Cleanup(cleanup), - from_hir_call: true, + call_source: CallSource::Normal, fn_span: self.span, }, false, @@ -789,7 +789,7 @@ fn build_call_shim<'tcx>( } else { UnwindAction::Continue }, - from_hir_call: true, + call_source: CallSource::Misc, fn_span: span, }, false, diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 6bd030b13d1ce..5327f8a3cc37f 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -346,7 +346,7 @@ impl<'tcx> Stable for mir::Terminator<'tcx> { target: target.as_usize(), unwind: unwind.stable(), }, - Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => { + Call { func, args, destination, target, unwind, call_source: _, fn_span: _ } => { Terminator::Call { func: func.stable(), args: args.iter().map(|arg| arg.stable()).collect(), 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 c0d2c835d63d4..566eecf36a777 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 @@ -317,7 +317,7 @@ fn check_terminator<'tcx>( TerminatorKind::Call { func, args, - from_hir_call: _, + call_source: _, destination: _, target: _, unwind: _, diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr new file mode 100644 index 0000000000000..bd0dd126c5e6b --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr @@ -0,0 +1,26 @@ +error[E0277]: can't compare `str` with `str` in const contexts + --> $DIR/match-non-const-eq.rs:6:9 + | +LL | "a" => (), + | ^^^ no implementation for `str == str` + | + = help: the trait `~const PartialEq` is not implemented for `str` +note: the trait `PartialEq` is implemented for `str`, but that implementation is not `const` + --> $DIR/match-non-const-eq.rs:6:9 + | +LL | "a" => (), + | ^^^ + +error[E0015]: cannot match on `str` in constant functions + --> $DIR/match-non-const-eq.rs:6:9 + | +LL | "a" => (), + | ^^^ + | + = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs new file mode 100644 index 0000000000000..0d04101a38307 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs @@ -0,0 +1,12 @@ +// revisions: stock gated +#![cfg_attr(gated, feature(const_trait_impl))] + +const fn foo(input: &'static str) { + match input { + "a" => (), //[gated]~ ERROR can't compare `str` with `str` in const contexts + //~^ ERROR cannot match on `str` in constant functions + _ => (), + } +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr new file mode 100644 index 0000000000000..dcb9b49ea04cf --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr @@ -0,0 +1,13 @@ +error[E0015]: cannot match on `str` in constant functions + --> $DIR/match-non-const-eq.rs:6:9 + | +LL | "a" => (), + | ^^^ + | + = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0015`. From 446db517af476c646844dc7064c3f472068d22f5 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 19 Jun 2023 03:47:27 +0000 Subject: [PATCH 07/11] fix doc --- compiler/rustc_middle/src/mir/syntax.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index fb3841f877687..57ec08bee4db1 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -522,7 +522,7 @@ pub enum CallSource { /// This was from comparison generated by a match, used by const-eval for better errors /// when the comparison cannot be done in compile time. /// - /// See https://github.com/rust-lang/rust/issues/90237. + /// (see ) MatchCmp, /// Other types of desugaring that did not come from the HIR, but we don't care about /// for diagnostics (yet). From 2e8af07a8aa14de595b11841ce655b9e6c271f60 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 18 Jun 2023 23:11:22 +0000 Subject: [PATCH 08/11] Don't consider TAIT normalizable to hidden ty if it would result in impossible item bounds --- compiler/rustc_borrowck/src/type_check/mod.rs | 3 ++- .../rustc_infer/src/infer/opaque_types.rs | 10 ++++---- .../src/solve/eval_ctxt.rs | 13 +++++++--- .../src/solve/opaques.rs | 24 +++++++++++++++---- .../issue-76202-trait-impl-for-tait.rs | 2 ++ 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 33f75437478b5..cbb1c307354f3 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1065,7 +1065,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { )?; ocx.infcx.add_item_bounds_for_hidden_type( - opaque_type_key, + opaque_type_key.def_id.to_def_id(), + opaque_type_key.substs, cause, param_env, hidden_ty.ty, diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 6b8293f90f10a..b19f685a4a455 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -536,7 +536,8 @@ impl<'tcx> InferCtxt<'tcx> { )?; self.add_item_bounds_for_hidden_type( - opaque_type_key, + opaque_type_key.def_id.to_def_id(), + opaque_type_key.substs, cause, param_env, hidden_ty, @@ -598,7 +599,8 @@ impl<'tcx> InferCtxt<'tcx> { pub fn add_item_bounds_for_hidden_type( &self, - OpaqueTypeKey { def_id, substs }: OpaqueTypeKey<'tcx>, + def_id: DefId, + substs: ty::SubstsRef<'tcx>, cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, @@ -631,7 +633,7 @@ impl<'tcx> InferCtxt<'tcx> { // Replace all other mentions of the same opaque type with the hidden type, // as the bounds must hold on the hidden type after all. ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, substs: substs2, .. }) - if def_id.to_def_id() == def_id2 && substs == substs2 => + if def_id == def_id2 && substs == substs2 => { hidden_ty } @@ -640,7 +642,7 @@ impl<'tcx> InferCtxt<'tcx> { ty::Alias( ty::Projection, ty::AliasTy { def_id: def_id2, substs: substs2, .. }, - ) if def_id.to_def_id() == def_id2 && substs == substs2 => hidden_ty, + ) if def_id == def_id2 && substs == substs2 => hidden_ty, _ => ty, }, lt_op: |lt| lt, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 4258f9f6bd28e..106849190e039 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -835,13 +835,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { pub(super) fn add_item_bounds_for_hidden_type( &mut self, - opaque_type_key: OpaqueTypeKey<'tcx>, + opaque_def_id: DefId, + opaque_substs: ty::SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, ) { let mut obligations = Vec::new(); self.infcx.add_item_bounds_for_hidden_type( - opaque_type_key, + opaque_def_id, + opaque_substs, ObligationCause::dummy(), param_env, hidden_ty, @@ -872,7 +874,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ecx.eq(param_env, a, b)?; } ecx.eq(param_env, candidate_ty, ty)?; - ecx.add_item_bounds_for_hidden_type(candidate_key, param_env, candidate_ty); + ecx.add_item_bounds_for_hidden_type( + candidate_key.def_id.to_def_id(), + candidate_key.substs, + param_env, + candidate_ty, + ); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }, |r| CandidateKind::Candidate { name: "opaque type storage".into(), result: *r }, diff --git a/compiler/rustc_trait_selection/src/solve/opaques.rs b/compiler/rustc_trait_selection/src/solve/opaques.rs index 538c16c8ce2cd..16194f5ad69c0 100644 --- a/compiler/rustc_trait_selection/src/solve/opaques.rs +++ b/compiler/rustc_trait_selection/src/solve/opaques.rs @@ -20,8 +20,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let Some(opaque_ty_def_id) = opaque_ty.def_id.as_local() else { return Err(NoSolution); }; - let opaque_ty = - ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs }; // FIXME: at some point we should call queries without defining // new opaque types but having the existing opaque type definitions. // This will require moving this below "Prefer opaques registered already". @@ -41,7 +39,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(()) => {} } // Prefer opaques registered already. - let matches = self.unify_existing_opaque_tys(goal.param_env, opaque_ty, expected); + let opaque_type_key = + ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs }; + let matches = + self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected); if !matches.is_empty() { if let Some(response) = self.try_merge_responses(&matches) { return Ok(response); @@ -50,11 +51,24 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } // Otherwise, define a new opaque type - self.insert_hidden_type(opaque_ty, goal.param_env, expected)?; - self.add_item_bounds_for_hidden_type(opaque_ty, goal.param_env, expected); + self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?; + self.add_item_bounds_for_hidden_type( + opaque_ty.def_id, + opaque_ty.substs, + goal.param_env, + expected, + ); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } (Reveal::UserFacing, SolverMode::Coherence) => { + // An impossible opaque type bound is the only way this goal will fail + // e.g. assigning `impl Copy := NotCopy` + self.add_item_bounds_for_hidden_type( + opaque_ty.def_id, + opaque_ty.substs, + goal.param_env, + expected, + ); self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } (Reveal::All, _) => { diff --git a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs index b97e444c6d0e0..386b77d4d1618 100644 --- a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs +++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs @@ -1,6 +1,8 @@ // Regression test for issue #76202 // Tests that we don't ICE when we have a trait impl on a TAIT. +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next // check-pass #![feature(type_alias_impl_trait)] From 75e236375a50f0abcf455b34077dd97bae8cf4a3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Jun 2023 17:09:13 +0200 Subject: [PATCH 09/11] Clean up "doc(hidden)" check --- src/librustdoc/clean/mod.rs | 6 +++--- src/librustdoc/clean/types.rs | 8 ++++++++ src/librustdoc/passes/strip_hidden.rs | 4 ++-- src/librustdoc/passes/stripper.rs | 9 ++++----- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 29c11e1f3359d..851002d5e7965 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -54,7 +54,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< let mut inserted = FxHashSet::default(); items.extend(doc.foreigns.iter().map(|(item, renamed)| { let item = clean_maybe_renamed_foreign_item(cx, item, *renamed); - if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) { + if let Some(name) = item.name && !item.is_doc_hidden() { inserted.insert((item.type_(), name)); } item @@ -64,7 +64,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< return None; } let item = clean_doc_module(x, cx); - if item.attrs.lists(sym::doc).has_word(sym::hidden) { + if item.is_doc_hidden() { // Hidden modules are stripped at a later stage. // If a hidden module has the same name as a visible one, we want // to keep both of them around. @@ -85,7 +85,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< } let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id); for item in &v { - if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) { + if let Some(name) = item.name && !item.is_doc_hidden() { inserted.insert((item.type_(), name)); } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 1999a6b671d3a..fc5f03568a942 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -783,6 +783,10 @@ impl Item { } attrs } + + pub fn is_doc_hidden(&self) -> bool { + self.attrs.is_doc_hidden() + } } #[derive(Clone, Debug)] @@ -1129,6 +1133,10 @@ impl Attributes { false } + fn is_doc_hidden(&self) -> bool { + self.has_doc_flag(sym::hidden) + } + pub(crate) fn from_ast(attrs: &[ast::Attribute]) -> Attributes { Attributes::from_ast_iter(attrs.iter().map(|attr| (attr, None)), false) } diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 972b0c5ec190e..e2e38d3e79f73 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -6,7 +6,7 @@ use rustc_span::symbol::sym; use std::mem; use crate::clean; -use crate::clean::{Item, ItemIdSet, NestedAttributesExt}; +use crate::clean::{Item, ItemIdSet}; use crate::core::DocContext; use crate::fold::{strip_item, DocFolder}; use crate::passes::{ImplStripper, Pass}; @@ -85,7 +85,7 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> { impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { fn fold_item(&mut self, i: Item) -> Option { - let has_doc_hidden = i.attrs.lists(sym::doc).has_word(sym::hidden); + let has_doc_hidden = i.is_doc_hidden(); let is_impl_or_exported_macro = match *i.kind { clean::ImplItem(..) => true, // If the macro has the `#[macro_export]` attribute, it means it's accessible at the diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 73fc26a6b043a..90c361d9d2812 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -1,10 +1,9 @@ //! A collection of utility functions for the `strip_*` passes. use rustc_hir::def_id::DefId; use rustc_middle::ty::{TyCtxt, Visibility}; -use rustc_span::symbol::sym; use std::mem; -use crate::clean::{self, Item, ItemId, ItemIdSet, NestedAttributesExt}; +use crate::clean::{self, Item, ItemId, ItemIdSet}; use crate::fold::{strip_item, DocFolder}; use crate::formats::cache::Cache; use crate::visit_lib::RustdocEffectiveVisibilities; @@ -163,7 +162,7 @@ impl<'a> ImplStripper<'a, '_> { // If the "for" item is exported and the impl block isn't `#[doc(hidden)]`, then we // need to keep it. self.cache.effective_visibilities.is_exported(self.tcx, for_def_id) - && !item.attrs.lists(sym::doc).has_word(sym::hidden) + && !item.is_doc_hidden() } else { false } @@ -240,7 +239,7 @@ impl<'tcx> ImportStripper<'tcx> { // FIXME: This should be handled the same way as for HTML output. imp.imported_item_is_doc_hidden(self.tcx) } else { - i.attrs.lists(sym::doc).has_word(sym::hidden) + i.is_doc_hidden() } } } @@ -249,7 +248,7 @@ impl<'tcx> DocFolder for ImportStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { clean::ImportItem(imp) if self.import_should_be_hidden(&i, &imp) => None, - clean::ImportItem(_) if i.attrs.lists(sym::doc).has_word(sym::hidden) => None, + clean::ImportItem(_) if i.is_doc_hidden() => None, clean::ExternCrateItem { .. } | clean::ImportItem(..) if i.visibility(self.tcx) != Some(Visibility::Public) => { From 13aa0dc1c7cf4dd4d0e527d47741f7ace790dcc3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 19 Jun 2023 10:06:10 +0000 Subject: [PATCH 10/11] Add gha problem matcher --- src/ci/github-actions/problem_matchers.json | 40 +++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/ci/github-actions/problem_matchers.json b/src/ci/github-actions/problem_matchers.json index 37561924b7d4f..b6c7ace841e59 100644 --- a/src/ci/github-actions/problem_matchers.json +++ b/src/ci/github-actions/problem_matchers.json @@ -10,6 +10,46 @@ "message": 3 } ] + }, + { + "owner": "cargo-common", + "pattern": [ + { + "regexp": "^(warning|warn|error)(\\[(\\S*)\\])?: (.*)$", + "severity": 1, + "message": 4, + "code": 3 + }, + { + "regexp": "^\\s+-->\\s(\\S+):(\\d+):(\\d+)$", + "file": 1, + "line": 2, + "column": 3 + } + ] + }, + { + "owner": "compiler-panic", + "pattern": [ + { + "regexp": "error: internal compiler error: (.*):(\\d+):(\\d+): (.*)$", + "message": 4, + "file": 1, + "line": 2, + "column": 3 + } + ] + }, + { + "owner": "cargo-fmt", + "pattern": [ + { + "regexp": "^(Diff in (\\S+)) at line (\\d+):", + "message": 1, + "file": 2, + "line": 3 + } + ] } ] } From 86b7750ada1cc8a355dafe36f6a4bc5cebb8737e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 19 Jun 2023 16:54:28 +0000 Subject: [PATCH 11/11] Format the examples directory of cg_clif Formatting has been enforced in cg_clif's CI for a while now. --- rustfmt.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/rustfmt.toml b/rustfmt.toml index 828d492a3d19c..597ef5b90529e 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -38,6 +38,5 @@ ignore = [ # these are ignored by a standard cargo fmt run "compiler/rustc_codegen_cranelift/y.rs", # running rustfmt breaks this file - "compiler/rustc_codegen_cranelift/example", "compiler/rustc_codegen_cranelift/scripts", ]