Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,10 +632,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
let tcx = self.tcx;
trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
self.typeck_results
.borrow_mut()
.treat_byte_string_as_slice
.insert(lt.hir_id.local_id);
pat_ty =
Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, Ty::new_slice(tcx, tcx.types.u8));
}
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports);
wbcx.typeck_results.used_trait_imports = used_trait_imports;

wbcx.typeck_results.treat_byte_string_as_slice =
mem::take(&mut self.typeck_results.borrow_mut().treat_byte_string_as_slice);

debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results);

self.tcx.arena.alloc(wbcx.typeck_results)
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_middle/src/ty/typeck_results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,6 @@ pub struct TypeckResults<'tcx> {
/// formatting modified file tests/ui/coroutine/retain-resume-ref.rs
pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,

/// We sometimes treat byte string literals (which are of type `&[u8; N]`)
/// as `&[u8]`, depending on the pattern in which they are used.
/// This hashset records all instances where we behave
/// like this to allow `const_to_pat` to reliably handle this situation.
pub treat_byte_string_as_slice: ItemLocalSet,

/// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
/// on closure size.
pub closure_size_eval: LocalDefIdMap<ClosureSizeProfileData<'tcx>>,
Expand Down Expand Up @@ -237,7 +231,6 @@ impl<'tcx> TypeckResults<'tcx> {
closure_fake_reads: Default::default(),
rvalue_scopes: Default::default(),
coroutine_stalled_predicates: Default::default(),
treat_byte_string_as_slice: Default::default(),
closure_size_eval: Default::default(),
offset_of_data: Default::default(),
}
Expand Down
31 changes: 2 additions & 29 deletions compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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).
Expand Down Expand Up @@ -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) }
}
}
},
Expand Down
17 changes: 13 additions & 4 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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;
Expand All @@ -641,7 +645,12 @@ 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.
let ct_ty = pat_ty.unwrap_or_else(|| 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
Expand Down