From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by sourceware.org (Postfix) with ESMTPS id 7F7393945C22 for ; Tue, 31 Jan 2023 13:23:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7F7393945C22 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wm1-x32e.google.com with SMTP id iv8-20020a05600c548800b003db04a0a46bso900898wmb.0 for ; Tue, 31 Jan 2023 05:23:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=DkbxqWeBg6d/cBqfllxshmU9Tx2T1fenmXLpzbumItg=; b=S0EPG0YaNkDHDYjEOTFlmL1lM1piWhOOfajOynM8OmveA3v8o5Xztc6RG0metM8pu1 aDfVm44291Nn3249W1yLxfr3JIE4XgGFTfc5uDe7xVWI8eM+FGi3jqrg4mcoe77sErFk xGHxN+ELgNKBslAhtNhqQdF9LDqmgkwH1YUkkTH2wHawXDQvCYB3lYjdppK4sXVBES+W gi4t6PRdL6stexqUaP1wQH8Iw81Znxrai1mj4n6v+9Ucadq32UhSEWqLBoZUFWVosnt+ ItW6Eo3CKF7nEg/uQ3ojnSmUsuGa2DoE8qKU+aHY/0SlGgGiw32G9NjrbhJp6o/nvhKu RzQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=DkbxqWeBg6d/cBqfllxshmU9Tx2T1fenmXLpzbumItg=; b=i4tVtDIOLWq+h2F3jIg9PAAcvHAYROSSMg5i8pfMOhZIfSokfAknlXtM7adQjdMpjJ lftqUjOeJRWfUngklVwnwM67Wno9fNAH81vxLQpE4Ez3NLu3fmLk+1ud26gqSbENTXz/ bXvkUfPfW1kGOB6mSF9ibIynRwQV07wFcInADGk+fGkQqFyj9q95D7J9t6DR1KZeVEoa Un7He2Gac374yfrzCjaDQjYvkkU9cNv4+0jUlYfmEgTDcAAQChAylCwIEYoQpDkWyXmo AupNcDtGkM5aYq+hpTAQxaLNJJzIlk02IeFurh0HDn/8BtFsMGdJtkyvFI5MfNzAS4qi jRzA== X-Gm-Message-State: AO0yUKXzHqyyCLC8J3LBuqYEXZIevN6e2vQ4kfDKKr47KGA6m/fJ21ay Gn1EOLhC36C46TxNz51+Od8cHU2k2d5TFInIEQ== X-Google-Smtp-Source: AK7set96SQ8TTPNqzwGcYS9Fhs1bHNEIWVPnVBmapMtYoJctcTJ1Rt720pqY5OS6Tz23FjrTo2f+Rw== X-Received: by 2002:a05:600c:511c:b0:3dc:5240:53b6 with SMTP id o28-20020a05600c511c00b003dc524053b6mr9802084wms.6.1675171391078; Tue, 31 Jan 2023 05:23:11 -0800 (PST) Received: from platypus.lan ([2001:861:5e4c:3bb0:6424:328a:1734:3249]) by smtp.gmail.com with ESMTPSA id c3-20020a1c3503000000b003dc1d668866sm19210932wma.10.2023.01.31.05.23.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Jan 2023 05:23:10 -0800 (PST) From: Arthur Cohen To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Arthur Cohen Subject: [COMMITTED] gccrs: rust: Add -frust-compile-until option Date: Tue, 31 Jan 2023 14:26:56 +0100 Message-Id: <20230131132656.663600-1-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-15.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This option helps ensure that we do not introduce regressions on various parts of the compilation pipeline. For example, a testcase (or testsuite from the `testing` project) might pass attribute checking, expansion and lowering, but fail during typechecking. Should a change suddenly make that testcase fail expansion, we would not be able to notice it. By generating tests that run up until expansion, typechecking, compilation and so forth we ensure that no regressions are added accidentally to already failing tests/testsuites. gcc/rust/ChangeLog: * lang.opt: Add new ``-frust-compile-until` option. * rust-session-manager.cc (Session::compile_crate): Add stops around various compilation steps in the pipeline. * rust-session-manager.h (struct CompileOptions): Add `CompileStep` enum and field. gcc/testsuite/ChangeLog: * rust/compile/frust-compile-until.rs: New test. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/rust/lang.opt | 42 +++++++++++++++++++ gcc/rust/rust-session-manager.cc | 36 +++++++++++++++- gcc/rust/rust-session-manager.h | 25 ++++++++++- .../rust/compile/frust-compile-until.rs | 7 ++++ 4 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/rust/compile/frust-compile-until.rs diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt index 3e6826954da..40aafaf34d2 100644 --- a/gcc/rust/lang.opt +++ b/gcc/rust/lang.opt @@ -117,6 +117,48 @@ Rust Joined RejectNegative o Rust Joined Separate + +frust-compile-until= +Rust Joined RejectNegative Enum(frust_compile_until) Var(flag_rust_compile_until) +-frust-compile-until=[ast|attributecheck|expansion|nameresolution|lowering|typecheck|privacy|unsafety|const|copimlation|end] When to stop in the pipeline when compiling Rust code + +Enum +Name(frust_compile_until) Type(int) UnknownError(unknown rust compile-until %qs) + +EnumValue +Enum(frust_compile_until) String(ast) Value(0) + +EnumValue +Enum(frust_compile_until) String(attributecheck) Value(1) + +EnumValue +Enum(frust_compile_until) String(expansion) Value(2) + +EnumValue +Enum(frust_compile_until) String(nameresolution) Value(3) + +EnumValue +Enum(frust_compile_until) String(lowering) Value(4) + +EnumValue +Enum(frust_compile_until) String(typecheck) Value(5) + +EnumValue +Enum(frust_compile_until) String(privacy) Value(6) + +EnumValue +Enum(frust_compile_until) String(unsafety) Value(7) + +EnumValue +Enum(frust_compile_until) String(const) Value(8) + +EnumValue +Enum(frust_compile_until) String(compilation) Value(9) + +EnumValue +Enum(frust_compile_until) String(end) Value(10) + + ; Documented in common.opt ; This comment is to ensure we retain the blank line above. diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 157f5099155..4ee7175b48b 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -223,7 +223,9 @@ Session::handle_option ( case OPT_frust_edition_: options.set_edition (flag_rust_edition); break; - + case OPT_frust_compile_until_: + options.set_compile_step (flag_rust_compile_until); + break; case OPT_frust_metadata_output_: options.set_metadata_output (arg); break; @@ -447,6 +449,8 @@ Session::compile_crate (const char *filename) return; } + auto last_step = options.get_compile_until (); + // parse file here /* create lexer and parser - these are file-specific and so aren't instance * variables */ @@ -503,7 +507,7 @@ Session::compile_crate (const char *filename) // If -fsyntax-only was passed, we can just skip the remaining passes. // Parsing errors are already emitted in `parse_crate()` - if (flag_syntax_only) + if (flag_syntax_only || last_step == CompileOptions::CompileStep::Ast) return; // register plugins pipeline stage @@ -522,8 +526,14 @@ Session::compile_crate (const char *filename) // TODO: what do I dump here? injected crate names? } + if (last_step == CompileOptions::CompileStep::AttributeCheck) + return; + Analysis::AttributeChecker ().go (parsed_crate); + if (last_step == CompileOptions::CompileStep::Expansion) + return; + // expansion pipeline stage expansion (parsed_crate); rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m"); @@ -536,6 +546,9 @@ Session::compile_crate (const char *filename) rust_debug ("END POST-EXPANSION AST DUMP"); } + if (last_step == CompileOptions::CompileStep::NameResolution) + return; + // resolution pipeline stage Resolver::NameResolution::Resolve (parsed_crate); if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP)) @@ -546,6 +559,9 @@ Session::compile_crate (const char *filename) if (saw_errors ()) return; + if (last_step == CompileOptions::CompileStep::Lowering) + return; + // lower AST to HIR std::unique_ptr lowered = HIR::ASTLowering::Resolve (parsed_crate); @@ -563,6 +579,9 @@ Session::compile_crate (const char *filename) dump_hir_pretty (hir); } + if (last_step == CompileOptions::CompileStep::TypeCheck) + return; + // type resolve Resolver::TypeResolution::Resolve (hir); if (options.dump_option_enabled (CompileOptions::TYPE_RESOLUTION_DUMP)) @@ -573,17 +592,30 @@ Session::compile_crate (const char *filename) if (saw_errors ()) return; + if (last_step == CompileOptions::CompileStep::Privacy) + return; + // Various HIR error passes. The privacy pass happens before the unsafe checks Privacy::Resolver::resolve (hir); if (saw_errors ()) return; + if (last_step == CompileOptions::CompileStep::Unsafety) + return; + HIR::UnsafeChecker ().go (hir); + + if (last_step == CompileOptions::CompileStep::Const) + return; + HIR::ConstChecker ().go (hir); if (saw_errors ()) return; + if (last_step == CompileOptions::CompileStep::Compilation) + return; + // do compile to gcc generic Compile::Context ctx (backend); Compile::CompileCrate::Compile (hir, &ctx); diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h index db915991809..43f9ba4c72f 100644 --- a/gcc/rust/rust-session-manager.h +++ b/gcc/rust/rust-session-manager.h @@ -199,6 +199,22 @@ struct CompileOptions } edition = Edition::E2015; + enum class CompileStep + { + Ast, + AttributeCheck, + Expansion, + NameResolution, + Lowering, + TypeCheck, + Privacy, + Unsafety, + Const, + Compilation, + End, + } compile_until + = CompileStep::End; + bool dump_option_enabled (DumpOption option) const { return dump_options.find (option) != dump_options.end (); @@ -239,7 +255,14 @@ struct CompileOptions edition = static_cast (raw_edition); } - const Edition &get_edition () { return edition; } + const Edition &get_edition () const { return edition; } + + void set_compile_step (int raw_step) + { + compile_until = static_cast (raw_step); + } + + const CompileStep &get_compile_until () const { return compile_until; } void set_metadata_output (const std::string &path) { diff --git a/gcc/testsuite/rust/compile/frust-compile-until.rs b/gcc/testsuite/rust/compile/frust-compile-until.rs new file mode 100644 index 00000000000..7bb3932ef60 --- /dev/null +++ b/gcc/testsuite/rust/compile/frust-compile-until.rs @@ -0,0 +1,7 @@ +// { dg-additional-options "-frust-compile-until=unsafety" } + +unsafe fn foo() {} + +fn main() { + foo() +} -- 2.39.1