|
1 | 1 | use std::fmt::{self, Debug, Display, Formatter};
|
2 | 2 |
|
3 | 3 | use rustc_hir;
|
4 |
| -use rustc_hir::def_id::{DefId, LocalDefId}; |
5 |
| -use rustc_hir::{self as hir}; |
| 4 | +use rustc_hir::def_id::DefId; |
6 | 5 | use rustc_session::RemapFileNameExt;
|
7 | 6 | use rustc_span::Span;
|
8 | 7 | use rustc_target::abi::{HasDataLayout, Size};
|
9 | 8 |
|
10 | 9 | use crate::mir::interpret::{alloc_range, AllocId, ConstAllocation, ErrorHandled, Scalar};
|
11 | 10 | use crate::mir::{pretty_print_const_value, Promoted};
|
| 11 | +use crate::ty::GenericArgsRef; |
12 | 12 | use crate::ty::ScalarInt;
|
13 |
| -use crate::ty::{self, print::pretty_print_const, List, Ty, TyCtxt}; |
14 |
| -use crate::ty::{GenericArgs, GenericArgsRef}; |
| 13 | +use crate::ty::{self, print::pretty_print_const, Ty, TyCtxt}; |
15 | 14 |
|
16 | 15 | ///////////////////////////////////////////////////////////////////////////
|
17 | 16 | /// Evaluated Constants
|
@@ -220,6 +219,17 @@ pub enum Const<'tcx> {
|
220 | 219 | }
|
221 | 220 |
|
222 | 221 | impl<'tcx> Const<'tcx> {
|
| 222 | + pub fn identity_unevaluated(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::EarlyBinder<Const<'tcx>> { |
| 223 | + ty::EarlyBinder::bind(Const::Unevaluated( |
| 224 | + UnevaluatedConst { |
| 225 | + def: def_id, |
| 226 | + args: ty::GenericArgs::identity_for_item(tcx, def_id), |
| 227 | + promoted: None, |
| 228 | + }, |
| 229 | + tcx.type_of(def_id).skip_binder(), |
| 230 | + )) |
| 231 | + } |
| 232 | + |
223 | 233 | #[inline(always)]
|
224 | 234 | pub fn ty(&self) -> Ty<'tcx> {
|
225 | 235 | match self {
|
@@ -399,101 +409,6 @@ impl<'tcx> Const<'tcx> {
|
399 | 409 | Self::Val(val, ty)
|
400 | 410 | }
|
401 | 411 |
|
402 |
| - /// Literals are converted to `Const::Val`, const generic parameters are eagerly |
403 |
| - /// converted to a constant, everything else becomes `Unevaluated`. |
404 |
| - #[instrument(skip(tcx), level = "debug", ret)] |
405 |
| - pub fn from_anon_const( |
406 |
| - tcx: TyCtxt<'tcx>, |
407 |
| - def: LocalDefId, |
408 |
| - param_env: ty::ParamEnv<'tcx>, |
409 |
| - ) -> Self { |
410 |
| - let body_id = match tcx.hir().get_by_def_id(def) { |
411 |
| - hir::Node::AnonConst(ac) => ac.body, |
412 |
| - _ => { |
413 |
| - span_bug!(tcx.def_span(def), "from_anon_const can only process anonymous constants") |
414 |
| - } |
415 |
| - }; |
416 |
| - |
417 |
| - let expr = &tcx.hir().body(body_id).value; |
418 |
| - debug!(?expr); |
419 |
| - |
420 |
| - // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments |
421 |
| - // currently have to be wrapped in curly brackets, so it's necessary to special-case. |
422 |
| - let expr = match &expr.kind { |
423 |
| - hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { |
424 |
| - block.expr.as_ref().unwrap() |
425 |
| - } |
426 |
| - _ => expr, |
427 |
| - }; |
428 |
| - debug!("expr.kind: {:?}", expr.kind); |
429 |
| - |
430 |
| - let ty = tcx.type_of(def).instantiate_identity(); |
431 |
| - debug!(?ty); |
432 |
| - |
433 |
| - // FIXME(const_generics): We currently have to special case parameters because `min_const_generics` |
434 |
| - // does not provide the parents generics to anonymous constants. We still allow generic const |
435 |
| - // parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to |
436 |
| - // ever try to substitute the generic parameters in their bodies. |
437 |
| - // |
438 |
| - // While this doesn't happen as these constants are always used as `ty::ConstKind::Param`, it does |
439 |
| - // cause issues if we were to remove that special-case and try to evaluate the constant instead. |
440 |
| - use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath}; |
441 |
| - match expr.kind { |
442 |
| - ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => { |
443 |
| - // Find the name and index of the const parameter by indexing the generics of |
444 |
| - // the parent item and construct a `ParamConst`. |
445 |
| - let item_def_id = tcx.parent(def_id); |
446 |
| - let generics = tcx.generics_of(item_def_id); |
447 |
| - let index = generics.param_def_id_to_index[&def_id]; |
448 |
| - let name = tcx.item_name(def_id); |
449 |
| - let ty_const = ty::Const::new_param(tcx, ty::ParamConst::new(index, name), ty); |
450 |
| - debug!(?ty_const); |
451 |
| - |
452 |
| - return Self::Ty(ty_const); |
453 |
| - } |
454 |
| - _ => {} |
455 |
| - } |
456 |
| - |
457 |
| - let hir_id = tcx.hir().local_def_id_to_hir_id(def); |
458 |
| - let parent_args = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) |
459 |
| - && let Some(parent_did) = parent_hir_id.as_owner() |
460 |
| - { |
461 |
| - GenericArgs::identity_for_item(tcx, parent_did) |
462 |
| - } else { |
463 |
| - List::empty() |
464 |
| - }; |
465 |
| - debug!(?parent_args); |
466 |
| - |
467 |
| - let did = def.to_def_id(); |
468 |
| - let child_args = GenericArgs::identity_for_item(tcx, did); |
469 |
| - let args = tcx.mk_args_from_iter(parent_args.into_iter().chain(child_args.into_iter())); |
470 |
| - debug!(?args); |
471 |
| - |
472 |
| - let span = tcx.def_span(def); |
473 |
| - let uneval = UnevaluatedConst::new(did, args); |
474 |
| - debug!(?span, ?param_env); |
475 |
| - |
476 |
| - match tcx.const_eval_resolve(param_env, uneval, Some(span)) { |
477 |
| - Ok(val) => { |
478 |
| - debug!("evaluated const value"); |
479 |
| - Self::Val(val, ty) |
480 |
| - } |
481 |
| - Err(_) => { |
482 |
| - debug!("error encountered during evaluation"); |
483 |
| - // Error was handled in `const_eval_resolve`. Here we just create a |
484 |
| - // new unevaluated const and error hard later in codegen |
485 |
| - Self::Unevaluated( |
486 |
| - UnevaluatedConst { |
487 |
| - def: did, |
488 |
| - args: GenericArgs::identity_for_item(tcx, did), |
489 |
| - promoted: None, |
490 |
| - }, |
491 |
| - ty, |
492 |
| - ) |
493 |
| - } |
494 |
| - } |
495 |
| - } |
496 |
| - |
497 | 412 | pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
498 | 413 | match c.kind() {
|
499 | 414 | ty::ConstKind::Value(valtree) => {
|
|
0 commit comments