Auto merge of #139269 - matthiaskrgr:rollup-pk78gig, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #138992 (literal pattern lowering: use the pattern's type instead of the literal's in `const_to_pat`) - #139211 (interpret: add a version of run_for_validation for &self) - #139235 (`AstValidator` tweaks) - #139237 (Add a dep kind for use of the anon node with zero dependencies) - #139260 (Add dianqk to codegen reviewers) - #139264 (Fix two incorrect turbofish suggestions) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d5b4c2e4f1
22 changed files with 477 additions and 264 deletions
|
@ -58,25 +58,13 @@ struct ConstToPat<'tcx> {
|
|||
span: Span,
|
||||
id: hir::HirId,
|
||||
|
||||
treat_byte_string_as_slice: bool,
|
||||
|
||||
c: ty::Const<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> ConstToPat<'tcx> {
|
||||
fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
|
||||
trace!(?pat_ctxt.typeck_results.hir_owner);
|
||||
ConstToPat {
|
||||
tcx: pat_ctxt.tcx,
|
||||
typing_env: pat_ctxt.typing_env,
|
||||
span,
|
||||
id,
|
||||
treat_byte_string_as_slice: pat_ctxt
|
||||
.typeck_results
|
||||
.treat_byte_string_as_slice
|
||||
.contains(&id.local_id),
|
||||
c,
|
||||
}
|
||||
ConstToPat { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, id, c }
|
||||
}
|
||||
|
||||
fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool {
|
||||
|
@ -108,8 +96,6 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||
uv: ty::UnevaluatedConst<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Box<Pat<'tcx>> {
|
||||
trace!(self.treat_byte_string_as_slice);
|
||||
|
||||
// It's not *technically* correct to be revealing opaque types here as borrowcheck has
|
||||
// not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
|
||||
// during typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
|
||||
|
@ -307,21 +293,8 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||
ty,
|
||||
);
|
||||
} else {
|
||||
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
|
||||
// matching against references, you can only use byte string literals.
|
||||
// The typechecker has a special case for byte string literals, by treating them
|
||||
// as slices. This means we turn `&[T; N]` constants into slice patterns, which
|
||||
// has no negative effects on pattern matching, even if we're actually matching on
|
||||
// arrays.
|
||||
let pointee_ty = match *pointee_ty.kind() {
|
||||
ty::Array(elem_ty, _) if self.treat_byte_string_as_slice => {
|
||||
Ty::new_slice(tcx, elem_ty)
|
||||
}
|
||||
_ => *pointee_ty,
|
||||
};
|
||||
// References have the same valtree representation as their pointee.
|
||||
let subpattern = self.valtree_to_pat(cv, pointee_ty);
|
||||
PatKind::Deref { subpattern }
|
||||
PatKind::Deref { subpattern: self.valtree_to_pat(cv, *pointee_ty) }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_abi::{FieldIdx, Integer};
|
|||
use rustc_errors::codes::*;
|
||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use rustc_hir::{self as hir, RangeEnd};
|
||||
use rustc_hir::{self as hir, LangItem, RangeEnd};
|
||||
use rustc_index::Idx;
|
||||
use rustc_middle::mir::interpret::LitToConstInput;
|
||||
use rustc_middle::thir::{
|
||||
|
@ -130,7 +130,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
|
||||
// Lower the endpoint into a temporary `PatKind` that will then be
|
||||
// deconstructed to obtain the constant value and other data.
|
||||
let mut kind: PatKind<'tcx> = self.lower_pat_expr(expr);
|
||||
let mut kind: PatKind<'tcx> = self.lower_pat_expr(expr, None);
|
||||
|
||||
// Unpeel any ascription or inline-const wrapper nodes.
|
||||
loop {
|
||||
|
@ -294,7 +294,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
|
||||
hir::PatKind::Never => PatKind::Never,
|
||||
|
||||
hir::PatKind::Expr(value) => self.lower_pat_expr(value),
|
||||
hir::PatKind::Expr(value) => self.lower_pat_expr(value, Some(ty)),
|
||||
|
||||
hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => {
|
||||
let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref());
|
||||
|
@ -630,7 +630,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
/// - Paths (e.g. `FOO`, `foo::BAR`, `Option::None`)
|
||||
/// - Inline const blocks (e.g. `const { 1 + 1 }`)
|
||||
/// - Literals, possibly negated (e.g. `-128u8`, `"hello"`)
|
||||
fn lower_pat_expr(&mut self, expr: &'tcx hir::PatExpr<'tcx>) -> PatKind<'tcx> {
|
||||
fn lower_pat_expr(
|
||||
&mut self,
|
||||
expr: &'tcx hir::PatExpr<'tcx>,
|
||||
pat_ty: Option<Ty<'tcx>>,
|
||||
) -> PatKind<'tcx> {
|
||||
let (lit, neg) = match &expr.kind {
|
||||
hir::PatExprKind::Path(qpath) => {
|
||||
return self.lower_path(qpath, expr.hir_id, expr.span).kind;
|
||||
|
@ -641,7 +645,31 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
hir::PatExprKind::Lit { lit, negated } => (lit, *negated),
|
||||
};
|
||||
|
||||
let ct_ty = self.typeck_results.node_type(expr.hir_id);
|
||||
// We handle byte string literal patterns by using the pattern's type instead of the
|
||||
// literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference,
|
||||
// the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the
|
||||
// pattern's type means we'll properly translate it to a slice reference pattern. This works
|
||||
// because slices and arrays have the same valtree representation.
|
||||
// HACK: As an exception, use the literal's type if `pat_ty` is `String`; this can happen if
|
||||
// `string_deref_patterns` is enabled. There's a special case for that when lowering to MIR.
|
||||
// FIXME(deref_patterns): This hack won't be necessary once `string_deref_patterns` is
|
||||
// superseded by a more general implementation of deref patterns.
|
||||
let ct_ty = match pat_ty {
|
||||
Some(pat_ty)
|
||||
if let ty::Adt(def, _) = *pat_ty.kind()
|
||||
&& self.tcx.is_lang_item(def.did(), LangItem::String) =>
|
||||
{
|
||||
if !self.tcx.features().string_deref_patterns() {
|
||||
span_bug!(
|
||||
expr.span,
|
||||
"matching on `String` went through without enabling string_deref_patterns"
|
||||
);
|
||||
}
|
||||
self.typeck_results.node_type(expr.hir_id)
|
||||
}
|
||||
Some(pat_ty) => pat_ty,
|
||||
None => self.typeck_results.node_type(expr.hir_id),
|
||||
};
|
||||
let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg };
|
||||
let constant = self.tcx.at(expr.span).lit_to_const(lit_input);
|
||||
self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue