directly use ConstValue for single literals in blocks
This commit is contained in:
parent
cc65bf3ded
commit
4c27d348ec
3 changed files with 15 additions and 17 deletions
|
@ -36,6 +36,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
|
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
pub fn from_opt_const_arg_anon_const(
|
pub fn from_opt_const_arg_anon_const(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def: ty::WithOptConstParam<LocalDefId>,
|
def: ty::WithOptConstParam<LocalDefId>,
|
||||||
|
@ -53,6 +54,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let expr = &tcx.hir().body(body_id).value;
|
let expr = &tcx.hir().body(body_id).value;
|
||||||
|
debug!(?expr);
|
||||||
|
|
||||||
let ty = tcx.type_of(def.def_id_for_type_of());
|
let ty = tcx.type_of(def.def_id_for_type_of());
|
||||||
|
|
||||||
|
@ -69,11 +71,21 @@ impl<'tcx> Const<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
fn try_eval_lit_or_param(
|
fn try_eval_lit_or_param(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
) -> Option<&'tcx Self> {
|
) -> Option<&'tcx Self> {
|
||||||
|
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
|
||||||
|
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
|
||||||
|
let expr = match &expr.kind {
|
||||||
|
hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
|
||||||
|
block.expr.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
_ => expr,
|
||||||
|
};
|
||||||
|
|
||||||
let lit_input = match expr.kind {
|
let lit_input = match expr.kind {
|
||||||
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
|
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
|
||||||
hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
|
hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
|
||||||
|
@ -95,15 +107,6 @@ impl<'tcx> Const<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
|
|
||||||
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
|
|
||||||
let expr = match &expr.kind {
|
|
||||||
hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
|
|
||||||
block.expr.as_ref().unwrap()
|
|
||||||
}
|
|
||||||
_ => expr,
|
|
||||||
};
|
|
||||||
|
|
||||||
use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
|
use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
|
||||||
match expr.kind {
|
match expr.kind {
|
||||||
ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
|
ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
|
||||||
|
|
|
@ -53,6 +53,7 @@ pub fn add_placeholder_note(err: &mut rustc_errors::DiagnosticBuilder<'_>) {
|
||||||
/// If there are types that satisfy both impls, invokes `on_overlap`
|
/// If there are types that satisfy both impls, invokes `on_overlap`
|
||||||
/// with a suitably-freshened `ImplHeader` with those types
|
/// with a suitably-freshened `ImplHeader` with those types
|
||||||
/// substituted. Otherwise, invokes `no_overlap`.
|
/// substituted. Otherwise, invokes `no_overlap`.
|
||||||
|
#[instrument(skip(tcx, skip_leak_check, on_overlap, no_overlap), level = "debug")]
|
||||||
pub fn overlapping_impls<F1, F2, R>(
|
pub fn overlapping_impls<F1, F2, R>(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
impl1_def_id: DefId,
|
impl1_def_id: DefId,
|
||||||
|
@ -65,12 +66,6 @@ where
|
||||||
F1: FnOnce(OverlapResult<'_>) -> R,
|
F1: FnOnce(OverlapResult<'_>) -> R,
|
||||||
F2: FnOnce() -> R,
|
F2: FnOnce() -> R,
|
||||||
{
|
{
|
||||||
debug!(
|
|
||||||
"overlapping_impls(\
|
|
||||||
impl1_def_id={:?}, \
|
|
||||||
impl2_def_id={:?})",
|
|
||||||
impl1_def_id, impl2_def_id,
|
|
||||||
);
|
|
||||||
// Before doing expensive operations like entering an inference context, do
|
// Before doing expensive operations like entering an inference context, do
|
||||||
// a quick check via fast_reject to tell if the impl headers could possibly
|
// a quick check via fast_reject to tell if the impl headers could possibly
|
||||||
// unify.
|
// unify.
|
||||||
|
@ -85,6 +80,7 @@ where
|
||||||
.any(|(ty1, ty2)| {
|
.any(|(ty1, ty2)| {
|
||||||
let t1 = fast_reject::simplify_type(tcx, ty1, SimplifyParams::No, StripReferences::No);
|
let t1 = fast_reject::simplify_type(tcx, ty1, SimplifyParams::No, StripReferences::No);
|
||||||
let t2 = fast_reject::simplify_type(tcx, ty2, SimplifyParams::No, StripReferences::No);
|
let t2 = fast_reject::simplify_type(tcx, ty2, SimplifyParams::No, StripReferences::No);
|
||||||
|
|
||||||
if let (Some(t1), Some(t2)) = (t1, t2) {
|
if let (Some(t1), Some(t2)) = (t1, t2) {
|
||||||
// Simplified successfully
|
// Simplified successfully
|
||||||
t1 != t2
|
t1 != t2
|
||||||
|
|
|
@ -117,9 +117,8 @@ pub fn translate_substs<'a, 'tcx>(
|
||||||
/// Specialization is determined by the sets of types to which the impls apply;
|
/// Specialization is determined by the sets of types to which the impls apply;
|
||||||
/// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies
|
/// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies
|
||||||
/// to.
|
/// to.
|
||||||
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool {
|
pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool {
|
||||||
debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id);
|
|
||||||
|
|
||||||
// The feature gate should prevent introducing new specializations, but not
|
// The feature gate should prevent introducing new specializations, but not
|
||||||
// taking advantage of upstream ones.
|
// taking advantage of upstream ones.
|
||||||
let features = tcx.features();
|
let features = tcx.features();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue