Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ast address-of #66671

Merged
merged 3 commits into from
Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor.visit_expr(left_expression);
visitor.visit_expr(right_expression)
}
ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
visitor.visit_expr(subexpression)
}
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
Expand Down
10 changes: 7 additions & 3 deletions src/librustc/hir/lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ impl LoweringContext<'_> {
let expr = P(self.lower_expr(expr));
hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
}
ExprKind::AddrOf(m, ref ohs) => {
ExprKind::AddrOf(k, m, ref ohs) => {
let ohs = P(self.lower_expr(ohs));
hir::ExprKind::AddrOf(m, ohs)
hir::ExprKind::AddrOf(k, m, ohs)
}
ExprKind::Let(ref pat, ref scrutinee) => self.lower_expr_let(e.span, pat, scrutinee),
ExprKind::If(ref cond, ref then, ref else_opt) => {
Expand Down Expand Up @@ -1339,7 +1339,11 @@ impl LoweringContext<'_> {
}

fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> hir::Expr {
self.expr(span, hir::ExprKind::AddrOf(hir::Mutability::Mutable, e), ThinVec::new())
self.expr(
span,
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mutable, e),
ThinVec::new(),
)
}

fn expr_unit(&mut self, sp: Span) -> hir::Expr {
Expand Down
38 changes: 28 additions & 10 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use syntax::source_map::Spanned;
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
pub use syntax::ast::{Mutability, Constness, Unsafety, Movability, CaptureBy, IsAuto, ImplPolarity};
pub use syntax::ast::{Mutability, Constness, Unsafety, Movability, CaptureBy};
pub use syntax::ast::{IsAuto, ImplPolarity, BorrowKind};
use syntax::attr::{InlineAttr, OptimizeAttr};
use syntax::symbol::{Symbol, kw};
use syntax::tokenstream::TokenStream;
Expand Down Expand Up @@ -1493,8 +1494,20 @@ impl Expr {
}
}

pub fn is_place_expr(&self) -> bool {
match self.kind {
// Whether this looks like a place expr, without checking for deref
// adjustments.
// This will return `true` in some potentially surprising cases such as
// `CONSTANT.field`.
pub fn is_syntactic_place_expr(&self) -> bool {
self.is_place_expr(|_| true)
}

// Whether this is a place expression.
// `allow_projections_from` should return `true` if indexing a field or
// index expression based on the given expression should be considered a
// place expression.
pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
match self.kind {
ExprKind::Path(QPath::Resolved(_, ref path)) => {
match path.res {
Res::Local(..)
Expand All @@ -1504,14 +1517,19 @@ impl Expr {
}
}

// Type ascription inherits its place expression kind from its
// operand. See:
// https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md#type-ascription-and-temporaries
ExprKind::Type(ref e, _) => {
e.is_place_expr()
e.is_place_expr(allow_projections_from)
}

ExprKind::Unary(UnDeref, _) |
ExprKind::Field(..) |
ExprKind::Index(..) => {
true
ExprKind::Unary(UnDeref, _) => true,

ExprKind::Field(ref base, _) |
ExprKind::Index(ref base, _) => {
allow_projections_from(base)
|| base.is_place_expr(allow_projections_from)
}

// Partially qualified paths in expressions can only legally
Expand Down Expand Up @@ -1646,8 +1664,8 @@ pub enum ExprKind {
/// Path to a definition, possibly containing lifetime or type parameters.
Path(QPath),

/// A referencing operation (i.e., `&a` or `&mut a`).
AddrOf(Mutability, P<Expr>),
/// A referencing operation (i.e., `&a`, `&mut a`, `&raw const a`, or `&raw mut a`).
AddrOf(BorrowKind, Mutability, P<Expr>),
/// A `break`, with an optional label to break.
Break(Destination, Option<P<Expr>>),
/// A `continue`, with an optional label.
Expand Down
35 changes: 19 additions & 16 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,16 +294,12 @@ impl<'a> State<'a> {
}
hir::TyKind::Ptr(ref mt) => {
self.s.word("*");
match mt.mutbl {
hir::Mutability::Mutable => self.word_nbsp("mut"),
hir::Mutability::Immutable => self.word_nbsp("const"),
}
self.print_type(&mt.ty);
self.print_mt(mt, true);
}
hir::TyKind::Rptr(ref lifetime, ref mt) => {
self.s.word("&");
self.print_opt_lifetime(lifetime);
self.print_mt(mt);
self.print_mt(mt, false);
}
hir::TyKind::Never => {
self.s.word("!");
Expand Down Expand Up @@ -1178,11 +1174,18 @@ impl<'a> State<'a> {
}

fn print_expr_addr_of(&mut self,
kind: hir::BorrowKind,
mutability: hir::Mutability,
expr: &hir::Expr)
{
{
self.s.word("&");
self.print_mutability(mutability);
match kind {
hir::BorrowKind::Ref => self.print_mutability(mutability, false),
hir::BorrowKind::Raw => {
self.word_nbsp("raw");
self.print_mutability(mutability, true);
}
}
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
}

Expand Down Expand Up @@ -1225,8 +1228,8 @@ impl<'a> State<'a> {
hir::ExprKind::Unary(op, ref expr) => {
self.print_expr_unary(op, &expr);
}
hir::ExprKind::AddrOf(m, ref expr) => {
self.print_expr_addr_of(m, &expr);
hir::ExprKind::AddrOf(k, m, ref expr) => {
self.print_expr_addr_of(k, m, &expr);
}
hir::ExprKind::Lit(ref lit) => {
self.print_literal(&lit);
Expand Down Expand Up @@ -1629,11 +1632,11 @@ impl<'a> State<'a> {
match binding_mode {
hir::BindingAnnotation::Ref => {
self.word_nbsp("ref");
self.print_mutability(hir::Mutability::Immutable);
self.print_mutability(hir::Mutability::Immutable, false);
}
hir::BindingAnnotation::RefMut => {
self.word_nbsp("ref");
self.print_mutability(hir::Mutability::Mutable);
self.print_mutability(hir::Mutability::Mutable, false);
}
hir::BindingAnnotation::Unannotated => {}
hir::BindingAnnotation::Mutable => {
Expand Down Expand Up @@ -2060,15 +2063,15 @@ impl<'a> State<'a> {
}
}

pub fn print_mutability(&mut self, mutbl: hir::Mutability) {
pub fn print_mutability(&mut self, mutbl: hir::Mutability, print_const: bool) {
match mutbl {
hir::Mutability::Mutable => self.word_nbsp("mut"),
hir::Mutability::Immutable => {},
hir::Mutability::Immutable => if print_const { self.word_nbsp("const") },
}
}

pub fn print_mt(&mut self, mt: &hir::MutTy) {
self.print_mutability(mt.mutbl);
pub fn print_mt(&mut self, mt: &hir::MutTy, print_const: bool) {
self.print_mutability(mt.mutbl, print_const);
self.print_type(&mt.ty)
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
self.consume_exprs(exprs);
}

hir::ExprKind::AddrOf(m, ref base) => { // &base
hir::ExprKind::AddrOf(_, m, ref base) => { // &base
// make sure that the thing we are pointing out stays valid
// for the lifetime `scope_r` of the resulting ptr:
let bk = ty::BorrowKind::from_mutbl(m);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,7 @@ fn resolve_local<'tcx>(
blk_id: Option<Scope>,
) {
match expr.kind {
hir::ExprKind::AddrOf(_, ref subexpr) => {
hir::ExprKind::AddrOf(_, _, ref subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
record_rvalue_scope(visitor, &subexpr, blk_id);
}
Expand Down Expand Up @@ -1301,7 +1301,7 @@ fn resolve_local<'tcx>(
visitor.scope_tree.record_rvalue_scope(expr.hir_id.local_id, blk_scope);

match expr.kind {
hir::ExprKind::AddrOf(_, ref subexpr) |
hir::ExprKind::AddrOf(_, _, ref subexpr) |
hir::ExprKind::Unary(hir::UnDeref, ref subexpr) |
hir::ExprKind::Field(ref subexpr, _) |
hir::ExprKind::Index(ref subexpr, _) => {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ E0741: include_str!("./error_codes/E0741.md"),
E0742: include_str!("./error_codes/E0742.md"),
E0743: include_str!("./error_codes/E0743.md"),
E0744: include_str!("./error_codes/E0744.md"),
E0745: include_str!("./error_codes/E0745.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
Expand Down
20 changes: 20 additions & 0 deletions src/librustc_error_codes/error_codes/E0745.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Cannot take address of temporary value.

Erroneous code example:

```compile_fail,E0745
# #![feature(raw_ref_op)]
fn temp_address() {
let ptr = &raw const 2; // ERROR
}
```

To avoid the error, first bind the temporary to a named local variable.

```ignore
matthewjasper marked this conversation as resolved.
Show resolved Hide resolved
# #![feature(raw_ref_op)]
fn temp_address() {
let val = 2;
let ptr = &raw const val;
}
```
Loading