Skip to content

Commit 6c5c5ce

Browse files
Suppress type param suggestion if encountering invalid const infer
1 parent 2a1393d commit 6c5c5ce

File tree

4 files changed

+53
-33
lines changed

4 files changed

+53
-33
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -131,19 +131,25 @@ pub struct ItemCtxt<'tcx> {
131131
///////////////////////////////////////////////////////////////////////////
132132

133133
#[derive(Default)]
134-
pub(crate) struct HirPlaceholderCollector(pub(crate) Vec<Span>);
134+
pub(crate) struct HirPlaceholderCollector {
135+
pub spans: Vec<Span>,
136+
// If any of the spans points to a const infer var, then suppress any messages
137+
// that may try to turn that const infer into a type parameter.
138+
pub may_contain_const_infer: bool,
139+
}
135140

136141
impl<'v> Visitor<'v> for HirPlaceholderCollector {
137142
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
138143
if let hir::TyKind::Infer = t.kind {
139-
self.0.push(t.span);
144+
self.spans.push(t.span);
140145
}
141146
intravisit::walk_ty(self, t)
142147
}
143148
fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) {
144149
match generic_arg {
145150
hir::GenericArg::Infer(inf) => {
146-
self.0.push(inf.span);
151+
self.spans.push(inf.span);
152+
self.may_contain_const_infer = true;
147153
intravisit::walk_inf(self, inf);
148154
}
149155
hir::GenericArg::Type(t) => self.visit_ty(t),
@@ -152,7 +158,8 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
152158
}
153159
fn visit_const_arg(&mut self, const_arg: &'v hir::ConstArg<'v>) {
154160
if let hir::ConstArgKind::Infer(span) = const_arg.kind {
155-
self.0.push(span);
161+
self.may_contain_const_infer = true;
162+
self.spans.push(span);
156163
}
157164
intravisit::walk_const_arg(self, const_arg)
158165
}
@@ -277,8 +284,8 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
277284
placeholder_type_error(
278285
icx.lowerer(),
279286
Some(generics),
280-
visitor.0,
281-
suggest,
287+
visitor.spans,
288+
suggest && !visitor.may_contain_const_infer,
282289
None,
283290
item.kind.descr(),
284291
);
@@ -607,16 +614,16 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
607614
hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
608615
};
609616

610-
if !(visitor.0.is_empty() && infer_replacements.is_empty()) {
617+
if !(visitor.spans.is_empty() && infer_replacements.is_empty()) {
611618
// We check for the presence of
612619
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
613620

614621
let mut diag = crate::collect::placeholder_type_error_diag(
615622
self,
616623
generics,
617-
visitor.0,
624+
visitor.spans,
618625
infer_replacements.iter().map(|(s, _)| *s).collect(),
619-
true,
626+
!visitor.may_contain_const_infer,
620627
hir_ty,
621628
"function",
622629
);
@@ -712,7 +719,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
712719
placeholder_type_error(
713720
icx.lowerer(),
714721
None,
715-
visitor.0,
722+
visitor.spans,
716723
false,
717724
None,
718725
"static variable",
@@ -780,7 +787,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
780787
placeholder_type_error(
781788
icx.lowerer(),
782789
None,
783-
visitor.0,
790+
visitor.spans,
784791
false,
785792
None,
786793
it.kind.descr(),
@@ -822,7 +829,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
822829
placeholder_type_error(
823830
icx.lowerer(),
824831
None,
825-
visitor.0,
832+
visitor.spans,
826833
false,
827834
None,
828835
"associated constant",
@@ -837,7 +844,14 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
837844
// Account for `type T = _;`.
838845
let mut visitor = HirPlaceholderCollector::default();
839846
visitor.visit_trait_item(trait_item);
840-
placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type");
847+
placeholder_type_error(
848+
icx.lowerer(),
849+
None,
850+
visitor.spans,
851+
false,
852+
None,
853+
"associated type",
854+
);
841855
}
842856

843857
hir::TraitItemKind::Type(_, None) => {
@@ -848,7 +862,14 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
848862
let mut visitor = HirPlaceholderCollector::default();
849863
visitor.visit_trait_item(trait_item);
850864

851-
placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type");
865+
placeholder_type_error(
866+
icx.lowerer(),
867+
None,
868+
visitor.spans,
869+
false,
870+
None,
871+
"associated type",
872+
);
852873
}
853874
};
854875

@@ -872,7 +893,14 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
872893
let mut visitor = HirPlaceholderCollector::default();
873894
visitor.visit_impl_item(impl_item);
874895

875-
placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type");
896+
placeholder_type_error(
897+
icx.lowerer(),
898+
None,
899+
visitor.spans,
900+
false,
901+
None,
902+
"associated type",
903+
);
876904
}
877905
hir::ImplItemKind::Const(ty, _) => {
878906
// Account for `const T: _ = ..;`
@@ -882,7 +910,7 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
882910
placeholder_type_error(
883911
icx.lowerer(),
884912
None,
885-
visitor.0,
913+
visitor.spans,
886914
false,
887915
None,
888916
"associated constant",
@@ -1422,7 +1450,7 @@ fn recover_infer_ret_ty<'tcx>(
14221450
let mut visitor = HirPlaceholderCollector::default();
14231451
visitor.visit_ty(infer_ret_ty);
14241452

1425-
let mut diag = bad_placeholder(icx.lowerer(), visitor.0, "return type");
1453+
let mut diag = bad_placeholder(icx.lowerer(), visitor.spans, "return type");
14261454
let ret_ty = fn_sig.output();
14271455

14281456
// Don't leak types into signatures unless they're nameable!

compiler/rustc_hir_analysis/src/collect/type_of.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -453,16 +453,17 @@ fn infer_placeholder_type<'tcx>(
453453
visitor.visit_ty(ty);
454454
}
455455
// If we have just one span, let's try to steal a const `_` feature error.
456-
let try_steal_span = if !tcx.features().generic_arg_infer() && visitor.0.len() == 1 {
457-
visitor.0.first().copied()
456+
let try_steal_span = if !tcx.features().generic_arg_infer() && visitor.spans.len() == 1
457+
{
458+
visitor.spans.first().copied()
458459
} else {
459460
None
460461
};
461-
// If we didn't find any infer tys, then just fallback to `span``.
462-
if visitor.0.is_empty() {
463-
visitor.0.push(span);
462+
// If we didn't find any infer tys, then just fallback to `span`.
463+
if visitor.spans.is_empty() {
464+
visitor.spans.push(span);
464465
}
465-
let mut diag = bad_placeholder(cx, visitor.0, kind);
466+
let mut diag = bad_placeholder(cx, visitor.spans, kind);
466467

467468
if !ty.references_error() {
468469
if let Some(ty) = ty.make_suggestable(tcx, false, None) {

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,11 +1771,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17711771
let parent_node = self.tcx.hir().parent_iter(expr.hir_id).find(|(_, node)| {
17721772
!matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::AddrOf(..), .. }))
17731773
});
1774-
let Some((
1775-
_,
1776-
hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. })
1777-
)) = parent_node
1778-
else {
1774+
let Some((_, hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }))) = parent_node else {
17791775
return;
17801776
};
17811777
if let hir::TyKind::Array(_, ct) = ty.peel_refs().kind {

tests/ui/async-await/issues/issue-95307.stderr

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
33
|
44
LL | async fn new() -> [u8; _];
55
| ^ not allowed in type signatures
6-
|
7-
help: use type parameters instead
8-
|
9-
LL | async fn new<T>() -> [u8; T];
10-
| +++ ~
116

127
error[E0658]: using `_` for array lengths is unstable
138
--> $DIR/issue-95307.rs:7:28

0 commit comments

Comments
 (0)