mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Revert "Create const block DefIds in typeck instead of ast lowering"
This reverts commit ddc5f9b6c1
.
This commit is contained in:
parent
92c54db22f
commit
cbee17d502
@ -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));
|
||||||
|
@ -74,7 +74,14 @@ impl<'hir> LoweringContext<'_, '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) => hir::ExprKind::ConstBlock(self.lower_expr(c)),
|
ExprKind::ConstBlock(c) => {
|
||||||
|
let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock {
|
||||||
|
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);
|
||||||
let count = self.lower_array_length(count);
|
let count = self.lower_array_length(count);
|
||||||
|
@ -236,6 +236,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
@ -380,9 +380,8 @@ impl<'a> State<'a> {
|
|||||||
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 {
|
||||||
|
@ -1623,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> {
|
||||||
@ -1909,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.
|
||||||
@ -3641,6 +3649,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>),
|
||||||
@ -3701,6 +3710,7 @@ impl<'hir> Node<'hir> {
|
|||||||
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(..)
|
||||||
@ -3798,6 +3808,7 @@ impl<'hir> Node<'hir> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
@ -3866,6 +3877,7 @@ impl<'hir> Node<'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 @@ pub trait Visitor<'v>: Sized {
|
|||||||
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));
|
||||||
|
@ -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 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 @@ impl<'a> State<'a> {
|
|||||||
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 @@ impl<'a> State<'a> {
|
|||||||
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_errors::{
|
|||||||
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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -1456,6 +1457,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.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 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, '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::fold::{TypeFoldable, TypeFolder};
|
|||||||
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 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, '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 @@ impl<'hir> Map<'hir> {
|
|||||||
|
|
||||||
/// 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 @@ impl<'hir> Map<'hir> {
|
|||||||
|
|
||||||
/// 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 @@ impl<'hir> Map<'hir> {
|
|||||||
/// 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 @@ impl<'hir> Map<'hir> {
|
|||||||
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 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
|
|||||||
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);
|
||||||
|
@ -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 @@ impl<'tcx> 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 @@ impl<'tcx> Cx<'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 @@ impl<'tcx> Cx<'tcx> {
|
|||||||
&'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 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||||||
/// 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,12 +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() {
|
|
||||||
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::{AttributesData, DelimSpacing, DelimSpan, Spacing};
|
|||||||
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 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
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 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
|
|||||||
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 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'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 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'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 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
|
|||||||
|
|
||||||
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 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
|
|||||||
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 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, '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 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||||||
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 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||||||
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 crate::{clip, is_direct_expn_of, sext, unsext};
|
|||||||
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 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
|
|||||||
/// 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 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, '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 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||||||
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 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||||||
// 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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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