1
Fork 0

Auto merge of #94876 - b-naber:thir-abstract-const-changes, r=lcnr

Change Thir to lazily create constants

To allow `AbstractConst`s to work with the previous thir changes we made and those we want to make, i.e. to avoid problems due to `ValTree` and `ConstValue` conversions, we instead switch to a thir representation for constants that allows us to lazily create constants.

r? `@oli-obk`
This commit is contained in:
bors 2022-03-24 12:50:00 +00:00
commit 8d8135f003
17 changed files with 345 additions and 154 deletions

View file

@ -955,6 +955,7 @@ rustc_queries! {
desc { "get a &core::panic::Location referring to a span" }
}
// FIXME get rid of this with valtrees
query lit_to_const(
key: LitToConstInput<'tcx>
) -> Result<ty::Const<'tcx>, LitToConstError> {

View file

@ -369,7 +369,8 @@ pub enum ExprKind<'tcx> {
},
/// An inline `const` block, e.g. `const {}`.
ConstBlock {
value: Const<'tcx>,
did: DefId,
substs: SubstsRef<'tcx>,
},
/// An array literal constructed from one repeated element, e.g. `[1; 5]`.
Repeat {
@ -408,13 +409,25 @@ pub enum ExprKind<'tcx> {
},
/// A literal.
Literal {
literal: Const<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
/// The `DefId` of the `const` item this literal
/// was produced from, if this is not a user-written
/// literal value.
const_id: Option<DefId>,
lit: &'tcx hir::Lit,
neg: bool,
},
/// For literals that don't correspond to anything in the HIR
NonHirLiteral {
lit: ty::ScalarInt,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
},
/// Associated constants and named constants
NamedConst {
def_id: DefId,
substs: SubstsRef<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
},
ConstParam {
param: ty::ParamConst,
def_id: DefId,
},
// FIXME improve docs for `StaticRef` by distinguishing it from `NamedConst`
/// A literal containing the address of a `static`.
///
/// This is only distinguished from `Literal` so that we can register some
@ -439,6 +452,12 @@ pub enum ExprKind<'tcx> {
},
}
impl<'tcx> ExprKind<'tcx> {
pub fn zero_sized_literal(user_ty: Option<Canonical<'tcx, UserType<'tcx>>>) -> Self {
ExprKind::NonHirLiteral { lit: ty::ScalarInt::ZST, user_ty }
}
}
/// Represents the association of a field identifier and an expression.
///
/// This is used in struct constructors.

View file

@ -1,7 +1,6 @@
use super::{
Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir,
};
use rustc_middle::ty::Const;
pub trait Visitor<'a, 'tcx: 'a>: Sized {
fn thir(&self) -> &'a Thir<'tcx>;
@ -25,8 +24,6 @@ pub trait Visitor<'a, 'tcx: 'a>: Sized {
fn visit_pat(&mut self, pat: &Pat<'tcx>) {
walk_pat(self, pat);
}
fn visit_const(&mut self, _cnst: Const<'tcx>) {}
}
pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
@ -93,10 +90,9 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
visitor.visit_expr(&visitor.thir()[value])
}
}
ConstBlock { value } => visitor.visit_const(value),
Repeat { value, count } => {
ConstBlock { did: _, substs: _ } => {}
Repeat { value, count: _ } => {
visitor.visit_expr(&visitor.thir()[value]);
visitor.visit_const(count);
}
Array { ref fields } | Tuple { ref fields } => {
for &field in &**fields {
@ -122,7 +118,10 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
visitor.visit_expr(&visitor.thir()[source])
}
Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
Literal { lit: _, neg: _ } => {}
NonHirLiteral { lit: _, user_ty: _ } => {}
NamedConst { def_id: _, substs: _, user_ty: _ } => {}
ConstParam { param: _, def_id: _ } => {}
StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
for op in &**operands {
@ -209,11 +208,8 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
visitor.visit_pat(&subpattern.pattern);
}
}
Constant { value } => visitor.visit_const(*value),
Range(range) => {
visitor.visit_const(range.lo);
visitor.visit_const(range.hi);
}
Constant { value: _ } => {}
Range(_) => {}
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
for subpattern in prefix {
visitor.visit_pat(&subpattern);