diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index a1c6a8bf99e..567f65e83d9 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,7 +1,6 @@ //! Values computed by queries that use MIR. use crate::mir::{Body, Promoted}; -use crate::thir::abstract_const; use crate::ty::{self, Ty, TyCtxt}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::vec_map::VecMap; @@ -432,16 +431,4 @@ impl<'tcx> TyCtxt<'tcx> { self.mir_for_ctfe(def.did) } } - - #[inline] - pub fn thir_abstract_const_opt_const_arg( - self, - def: ty::WithOptConstParam, - ) -> Result]>, 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) - } - } } diff --git a/compiler/rustc_middle/src/thir/abstract_const.rs b/compiler/rustc_middle/src/thir/abstract_const.rs index 27849e4bdb0..00f1390eb4d 100644 --- a/compiler/rustc_middle/src/thir/abstract_const.rs +++ b/compiler/rustc_middle/src/thir/abstract_const.rs @@ -1,6 +1,7 @@ //! A subset of a mir body used for const evaluatability checking. use crate::mir; -use crate::ty::{self, Ty}; +use crate::ty::{self, Ty, TyCtxt}; +use rustc_errors::ErrorReported; rustc_index::newtype_index! { /// An index into an `AbstractConst`. @@ -22,13 +23,13 @@ pub enum Node<'tcx> { #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub enum NotConstEvaluatable { - Error(rustc_errors::ErrorReported), + Error(ErrorReported), MentionsInfer, MentionsParam, } -impl From for NotConstEvaluatable { - fn from(e: rustc_errors::ErrorReported) -> NotConstEvaluatable { +impl From for NotConstEvaluatable { + fn from(e: ErrorReported) -> NotConstEvaluatable { NotConstEvaluatable::Error(e) } } @@ -36,3 +37,17 @@ impl From for NotConstEvaluatable { TrivialTypeFoldableAndLiftImpls! { NotConstEvaluatable, } + +impl<'tcx> TyCtxt<'tcx> { + #[inline] + pub fn thir_abstract_const_opt_const_arg( + self, + def: ty::WithOptConstParam, + ) -> Result]>, 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) + } + } +} diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 21826ac89d3..7fc15e02fcd 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -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 { fn thir(&self) -> &'a Thir<'tcx>; diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 1aaed7cade2..1845b9d1314 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -8,7 +8,6 @@ //! 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 //! generic constants mentioned in the `caller_bounds` of the current environment. -use rustc_data_structures::sync::Lrc; use rustc_errors::ErrorReported; use rustc_hir::def::DefKind; use rustc_index::vec::IndexVec; @@ -227,8 +226,7 @@ impl<'tcx> AbstractConst<'tcx> { struct AbstractConstBuilder<'a, 'tcx> { tcx: TyCtxt<'tcx>, body_id: thir::ExprId, - /// `Lrc` is used to avoid borrowck difficulties in `recurse_build` - body: Lrc<&'a thir::Thir<'tcx>>, + body: &'a thir::Thir<'tcx>, /// The current WIP node tree. nodes: IndexVec>, } @@ -253,8 +251,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { tcx: TyCtxt<'tcx>, (body, body_id): (&'a thir::Thir<'tcx>, thir::ExprId), ) -> Result>, ErrorReported> { - let builder = - AbstractConstBuilder { tcx, body_id, body: Lrc::new(body), nodes: IndexVec::new() }; + let builder = AbstractConstBuilder { tcx, body_id, body, nodes: IndexVec::new() }; struct IsThirPolymorphic<'a, 'tcx> { is_poly: bool, @@ -328,7 +325,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { fn recurse_build(&mut self, node: thir::ExprId) -> Result { use thir::ExprKind; - let node = &self.body.clone().exprs[node]; + let node = &self.body.exprs[node]; debug!("recurse_build: node={:?}", node); Ok(match &node.kind { // 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 // `::ASSOC` as well as `12` - &ExprKind::Literal { literal, .. } - | &ExprKind::StaticRef { literal, .. } => self.nodes.push(Node::Leaf(literal)), + &ExprKind::Literal { 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, .. } => { let fun = self.recurse_build(*fun)?; @@ -361,7 +357,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { let arg = self.recurse_build(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(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::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. - // 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::Cast { source } => { let arg = self.recurse_build(source)?; 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::Borrow { .. } | ExprKind::Deref { .. } @@ -390,21 +386,24 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { | ExprKind::Index { .. } | ExprKind::Field { .. } | ExprKind::ConstBlock { .. } - | ExprKind::Adt(_) => return self.error( + | ExprKind::Adt(_) => self.error( Some(node.span), "unsupported operation in generic constant, this may be supported in the future", - ).map(|never| never), + )?, ExprKind::Match { .. } - | ExprKind::VarRef { .. } // - | ExprKind::UpvarRef { .. } // we dont permit let stmts so... + // we dont permit let stmts so `VarRef` and `UpvarRef` cant happen + | ExprKind::VarRef { .. } + | ExprKind::UpvarRef { .. } | ExprKind::Closure { .. } | ExprKind::Let { .. } // let expressions imply control flow | ExprKind::Loop { .. } | ExprKind::Assign { .. } + | ExprKind::StaticRef { .. } | ExprKind::LogicalOp { .. } - | ExprKind::Unary { .. } // - | ExprKind::Binary { .. } // we handle valid unary/binary ops above + // we handle valid unary/binary ops above + | ExprKind::Unary { .. } + | ExprKind::Binary { .. } | ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::If { .. } @@ -415,7 +414,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { | ExprKind::Box { .. } // allocations not allowed in constants | ExprKind::AssignOp { .. } | 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")?, }) } }