Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 45d92b4

Browse files
committed
merge need_type_info_err(_const)
1 parent e0bc267 commit 45d92b4

File tree

13 files changed

+148
-131
lines changed

13 files changed

+148
-131
lines changed

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

Lines changed: 117 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,10 @@ fn closure_return_type_suggestion(
176176
suggestion,
177177
Applicability::HasPlaceholders,
178178
);
179-
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr));
179+
err.span_label(
180+
span,
181+
InferCtxt::missing_type_msg("type", &name, &descr, parent_name, parent_descr),
182+
);
180183
}
181184

182185
/// Given a closure signature, return a `String` containing a list of all its argument types.
@@ -220,60 +223,119 @@ impl Into<rustc_errors::DiagnosticId> for TypeAnnotationNeeded {
220223
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
221224
pub fn extract_type_name(
222225
&self,
223-
ty: Ty<'tcx>,
226+
arg: GenericArg<'tcx>,
224227
highlight: Option<ty::print::RegionHighlightMode>,
225228
) -> (String, Option<Span>, Cow<'static, str>, Option<String>, Option<&'static str>) {
226-
if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
227-
let mut inner = self.inner.borrow_mut();
228-
let ty_vars = &inner.type_variables();
229-
let var_origin = ty_vars.var_origin(ty_vid);
230-
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind {
231-
let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
232-
let (parent_name, parent_desc) = if let Some(parent_def_id) = parent_def_id {
233-
let parent_name = self
234-
.tcx
235-
.def_key(parent_def_id)
236-
.disambiguated_data
237-
.data
238-
.get_opt_name()
239-
.map(|parent_symbol| parent_symbol.to_string());
240-
241-
(parent_name, Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)))
242-
} else {
243-
(None, None)
244-
};
229+
match arg.unpack() {
230+
GenericArgKind::Type(ty) => {
231+
if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
232+
let mut inner = self.inner.borrow_mut();
233+
let ty_vars = &inner.type_variables();
234+
let var_origin = ty_vars.var_origin(ty_vid);
235+
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) =
236+
var_origin.kind
237+
{
238+
let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
239+
let (parent_name, parent_desc) = if let Some(parent_def_id) = parent_def_id
240+
{
241+
let parent_name = self
242+
.tcx
243+
.def_key(parent_def_id)
244+
.disambiguated_data
245+
.data
246+
.get_opt_name()
247+
.map(|parent_symbol| parent_symbol.to_string());
248+
249+
(
250+
parent_name,
251+
Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)),
252+
)
253+
} else {
254+
(None, None)
255+
};
256+
257+
if name != kw::SelfUpper {
258+
return (
259+
name.to_string(),
260+
Some(var_origin.span),
261+
"type parameter".into(),
262+
parent_name,
263+
parent_desc,
264+
);
265+
}
266+
}
267+
}
245268

246-
if name != kw::SelfUpper {
247-
return (
248-
name.to_string(),
249-
Some(var_origin.span),
250-
"type parameter".into(),
251-
parent_name,
252-
parent_desc,
253-
);
269+
let mut s = String::new();
270+
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
271+
if let Some(highlight) = highlight {
272+
printer.region_highlight_mode = highlight;
254273
}
274+
let _ = ty.print(printer);
275+
(s, None, ty.prefix_string(), None, None)
255276
}
256-
}
277+
GenericArgKind::Const(ct) => {
278+
if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
279+
let origin =
280+
self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
281+
if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
282+
origin.kind
283+
{
284+
let parent_def_id = self.tcx.parent(def_id);
285+
let (parent_name, parent_descr) = if let Some(parent_def_id) = parent_def_id
286+
{
287+
let parent_name = self
288+
.tcx
289+
.def_key(parent_def_id)
290+
.disambiguated_data
291+
.data
292+
.get_opt_name()
293+
.map(|parent_symbol| parent_symbol.to_string());
294+
295+
(
296+
parent_name,
297+
Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)),
298+
)
299+
} else {
300+
(None, None)
301+
};
302+
303+
return (
304+
name.to_string(),
305+
Some(origin.span),
306+
"const parameter".into(),
307+
parent_name,
308+
parent_descr,
309+
);
310+
}
311+
}
257312

258-
let mut s = String::new();
259-
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
260-
if let Some(highlight) = highlight {
261-
printer.region_highlight_mode = highlight;
313+
let mut s = String::new();
314+
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
315+
if let Some(highlight) = highlight {
316+
printer.region_highlight_mode = highlight;
317+
}
318+
let _ = ct.print(printer);
319+
(s, None, "<TODO>".into(), None, None)
320+
}
321+
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
262322
}
263-
let _ = ty.print(printer);
264-
(s, None, ty.prefix_string(), None, None)
265323
}
266324

267-
// FIXME(eddyb) generalize all of this to handle `ty::Const` inference variables as well.
268325
pub fn need_type_info_err(
269326
&self,
270327
body_id: Option<hir::BodyId>,
271328
span: Span,
272-
ty: Ty<'tcx>,
329+
ty: GenericArg<'tcx>,
273330
error_code: TypeAnnotationNeeded,
274331
) -> DiagnosticBuilder<'tcx> {
275332
let ty = self.resolve_vars_if_possible(&ty);
276-
let (name, name_sp, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);
333+
let (name, name_sp, descr, parent_name, parent_descr) = self.extract_type_name(ty, None);
334+
let kind_str = match ty.unpack() {
335+
GenericArgKind::Type(_) => "type",
336+
GenericArgKind::Const(_) => "the value",
337+
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
338+
};
277339

278340
let mut local_visitor = FindHirNodeVisitor::new(&self, ty.into(), span);
279341
let ty_to_string = |ty: Ty<'tcx>| -> String {
@@ -545,55 +607,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
545607
// Avoid multiple labels pointing at `span`.
546608
err.span_label(
547609
span,
548-
InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr),
610+
InferCtxt::missing_type_msg(kind_str, &name, &descr, parent_name, parent_descr),
549611
);
550612
}
551613

552614
err
553615
}
554616

555-
// FIXME(const_generics): We should either try and merge this with `need_type_info_err`
556-
// or improve the errors created here.
557-
//
558-
// Unlike for type inference variables, we don't yet store the origin of const inference variables.
559-
// This is needed for to get a more relevant error span.
560-
pub fn need_type_info_err_const(
561-
&self,
562-
body_id: Option<hir::BodyId>,
563-
span: Span,
564-
ct: &'tcx ty::Const<'tcx>,
565-
error_code: TypeAnnotationNeeded,
566-
) -> DiagnosticBuilder<'tcx> {
567-
let mut local_visitor = FindHirNodeVisitor::new(&self, ct.into(), span);
568-
if let Some(body_id) = body_id {
569-
let expr = self.tcx.hir().expect_expr(body_id.hir_id);
570-
local_visitor.visit_expr(expr);
571-
}
572-
573-
let mut param_name = None;
574-
let span = if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
575-
let origin = self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
576-
if let ConstVariableOriginKind::ConstParameterDefinition(param) = origin.kind {
577-
param_name = Some(param);
578-
}
579-
origin.span
580-
} else {
581-
local_visitor.target_span
582-
};
583-
584-
let error_code = error_code.into();
585-
let mut err =
586-
self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code);
587-
588-
if let Some(param_name) = param_name {
589-
err.note(&format!("cannot infer the value of the const parameter `{}`", param_name));
590-
} else {
591-
err.note("unable to infer the value of a const parameter");
592-
}
593-
594-
err
595-
}
596-
597617
/// If the `FnSig` for the method call can be found and type arguments are identified as
598618
/// needed, suggest annotating the call, otherwise point out the resulting type of the call.
599619
fn annotate_method_call(
@@ -647,7 +667,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
647667
ty: Ty<'tcx>,
648668
) -> DiagnosticBuilder<'tcx> {
649669
let ty = self.resolve_vars_if_possible(&ty);
650-
let (name, _, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);
670+
let (name, _, descr, parent_name, parent_descr) = self.extract_type_name(ty.into(), None);
651671

652672
let mut err = struct_span_err!(
653673
self.tcx.sess,
@@ -656,18 +676,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
656676
"type inside {} must be known in this context",
657677
kind,
658678
);
659-
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr));
679+
err.span_label(
680+
span,
681+
InferCtxt::missing_type_msg("type", &name, &descr, parent_name, parent_descr),
682+
);
660683
err
661684
}
662685

663686
fn missing_type_msg(
687+
kind_str: &str,
664688
type_name: &str,
665689
descr: &str,
666690
parent_name: Option<String>,
667691
parent_descr: Option<&str>,
668-
) -> Cow<'static, str> {
692+
) -> String {
669693
if type_name == "_" {
670-
"cannot infer type".into()
694+
format!("cannot infer {}", kind_str)
671695
} else {
672696
let parent_desc = if let Some(parent_name) = parent_name {
673697
let parent_type_descr = if let Some(parent_descr) = parent_descr {
@@ -681,7 +705,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
681705
"".to_string()
682706
};
683707

684-
format!("cannot infer type for {} `{}`{}", descr, type_name, parent_desc).into()
708+
let preposition = if "value" == kind_str { "of" } else { "for" };
709+
// For example: "cannot infer type for type parameter `T`"
710+
format!(
711+
"cannot infer {} {} {} `{}`{}",
712+
kind_str, preposition, descr, type_name, parent_desc
713+
)
714+
.into()
685715
}
686716
}
687717
}

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11631163
}
11641164
GenericParamDefKind::Const { .. } => {
11651165
let origin = ConstVariableOrigin {
1166-
kind: ConstVariableOriginKind::ConstParameterDefinition(param.name),
1166+
kind: ConstVariableOriginKind::ConstParameterDefinition(
1167+
param.name,
1168+
param.def_id,
1169+
),
11671170
span,
11681171
};
11691172
let const_var_id =

compiler/rustc_middle/src/infer/unify_key.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_data_structures::undo_log::UndoLogs;
44
use rustc_data_structures::unify::{
55
self, EqUnifyValue, InPlace, NoError, UnificationTable, UnifyKey, UnifyValue,
66
};
7+
use rustc_span::def_id::DefId;
78
use rustc_span::symbol::Symbol;
89
use rustc_span::{Span, DUMMY_SP};
910

@@ -124,8 +125,7 @@ pub struct ConstVariableOrigin {
124125
pub enum ConstVariableOriginKind {
125126
MiscVariable,
126127
ConstInference,
127-
// FIXME(const_generics): Consider storing the `DefId` of the param here.
128-
ConstParameterDefinition(Symbol),
128+
ConstParameterDefinition(Symbol, DefId),
129129
SubstitutionPlaceholder,
130130
}
131131

compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
396396
) -> Option<RegionNameHighlight> {
397397
let mut highlight = RegionHighlightMode::default();
398398
highlight.highlighting_region_vid(needle_fr, counter);
399-
let type_name = self.infcx.extract_type_name(&ty, Some(highlight)).0;
399+
let type_name = self.infcx.extract_type_name(ty.into(), Some(highlight)).0;
400400

401401
debug!(
402402
"highlight_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@@ -646,7 +646,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
646646

647647
let mut highlight = RegionHighlightMode::default();
648648
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
649-
let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0;
649+
let type_name = self.infcx.extract_type_name(return_ty.into(), Some(highlight)).0;
650650

651651
let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id);
652652

@@ -698,7 +698,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
698698

699699
let mut highlight = RegionHighlightMode::default();
700700
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
701-
let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0;
701+
let type_name = self.infcx.extract_type_name(yield_ty.into(), Some(highlight)).0;
702702

703703
let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id);
704704

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use rustc_hir::Node;
2020
use rustc_middle::mir::interpret::ErrorHandled;
2121
use rustc_middle::ty::error::ExpectedFound;
2222
use rustc_middle::ty::fold::TypeFolder;
23-
use rustc_middle::ty::subst::GenericArgKind;
2423
use rustc_middle::ty::{
2524
self, fast_reject, AdtKind, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt,
2625
TypeFoldable, WithConstness,
@@ -1513,10 +1512,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
15131512
// check upstream for type errors and don't add the obligations to
15141513
// begin with in those cases.
15151514
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
1516-
self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit();
1515+
self.need_type_info_err(body_id, span, self_ty.into(), ErrorCode::E0282).emit();
15171516
return;
15181517
}
1519-
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
1518+
let mut err =
1519+
self.need_type_info_err(body_id, span, self_ty.into(), ErrorCode::E0283);
15201520
err.note(&format!("cannot satisfy `{}`", predicate));
15211521
if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
15221522
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
@@ -1580,17 +1580,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
15801580
return;
15811581
}
15821582

1583-
match arg.unpack() {
1584-
GenericArgKind::Lifetime(lt) => {
1585-
span_bug!(span, "unexpected well formed predicate: {:?}", lt)
1586-
}
1587-
GenericArgKind::Type(ty) => {
1588-
self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
1589-
}
1590-
GenericArgKind::Const(ct) => {
1591-
self.need_type_info_err_const(body_id, span, ct, ErrorCode::E0282)
1592-
}
1593-
}
1583+
self.need_type_info_err(body_id, span, arg, ErrorCode::E0282)
15941584
}
15951585

15961586
ty::PredicateAtom::Subtype(data) => {
@@ -1601,7 +1591,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
16011591
let SubtypePredicate { a_is_expected: _, a, b } = data;
16021592
// both must be type variables, or the other would've been instantiated
16031593
assert!(a.is_ty_var() && b.is_ty_var());
1604-
self.need_type_info_err(body_id, span, a, ErrorCode::E0282)
1594+
self.need_type_info_err(body_id, span, a.into(), ErrorCode::E0282)
16051595
}
16061596
ty::PredicateAtom::Projection(data) => {
16071597
let trait_ref = ty::Binder::bind(data).to_poly_trait_ref(self.tcx);
@@ -1612,7 +1602,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
16121602
}
16131603
if self_ty.needs_infer() && ty.needs_infer() {
16141604
// We do this for the `foo.collect()?` case to produce a suggestion.
1615-
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284);
1605+
let mut err =
1606+
self.need_type_info_err(body_id, span, self_ty.into(), ErrorCode::E0284);
16161607
err.note(&format!("cannot satisfy `{}`", predicate));
16171608
err
16181609
} else {

0 commit comments

Comments
 (0)