diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/rust-lang.cc | 36 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 23 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.h | 4 | ||||
-rw-r--r-- | gcc/rust/rustspec.cc | 131 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 11 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-coercion.h | 46 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-rules.h | 34 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-1447.rs | 28 |
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, + } + } +} |