Skip to content

Commit db1253f

Browse files
authored
Rollup merge of #92582 - lcnr:generic-arg-infer, r=BoxyUwU
improve `_` constants in item signature handling removing the "type" from the error messages does slightly worsen the error messages for types, but figuring out whether the placeholder is for a type or a constant and correctly dealing with that seemed fairly difficult to me so I took the easy way out ✨ Imo the error message is still clear enough. r? `@BoxyUwU` cc `@estebank`
2 parents 413f490 + 217458b commit db1253f

40 files changed

+424
-256
lines changed

compiler/rustc_middle/src/ty/context.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -1210,11 +1210,25 @@ impl<'tcx> TyCtxt<'tcx> {
12101210
self.mk_ty(Error(DelaySpanBugEmitted(())))
12111211
}
12121212

1213-
/// Like `err` but for constants.
1213+
/// Like [TyCtxt::ty_error] but for constants.
12141214
#[track_caller]
12151215
pub fn const_error(self, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
1216-
self.sess
1217-
.delay_span_bug(DUMMY_SP, "ty::ConstKind::Error constructed but no error reported.");
1216+
self.const_error_with_message(
1217+
ty,
1218+
DUMMY_SP,
1219+
"ty::ConstKind::Error constructed but no error reported",
1220+
)
1221+
}
1222+
1223+
/// Like [TyCtxt::ty_error_with_message] but for constants.
1224+
#[track_caller]
1225+
pub fn const_error_with_message<S: Into<MultiSpan>>(
1226+
self,
1227+
ty: Ty<'tcx>,
1228+
span: S,
1229+
msg: &str,
1230+
) -> &'tcx Const<'tcx> {
1231+
self.sess.delay_span_bug(span, msg);
12181232
self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
12191233
}
12201234

compiler/rustc_privacy/src/lib.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -1148,19 +1148,11 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
11481148
if self.visit(ty).is_break() {
11491149
return;
11501150
}
1151+
} else {
1152+
// We don't do anything for const infers here.
11511153
}
11521154
} else {
1153-
let local_id = self.tcx.hir().local_def_id(inf.hir_id);
1154-
if let Some(did) = self.tcx.opt_const_param_of(local_id) {
1155-
if self.visit_def_id(did, "inferred", &"").is_break() {
1156-
return;
1157-
}
1158-
}
1159-
1160-
// FIXME see above note for same issue.
1161-
if self.visit(rustc_typeck::hir_ty_to_ty(self.tcx, &inf.to_ty())).is_break() {
1162-
return;
1163-
}
1155+
bug!("visit_infer without typeck_results");
11641156
}
11651157
intravisit::walk_inf(self, inf);
11661158
}

compiler/rustc_typeck/src/astconv/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod errors;
66
mod generics;
77

88
use crate::bounds::Bounds;
9-
use crate::collect::PlaceholderHirTyCollector;
9+
use crate::collect::HirPlaceholderCollector;
1010
use crate::errors::{
1111
AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits,
1212
TypeofReservedKeywordUsed, ValueOfAssociatedStructAlreadySpecified,
@@ -2504,7 +2504,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25042504
debug!(?bound_vars);
25052505

25062506
// We proactively collect all the inferred type params to emit a single error per fn def.
2507-
let mut visitor = PlaceholderHirTyCollector::default();
2507+
let mut visitor = HirPlaceholderCollector::default();
25082508
for ty in decl.inputs {
25092509
visitor.visit_ty(ty);
25102510
}

compiler/rustc_typeck/src/collect.rs

+26-20
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ pub struct ItemCtxt<'tcx> {
112112
///////////////////////////////////////////////////////////////////////////
113113

114114
#[derive(Default)]
115-
crate struct PlaceholderHirTyCollector(crate Vec<Span>);
115+
crate struct HirPlaceholderCollector(crate Vec<Span>);
116116

117-
impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
117+
impl<'v> Visitor<'v> for HirPlaceholderCollector {
118118
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
119119
if let hir::TyKind::Infer = t.kind {
120120
self.0.push(t.span);
@@ -131,6 +131,12 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
131131
_ => {}
132132
}
133133
}
134+
fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
135+
if let &hir::ArrayLen::Infer(_, span) = length {
136+
self.0.push(span);
137+
}
138+
intravisit::walk_array_len(self, length)
139+
}
134140
}
135141

136142
struct CollectItemTypesVisitor<'tcx> {
@@ -175,7 +181,7 @@ crate fn placeholder_type_error<'tcx>(
175181
sugg.push((span, format!(", {}", type_name)));
176182
}
177183

178-
let mut err = bad_placeholder(tcx, "type", placeholder_types, kind);
184+
let mut err = bad_placeholder(tcx, placeholder_types, kind);
179185

180186
// Suggest, but only if it is not a function in const or static
181187
if suggest {
@@ -233,7 +239,7 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
233239
_ => return,
234240
};
235241

236-
let mut visitor = PlaceholderHirTyCollector::default();
242+
let mut visitor = HirPlaceholderCollector::default();
237243
visitor.visit_item(item);
238244

239245
placeholder_type_error(
@@ -311,7 +317,6 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
311317

312318
fn bad_placeholder<'tcx>(
313319
tcx: TyCtxt<'tcx>,
314-
placeholder_kind: &'static str,
315320
mut spans: Vec<Span>,
316321
kind: &'static str,
317322
) -> rustc_errors::DiagnosticBuilder<'tcx> {
@@ -322,8 +327,7 @@ fn bad_placeholder<'tcx>(
322327
tcx.sess,
323328
spans.clone(),
324329
E0121,
325-
"the {} placeholder `_` is not allowed within types on item signatures for {}",
326-
placeholder_kind,
330+
"the placeholder `_` is not allowed within types on item signatures for {}",
327331
kind
328332
);
329333
for span in spans {
@@ -381,7 +385,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
381385
}
382386

383387
fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
384-
self.tcx().ty_error_with_message(span, "bad_placeholder_type")
388+
self.tcx().ty_error_with_message(span, "bad placeholder type")
385389
}
386390

387391
fn ct_infer(
@@ -390,13 +394,11 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
390394
_: Option<&ty::GenericParamDef>,
391395
span: Span,
392396
) -> &'tcx Const<'tcx> {
393-
bad_placeholder(self.tcx(), "const", vec![span], "generic").emit();
394-
// Typeck doesn't expect erased regions to be returned from `type_of`.
395397
let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r {
396398
ty::ReErased => self.tcx.lifetimes.re_static,
397399
_ => r,
398400
});
399-
self.tcx().const_error(ty)
401+
self.tcx().const_error_with_message(ty, span, "bad placeholder constant")
400402
}
401403

402404
fn projected_ty_from_poly_trait_ref(
@@ -743,7 +745,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
743745
match item.kind {
744746
hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id),
745747
hir::ForeignItemKind::Static(..) => {
746-
let mut visitor = PlaceholderHirTyCollector::default();
748+
let mut visitor = HirPlaceholderCollector::default();
747749
visitor.visit_foreign_item(item);
748750
placeholder_type_error(
749751
tcx,
@@ -826,7 +828,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
826828
hir::ItemKind::Const(ty, ..) | hir::ItemKind::Static(ty, ..) => {
827829
// (#75889): Account for `const C: dyn Fn() -> _ = "";`
828830
if let hir::TyKind::TraitObject(..) = ty.kind {
829-
let mut visitor = PlaceholderHirTyCollector::default();
831+
let mut visitor = HirPlaceholderCollector::default();
830832
visitor.visit_item(it);
831833
placeholder_type_error(
832834
tcx,
@@ -862,7 +864,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
862864
hir::TraitItemKind::Const(..) => {
863865
tcx.ensure().type_of(trait_item_id.def_id);
864866
// Account for `const C: _;`.
865-
let mut visitor = PlaceholderHirTyCollector::default();
867+
let mut visitor = HirPlaceholderCollector::default();
866868
visitor.visit_trait_item(trait_item);
867869
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "constant");
868870
}
@@ -871,7 +873,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
871873
tcx.ensure().item_bounds(trait_item_id.def_id);
872874
tcx.ensure().type_of(trait_item_id.def_id);
873875
// Account for `type T = _;`.
874-
let mut visitor = PlaceholderHirTyCollector::default();
876+
let mut visitor = HirPlaceholderCollector::default();
875877
visitor.visit_trait_item(trait_item);
876878
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
877879
}
@@ -880,7 +882,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
880882
tcx.ensure().item_bounds(trait_item_id.def_id);
881883
// #74612: Visit and try to find bad placeholders
882884
// even if there is no concrete type.
883-
let mut visitor = PlaceholderHirTyCollector::default();
885+
let mut visitor = HirPlaceholderCollector::default();
884886
visitor.visit_trait_item(trait_item);
885887

886888
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
@@ -902,7 +904,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
902904
}
903905
hir::ImplItemKind::TyAlias(_) => {
904906
// Account for `type T = _;`
905-
let mut visitor = PlaceholderHirTyCollector::default();
907+
let mut visitor = HirPlaceholderCollector::default();
906908
visitor.visit_impl_item(impl_item);
907909

908910
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
@@ -1822,10 +1824,14 @@ fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
18221824
/// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
18231825
/// use inference to provide suggestions for the appropriate type if possible.
18241826
fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
1827+
debug!(?ty);
18251828
use hir::TyKind::*;
18261829
match &ty.kind {
18271830
Infer => true,
1828-
Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty),
1831+
Slice(ty) => is_suggestable_infer_ty(ty),
1832+
Array(ty, length) => {
1833+
is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _))
1834+
}
18291835
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
18301836
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
18311837
OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
@@ -1877,9 +1883,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
18771883
});
18781884
let fn_sig = ty::Binder::dummy(fn_sig);
18791885

1880-
let mut visitor = PlaceholderHirTyCollector::default();
1886+
let mut visitor = HirPlaceholderCollector::default();
18811887
visitor.visit_ty(ty);
1882-
let mut diag = bad_placeholder(tcx, "type", visitor.0, "return type");
1888+
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
18831889
let ret_ty = fn_sig.skip_binder().output();
18841890
if !ret_ty.references_error() {
18851891
if !ret_ty.is_closure() {

compiler/rustc_typeck/src/collect/type_of.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ use super::{bad_placeholder, is_suggestable_infer_ty};
2020
/// This should be called using the query `tcx.opt_const_param_of`.
2121
#[instrument(level = "debug", skip(tcx))]
2222
pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
23-
// FIXME(generic_arg_infer): allow for returning DefIds of inference of
24-
// GenericArg::Infer below. This may require a change where GenericArg::Infer has some flag
25-
// for const or type.
2623
use hir::*;
2724
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
2825

@@ -753,7 +750,7 @@ fn infer_placeholder_type<'a>(
753750
err.emit();
754751
}
755752
None => {
756-
let mut diag = bad_placeholder(tcx, "type", vec![span], kind);
753+
let mut diag = bad_placeholder(tcx, vec![span], kind);
757754

758755
if !ty.references_error() {
759756
let mut mk_nameable = MakeNameable::new(tcx);

src/test/ui/const-generics/generic_arg_infer/array-in-sig.rs

-12
This file was deleted.

src/test/ui/const-generics/generic_arg_infer/array-in-sig.stderr

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#![crate_type = "rlib"]
2+
#![feature(generic_arg_infer)]
3+
4+
struct Foo<const N: usize>;
5+
struct Bar<T, const N: usize>(T);
6+
7+
fn arr_fn() -> [u8; _] {
8+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
9+
[0; 3]
10+
}
11+
12+
fn ty_fn() -> Bar<i32, _> {
13+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
14+
Bar::<i32, 3>(0)
15+
}
16+
17+
fn ty_fn_mixed() -> Bar<_, _> {
18+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
19+
Bar::<i32, 3>(0)
20+
}
21+
22+
const ARR_CT: [u8; _] = [0; 3];
23+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
24+
static ARR_STATIC: [u8; _] = [0; 3];
25+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
26+
const TY_CT: Bar<i32, _> = Bar::<i32, 3>(0);
27+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
28+
static TY_STATIC: Bar<i32, _> = Bar::<i32, 3>(0);
29+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
30+
const TY_CT_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
31+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
32+
static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
33+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
34+
trait ArrAssocConst {
35+
const ARR: [u8; _];
36+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
37+
}
38+
trait TyAssocConst {
39+
const ARR: Bar<i32, _>;
40+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
41+
}
42+
trait TyAssocConstMixed {
43+
const ARR: Bar<_, _>;
44+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
45+
}
46+
47+
trait AssocTy {
48+
type Assoc;
49+
}
50+
impl AssocTy for i8 {
51+
type Assoc = [u8; _];
52+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
53+
}
54+
impl AssocTy for i16 {
55+
type Assoc = Bar<i32, _>;
56+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
57+
}
58+
impl AssocTy for i32 {
59+
type Assoc = Bar<_, _>;
60+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
61+
}

0 commit comments

Comments
 (0)