aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/ChangeLog159
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc3
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc8
-rw-r--r--gcc/rust/ast/rust-stmt.h29
-rw-r--r--gcc/rust/backend/rust-compile-base.cc14
-rw-r--r--gcc/rust/backend/rust-compile-base.h8
-rw-r--r--gcc/rust/backend/rust-compile-context.h5
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc11
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc2
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc21
-rw-r--r--gcc/rust/backend/rust-compile-type.cc31
-rw-r--r--gcc/rust/backend/rust-compile-type.h2
-rw-r--r--gcc/rust/backend/rust-constexpr.cc6
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/.cargo/config.toml5
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock10
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml10
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml2
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs138
-rw-r--r--gcc/rust/checks/errors/rust-ast-validation.cc2
-rw-r--r--gcc/rust/expand/rust-macro-builtins-log-debug.cc2
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc4
-rw-r--r--gcc/rust/hir/rust-ast-lower-stmt.cc14
-rw-r--r--gcc/rust/hir/rust-hir-dump.cc8
-rw-r--r--gcc/rust/hir/tree/rust-hir-stmt.cc12
-rw-r--r--gcc/rust/hir/tree/rust-hir-stmt.h16
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.cc3
-rw-r--r--gcc/rust/parse/rust-parse-impl.h6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h7
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc17
-rw-r--r--gcc/rust/resolve/rust-forever-stack.h12
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx46
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc5
-rw-r--r--gcc/rust/typecheck/rust-hir-dot-operator.cc7
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-reference.h7
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc26
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.cc13
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc7
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc59
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty.h8
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
{