From a3312784518b9fa95e43f9a2d773acb0c083147a Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Wed, 13 Jan 2016 01:24:34 -0500 Subject: [PATCH] HIR: add inclusive ranges, desugar all ranges (remove ExprRange) --- src/librustc_front/hir.rs | 2 - src/librustc_front/lowering.rs | 92 ++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs index dbc1d71517b..cf9952248a8 100644 --- a/src/librustc_front/hir.rs +++ b/src/librustc_front/hir.rs @@ -777,8 +777,6 @@ pub enum Expr_ { ExprTupField(P, Spanned), /// An indexing operation (`foo[2]`) ExprIndex(P, P), - /// A range (`1..2`, `1..`, or `..2`) - ExprRange(Option>, Option>), /// Variable reference, possibly containing `::` and/or type /// parameters, e.g. foo::bar::. diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index 0e7d9db37fd..5e39a7c817a 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -65,6 +65,7 @@ use std::collections::BTreeMap; use std::collections::HashMap; +use std::iter; use syntax::ast::*; use syntax::attr::{ThinAttributes, ThinAttributesExt}; use syntax::ext::mtwt; @@ -1213,9 +1214,74 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { ExprKind::Index(ref el, ref er) => { hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er)) } - ExprKind::Range(ref e1, ref e2) => { - hir::ExprRange(e1.as_ref().map(|x| lower_expr(lctx, x)), - e2.as_ref().map(|x| lower_expr(lctx, x))) + ExprKind::Range(ref e1, ref e2, lims) => { + fn make_struct(lctx: &LoweringContext, + ast_expr: &Expr, + path: &[&str], + fields: &[(&str, &P)]) -> P { + let strs = std_path(lctx, &iter::once(&"ops") + .chain(path) + .map(|s| *s) + .collect::>()); + + let structpath = path_global(ast_expr.span, strs); + + let hir_expr = if fields.len() == 0 { + expr_path(lctx, + structpath, + ast_expr.attrs.clone()) + } else { + expr_struct(lctx, + ast_expr.span, + structpath, + fields.into_iter().map(|&(s, e)| { + field(token::intern(s), + lower_expr(lctx, &**e), + ast_expr.span) + }).collect(), + None, + ast_expr.attrs.clone()) + }; + + signal_block_expr(lctx, + hir_vec![], + hir_expr, + ast_expr.span, + hir::PushUnstableBlock, + None) + } + + return cache_ids(lctx, e.id, |lctx| { + use syntax::ast::RangeLimits::*; + + match (e1, e2, lims) { + (&None, &None, HalfOpen) => + make_struct(lctx, e, &["RangeFull"], + &[]), + + (&Some(ref e1), &None, HalfOpen) => + make_struct(lctx, e, &["RangeFrom"], + &[("start", e1)]), + + (&None, &Some(ref e2), HalfOpen) => + make_struct(lctx, e, &["RangeTo"], + &[("end", e2)]), + + (&Some(ref e1), &Some(ref e2), HalfOpen) => + make_struct(lctx, e, &["Range"], + &[("start", e1), ("end", e2)]), + + (&None, &Some(ref e2), Closed) => + make_struct(lctx, e, &["RangeToInclusive"], + &[("end", e2)]), + + (&Some(ref e1), &Some(ref e2), Closed) => + make_struct(lctx, e, &["RangeInclusive", "NonEmpty"], + &[("start", e1), ("end", e2)]), + + _ => panic!("impossible range in AST"), + } + }); } ExprKind::Path(ref qself, ref path) => { let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| { @@ -1632,6 +1698,17 @@ fn arm(pats: hir::HirVec>, expr: P) -> hir::Arm { } } +fn field(name: Name, expr: P, span: Span) -> hir::Field { + hir::Field { + name: Spanned { + node: name, + span: span, + }, + span: span, + expr: expr, + } +} + fn expr_break(lctx: &LoweringContext, span: Span, attrs: ThinAttributes) -> P { expr(lctx, span, hir::ExprBreak(None), attrs) @@ -1681,6 +1758,15 @@ fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: hir::HirVec> expr(lctx, sp, hir::ExprTup(exprs), attrs) } +fn expr_struct(lctx: &LoweringContext, + sp: Span, + path: hir::Path, + fields: hir::HirVec, + e: Option>, + attrs: ThinAttributes) -> P { + expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs) +} + fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_, attrs: ThinAttributes) -> P { P(hir::Expr { -- 2.44.0