Use a different hir type for patterns in pattern types than we use in match patterns
This commit is contained in:
parent
613bdd4997
commit
f0308938ba
27 changed files with 311 additions and 168 deletions
|
@ -436,9 +436,6 @@ hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a t
|
|||
hir_analysis_parenthesized_fn_trait_expansion =
|
||||
parenthesized trait syntax expands to `{$expanded_type}`
|
||||
|
||||
hir_analysis_pattern_type_non_const_range = range patterns must have constant range start and end
|
||||
hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pattern types
|
||||
.label = this type is the same as the inner type without a pattern
|
||||
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
|
||||
.label = not allowed in type signatures
|
||||
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
||||
|
|
|
@ -831,8 +831,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::Pat<'tcx>) {
|
||||
intravisit::walk_pat(self, p)
|
||||
fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::TyPat<'tcx>) {
|
||||
intravisit::walk_ty_pat(self, p)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
|
|
|
@ -18,9 +18,10 @@ use crate::hir_ty_lowering::HirTyLowerer;
|
|||
|
||||
mod opaque;
|
||||
|
||||
fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||
fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||
use hir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
let tcx = icx.tcx;
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
||||
let node = tcx.hir_node(hir_id);
|
||||
|
@ -54,7 +55,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
hir_id: arg_hir_id,
|
||||
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
|
||||
..
|
||||
}) if anon_hir_id == hir_id => const_arg_anon_type_of(tcx, arg_hir_id, span),
|
||||
}) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
|
||||
|
||||
// Anon consts outside the type system.
|
||||
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
||||
|
@ -138,10 +139,12 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
|
||||
fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
|
||||
use hir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
|
||||
let tcx = icx.tcx;
|
||||
|
||||
match tcx.parent_hir_node(arg_hir_id) {
|
||||
// Array length const arguments do not have `type_of` fed as there is never a corresponding
|
||||
// generic parameter definition.
|
||||
|
@ -149,7 +152,15 @@ fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span
|
|||
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
||||
if constant.hir_id == arg_hir_id =>
|
||||
{
|
||||
return tcx.types.usize;
|
||||
tcx.types.usize
|
||||
}
|
||||
|
||||
Node::TyPat(pat) => {
|
||||
let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else {
|
||||
bug!()
|
||||
};
|
||||
assert_eq!(p.hir_id, pat.hir_id);
|
||||
icx.lower_ty(ty)
|
||||
}
|
||||
|
||||
// This is not a `bug!` as const arguments in path segments that did not resolve to anything
|
||||
|
@ -344,7 +355,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
|||
tcx.typeck(def_id).node_type(hir_id)
|
||||
}
|
||||
|
||||
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
|
||||
Node::AnonConst(_) => anon_const_type_of(&icx, def_id),
|
||||
|
||||
Node::ConstBlock(_) => {
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
||||
|
|
|
@ -1605,13 +1605,6 @@ pub(crate) struct OpaqueCapturesHigherRankedLifetime {
|
|||
pub bad_place: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_pattern_type_non_const_range)]
|
||||
pub(crate) struct NonConstRange {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum InvalidReceiverTyHint {
|
||||
#[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
|
||||
|
|
|
@ -2,13 +2,6 @@ use rustc_macros::Diagnostic;
|
|||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Span;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_pattern_type_wild_pat)]
|
||||
pub(crate) struct WildPatTy {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_invalid_base_type)]
|
||||
pub(crate) struct InvalidBaseType<'tcx> {
|
||||
|
|
|
@ -53,7 +53,7 @@ use tracing::{debug, instrument};
|
|||
|
||||
use crate::bounds::Bounds;
|
||||
use crate::check::check_abi_fn_ptr;
|
||||
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, WildPatTy};
|
||||
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType};
|
||||
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
|
||||
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
||||
use crate::middle::resolve_bound_vars as rbv;
|
||||
|
@ -2435,11 +2435,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let ty_span = ty.span;
|
||||
let ty = self.lower_ty(ty);
|
||||
let pat_ty = match pat.kind {
|
||||
hir::PatKind::Wild => {
|
||||
let err = self.dcx().emit_err(WildPatTy { span: pat.span });
|
||||
Ty::new_error(tcx, err)
|
||||
}
|
||||
hir::PatKind::Range(start, end, include_end) => {
|
||||
hir::TyPatKind::Range(start, end, include_end) => {
|
||||
let ty = match ty.kind() {
|
||||
ty::Int(_) | ty::Uint(_) | ty::Char => ty,
|
||||
_ => Ty::new_error(
|
||||
|
@ -2452,54 +2448,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}),
|
||||
),
|
||||
};
|
||||
let expr_to_const = |expr: &'tcx hir::PatExpr<'tcx>| -> ty::Const<'tcx> {
|
||||
let (c, c_ty) = match expr.kind {
|
||||
hir::PatExprKind::Lit { lit, negated } => {
|
||||
let lit_input =
|
||||
LitToConstInput { lit: &lit.node, ty, neg: negated };
|
||||
let ct = tcx.lit_to_const(lit_input);
|
||||
(ct, ty)
|
||||
}
|
||||
|
||||
hir::PatExprKind::Path(hir::QPath::Resolved(
|
||||
_,
|
||||
path @ &hir::Path {
|
||||
res: Res::Def(DefKind::ConstParam, def_id),
|
||||
..
|
||||
},
|
||||
)) => {
|
||||
match self.prohibit_generic_args(
|
||||
path.segments.iter(),
|
||||
GenericsArgsErrExtend::Param(def_id),
|
||||
) {
|
||||
Ok(()) => {
|
||||
let ty = tcx
|
||||
.type_of(def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic");
|
||||
let ct = self.lower_const_param(def_id, expr.hir_id);
|
||||
(ct, ty)
|
||||
}
|
||||
Err(guar) => (
|
||||
ty::Const::new_error(tcx, guar),
|
||||
Ty::new_error(tcx, guar),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
let err = tcx
|
||||
.dcx()
|
||||
.emit_err(crate::errors::NonConstRange { span: expr.span });
|
||||
(ty::Const::new_error(tcx, err), Ty::new_error(tcx, err))
|
||||
}
|
||||
};
|
||||
self.record_ty(expr.hir_id, c_ty, expr.span);
|
||||
c
|
||||
};
|
||||
|
||||
let start = start.map(expr_to_const);
|
||||
let end = end.map(expr_to_const);
|
||||
let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
|
||||
let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
|
||||
|
||||
let include_end = match include_end {
|
||||
hir::RangeEnd::Included => true,
|
||||
|
@ -2509,12 +2459,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
|
||||
Ty::new_pat(tcx, ty, pat)
|
||||
}
|
||||
hir::PatKind::Err(e) => Ty::new_error(tcx, e),
|
||||
_ => Ty::new_error_with_message(
|
||||
tcx,
|
||||
pat.span,
|
||||
format!("unsupported pattern for pattern type: {pat:#?}"),
|
||||
),
|
||||
hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
|
||||
};
|
||||
self.record_ty(pat.hir_id, ty, pat.span);
|
||||
pat_ty
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue