aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-08-31 13:53:28 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2023-01-31 14:16:52 +0100
commit9d6b434e1fda4aaf853728967a6c0f65e7d20d3d (patch)
treeaf3c4c5b5baa1c69366dcb4238842b70dbdd3f2c /gcc/rust
parentf92f8ee75bf0f4a653218a52698263b559c463a4 (diff)
downloadgcc-9d6b434e1fda4aaf853728967a6c0f65e7d20d3d.zip
gcc-9d6b434e1fda4aaf853728967a6c0f65e7d20d3d.tar.gz
gcc-9d6b434e1fda4aaf853728967a6c0f65e7d20d3d.tar.bz2
gccrs: rust: Add -frust-compile-until option
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.
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/lang.opt42
-rw-r--r--gcc/rust/rust-session-manager.cc36
-rw-r--r--gcc/rust/rust-session-manager.h25
3 files changed, 100 insertions, 3 deletions
diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
index 3e68269..40aafaf 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 157f509..4ee7175 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<HIR::Crate> 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 db91599..43f9ba4 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<Edition> (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<CompileStep> (raw_step);
+ }
+
+ const CompileStep &get_compile_until () const { return compile_until; }
void set_metadata_output (const std::string &path)
{