nits
This commit is contained in:
parent
79be080255
commit
955e2b2da0
4 changed files with 43 additions and 38 deletions
|
@ -1,7 +1,6 @@
|
||||||
//! Values computed by queries that use MIR.
|
//! Values computed by queries that use MIR.
|
||||||
|
|
||||||
use crate::mir::{Body, Promoted};
|
use crate::mir::{Body, Promoted};
|
||||||
use crate::thir::abstract_const;
|
|
||||||
use crate::ty::{self, Ty, TyCtxt};
|
use crate::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::vec_map::VecMap;
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
|
@ -432,16 +431,4 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self.mir_for_ctfe(def.did)
|
self.mir_for_ctfe(def.did)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn thir_abstract_const_opt_const_arg(
|
|
||||||
self,
|
|
||||||
def: ty::WithOptConstParam<DefId>,
|
|
||||||
) -> Result<Option<&'tcx [abstract_const::Node<'tcx>]>, ErrorReported> {
|
|
||||||
if let Some((did, param_did)) = def.as_const_arg() {
|
|
||||||
self.thir_abstract_const_of_const_arg((did, param_did))
|
|
||||||
} else {
|
|
||||||
self.thir_abstract_const(def.did)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! A subset of a mir body used for const evaluatability checking.
|
//! A subset of a mir body used for const evaluatability checking.
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
use crate::ty::{self, Ty};
|
use crate::ty::{self, Ty, TyCtxt};
|
||||||
|
use rustc_errors::ErrorReported;
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
/// An index into an `AbstractConst`.
|
/// An index into an `AbstractConst`.
|
||||||
|
@ -22,13 +23,13 @@ pub enum Node<'tcx> {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||||
pub enum NotConstEvaluatable {
|
pub enum NotConstEvaluatable {
|
||||||
Error(rustc_errors::ErrorReported),
|
Error(ErrorReported),
|
||||||
MentionsInfer,
|
MentionsInfer,
|
||||||
MentionsParam,
|
MentionsParam,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<rustc_errors::ErrorReported> for NotConstEvaluatable {
|
impl From<ErrorReported> for NotConstEvaluatable {
|
||||||
fn from(e: rustc_errors::ErrorReported) -> NotConstEvaluatable {
|
fn from(e: ErrorReported) -> NotConstEvaluatable {
|
||||||
NotConstEvaluatable::Error(e)
|
NotConstEvaluatable::Error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,3 +37,17 @@ impl From<rustc_errors::ErrorReported> for NotConstEvaluatable {
|
||||||
TrivialTypeFoldableAndLiftImpls! {
|
TrivialTypeFoldableAndLiftImpls! {
|
||||||
NotConstEvaluatable,
|
NotConstEvaluatable,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
#[inline]
|
||||||
|
pub fn thir_abstract_const_opt_const_arg(
|
||||||
|
self,
|
||||||
|
def: ty::WithOptConstParam<rustc_hir::def_id::DefId>,
|
||||||
|
) -> Result<Option<&'tcx [Node<'tcx>]>, ErrorReported> {
|
||||||
|
if let Some((did, param_did)) = def.as_const_arg() {
|
||||||
|
self.thir_abstract_const_of_const_arg((did, param_did))
|
||||||
|
} else {
|
||||||
|
self.thir_abstract_const(def.did)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
use super::*;
|
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 {
|
pub trait Visitor<'a, 'tcx: 'a>: Sized {
|
||||||
fn thir(&self) -> &'a Thir<'tcx>;
|
fn thir(&self) -> &'a Thir<'tcx>;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
//! In this case we try to build an abstract representation of this constant using
|
//! In this case we try to build an abstract representation of this constant using
|
||||||
//! `thir_abstract_const` which can then be checked for structural equality with other
|
//! `thir_abstract_const` which can then be checked for structural equality with other
|
||||||
//! generic constants mentioned in the `caller_bounds` of the current environment.
|
//! generic constants mentioned in the `caller_bounds` of the current environment.
|
||||||
use rustc_data_structures::sync::Lrc;
|
|
||||||
use rustc_errors::ErrorReported;
|
use rustc_errors::ErrorReported;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
|
@ -227,8 +226,7 @@ impl<'tcx> AbstractConst<'tcx> {
|
||||||
struct AbstractConstBuilder<'a, 'tcx> {
|
struct AbstractConstBuilder<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body_id: thir::ExprId,
|
body_id: thir::ExprId,
|
||||||
/// `Lrc` is used to avoid borrowck difficulties in `recurse_build`
|
body: &'a thir::Thir<'tcx>,
|
||||||
body: Lrc<&'a thir::Thir<'tcx>>,
|
|
||||||
/// The current WIP node tree.
|
/// The current WIP node tree.
|
||||||
nodes: IndexVec<NodeId, Node<'tcx>>,
|
nodes: IndexVec<NodeId, Node<'tcx>>,
|
||||||
}
|
}
|
||||||
|
@ -253,8 +251,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
(body, body_id): (&'a thir::Thir<'tcx>, thir::ExprId),
|
(body, body_id): (&'a thir::Thir<'tcx>, thir::ExprId),
|
||||||
) -> Result<Option<AbstractConstBuilder<'a, 'tcx>>, ErrorReported> {
|
) -> Result<Option<AbstractConstBuilder<'a, 'tcx>>, ErrorReported> {
|
||||||
let builder =
|
let builder = AbstractConstBuilder { tcx, body_id, body, nodes: IndexVec::new() };
|
||||||
AbstractConstBuilder { tcx, body_id, body: Lrc::new(body), nodes: IndexVec::new() };
|
|
||||||
|
|
||||||
struct IsThirPolymorphic<'a, 'tcx> {
|
struct IsThirPolymorphic<'a, 'tcx> {
|
||||||
is_poly: bool,
|
is_poly: bool,
|
||||||
|
@ -328,7 +325,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
|
|
||||||
fn recurse_build(&mut self, node: thir::ExprId) -> Result<NodeId, ErrorReported> {
|
fn recurse_build(&mut self, node: thir::ExprId) -> Result<NodeId, ErrorReported> {
|
||||||
use thir::ExprKind;
|
use thir::ExprKind;
|
||||||
let node = &self.body.clone().exprs[node];
|
let node = &self.body.exprs[node];
|
||||||
debug!("recurse_build: node={:?}", node);
|
debug!("recurse_build: node={:?}", node);
|
||||||
Ok(match &node.kind {
|
Ok(match &node.kind {
|
||||||
// I dont know if handling of these 3 is correct
|
// I dont know if handling of these 3 is correct
|
||||||
|
@ -338,10 +335,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
|
|
||||||
// subtle: associated consts are literals this arm handles
|
// subtle: associated consts are literals this arm handles
|
||||||
// `<T as Trait>::ASSOC` as well as `12`
|
// `<T as Trait>::ASSOC` as well as `12`
|
||||||
&ExprKind::Literal { literal, .. }
|
&ExprKind::Literal { literal, .. } => self.nodes.push(Node::Leaf(literal)),
|
||||||
| &ExprKind::StaticRef { literal, .. } => self.nodes.push(Node::Leaf(literal)),
|
|
||||||
|
|
||||||
// FIXME(generic_const_exprs) handle `from_hir_call` field
|
// FIXME(generic_const_exprs): Handle `from_hir_call` field
|
||||||
ExprKind::Call { fun, args, .. } => {
|
ExprKind::Call { fun, args, .. } => {
|
||||||
let fun = self.recurse_build(*fun)?;
|
let fun = self.recurse_build(*fun)?;
|
||||||
|
|
||||||
|
@ -361,7 +357,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
let arg = self.recurse_build(arg)?;
|
let arg = self.recurse_build(arg)?;
|
||||||
self.nodes.push(Node::UnaryOp(op, arg))
|
self.nodes.push(Node::UnaryOp(op, arg))
|
||||||
},
|
},
|
||||||
// this is necessary so that the following compiles:
|
// This is necessary so that the following compiles:
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
// fn foo<const N: usize>(a: [(); N + 1]) {
|
// fn foo<const N: usize>(a: [(); N + 1]) {
|
||||||
|
@ -369,16 +365,16 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
ExprKind::Block { body: thir::Block { stmts: box [], expr: Some(e), .. }} => self.recurse_build(*e)?,
|
ExprKind::Block { body: thir::Block { stmts: box [], expr: Some(e), .. }} => self.recurse_build(*e)?,
|
||||||
// ExprKind::Use happens when a `hir::ExprKind::Cast` is a
|
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
|
||||||
// "coercion cast" i.e. using a coercion or is a no-op.
|
// "coercion cast" i.e. using a coercion or is a no-op.
|
||||||
// this is important so that `N as usize as usize` doesnt unify with `N as usize`
|
// This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested)
|
||||||
&ExprKind::Use { source}
|
&ExprKind::Use { source}
|
||||||
| &ExprKind::Cast { source } => {
|
| &ExprKind::Cast { source } => {
|
||||||
let arg = self.recurse_build(source)?;
|
let arg = self.recurse_build(source)?;
|
||||||
self.nodes.push(Node::Cast(arg, node.ty))
|
self.nodes.push(Node::Cast(arg, node.ty))
|
||||||
},
|
},
|
||||||
|
|
||||||
// FIXME(generic_const_exprs) we want to support these
|
// FIXME(generic_const_exprs): We may want to support these.
|
||||||
ExprKind::AddressOf { .. }
|
ExprKind::AddressOf { .. }
|
||||||
| ExprKind::Borrow { .. }
|
| ExprKind::Borrow { .. }
|
||||||
| ExprKind::Deref { .. }
|
| ExprKind::Deref { .. }
|
||||||
|
@ -390,21 +386,24 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
| ExprKind::Index { .. }
|
| ExprKind::Index { .. }
|
||||||
| ExprKind::Field { .. }
|
| ExprKind::Field { .. }
|
||||||
| ExprKind::ConstBlock { .. }
|
| ExprKind::ConstBlock { .. }
|
||||||
| ExprKind::Adt(_) => return self.error(
|
| ExprKind::Adt(_) => self.error(
|
||||||
Some(node.span),
|
Some(node.span),
|
||||||
"unsupported operation in generic constant, this may be supported in the future",
|
"unsupported operation in generic constant, this may be supported in the future",
|
||||||
).map(|never| never),
|
)?,
|
||||||
|
|
||||||
ExprKind::Match { .. }
|
ExprKind::Match { .. }
|
||||||
| ExprKind::VarRef { .. } //
|
// we dont permit let stmts so `VarRef` and `UpvarRef` cant happen
|
||||||
| ExprKind::UpvarRef { .. } // we dont permit let stmts so...
|
| ExprKind::VarRef { .. }
|
||||||
|
| ExprKind::UpvarRef { .. }
|
||||||
| ExprKind::Closure { .. }
|
| ExprKind::Closure { .. }
|
||||||
| ExprKind::Let { .. } // let expressions imply control flow
|
| ExprKind::Let { .. } // let expressions imply control flow
|
||||||
| ExprKind::Loop { .. }
|
| ExprKind::Loop { .. }
|
||||||
| ExprKind::Assign { .. }
|
| ExprKind::Assign { .. }
|
||||||
|
| ExprKind::StaticRef { .. }
|
||||||
| ExprKind::LogicalOp { .. }
|
| ExprKind::LogicalOp { .. }
|
||||||
| ExprKind::Unary { .. } //
|
// we handle valid unary/binary ops above
|
||||||
| ExprKind::Binary { .. } // we handle valid unary/binary ops above
|
| ExprKind::Unary { .. }
|
||||||
|
| ExprKind::Binary { .. }
|
||||||
| ExprKind::Break { .. }
|
| ExprKind::Break { .. }
|
||||||
| ExprKind::Continue { .. }
|
| ExprKind::Continue { .. }
|
||||||
| ExprKind::If { .. }
|
| ExprKind::If { .. }
|
||||||
|
@ -415,7 +414,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
| ExprKind::Box { .. } // allocations not allowed in constants
|
| ExprKind::Box { .. } // allocations not allowed in constants
|
||||||
| ExprKind::AssignOp { .. }
|
| ExprKind::AssignOp { .. }
|
||||||
| ExprKind::InlineAsm { .. }
|
| ExprKind::InlineAsm { .. }
|
||||||
| ExprKind::Yield { .. } => return self.error(Some(node.span), "unsupported operation in generic constant").map(|never| never),
|
| ExprKind::Yield { .. } => self.error(Some(node.span), "unsupported operation in generic constant")?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue