Skip to content

Commit ccce2c6

Browse files
committed
Auto merge of #40764 - arielb1:range-nodes, r=eddyb
keep the AST node-id when lowering ExprKind::Range When the Range expression is the root of a constant, its node-id is used for the def-id of the body, so it has to be preserved in the AST -> HIR lowering. Fixes #40749. r? @eddyb beta-nominating because regression
2 parents 7846dbe + 8ffe406 commit ccce2c6

File tree

2 files changed

+52
-59
lines changed

2 files changed

+52
-59
lines changed

src/librustc/hir/lowering.rs

+36-59
Original file line numberDiff line numberDiff line change
@@ -1900,57 +1900,45 @@ impl<'a> LoweringContext<'a> {
19001900
hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
19011901
}
19021902
ExprKind::Range(ref e1, ref e2, lims) => {
1903-
fn make_struct(this: &mut LoweringContext,
1904-
ast_expr: &Expr,
1905-
path: &[&str],
1906-
fields: &[(&str, &P<Expr>)]) -> hir::Expr {
1907-
let struct_path = &iter::once(&"ops").chain(path).map(|s| *s)
1908-
.collect::<Vec<_>>();
1909-
let unstable_span = this.allow_internal_unstable("...", ast_expr.span);
1910-
1911-
if fields.len() == 0 {
1912-
this.expr_std_path(unstable_span, struct_path,
1913-
ast_expr.attrs.clone())
1914-
} else {
1915-
let fields = fields.into_iter().map(|&(s, e)| {
1916-
let expr = P(this.lower_expr(&e));
1917-
let unstable_span = this.allow_internal_unstable("...", e.span);
1918-
this.field(Symbol::intern(s), expr, unstable_span)
1919-
}).collect();
1920-
let attrs = ast_expr.attrs.clone();
1921-
1922-
this.expr_std_struct(unstable_span, struct_path, fields, None, attrs)
1923-
}
1924-
}
1925-
19261903
use syntax::ast::RangeLimits::*;
19271904

1928-
return match (e1, e2, lims) {
1929-
(&None, &None, HalfOpen) =>
1930-
make_struct(self, e, &["RangeFull"], &[]),
1931-
1932-
(&Some(ref e1), &None, HalfOpen) =>
1933-
make_struct(self, e, &["RangeFrom"],
1934-
&[("start", e1)]),
1935-
1936-
(&None, &Some(ref e2), HalfOpen) =>
1937-
make_struct(self, e, &["RangeTo"],
1938-
&[("end", e2)]),
1939-
1940-
(&Some(ref e1), &Some(ref e2), HalfOpen) =>
1941-
make_struct(self, e, &["Range"],
1942-
&[("start", e1), ("end", e2)]),
1943-
1944-
(&None, &Some(ref e2), Closed) =>
1945-
make_struct(self, e, &["RangeToInclusive"],
1946-
&[("end", e2)]),
1947-
1948-
(&Some(ref e1), &Some(ref e2), Closed) =>
1949-
make_struct(self, e, &["RangeInclusive", "NonEmpty"],
1950-
&[("start", e1), ("end", e2)]),
1905+
let (path, variant) = match (e1, e2, lims) {
1906+
(&None, &None, HalfOpen) => ("RangeFull", None),
1907+
(&Some(..), &None, HalfOpen) => ("RangeFrom", None),
1908+
(&None, &Some(..), HalfOpen) => ("RangeTo", None),
1909+
(&Some(..), &Some(..), HalfOpen) => ("Range", None),
1910+
(&None, &Some(..), Closed) => ("RangeToInclusive", None),
1911+
(&Some(..), &Some(..), Closed) => ("RangeInclusive", Some("NonEmpty")),
1912+
(_, &None, Closed) =>
1913+
panic!(self.diagnostic().span_fatal(
1914+
e.span, "inclusive range with no end")),
1915+
};
19511916

1952-
_ => panic!(self.diagnostic()
1953-
.span_fatal(e.span, "inclusive range with no end")),
1917+
let fields =
1918+
e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e)))
1919+
.map(|(s, e)| {
1920+
let expr = P(self.lower_expr(&e));
1921+
let unstable_span = self.allow_internal_unstable("...", e.span);
1922+
self.field(Symbol::intern(s), expr, unstable_span)
1923+
}).collect::<P<[hir::Field]>>();
1924+
1925+
let is_unit = fields.is_empty();
1926+
let unstable_span = self.allow_internal_unstable("...", e.span);
1927+
let struct_path =
1928+
iter::once("ops").chain(iter::once(path)).chain(variant)
1929+
.collect::<Vec<_>>();
1930+
let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
1931+
let struct_path = hir::QPath::Resolved(None, P(struct_path));
1932+
1933+
return hir::Expr {
1934+
id: self.lower_node_id(e.id),
1935+
node: if is_unit {
1936+
hir::ExprPath(struct_path)
1937+
} else {
1938+
hir::ExprStruct(struct_path, fields, None)
1939+
},
1940+
span: unstable_span,
1941+
attrs: e.attrs.clone(),
19541942
};
19551943
}
19561944
ExprKind::Path(ref qself, ref path) => {
@@ -2613,17 +2601,6 @@ impl<'a> LoweringContext<'a> {
26132601
P(self.expr(sp, hir::ExprTup(exprs), ThinVec::new()))
26142602
}
26152603

2616-
fn expr_std_struct(&mut self,
2617-
span: Span,
2618-
components: &[&str],
2619-
fields: hir::HirVec<hir::Field>,
2620-
e: Option<P<hir::Expr>>,
2621-
attrs: ThinVec<Attribute>) -> hir::Expr {
2622-
let path = self.std_path(span, components, false);
2623-
let qpath = hir::QPath::Resolved(None, P(path));
2624-
self.expr(span, hir::ExprStruct(qpath, fields, e), attrs)
2625-
}
2626-
26272604
fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> hir::Expr {
26282605
hir::Expr {
26292606
id: self.next_id(),

src/test/compile-fail/issue-40749.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
[0; ..10];
13+
//~^ ERROR mismatched types
14+
//~| expected type `usize`
15+
//~| found type `std::ops::RangeTo<{integer}>`
16+
}

0 commit comments

Comments
 (0)