}
tree
-HIRCompileBase::address_expression (tree expr, location_t location)
+HIRCompileBase::address_expression (tree expr, location_t location, tree ptrty)
{
if (expr == error_mark_node)
return error_mark_node;
if (!mark_addressable (expr, location))
return error_mark_node;
- return build_fold_addr_expr_loc (location, expr);
+ if (ptrty == NULL || ptrty == error_mark_node)
+ ptrty = build_pointer_type (TREE_TYPE (expr));
+
+ return build_fold_addr_expr_with_type_loc (location, expr, ptrty);
}
tree
public:
virtual ~HIRCompileBase () {}
- static tree address_expression (tree expr, location_t locus);
+ static tree address_expression (tree expr, location_t locus,
+ tree ptrty = NULL_TREE);
static tree compile_constant_expr (
Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type,
&tyty))
return;
- translated = address_expression (main_expr, expr.get_locus ());
+ tree expected_type = TyTyResolveCompile::compile (ctx, tyty);
+ translated = address_expression (main_expr, expr.get_locus (), expected_type);
}
void
public:
static tree compile (HIR::ExternalItem *item, Context *ctx,
TyTy::BaseType *concrete = nullptr,
- bool is_query_mode = false,
location_t ref_locus = UNDEF_LOCATION)
{
CompileExternItem compiler (ctx, concrete, ref_locus);
item->accept_vis (compiler);
-
- if (is_query_mode && compiler.reference == error_mark_node)
- rust_internal_error_at (ref_locus, "failed to compile extern item: %s",
- item->as_string ().c_str ());
-
return compiler.reference;
}
HIR::ExternalItem *resolved_extern_item = hir_extern_item->first;
if (!lookup->has_substitutions_defined ())
return CompileExternItem::compile (resolved_extern_item, ctx, nullptr,
- true, expr_locus);
+ expr_locus);
else
return CompileExternItem::compile (resolved_extern_item, ctx, lookup,
- true, expr_locus);
+ expr_locus);
}
else
{
void
ASTLoweringExpr::visit (AST::BorrowExpr &expr)
{
- if (expr.is_raw_borrow ())
- rust_unreachable ();
-
HIR::Expr *borrow_lvalue
= ASTLoweringExpr::translate (expr.get_borrowed_expr ());
auto *borrow_expr
= new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_lvalue),
- expr.get_mutability (), expr.get_outer_attrs (),
- expr.get_locus ());
+ expr.get_mutability (), expr.is_raw_borrow (),
+ expr.get_outer_attrs (), expr.get_locus ());
if (expr.get_is_double_borrow ())
{
borrow_expr
= new HIR::BorrowExpr (mapping,
std::unique_ptr<HIR::Expr> (borrow_expr),
- expr.get_mutability (), expr.get_outer_attrs (),
- expr.get_locus ());
+ expr.get_mutability (), expr.is_raw_borrow (),
+ expr.get_outer_attrs (), expr.get_locus ());
}
translated = borrow_expr;
BorrowExpr::BorrowExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
- AST::AttrVec outer_attribs, location_t locus)
+ bool raw, AST::AttrVec outer_attribs, location_t locus)
: OperatorExpr (std::move (mappings), std::move (borrow_lvalue),
std::move (outer_attribs), locus),
- mut (mut)
+ mut (mut), raw (raw)
{}
DereferenceExpr::DereferenceExpr (Analysis::NodeMapping mappings,
class BorrowExpr : public OperatorExpr
{
Mutability mut;
+ bool raw;
public:
std::string as_string () const override;
BorrowExpr (Analysis::NodeMapping mappings,
- std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
+ std::unique_ptr<Expr> borrow_lvalue, Mutability mut, bool raw,
AST::AttrVec outer_attribs, location_t locus);
void accept_vis (HIRFullVisitor &vis) override;
Mutability get_mut () const { return mut; }
bool is_mut () const { return mut == Mutability::Mut; }
+ bool is_raw_borrow () const { return raw; }
protected:
/* Use covariance to implement clone function as returning this object rather
}
}
+ if (expr.is_raw_borrow ())
+ {
+ infered = new TyTy::PointerType (expr.get_mappings ().get_hirid (),
+ TyTy::TyVar (resolved_base->get_ref ()),
+ expr.get_mut ());
+
+ return;
+ }
+
infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
TyTy::TyVar (resolved_base->get_ref ()),
expr.get_mut ());
--- /dev/null
+// { dg-options "-w" }
+#![feature(raw_ref_op)]
+
+const pq1: () = {
+ let mut x = 2;
+ &raw mut x;
+}; //~ mutable reference
+
+static B: () = {
+ let mut x = 2;
+ &raw mut x;
+}; //~ mutable reference
+
+static mut C: () = {
+ let mut x = 2;
+ &raw mut x;
+}; //~ mutable reference
+
+const fn foo() {
+ let mut x = 0;
+ let y = &raw mut x; //~ mutable reference
+}
+
+fn main() {}