@@ -533,43 +533,64 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
533533 }
534534 }
535535
536+ /// Converts inline const patterns.
537+ fn lower_inline_const(
538+ &mut self,
539+ anon_const: &'tcx hir::AnonConst,
540+ id: hir::HirId,
541+ span: Span,
542+ ) -> PatKind<'tcx> {
543+ let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
544+ let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id);
545+
546+ // Evaluate early like we do in `lower_path`.
547+ let value = value.eval(self.tcx, self.param_env);
548+
549+ match value.val {
550+ ConstKind::Param(_) => {
551+ self.errors.push(PatternError::ConstParamInPattern(span));
552+ return PatKind::Wild;
553+ }
554+ ConstKind::Unevaluated(_) => {
555+ // If we land here it means the const can't be evaluated because it's `TooGeneric`.
556+ self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter");
557+ return PatKind::Wild;
558+ }
559+ _ => (),
560+ }
561+
562+ *self.const_to_pat(value, id, span, false).kind
563+ }
564+
536565 /// Converts literals, paths and negation of literals to patterns.
537566 /// The special case for negation exists to allow things like `-128_i8`
538567 /// which would overflow if we tried to evaluate `128_i8` and then negate
539568 /// afterwards.
540569 fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> {
541- if let hir::ExprKind::Path(ref qpath) = expr.kind {
542- *self.lower_path(qpath, expr.hir_id, expr.span).kind
543- } else {
544- let (lit, neg) = match expr.kind {
545- hir::ExprKind::ConstBlock(ref anon_const) => {
546- let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
547- let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id);
548- if matches!(value.val, ConstKind::Param(_)) {
549- let span = self.tcx.hir().span(anon_const.hir_id);
550- self.errors.push(PatternError::ConstParamInPattern(span));
551- return PatKind::Wild;
552- }
553- return *self.const_to_pat(value, expr.hir_id, expr.span, false).kind;
554- }
555- hir::ExprKind::Lit(ref lit) => (lit, false),
556- hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => {
557- let lit = match expr.kind {
558- hir::ExprKind::Lit(ref lit) => lit,
559- _ => span_bug!(expr.span, "not a literal: {:?}", expr),
560- };
561- (lit, true)
562- }
563- _ => span_bug!(expr.span, "not a literal: {:?}", expr),
564- };
565-
566- let lit_input =
567- LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
568- match self.tcx.at(expr.span).lit_to_const(lit_input) {
569- Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span, false).kind,
570- Err(LitToConstError::Reported) => PatKind::Wild,
571- Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
570+ let (lit, neg) = match expr.kind {
571+ hir::ExprKind::Path(ref qpath) => {
572+ return *self.lower_path(qpath, expr.hir_id, expr.span).kind;
573+ }
574+ hir::ExprKind::ConstBlock(ref anon_const) => {
575+ return self.lower_inline_const(anon_const, expr.hir_id, expr.span);
576+ }
577+ hir::ExprKind::Lit(ref lit) => (lit, false),
578+ hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => {
579+ let lit = match expr.kind {
580+ hir::ExprKind::Lit(ref lit) => lit,
581+ _ => span_bug!(expr.span, "not a literal: {:?}", expr),
582+ };
583+ (lit, true)
572584 }
585+ _ => span_bug!(expr.span, "not a literal: {:?}", expr),
586+ };
587+
588+ let lit_input =
589+ LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
590+ match self.tcx.at(expr.span).lit_to_const(lit_input) {
591+ Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span, false).kind,
592+ Err(LitToConstError::Reported) => PatKind::Wild,
593+ Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
573594 }
574595 }
575596}
0 commit comments