Rollup merge of #91907 - lcnr:const-arg-infer, r=BoxyUwU
Allow `_` as the length of array types and repeat expressions r? `@BoxyUwU` cc `@varkor`
This commit is contained in:
commit
ac7a867715
28 changed files with 268 additions and 85 deletions
|
@ -104,7 +104,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
|
||||
GenericParamDefKind::Const { .. },
|
||||
) if tcx.type_of(param.def_id) == tcx.types.usize => {
|
||||
let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id));
|
||||
let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id()));
|
||||
if let Ok(snippet) = snippet {
|
||||
err.span_suggestion(
|
||||
arg.span(),
|
||||
|
|
|
@ -2363,8 +2363,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
self.normalize_ty(span, tcx.at(span).type_of(def_id).subst(tcx, substs))
|
||||
}
|
||||
hir::TyKind::Array(ref ty, ref length) => {
|
||||
let length_def_id = tcx.hir().local_def_id(length.hir_id);
|
||||
let length = ty::Const::from_anon_const(tcx, length_def_id);
|
||||
let length = match length {
|
||||
&hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span),
|
||||
hir::ArrayLen::Body(constant) => {
|
||||
let length_def_id = tcx.hir().local_def_id(constant.hir_id);
|
||||
ty::Const::from_anon_const(tcx, length_def_id)
|
||||
}
|
||||
};
|
||||
|
||||
let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length));
|
||||
self.normalize_ty(ast_ty.span, array_ty)
|
||||
}
|
||||
|
|
|
@ -1238,12 +1238,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
fn check_expr_repeat(
|
||||
&self,
|
||||
element: &'tcx hir::Expr<'tcx>,
|
||||
count: &'tcx hir::AnonConst,
|
||||
count: &'tcx hir::ArrayLen,
|
||||
expected: Expectation<'tcx>,
|
||||
_expr: &'tcx hir::Expr<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let count = self.to_const(count);
|
||||
let count = self.array_length_to_const(count);
|
||||
|
||||
let uty = match expected {
|
||||
ExpectHasType(uty) => match *uty.kind() {
|
||||
|
|
|
@ -498,6 +498,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ty
|
||||
}
|
||||
|
||||
pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> &'tcx ty::Const<'tcx> {
|
||||
match length {
|
||||
&hir::ArrayLen::Infer(_, span) => self.ct_infer(self.tcx.types.usize, None, span),
|
||||
hir::ArrayLen::Body(anon_const) => self.to_const(anon_const),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
|
||||
let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
|
||||
let c = ty::Const::from_anon_const(self.tcx, const_def_id);
|
||||
|
|
|
@ -182,7 +182,7 @@ crate fn placeholder_type_error<'tcx>(
|
|||
sugg.push((span, format!(", {}", type_name)));
|
||||
}
|
||||
|
||||
let mut err = bad_placeholder_type(tcx, placeholder_types, kind);
|
||||
let mut err = bad_placeholder(tcx, "type", placeholder_types, kind);
|
||||
|
||||
// Suggest, but only if it is not a function in const or static
|
||||
if suggest {
|
||||
|
@ -314,8 +314,9 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// Utility types and common code for the above passes.
|
||||
|
||||
fn bad_placeholder_type<'tcx>(
|
||||
fn bad_placeholder<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
placeholder_kind: &'static str,
|
||||
mut spans: Vec<Span>,
|
||||
kind: &'static str,
|
||||
) -> rustc_errors::DiagnosticBuilder<'tcx> {
|
||||
|
@ -326,7 +327,8 @@ fn bad_placeholder_type<'tcx>(
|
|||
tcx.sess,
|
||||
spans.clone(),
|
||||
E0121,
|
||||
"the type placeholder `_` is not allowed within types on item signatures for {}",
|
||||
"the {} placeholder `_` is not allowed within types on item signatures for {}",
|
||||
placeholder_kind,
|
||||
kind
|
||||
);
|
||||
for span in spans {
|
||||
|
@ -393,7 +395,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||
_: Option<&ty::GenericParamDef>,
|
||||
span: Span,
|
||||
) -> &'tcx Const<'tcx> {
|
||||
bad_placeholder_type(self.tcx(), vec![span], "generic").emit();
|
||||
bad_placeholder(self.tcx(), "const", vec![span], "generic").emit();
|
||||
// Typeck doesn't expect erased regions to be returned from `type_of`.
|
||||
let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r {
|
||||
ty::ReErased => self.tcx.lifetimes.re_static,
|
||||
|
@ -1482,7 +1484,11 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
|||
// `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
|
||||
// as they shouldn't be able to cause query cycle errors.
|
||||
Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
||||
| Node::Variant(Variant { disr_expr: Some(ref constant), .. })
|
||||
if constant.hir_id() == hir_id =>
|
||||
{
|
||||
Some(parent_def_id.to_def_id())
|
||||
}
|
||||
Node::Variant(Variant { disr_expr: Some(ref constant), .. })
|
||||
if constant.hir_id == hir_id =>
|
||||
{
|
||||
Some(parent_def_id.to_def_id())
|
||||
|
@ -1788,7 +1794,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
|||
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
visitor.visit_ty(ty);
|
||||
let mut diag = bad_placeholder_type(tcx, visitor.0, "return type");
|
||||
let mut diag = bad_placeholder(tcx, "type", visitor.0, "return type");
|
||||
let ret_ty = fn_sig.skip_binder().output();
|
||||
if !ret_ty.references_error() {
|
||||
if !ret_ty.is_closure() {
|
||||
|
|
|
@ -13,7 +13,7 @@ use rustc_span::symbol::Ident;
|
|||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use super::ItemCtxt;
|
||||
use super::{bad_placeholder_type, is_suggestable_infer_ty};
|
||||
use super::{bad_placeholder, is_suggestable_infer_ty};
|
||||
|
||||
/// Computes the relevant generic parameter for a potential generic const argument.
|
||||
///
|
||||
|
@ -490,7 +490,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
match parent_node {
|
||||
Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
|
||||
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
||||
if constant.hir_id == hir_id =>
|
||||
if constant.hir_id() == hir_id =>
|
||||
{
|
||||
tcx.types.usize
|
||||
}
|
||||
|
@ -788,7 +788,7 @@ fn infer_placeholder_type<'a>(
|
|||
err.emit();
|
||||
}
|
||||
None => {
|
||||
let mut diag = bad_placeholder_type(tcx, vec![span], kind);
|
||||
let mut diag = bad_placeholder(tcx, "type", vec![span], kind);
|
||||
|
||||
if !ty.references_error() {
|
||||
let mut mk_nameable = MakeNameable::new(tcx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue