From 7d2373e48f9fe91520c3a15cd5cd8bd0820b276f Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 4 Jun 2023 12:10:45 -0500 Subject: [PATCH 1/8] Fix progress messages for configure in bootstrap_test.py Before it would unconditionally print `configure-args = []`. --- src/bootstrap/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index a16f77317c82b..76a153b60a30d 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -280,7 +280,7 @@ def parse_args(args): config = {} - set('build.configure-args', sys.argv[1:], config) + set('build.configure-args', args, config) apply_args(known_args, option_checking, config) return parse_example_config(known_args, config) From 3508cde815941317a8a5ee81c8de9c9854fdb53a Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 4 Jun 2023 12:16:49 -0500 Subject: [PATCH 2/8] Allow passing arguments to `bootstrap_test.py` Previous, it used the built-in test runner, which doesn't support options unless they're manually passed in the script. --- src/bootstrap/bootstrap_test.py | 16 +++------------- src/bootstrap/test.rs | 7 ++++++- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 5ecda83ee66b1..a0c296dc19cc1 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -1,4 +1,6 @@ -"""Bootstrap tests""" +"""Bootstrap tests + +Run these with `x test bootstrap`, or `python -m unittest bootstrap_test.py`.""" from __future__ import absolute_import, division, print_function import os @@ -120,15 +122,3 @@ def test_set_codegen_backends(self): build = self.serialize_and_parse(["--enable-full-tools"]) self.assertNotEqual(build.config_toml.find("codegen-backends = ['llvm']"), -1) -if __name__ == '__main__': - SUITE = unittest.TestSuite() - TEST_LOADER = unittest.TestLoader() - SUITE.addTest(doctest.DocTestSuite(bootstrap)) - SUITE.addTests([ - TEST_LOADER.loadTestsFromTestCase(VerifyTestCase), - TEST_LOADER.loadTestsFromTestCase(GenerateAndParseConfig), - TEST_LOADER.loadTestsFromTestCase(ProgramOutOfDate)]) - - RUNNER = unittest.TextTestRunner(stream=sys.stdout, verbosity=2) - result = RUNNER.run(SUITE) - sys.exit(0 if result.wasSuccessful() else 1) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 873ed61daf33c..9cc5a69b920e4 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -2664,7 +2664,12 @@ impl Step for Bootstrap { /// Tests the build system itself. fn run(self, builder: &Builder<'_>) { let mut check_bootstrap = Command::new(&builder.python()); - check_bootstrap.arg("bootstrap_test.py").current_dir(builder.src.join("src/bootstrap/")); + check_bootstrap + .arg("-m") + .arg("unittest") + .arg("bootstrap_test.py") + .current_dir(builder.src.join("src/bootstrap/")) + .args(builder.config.test_args()); try_run(builder, &mut check_bootstrap).unwrap(); let host = builder.config.build; From c5820b50c558943f83a7f8d531f5e96da59989bc Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 4 Jun 2023 12:22:45 -0500 Subject: [PATCH 3/8] Test cargo arguments passed by bootstrap.py This moves a lot of code around, but the logic itself is not too terribly complicated. - Move almost all logic in `def bootstrap` to the `RustBuild` class, to avoid mixing setting configuration with running commands - Update various doctests to the new (more complete) RustBuild config. In particular, don't pretend that `bin_root` supports `build` being unset. - Change `parse_args` not to use a global, to allow testing it - Set BUILD_DIR appropriately so bootstrap.py doesn't panic because cargo isn't found --- src/bootstrap/bootstrap.py | 125 ++++++++++++++++---------------- src/bootstrap/bootstrap_test.py | 76 +++++++++++++------ src/bootstrap/test.rs | 5 +- 3 files changed, 118 insertions(+), 88 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 5714613cdf512..9b8fdd38d22a9 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -458,23 +458,52 @@ def unpack_component(download_info): verbose=download_info.verbose, ) -class RustBuild(object): - """Provide all the methods required to build Rust""" +class FakeArgs: + """Used for unit tests to avoid updating all call sites""" def __init__(self): - self.checksums_sha256 = {} - self.stage0_compiler = None - self.download_url = '' self.build = '' self.build_dir = '' self.clean = False - self.config_toml = '' - self.rust_root = '' - self.use_locked_deps = False - self.use_vendored_sources = False self.verbose = False + self.json_output = False + +class RustBuild(object): + """Provide all the methods required to build Rust""" + def __init__(self, config_toml="", args=FakeArgs()): self.git_version = None self.nix_deps_dir = None self._should_fix_bins_and_dylibs = None + self.rust_root = os.path.abspath(os.path.join(__file__, '../../..')) + + self.config_toml = config_toml + + self.verbose = args.verbose != 0 + self.clean = args.clean + self.json_output = args.json_output + + profile = self.get_toml('profile') + if profile is not None: + include_file = 'config.{}.toml'.format(profile) + include_dir = os.path.join(self.rust_root, 'src', 'bootstrap', 'defaults') + include_path = os.path.join(include_dir, include_file) + # HACK: This works because `self.get_toml()` returns the first match it finds for a + # specific key, so appending our defaults at the end allows the user to override them + with open(include_path) as included_toml: + self.config_toml += os.linesep + included_toml.read() + + self.use_vendored_sources = self.get_toml('vendor', 'build') == 'true' + self.use_locked_deps = self.get_toml('locked-deps', 'build') == 'true' + + build_dir = args.build_dir or self.get_toml('build-dir', 'build') or 'build' + self.build_dir = os.path.abspath(build_dir) + + with open(os.path.join(self.rust_root, "src", "stage0.json")) as f: + data = json.load(f) + self.checksums_sha256 = data["checksums_sha256"] + self.stage0_compiler = Stage0Toolchain(data["compiler"]) + self.download_url = os.getenv("RUSTUP_DIST_SERVER") or data["config"]["dist_server"] + + self.build = args.build or self.build_triple() def download_toolchain(self): """Fetch the build system for Rust, written in Rust @@ -704,9 +733,10 @@ def rustc_stamp(self): """Return the path for .rustc-stamp at the given stage >>> rb = RustBuild() + >>> rb.build = "host" >>> rb.build_dir = "build" - >>> rb.rustc_stamp() == os.path.join("build", "stage0", ".rustc-stamp") - True + >>> expected = os.path.join("build", "host", "stage0", ".rustc-stamp") + >>> assert rb.rustc_stamp() == expected, rb.rustc_stamp() """ return os.path.join(self.bin_root(), '.rustc-stamp') @@ -721,15 +751,9 @@ def bin_root(self): """Return the binary root directory for the given stage >>> rb = RustBuild() - >>> rb.build_dir = "build" - >>> rb.bin_root() == os.path.join("build", "stage0") - True - - When the 'build' property is given should be a nested directory: - >>> rb.build = "devel" - >>> rb.bin_root() == os.path.join("build", "devel", "stage0") - True + >>> expected = os.path.abspath(os.path.join("build", "devel", "stage0")) + >>> assert rb.bin_root() == expected, rb.bin_root() """ subdir = "stage0" return os.path.join(self.build_dir, self.build, subdir) @@ -842,6 +866,16 @@ def build_bootstrap(self, color, warnings, verbose_count): print("::group::Building bootstrap") else: print("Building bootstrap", file=sys.stderr) + + args = self.build_bootstrap_cmd(env, color, warnings, verbose_count) + # Run this from the source directory so cargo finds .cargo/config + run(args, env=env, verbose=self.verbose, cwd=self.rust_root) + + if "GITHUB_ACTIONS" in env: + print("::endgroup::") + + def build_bootstrap_cmd(self, env, color, warnings, verbose_count): + """For tests.""" build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) @@ -927,11 +961,7 @@ def build_bootstrap(self, color, warnings, verbose_count): except KeyError: pass - # Run this from the source directory so cargo finds .cargo/config - run(args, env=env, verbose=self.verbose, cwd=self.rust_root) - - if "GITHUB_ACTIONS" in env: - print("::endgroup::") + return args def build_triple(self): """Build triple as in LLVM @@ -981,7 +1011,7 @@ def check_vendored_status(self): if os.path.exists(cargo_dir): shutil.rmtree(cargo_dir) -def parse_args(): +def parse_args(args): """Parse the command line arguments that the python script needs.""" parser = argparse.ArgumentParser(add_help=False) parser.add_argument('-h', '--help', action='store_true') @@ -994,16 +1024,11 @@ def parse_args(): parser.add_argument('--warnings', choices=['deny', 'warn', 'default'], default='default') parser.add_argument('-v', '--verbose', action='count', default=0) - return parser.parse_known_args(sys.argv)[0] + return parser.parse_known_args(args)[0] def bootstrap(args): """Configure, fetch, build and run the initial bootstrap""" - # Configure initial bootstrap - build = RustBuild() - build.rust_root = os.path.abspath(os.path.join(__file__, '../../..')) - build.verbose = args.verbose != 0 - build.clean = args.clean - build.json_output = args.json_output + rust_root = os.path.abspath(os.path.join(__file__, '../../..')) # Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, # then `config.toml` in the root directory. @@ -1012,45 +1037,23 @@ def bootstrap(args): if using_default_path: toml_path = 'config.toml' if not os.path.exists(toml_path): - toml_path = os.path.join(build.rust_root, toml_path) + toml_path = os.path.join(rust_root, toml_path) # Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path, # but not if `config.toml` hasn't been created. if not using_default_path or os.path.exists(toml_path): with open(toml_path) as config: - build.config_toml = config.read() - - profile = build.get_toml('profile') - if profile is not None: - include_file = 'config.{}.toml'.format(profile) - include_dir = os.path.join(build.rust_root, 'src', 'bootstrap', 'defaults') - include_path = os.path.join(include_dir, include_file) - # HACK: This works because `build.get_toml()` returns the first match it finds for a - # specific key, so appending our defaults at the end allows the user to override them - with open(include_path) as included_toml: - build.config_toml += os.linesep + included_toml.read() + config_toml = config.read() + + # Configure initial bootstrap + build = RustBuild(config_toml, args) + build.check_vendored_status() verbose_count = args.verbose config_verbose_count = build.get_toml('verbose', 'build') if config_verbose_count is not None: verbose_count = max(args.verbose, int(config_verbose_count)) - build.use_vendored_sources = build.get_toml('vendor', 'build') == 'true' - build.use_locked_deps = build.get_toml('locked-deps', 'build') == 'true' - - build.check_vendored_status() - - build_dir = args.build_dir or build.get_toml('build-dir', 'build') or 'build' - build.build_dir = os.path.abspath(build_dir) - - with open(os.path.join(build.rust_root, "src", "stage0.json")) as f: - data = json.load(f) - build.checksums_sha256 = data["checksums_sha256"] - build.stage0_compiler = Stage0Toolchain(data["compiler"]) - build.download_url = os.getenv("RUSTUP_DIST_SERVER") or data["config"]["dist_server"] - - build.build = args.build or build.build_triple() - if not os.path.exists(build.build_dir): os.makedirs(build.build_dir) @@ -1077,7 +1080,7 @@ def main(): if len(sys.argv) > 1 and sys.argv[1] == 'help': sys.argv[1] = '-h' - args = parse_args() + args = parse_args(sys.argv) help_triggered = args.help or len(sys.argv) == 1 # If the user is asking for help, let them know that the whole download-and-build diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index a0c296dc19cc1..6854aafa1c049 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -15,6 +15,23 @@ import bootstrap import configure +def serialize_and_parse(args): + from io import StringIO + + section_order, sections, targets = configure.parse_args(args) + buffer = StringIO() + configure.write_config_toml(buffer, section_order, targets, sections) + build = bootstrap.RustBuild() + build.config_toml = buffer.getvalue() + + try: + import tomllib + # Verify this is actually valid TOML. + tomllib.loads(build.config_toml) + except ImportError: + print("warning: skipping TOML validation, need at least python 3.11", file=sys.stderr) + return build + class VerifyTestCase(unittest.TestCase): """Test Case for verify""" @@ -79,46 +96,57 @@ def test_same_dates(self): class GenerateAndParseConfig(unittest.TestCase): """Test that we can serialize and deserialize a config.toml file""" - def serialize_and_parse(self, args): - from io import StringIO - - section_order, sections, targets = configure.parse_args(args) - buffer = StringIO() - configure.write_config_toml(buffer, section_order, targets, sections) - build = bootstrap.RustBuild() - build.config_toml = buffer.getvalue() - - try: - import tomllib - # Verify this is actually valid TOML. - tomllib.loads(build.config_toml) - except ImportError: - print("warning: skipping TOML validation, need at least python 3.11", file=sys.stderr) - return build - def test_no_args(self): - build = self.serialize_and_parse([]) + build = serialize_and_parse([]) self.assertEqual(build.get_toml("changelog-seen"), '2') self.assertEqual(build.get_toml("profile"), 'user') self.assertIsNone(build.get_toml("llvm.download-ci-llvm")) def test_set_section(self): - build = self.serialize_and_parse(["--set", "llvm.download-ci-llvm"]) + build = serialize_and_parse(["--set", "llvm.download-ci-llvm"]) self.assertEqual(build.get_toml("download-ci-llvm", section="llvm"), 'true') def test_set_target(self): - build = self.serialize_and_parse(["--set", "target.x86_64-unknown-linux-gnu.cc=gcc"]) + build = serialize_and_parse(["--set", "target.x86_64-unknown-linux-gnu.cc=gcc"]) self.assertEqual(build.get_toml("cc", section="target.x86_64-unknown-linux-gnu"), 'gcc') def test_set_top_level(self): - build = self.serialize_and_parse(["--set", "profile=compiler"]) + build = serialize_and_parse(["--set", "profile=compiler"]) self.assertEqual(build.get_toml("profile"), 'compiler') def test_set_codegen_backends(self): - build = self.serialize_and_parse(["--set", "rust.codegen-backends=cranelift"]) + build = serialize_and_parse(["--set", "rust.codegen-backends=cranelift"]) self.assertNotEqual(build.config_toml.find("codegen-backends = ['cranelift']"), -1) - build = self.serialize_and_parse(["--set", "rust.codegen-backends=cranelift,llvm"]) + build = serialize_and_parse(["--set", "rust.codegen-backends=cranelift,llvm"]) self.assertNotEqual(build.config_toml.find("codegen-backends = ['cranelift', 'llvm']"), -1) - build = self.serialize_and_parse(["--enable-full-tools"]) + build = serialize_and_parse(["--enable-full-tools"]) self.assertNotEqual(build.config_toml.find("codegen-backends = ['llvm']"), -1) + +class BuildBootstrap(unittest.TestCase): + """Test that we generate the appropriate arguments when building bootstrap""" + + def build_args(self, configure_args=[], args=[], env={}): + env = env.copy() + env["PATH"] = os.environ["PATH"] + + build = serialize_and_parse(configure_args) + build.build_dir = os.environ["BUILD_DIR"] + parsed = bootstrap.parse_args(args) + return build.build_bootstrap_cmd(env, parsed.color, parsed.warnings, parsed.verbose), env + + def test_cargoflags(self): + args, _ = self.build_args(env={"CARGOFLAGS": "--timings"}) + self.assertTrue("--timings" in args) + + def test_warnings(self): + for toml_warnings in ['false', 'true', None]: + configure_args = [] + if toml_warnings is not None: + configure_args = ["--set", "rust.deny-warnings=" + toml_warnings] + + _, env = self.build_args(configure_args, args=["--warnings=warn"]) + self.assertFalse("-Dwarnings" in env["RUSTFLAGS"]) + + _, env = self.build_args(configure_args, args=["--warnings=deny"]) + self.assertTrue("-Dwarnings" in env["RUSTFLAGS"]) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 9cc5a69b920e4..9f0f24e0f7b22 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -2665,9 +2665,8 @@ impl Step for Bootstrap { fn run(self, builder: &Builder<'_>) { let mut check_bootstrap = Command::new(&builder.python()); check_bootstrap - .arg("-m") - .arg("unittest") - .arg("bootstrap_test.py") + .args(["-m", "unittest", "bootstrap_test.py"]) + .env("BUILD_DIR", &builder.out) .current_dir(builder.src.join("src/bootstrap/")) .args(builder.config.test_args()); try_run(builder, &mut check_bootstrap).unwrap(); From c7af6fb5b8d75bc767c05585a63a0d075d8c3e5f Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 4 Jun 2023 12:50:15 -0500 Subject: [PATCH 4/8] Test color/verbose/warnings properly These weren't being passed in to bootstrap consistently before; in particular `serialize_and_parse` forgot to pass them in. --- src/bootstrap/bootstrap.py | 34 ++++++++++++++++++--------------- src/bootstrap/bootstrap_test.py | 13 ++++++------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 9b8fdd38d22a9..6d215224abfd9 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -466,6 +466,8 @@ def __init__(self): self.clean = False self.verbose = False self.json_output = False + self.color = 'auto' + self.warnings = 'default' class RustBuild(object): """Provide all the methods required to build Rust""" @@ -477,9 +479,11 @@ def __init__(self, config_toml="", args=FakeArgs()): self.config_toml = config_toml - self.verbose = args.verbose != 0 self.clean = args.clean self.json_output = args.json_output + self.verbose = args.verbose + self.color = args.color + self.warnings = args.warnings profile = self.get_toml('profile') if profile is not None: @@ -491,6 +495,10 @@ def __init__(self, config_toml="", args=FakeArgs()): with open(include_path) as included_toml: self.config_toml += os.linesep + included_toml.read() + config_verbose_count = self.get_toml('verbose', 'build') + if config_verbose_count is not None: + self.verbose = max(self.verbose, int(config_verbose_count)) + self.use_vendored_sources = self.get_toml('vendor', 'build') == 'true' self.use_locked_deps = self.get_toml('locked-deps', 'build') == 'true' @@ -505,6 +513,7 @@ def __init__(self, config_toml="", args=FakeArgs()): self.build = args.build or self.build_triple() + def download_toolchain(self): """Fetch the build system for Rust, written in Rust @@ -859,7 +868,7 @@ def bootstrap_binary(self): """ return os.path.join(self.build_dir, "bootstrap", "debug", "bootstrap") - def build_bootstrap(self, color, warnings, verbose_count): + def build_bootstrap(self): """Build bootstrap""" env = os.environ.copy() if "GITHUB_ACTIONS" in env: @@ -867,14 +876,14 @@ def build_bootstrap(self, color, warnings, verbose_count): else: print("Building bootstrap", file=sys.stderr) - args = self.build_bootstrap_cmd(env, color, warnings, verbose_count) + args = self.build_bootstrap_cmd(env) # Run this from the source directory so cargo finds .cargo/config run(args, env=env, verbose=self.verbose, cwd=self.rust_root) if "GITHUB_ACTIONS" in env: print("::endgroup::") - def build_bootstrap_cmd(self, env, color, warnings, verbose_count): + def build_bootstrap_cmd(self, env): """For tests.""" build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): @@ -928,10 +937,10 @@ def build_bootstrap_cmd(self, env, color, warnings, verbose_count): if target_linker is not None: env["RUSTFLAGS"] += " -C linker=" + target_linker env["RUSTFLAGS"] += " -Wrust_2018_idioms -Wunused_lifetimes" - if warnings == "default": + if self.warnings == "default": deny_warnings = self.get_toml("deny-warnings", "rust") != "false" else: - deny_warnings = warnings == "deny" + deny_warnings = self.warnings == "deny" if deny_warnings: env["RUSTFLAGS"] += " -Dwarnings" @@ -942,7 +951,7 @@ def build_bootstrap_cmd(self, env, color, warnings, verbose_count): self.cargo())) args = [self.cargo(), "build", "--manifest-path", os.path.join(self.rust_root, "src/bootstrap/Cargo.toml")] - args.extend("--verbose" for _ in range(verbose_count)) + args.extend("--verbose" for _ in range(self.verbose)) if self.use_locked_deps: args.append("--locked") if self.use_vendored_sources: @@ -952,9 +961,9 @@ def build_bootstrap_cmd(self, env, color, warnings, verbose_count): args.append("build-metrics") if self.json_output: args.append("--message-format=json") - if color == "always": + if self.color == "always": args.append("--color=always") - elif color == "never": + elif self.color == "never": args.append("--color=never") try: args += env["CARGOFLAGS"].split() @@ -1049,18 +1058,13 @@ def bootstrap(args): build = RustBuild(config_toml, args) build.check_vendored_status() - verbose_count = args.verbose - config_verbose_count = build.get_toml('verbose', 'build') - if config_verbose_count is not None: - verbose_count = max(args.verbose, int(config_verbose_count)) - if not os.path.exists(build.build_dir): os.makedirs(build.build_dir) # Fetch/build the bootstrap build.download_toolchain() sys.stdout.flush() - build.build_bootstrap(args.color, args.warnings, verbose_count) + build.build_bootstrap() sys.stdout.flush() # Run the bootstrap diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 6854aafa1c049..167b11d421eaf 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -15,14 +15,13 @@ import bootstrap import configure -def serialize_and_parse(args): +def serialize_and_parse(configure_args, bootstrap_args=bootstrap.FakeArgs()): from io import StringIO - section_order, sections, targets = configure.parse_args(args) + section_order, sections, targets = configure.parse_args(configure_args) buffer = StringIO() configure.write_config_toml(buffer, section_order, targets, sections) - build = bootstrap.RustBuild() - build.config_toml = buffer.getvalue() + build = bootstrap.RustBuild(config_toml=buffer.getvalue(), args=bootstrap_args) try: import tomllib @@ -130,10 +129,10 @@ def build_args(self, configure_args=[], args=[], env={}): env = env.copy() env["PATH"] = os.environ["PATH"] - build = serialize_and_parse(configure_args) - build.build_dir = os.environ["BUILD_DIR"] parsed = bootstrap.parse_args(args) - return build.build_bootstrap_cmd(env, parsed.color, parsed.warnings, parsed.verbose), env + build = serialize_and_parse(configure_args, parsed) + build.build_dir = os.environ["BUILD_DIR"] + return build.build_bootstrap_cmd(env), env def test_cargoflags(self): args, _ = self.build_args(env={"CARGOFLAGS": "--timings"}) From 24e67d51a0fbf20910e19045e038fe646e5b0910 Mon Sep 17 00:00:00 2001 From: jyn Date: Thu, 8 Jun 2023 21:30:04 -0500 Subject: [PATCH 5/8] Don't test the profile override hack It generates invalid TOML. I want to get rid of it eventually, but this avoids the issue in the meantime. --- src/bootstrap/bootstrap.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 6d215224abfd9..3dae37ca35020 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -485,16 +485,6 @@ def __init__(self, config_toml="", args=FakeArgs()): self.color = args.color self.warnings = args.warnings - profile = self.get_toml('profile') - if profile is not None: - include_file = 'config.{}.toml'.format(profile) - include_dir = os.path.join(self.rust_root, 'src', 'bootstrap', 'defaults') - include_path = os.path.join(include_dir, include_file) - # HACK: This works because `self.get_toml()` returns the first match it finds for a - # specific key, so appending our defaults at the end allows the user to override them - with open(include_path) as included_toml: - self.config_toml += os.linesep + included_toml.read() - config_verbose_count = self.get_toml('verbose', 'build') if config_verbose_count is not None: self.verbose = max(self.verbose, int(config_verbose_count)) @@ -794,9 +784,12 @@ def get_toml(self, key, section=None): >>> rb.get_toml("key1") 'true' """ + return RustBuild.get_toml_static(self.config_toml, key, section) + @staticmethod + def get_toml_static(config_toml, key, section=None): cur_section = None - for line in self.config_toml.splitlines(): + for line in config_toml.splitlines(): section_match = re.match(r'^\s*\[(.*)\]\s*$', line) if section_match is not None: cur_section = section_match.group(1) @@ -805,7 +798,7 @@ def get_toml(self, key, section=None): if match is not None: value = match.group(1) if section is None or section == cur_section: - return self.get_string(value) or value.strip() + return RustBuild.get_string(value) or value.strip() return None def cargo(self): @@ -1054,6 +1047,16 @@ def bootstrap(args): with open(toml_path) as config: config_toml = config.read() + profile = RustBuild.get_toml_static(config_toml, 'profile') + if profile is not None: + include_file = 'config.{}.toml'.format(profile) + include_dir = os.path.join(rust_root, 'src', 'bootstrap', 'defaults') + include_path = os.path.join(include_dir, include_file) + # HACK: This works because `self.get_toml()` returns the first match it finds for a + # specific key, so appending our defaults at the end allows the user to override them + with open(include_path) as included_toml: + config_toml += os.linesep + included_toml.read() + # Configure initial bootstrap build = RustBuild(config_toml, args) build.check_vendored_status() From 247aa06f106d6b88ca5d48333164797c2d35acd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 25 Jun 2023 15:37:39 +0200 Subject: [PATCH 6/8] rustdoc: handle assoc const equalities in cross-crate impl-Trait-in-arg-pos --- src/librustdoc/clean/mod.rs | 18 +++++------------- .../inline_cross/assoc-const-equality.rs | 8 ++++++++ .../auxiliary/assoc-const-equality.rs | 7 +++++++ 3 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 tests/rustdoc/inline_cross/assoc-const-equality.rs create mode 100644 tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f86c32158e0b3..fdd3fc38b0b05 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -791,10 +791,10 @@ fn clean_ty_generics<'tcx>( }) .collect::>(); - // param index -> [(trait DefId, associated type name & generics, type, higher-ranked params)] + // param index -> [(trait DefId, associated type name & generics, term, higher-ranked params)] let mut impl_trait_proj = FxHashMap::< u32, - Vec<(DefId, PathSegment, ty::Binder<'_, Ty<'_>>, Vec)>, + Vec<(DefId, PathSegment, ty::Binder<'_, ty::Term<'_>>, Vec)>, >::default(); let where_predicates = preds @@ -852,11 +852,10 @@ fn clean_ty_generics<'tcx>( .as_ref() .and_then(|(lhs, rhs): &(Type, _)| Some((lhs.projection()?, rhs))) { - // FIXME(...): Remove this unwrap() impl_trait_proj.entry(param_idx).or_default().push(( trait_did, name, - rhs.map_bound(|rhs| rhs.ty().unwrap()), + *rhs, p.get_bound_params() .into_iter() .flatten() @@ -879,15 +878,8 @@ fn clean_ty_generics<'tcx>( let crate::core::ImplTraitParam::ParamIndex(idx) = param else { unreachable!() }; if let Some(proj) = impl_trait_proj.remove(&idx) { for (trait_did, name, rhs, bound_params) in proj { - let rhs = clean_middle_ty(rhs, cx, None, None); - simplify::merge_bounds( - cx, - &mut bounds, - bound_params, - trait_did, - name, - &Term::Type(rhs), - ); + let rhs = clean_middle_term(rhs, cx); + simplify::merge_bounds(cx, &mut bounds, bound_params, trait_did, name, &rhs); } } diff --git a/tests/rustdoc/inline_cross/assoc-const-equality.rs b/tests/rustdoc/inline_cross/assoc-const-equality.rs new file mode 100644 index 0000000000000..1d3ce9e3172f0 --- /dev/null +++ b/tests/rustdoc/inline_cross/assoc-const-equality.rs @@ -0,0 +1,8 @@ +// aux-crate:assoc_const_equality=assoc-const-equality.rs +// edition:2021 + +#![crate_name = "user"] + +// @has user/fn.accept.html +// @has - '//pre[@class="rust item-decl"]' 'fn accept(_: impl Trait)' +pub use assoc_const_equality::accept; diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs new file mode 100644 index 0000000000000..6a25dcea62e2e --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs @@ -0,0 +1,7 @@ +#![feature(associated_const_equality)] + +pub fn accept(_: impl Trait) {} + +pub trait Trait { + const K: i32; +} From cb06c973c7e012517adca311d08572bcb548f510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 25 Jun 2023 15:55:27 +0200 Subject: [PATCH 7/8] CI: do not run Bump dependencies workflow on forks --- .github/workflows/dependencies.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 2eccd28e5bb1f..26d2ba636f3e3 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -25,6 +25,7 @@ env: jobs: not-waiting-on-bors: + if: github.repository_owner == 'rust-lang' name: skip if S-waiting-on-bors runs-on: ubuntu-latest steps: @@ -43,6 +44,7 @@ jobs: fi update: + if: github.repository_owner == 'rust-lang' name: update dependencies needs: not-waiting-on-bors runs-on: ubuntu-latest @@ -76,6 +78,7 @@ jobs: retention-days: 1 pr: + if: github.repository_owner == 'rust-lang' name: amend PR needs: update runs-on: ubuntu-latest From 1e7f03718b3e1c19e59afff518d80d3717b785b9 Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 25 Jun 2023 10:01:04 -0500 Subject: [PATCH 8/8] fix some bugs - fix tests when `--build` is set - don't leak `config.example.toml` fd - don't crash if `config.toml` doesn't exist yet --- src/bootstrap/bootstrap.py | 2 ++ src/bootstrap/bootstrap_test.py | 1 + src/bootstrap/configure.py | 4 +++- src/bootstrap/test.rs | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 3dae37ca35020..53a762cd0a8c7 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -1046,6 +1046,8 @@ def bootstrap(args): if not using_default_path or os.path.exists(toml_path): with open(toml_path) as config: config_toml = config.read() + else: + config_toml = '' profile = RustBuild.get_toml_static(config_toml, 'profile') if profile is not None: diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 167b11d421eaf..815b32eb991b1 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -132,6 +132,7 @@ def build_args(self, configure_args=[], args=[], env={}): parsed = bootstrap.parse_args(args) build = serialize_and_parse(configure_args, parsed) build.build_dir = os.environ["BUILD_DIR"] + build.build = os.environ["BUILD_PLATFORM"] return build.build_bootstrap_cmd(env), env def test_cargoflags(self): diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 76a153b60a30d..a5a1385dc0d64 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -400,7 +400,9 @@ def parse_example_config(known_args, config): targets = {} top_level_keys = [] - for line in open(rust_dir + '/config.example.toml').read().split("\n"): + with open(rust_dir + '/config.example.toml') as example_config: + example_lines = example_config.read().split("\n") + for line in example_lines: if cur_section is None: if line.count('=') == 1: top_level_key = line.split('=')[0] diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 9f0f24e0f7b22..bdc6b4de6cdc0 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -2667,6 +2667,7 @@ impl Step for Bootstrap { check_bootstrap .args(["-m", "unittest", "bootstrap_test.py"]) .env("BUILD_DIR", &builder.out) + .env("BUILD_PLATFORM", &builder.build.build.triple) .current_dir(builder.src.join("src/bootstrap/")) .args(builder.config.test_args()); try_run(builder, &mut check_bootstrap).unwrap();