Rollup merge of #152139 - khyperia:mgca-negative-literals, r=BoxyUwU
mGCA: Support directly represented negated literals
fixes rust-lang/rust#152123
PatExprKind already awkwardly tacks on a `negated: bool` for the same purpose:
8bccf1224d/compiler/rustc_hir/src/hir.rs (L1954-L1959)
perhaps one day we should indeed do that FIXME...
r? @BoxyUwU
This commit is contained in:
commit
30bbeae0a5
11 changed files with 70 additions and 19 deletions
|
|
@ -2570,7 +2570,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
ConstArg {
|
||||
hir_id: self.lower_node_id(expr.id),
|
||||
kind: hir::ConstArgKind::Literal(literal.node),
|
||||
kind: hir::ConstArgKind::Literal { lit: literal.node, negated: false },
|
||||
span,
|
||||
}
|
||||
}
|
||||
ExprKind::Unary(UnOp::Neg, inner_expr)
|
||||
if let ExprKind::Lit(literal) = &inner_expr.kind =>
|
||||
{
|
||||
let span = expr.span;
|
||||
let literal = self.lower_lit(literal, span);
|
||||
|
||||
ConstArg {
|
||||
hir_id: self.lower_node_id(expr.id),
|
||||
kind: hir::ConstArgKind::Literal { lit: literal.node, negated: true },
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -521,7 +521,10 @@ pub enum ConstArgKind<'hir, Unambig = ()> {
|
|||
/// This variant is not always used to represent inference consts, sometimes
|
||||
/// [`GenericArg::Infer`] is used instead.
|
||||
Infer(Unambig),
|
||||
Literal(LitKind),
|
||||
Literal {
|
||||
lit: LitKind,
|
||||
negated: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||
|
|
@ -1958,8 +1961,6 @@ pub struct PatExpr<'hir> {
|
|||
pub enum PatExprKind<'hir> {
|
||||
Lit {
|
||||
lit: Lit,
|
||||
// FIXME: move this into `Lit` and handle negated literal expressions
|
||||
// once instead of matching on unop neg expressions everywhere.
|
||||
negated: bool,
|
||||
},
|
||||
/// A path pattern for a unit struct/variant or a (maybe-associated) constant.
|
||||
|
|
|
|||
|
|
@ -1110,7 +1110,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
|
|||
ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()),
|
||||
ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
|
||||
ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important
|
||||
ConstArgKind::Literal(..) => V::Result::output(), // FIXME(mcga)
|
||||
ConstArgKind::Literal { .. } => V::Result::output(), // FIXME(mcga)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2377,8 +2377,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon),
|
||||
hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span),
|
||||
hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e),
|
||||
hir::ConstArgKind::Literal(kind) => {
|
||||
self.lower_const_arg_literal(&kind, ty, const_arg.span)
|
||||
hir::ConstArgKind::Literal { lit, negated } => {
|
||||
self.lower_const_arg_literal(&lit, negated, ty, const_arg.span)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2790,9 +2790,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn lower_const_arg_literal(&self, kind: &LitKind, ty: Ty<'tcx>, span: Span) -> Const<'tcx> {
|
||||
fn lower_const_arg_literal(
|
||||
&self,
|
||||
kind: &LitKind,
|
||||
neg: bool,
|
||||
ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
) -> Const<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let input = LitToConstInput { lit: *kind, ty, neg: false };
|
||||
let input = LitToConstInput { lit: *kind, ty, neg };
|
||||
tcx.at(span).lit_to_const(input)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1158,9 +1158,12 @@ impl<'a> State<'a> {
|
|||
ConstArgKind::Anon(anon) => self.print_anon_const(anon),
|
||||
ConstArgKind::Error(_) => self.word("/*ERROR*/"),
|
||||
ConstArgKind::Infer(..) => self.word("_"),
|
||||
ConstArgKind::Literal(node) => {
|
||||
ConstArgKind::Literal { lit, negated } => {
|
||||
if *negated {
|
||||
self.word("-");
|
||||
}
|
||||
let span = const_arg.span;
|
||||
self.print_literal(&Spanned { span, node: *node })
|
||||
self.print_literal(&Spanned { span, node: *lit })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1439,7 +1439,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
| hir::ConstArgKind::TupleCall(..)
|
||||
| hir::ConstArgKind::Tup(..)
|
||||
| hir::ConstArgKind::Path(..)
|
||||
| hir::ConstArgKind::Literal(..)
|
||||
| hir::ConstArgKind::Literal { .. }
|
||||
| hir::ConstArgKind::Infer(..) => true,
|
||||
hir::ConstArgKind::Anon(..) => false,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind
|
|||
}
|
||||
hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body },
|
||||
hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer,
|
||||
hir::ConstArgKind::Literal(..) => {
|
||||
hir::ConstArgKind::Literal { .. } => {
|
||||
ConstantKind::Path { path: "/* LITERAL */".to_string().into() }
|
||||
}
|
||||
}
|
||||
|
|
@ -1829,7 +1829,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
|||
| hir::ConstArgKind::TupleCall(..)
|
||||
| hir::ConstArgKind::Tup(..)
|
||||
| hir::ConstArgKind::Array(..)
|
||||
| hir::ConstArgKind::Literal(..) => {
|
||||
| hir::ConstArgKind::Literal { .. } => {
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize);
|
||||
print_const(cx, ct)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"),
|
||||
ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"),
|
||||
ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"),
|
||||
ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind"),
|
||||
ConstArgKind::Literal { .. } => chain!(self, "let ConstArgKind::Literal {{ .. }} = {const_arg}.kind"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1142,7 +1142,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx
|
|||
ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value),
|
||||
ConstArgKind::Struct(..)
|
||||
| ConstArgKind::Tup(..)
|
||||
| ConstArgKind::Literal(..)
|
||||
| ConstArgKind::Literal { .. }
|
||||
| ConstArgKind::TupleCall(..)
|
||||
| ConstArgKind::Array(..)
|
||||
| ConstArgKind::Path(_)
|
||||
|
|
|
|||
|
|
@ -686,7 +686,16 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
.zip(*args_b)
|
||||
.all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b))
|
||||
},
|
||||
(ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => kind_l == kind_r,
|
||||
(
|
||||
ConstArgKind::Literal {
|
||||
lit: kind_l,
|
||||
negated: negated_l,
|
||||
},
|
||||
ConstArgKind::Literal {
|
||||
lit: kind_r,
|
||||
negated: negated_r,
|
||||
},
|
||||
) => kind_l == kind_r && negated_l == negated_r,
|
||||
(ConstArgKind::Array(l_arr), ConstArgKind::Array(r_arr)) => {
|
||||
l_arr.elems.len() == r_arr.elems.len()
|
||||
&& l_arr
|
||||
|
|
@ -703,7 +712,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
| ConstArgKind::TupleCall(..)
|
||||
| ConstArgKind::Infer(..)
|
||||
| ConstArgKind::Struct(..)
|
||||
| ConstArgKind::Literal(..)
|
||||
| ConstArgKind::Literal { .. }
|
||||
| ConstArgKind::Array(..)
|
||||
| ConstArgKind::Error(..),
|
||||
_,
|
||||
|
|
@ -1599,7 +1608,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
}
|
||||
},
|
||||
ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {},
|
||||
ConstArgKind::Literal(lit) => lit.hash(&mut self.s),
|
||||
ConstArgKind::Literal { lit, negated } => {
|
||||
lit.hash(&mut self.s);
|
||||
negated.hash(&mut self.s);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
17
tests/ui/const-generics/mgca/negated-literal.rs
Normal file
17
tests/ui/const-generics/mgca/negated-literal.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(adt_const_params, min_generic_const_args)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::marker::ConstParamTy;
|
||||
|
||||
#[derive(Eq, PartialEq, ConstParamTy)]
|
||||
struct Foo {
|
||||
field: isize
|
||||
}
|
||||
|
||||
fn foo<const F: Foo>() {}
|
||||
|
||||
fn main() {
|
||||
foo::<{ Foo { field: -1 } }>();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue