Skip to content

Commit b331e0d

Browse files
authored
Rollup merge of rust-lang#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 89ea551 + a3c55ac commit b331e0d

40 files changed

+424
-256
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,11 +1209,25 @@ impl<'tcx> TyCtxt<'tcx> {
12091209
self.mk_ty(Error(DelaySpanBugEmitted(())))
12101210
}
12111211

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

compiler/rustc_privacy/src/lib.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,19 +1152,11 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
11521152
if self.visit(ty).is_break() {
11531153
return;
11541154
}
1155+
} else {
1156+
// We don't do anything for const infers here.
11551157
}
11561158
} else {
1157-
let local_id = self.tcx.hir().local_def_id(inf.hir_id);
1158-
if let Some(did) = self.tcx.opt_const_param_of(local_id) {
1159-
if self.visit_def_id(did, "inferred", &"").is_break() {
1160-
return;
1161-
}
1162-
}
1163-
1164-
// FIXME see above note for same issue.
1165-
if self.visit(rustc_typeck::hir_ty_to_ty(self.tcx, &inf.to_ty())).is_break() {
1166-
return;
1167-
}
1159+
bug!("visit_infer without typeck_results");
11681160
}
11691161
intravisit::walk_inf(self, inf);
11701162
}

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 2 additions & 2 deletions
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,
@@ -2469,7 +2469,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24692469
debug!(?bound_vars);
24702470

24712471
// We proactively collect all the inferred type params to emit a single error per fn def.
2472-
let mut visitor = PlaceholderHirTyCollector::default();
2472+
let mut visitor = HirPlaceholderCollector::default();
24732473
for ty in decl.inputs {
24742474
visitor.visit_ty(ty);
24752475
}

compiler/rustc_typeck/src/collect.rs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ pub struct ItemCtxt<'tcx> {
113113
///////////////////////////////////////////////////////////////////////////
114114

115115
#[derive(Default)]
116-
crate struct PlaceholderHirTyCollector(crate Vec<Span>);
116+
crate struct HirPlaceholderCollector(crate Vec<Span>);
117117

118-
impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
118+
impl<'v> Visitor<'v> for HirPlaceholderCollector {
119119
type Map = intravisit::ErasedMap<'v>;
120120

121121
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
@@ -137,6 +137,12 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
137137
_ => {}
138138
}
139139
}
140+
fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
141+
if let &hir::ArrayLen::Infer(_, span) = length {
142+
self.0.push(span);
143+
}
144+
intravisit::walk_array_len(self, length)
145+
}
140146
}
141147

142148
struct CollectItemTypesVisitor<'tcx> {
@@ -181,7 +187,7 @@ crate fn placeholder_type_error<'tcx>(
181187
sugg.push((span, format!(", {}", type_name)));
182188
}
183189

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

186192
// Suggest, but only if it is not a function in const or static
187193
if suggest {
@@ -239,7 +245,7 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
239245
_ => return,
240246
};
241247

242-
let mut visitor = PlaceholderHirTyCollector::default();
248+
let mut visitor = HirPlaceholderCollector::default();
243249
visitor.visit_item(item);
244250

245251
placeholder_type_error(
@@ -317,7 +323,6 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
317323

318324
fn bad_placeholder<'tcx>(
319325
tcx: TyCtxt<'tcx>,
320-
placeholder_kind: &'static str,
321326
mut spans: Vec<Span>,
322327
kind: &'static str,
323328
) -> rustc_errors::DiagnosticBuilder<'tcx> {
@@ -328,8 +333,7 @@ fn bad_placeholder<'tcx>(
328333
tcx.sess,
329334
spans.clone(),
330335
E0121,
331-
"the {} placeholder `_` is not allowed within types on item signatures for {}",
332-
placeholder_kind,
336+
"the placeholder `_` is not allowed within types on item signatures for {}",
333337
kind
334338
);
335339
for span in spans {
@@ -387,7 +391,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
387391
}
388392

389393
fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
390-
self.tcx().ty_error_with_message(span, "bad_placeholder_type")
394+
self.tcx().ty_error_with_message(span, "bad placeholder type")
391395
}
392396

393397
fn ct_infer(
@@ -396,13 +400,11 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
396400
_: Option<&ty::GenericParamDef>,
397401
span: Span,
398402
) -> &'tcx Const<'tcx> {
399-
bad_placeholder(self.tcx(), "const", vec![span], "generic").emit();
400-
// Typeck doesn't expect erased regions to be returned from `type_of`.
401403
let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r {
402404
ty::ReErased => self.tcx.lifetimes.re_static,
403405
_ => r,
404406
});
405-
self.tcx().const_error(ty)
407+
self.tcx().const_error_with_message(ty, span, "bad placeholder constant")
406408
}
407409

408410
fn projected_ty_from_poly_trait_ref(
@@ -746,7 +748,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
746748
match item.kind {
747749
hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id),
748750
hir::ForeignItemKind::Static(..) => {
749-
let mut visitor = PlaceholderHirTyCollector::default();
751+
let mut visitor = HirPlaceholderCollector::default();
750752
visitor.visit_foreign_item(item);
751753
placeholder_type_error(
752754
tcx,
@@ -829,7 +831,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
829831
hir::ItemKind::Const(ty, ..) | hir::ItemKind::Static(ty, ..) => {
830832
// (#75889): Account for `const C: dyn Fn() -> _ = "";`
831833
if let hir::TyKind::TraitObject(..) = ty.kind {
832-
let mut visitor = PlaceholderHirTyCollector::default();
834+
let mut visitor = HirPlaceholderCollector::default();
833835
visitor.visit_item(it);
834836
placeholder_type_error(
835837
tcx,
@@ -865,7 +867,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
865867
hir::TraitItemKind::Const(..) => {
866868
tcx.ensure().type_of(trait_item_id.def_id);
867869
// Account for `const C: _;`.
868-
let mut visitor = PlaceholderHirTyCollector::default();
870+
let mut visitor = HirPlaceholderCollector::default();
869871
visitor.visit_trait_item(trait_item);
870872
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "constant");
871873
}
@@ -874,7 +876,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
874876
tcx.ensure().item_bounds(trait_item_id.def_id);
875877
tcx.ensure().type_of(trait_item_id.def_id);
876878
// Account for `type T = _;`.
877-
let mut visitor = PlaceholderHirTyCollector::default();
879+
let mut visitor = HirPlaceholderCollector::default();
878880
visitor.visit_trait_item(trait_item);
879881
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
880882
}
@@ -883,7 +885,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
883885
tcx.ensure().item_bounds(trait_item_id.def_id);
884886
// #74612: Visit and try to find bad placeholders
885887
// even if there is no concrete type.
886-
let mut visitor = PlaceholderHirTyCollector::default();
888+
let mut visitor = HirPlaceholderCollector::default();
887889
visitor.visit_trait_item(trait_item);
888890

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

911913
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
@@ -1738,10 +1740,14 @@ fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
17381740
/// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
17391741
/// use inference to provide suggestions for the appropriate type if possible.
17401742
fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
1743+
debug!(?ty);
17411744
use hir::TyKind::*;
17421745
match &ty.kind {
17431746
Infer => true,
1744-
Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty),
1747+
Slice(ty) => is_suggestable_infer_ty(ty),
1748+
Array(ty, length) => {
1749+
is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _))
1750+
}
17451751
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
17461752
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
17471753
OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
@@ -1793,9 +1799,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
17931799
});
17941800
let fn_sig = ty::Binder::dummy(fn_sig);
17951801

1796-
let mut visitor = PlaceholderHirTyCollector::default();
1802+
let mut visitor = HirPlaceholderCollector::default();
17971803
visitor.visit_ty(ty);
1798-
let mut diag = bad_placeholder(tcx, "type", visitor.0, "return type");
1804+
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
17991805
let ret_ty = fn_sig.skip_binder().output();
18001806
if !ret_ty.references_error() {
18011807
if !ret_ty.is_closure() {

compiler/rustc_typeck/src/collect/type_of.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ use super::{bad_placeholder, is_suggestable_infer_ty};
1919
///
2020
/// This should be called using the query `tcx.opt_const_param_of`.
2121
pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
22-
// FIXME(generic_arg_infer): allow for returning DefIds of inference of
23-
// GenericArg::Infer below. This may require a change where GenericArg::Infer has some flag
24-
// for const or type.
2522
use hir::*;
2623
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
2724

@@ -781,7 +778,7 @@ fn infer_placeholder_type<'a>(
781778
err.emit();
782779
}
783780
None => {
784-
let mut diag = bad_placeholder(tcx, "type", vec![span], kind);
781+
let mut diag = bad_placeholder(tcx, vec![span], kind);
785782

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

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

Lines changed: 0 additions & 12 deletions
This file was deleted.

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

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 61 additions & 0 deletions
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)