MGCA: literals support
This commit is contained in:
parent
32fe406b5e
commit
9f3956f378
12 changed files with 47 additions and 17 deletions
|
|
@ -2536,6 +2536,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
overly_complex_const(self)
|
||||
}
|
||||
ExprKind::Lit(literal) => {
|
||||
let span = expr.span;
|
||||
let literal = self.lower_lit(literal, span);
|
||||
|
||||
ConstArg {
|
||||
hir_id: self.lower_node_id(expr.id),
|
||||
kind: hir::ConstArgKind::Literal(literal.node),
|
||||
span,
|
||||
}
|
||||
}
|
||||
_ => overly_complex_const(self),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -518,6 +518,7 @@ 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),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||
|
|
|
|||
|
|
@ -1104,6 +1104,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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ pub mod generics;
|
|||
use std::assert_matches::assert_matches;
|
||||
use std::slice;
|
||||
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{
|
||||
|
|
@ -2391,6 +2392,13 @@ 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) if let FeedConstTy::WithTy(anon_const_type) = feed => {
|
||||
self.lower_const_arg_literal(&kind, anon_const_type, const_arg.span)
|
||||
}
|
||||
hir::ConstArgKind::Literal(..) => {
|
||||
let e = self.dcx().span_err(const_arg.span, "literal of unknown type");
|
||||
ty::Const::new_error(tcx, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2773,6 +2781,13 @@ 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> {
|
||||
let tcx = self.tcx();
|
||||
let input = LitToConstInput { lit: *kind, ty, neg: false };
|
||||
tcx.at(span).lit_to_const(input)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn try_lower_anon_const_lit(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use rustc_hir::{
|
|||
GenericParam, GenericParamKind, HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind,
|
||||
PreciseCapturingArg, RangeEnd, Term, TyPatKind,
|
||||
};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::source_map::{SourceMap, Spanned};
|
||||
use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym};
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
|
|
@ -1157,6 +1157,10 @@ impl<'a> State<'a> {
|
|||
ConstArgKind::Anon(anon) => self.print_anon_const(anon),
|
||||
ConstArgKind::Error(_) => self.word("/*ERROR*/"),
|
||||
ConstArgKind::Infer(..) => self.word("_"),
|
||||
ConstArgKind::Literal(node) => {
|
||||
let span = const_arg.span;
|
||||
self.print_literal(&Spanned { span, node: *node })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1444,6 +1444,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
| hir::ConstArgKind::TupleCall(..)
|
||||
| hir::ConstArgKind::Tup(..)
|
||||
| hir::ConstArgKind::Path(..)
|
||||
| hir::ConstArgKind::Literal(..)
|
||||
| hir::ConstArgKind::Infer(..) => true,
|
||||
hir::ConstArgKind::Anon(..) => false,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -332,6 +332,9 @@ 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(..) => {
|
||||
ConstantKind::Path { path: "/* LITERAL */".to_string().into() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1814,7 +1817,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
|||
hir::ConstArgKind::Struct(..)
|
||||
| hir::ConstArgKind::Path(..)
|
||||
| hir::ConstArgKind::TupleCall(..)
|
||||
| hir::ConstArgKind::Tup(..) => {
|
||||
| hir::ConstArgKind::Tup(..)
|
||||
| hir::ConstArgKind::Literal(..) => {
|
||||
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No);
|
||||
print_const(cx, ct)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"),
|
||||
ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"),
|
||||
ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"),
|
||||
ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1140,7 +1140,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx
|
|||
ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value),
|
||||
ConstItemRhs::TypeConst(const_arg) => match const_arg.kind {
|
||||
ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value),
|
||||
ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => {
|
||||
ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) | ConstArgKind::Literal(..) => {
|
||||
None
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -689,6 +689,9 @@ 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
|
||||
},
|
||||
// Use explicit match for now since ConstArg is undergoing flux.
|
||||
(
|
||||
ConstArgKind::Path(..)
|
||||
|
|
@ -697,6 +700,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
| ConstArgKind::Tup(..)
|
||||
| ConstArgKind::Infer(..)
|
||||
| ConstArgKind::Struct(..)
|
||||
| ConstArgKind::Literal(..)
|
||||
| ConstArgKind::Error(..),
|
||||
_,
|
||||
) => false,
|
||||
|
|
@ -1577,6 +1581,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
}
|
||||
},
|
||||
ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {},
|
||||
ConstArgKind::Literal(lit) => lit.hash(&mut self.s)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
// We allow for literals to implicitly be anon consts still regardless
|
||||
// of whether a const block is placed around them or not
|
||||
//
|
||||
// However, we don't allow so for const arguments in field init positions.
|
||||
// This is just harder to implement so we did not do so.
|
||||
//@ check-pass
|
||||
|
||||
#![feature(min_generic_const_args, adt_const_params)]
|
||||
#![expect(incomplete_features)]
|
||||
|
|
@ -27,7 +23,7 @@ fn struct_expr() {
|
|||
fn takes_n<const N: ADT>() {}
|
||||
|
||||
takes_n::<{ ADT { field: 1 } }>();
|
||||
//~^ ERROR: complex const arguments must be placed inside of a `const` block
|
||||
|
||||
takes_n::<{ ADT { field: const { 1 } } }>();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/explicit_anon_consts_literals_hack.rs:29:30
|
||||
|
|
||||
LL | takes_n::<{ ADT { field: 1 } }>();
|
||||
| ^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue