Rollup merge of #50421 - kennytm:fix-50415-ice-when-returning-range-inclusive-from-closure, r=michaelwoerister

Fix ICE when using a..=b in a closure.

Fix #50415.
This commit is contained in:
kennytm 2018-05-03 23:42:36 +08:00
commit dfb32af87d
No known key found for this signature in database
GPG key ID: FEF6C8051D0E013C
6 changed files with 34 additions and 13 deletions

View file

@ -3121,9 +3121,9 @@ impl<'a> LoweringContext<'a> {
}
// Desugar `<start>..=<end>` to `std::ops::RangeInclusive::new(<start>, <end>)`
ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
// FIXME: Use head_sp directly after RangeInclusive::new() is stabilized in stage0.
// FIXME: Use e.span directly after RangeInclusive::new() is stabilized in stage0.
let span = self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
let id = self.lower_node_id(e.id);
let id = self.next_id();
let e1 = self.lower_expr(e1);
let e2 = self.lower_expr(e2);
let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], false));

View file

@ -1252,10 +1252,7 @@ impl LitKind {
match *self {
LitKind::Str(string, ast::StrStyle::Cooked) => {
let mut escaped = String::new();
for ch in string.as_str().chars() {
escaped.extend(ch.escape_unicode());
}
let escaped = string.as_str().escape_default();
Token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None)
}
LitKind::Str(string, ast::StrStyle::Raw(n)) => {

View file

@ -25,6 +25,7 @@
#![feature(non_exhaustive)]
#![feature(const_atomic_usize_new)]
#![feature(rustc_attrs)]
#![feature(str_escape)]
#![recursion_limit="256"]

View file

@ -298,14 +298,10 @@ pub fn char_lit(lit: &str, diag: Option<(Span, &Handler)>) -> (char, isize) {
}
}
pub fn escape_default(s: &str) -> String {
s.chars().map(char::escape_default).flat_map(|x| x).collect()
}
/// Parse a string representing a string literal into its final form. Does
/// unescaping.
pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
debug!("parse_str_lit: given {}", escape_default(lit));
debug!("str_lit: given {}", lit.escape_default());
let mut res = String::with_capacity(lit.len());
let error = |i| format!("lexer should have rejected {} at {}", lit, i);
@ -374,7 +370,7 @@ pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
/// Parse a string representing a raw string literal into its final form. The
/// only operation this does is convert embedded CRLF into a single LF.
pub fn raw_str_lit(lit: &str) -> String {
debug!("raw_str_lit: given {}", escape_default(lit));
debug!("raw_str_lit: given {}", lit.escape_default());
let mut res = String::with_capacity(lit.len());
let mut chars = lit.chars().peekable();

View file

@ -656,7 +656,7 @@ pub trait PrintState<'a> {
style: ast::StrStyle) -> io::Result<()> {
let st = match style {
ast::StrStyle::Cooked => {
(format!("\"{}\"", parse::escape_default(st)))
(format!("\"{}\"", st.escape_default()))
}
ast::StrStyle::Raw(n) => {
(format!("r{delim}\"{string}\"{delim}",

View file

@ -0,0 +1,27 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
// -------- Simplified test case --------
let _ = || 0..=1;
// -------- Original test case --------
let full_length = 1024;
let range = {
// do some stuff, omit here
None
};
let range = range.map(|(s, t)| s..=t).unwrap_or(0..=(full_length-1));
assert_eq!(range, 0..=1023);
}