summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_build/src/thir/cx
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_build/src/thir/cx')
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs47
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs41
2 files changed, 65 insertions, 23 deletions
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 261b95ba9..9086412c0 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -1,3 +1,4 @@
+use crate::errors;
use crate::thir::cx::region::Scope;
use crate::thir::cx::Cx;
use crate::thir::util::UserAnnotatedTyHelpers;
@@ -18,7 +19,7 @@ use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{
self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType,
};
-use rustc_span::Span;
+use rustc_span::{sym, Span};
use rustc_target::abi::VariantIdx;
impl<'tcx> Cx<'tcx> {
@@ -33,8 +34,6 @@ impl<'tcx> Cx<'tcx> {
#[instrument(level = "trace", skip(self, hir_expr))]
pub(super) fn mirror_expr_inner(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> ExprId {
- let temp_lifetime =
- self.rvalue_scopes.temporary_scope(self.region_scope_tree, hir_expr.hir_id.local_id);
let expr_scope =
region::Scope { id: hir_expr.hir_id.local_id, data: region::ScopeData::Node };
@@ -67,7 +66,7 @@ impl<'tcx> Cx<'tcx> {
// Next, wrap this up in the expr's scope.
expr = Expr {
- temp_lifetime,
+ temp_lifetime: expr.temp_lifetime,
ty: expr.ty,
span: hir_expr.span,
kind: ExprKind::Scope {
@@ -82,7 +81,7 @@ impl<'tcx> Cx<'tcx> {
self.region_scope_tree.opt_destruction_scope(hir_expr.hir_id.local_id)
{
expr = Expr {
- temp_lifetime,
+ temp_lifetime: expr.temp_lifetime,
ty: expr.ty,
span: hir_expr.span,
kind: ExprKind::Scope {
@@ -262,6 +261,7 @@ impl<'tcx> Cx<'tcx> {
}
}
+ #[instrument(level = "debug", skip(self), ret)]
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
let tcx = self.tcx;
let expr_ty = self.typeck_results().expr_ty(expr);
@@ -307,7 +307,7 @@ impl<'tcx> Cx<'tcx> {
let arg_tys = args.iter().map(|e| self.typeck_results().expr_ty_adjusted(e));
let tupled_args = Expr {
- ty: tcx.mk_tup(arg_tys),
+ ty: tcx.mk_tup_from_iter(arg_tys),
temp_lifetime,
span: expr.span,
kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
@@ -322,6 +322,34 @@ impl<'tcx> Cx<'tcx> {
fn_span: expr.span,
}
} else {
+ let attrs = tcx.hir().attrs(expr.hir_id);
+ if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_box) {
+ if attrs.len() != 1 {
+ tcx.sess.emit_err(errors::RustcBoxAttributeError {
+ span: attrs[0].span,
+ reason: errors::RustcBoxAttrReason::Attributes,
+ });
+ } else if let Some(box_item) = tcx.lang_items().owned_box() {
+ if let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, fn_path)) = fun.kind
+ && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
+ && path.res.opt_def_id().map_or(false, |did| did == box_item)
+ && fn_path.ident.name == sym::new
+ && let [value] = args
+ {
+ return Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind: ExprKind::Box { value: self.mirror_expr(value) } }
+ } else {
+ tcx.sess.emit_err(errors::RustcBoxAttributeError {
+ span: expr.span,
+ reason: errors::RustcBoxAttrReason::NotBoxNew
+ });
+ }
+ } else {
+ tcx.sess.emit_err(errors::RustcBoxAttributeError {
+ span: attrs[0].span,
+ reason: errors::RustcBoxAttrReason::MissingBox,
+ });
+ }
+ }
let adt_data =
if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = fun.kind {
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
@@ -541,8 +569,9 @@ impl<'tcx> Cx<'tcx> {
let def_id = def_id.expect_local();
let upvars = self
- .typeck_results
- .closure_min_captures_flattened(def_id)
+ .tcx
+ .closure_captures(def_id)
+ .iter()
.zip(substs.upvar_tys())
.map(|(captured_place, ty)| {
let upvars = self.capture_upvar(expr, captured_place, ty);
@@ -758,7 +787,7 @@ impl<'tcx> Cx<'tcx> {
hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) },
hir::ExprKind::Yield(ref v, _) => ExprKind::Yield { value: self.mirror_expr(v) },
- hir::ExprKind::Err => unreachable!(),
+ hir::ExprKind::Err(_) => unreachable!(),
};
Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind }
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index a355e1bda..070544446 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -52,13 +52,6 @@ pub(crate) fn thir_body(
Ok((tcx.alloc_steal_thir(cx.thir), expr))
}
-pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
- match thir_body(tcx, owner_def) {
- Ok((thir, _)) => format!("{:#?}", thir.steal()),
- Err(_) => "error".into(),
- }
-}
-
struct Cx<'tcx> {
tcx: TyCtxt<'tcx>,
thir: Thir<'tcx>,
@@ -89,9 +82,30 @@ impl<'tcx> Cx<'tcx> {
let typeck_results = tcx.typeck_opt_const_arg(def);
let did = def.did;
let hir = tcx.hir();
+ let hir_id = hir.local_def_id_to_hir_id(did);
+
+ let body_type = if hir.body_owner_kind(did).is_fn_or_closure() {
+ // fetch the fully liberated fn signature (that is, all bound
+ // types/lifetimes replaced)
+ BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id])
+ } else {
+ // Get the revealed type of this const. This is *not* the adjusted
+ // type of its body, which may be a subtype of this type. For
+ // example:
+ //
+ // fn foo(_: &()) {}
+ // static X: fn(&'static ()) = foo;
+ //
+ // The adjusted type of the body of X is `for<'a> fn(&'a ())` which
+ // is not the same as the type of X. We need the type of the return
+ // place to be the type of the constant because NLL typeck will
+ // equate them.
+ BodyTy::Const(typeck_results.node_type(hir_id))
+ };
+
Cx {
tcx,
- thir: Thir::new(),
+ thir: Thir::new(body_type),
param_env: tcx.param_env(def.did),
region_scope_tree: tcx.region_scope_tree(def.did),
typeck_results,
@@ -99,7 +113,7 @@ impl<'tcx> Cx<'tcx> {
body_owner: did.to_def_id(),
adjustment_span: None,
apply_adjustments: hir
- .attrs(hir.local_def_id_to_hir_id(did))
+ .attrs(hir_id)
.iter()
.all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir),
}
@@ -123,14 +137,13 @@ impl<'tcx> Cx<'tcx> {
bug!("closure expr does not have closure type: {:?}", closure_ty);
};
- let bound_vars = self.tcx.mk_bound_variable_kinds(std::iter::once(
- ty::BoundVariableKind::Region(ty::BrEnv),
- ));
+ let bound_vars =
+ self.tcx.mk_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]);
let br = ty::BoundRegion {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind: ty::BrEnv,
};
- let env_region = ty::ReLateBound(ty::INNERMOST, br);
+ let env_region = self.tcx.mk_re_late_bound(ty::INNERMOST, br);
let closure_env_ty =
self.tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap();
let liberated_closure_env_ty = self.tcx.erase_late_bound_regions(
@@ -183,7 +196,7 @@ impl<'tcx> Cx<'tcx> {
let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span));
self.tcx
- .bound_type_of(va_list_did)
+ .type_of(va_list_did)
.subst(self.tcx, &[self.tcx.lifetimes.re_erased.into()])
} else {
fn_sig.inputs()[index]