Skip to content

Commit 871b595

Browse files
committedMay 31, 2023
Auto merge of rust-lang#111913 - oli-obk:valtrees2, r=lcnr
Only rewrite valtree-constants to patterns and keep other constants opaque Now that we can reliably fall back to comparing constants with `PartialEq::eq` to the match scrutinee, we can 1. eagerly try to convert constants to valtrees 2. then deeply convert the valtree to a pattern 3. if the to-valtree conversion failed, create an "opaque constant" pattern. This PR specifically avoids any behavioral changes or major cleanups. What we can now do as follow ups is * move the two remaining call sites to `destructure_mir_constant` off that query * make valtree to pattern conversion infallible * this needs to be done after careful analysis of the effects. There may be user visible changes from that. based on rust-lang#111768
2 parents ad8304a + 3c02cfc commit 871b595

File tree

21 files changed

+302
-325
lines changed

21 files changed

+302
-325
lines changed
 

‎compiler/rustc_const_eval/src/const_eval/mod.rs

+1-38
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22

33
use crate::errors::MaxNumNodesInConstErr;
44
use crate::interpret::{
5-
intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta,
6-
Scalar,
5+
intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, Scalar,
76
};
8-
use rustc_hir::Mutability;
97
use rustc_middle::mir;
108
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
119
use rustc_middle::ty::{self, TyCtxt};
@@ -131,38 +129,3 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
131129

132130
Ok(mir::DestructuredConstant { variant, fields })
133131
}
134-
135-
#[instrument(skip(tcx), level = "debug")]
136-
pub(crate) fn deref_mir_constant<'tcx>(
137-
tcx: TyCtxt<'tcx>,
138-
param_env: ty::ParamEnv<'tcx>,
139-
val: mir::ConstantKind<'tcx>,
140-
) -> mir::ConstantKind<'tcx> {
141-
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
142-
let op = ecx.eval_mir_constant(&val, None, None).unwrap();
143-
let mplace = ecx.deref_operand(&op).unwrap();
144-
if let Some(alloc_id) = mplace.ptr.provenance {
145-
assert_eq!(
146-
tcx.global_alloc(alloc_id).unwrap_memory().0.0.mutability,
147-
Mutability::Not,
148-
"deref_mir_constant cannot be used with mutable allocations as \
149-
that could allow pattern matching to observe mutable statics",
150-
);
151-
}
152-
153-
let ty = match mplace.meta {
154-
MemPlaceMeta::None => mplace.layout.ty,
155-
// In case of unsized types, figure out the real type behind.
156-
MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() {
157-
ty::Str => bug!("there's no sized equivalent of a `str`"),
158-
ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_target_usize(&tcx).unwrap()),
159-
_ => bug!(
160-
"type {} should not have metadata, but had {:?}",
161-
mplace.layout.ty,
162-
mplace.meta
163-
),
164-
},
165-
};
166-
167-
mir::ConstantKind::Val(op_to_const(&ecx, &mplace.into()), ty)
168-
}

‎compiler/rustc_const_eval/src/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ pub fn provide(providers: &mut Providers) {
5656
providers.valtree_to_const_val = |tcx, (ty, valtree)| {
5757
const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree)
5858
};
59-
providers.deref_mir_constant = |tcx, param_env_and_value| {
60-
let (param_env, value) = param_env_and_value.into_parts();
61-
const_eval::deref_mir_constant(tcx, param_env, value)
62-
};
6359
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
6460
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
6561
};

‎compiler/rustc_metadata/src/rmeta/table.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ where
439439
/// Given the metadata, extract out the value at a particular index (if any).
440440
#[inline(never)]
441441
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
442-
debug!("LazyTable::lookup: index={:?} len={:?}", i, self.encoded_size);
442+
trace!("LazyTable::lookup: index={:?} len={:?}", i, self.encoded_size);
443443

444444
let start = self.position.get();
445445
let bytes = &metadata.blob()[start..start + self.encoded_size];

‎compiler/rustc_middle/src/mir/mod.rs

+1-46
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
44
55
use crate::mir::interpret::{
6-
AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, LitToConstInput, Scalar,
6+
AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
77
};
88
use crate::mir::visit::MirVisitable;
99
use crate::ty::codec::{TyDecoder, TyEncoder};
@@ -2461,51 +2461,6 @@ impl<'tcx> ConstantKind<'tcx> {
24612461
Self::Val(val, ty)
24622462
}
24632463

2464-
#[instrument(skip(tcx), level = "debug", ret)]
2465-
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
2466-
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
2467-
let body_id = match tcx.hir().get(hir_id) {
2468-
hir::Node::AnonConst(ac) => ac.body,
2469-
_ => span_bug!(
2470-
tcx.def_span(def_id.to_def_id()),
2471-
"from_inline_const can only process anonymous constants"
2472-
),
2473-
};
2474-
let expr = &tcx.hir().body(body_id).value;
2475-
let ty = tcx.typeck(def_id).node_type(hir_id);
2476-
2477-
let lit_input = match expr.kind {
2478-
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
2479-
hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
2480-
hir::ExprKind::Lit(ref lit) => {
2481-
Some(LitToConstInput { lit: &lit.node, ty, neg: true })
2482-
}
2483-
_ => None,
2484-
},
2485-
_ => None,
2486-
};
2487-
if let Some(lit_input) = lit_input {
2488-
// If an error occurred, ignore that it's a literal and leave reporting the error up to
2489-
// mir.
2490-
match tcx.at(expr.span).lit_to_mir_constant(lit_input) {
2491-
Ok(c) => return c,
2492-
Err(_) => {}
2493-
}
2494-
}
2495-
2496-
let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
2497-
let parent_substs =
2498-
tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
2499-
let substs =
2500-
ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
2501-
.substs;
2502-
2503-
let uneval = UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None };
2504-
debug_assert!(!uneval.has_free_regions());
2505-
2506-
Self::Unevaluated(uneval, ty)
2507-
}
2508-
25092464
/// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
25102465
/// converted to a constant, everything else becomes `Unevaluated`.
25112466
#[instrument(skip(tcx), level = "debug", ret)]

‎compiler/rustc_middle/src/query/mod.rs

-12
Original file line numberDiff line numberDiff line change
@@ -1081,14 +1081,6 @@ rustc_queries! {
10811081
desc { "destructuring MIR constant"}
10821082
}
10831083

1084-
/// Dereference a constant reference or raw pointer and turn the result into a constant
1085-
/// again.
1086-
query deref_mir_constant(
1087-
key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
1088-
) -> mir::ConstantKind<'tcx> {
1089-
desc { "dereferencing MIR constant" }
1090-
}
1091-
10921084
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
10931085
desc { "getting a &core::panic::Location referring to a span" }
10941086
}
@@ -1100,10 +1092,6 @@ rustc_queries! {
11001092
desc { "converting literal to const" }
11011093
}
11021094

1103-
query lit_to_mir_constant(key: LitToConstInput<'tcx>) -> Result<mir::ConstantKind<'tcx>, LitToConstError> {
1104-
desc { "converting literal to mir constant" }
1105-
}
1106-
11071095
query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> {
11081096
desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) }
11091097
cache_on_disk_if { true }

‎compiler/rustc_mir_build/src/build/expr/as_constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub fn as_constant_inner<'tcx>(
106106
}
107107

108108
#[instrument(skip(tcx, lit_input))]
109-
pub(crate) fn lit_to_mir_constant<'tcx>(
109+
fn lit_to_mir_constant<'tcx>(
110110
tcx: TyCtxt<'tcx>,
111111
lit_input: LitToConstInput<'tcx>,
112112
) -> Result<ConstantKind<'tcx>, LitToConstError> {

‎compiler/rustc_mir_build/src/build/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
pub(crate) use crate::build::expr::as_constant::lit_to_mir_constant;
21
use crate::build::expr::as_place::PlaceBuilder;
32
use crate::build::scope::DropKind;
43
use rustc_apfloat::ieee::{Double, Single};

‎compiler/rustc_mir_build/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ fluent_messages! { "../messages.ftl" }
3232
pub fn provide(providers: &mut Providers) {
3333
providers.check_match = thir::pattern::check_match;
3434
providers.lit_to_const = thir::constant::lit_to_const;
35-
providers.lit_to_mir_constant = build::lit_to_mir_constant;
3635
providers.mir_built = build::mir_built;
3736
providers.thir_check_unsafety = check_unsafety::thir_check_unsafety;
3837
providers.thir_body = thir::cx::thir_body;

‎compiler/rustc_mir_build/src/thir/constant.rs

+18
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
33
use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt};
44
use rustc_span::DUMMY_SP;
55

6+
use crate::build::parse_float_into_scalar;
7+
68
pub(crate) fn lit_to_const<'tcx>(
79
tcx: TyCtxt<'tcx>,
810
lit_input: LitToConstInput<'tcx>,
@@ -46,12 +48,28 @@ pub(crate) fn lit_to_const<'tcx>(
4648
(ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => {
4749
ty::ValTree::from_scalar_int((*n).into())
4850
}
51+
(ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) =>
52+
{
53+
let bytes = data as &[u8];
54+
ty::ValTree::from_raw_bytes(tcx, bytes)
55+
}
4956
(ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
5057
let scalar_int =
5158
trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })?;
5259
ty::ValTree::from_scalar_int(scalar_int)
5360
}
5461
(ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()),
62+
(ast::LitKind::Float(n, _), ty::Float(fty)) => {
63+
let bits = parse_float_into_scalar(*n, *fty, neg)
64+
.ok_or_else(|| {
65+
LitToConstError::Reported(tcx.sess.delay_span_bug(
66+
DUMMY_SP,
67+
format!("couldn't parse float literal: {:?}", lit_input.lit),
68+
))
69+
})?
70+
.assert_int();
71+
ty::ValTree::from_scalar_int(bits)
72+
}
5573
(ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
5674
(ast::LitKind::Err, _) => {
5775
return Err(LitToConstError::Reported(

‎compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+165-146
Large diffs are not rendered by default.

‎compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs

+11-22
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ use smallvec::{smallvec, SmallVec};
5353
use rustc_data_structures::captures::Captures;
5454
use rustc_hir::{HirId, RangeEnd};
5555
use rustc_index::Idx;
56+
use rustc_middle::middle::stability::EvalResult;
5657
use rustc_middle::mir;
5758
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
5859
use rustc_middle::ty::layout::IntegerExt;
5960
use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
60-
use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue};
6161
use rustc_session::lint;
6262
use rustc_span::{Span, DUMMY_SP};
6363
use rustc_target::abi::{FieldIdx, Integer, Size, VariantIdx, FIRST_VARIANT};
@@ -140,28 +140,17 @@ impl IntRange {
140140
value: mir::ConstantKind<'tcx>,
141141
) -> Option<IntRange> {
142142
let ty = value.ty();
143-
if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) {
144-
let val = if let mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) = value {
145-
// For this specific pattern we can skip a lot of effort and go
146-
// straight to the result, after doing a bit of checking. (We
147-
// could remove this branch and just fall through, which
148-
// is more general but much slower.)
149-
scalar.to_bits_or_ptr_internal(target_size).unwrap().left()?
150-
} else {
151-
if let mir::ConstantKind::Ty(c) = value
152-
&& let ty::ConstKind::Value(_) = c.kind()
153-
{
154-
bug!("encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val");
155-
}
143+
let (target_size, bias) = Self::integral_size_and_signed_bias(tcx, ty)?;
144+
let val = match value {
145+
mir::ConstantKind::Ty(c) if let ty::ConstKind::Value(valtree) = c.kind() => {
146+
valtree.unwrap_leaf().to_bits(target_size).ok()
147+
},
148+
// This is a more general form of the previous case.
149+
_ => value.try_eval_bits(tcx, param_env, ty),
150+
}?;
156151

157-
// This is a more general form of the previous case.
158-
value.try_eval_bits(tcx, param_env, ty)?
159-
};
160-
let val = val ^ bias;
161-
Some(IntRange { range: val..=val, bias })
162-
} else {
163-
None
164-
}
152+
let val = val ^ bias;
153+
Some(IntRange { range: val..=val, bias })
165154
}
166155

167156
#[inline]

‎compiler/rustc_mir_build/src/thir/pattern/mod.rs

+90-34
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
1818
use rustc_hir::RangeEnd;
1919
use rustc_index::Idx;
2020
use rustc_middle::mir::interpret::{
21-
ConstValue, ErrorHandled, LitToConstError, LitToConstInput, Scalar,
21+
ConstValue, ErrorHandled, GlobalId, LitToConstError, LitToConstInput, Scalar,
2222
};
23-
use rustc_middle::mir::{self, UserTypeProjection};
23+
use rustc_middle::mir::{self, ConstantKind, UserTypeProjection};
2424
use rustc_middle::mir::{BorrowKind, Mutability};
2525
use rustc_middle::thir::{Ascription, BindingMode, FieldPat, LocalVarId, Pat, PatKind, PatRange};
2626
use rustc_middle::ty::subst::{GenericArg, SubstsRef};
2727
use rustc_middle::ty::CanonicalUserTypeAnnotation;
28-
use rustc_middle::ty::{self, AdtDef, ConstKind, Region, Ty, TyCtxt, UserType};
28+
use rustc_middle::ty::TypeVisitableExt;
29+
use rustc_middle::ty::{self, AdtDef, Region, Ty, TyCtxt, UserType};
2930
use rustc_span::{Span, Symbol};
3031
use rustc_target::abi::FieldIdx;
3132

@@ -518,16 +519,24 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
518519
}
519520
};
520521

521-
// `mir_const_qualif` must be called with the `DefId` of the item where the const is
522-
// defined, not where it is declared. The difference is significant for associated
523-
// constants.
524-
let mir_structural_match_violation = self.tcx.mir_const_qualif(instance.def_id()).custom_eq;
525-
debug!("mir_structural_match_violation({:?}) -> {}", qpath, mir_structural_match_violation);
526-
527-
match self.tcx.const_eval_instance(param_env_reveal_all, instance, Some(span)) {
528-
Ok(literal) => {
529-
let const_ = mir::ConstantKind::Val(literal, ty);
530-
let pattern = self.const_to_pat(const_, id, span, mir_structural_match_violation);
522+
let cid = GlobalId { instance, promoted: None };
523+
// Prefer valtrees over opaque constants.
524+
let const_value = self
525+
.tcx
526+
.const_eval_global_id_for_typeck(param_env_reveal_all, cid, Some(span))
527+
.map(|val| match val {
528+
Some(valtree) => mir::ConstantKind::Ty(self.tcx.mk_const(valtree, ty)),
529+
None => mir::ConstantKind::Val(
530+
self.tcx
531+
.const_eval_global_id(param_env_reveal_all, cid, Some(span))
532+
.expect("const_eval_global_id_for_typeck should have already failed"),
533+
ty,
534+
),
535+
});
536+
537+
match const_value {
538+
Ok(const_) => {
539+
let pattern = self.const_to_pat(const_, id, span, Some(instance.def_id()));
531540

532541
if !is_associated_const {
533542
return pattern;
@@ -577,27 +586,69 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
577586
id: hir::HirId,
578587
span: Span,
579588
) -> PatKind<'tcx> {
580-
let value = mir::ConstantKind::from_inline_const(self.tcx, anon_const.def_id);
581-
582-
// Evaluate early like we do in `lower_path`.
583-
let value = value.eval(self.tcx, self.param_env);
584-
585-
match value {
586-
mir::ConstantKind::Ty(c) => match c.kind() {
587-
ConstKind::Param(_) => {
588-
self.tcx.sess.emit_err(ConstParamInPattern { span });
589-
return PatKind::Wild;
590-
}
591-
ConstKind::Error(_) => {
592-
return PatKind::Wild;
589+
let tcx = self.tcx;
590+
let def_id = anon_const.def_id;
591+
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
592+
let body_id = match tcx.hir().get(hir_id) {
593+
hir::Node::AnonConst(ac) => ac.body,
594+
_ => span_bug!(
595+
tcx.def_span(def_id.to_def_id()),
596+
"from_inline_const can only process anonymous constants"
597+
),
598+
};
599+
let expr = &tcx.hir().body(body_id).value;
600+
let ty = tcx.typeck(def_id).node_type(hir_id);
601+
602+
// Special case inline consts that are just literals. This is solely
603+
// a performance optimization, as we could also just go through the regular
604+
// const eval path below.
605+
// FIXME: investigate the performance impact of removing this.
606+
let lit_input = match expr.kind {
607+
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
608+
hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
609+
hir::ExprKind::Lit(ref lit) => {
610+
Some(LitToConstInput { lit: &lit.node, ty, neg: true })
593611
}
594-
_ => bug!("Expected ConstKind::Param"),
612+
_ => None,
595613
},
596-
mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
597-
mir::ConstantKind::Unevaluated(..) => {
598-
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
599-
self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
600-
return PatKind::Wild;
614+
_ => None,
615+
};
616+
if let Some(lit_input) = lit_input {
617+
match tcx.at(expr.span).lit_to_const(lit_input) {
618+
Ok(c) => return self.const_to_pat(ConstantKind::Ty(c), id, span, None).kind,
619+
// If an error occurred, ignore that it's a literal
620+
// and leave reporting the error up to const eval of
621+
// the unevaluated constant below.
622+
Err(_) => {}
623+
}
624+
}
625+
626+
let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
627+
let parent_substs =
628+
tcx.erase_regions(ty::InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
629+
let substs =
630+
ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
631+
.substs;
632+
633+
let uneval = mir::UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None };
634+
debug_assert!(!substs.has_free_regions());
635+
636+
let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), substs: substs };
637+
// First try using a valtree in order to destructure the constant into a pattern.
638+
if let Ok(Some(valtree)) =
639+
self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, Some(span))
640+
{
641+
self.const_to_pat(ConstantKind::Ty(self.tcx.mk_const(valtree, ty)), id, span, None).kind
642+
} else {
643+
// If that fails, convert it to an opaque constant pattern.
644+
match tcx.const_eval_resolve(self.param_env, uneval, None) {
645+
Ok(val) => self.const_to_pat(mir::ConstantKind::Val(val, ty), id, span, None).kind,
646+
Err(ErrorHandled::TooGeneric) => {
647+
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
648+
self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
649+
PatKind::Wild
650+
}
651+
Err(ErrorHandled::Reported(_)) => PatKind::Wild,
601652
}
602653
}
603654
}
@@ -626,8 +677,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
626677

627678
let lit_input =
628679
LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
629-
match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) {
630-
Ok(constant) => self.const_to_pat(constant, expr.hir_id, lit.span, false).kind,
680+
match self.tcx.at(expr.span).lit_to_const(lit_input) {
681+
Ok(constant) => {
682+
self.const_to_pat(ConstantKind::Ty(constant), expr.hir_id, lit.span, None).kind
683+
}
631684
Err(LitToConstError::Reported(_)) => PatKind::Wild,
632685
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
633686
}
@@ -806,6 +859,9 @@ pub(crate) fn compare_const_vals<'tcx>(
806859
mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(a)), _a_ty),
807860
mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(b)), _b_ty),
808861
) => return Some(a.cmp(&b)),
862+
(mir::ConstantKind::Ty(a), mir::ConstantKind::Ty(b)) => {
863+
return Some(a.kind().cmp(&b.kind()));
864+
}
809865
_ => {}
810866
},
811867
}

‎compiler/rustc_mir_transform/src/required_consts.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
1717
let literal = constant.literal;
1818
match literal {
1919
ConstantKind::Ty(c) => match c.kind() {
20-
ConstKind::Param(_) | ConstKind::Error(_) => {}
21-
_ => bug!("only ConstKind::Param should be encountered here, got {:#?}", c),
20+
ConstKind::Param(_) | ConstKind::Error(_) | ConstKind::Value(_) => {}
21+
_ => bug!("only ConstKind::Param/Value should be encountered here, got {:#?}", c),
2222
},
2323
ConstantKind::Unevaluated(..) => self.required_consts.push(*constant),
2424
ConstantKind::Val(..) => {}

‎compiler/rustc_span/src/hygiene.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ pub fn decode_expn_id(
12881288
decode_data: impl FnOnce(ExpnId) -> (ExpnData, ExpnHash),
12891289
) -> ExpnId {
12901290
if index == 0 {
1291-
debug!("decode_expn_id: deserialized root");
1291+
trace!("decode_expn_id: deserialized root");
12921292
return ExpnId::root();
12931293
}
12941294

@@ -1321,7 +1321,7 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
13211321
) -> SyntaxContext {
13221322
let raw_id: u32 = Decodable::decode(d);
13231323
if raw_id == 0 {
1324-
debug!("decode_syntax_context: deserialized root");
1324+
trace!("decode_syntax_context: deserialized root");
13251325
// The root is special
13261326
return SyntaxContext::root();
13271327
}

‎tests/codegen/const_scalar_pair.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#![feature(inline_const)]
44

5+
// Test that we don't generate a memory allocation for the constant
6+
// and read the fields from that, but instead just create the value pair directly.
57
pub fn foo() -> (i32, i32) {
68
// CHECK: ret { i32, i32 } { i32 1, i32 2 }
79
const { (1, 2) }

‎tests/incremental/issue-101518.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
1-
// revisions: cfail1
2-
// should-ice
3-
// error-pattern: forcing query
4-
// known-bug: #101518
1+
// revisions: cpass
52

63
#[derive(PartialEq, Eq)]
74
struct Id<'a> {
85
ns: &'a str,
96
}
107
fn visit_struct() {
118
let id = Id { ns: "random1" };
12-
const FLAG: Id<'static> = Id {
13-
ns: "needs_to_be_the_same",
14-
};
9+
const FLAG: Id<'static> = Id { ns: "needs_to_be_the_same" };
1510
match id {
1611
FLAG => {}
1712
_ => {}
1813
}
1914
}
2015
fn visit_struct2() {
2116
let id = Id { ns: "random2" };
22-
const FLAG: Id<'static> = Id {
23-
ns: "needs_to_be_the_same",
24-
};
17+
const FLAG: Id<'static> = Id { ns: "needs_to_be_the_same" };
2518
match id {
2619
FLAG => {}
2720
_ => {}

‎tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn foo(_1: Option<String>) -> i32 {
3535
// + literal: Const { ty: for<'a, 'b> fn(&'a str, &'b str) -> bool {<str as PartialEq>::eq}, val: Value(<ZST>) }
3636
// mir::Constant
3737
// + span: $DIR/string.rs:9:14: 9:17
38-
// + literal: Const { ty: &str, val: Value(Slice(..)) }
38+
// + literal: Const { ty: &str, val: Value(ValTree::Branch(..)) }
3939
}
4040

4141
bb3: {

‎tests/ui/match/issue-70972-dyn-trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fn main() {
44
let a: &dyn Send = &7u32;
55
match a {
66
F => panic!(),
7-
//~^ ERROR `&dyn Send` cannot be used in patterns
7+
//~^ ERROR `dyn Send` cannot be used in patterns
88
_ => {}
99
}
1010
}

‎tests/ui/match/issue-70972-dyn-trait.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: `&dyn Send` cannot be used in patterns
1+
error: `dyn Send` cannot be used in patterns
22
--> $DIR/issue-70972-dyn-trait.rs:6:9
33
|
44
LL | F => panic!(),

‎tests/ui/pattern/issue-72565.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ const F: &'static dyn PartialEq<u32> = &7u32;
33
fn main() {
44
let a: &dyn PartialEq<u32> = &7u32;
55
match a {
6-
F => panic!(), //~ ERROR: `&dyn PartialEq<u32>` cannot be used in patterns
6+
F => panic!(), //~ ERROR: `dyn PartialEq<u32>` cannot be used in patterns
77
}
88
}

‎tests/ui/pattern/issue-72565.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: `&dyn PartialEq<u32>` cannot be used in patterns
1+
error: `dyn PartialEq<u32>` cannot be used in patterns
22
--> $DIR/issue-72565.rs:6:9
33
|
44
LL | F => panic!(),

0 commit comments

Comments
 (0)
Please sign in to comment.