aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/rust-lang.cc36
-rw-r--r--gcc/rust/rust-session-manager.cc23
-rw-r--r--gcc/rust/rust-session-manager.h4
-rw-r--r--gcc/rust/rustspec.cc131
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h11
-rw-r--r--gcc/rust/typecheck/rust-tyty-coercion.h46
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h34
-rw-r--r--gcc/testsuite/rust/compile/issue-1447.rs28
8 files changed, 145 insertions, 168 deletions
diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index dd8c608..95c92f8 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -69,13 +69,11 @@
// Language-dependent contents of a type. GTY() mark used for garbage collector.
struct GTY (()) lang_type
{
- char dummy;
};
// Language-dependent contents of a decl.
struct GTY (()) lang_decl
{
- char dummy;
};
// Language-dependent contents of an identifier. This must include a
@@ -100,7 +98,6 @@ union GTY ((
// We don't use language_function.
struct GTY (()) language_function
{
- int dummy;
};
// has to be in same compilation unit as session, so here for now
@@ -172,7 +169,7 @@ grs_langhook_parse_file (void)
{
rust_debug ("Preparing to parse files. ");
- Rust::Session::get_instance ().parse_files (num_in_fnames, in_fnames);
+ Rust::Session::get_instance ().handle_input_files (num_in_fnames, in_fnames);
}
/* Seems to get the exact type for a specific type - e.g. for scalar float with
@@ -280,32 +277,10 @@ grs_langhook_handle_option (
{
// Convert integer code to lang.opt enum codes with names.
enum opt_code code = (enum opt_code) scode;
- // used to store whether results of various stuff are successful
- // bool ret = true;
- // delegate to session manager
+ // Delegate to session manager
return Rust::Session::get_instance ().handle_option (code, arg, value, kind,
loc, handlers);
-
- // Handles options as listed in lang.opt.
- /*switch (code) {
- case OPT_I:
- // TODO: add search path
- break;
- case OPT_L:
- // TODO: add library link path or something
- break;
- case OPT_frust_dump:
- // enable dump and return whether this was successful
- ret = rust_enable_dump(arg) ? true : false;
- break;
- // no option handling for -o
- default:
- // return 1 to indicate option is valid
- break;
- }
-
- return ret;*/
}
/* Run after parsing options. */
@@ -447,17 +422,10 @@ rust_localize_identifier (const char *ident)
namespace selftest {
-static void
-simple_assert ()
-{
- ASSERT_TRUE (true);
-}
-
void
run_rust_tests ()
{
// Call tests for the rust frontend here
- simple_assert ();
rust_cfg_parser_test ();
rust_privacy_ctx_test ();
rust_crate_name_validation_test ();
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index e3c211e..7d599b1 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -575,13 +575,16 @@ Session::enable_dump (std::string arg)
/* Actual main entry point for front-end. Called from langhook to parse files.
*/
void
-Session::parse_files (int num_files, const char **files)
+Session::handle_input_files (int num_files, const char **files)
{
+ if (num_files != 1)
+ rust_fatal_error (Location (),
+ "only one file may be specified on the command line");
+
+ const auto &file = files[0];
+
if (options.crate_name.empty ())
{
- /* HACK: We use the first file to infer the crate name, which might be
- * incorrect: since rustc only allows one file to be supplied in the
- * command-line */
auto filename = "-";
if (num_files > 0)
filename = files[0];
@@ -595,13 +598,9 @@ Session::parse_files (int num_files, const char **files)
CrateNum crate_num = mappings->get_next_crate_num (options.get_crate_name ());
mappings->set_current_crate (crate_num);
- for (int i = 0; i < num_files; i++)
- {
- rust_debug ("Attempting to parse file: %s", files[i]);
- parse_file (files[i]);
- }
- /* TODO: should semantic analysis be dealed with here? or per file? for now,
- * per-file. */
+
+ rust_debug ("Attempting to parse file: %s", file);
+ compile_crate (file);
}
void
@@ -657,7 +656,7 @@ Session::handle_crate_name (const AST::Crate &parsed_crate)
// Parses a single file with filename filename.
void
-Session::parse_file (const char *filename)
+Session::compile_crate (const char *filename)
{
RAIIFile file_wrap (filename);
if (!file_wrap.ok ())
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 24a15f5..2432de7 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -298,7 +298,7 @@ public:
bool handle_option (enum opt_code code, const char *arg, HOST_WIDE_INT value,
int kind, location_t loc,
const struct cl_option_handlers *handlers);
- void parse_files (int num_files, const char **files);
+ void handle_input_files (int num_files, const char **files);
void init_options ();
void handle_crate_name (const AST::Crate &parsed_crate);
@@ -314,7 +314,7 @@ public:
NodeId load_extern_crate (const std::string &crate_name, Location locus);
private:
- void parse_file (const char *filename);
+ void compile_crate (const char *filename);
bool enable_dump (std::string arg);
void dump_lex (Parser<Lexer> &parser) const;
diff --git a/gcc/rust/rustspec.cc b/gcc/rust/rustspec.cc
index a504602..b05f8ae 100644
--- a/gcc/rust/rustspec.cc
+++ b/gcc/rust/rustspec.cc
@@ -40,13 +40,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
{
unsigned int i, j;
- /* This is a tristate:
- -1 means we should not link in librust
- 0 means we should link in librust if it is needed
- 1 means librust is needed and should be linked in.
- 2 means librust is needed and should be linked statically. */
- int library = 0;
-
/* The new argument list will be contained in this. */
struct cl_decoded_option *new_decoded_options;
@@ -78,14 +71,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
/* Whether the -o option was used. */
bool saw_opt_o = false;
- /* Whether the -c option was used. Also used for -E, -fsyntax-only,
- in general anything which implies only compilation and not
- linking. */
- bool saw_opt_c = false;
-
- /* Whether the -S option was used. */
- bool saw_opt_S = false;
-
/* The first input file with an extension of .rs. */
const char *first_rust_file = NULL;
@@ -101,47 +86,9 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
switch (decoded_options[i].opt_index)
{
- case OPT_r:
- case OPT_nostdlib:
- case OPT_nodefaultlibs:
- library = -1;
- break;
-
case OPT_l:
if (strcmp (arg, "c") == 0)
args[i] |= WITHLIBC;
- else
- /* Unrecognized libraries (e.g. -lfoo) may require librust. */
- library = (library == 0) ? 1 : library;
- break;
-
- case OPT_x:
- if (library == 0 && strcmp (arg, "rust") == 0)
- library = 1;
- break;
-
- case OPT_Xlinker:
- case OPT_Wl_:
- /* Arguments that go directly to the linker might be .o files,
- or something, and so might cause librust to be needed. */
- if (library == 0)
- library = 1;
- break;
-
- case OPT_c:
- case OPT_E:
- case OPT_M:
- case OPT_MM:
- case OPT_fsyntax_only:
- /* Don't specify libraries if we won't link, since that would
- cause a warning. */
- saw_opt_c = true;
- library = -1;
- break;
-
- case OPT_S:
- saw_opt_S = true;
- library = -1;
break;
case OPT_o:
@@ -156,15 +103,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
shared_libgcc = 0;
break;
- case OPT_static_librust:
- library = library >= 0 ? 2 : library;
- args[i] |= SKIPOPT;
- break;
-
case OPT_SPECIAL_input_file:
- if (library == 0)
- library = 1;
-
if (first_rust_file == NULL)
{
int len;
@@ -173,6 +112,13 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
if (len > 3 && strcmp (arg + len - 3, ".rs") == 0)
first_rust_file = arg;
}
+ else
+ {
+ // FIXME: ARTHUR: Do we want to error here? If there's already one
+ // file?
+ // How do we error here? Do we want to instead just handle that in
+ // the session manager?
+ }
break;
}
@@ -185,7 +131,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
#endif
/* Make sure to have room for the trailing NULL argument. */
- num_args = argc + shared_libgcc + (library > 0) * 5 + 10;
+ num_args = argc + shared_libgcc * 5 + 10;
new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
i = 0;
@@ -199,7 +145,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
{
new_decoded_options[j] = decoded_options[i];
- if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
+ if (!saw_libc && (args[i] & WITHLIBC))
{
--j;
saw_libc = &decoded_options[i];
@@ -217,67 +163,12 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
driver will invoke rust1 separately for each input file. FIXME:
This should probably use some other interface to force the driver
to set combine_inputs. */
- if (first_rust_file != NULL && !saw_opt_o)
+ if (!saw_opt_o)
{
- if (saw_opt_c || saw_opt_S)
- {
- const char *base;
- int baselen;
- int alen;
- char *out;
-
- base = lbasename (first_rust_file);
- baselen = strlen (base) - 3;
- alen = baselen + 3;
- out = XNEWVEC (char, alen);
- memcpy (out, base, baselen);
- /* The driver will convert .o to some other suffix (e.g.,
- .obj) if appropriate. */
- out[baselen] = '.';
- if (saw_opt_S)
- out[baselen + 1] = 's';
- else
- out[baselen + 1] = 'o';
- out[baselen + 2] = '\0';
- generate_option (OPT_o, out, 1, CL_DRIVER, &new_decoded_options[j]);
- }
- else
- generate_option (OPT_o, "a.out", 1, CL_DRIVER, &new_decoded_options[j]);
+ generate_option (OPT_o, "a.out", 1, CL_DRIVER, &new_decoded_options[j]);
j++;
}
- /* Add `-lrust' if we haven't already done so. */
- if (library > 0)
- {
- // generate_option (OPT_l, LIBGOBEGIN, 1, CL_DRIVER,
- // &new_decoded_options[j]);
- // added_libraries++;
- // j++;
-
-#ifdef HAVE_LD_STATIC_DYNAMIC
- if (library > 1 && !static_link)
- {
- generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
- &new_decoded_options[j]);
- j++;
- }
-#endif
-
- // generate_option (OPT_l, LIBGO, 1,
- // CL_DRIVER, &new_decoded_options[j]);
- // added_libraries++;
- // j++;
-
-#ifdef HAVE_LD_STATIC_DYNAMIC
- if (library > 1 && !static_link)
- {
- generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
- &new_decoded_options[j]);
- j++;
- }
-#endif
- }
-
if (saw_libc)
new_decoded_options[j++] = *saw_libc;
if (shared_libgcc && !static_link)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index de542ca..0c44f28 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -310,6 +310,17 @@ public:
}
infered = lookup->clone ();
+
+ // Generic unit structs look like an identifier but they actually need be
+ // handled as a path-in-expression so this gives us a chance to infer the
+ // generic parameters.
+ // see https://github.com/Rust-GCC/gccrs/issues/1447
+ bool is_unit_struct
+ = infered->get_kind () == TyTy::TypeKind::ADT && infered->is_unit ();
+ if (is_unit_struct && infered->needs_generic_substitutions ())
+ {
+ infered = SubstMapper::InferSubst (infered, expr.get_locus ());
+ }
}
void visit (HIR::LiteralExpr &expr) override
diff --git a/gcc/rust/typecheck/rust-tyty-coercion.h b/gcc/rust/typecheck/rust-tyty-coercion.h
index c862de5..ed16365 100644
--- a/gcc/rust/typecheck/rust-tyty-coercion.h
+++ b/gcc/rust/typecheck/rust-tyty-coercion.h
@@ -1130,9 +1130,43 @@ public:
}
}
+ // generic args for the unit-struct case
+ if (type.is_unit () && base->is_unit ())
+ {
+ rust_assert (type.get_num_substitutions ()
+ == base->get_num_substitutions ());
+
+ for (size_t i = 0; i < type.get_num_substitutions (); i++)
+ {
+ auto &a = base->get_substs ().at (i);
+ auto &b = type.get_substs ().at (i);
+
+ auto pa = a.get_param_ty ();
+ auto pb = b.get_param_ty ();
+
+ auto res = pa->unify (pb);
+ if (res->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ return;
+ }
+ }
+ }
+
resolved = type.clone ();
}
+ void visit (InferType &type) override
+ {
+ if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
+ {
+ BaseCoercionRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ resolved->set_ref (type.get_ref ());
+ }
+
private:
BaseType *get_base () override { return base; }
@@ -1172,6 +1206,18 @@ public:
type.get_ident ().locus, fields);
}
+ void visit (InferType &type) override
+ {
+ if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
+ {
+ BaseCoercionRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ resolved->set_ref (type.get_ref ());
+ }
+
private:
BaseType *get_base () override { return base; }
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 1dd0112..77d912a 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -1128,9 +1128,43 @@ public:
}
}
+ // generic args for the unit-struct case
+ if (type.is_unit () && base->is_unit ())
+ {
+ rust_assert (type.get_num_substitutions ()
+ == base->get_num_substitutions ());
+
+ for (size_t i = 0; i < type.get_num_substitutions (); i++)
+ {
+ auto &a = base->get_substs ().at (i);
+ auto &b = type.get_substs ().at (i);
+
+ auto pa = a.get_param_ty ();
+ auto pb = b.get_param_ty ();
+
+ auto res = pa->unify (pb);
+ if (res->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ return;
+ }
+ }
+ }
+
resolved = type.clone ();
}
+ void visit (InferType &type) override
+ {
+ if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ resolved->set_ref (type.get_ref ());
+ }
+
private:
BaseType *get_base () override { return base; }
diff --git a/gcc/testsuite/rust/compile/issue-1447.rs b/gcc/testsuite/rust/compile/issue-1447.rs
new file mode 100644
index 0000000..e0543e6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1447.rs
@@ -0,0 +1,28 @@
+// { dg-options "-w" }
+struct PhantomData<T>;
+
+struct Hasher<S> {
+ _marker: PhantomData<S>,
+}
+
+struct Sip24Rounds;
+
+struct SipHasher24 {
+ hasher: Hasher<Sip24Rounds>,
+}
+
+impl SipHasher24 {
+ pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 {
+ SipHasher24 {
+ hasher: Hasher::new_with_keys(),
+ }
+ }
+}
+
+impl<S> Hasher<S> {
+ fn new_with_keys() -> Hasher<S> {
+ Hasher {
+ _marker: PhantomData,
+ }
+ }
+}