diff options
Diffstat (limited to 'gcc/rust')
43 files changed, 538 insertions, 227 deletions
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog index b85622b..31c731b 100644 --- a/gcc/rust/ChangeLog +++ b/gcc/rust/ChangeLog @@ -1,3 +1,162 @@ +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path): + catch nullptr root_tyty + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::parse_repr_options): + check for null and empty and add missing delete call + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-tyty-subst.h: check for min range + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::parse_repr_options): check for input + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * hir/rust-hir-dump.cc (Dump::visit): check has type + * hir/tree/rust-hir-type.cc (BareFunctionType::BareFunctionType): likewise + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-constexpr.cc (eval_store_expression): turn this back on + +2025-03-31 Owen Avery <powerboat9.gamer@gmail.com> + + * expand/rust-macro-builtins-log-debug.cc: + Add newline to end of file. + +2025-03-31 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-forever-stack.h + (ForeverStack::get_prelude): Rename to... + (ForeverStack::get_lang_prelude): ...here. + (ForeverStack::prelude): Rename to... + (ForeverStack::lang_prelude): ...here. + (ForeverStack::ForeverStack): Handle renames. + * resolve/rust-forever-stack.hxx + (ForeverStack::push_inner): Likewise. + (ForeverStack::resolve_segments): Likewise. + (ForeverStack::resolve_path): Likewise. + (ForeverStack::get_prelude): Rename to... + (ForeverStack::get_lang_prelude): ...here and handle renames. + * resolve/rust-late-name-resolver-2.0.cc + (Late::visit): Handle renames. + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-context.h: only push named types + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): run the type hasher + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): check for Expr trait + * hir/rust-hir-dump.cc (Dump::visit): expr is optional + +2025-03-31 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * resolve/rust-forever-stack.hxx: Add a new specialized function + to retrieve the last "real" segment depending on the namespace. + * resolve/rust-forever-stack.h: Add new function prototype. + * resolve/rust-early-name-resolver-2.0.cc (Early::finalize_rebind_import): + Set declared name according to the selected segment, if there is a self + suffix in the use declaration then select the previous segment. + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-base.cc (HIRCompileBase::unit_expression): pass ctx + * backend/rust-compile-base.h: cant be static + * backend/rust-compile-intrinsic.cc (try_handler_inner): pass ctx + * backend/rust-compile-type.cc + (TyTyResolveCompile::get_unit_type): update to grab the first locus + (TyTyResolveCompile::visit): pass ctx + * backend/rust-compile-type.h: likewise + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-dot-operator.cc: + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * resolve/rust-ast-resolve-path.cc (ResolvePath::resolve_path): check for super mid path + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-base.cc (HIRCompileBase::address_expression): new helper constexpr + * backend/rust-compile-base.h: prototype + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): call constexpr helper + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::resolve_impl_block_substitutions): + Track the polarity + * typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::validate_type_implements_this): + new validator + * typecheck/rust-tyty.h: new prototypes + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-expr.cc (CompileExpr::array_value_expr): add value chk for array expr + +2025-03-31 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-trait-reference.h: add default infer arg + * typecheck/rust-hir-trait-resolve.cc: dont add new infer vars + * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): dont infer + +2025-03-31 Owen Avery <powerboat9.gamer@gmail.com> + + * checks/errors/rust-ast-validation.cc + (ASTValidation::visit): Allow constant items lacking expressions + if and only if they're associated with a trait definition, not a + trait implementation. + +2025-03-31 Owen Avery <powerboat9.gamer@gmail.com> + + * hir/rust-ast-lower-base.cc + (ASTLoweringBase::lower_literal): Lower raw string literals into + normal string literals. + +2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com> + + * checks/errors/borrowck/ffi-polonius/Cargo.lock: Regenerate. + * checks/errors/borrowck/ffi-polonius/Cargo.toml: Update to use source patching instead of + vendoring, lower edition to 2018. + * checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml: Change edition to 2018. + * checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs: Remove uses of unstable + feature. + * checks/errors/borrowck/ffi-polonius/.cargo/config.toml: Removed. + +2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com> + + * hir/tree/rust-hir-stmt.h (class LetStmt): Add optional diverging else expression. + * hir/tree/rust-hir-stmt.cc: Likewise. + * hir/rust-ast-lower-stmt.cc (ASTLoweringStmt::visit): Add handling for lowering + diverging else. + +2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com> + + * resolve/rust-ast-resolve-stmt.h: Add handling for diverging else. + * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise. + +2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-collector.cc (TokenCollector::visit): Add handling for diverging else + expression. + +2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com> + + * parse/rust-parse-impl.h (Parser::parse_let_stmt): Add new parsing in case of `else` token. + +2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-stmt.h (class LetStmt): Add optional expression for diverging else. + * ast/rust-ast-builder.cc (Builder::let): Use new API. + 2025-03-26 Iain Sandoe <iain@sandoe.co.uk> * metadata/rust-export-metadata.cc diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index 86290e1..cdc6eec 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -17,6 +17,7 @@ // <http://www.gnu.org/licenses/>. #include "rust-ast-builder.h" +#include "optional.h" #include "rust-ast-builder-type.h" #include "rust-ast.h" #include "rust-common.h" @@ -352,7 +353,7 @@ Builder::let (std::unique_ptr<Pattern> &&pattern, std::unique_ptr<Type> &&type, { return std::unique_ptr<Stmt> (new LetStmt (std::move (pattern), std::move (init), std::move (type), - {}, loc)); + tl::nullopt, {}, loc)); } std::unique_ptr<Expr> diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index 073fa72..3297407 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -22,6 +22,7 @@ #include "rust-expr.h" #include "rust-item.h" #include "rust-keyword-values.h" +#include "rust-location.h" #include "rust-path.h" #include "rust-system.h" #include "rust-token.h" @@ -2587,6 +2588,13 @@ TokenCollector::visit (LetStmt &stmt) push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); visit (stmt.get_init_expr ()); } + + if (stmt.has_else_expr ()) + { + push (Rust::Token::make (ELSE, UNDEF_LOCATION)); + visit (stmt.get_else_expr ()); + } + push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); } diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h index 6cbecaf..f843a79 100644 --- a/gcc/rust/ast/rust-stmt.h +++ b/gcc/rust/ast/rust-stmt.h @@ -19,6 +19,7 @@ #ifndef RUST_AST_STATEMENT_H #define RUST_AST_STATEMENT_H +#include "optional.h" #include "rust-ast.h" #include "rust-path.h" #include "rust-expr.h" @@ -72,6 +73,8 @@ class LetStmt : public Stmt // bool has_init_expr; std::unique_ptr<Expr> init_expr; + tl::optional<std::unique_ptr<Expr>> else_expr; + location_t locus; public: @@ -85,15 +88,18 @@ public: // Returns whether let statement has an initialisation expression. bool has_init_expr () const { return init_expr != nullptr; } + bool has_else_expr () const { return else_expr.has_value (); } std::string as_string () const override; LetStmt (std::unique_ptr<Pattern> variables_pattern, std::unique_ptr<Expr> init_expr, std::unique_ptr<Type> type, + tl::optional<std::unique_ptr<Expr>> else_expr, std::vector<Attribute> outer_attrs, location_t locus) : outer_attrs (std::move (outer_attrs)), variables_pattern (std::move (variables_pattern)), - type (std::move (type)), init_expr (std::move (init_expr)), locus (locus) + type (std::move (type)), init_expr (std::move (init_expr)), + else_expr (std::move (else_expr)), locus (locus) {} // Copy constructor with clone @@ -107,6 +113,9 @@ public: // guard to prevent null dereference (always required) if (other.init_expr != nullptr) init_expr = other.init_expr->clone_expr (); + if (other.else_expr.has_value ()) + else_expr = other.else_expr.value ()->clone_expr (); + if (other.type != nullptr) type = other.type->clone_type (); } @@ -128,6 +137,12 @@ public: init_expr = other.init_expr->clone_expr (); else init_expr = nullptr; + + if (other.else_expr != nullptr) + else_expr = other.else_expr.value ()->clone_expr (); + else + else_expr = tl::nullopt; + if (other.type != nullptr) type = other.type->clone_type (); else @@ -162,12 +177,24 @@ public: return *init_expr; } + Expr &get_else_expr () + { + rust_assert (has_else_expr ()); + return *else_expr.value (); + } + std::unique_ptr<Expr> &get_init_expr_ptr () { rust_assert (has_init_expr ()); return init_expr; } + std::unique_ptr<Expr> &get_else_expr_ptr () + { + rust_assert (has_else_expr ()); + return else_expr.value (); + } + Pattern &get_pattern () { rust_assert (variables_pattern != nullptr); diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index bcc7fc4..fdbca7f 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -561,6 +561,18 @@ HIRCompileBase::address_expression (tree expr, location_t location) } tree +HIRCompileBase::compile_constant_expr ( + Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type, + TyTy::BaseType *expected_type, const Resolver::CanonicalPath &canonical_path, + HIR::Expr &const_value_expr, location_t locus, location_t expr_locus) +{ + HIRCompileBase c (ctx); + return c.compile_constant_item (coercion_id, resolved_type, expected_type, + canonical_path, const_value_expr, locus, + expr_locus); +} + +tree HIRCompileBase::indirect_expression (tree expr, location_t locus) { if (expr == error_mark_node) @@ -1011,7 +1023,7 @@ HIRCompileBase::resolve_method_address (TyTy::FnType *fntype, tree HIRCompileBase::unit_expression (location_t locus) { - tree unit_type = TyTyResolveCompile::get_unit_type (); + tree unit_type = TyTyResolveCompile::get_unit_type (ctx); return Backend::constructor_expression (unit_type, false, {}, -1, locus); } diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index 9328a7f..4b4f8b0 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -31,6 +31,12 @@ public: static tree address_expression (tree expr, location_t locus); + static tree compile_constant_expr ( + Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type, + TyTy::BaseType *expected_type, + const Resolver::CanonicalPath &canonical_path, HIR::Expr &const_value_expr, + location_t locus, location_t expr_locus); + protected: HIRCompileBase (Context *ctx) : ctx (ctx) {} @@ -104,7 +110,7 @@ protected: const Resolver::CanonicalPath &canonical_path, TyTy::FnType *fntype); - static tree unit_expression (location_t locus); + tree unit_expression (location_t locus); void setup_fndecl (tree fndecl, bool is_main_entry_point, bool is_generic_fn, HIR::Visibility &visibility, diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index a446388..ce81a1d 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -72,7 +72,10 @@ public: return it->second; compiled_type_map.insert ({h, type}); - push_type (type); + + if (TYPE_NAME (type) != NULL) + push_type (type); + return type; } diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 21f4ca1..e4ab9f0 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -1902,6 +1902,14 @@ CompileExpr::array_value_expr (location_t expr_locus, for (auto &elem : elems.get_values ()) { tree translated_expr = CompileExpr::Compile (*elem, ctx); + if (translated_expr == error_mark_node) + { + rich_location r (line_table, expr_locus); + r.add_fixit_replace (elem->get_locus (), "not a value"); + rust_error_at (r, ErrorCode::E0423, "expected value"); + return error_mark_node; + } + constructor.push_back (translated_expr); indexes.push_back (i++); } @@ -2003,6 +2011,9 @@ HIRCompileBase::resolve_adjustements ( tree e = expression; for (auto &adjustment : adjustments) { + if (e == error_mark_node) + return error_mark_node; + switch (adjustment.get_type ()) { case Resolver::Adjustment::AdjustmentType::ERROR: diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index fb0c661..4888e23 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -1322,7 +1322,7 @@ try_handler_inner (Context *ctx, TyTy::FnType *fntype, bool is_new_api) if (is_new_api) { - auto ret_type = TyTyResolveCompile::get_unit_type (); + auto ret_type = TyTyResolveCompile::get_unit_type (ctx); auto ret_expr = Backend::constructor_expression (ret_type, false, {}, -1, UNDEF_LOCATION); normal_return_stmt diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 2b6880c..115dd04 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -301,6 +301,27 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, trait->get_mappings ().get_defid (), &trait_ref); rust_assert (ok); + if (trait_item.value ()->get_item_kind () + == HIR::TraitItem::TraitItemKind::CONST) + { + auto &c + = *static_cast<HIR::TraitItemConst *> (trait_item.value ()); + if (!c.has_expr ()) + { + rich_location r (line_table, expr_locus); + r.add_range (trait->get_locus ()); + r.add_range (c.get_locus ()); + rust_error_at (r, "no default expression on trait constant"); + return error_mark_node; + } + + return CompileExpr::Compile (c.get_expr (), ctx); + } + + if (trait_item.value ()->get_item_kind () + != HIR::TraitItem::TraitItemKind::FUNC) + return error_mark_node; + // the type resolver can only resolve type bounds to their trait // item so its up to us to figure out if this path should resolve // to an trait-impl-block-item or if it can be defaulted to the diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc index d8af1d1..83e5756 100644 --- a/gcc/rust/backend/rust-compile-type.cc +++ b/gcc/rust/backend/rust-compile-type.cc @@ -81,13 +81,22 @@ TyTyResolveCompile::get_implicit_enumeral_node_type (TyTy::BaseType *repr) } tree -TyTyResolveCompile::get_unit_type () +TyTyResolveCompile::get_unit_type (Context *ctx) { static tree unit_type; if (unit_type == nullptr) { + auto cn = ctx->get_mappings ().get_current_crate (); + auto &c = ctx->get_mappings ().get_ast_crate (cn); + location_t locus = BUILTINS_LOCATION; + if (c.items.size () > 0) + { + auto &item = c.items[0]; + locus = item->get_locus (); + } + auto unit_type_node = Backend::struct_type ({}); - unit_type = Backend::named_type ("()", unit_type_node, BUILTINS_LOCATION); + unit_type = Backend::named_type ("()", unit_type_node, locus); } return unit_type; } @@ -421,7 +430,7 @@ TyTyResolveCompile::visit (const TyTy::TupleType &type) { if (type.num_fields () == 0) { - translated = get_unit_type (); + translated = get_unit_type (ctx); return; } @@ -456,12 +465,24 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type) = TyTyResolveCompile::compile (ctx, type.get_element_type ()); ctx->push_const_context (); - tree capacity_expr = CompileExpr::Compile (type.get_capacity_expr (), ctx); + + HIR::Expr &hir_capacity_expr = type.get_capacity_expr (); + TyTy::BaseType *capacity_expr_ty = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type ( + hir_capacity_expr.get_mappings ().get_hirid (), &capacity_expr_ty); + rust_assert (ok); + tree capacity_expr = HIRCompileBase::compile_constant_expr ( + ctx, hir_capacity_expr.get_mappings ().get_hirid (), capacity_expr_ty, + capacity_expr_ty, Resolver::CanonicalPath::create_empty (), + hir_capacity_expr, type.get_locus (), hir_capacity_expr.get_locus ()); + ctx->pop_const_context (); tree folded_capacity_expr = fold_expr (capacity_expr); translated = Backend::array_type (element_type, folded_capacity_expr); + if (translated != error_mark_node) + translated = ctx->insert_compiled_type (translated); } void @@ -714,7 +735,7 @@ TyTyResolveCompile::visit (const TyTy::StrType &type) void TyTyResolveCompile::visit (const TyTy::NeverType &) { - translated = get_unit_type (); + translated = get_unit_type (ctx); } void diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h index bc611cf..7ebc4a6 100644 --- a/gcc/rust/backend/rust-compile-type.h +++ b/gcc/rust/backend/rust-compile-type.h @@ -30,7 +30,7 @@ public: static tree compile (Context *ctx, const TyTy::BaseType *ty, bool trait_object_mode = false); - static tree get_unit_type (); + static tree get_unit_type (Context *ctx); void visit (const TyTy::InferType &) override; void visit (const TyTy::ADTType &) override; diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc index 2f2bbbd..dc2d6b1 100644 --- a/gcc/rust/backend/rust-constexpr.cc +++ b/gcc/rust/backend/rust-constexpr.cc @@ -2697,10 +2697,8 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval, } if (TREE_CODE (probe) == ARRAY_REF) { - // TODO - rust_unreachable (); - // elt = eval_and_check_array_index (ctx, probe, false, - // non_constant_p, overflow_p); + elt = eval_and_check_array_index (ctx, probe, false, + non_constant_p, overflow_p); if (*non_constant_p) return t; } diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/.cargo/config.toml b/gcc/rust/checks/errors/borrowck/ffi-polonius/.cargo/config.toml deleted file mode 100644 index 0236928..0000000 --- a/gcc/rust/checks/errors/borrowck/ffi-polonius/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[source.crates-io] -replace-with = "vendored-sources" - -[source.vendored-sources] -directory = "vendor" diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock index f7cbd41..1b223b6 100644 --- a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock +++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock @@ -1,12 +1,8 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - [[package]] name = "datafrog" version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69" [[package]] name = "ffi-polonius" @@ -18,14 +14,10 @@ dependencies = [ [[package]] name = "log" version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "polonius-engine" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e8e505342045d397d0b6674dcb82d6faf5cf40484d30eeb88fc82ef14e903f" dependencies = [ "datafrog", "log", @@ -35,5 +27,3 @@ dependencies = [ [[package]] name = "rustc-hash" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml index 71315c3..3bc8e3f 100644 --- a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml +++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml @@ -1,11 +1,17 @@ [package] name = "ffi-polonius" version = "0.1.0" -edition = "2021" +edition = "2018" license = "GPL-3" [lib] crate-type = ["staticlib"] [dependencies] -polonius-engine = "0.13.0"
\ No newline at end of file +polonius-engine = "0.13.0" + +[patch.crates-io] +log = { path = "vendor/log" } +datafrog = { path = "vendor/datafrog" } +polonius-engine = { path = "vendor/polonius-engine" } +rustc-hash = { path = "vendor/rustc-hash" } diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml index 313a005..a199e31 100644 --- a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml +++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml @@ -10,7 +10,7 @@ # See Cargo.toml.orig for the original contents. [package] -edition = "2021" +edition = "2018" rust-version = "1.60.0" name = "log" version = "0.4.22" diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs index 6b43a9a..603bbac 100644 --- a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs +++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs @@ -397,20 +397,13 @@ mod serde; #[cfg(feature = "kv")] pub mod kv; -#[cfg(target_has_atomic = "ptr")] -use std::sync::atomic::{AtomicUsize, Ordering}; - -#[cfg(not(target_has_atomic = "ptr"))] use std::cell::Cell; -#[cfg(not(target_has_atomic = "ptr"))] use std::sync::atomic::Ordering; -#[cfg(not(target_has_atomic = "ptr"))] struct AtomicUsize { v: Cell<usize>, } -#[cfg(not(target_has_atomic = "ptr"))] impl AtomicUsize { const fn new(v: usize) -> AtomicUsize { AtomicUsize { v: Cell::new(v) } @@ -423,26 +416,10 @@ impl AtomicUsize { fn store(&self, val: usize, _order: Ordering) { self.v.set(val) } - - #[cfg(target_has_atomic = "ptr")] - fn compare_exchange( - &self, - current: usize, - new: usize, - _success: Ordering, - _failure: Ordering, - ) -> Result<usize, usize> { - let prev = self.v.get(); - if current == prev { - self.v.set(new); - } - Ok(prev) - } } // Any platform without atomics is unlikely to have multiple cores, so // writing via Cell will not be a race condition. -#[cfg(not(target_has_atomic = "ptr"))] unsafe impl Sync for AtomicUsize {} // The LOGGER static holds a pointer to the global logger. It is protected by @@ -1258,17 +1235,6 @@ where } } -/// Sets the global maximum log level. -/// -/// Generally, this should only be called by the active logging implementation. -/// -/// Note that `Trace` is the maximum level, because it provides the maximum amount of detail in the emitted logs. -#[inline] -#[cfg(target_has_atomic = "ptr")] -pub fn set_max_level(level: LevelFilter) { - MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed); -} - /// A thread-unsafe version of [`set_max_level`]. /// /// This function is available on all platforms, even those that do not have @@ -1320,110 +1286,6 @@ pub fn max_level() -> LevelFilter { unsafe { mem::transmute(MAX_LOG_LEVEL_FILTER.load(Ordering::Relaxed)) } } -/// Sets the global logger to a `Box<Log>`. -/// -/// This is a simple convenience wrapper over `set_logger`, which takes a -/// `Box<Log>` rather than a `&'static Log`. See the documentation for -/// [`set_logger`] for more details. -/// -/// Requires the `std` feature. -/// -/// # Errors -/// -/// An error is returned if a logger has already been set. -/// -/// [`set_logger`]: fn.set_logger.html -#[cfg(all(feature = "std", target_has_atomic = "ptr"))] -pub fn set_boxed_logger(logger: Box<dyn Log>) -> Result<(), SetLoggerError> { - set_logger_inner(|| Box::leak(logger)) -} - -/// Sets the global logger to a `&'static Log`. -/// -/// This function may only be called once in the lifetime of a program. Any log -/// events that occur before the call to `set_logger` completes will be ignored. -/// -/// This function does not typically need to be called manually. Logger -/// implementations should provide an initialization method that installs the -/// logger internally. -/// -/// # Availability -/// -/// This method is available even when the `std` feature is disabled. However, -/// it is currently unavailable on `thumbv6` targets, which lack support for -/// some atomic operations which are used by this function. Even on those -/// targets, [`set_logger_racy`] will be available. -/// -/// # Errors -/// -/// An error is returned if a logger has already been set. -/// -/// # Examples -/// -/// ``` -/// use log::{error, info, warn, Record, Level, Metadata, LevelFilter}; -/// -/// static MY_LOGGER: MyLogger = MyLogger; -/// -/// struct MyLogger; -/// -/// impl log::Log for MyLogger { -/// fn enabled(&self, metadata: &Metadata) -> bool { -/// metadata.level() <= Level::Info -/// } -/// -/// fn log(&self, record: &Record) { -/// if self.enabled(record.metadata()) { -/// println!("{} - {}", record.level(), record.args()); -/// } -/// } -/// fn flush(&self) {} -/// } -/// -/// # fn main(){ -/// log::set_logger(&MY_LOGGER).unwrap(); -/// log::set_max_level(LevelFilter::Info); -/// -/// info!("hello log"); -/// warn!("warning"); -/// error!("oops"); -/// # } -/// ``` -/// -/// [`set_logger_racy`]: fn.set_logger_racy.html -#[cfg(target_has_atomic = "ptr")] -pub fn set_logger(logger: &'static dyn Log) -> Result<(), SetLoggerError> { - set_logger_inner(|| logger) -} - -#[cfg(target_has_atomic = "ptr")] -fn set_logger_inner<F>(make_logger: F) -> Result<(), SetLoggerError> -where - F: FnOnce() -> &'static dyn Log, -{ - match STATE.compare_exchange( - UNINITIALIZED, - INITIALIZING, - Ordering::Acquire, - Ordering::Relaxed, - ) { - Ok(UNINITIALIZED) => { - unsafe { - LOGGER = make_logger(); - } - STATE.store(INITIALIZED, Ordering::Release); - Ok(()) - } - Err(INITIALIZING) => { - while STATE.load(Ordering::Relaxed) == INITIALIZING { - std::hint::spin_loop(); - } - Err(SetLoggerError(())) - } - _ => Err(SetLoggerError(())), - } -} - /// A thread-unsafe version of [`set_logger`]. /// /// This function is available on all platforms, even those that do not have diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc b/gcc/rust/checks/errors/rust-ast-validation.cc index 59b2805..0f4bdeb 100644 --- a/gcc/rust/checks/errors/rust-ast-validation.cc +++ b/gcc/rust/checks/errors/rust-ast-validation.cc @@ -56,7 +56,7 @@ ASTValidation::visit (AST::LoopLabel &label) void ASTValidation::visit (AST::ConstantItem &const_item) { - if (!const_item.has_expr () && ctx.peek () != Kind::TRAIT_IMPL) + if (!const_item.has_expr () && ctx.peek () != Kind::TRAIT) { rust_error_at (const_item.get_locus (), "associated constant in %<impl%> without body"); diff --git a/gcc/rust/expand/rust-macro-builtins-log-debug.cc b/gcc/rust/expand/rust-macro-builtins-log-debug.cc index 49670d2..3d7b54f 100644 --- a/gcc/rust/expand/rust-macro-builtins-log-debug.cc +++ b/gcc/rust/expand/rust-macro-builtins-log-debug.cc @@ -30,4 +30,4 @@ MacroBuiltin::assert_handler (location_t invoc_locus, return AST::Fragment::create_error (); } -} // namespace Rust
\ No newline at end of file +} // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index c1fef3d..b0d347e 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -933,8 +933,8 @@ ASTLoweringBase::lower_literal (const AST::Literal &literal) case AST::Literal::LitType::BYTE_STRING: type = HIR::Literal::LitType::BYTE_STRING; break; - case AST::Literal::LitType::RAW_STRING: // TODO: Lower raw string literals. - rust_unreachable (); + case AST::Literal::LitType::RAW_STRING: + type = HIR::Literal::LitType::STRING; break; case AST::Literal::LitType::INT: type = HIR::Literal::LitType::INT; diff --git a/gcc/rust/hir/rust-ast-lower-stmt.cc b/gcc/rust/hir/rust-ast-lower-stmt.cc index fd2cdfb..dbb1723 100644 --- a/gcc/rust/hir/rust-ast-lower-stmt.cc +++ b/gcc/rust/hir/rust-ast-lower-stmt.cc @@ -76,20 +76,26 @@ ASTLoweringStmt::visit (AST::LetStmt &stmt) type = std::unique_ptr<Type> (ASTLoweringType::translate (stmt.get_type ())); - tl::optional<std::unique_ptr<HIR::Expr>> init_expression = tl::nullopt; + tl::optional<std::unique_ptr<HIR::Expr>> init_expr = tl::nullopt; + tl::optional<std::unique_ptr<HIR::Expr>> else_expr = tl::nullopt; if (stmt.has_init_expr ()) - init_expression = std::unique_ptr<HIR::Expr> ( + init_expr = std::unique_ptr<HIR::Expr> ( ASTLoweringExpr::translate (stmt.get_init_expr ())); + if (stmt.has_else_expr ()) + else_expr = std::unique_ptr<HIR::Expr> ( + ASTLoweringExpr::translate (stmt.get_else_expr ())); + auto crate_num = mappings.get_current_crate (); Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (), mappings.get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID); translated = new HIR::LetStmt (mapping, std::unique_ptr<HIR::Pattern> (variables), - std::move (init_expression), std::move (type), - stmt.get_outer_attrs (), stmt.get_locus ()); + std::move (init_expr), std::move (else_expr), + std::move (type), stmt.get_outer_attrs (), + stmt.get_locus ()); } void diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc index d495841..89fcc3d 100644 --- a/gcc/rust/hir/rust-hir-dump.cc +++ b/gcc/rust/hir/rust-hir-dump.cc @@ -1932,7 +1932,9 @@ Dump::visit (TraitItemConst &e) put_field ("name", e.get_name ().as_string ()); visit_field ("type", e.get_type ()); - visit_field ("expr", e.get_expr ()); + if (e.has_expr ()) + visit_field ("expr", e.get_expr ()); + end ("TraitItemConst"); } @@ -2438,7 +2440,9 @@ Dump::visit (BareFunctionType &e) end_field ("params"); } - visit_field ("return_type", e.get_return_type ()); + if (e.has_return_type ()) + visit_field ("return_type", e.get_return_type ()); + put_field ("is_variadic", std::to_string (e.get_is_variadic ())); end ("BareFunctionType"); } diff --git a/gcc/rust/hir/tree/rust-hir-stmt.cc b/gcc/rust/hir/tree/rust-hir-stmt.cc index 025f67e..fd58e29 100644 --- a/gcc/rust/hir/tree/rust-hir-stmt.cc +++ b/gcc/rust/hir/tree/rust-hir-stmt.cc @@ -26,11 +26,13 @@ namespace HIR { LetStmt::LetStmt (Analysis::NodeMapping mappings, std::unique_ptr<Pattern> variables_pattern, tl::optional<std::unique_ptr<Expr>> init_expr, + tl::optional<std::unique_ptr<Expr>> else_expr, tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs, location_t locus) : Stmt (std::move (mappings)), outer_attrs (std::move (outer_attrs)), variables_pattern (std::move (variables_pattern)), type (std::move (type)), - init_expr (std::move (init_expr)), locus (locus) + init_expr (std::move (init_expr)), else_expr (std::move (else_expr)), + locus (locus) {} LetStmt::LetStmt (LetStmt const &other) @@ -43,6 +45,8 @@ LetStmt::LetStmt (LetStmt const &other) // guard to prevent null dereference (always required) if (other.has_init_expr ()) init_expr = other.get_init_expr ().clone_expr (); + if (other.has_else_expr ()) + else_expr = other.get_else_expr ().clone_expr (); if (other.has_type ()) type = other.get_type ().clone_type (); @@ -67,6 +71,12 @@ LetStmt::operator= (LetStmt const &other) init_expr = other.get_init_expr ().clone_expr (); else init_expr = nullptr; + + if (other.has_else_expr ()) + else_expr = other.get_else_expr ().clone_expr (); + else + else_expr = tl::nullopt; + if (other.has_type ()) type = other.get_type ().clone_type (); else diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h index 3db1728..9c1a9ec 100644 --- a/gcc/rust/hir/tree/rust-hir-stmt.h +++ b/gcc/rust/hir/tree/rust-hir-stmt.h @@ -101,6 +101,7 @@ class LetStmt : public Stmt tl::optional<std::unique_ptr<Type>> type; tl::optional<std::unique_ptr<Expr>> init_expr; + tl::optional<std::unique_ptr<Expr>> else_expr; location_t locus; @@ -113,12 +114,15 @@ public: // Returns whether let statement has an initialisation expression. bool has_init_expr () const { return init_expr.has_value (); } + // Returns whether let statement has a diverging else expression. + bool has_else_expr () const { return else_expr.has_value (); } std::string as_string () const override; LetStmt (Analysis::NodeMapping mappings, std::unique_ptr<Pattern> variables_pattern, tl::optional<std::unique_ptr<Expr>> init_expr, + tl::optional<std::unique_ptr<Expr>> else_expr, tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs, location_t locus); @@ -167,6 +171,18 @@ public: return *init_expr.value (); } + HIR::Expr &get_else_expr () + { + rust_assert (*else_expr); + return *else_expr.value (); + } + + const HIR::Expr &get_else_expr () const + { + rust_assert (*else_expr); + return *else_expr.value (); + } + HIR::Pattern &get_pattern () { return *variables_pattern; } bool is_item () const override final { return false; } diff --git a/gcc/rust/hir/tree/rust-hir-type.cc b/gcc/rust/hir/tree/rust-hir-type.cc index 689d86b..6a6c319 100644 --- a/gcc/rust/hir/tree/rust-hir-type.cc +++ b/gcc/rust/hir/tree/rust-hir-type.cc @@ -268,7 +268,8 @@ BareFunctionType::BareFunctionType (BareFunctionType const &other) for_lifetimes (other.for_lifetimes), function_qualifiers (other.function_qualifiers), params (other.params), is_variadic (other.is_variadic), - return_type (other.return_type->clone_type ()) + return_type (other.has_return_type () ? other.return_type->clone_type () + : nullptr) {} BareFunctionType & diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index dd60868..71d7250 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -6163,6 +6163,10 @@ Parser<ManagedTokenSource>::parse_let_stmt (AST::AttrVec outer_attrs, } } + tl::optional<std::unique_ptr<AST::Expr>> else_expr = tl::nullopt; + if (maybe_skip_token (ELSE)) + else_expr = parse_block_expr (); + if (restrictions.consume_semi) { // `stmt` macro variables are parsed without a semicolon, but should be @@ -6177,7 +6181,7 @@ Parser<ManagedTokenSource>::parse_let_stmt (AST::AttrVec outer_attrs, return std::unique_ptr<AST::LetStmt> ( new AST::LetStmt (std::move (pattern), std::move (expr), std::move (type), - std::move (outer_attrs), locus)); + std::move (else_expr), std::move (outer_attrs), locus)); } // Parses a type path. diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc index b2b1071..530926d 100644 --- a/gcc/rust/resolve/rust-ast-resolve-path.cc +++ b/gcc/rust/resolve/rust-ast-resolve-path.cc @@ -370,6 +370,12 @@ ResolvePath::resolve_path (AST::SimplePath &expr) } else if (segment.is_super_path_seg ()) { + if (!is_first_segment) + { + rust_error_at (segment.get_locus (), + "%<super%> can only be used in start position"); + return UNKNOWN_NODEID; + } if (module_scope_id == crate_scope_id) { rust_error_at (segment.get_locus (), diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index d3ff14f..6c99d6a 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -73,9 +73,10 @@ public: void visit (AST::LetStmt &stmt) override { if (stmt.has_init_expr ()) - { - ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix); - } + ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix); + + if (stmt.has_else_expr ()) + ResolveExpr::go (stmt.get_else_expr (), prefix, canonical_prefix); PatternDeclaration::go (stmt.get_pattern (), Rib::ItemType::Var); if (stmt.has_type ()) diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc index 492a665..afaca1f 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc @@ -417,10 +417,19 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping) declared_name = rebind.get_identifier ().as_string (); locus = rebind.get_identifier ().get_locus (); break; - case AST::UseTreeRebind::NewBindType::NONE: - declared_name = path.get_final_segment ().as_string (); - locus = path.get_final_segment ().get_locus (); - break; + case AST::UseTreeRebind::NewBindType::NONE: { + const auto &segments = path.get_segments (); + // We don't want to insert `self` with `use module::self` + if (path.get_final_segment ().is_lower_self_seg ()) + { + rust_assert (segments.size () > 1); + declared_name = segments[segments.size () - 2].as_string (); + } + else + declared_name = path.get_final_segment ().as_string (); + locus = path.get_final_segment ().get_locus (); + break; + } case AST::UseTreeRebind::NewBindType::WILDCARD: rust_unreachable (); break; diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h index 2a4c734..f390e38 100644 --- a/gcc/rust/resolve/rust-forever-stack.h +++ b/gcc/rust/resolve/rust-forever-stack.h @@ -548,7 +548,7 @@ template <Namespace N> class ForeverStack public: ForeverStack () : root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)), - prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)), + lang_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)), cursor_reference (root) { rust_assert (root.is_root ()); @@ -658,8 +658,8 @@ public: * the current map, an empty one otherwise. */ tl::optional<Rib::Definition> get (const Identifier &name); - tl::optional<Rib::Definition> get_prelude (const Identifier &name); - tl::optional<Rib::Definition> get_prelude (const std::string &name); + tl::optional<Rib::Definition> get_lang_prelude (const Identifier &name); + tl::optional<Rib::Definition> get_lang_prelude (const std::string &name); /** * Resolve a path to its definition in the current `ForeverStack` @@ -767,7 +767,7 @@ private: * It has the root node as a parent, and acts as a "special case" for name * resolution */ - Node prelude; + Node lang_prelude; std::reference_wrapper<Node> cursor_reference; @@ -795,6 +795,10 @@ private: SegIterator<S> iterator, std::function<void (const S &, NodeId)> insert_segment_resolution); + tl::optional<Rib::Definition> resolve_final_segment (Node &final_node, + std::string &seg_name, + bool is_lower_self); + /* Helper functions for forward resolution (to_canonical_path, to_rib...) */ struct DfsResult { diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index a6e0b30..885f282 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -77,7 +77,7 @@ ForeverStack<N>::push_inner (Rib rib, Link link) rust_assert (&cursor_reference.get () == &root); // Prelude doesn't have an access path rust_assert (!link.path); - update_cursor (this->prelude); + update_cursor (this->lang_prelude); return; } // If the link does not exist, we create it and emplace a new `Node` with the @@ -319,16 +319,16 @@ ForeverStack<N>::get (const Identifier &name) template <Namespace N> tl::optional<Rib::Definition> -ForeverStack<N>::get_prelude (const Identifier &name) +ForeverStack<N>::get_lang_prelude (const Identifier &name) { - return prelude.rib.get (name.as_string ()); + return lang_prelude.rib.get (name.as_string ()); } template <Namespace N> tl::optional<Rib::Definition> -ForeverStack<N>::get_prelude (const std::string &name) +ForeverStack<N>::get_lang_prelude (const std::string &name) { - return prelude.rib.get (name); + return lang_prelude.rib.get (name); } template <> @@ -571,7 +571,7 @@ ForeverStack<N>::resolve_segments ( if (current_node->is_root () && !searched_prelude) { searched_prelude = true; - current_node = &prelude; + current_node = &lang_prelude; continue; } @@ -594,6 +594,26 @@ ForeverStack<N>::resolve_segments ( return *current_node; } +template <> +inline tl::optional<Rib::Definition> +ForeverStack<Namespace::Types>::resolve_final_segment (Node &final_node, + std::string &seg_name, + bool is_lower_self) +{ + if (is_lower_self) + return Rib::Definition::NonShadowable (final_node.id); + else + return final_node.rib.get (seg_name); +} + +template <Namespace N> +tl::optional<Rib::Definition> +ForeverStack<N>::resolve_final_segment (Node &final_node, std::string &seg_name, + bool is_lower_self) +{ + return final_node.rib.get (seg_name); +} + template <Namespace N> template <typename S> tl::optional<Rib::Definition> @@ -621,7 +641,8 @@ ForeverStack<N>::resolve_path ( = get (unwrap_type_segment (segments.back ()).as_string ()); if (!res) - res = get_prelude (unwrap_type_segment (segments.back ()).as_string ()); + res = get_lang_prelude ( + unwrap_type_segment (segments.back ()).as_string ()); if (res && !res->is_ambiguous ()) insert_segment_resolution (segments.back (), res->get_node_id ()); @@ -643,15 +664,16 @@ ForeverStack<N>::resolve_path ( if (final_node.rib.kind == Rib::Kind::TraitOrImpl) return tl::nullopt; - std::string seg_name - = unwrap_type_segment (segments.back ()).as_string (); + auto &seg = unwrap_type_segment (segments.back ()); + std::string seg_name = seg.as_string (); // assuming this can't be a lang item segment - tl::optional<Rib::Definition> res = final_node.rib.get (seg_name); - + tl::optional<Rib::Definition> res + = resolve_final_segment (final_node, seg_name, + seg.is_lower_self_seg ()); // Ok we didn't find it in the rib, Lets try the prelude... if (!res) - res = get_prelude (seg_name); + res = get_lang_prelude (seg_name); if (res && !res->is_ambiguous ()) insert_segment_resolution (segments.back (), res->get_node_id ()); diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc index cf7b7dc..7d32374 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -140,6 +140,9 @@ Late::visit (AST::LetStmt &let) visit (let.get_init_expr ()); visit (let.get_pattern ()); + if (let.has_else_expr ()) + visit (let.get_init_expr ()); + // how do we deal with the fact that `let a = blipbloup` should look for a // label and cannot go through function ribs, but `let a = blipbloup()` can? @@ -232,7 +235,7 @@ Late::visit (AST::IdentifierExpr &expr) } else { - if (auto type = ctx.types.get_prelude (expr.get_ident ())) + if (auto type = ctx.types.get_lang_prelude (expr.get_ident ())) { resolved = type; } diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc index 38bd5b7..c1165e9 100644 --- a/gcc/rust/typecheck/rust-hir-dot-operator.cc +++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc @@ -472,8 +472,11 @@ MethodResolver::get_predicate_items ( if (ty->get_kind () == TyTy::TypeKind::FNDEF) { TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty); - predicate_candidate candidate{lookup, fnty}; - predicate_items.push_back (candidate); + if (fnty->is_method ()) + { + predicate_candidate candidate{lookup, fnty}; + predicate_items.push_back (candidate); + } } } diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h index 6a570ed..8b1ac7d 100644 --- a/gcc/rust/typecheck/rust-hir-trait-reference.h +++ b/gcc/rust/typecheck/rust-hir-trait-reference.h @@ -254,10 +254,9 @@ public: void setup_raw_associated_types (); - TyTy::BaseType * - setup_associated_types (const TyTy::BaseType *self, - const TyTy::TypeBoundPredicate &bound, - TyTy::SubstitutionArgumentMappings *args = nullptr); + TyTy::BaseType *setup_associated_types ( + const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound, + TyTy::SubstitutionArgumentMappings *args = nullptr, bool infer = true); void reset_associated_types (); diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index c07425d..e4a61bd 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -485,7 +485,7 @@ AssociatedImplTrait::setup_raw_associated_types () TyTy::BaseType * AssociatedImplTrait::setup_associated_types ( const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound, - TyTy::SubstitutionArgumentMappings *args) + TyTy::SubstitutionArgumentMappings *args, bool infer) { // compute the constrained impl block generic arguments based on self and the // higher ranked trait bound @@ -545,7 +545,7 @@ AssociatedImplTrait::setup_associated_types ( std::vector<TyTy::SubstitutionArg> subst_args; for (auto &p : substitutions) { - if (p.needs_substitution ()) + if (p.needs_substitution () && infer) { TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus); subst_args.push_back ( @@ -619,7 +619,7 @@ AssociatedImplTrait::setup_associated_types ( = unify_site_and (a->get_ref (), TyTy::TyWithLocation (a), TyTy::TyWithLocation (b), impl_predicate.get_locus (), true /*emit-errors*/, true /*commit-if-ok*/, - false /*infer*/, true /*cleanup-on-fail*/); + true /*infer*/, true /*cleanup-on-fail*/); rust_assert (result->get_kind () != TyTy::TypeKind::ERROR); } @@ -632,7 +632,7 @@ AssociatedImplTrait::setup_associated_types ( TyTy::TyWithLocation (impl_self_infer), impl_predicate.get_locus (), true /*emit-errors*/, true /*commit-if-ok*/, - false /*infer*/, true /*cleanup-on-fail*/); + true /*infer*/, true /*cleanup-on-fail*/); rust_assert (result->get_kind () != TyTy::TypeKind::ERROR); TyTy::BaseType *self_result = result; diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc index 8f2471d..34a726c 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc @@ -305,6 +305,12 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus) for (const auto &attr : attrs) { bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR; + if (is_repr && !attr.has_attr_input ()) + { + rust_error_at (attr.get_locus (), "malformed %qs attribute", "repr"); + continue; + } + if (is_repr) { const AST::AttrInput &input = attr.get_attr_input (); @@ -315,8 +321,22 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus) AST::AttrInputMetaItemContainer *meta_items = option.parse_to_meta_item (); - const std::string inline_option - = meta_items->get_items ().at (0)->as_string (); + if (meta_items == nullptr) + { + rust_error_at (attr.get_locus (), "malformed %qs attribute", + "repr"); + continue; + } + + auto &items = meta_items->get_items (); + if (items.size () == 0) + { + // nothing to do with this its empty + delete meta_items; + continue; + } + + const std::string inline_option = items.at (0)->as_string (); // TODO: it would probably be better to make the MetaItems more aware // of constructs with nesting like #[repr(packed(2))] rather than @@ -353,6 +373,8 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus) else if (is_align) repr.align = value; + delete meta_items; + // Multiple repr options must be specified with e.g. #[repr(C, // packed(2))]. break; diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc index a003848..9774921 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc @@ -725,11 +725,11 @@ TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block, // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs // for example - specified_bound = get_predicate_from_bound (ref, impl_block.get_type ()); + specified_bound = get_predicate_from_bound (ref, impl_block.get_type (), + impl_block.get_polarity ()); } TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ()); - if (self->is<TyTy::ErrorType> ()) { // we cannot check for unconstrained type arguments when the Self type is @@ -771,7 +771,14 @@ TypeCheckItem::validate_trait_impl_block ( // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs // for example - specified_bound = get_predicate_from_bound (ref, impl_block.get_type ()); + specified_bound = get_predicate_from_bound (ref, impl_block.get_type (), + impl_block.get_polarity ()); + + // need to check that if this specified bound has super traits does this + // Self + // implement them? + specified_bound.validate_type_implements_super_traits ( + *self, impl_block.get_type (), impl_block.get_trait_ref ()); } bool is_trait_impl_block = !trait_reference->is_error (); diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 33570ff..1fe39aae 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -535,8 +535,8 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id, = impl_block_ty->lookup_predicate (trait_ref.get_defid ()); if (!predicate.is_error ()) impl_block_ty - = associated->setup_associated_types (prev_segment, - predicate); + = associated->setup_associated_types (prev_segment, predicate, + nullptr, false); } } diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index e56fa39..54f50ec 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -360,6 +360,13 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset, seg->as_string ().c_str ()); return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); } + else if (root_tyty == nullptr) + { + rust_error_at (seg->get_locus (), + "unknown reference for resolved name: %qs", + seg->as_string ().c_str ()); + return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + } return root_tyty; } diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc index 65f24c0..e028a0a 100644 --- a/gcc/rust/typecheck/rust-tyty-bounds.cc +++ b/gcc/rust/typecheck/rust-tyty-bounds.cc @@ -828,6 +828,65 @@ TypeBoundPredicate::is_equal (const TypeBoundPredicate &other) const return true; } +bool +TypeBoundPredicate::validate_type_implements_super_traits ( + TyTy::BaseType &self, HIR::Type &impl_type, HIR::Type &trait) const +{ + if (get_polarity () != BoundPolarity::RegularBound) + return true; + + auto &ptref = *get (); + for (auto &super : super_traits) + { + if (super.get_polarity () != BoundPolarity::RegularBound) + continue; + + if (!super.validate_type_implements_this (self, impl_type, trait)) + { + auto &sptref = *super.get (); + + // emit error + std::string fixit1 + = "required by this bound in: " + ptref.get_name (); + std::string fixit2 = "the trait " + sptref.get_name () + + " is not implemented for " + + impl_type.as_string (); + + rich_location r (line_table, trait.get_locus ()); + r.add_fixit_insert_after (super.get_locus (), fixit1.c_str ()); + r.add_fixit_insert_after (trait.get_locus (), fixit2.c_str ()); + rust_error_at (r, ErrorCode::E0277, + "the trait bound %<%s: %s%> is not satisfied", + impl_type.as_string ().c_str (), + sptref.get_name ().c_str ()); + + return false; + } + + if (!super.validate_type_implements_super_traits (self, impl_type, trait)) + return false; + } + + return true; +} + +bool +TypeBoundPredicate::validate_type_implements_this (TyTy::BaseType &self, + HIR::Type &impl_type, + HIR::Type &trait) const +{ + const auto &ptref = *get (); + auto probed_bounds = Resolver::TypeBoundsProbe::Probe (&self); + for (auto &elem : probed_bounds) + { + auto &tref = *(elem.first); + if (ptref.is_equal (tref)) + return true; + } + + return false; +} + // trait item reference const Resolver::TraitItemReference * diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h index b8e928d..3f0b912 100644 --- a/gcc/rust/typecheck/rust-tyty-subst.h +++ b/gcc/rust/typecheck/rust-tyty-subst.h @@ -125,7 +125,7 @@ public: std::vector<Region> subst) { RegionParamList list (num_regions); - for (size_t i = 0; i < subst.size (); i++) + for (size_t i = 0; i < MIN (num_regions, subst.size ()); i++) list.regions.at (i) = subst.at (i); for (size_t i = subst.size (); i < num_regions; i++) { diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 0bfd29d..e814f07 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -578,6 +578,14 @@ public: bool is_equal (const TypeBoundPredicate &other) const; + bool validate_type_implements_super_traits (TyTy::BaseType &self, + HIR::Type &impl_type, + HIR::Type &trait) const; + + bool validate_type_implements_this (TyTy::BaseType &self, + HIR::Type &impl_type, + HIR::Type &trait) const; + private: struct mark_is_error { |