diff options
Diffstat (limited to 'compiler/rustc_resolve/src/diagnostics.rs')
-rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index cd1a9b934..907a6b1c4 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -553,43 +553,40 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { resolution_error: ResolutionError<'a>, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { match resolution_error { - ResolutionError::GenericParamsFromOuterFunction(outer_res, has_generic_params) => { - let mut err = struct_span_err!( - self.tcx.sess, + ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => { + use errs::GenericParamsFromOuterItemLabel as Label; + let mut err = errs::GenericParamsFromOuterItem { span, - E0401, - "can't use generic parameters from outer function", - ); - err.span_label(span, "use of generic parameter from outer function"); + label: None, + refer_to_type_directly: None, + sugg: None, + }; let sm = self.tcx.sess.source_map(); let def_id = match outer_res { Res::SelfTyParam { .. } => { - err.span_label(span, "can't use `Self` here"); - return err; + err.label = Some(Label::SelfTyParam(span)); + return self.tcx.sess.create_err(err); } Res::SelfTyAlias { alias_to: def_id, .. } => { - err.span_label( - reduce_impl_span_to_impl_keyword(sm, self.def_span(def_id)), - "`Self` type implicitly declared here, by this `impl`", - ); - err.span_label(span, "use a type here instead"); - return err; + err.label = Some(Label::SelfTyAlias(reduce_impl_span_to_impl_keyword( + sm, + self.def_span(def_id), + ))); + err.refer_to_type_directly = Some(span); + return self.tcx.sess.create_err(err); } Res::Def(DefKind::TyParam, def_id) => { - err.span_label(self.def_span(def_id), "type parameter from outer function"); + err.label = Some(Label::TyParam(self.def_span(def_id))); def_id } Res::Def(DefKind::ConstParam, def_id) => { - err.span_label( - self.def_span(def_id), - "const parameter from outer function", - ); + err.label = Some(Label::ConstParam(self.def_span(def_id))); def_id } _ => { bug!( - "GenericParamsFromOuterFunction should only be used with \ + "GenericParamsFromOuterItem should only be used with \ Res::SelfTyParam, Res::SelfTyAlias, DefKind::TyParam or \ DefKind::ConstParam" ); @@ -597,9 +594,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; if let HasGenericParams::Yes(span) = has_generic_params { - // Try to retrieve the span of the function signature and generate a new - // message with a local type or const parameter. - let sugg_msg = "try using a local generic parameter instead"; let name = self.tcx.item_name(def_id); let (span, snippet) = if span.is_empty() { let snippet = format!("<{name}>"); @@ -609,11 +603,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let snippet = format!("{name}, "); (span, snippet) }; - // Suggest the modification to the user - err.span_suggestion(span, sugg_msg, snippet, Applicability::MaybeIncorrect); + err.sugg = Some(errs::GenericParamsFromOuterItemSugg { span, snippet }); } - err + self.tcx.sess.create_err(err) } ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self .tcx @@ -1032,7 +1025,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .get(&expn_id) .into_iter() .flatten() - .map(|ident| TypoSuggestion::typo_from_ident(*ident, res)), + .map(|(ident, _)| TypoSuggestion::typo_from_ident(*ident, res)), ); } } @@ -2603,7 +2596,9 @@ fn show_candidates( ); if let [first, .., last] = &path[..] { let sp = first.ident.span.until(last.ident.span); - if sp.can_be_used_for_suggestions() { + // Our suggestion is empty, so make sure the span is not empty (or we'd ICE). + // Can happen for derive-generated spans. + if sp.can_be_used_for_suggestions() && !sp.is_empty() { err.span_suggestion_verbose( sp, format!("if you import `{}`, refer to it directly", last.ident), @@ -2753,7 +2748,13 @@ fn search_for_any_use_in_items(items: &[P<ast::Item>]) -> Option<Span> { for item in items { if let ItemKind::Use(..) = item.kind { if is_span_suitable_for_use_injection(item.span) { - return Some(item.span.shrink_to_lo()); + let mut lo = item.span.lo(); + for attr in &item.attrs { + if attr.span.eq_ctxt(item.span) { + lo = std::cmp::min(lo, attr.span.lo()); + } + } + return Some(Span::new(lo, lo, item.span.ctxt(), item.span.parent())); } } } |