2020-07-06 23:49:53 +02:00
|
|
|
//! This module contains the functionality to convert from the wacky tcx data
|
2020-07-21 09:09:27 +00:00
|
|
|
//! structures into the THIR. The `builder` is generally ignorant of the tcx,
|
2019-02-08 14:53:55 +01:00
|
|
|
//! etc., and instead goes through the `Cx` for most of its work.
|
2015-10-05 12:31:48 -04:00
|
|
|
|
2020-07-21 09:09:27 +00:00
|
|
|
use crate::thir::util::UserAnnotatedTyHelpers;
|
2021-04-04 02:24:02 +02:00
|
|
|
use crate::thir::pattern::pat_from_hir;
|
2015-10-05 12:31:48 -04:00
|
|
|
|
2020-04-27 23:26:11 +05:30
|
|
|
use rustc_ast as ast;
|
2020-01-05 02:37:57 +01:00
|
|
|
use rustc_hir as hir;
|
2020-07-06 23:49:53 +02:00
|
|
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
2020-01-05 02:37:57 +01:00
|
|
|
use rustc_hir::Node;
|
2020-03-29 17:19:48 +02:00
|
|
|
use rustc_middle::middle::region;
|
|
|
|
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
|
2021-04-04 02:24:02 +02:00
|
|
|
use rustc_middle::thir::*;
|
2020-03-29 17:19:48 +02:00
|
|
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
2021-04-04 02:24:02 +02:00
|
|
|
use rustc_span::Span;
|
2015-08-18 17:59:21 -04:00
|
|
|
|
2021-04-03 19:58:46 +02:00
|
|
|
pub fn build_thir<'tcx>(
|
2019-06-14 00:48:52 +03:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2021-03-05 21:56:02 +01:00
|
|
|
owner_def: ty::WithOptConstParam<LocalDefId>,
|
|
|
|
expr: &'tcx hir::Expr<'tcx>,
|
2021-04-03 19:58:46 +02:00
|
|
|
) -> (Thir<'tcx>, ExprId) {
|
|
|
|
let mut cx = Cx::new(tcx, owner_def);
|
|
|
|
let expr = cx.mirror_expr(expr);
|
|
|
|
(cx.thir, expr)
|
2021-03-05 21:56:02 +01:00
|
|
|
}
|
|
|
|
|
2021-04-03 19:58:46 +02:00
|
|
|
struct Cx<'tcx> {
|
2021-03-05 21:56:02 +01:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2021-04-03 19:58:46 +02:00
|
|
|
thir: Thir<'tcx>,
|
2017-07-26 15:54:44 +03:00
|
|
|
|
2020-01-05 15:46:44 +00:00
|
|
|
crate param_env: ty::ParamEnv<'tcx>,
|
2017-07-26 15:54:44 +03:00
|
|
|
|
2020-01-05 15:46:44 +00:00
|
|
|
crate region_scope_tree: &'tcx region::ScopeTree,
|
2021-03-03 16:35:54 +01:00
|
|
|
crate typeck_results: &'tcx ty::TypeckResults<'tcx>,
|
2016-05-26 15:42:29 +03:00
|
|
|
|
2019-05-07 04:40:36 +03:00
|
|
|
/// The `DefId` of the owner of this body.
|
|
|
|
body_owner: DefId,
|
2015-08-18 17:59:21 -04:00
|
|
|
}
|
|
|
|
|
2021-04-03 19:58:46 +02:00
|
|
|
impl<'tcx> Cx<'tcx> {
|
|
|
|
fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) -> Cx<'tcx> {
|
2020-07-17 08:47:04 +00:00
|
|
|
let typeck_results = tcx.typeck_opt_const_arg(def);
|
2017-07-26 15:54:44 +03:00
|
|
|
Cx {
|
|
|
|
tcx,
|
2021-04-03 19:58:46 +02:00
|
|
|
thir: Thir::new(),
|
2020-07-06 23:49:53 +02:00
|
|
|
param_env: tcx.param_env(def.did),
|
|
|
|
region_scope_tree: tcx.region_scope_tree(def.did),
|
2020-07-17 08:47:04 +00:00
|
|
|
typeck_results,
|
2020-07-06 23:49:53 +02:00
|
|
|
body_owner: def.did.to_def_id(),
|
2017-07-26 15:54:44 +03:00
|
|
|
}
|
2015-08-18 17:59:21 -04:00
|
|
|
}
|
|
|
|
|
2020-01-05 15:46:44 +00:00
|
|
|
crate fn const_eval_literal(
|
2018-01-16 09:24:38 +01:00
|
|
|
&mut self,
|
|
|
|
lit: &'tcx ast::LitKind,
|
|
|
|
ty: Ty<'tcx>,
|
|
|
|
sp: Span,
|
|
|
|
neg: bool,
|
2019-04-03 15:29:31 +02:00
|
|
|
) -> &'tcx ty::Const<'tcx> {
|
2018-02-21 22:02:52 +01:00
|
|
|
trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);
|
2018-01-16 09:24:38 +01:00
|
|
|
|
2020-01-11 15:22:36 +13:00
|
|
|
match self.tcx.at(sp).lit_to_const(LitToConstInput { lit, ty, neg }) {
|
2018-11-28 16:07:30 +01:00
|
|
|
Ok(c) => c,
|
|
|
|
Err(LitToConstError::UnparseableFloat) => {
|
2018-04-26 10:39:04 +02:00
|
|
|
// FIXME(#31407) this is only necessary because float parsing is buggy
|
2018-11-28 16:07:30 +01:00
|
|
|
self.tcx.sess.span_err(sp, "could not evaluate float literal (see issue #31407)");
|
|
|
|
// create a dummy value and continue compiling
|
2021-03-08 14:09:22 +00:00
|
|
|
self.tcx.const_error(ty)
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
2018-11-28 16:07:30 +01:00
|
|
|
Err(LitToConstError::Reported) => {
|
|
|
|
// create a dummy value and continue compiling
|
2021-03-08 14:09:22 +00:00
|
|
|
self.tcx.const_error(ty)
|
2018-01-16 09:24:38 +01:00
|
|
|
}
|
2020-02-20 23:23:22 +01:00
|
|
|
Err(LitToConstError::TypeError) => bug!("const_eval_literal: had type error"),
|
2018-11-28 16:07:30 +01:00
|
|
|
}
|
2015-11-11 17:58:41 +02:00
|
|
|
}
|
|
|
|
|
2020-01-05 15:46:44 +00:00
|
|
|
crate fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> {
|
2019-09-25 15:36:14 -04:00
|
|
|
let p = match self.tcx.hir().get(p.hir_id) {
|
2018-08-25 15:56:16 +01:00
|
|
|
Node::Pat(p) | Node::Binding(p) => p,
|
2019-12-22 17:42:04 -05:00
|
|
|
node => bug!("pattern became {:?}", node),
|
2017-08-04 00:41:44 +03:00
|
|
|
};
|
2021-04-04 02:24:02 +02:00
|
|
|
pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p)
|
2017-08-04 00:41:44 +03:00
|
|
|
}
|
2015-08-18 17:59:21 -04:00
|
|
|
}
|
|
|
|
|
2021-04-03 19:58:46 +02:00
|
|
|
impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> {
|
2019-06-14 00:48:52 +03:00
|
|
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
2021-03-03 16:35:54 +01:00
|
|
|
self.tcx
|
2018-10-02 11:00:57 -04:00
|
|
|
}
|
|
|
|
|
2020-07-17 08:47:04 +00:00
|
|
|
fn typeck_results(&self) -> &ty::TypeckResults<'tcx> {
|
2021-03-03 16:35:54 +01:00
|
|
|
self.typeck_results
|
2018-10-02 11:00:57 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-18 17:59:21 -04:00
|
|
|
mod block;
|
|
|
|
mod expr;
|