Auto merge of #125918 - oli-obk:const_block_ice, r=compiler-errors
Revert: create const block bodies in typeck via query feeding as per the discussion in https://github.com/rust-lang/rust/pull/125806#discussion_r1622563948 It was a mistake to try to shoehorn const blocks and some specific anon consts into the same box and feed them during typeck. It turned out not simplifying anything (my hope was that we could feed `type_of` to start avoiding the huge HIR matcher, but that didn't work out), but instead making a few things more fragile. reverts the const-block-specific parts of https://github.com/rust-lang/rust/pull/124650 `@bors` rollup=never had a small perf impact previously fixes https://github.com/rust-lang/rust/issues/125846 r? `@compiler-errors`
This commit is contained in:
commit
1be24d70ce
@ -1392,7 +1392,7 @@ pub enum ExprKind {
|
|||||||
/// An array (e.g, `[a, b, c, d]`).
|
/// An array (e.g, `[a, b, c, d]`).
|
||||||
Array(ThinVec<P<Expr>>),
|
Array(ThinVec<P<Expr>>),
|
||||||
/// Allow anonymous constants from an inline `const` block
|
/// Allow anonymous constants from an inline `const` block
|
||||||
ConstBlock(P<Expr>),
|
ConstBlock(AnonConst),
|
||||||
/// A function call
|
/// A function call
|
||||||
///
|
///
|
||||||
/// The first field resolves to the function itself,
|
/// The first field resolves to the function itself,
|
||||||
|
@ -1417,7 +1417,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||||||
match kind {
|
match kind {
|
||||||
ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis),
|
ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis),
|
||||||
ExprKind::ConstBlock(anon_const) => {
|
ExprKind::ConstBlock(anon_const) => {
|
||||||
vis.visit_expr(anon_const);
|
vis.visit_anon_const(anon_const);
|
||||||
}
|
}
|
||||||
ExprKind::Repeat(expr, count) => {
|
ExprKind::Repeat(expr, count) => {
|
||||||
vis.visit_expr(expr);
|
vis.visit_expr(expr);
|
||||||
|
@ -959,7 +959,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
|
|||||||
ExprKind::Array(subexpressions) => {
|
ExprKind::Array(subexpressions) => {
|
||||||
walk_list!(visitor, visit_expr, subexpressions);
|
walk_list!(visitor, visit_expr, subexpressions);
|
||||||
}
|
}
|
||||||
ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_expr(anon_const)),
|
ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)),
|
||||||
ExprKind::Repeat(element, count) => {
|
ExprKind::Repeat(element, count) => {
|
||||||
try_visit!(visitor.visit_expr(element));
|
try_visit!(visitor.visit_expr(element));
|
||||||
try_visit!(visitor.visit_anon_const(count));
|
try_visit!(visitor.visit_anon_const(count));
|
||||||
|
@ -75,8 +75,12 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
|||||||
let kind = match &e.kind {
|
let kind = match &e.kind {
|
||||||
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
|
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
|
||||||
ExprKind::ConstBlock(c) => {
|
ExprKind::ConstBlock(c) => {
|
||||||
self.has_inline_consts = true;
|
let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock {
|
||||||
hir::ExprKind::ConstBlock(self.lower_expr(c))
|
def_id: this.local_def_id(c.id),
|
||||||
|
hir_id: this.lower_node_id(c.id),
|
||||||
|
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
||||||
|
});
|
||||||
|
hir::ExprKind::ConstBlock(c)
|
||||||
}
|
}
|
||||||
ExprKind::Repeat(expr, count) => {
|
ExprKind::Repeat(expr, count) => {
|
||||||
let expr = self.lower_expr(expr);
|
let expr = self.lower_expr(expr);
|
||||||
|
@ -236,6 +236,14 @@ fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_inline_const(&mut self, constant: &'hir ConstBlock) {
|
||||||
|
self.insert(DUMMY_SP, constant.hir_id, Node::ConstBlock(constant));
|
||||||
|
|
||||||
|
self.with_parent(constant.hir_id, |this| {
|
||||||
|
intravisit::walk_inline_const(this, constant);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
|
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
|
||||||
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
|
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
|
||||||
|
|
||||||
|
@ -96,8 +96,6 @@ struct LoweringContext<'a, 'hir> {
|
|||||||
|
|
||||||
/// Bodies inside the owner being lowered.
|
/// Bodies inside the owner being lowered.
|
||||||
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
|
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
|
||||||
/// Whether there were inline consts that typeck will split out into bodies
|
|
||||||
has_inline_consts: bool,
|
|
||||||
/// Attributes inside the owner being lowered.
|
/// Attributes inside the owner being lowered.
|
||||||
attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>,
|
attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>,
|
||||||
/// Collect items that were created by lowering the current owner.
|
/// Collect items that were created by lowering the current owner.
|
||||||
@ -160,7 +158,6 @@ fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
|
|||||||
item_local_id_counter: hir::ItemLocalId::ZERO,
|
item_local_id_counter: hir::ItemLocalId::ZERO,
|
||||||
node_id_to_local_id: Default::default(),
|
node_id_to_local_id: Default::default(),
|
||||||
trait_map: Default::default(),
|
trait_map: Default::default(),
|
||||||
has_inline_consts: false,
|
|
||||||
|
|
||||||
// Lowering state.
|
// Lowering state.
|
||||||
catch_scope: None,
|
catch_scope: None,
|
||||||
@ -570,7 +567,6 @@ fn with_hir_id_owner(
|
|||||||
|
|
||||||
let current_attrs = std::mem::take(&mut self.attrs);
|
let current_attrs = std::mem::take(&mut self.attrs);
|
||||||
let current_bodies = std::mem::take(&mut self.bodies);
|
let current_bodies = std::mem::take(&mut self.bodies);
|
||||||
let current_has_inline_consts = std::mem::take(&mut self.has_inline_consts);
|
|
||||||
let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
|
let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
|
||||||
let current_trait_map = std::mem::take(&mut self.trait_map);
|
let current_trait_map = std::mem::take(&mut self.trait_map);
|
||||||
let current_owner =
|
let current_owner =
|
||||||
@ -597,7 +593,6 @@ fn with_hir_id_owner(
|
|||||||
|
|
||||||
self.attrs = current_attrs;
|
self.attrs = current_attrs;
|
||||||
self.bodies = current_bodies;
|
self.bodies = current_bodies;
|
||||||
self.has_inline_consts = current_has_inline_consts;
|
|
||||||
self.node_id_to_local_id = current_node_ids;
|
self.node_id_to_local_id = current_node_ids;
|
||||||
self.trait_map = current_trait_map;
|
self.trait_map = current_trait_map;
|
||||||
self.current_hir_id_owner = current_owner;
|
self.current_hir_id_owner = current_owner;
|
||||||
@ -634,7 +629,6 @@ fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInf
|
|||||||
let attrs = std::mem::take(&mut self.attrs);
|
let attrs = std::mem::take(&mut self.attrs);
|
||||||
let mut bodies = std::mem::take(&mut self.bodies);
|
let mut bodies = std::mem::take(&mut self.bodies);
|
||||||
let trait_map = std::mem::take(&mut self.trait_map);
|
let trait_map = std::mem::take(&mut self.trait_map);
|
||||||
let has_inline_consts = std::mem::take(&mut self.has_inline_consts);
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
for (id, attrs) in attrs.iter() {
|
for (id, attrs) in attrs.iter() {
|
||||||
@ -652,7 +646,7 @@ fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInf
|
|||||||
self.tcx.hash_owner_nodes(node, &bodies, &attrs);
|
self.tcx.hash_owner_nodes(node, &bodies, &attrs);
|
||||||
let num_nodes = self.item_local_id_counter.as_usize();
|
let num_nodes = self.item_local_id_counter.as_usize();
|
||||||
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
|
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
|
||||||
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies, has_inline_consts };
|
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
|
||||||
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
|
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
|
||||||
|
|
||||||
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
|
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
|
||||||
|
@ -380,9 +380,8 @@ pub(super) fn print_expr_outer_attr_style(
|
|||||||
ast::ExprKind::Array(exprs) => {
|
ast::ExprKind::Array(exprs) => {
|
||||||
self.print_expr_vec(exprs);
|
self.print_expr_vec(exprs);
|
||||||
}
|
}
|
||||||
ast::ExprKind::ConstBlock(expr) => {
|
ast::ExprKind::ConstBlock(anon_const) => {
|
||||||
self.word_space("const");
|
self.print_expr_anon_const(anon_const, attrs);
|
||||||
self.print_expr(expr, FixupContext::default());
|
|
||||||
}
|
}
|
||||||
ast::ExprKind::Repeat(element, count) => {
|
ast::ExprKind::Repeat(element, count) => {
|
||||||
self.print_expr_repeat(element, count);
|
self.print_expr_repeat(element, count);
|
||||||
|
@ -38,6 +38,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
|
|||||||
match node {
|
match node {
|
||||||
hir::Node::Ctor(_)
|
hir::Node::Ctor(_)
|
||||||
| hir::Node::AnonConst(_)
|
| hir::Node::AnonConst(_)
|
||||||
|
| hir::Node::ConstBlock(_)
|
||||||
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => {
|
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => {
|
||||||
hir::Constness::Const
|
hir::Constness::Const
|
||||||
}
|
}
|
||||||
@ -56,7 +57,6 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
|
|||||||
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
||||||
}
|
}
|
||||||
hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
|
hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
|
||||||
hir::Node::Expr(e) if let hir::ExprKind::ConstBlock(_) = e.kind => hir::Constness::Const,
|
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(fn_kind) = node.fn_kind() {
|
if let Some(fn_kind) = node.fn_kind() {
|
||||||
if fn_kind.constness() == hir::Constness::Const {
|
if fn_kind.constness() == hir::Constness::Const {
|
||||||
|
@ -907,9 +907,6 @@ pub struct OwnerNodes<'tcx> {
|
|||||||
pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
|
pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
|
||||||
/// Content of local bodies.
|
/// Content of local bodies.
|
||||||
pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
|
pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
|
||||||
/// Whether the body contains inline constants that are created for the query system during typeck
|
|
||||||
/// of the body.
|
|
||||||
pub has_inline_consts: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> OwnerNodes<'tcx> {
|
impl<'tcx> OwnerNodes<'tcx> {
|
||||||
@ -1626,6 +1623,14 @@ pub struct AnonConst {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An inline constant expression `const { something }`.
|
||||||
|
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||||
|
pub struct ConstBlock {
|
||||||
|
pub hir_id: HirId,
|
||||||
|
pub def_id: LocalDefId,
|
||||||
|
pub body: BodyId,
|
||||||
|
}
|
||||||
|
|
||||||
/// An expression.
|
/// An expression.
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub struct Expr<'hir> {
|
pub struct Expr<'hir> {
|
||||||
@ -1912,7 +1917,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
|
|||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub enum ExprKind<'hir> {
|
pub enum ExprKind<'hir> {
|
||||||
/// Allow anonymous constants from an inline `const` block
|
/// Allow anonymous constants from an inline `const` block
|
||||||
ConstBlock(&'hir Expr<'hir>),
|
ConstBlock(ConstBlock),
|
||||||
/// An array (e.g., `[a, b, c, d]`).
|
/// An array (e.g., `[a, b, c, d]`).
|
||||||
Array(&'hir [Expr<'hir>]),
|
Array(&'hir [Expr<'hir>]),
|
||||||
/// A function call.
|
/// A function call.
|
||||||
@ -3650,6 +3655,7 @@ pub enum Node<'hir> {
|
|||||||
Variant(&'hir Variant<'hir>),
|
Variant(&'hir Variant<'hir>),
|
||||||
Field(&'hir FieldDef<'hir>),
|
Field(&'hir FieldDef<'hir>),
|
||||||
AnonConst(&'hir AnonConst),
|
AnonConst(&'hir AnonConst),
|
||||||
|
ConstBlock(&'hir ConstBlock),
|
||||||
Expr(&'hir Expr<'hir>),
|
Expr(&'hir Expr<'hir>),
|
||||||
ExprField(&'hir ExprField<'hir>),
|
ExprField(&'hir ExprField<'hir>),
|
||||||
Stmt(&'hir Stmt<'hir>),
|
Stmt(&'hir Stmt<'hir>),
|
||||||
@ -3710,6 +3716,7 @@ pub fn ident(&self) -> Option<Ident> {
|
|||||||
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
|
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
|
||||||
Node::Param(..)
|
Node::Param(..)
|
||||||
| Node::AnonConst(..)
|
| Node::AnonConst(..)
|
||||||
|
| Node::ConstBlock(..)
|
||||||
| Node::Expr(..)
|
| Node::Expr(..)
|
||||||
| Node::Stmt(..)
|
| Node::Stmt(..)
|
||||||
| Node::Block(..)
|
| Node::Block(..)
|
||||||
@ -3807,6 +3814,7 @@ pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
|
Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
|
||||||
|
Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
|
||||||
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -3875,6 +3883,7 @@ pub fn fn_kind(self) -> Option<FnKind<'hir>> {
|
|||||||
expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
|
expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
|
||||||
expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
|
expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
|
||||||
expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
|
expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
|
||||||
|
expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
|
||||||
expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
|
expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
|
||||||
expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
|
expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
|
||||||
expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
|
expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
|
||||||
|
@ -344,6 +344,9 @@ fn visit_array_length(&mut self, len: &'v ArrayLen<'v>) -> Self::Result {
|
|||||||
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
|
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
|
||||||
walk_anon_const(self, c)
|
walk_anon_const(self, c)
|
||||||
}
|
}
|
||||||
|
fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result {
|
||||||
|
walk_inline_const(self, c)
|
||||||
|
}
|
||||||
fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result {
|
fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result {
|
||||||
walk_expr(self, ex)
|
walk_expr(self, ex)
|
||||||
}
|
}
|
||||||
@ -718,6 +721,14 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo
|
|||||||
visitor.visit_nested_body(constant.body)
|
visitor.visit_nested_body(constant.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_inline_const<'v, V: Visitor<'v>>(
|
||||||
|
visitor: &mut V,
|
||||||
|
constant: &'v ConstBlock,
|
||||||
|
) -> V::Result {
|
||||||
|
try_visit!(visitor.visit_id(constant.hir_id));
|
||||||
|
visitor.visit_nested_body(constant.body)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result {
|
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result {
|
||||||
try_visit!(visitor.visit_id(expression.hir_id));
|
try_visit!(visitor.visit_id(expression.hir_id));
|
||||||
match expression.kind {
|
match expression.kind {
|
||||||
@ -725,7 +736,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
|
|||||||
walk_list!(visitor, visit_expr, subexpressions);
|
walk_list!(visitor, visit_expr, subexpressions);
|
||||||
}
|
}
|
||||||
ExprKind::ConstBlock(ref const_block) => {
|
ExprKind::ConstBlock(ref const_block) => {
|
||||||
try_visit!(visitor.visit_expr(const_block))
|
try_visit!(visitor.visit_inline_const(const_block))
|
||||||
}
|
}
|
||||||
ExprKind::Repeat(ref element, ref count) => {
|
ExprKind::Repeat(ref element, ref count) => {
|
||||||
try_visit!(visitor.visit_expr(element));
|
try_visit!(visitor.visit_expr(element));
|
||||||
|
@ -93,8 +93,7 @@ fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|||||||
// `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing
|
// `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing
|
||||||
// the body satisfies the condition of two nodes being different have different
|
// the body satisfies the condition of two nodes being different have different
|
||||||
// `hash_stable` results.
|
// `hash_stable` results.
|
||||||
let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _, has_inline_consts: _ } =
|
let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _ } = *self;
|
||||||
*self;
|
|
||||||
opt_hash_including_bodies.unwrap().hash_stable(hcx, hasher);
|
opt_hash_including_bodies.unwrap().hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,14 +407,11 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
|
|||||||
match expr.kind {
|
match expr.kind {
|
||||||
// Manually recurse over closures and inline consts, because they are the only
|
// Manually recurse over closures and inline consts, because they are the only
|
||||||
// case of nested bodies that share the parent environment.
|
// case of nested bodies that share the parent environment.
|
||||||
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
|
hir::ExprKind::Closure(&hir::Closure { body, .. })
|
||||||
|
| hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => {
|
||||||
let body = visitor.tcx.hir().body(body);
|
let body = visitor.tcx.hir().body(body);
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
}
|
}
|
||||||
hir::ExprKind::ConstBlock(expr) => visitor.enter_body(expr.hir_id, |this| {
|
|
||||||
this.cx.var_parent = None;
|
|
||||||
resolve_local(this, None, Some(expr));
|
|
||||||
}),
|
|
||||||
hir::ExprKind::AssignOp(_, left_expr, right_expr) => {
|
hir::ExprKind::AssignOp(_, left_expr, right_expr) => {
|
||||||
debug!(
|
debug!(
|
||||||
"resolve_expr - enabling pessimistic_yield, was previously {}",
|
"resolve_expr - enabling pessimistic_yield, was previously {}",
|
||||||
|
@ -177,10 +177,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node::Expr(&hir::Expr {
|
Node::ConstBlock(_)
|
||||||
kind: hir::ExprKind::Closure { .. } | hir::ExprKind::ConstBlock { .. },
|
| Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
|
||||||
..
|
Some(tcx.typeck_root_def_id(def_id.to_def_id()))
|
||||||
}) => Some(tcx.typeck_root_def_id(def_id.to_def_id())),
|
}
|
||||||
Node::Item(item) => match item.kind {
|
Node::Item(item) => match item.kind {
|
||||||
ItemKind::OpaqueTy(&hir::OpaqueTy {
|
ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||||
origin:
|
origin:
|
||||||
@ -415,7 +415,7 @@ enum Defaults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// provide junk type parameter defs for const blocks.
|
// provide junk type parameter defs for const blocks.
|
||||||
if let Node::Expr(Expr { kind: ExprKind::ConstBlock(..), .. }) = node {
|
if let Node::ConstBlock(_) = node {
|
||||||
own_params.push(ty::GenericParamDef {
|
own_params.push(ty::GenericParamDef {
|
||||||
index: next_index(),
|
index: next_index(),
|
||||||
name: Symbol::intern("<const_ty>"),
|
name: Symbol::intern("<const_ty>"),
|
||||||
|
@ -485,7 +485,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
|
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
|
||||||
Node::Expr(&Expr { kind: ExprKind::ConstBlock(..), .. }) => {
|
|
||||||
|
Node::ConstBlock(_) => {
|
||||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
||||||
args.as_inline_const().ty()
|
args.as_inline_const().ty()
|
||||||
}
|
}
|
||||||
|
@ -190,6 +190,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Freeze definitions as we don't add new ones at this point. This improves performance by
|
||||||
|
// allowing lock-free access to them.
|
||||||
|
tcx.untracked().definitions.freeze();
|
||||||
|
|
||||||
// FIXME: Remove this when we implement creating `DefId`s
|
// FIXME: Remove this when we implement creating `DefId`s
|
||||||
// for anon constants during their parents' typeck.
|
// for anon constants during their parents' typeck.
|
||||||
// Typeck all body owners in parallel will produce queries
|
// Typeck all body owners in parallel will produce queries
|
||||||
@ -201,10 +205,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Freeze definitions as we don't add new ones at this point. This improves performance by
|
|
||||||
// allowing lock-free access to them.
|
|
||||||
tcx.untracked().definitions.freeze();
|
|
||||||
|
|
||||||
tcx.ensure().check_unused_traits(());
|
tcx.ensure().check_unused_traits(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ fn print_node(&mut self, node: Node<'_>) {
|
|||||||
Node::ImplItem(a) => self.print_impl_item(a),
|
Node::ImplItem(a) => self.print_impl_item(a),
|
||||||
Node::Variant(a) => self.print_variant(a),
|
Node::Variant(a) => self.print_variant(a),
|
||||||
Node::AnonConst(a) => self.print_anon_const(a),
|
Node::AnonConst(a) => self.print_anon_const(a),
|
||||||
|
Node::ConstBlock(a) => self.print_inline_const(a),
|
||||||
Node::Expr(a) => self.print_expr(a),
|
Node::Expr(a) => self.print_expr(a),
|
||||||
Node::ExprField(a) => self.print_expr_field(a),
|
Node::ExprField(a) => self.print_expr_field(a),
|
||||||
Node::Stmt(a) => self.print_stmt(a),
|
Node::Stmt(a) => self.print_stmt(a),
|
||||||
@ -1049,10 +1050,10 @@ fn print_expr_vec(&mut self, exprs: &[hir::Expr<'_>]) {
|
|||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_inline_const(&mut self, constant: &hir::Expr<'_>) {
|
fn print_inline_const(&mut self, constant: &hir::ConstBlock) {
|
||||||
self.ibox(INDENT_UNIT);
|
self.ibox(INDENT_UNIT);
|
||||||
self.word_space("const");
|
self.word_space("const");
|
||||||
self.print_expr(constant);
|
self.ann.nested(self, Nested::Body(constant.body));
|
||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{ExprKind, HirId, QPath};
|
use rustc_hir::{ExprKind, HirId, QPath};
|
||||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
|
||||||
@ -334,7 +335,7 @@ fn check_expr_kind(
|
|||||||
}
|
}
|
||||||
ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected),
|
ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected),
|
||||||
ExprKind::Array(args) => self.check_expr_array(args, expected, expr),
|
ExprKind::Array(args) => self.check_expr_array(args, expected, expr),
|
||||||
ExprKind::ConstBlock(ref block) => self.check_expr_with_expectation(block, expected),
|
ExprKind::ConstBlock(ref block) => self.check_expr_const_block(block, expected),
|
||||||
ExprKind::Repeat(element, ref count) => {
|
ExprKind::Repeat(element, ref count) => {
|
||||||
self.check_expr_repeat(element, count, expected, expr)
|
self.check_expr_repeat(element, count, expected, expr)
|
||||||
}
|
}
|
||||||
@ -1457,6 +1458,24 @@ fn suggest_array_len(&self, expr: &'tcx hir::Expr<'tcx>, array_len: u64) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_expr_const_block(
|
||||||
|
&self,
|
||||||
|
block: &'tcx hir::ConstBlock,
|
||||||
|
expected: Expectation<'tcx>,
|
||||||
|
) -> Ty<'tcx> {
|
||||||
|
let body = self.tcx.hir().body(block.body);
|
||||||
|
|
||||||
|
// Create a new function context.
|
||||||
|
let def_id = block.def_id;
|
||||||
|
let fcx = FnCtxt::new(self, self.param_env, def_id);
|
||||||
|
crate::GatherLocalsVisitor::new(&fcx).visit_body(body);
|
||||||
|
|
||||||
|
let ty = fcx.check_expr_with_expectation(body.value, expected);
|
||||||
|
fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::ConstSized);
|
||||||
|
fcx.write_ty(block.hir_id, ty);
|
||||||
|
ty
|
||||||
|
}
|
||||||
|
|
||||||
fn check_expr_repeat(
|
fn check_expr_repeat(
|
||||||
&self,
|
&self,
|
||||||
element: &'tcx hir::Expr<'tcx>,
|
element: &'tcx hir::Expr<'tcx>,
|
||||||
|
@ -1051,10 +1051,6 @@ pub(in super::super) fn suggest_missing_break_or_return_expr(
|
|||||||
.take_while(|(_, node)| {
|
.take_while(|(_, node)| {
|
||||||
// look at parents until we find the first body owner
|
// look at parents until we find the first body owner
|
||||||
node.body_id().is_none()
|
node.body_id().is_none()
|
||||||
&& !matches!(
|
|
||||||
node,
|
|
||||||
Node::Expr(Expr { kind: ExprKind::ConstBlock { .. }, .. })
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.any(|(parent_id, _)| self.is_loop(parent_id));
|
.any(|(parent_id, _)| self.is_loop(parent_id));
|
||||||
|
|
||||||
|
@ -149,6 +149,10 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
|||||||
self.visit_body(body);
|
self.visit_body(body);
|
||||||
self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, capture_clause);
|
self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, capture_clause);
|
||||||
}
|
}
|
||||||
|
hir::ExprKind::ConstBlock(anon_const) => {
|
||||||
|
let body = self.fcx.tcx.hir().body(anon_const.body);
|
||||||
|
self.visit_body(body);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
// generic parameters.
|
// generic parameters.
|
||||||
|
|
||||||
use crate::FnCtxt;
|
use crate::FnCtxt;
|
||||||
use hir::def::DefKind;
|
|
||||||
use rustc_data_structures::unord::ExtendUnord;
|
use rustc_data_structures::unord::ExtendUnord;
|
||||||
use rustc_errors::{ErrorGuaranteed, StashKey};
|
use rustc_errors::{ErrorGuaranteed, StashKey};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -17,7 +16,7 @@
|
|||||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::TypeSuperFoldable;
|
use rustc_middle::ty::TypeSuperFoldable;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::solve;
|
use rustc_trait_selection::solve;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||||
@ -296,11 +295,11 @@ fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
|
|||||||
hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => {
|
hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => {
|
||||||
self.visit_field_id(e.hir_id);
|
self.visit_field_id(e.hir_id);
|
||||||
}
|
}
|
||||||
hir::ExprKind::ConstBlock(_) => {
|
hir::ExprKind::ConstBlock(anon_const) => {
|
||||||
let feed = self.tcx().create_def(self.fcx.body_id, kw::Empty, DefKind::InlineConst);
|
self.visit_node_id(e.span, anon_const.hir_id);
|
||||||
feed.def_span(e.span);
|
|
||||||
feed.local_def_id_to_hir_id(e.hir_id);
|
let body = self.tcx().hir().body(anon_const.body);
|
||||||
self.typeck_results.inline_consts.insert(e.hir_id.local_id, feed.def_id());
|
self.visit_body(body);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::borrow::Cow;
|
|
||||||
|
|
||||||
use crate::hir::ModuleItems;
|
use crate::hir::ModuleItems;
|
||||||
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
|
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
|
||||||
use crate::query::LocalCrate;
|
use crate::query::LocalCrate;
|
||||||
@ -256,26 +254,13 @@ pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId {
|
|||||||
|
|
||||||
/// Given a `LocalDefId`, returns the `BodyId` associated with it,
|
/// Given a `LocalDefId`, returns the `BodyId` associated with it,
|
||||||
/// if the node is a body owner, otherwise returns `None`.
|
/// if the node is a body owner, otherwise returns `None`.
|
||||||
pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<Cow<'hir, Body<'hir>>> {
|
pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<&'hir Body<'hir>> {
|
||||||
Some(match self.tcx.def_kind(id) {
|
Some(self.body(self.tcx.hir_node_by_def_id(id).body_id()?))
|
||||||
// Inline consts do not have bodies of their own, so create one to make the follow-up logic simpler.
|
|
||||||
DefKind::InlineConst => {
|
|
||||||
let e = self.expect_expr(self.tcx.local_def_id_to_hir_id(id));
|
|
||||||
Cow::Owned(Body {
|
|
||||||
params: &[],
|
|
||||||
value: match e.kind {
|
|
||||||
ExprKind::ConstBlock(body) => body,
|
|
||||||
_ => span_bug!(e.span, "InlineConst was not a ConstBlock: {e:#?}"),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => Cow::Borrowed(self.body(self.tcx.hir_node_by_def_id(id).body_id()?)),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a body owner's id, returns the `BodyId` associated with it.
|
/// Given a body owner's id, returns the `BodyId` associated with it.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn body_owned_by(self, id: LocalDefId) -> Cow<'hir, Body<'hir>> {
|
pub fn body_owned_by(self, id: LocalDefId) -> &'hir Body<'hir> {
|
||||||
self.maybe_body_owned_by(id).unwrap_or_else(|| {
|
self.maybe_body_owned_by(id).unwrap_or_else(|| {
|
||||||
let hir_id = self.tcx.local_def_id_to_hir_id(id);
|
let hir_id = self.tcx.local_def_id_to_hir_id(id);
|
||||||
span_bug!(
|
span_bug!(
|
||||||
@ -338,7 +323,7 @@ pub fn body_const_context(self, def_id: impl Into<DefId>) -> Option<ConstContext
|
|||||||
|
|
||||||
/// Returns an iterator of the `DefId`s for all body-owners in this
|
/// Returns an iterator of the `DefId`s for all body-owners in this
|
||||||
/// crate. If you would prefer to iterate over the bodies
|
/// crate. If you would prefer to iterate over the bodies
|
||||||
/// themselves, you can do `self.hir().krate().owners.iter()`.
|
/// themselves, you can do `self.hir().krate().body_ids.iter()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + 'hir {
|
pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + 'hir {
|
||||||
self.tcx.hir_crate_items(()).body_owners.iter().copied()
|
self.tcx.hir_crate_items(()).body_owners.iter().copied()
|
||||||
@ -525,17 +510,7 @@ pub fn is_lhs(self, id: HirId) -> bool {
|
|||||||
/// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context.
|
/// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context.
|
||||||
/// Used exclusively for diagnostics, to avoid suggestion function calls.
|
/// Used exclusively for diagnostics, to avoid suggestion function calls.
|
||||||
pub fn is_inside_const_context(self, hir_id: HirId) -> bool {
|
pub fn is_inside_const_context(self, hir_id: HirId) -> bool {
|
||||||
for (_, node) in self.parent_iter(hir_id) {
|
self.body_const_context(self.enclosing_body_owner(hir_id)).is_some()
|
||||||
if let Some((def_id, _)) = node.associated_body() {
|
|
||||||
return self.body_const_context(def_id).is_some();
|
|
||||||
}
|
|
||||||
if let Node::Expr(e) = node {
|
|
||||||
if let ExprKind::ConstBlock(_) = e.kind {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the `HirId` for `id`'s enclosing function *if* the `id` block or return is
|
/// Retrieves the `HirId` for `id`'s enclosing function *if* the `id` block or return is
|
||||||
@ -918,6 +893,7 @@ pub fn span_with_body(self, hir_id: HirId) -> Span {
|
|||||||
Node::Variant(variant) => variant.span,
|
Node::Variant(variant) => variant.span,
|
||||||
Node::Field(field) => field.span,
|
Node::Field(field) => field.span,
|
||||||
Node::AnonConst(constant) => constant.span,
|
Node::AnonConst(constant) => constant.span,
|
||||||
|
Node::ConstBlock(constant) => self.body(constant.body).value.span,
|
||||||
Node::Expr(expr) => expr.span,
|
Node::Expr(expr) => expr.span,
|
||||||
Node::ExprField(field) => field.span,
|
Node::ExprField(field) => field.span,
|
||||||
Node::Stmt(stmt) => stmt.span,
|
Node::Stmt(stmt) => stmt.span,
|
||||||
@ -1187,6 +1163,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
|||||||
format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
|
format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
|
||||||
}
|
}
|
||||||
Node::AnonConst(_) => node_str("const"),
|
Node::AnonConst(_) => node_str("const"),
|
||||||
|
Node::ConstBlock(_) => node_str("const"),
|
||||||
Node::Expr(_) => node_str("expr"),
|
Node::Expr(_) => node_str("expr"),
|
||||||
Node::ExprField(_) => node_str("expr field"),
|
Node::ExprField(_) => node_str("expr field"),
|
||||||
Node::Stmt(_) => node_str("stmt"),
|
Node::Stmt(_) => node_str("stmt"),
|
||||||
@ -1336,6 +1313,11 @@ fn visit_anon_const(&mut self, c: &'hir AnonConst) {
|
|||||||
intravisit::walk_anon_const(self, c)
|
intravisit::walk_anon_const(self, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_inline_const(&mut self, c: &'hir ConstBlock) {
|
||||||
|
self.body_owners.push(c.def_id);
|
||||||
|
intravisit::walk_inline_const(self, c)
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
|
fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
|
||||||
if let ExprKind::Closure(closure) = ex.kind {
|
if let ExprKind::Closure(closure) = ex.kind {
|
||||||
self.body_owners.push(closure.def_id);
|
self.body_owners.push(closure.def_id);
|
||||||
|
@ -774,7 +774,6 @@ pub fn feed_hir(&self) {
|
|||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
bodies,
|
bodies,
|
||||||
has_inline_consts: false,
|
|
||||||
})));
|
})));
|
||||||
self.feed_owner_id().hir_attrs(attrs);
|
self.feed_owner_id().hir_attrs(attrs);
|
||||||
}
|
}
|
||||||
|
@ -217,10 +217,6 @@ pub struct TypeckResults<'tcx> {
|
|||||||
|
|
||||||
/// Container types and field indices of `offset_of!` expressions
|
/// Container types and field indices of `offset_of!` expressions
|
||||||
offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<(VariantIdx, FieldIdx)>)>,
|
offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<(VariantIdx, FieldIdx)>)>,
|
||||||
|
|
||||||
/// Maps from `HirId`s of const blocks (the `ExprKind::ConstBlock`, not the inner expression's)
|
|
||||||
/// to the `DefId` of the corresponding inline const.
|
|
||||||
pub inline_consts: FxIndexMap<ItemLocalId, LocalDefId>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeckResults<'tcx> {
|
impl<'tcx> TypeckResults<'tcx> {
|
||||||
@ -253,7 +249,6 @@ pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
|
|||||||
treat_byte_string_as_slice: Default::default(),
|
treat_byte_string_as_slice: Default::default(),
|
||||||
closure_size_eval: Default::default(),
|
closure_size_eval: Default::default(),
|
||||||
offset_of_data: Default::default(),
|
offset_of_data: Default::default(),
|
||||||
inline_consts: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,8 +568,11 @@ fn construct_const<'a, 'tcx>(
|
|||||||
..
|
..
|
||||||
}) => (*span, ty.span),
|
}) => (*span, ty.span),
|
||||||
Node::AnonConst(ct) => (ct.span, ct.span),
|
Node::AnonConst(ct) => (ct.span, ct.span),
|
||||||
Node::Expr(&hir::Expr { span, kind: hir::ExprKind::ConstBlock(_), .. }) => (span, span),
|
Node::ConstBlock(_) => {
|
||||||
node => span_bug!(tcx.def_span(def), "can't build MIR for {def:?}: {node:#?}"),
|
let span = tcx.def_span(def);
|
||||||
|
(span, span)
|
||||||
|
}
|
||||||
|
_ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def),
|
||||||
};
|
};
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
|
@ -671,9 +671,9 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
|
|||||||
ExprKind::OffsetOf { container, fields }
|
ExprKind::OffsetOf { container, fields }
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::ConstBlock(body) => {
|
hir::ExprKind::ConstBlock(ref anon_const) => {
|
||||||
let ty = self.typeck_results().node_type(body.hir_id);
|
let ty = self.typeck_results().node_type(anon_const.hir_id);
|
||||||
let did = self.typeck_results().inline_consts[&expr.hir_id.local_id].into();
|
let did = anon_const.def_id.to_def_id();
|
||||||
let typeck_root_def_id = tcx.typeck_root_def_id(did);
|
let typeck_root_def_id = tcx.typeck_root_def_id(did);
|
||||||
let parent_args =
|
let parent_args =
|
||||||
tcx.erase_regions(GenericArgs::identity_for_item(tcx, typeck_root_def_id));
|
tcx.erase_regions(GenericArgs::identity_for_item(tcx, typeck_root_def_id));
|
||||||
|
@ -165,7 +165,7 @@ fn explicit_params<'a>(
|
|||||||
&'a mut self,
|
&'a mut self,
|
||||||
owner_id: HirId,
|
owner_id: HirId,
|
||||||
fn_decl: &'tcx hir::FnDecl<'tcx>,
|
fn_decl: &'tcx hir::FnDecl<'tcx>,
|
||||||
body: &hir::Body<'tcx>,
|
body: &'tcx hir::Body<'tcx>,
|
||||||
) -> impl Iterator<Item = Param<'tcx>> + 'a {
|
) -> impl Iterator<Item = Param<'tcx>> + 'a {
|
||||||
let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id];
|
let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id];
|
||||||
|
|
||||||
|
@ -637,13 +637,15 @@ fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) ->
|
|||||||
/// Converts inline const patterns.
|
/// Converts inline const patterns.
|
||||||
fn lower_inline_const(
|
fn lower_inline_const(
|
||||||
&mut self,
|
&mut self,
|
||||||
expr: &'tcx hir::Expr<'tcx>,
|
block: &'tcx hir::ConstBlock,
|
||||||
id: hir::HirId,
|
id: hir::HirId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> PatKind<'tcx> {
|
) -> PatKind<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let def_id = self.typeck_results.inline_consts[&id.local_id];
|
let def_id = block.def_id;
|
||||||
let ty = tcx.typeck(def_id).node_type(expr.hir_id);
|
let body_id = block.body;
|
||||||
|
let expr = &tcx.hir().body(body_id).value;
|
||||||
|
let ty = tcx.typeck(def_id).node_type(block.hir_id);
|
||||||
|
|
||||||
// Special case inline consts that are just literals. This is solely
|
// Special case inline consts that are just literals. This is solely
|
||||||
// a performance optimization, as we could also just go through the regular
|
// a performance optimization, as we could also just go through the regular
|
||||||
|
@ -222,16 +222,6 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
|
|||||||
// All body-owners have MIR associated with them.
|
// All body-owners have MIR associated with them.
|
||||||
set.extend(tcx.hir().body_owners());
|
set.extend(tcx.hir().body_owners());
|
||||||
|
|
||||||
// Inline consts' bodies are created in
|
|
||||||
// typeck instead of during ast lowering, like all other bodies so far.
|
|
||||||
for def_id in tcx.hir().body_owners() {
|
|
||||||
// Incremental performance optimization: only load typeck results for things that actually have inline consts
|
|
||||||
if tcx.hir_owner_nodes(tcx.hir().body_owned_by(def_id).id().hir_id.owner).has_inline_consts
|
|
||||||
{
|
|
||||||
set.extend(tcx.typeck(def_id).inline_consts.values())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Additionally, tuple struct/variant constructors have MIR, but
|
// Additionally, tuple struct/variant constructors have MIR, but
|
||||||
// they don't have a BodyId, so we need to build them separately.
|
// they don't have a BodyId, so we need to build them separately.
|
||||||
struct GatherCtors<'a> {
|
struct GatherCtors<'a> {
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor};
|
use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor};
|
||||||
use rustc_ast::util::case::Case;
|
use rustc_ast::util::case::Case;
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
self as ast, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, DelimArgs, Expr,
|
self as ast, AnonConst, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, DelimArgs,
|
||||||
ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, Visibility,
|
Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, Visibility,
|
||||||
VisibilityKind, DUMMY_NODE_ID,
|
VisibilityKind, DUMMY_NODE_ID,
|
||||||
};
|
};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
@ -1262,9 +1262,12 @@ fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
|
|||||||
}
|
}
|
||||||
self.eat_keyword(kw::Const);
|
self.eat_keyword(kw::Const);
|
||||||
let (attrs, blk) = self.parse_inner_attrs_and_block()?;
|
let (attrs, blk) = self.parse_inner_attrs_and_block()?;
|
||||||
let expr = self.mk_expr(blk.span, ExprKind::Block(blk, None));
|
let anon_const = AnonConst {
|
||||||
let blk_span = expr.span;
|
id: DUMMY_NODE_ID,
|
||||||
Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(expr), attrs))
|
value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
|
||||||
|
};
|
||||||
|
let blk_span = anon_const.value.span;
|
||||||
|
Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(anon_const), attrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses mutability (`mut` or nothing).
|
/// Parses mutability (`mut` or nothing).
|
||||||
|
@ -196,6 +196,11 @@ fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
|
|||||||
self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));
|
self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_inline_const(&mut self, block: &'tcx hir::ConstBlock) {
|
||||||
|
let kind = Some(hir::ConstContext::Const { inline: true });
|
||||||
|
self.recurse_into(kind, None, |this| intravisit::walk_inline_const(this, block));
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_body(&mut self, body: &hir::Body<'tcx>) {
|
fn visit_body(&mut self, body: &hir::Body<'tcx>) {
|
||||||
let owner = self.tcx.hir().body_owner_def_id(body.id());
|
let owner = self.tcx.hir().body_owner_def_id(body.id());
|
||||||
let kind = self.tcx.hir().body_const_context(owner);
|
let kind = self.tcx.hir().body_const_context(owner);
|
||||||
@ -223,11 +228,6 @@ fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
|
|||||||
self.const_check_violated(expr, e.span);
|
self.const_check_violated(expr, e.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprKind::ConstBlock(expr) => {
|
|
||||||
let kind = Some(hir::ConstContext::Const { inline: true });
|
|
||||||
self.recurse_into(kind, None, |this| intravisit::walk_expr(this, expr));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -587,16 +587,6 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
|||||||
hir::ExprKind::OffsetOf(..) => {
|
hir::ExprKind::OffsetOf(..) => {
|
||||||
self.handle_offset_of(expr);
|
self.handle_offset_of(expr);
|
||||||
}
|
}
|
||||||
hir::ExprKind::ConstBlock(expr) => {
|
|
||||||
// When inline const blocks are used in pattern position, paths
|
|
||||||
// referenced by it should be considered as used.
|
|
||||||
let in_pat = mem::replace(&mut self.in_pat, false);
|
|
||||||
|
|
||||||
intravisit::walk_expr(self, expr);
|
|
||||||
|
|
||||||
self.in_pat = in_pat;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,6 +648,17 @@ fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
|
|||||||
|
|
||||||
self.in_pat = in_pat;
|
self.in_pat = in_pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) {
|
||||||
|
// When inline const blocks are used in pattern position, paths
|
||||||
|
// referenced by it should be considered as used.
|
||||||
|
let in_pat = mem::replace(&mut self.in_pat, false);
|
||||||
|
|
||||||
|
self.live_symbols.insert(c.def_id);
|
||||||
|
intravisit::walk_inline_const(self, c);
|
||||||
|
|
||||||
|
self.in_pat = in_pat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_allow_dead_code_or_lang_attr(
|
fn has_allow_dead_code_or_lang_attr(
|
||||||
|
@ -147,11 +147,6 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't run for inline consts, they are collected together with their parent
|
|
||||||
if let DefKind::InlineConst = tcx.def_kind(def_id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't run unused pass for #[naked]
|
// Don't run unused pass for #[naked]
|
||||||
if tcx.has_attr(def_id.to_def_id(), sym::naked) {
|
if tcx.has_attr(def_id.to_def_id(), sym::naked) {
|
||||||
return;
|
return;
|
||||||
@ -1148,13 +1143,12 @@ fn propagate_through_expr(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNod
|
|||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::Lit(..)
|
hir::ExprKind::Lit(..)
|
||||||
|
| hir::ExprKind::ConstBlock(..)
|
||||||
| hir::ExprKind::Err(_)
|
| hir::ExprKind::Err(_)
|
||||||
| hir::ExprKind::Path(hir::QPath::TypeRelative(..))
|
| hir::ExprKind::Path(hir::QPath::TypeRelative(..))
|
||||||
| hir::ExprKind::Path(hir::QPath::LangItem(..))
|
| hir::ExprKind::Path(hir::QPath::LangItem(..))
|
||||||
| hir::ExprKind::OffsetOf(..) => succ,
|
| hir::ExprKind::OffsetOf(..) => succ,
|
||||||
|
|
||||||
hir::ExprKind::ConstBlock(expr) => self.propagate_through_expr(expr, succ),
|
|
||||||
|
|
||||||
// Note that labels have been resolved, so we don't need to look
|
// Note that labels have been resolved, so we don't need to look
|
||||||
// at the label ident
|
// at the label ident
|
||||||
hir::ExprKind::Block(ref blk, _) => self.propagate_through_block(blk, succ),
|
hir::ExprKind::Block(ref blk, _) => self.propagate_through_block(blk, succ),
|
||||||
|
@ -93,6 +93,10 @@ fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
|
|||||||
self.with_context(Constant, |v| intravisit::walk_anon_const(v, c));
|
self.with_context(Constant, |v| intravisit::walk_anon_const(v, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) {
|
||||||
|
self.with_context(Constant, |v| intravisit::walk_inline_const(v, c));
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_fn(
|
fn visit_fn(
|
||||||
&mut self,
|
&mut self,
|
||||||
fk: hir::intravisit::FnKind<'hir>,
|
fk: hir::intravisit::FnKind<'hir>,
|
||||||
@ -285,9 +289,6 @@ fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
|
|||||||
self.cx_stack.len() - 1,
|
self.cx_stack.len() - 1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
hir::ExprKind::ConstBlock(expr) => {
|
|
||||||
self.with_context(Constant, |v| intravisit::walk_expr(v, expr));
|
|
||||||
}
|
|
||||||
_ => intravisit::walk_expr(self, e),
|
_ => intravisit::walk_expr(self, e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,6 +340,16 @@ fn visit_expr(&mut self, expr: &'a Expr) {
|
|||||||
ExprKind::Gen(_, _, _) => {
|
ExprKind::Gen(_, _, _) => {
|
||||||
self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
|
self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
|
||||||
}
|
}
|
||||||
|
ExprKind::ConstBlock(ref constant) => {
|
||||||
|
let def = self.create_def(
|
||||||
|
constant.id,
|
||||||
|
kw::Empty,
|
||||||
|
DefKind::InlineConst,
|
||||||
|
constant.value.span,
|
||||||
|
);
|
||||||
|
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
|
||||||
|
return;
|
||||||
|
}
|
||||||
_ => self.parent_def,
|
_ => self.parent_def,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4535,10 +4535,8 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
|
|||||||
self.visit_expr(elem);
|
self.visit_expr(elem);
|
||||||
self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes));
|
self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes));
|
||||||
}
|
}
|
||||||
ExprKind::ConstBlock(ref expr) => {
|
ExprKind::ConstBlock(ref ct) => {
|
||||||
self.resolve_anon_const_manual(false, AnonConstKind::InlineConst, |this| {
|
self.resolve_anon_const(ct, AnonConstKind::InlineConst);
|
||||||
this.visit_expr(expr)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
ExprKind::Index(ref elem, ref idx, _) => {
|
ExprKind::Index(ref elem, ref idx, _) => {
|
||||||
self.resolve_expr(elem, Some(expr));
|
self.resolve_expr(elem, Some(expr));
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
use rustc_ast::ast::{self, LitFloatType, LitKind};
|
use rustc_ast::ast::{self, LitFloatType, LitKind};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp};
|
use rustc_hir::{BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp};
|
||||||
use rustc_lexer::tokenize;
|
use rustc_lexer::tokenize;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::mir::interpret::{alloc_range, Scalar};
|
use rustc_middle::mir::interpret::{alloc_range, Scalar};
|
||||||
@ -412,7 +412,7 @@ pub fn new(lcx: &'a LateContext<'tcx>, typeck_results: &'a ty::TypeckResults<'tc
|
|||||||
/// Simple constant folding: Insert an expression, get a constant or none.
|
/// Simple constant folding: Insert an expression, get a constant or none.
|
||||||
pub fn expr(&mut self, e: &Expr<'_>) -> Option<Constant<'tcx>> {
|
pub fn expr(&mut self, e: &Expr<'_>) -> Option<Constant<'tcx>> {
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ExprKind::ConstBlock(e) | ExprKind::DropTemps(e) => self.expr(e),
|
ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr(e),
|
||||||
ExprKind::Path(ref qpath) => {
|
ExprKind::Path(ref qpath) => {
|
||||||
self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| {
|
self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| {
|
||||||
let result = mir_to_const(this.lcx, result)?;
|
let result = mir_to_const(this.lcx, result)?;
|
||||||
@ -490,7 +490,7 @@ pub fn expr(&mut self, e: &Expr<'_>) -> Option<Constant<'tcx>> {
|
|||||||
/// leaves the local crate.
|
/// leaves the local crate.
|
||||||
pub fn expr_is_empty(&mut self, e: &Expr<'_>) -> Option<bool> {
|
pub fn expr_is_empty(&mut self, e: &Expr<'_>) -> Option<bool> {
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ExprKind::ConstBlock(e) | ExprKind::DropTemps(e) => self.expr_is_empty(e),
|
ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr_is_empty(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr_is_empty(e),
|
||||||
ExprKind::Path(ref qpath) => {
|
ExprKind::Path(ref qpath) => {
|
||||||
if !self
|
if !self
|
||||||
.typeck_results
|
.typeck_results
|
||||||
|
@ -295,7 +295,7 @@ pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {
|
|||||||
self.eq_expr(lx, rx) && self.eq_ty(lt, rt)
|
self.eq_expr(lx, rx) && self.eq_ty(lt, rt)
|
||||||
},
|
},
|
||||||
(&ExprKind::Closure(_l), &ExprKind::Closure(_r)) => false,
|
(&ExprKind::Closure(_l), &ExprKind::Closure(_r)) => false,
|
||||||
(&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_expr(lb, rb),
|
(&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_body(lb.body, rb.body),
|
||||||
(&ExprKind::Continue(li), &ExprKind::Continue(ri)) => {
|
(&ExprKind::Continue(li), &ExprKind::Continue(ri)) => {
|
||||||
both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name)
|
both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name)
|
||||||
},
|
},
|
||||||
@ -769,8 +769,8 @@ pub fn hash_expr(&mut self, e: &Expr<'_>) {
|
|||||||
// closures inherit TypeckResults
|
// closures inherit TypeckResults
|
||||||
self.hash_expr(self.cx.tcx.hir().body(body).value);
|
self.hash_expr(self.cx.tcx.hir().body(body).value);
|
||||||
},
|
},
|
||||||
ExprKind::ConstBlock(l_id) => {
|
ExprKind::ConstBlock(ref l_id) => {
|
||||||
self.hash_expr(l_id);
|
self.hash_body(l_id.body);
|
||||||
},
|
},
|
||||||
ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => {
|
ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => {
|
||||||
self.hash_expr(e);
|
self.hash_expr(e);
|
||||||
|
@ -1,35 +1,11 @@
|
|||||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
|
||||||
--> tests/ui/arithmetic_side_effects.rs:188:36
|
|
||||||
|
|
|
||||||
LL | let _ = const { let mut n = 1; n += 1; n };
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`
|
|
||||||
= help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`
|
|
||||||
|
|
||||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
|
||||||
--> tests/ui/arithmetic_side_effects.rs:191:40
|
|
||||||
|
|
|
||||||
LL | let _ = const { let mut n = 1; n = n + 1; n };
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
|
||||||
--> tests/ui/arithmetic_side_effects.rs:194:40
|
|
||||||
|
|
|
||||||
LL | let _ = const { let mut n = 1; n = 1 + n; n };
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
|
||||||
--> tests/ui/arithmetic_side_effects.rs:200:59
|
|
||||||
|
|
|
||||||
LL | let _ = const { let mut n = 1; n = -1; n = -(-1); n = -n; n };
|
|
||||||
| ^^
|
|
||||||
|
|
||||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||||
--> tests/ui/arithmetic_side_effects.rs:304:5
|
--> tests/ui/arithmetic_side_effects.rs:304:5
|
||||||
|
|
|
|
||||||
LL | _n += 1;
|
LL | _n += 1;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`
|
||||||
|
= help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`
|
||||||
|
|
||||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||||
--> tests/ui/arithmetic_side_effects.rs:305:5
|
--> tests/ui/arithmetic_side_effects.rs:305:5
|
||||||
@ -751,5 +727,5 @@ error: arithmetic operation that can potentially result in unexpected side-effec
|
|||||||
LL | one.sub_assign(1);
|
LL | one.sub_assign(1);
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 125 previous errors
|
error: aborting due to 121 previous errors
|
||||||
|
|
||||||
|
@ -82,9 +82,9 @@ pub fn foo12(_: &Type4, _: &Type4, _: &Type4) {}
|
|||||||
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"}
|
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"}
|
||||||
// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"}
|
// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"}
|
||||||
// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"}
|
// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"}
|
||||||
// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooEE"}
|
// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"}
|
||||||
// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooES0_E"}
|
// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"}
|
||||||
// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooES0_S0_E"}
|
// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"}
|
||||||
// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"}
|
// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"}
|
||||||
// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"}
|
// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"}
|
||||||
// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"}
|
// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"}
|
||||||
|
@ -10,7 +10,7 @@ fn consts() -> () {
|
|||||||
|
|
||||||
bb0: {
|
bb0: {
|
||||||
_1 = const 5_u8;
|
_1 = const 5_u8;
|
||||||
_2 = const consts::<C>::{constant#1};
|
_2 = const consts::<C>::{constant#0};
|
||||||
_3 = const C;
|
_3 = const C;
|
||||||
_4 = const D;
|
_4 = const D;
|
||||||
_5 = consts::<10>;
|
_5 = consts::<10>;
|
||||||
|
@ -206,7 +206,12 @@ fn _11() {
|
|||||||
let _ = ();
|
let _ = ();
|
||||||
()
|
()
|
||||||
};
|
};
|
||||||
let const {} = #[rustc_dummy] const {};
|
let const {
|
||||||
|
#![rustc_dummy]
|
||||||
|
} =
|
||||||
|
#[rustc_dummy] const {
|
||||||
|
#![rustc_dummy]
|
||||||
|
};
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let _ = #[rustc_dummy] x = 15;
|
let _ = #[rustc_dummy] x = 15;
|
||||||
let _ = #[rustc_dummy] x += 15;
|
let _ = #[rustc_dummy] x += 15;
|
||||||
|
18
tests/ui/inline-const/const_block_pat_liveness.rs
Normal file
18
tests/ui/inline-const/const_block_pat_liveness.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//! This test used to ICE because const blocks didn't have a body
|
||||||
|
//! anymore, making a lot of logic very fragile around handling the
|
||||||
|
//! HIR of a const block.
|
||||||
|
//! https://github.com/rust-lang/rust/issues/125846
|
||||||
|
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match 0 {
|
||||||
|
const {
|
||||||
|
let a = 10_usize;
|
||||||
|
*&a
|
||||||
|
}
|
||||||
|
| _ => {}
|
||||||
|
}
|
||||||
|
}
|
@ -67,13 +67,18 @@ LL | impl Test {
|
|||||||
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
|
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
|
||||||
--> $DIR/consts.rs:50:9
|
--> $DIR/consts.rs:50:9
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | const {
|
||||||
| --------- move the `impl` block outside of this function `main`
|
| ___________-
|
||||||
...
|
LL | | impl Test {
|
||||||
LL | impl Test {
|
| | ^^^^^----
|
||||||
| ^^^^^----
|
| | |
|
||||||
| |
|
| | `Test` is not local
|
||||||
| `Test` is not local
|
LL | |
|
||||||
|
LL | | fn hoo() {}
|
||||||
|
... |
|
||||||
|
LL | | 1
|
||||||
|
LL | | };
|
||||||
|
| |_____- move the `impl` block outside of this inline constant `<unnameable>` and up 2 bodies
|
||||||
|
|
|
|
||||||
= note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
|
= note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
|
||||||
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
|
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
|
||||||
|
@ -83,8 +83,7 @@ mod expressions {
|
|||||||
fn expr_const_block() {
|
fn expr_const_block() {
|
||||||
const {};
|
const {};
|
||||||
const { 1 };
|
const { 1 };
|
||||||
const
|
const {
|
||||||
{
|
|
||||||
struct S;
|
struct S;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user