Skip to content

Commit 5afbc52

Browse files
committed
typeck: report placeholder type error w/out span
This commit fixes a regression introduced in rust-lang#70369 which meant that an error was not being emitted for invalid placeholder types when there wasn't a span available. Signed-off-by: David Wood <[email protected]>
1 parent 346aec9 commit 5afbc52

File tree

6 files changed

+103
-63
lines changed

6 files changed

+103
-63
lines changed

src/librustc_typeck/astconv.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3049,14 +3049,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
30493049
let bare_fn_ty =
30503050
ty::Binder::bind(tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi));
30513051

3052-
if let (false, Some(ident_span)) = (self.allow_ty_infer(), ident_span) {
3052+
if !self.allow_ty_infer() {
30533053
// We always collect the spans for placeholder types when evaluating `fn`s, but we
30543054
// only want to emit an error complaining about them if infer types (`_`) are not
30553055
// allowed. `allow_ty_infer` gates this behavior. We check for the presence of
30563056
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
30573057
crate::collect::placeholder_type_error(
30583058
tcx,
3059-
ident_span.shrink_to_hi(),
3059+
ident_span.map(|sp| sp.shrink_to_hi()),
30603060
&generics.params[..],
30613061
visitor.0,
30623062
true,

src/librustc_typeck/collect.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,23 @@ struct CollectItemTypesVisitor<'tcx> {
129129
/// all already existing generic type parameters to avoid suggesting a name that is already in use.
130130
crate fn placeholder_type_error(
131131
tcx: TyCtxt<'tcx>,
132-
span: Span,
132+
span: Option<Span>,
133133
generics: &[hir::GenericParam<'_>],
134134
placeholder_types: Vec<Span>,
135135
suggest: bool,
136136
) {
137137
if placeholder_types.is_empty() {
138138
return;
139139
}
140-
let type_name = generics.next_type_param_name(None);
141140

141+
let type_name = generics.next_type_param_name(None);
142142
let mut sugg: Vec<_> =
143143
placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();
144+
144145
if generics.is_empty() {
145-
sugg.push((span, format!("<{}>", type_name)));
146+
if let Some(span) = span {
147+
sugg.push((span, format!("<{}>", type_name)));
148+
}
146149
} else if let Some(arg) = generics.iter().find(|arg| match arg.name {
147150
hir::ParamName::Plain(Ident { name: kw::Underscore, .. }) => true,
148151
_ => false,
@@ -158,6 +161,7 @@ crate fn placeholder_type_error(
158161
format!(", {}", type_name),
159162
));
160163
}
164+
161165
let mut err = bad_placeholder_type(tcx, placeholder_types);
162166
if suggest {
163167
err.multipart_suggestion(
@@ -186,7 +190,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir
186190
let mut visitor = PlaceholderHirTyCollector::default();
187191
visitor.visit_item(item);
188192

189-
placeholder_type_error(tcx, generics.span, &generics.params[..], visitor.0, suggest);
193+
placeholder_type_error(tcx, Some(generics.span), &generics.params[..], visitor.0, suggest);
190194
}
191195

192196
impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
@@ -722,7 +726,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
722726
// Account for `const C: _;` and `type T = _;`.
723727
let mut visitor = PlaceholderHirTyCollector::default();
724728
visitor.visit_trait_item(trait_item);
725-
placeholder_type_error(tcx, DUMMY_SP, &[], visitor.0, false);
729+
placeholder_type_error(tcx, None, &[], visitor.0, false);
726730
}
727731

728732
hir::TraitItemKind::Type(_, None) => {}
@@ -745,7 +749,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) {
745749
// Account for `type T = _;`
746750
let mut visitor = PlaceholderHirTyCollector::default();
747751
visitor.visit_impl_item(impl_item);
748-
placeholder_type_error(tcx, DUMMY_SP, &[], visitor.0, false);
752+
placeholder_type_error(tcx, None, &[], visitor.0, false);
749753
}
750754
hir::ImplItemKind::Const(..) => {}
751755
}

src/test/ui/issues/issue-74086.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
static BUG: fn(_) -> u8 = |_| 8;
3+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121]
4+
}

src/test/ui/issues/issue-74086.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
2+
--> $DIR/issue-74086.rs:2:20
3+
|
4+
LL | static BUG: fn(_) -> u8 = |_| 8;
5+
| ^
6+
| |
7+
| not allowed in type signatures
8+
| help: use type parameters instead: `T`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0121`.

src/test/ui/typeck/typeck_type_placeholder_item.rs

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ fn test7(x: _) { let _x: usize = x; }
3232

3333
fn test8(_f: fn() -> _) { }
3434
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
35+
//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
3536

3637
struct Test9;
3738

@@ -98,6 +99,7 @@ pub fn main() {
9899

99100
fn fn_test8(_f: fn() -> _) { }
100101
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
102+
//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
101103

102104
struct FnTest9;
103105

0 commit comments

Comments
 (0)