diff options
Diffstat (limited to 'compiler')
6 files changed, 31 insertions, 20 deletions
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index acca1a1477f..a4e0e773a81 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -278,7 +278,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, move_from_desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,) + struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc) } /// Signal an error due to an attempt to move out of the interior diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e759fd6bc94..762176ecfc7 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -12,6 +12,7 @@ use rustc_hir::def::DefKind; use rustc_hir_analysis::autoderef::{self, Autoderef}; use rustc_infer::infer::canonical::OriginalQueryValues; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; +use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::{self, InferOk, TyCtxtInferExt}; use rustc_middle::middle::stability; @@ -448,15 +449,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } else { - // Encountered a real ambiguity, so abort the lookup. If `ty` is not - // an `Err`, report the right "type annotations needed" error pointing - // to it. + // Ended up encountering a type variable when doing autoderef, + // but it may not be a type variable after processing obligations + // in our local `FnCtxt`, so don't call `structurally_resolved_type`. let ty = &bad_ty.ty; let ty = self .probe_instantiate_query_response(span, &orig_values, ty) .unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty)); - let ty = self.structurally_resolved_type(span, ty.value); - assert!(matches!(ty.kind(), ty::Error(_))); + let ty = self.resolve_vars_if_possible(ty.value); + let guar = match *ty.kind() { + ty::Infer(ty::TyVar(_)) => self + .err_ctxt() + .emit_inference_failure_err(self.body_id, span, ty.into(), E0282, true) + .emit(), + ty::Error(guar) => guar, + _ => bug!("unexpected bad final type in method autoderef"), + }; + self.demand_eqtype(span, ty, self.tcx.ty_error(guar)); return Err(MethodError::NoMatch(NoMatchData { static_candidates: Vec::new(), unsatisfied_predicates: Vec::new(), diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs index b37dc826d28..84b18a62028 100644 --- a/compiler/rustc_macros/src/diagnostics/error.rs +++ b/compiler/rustc_macros/src/diagnostics/error.rs @@ -54,7 +54,7 @@ fn path_to_string(path: &syn::Path) -> String { /// Returns an error diagnostic on span `span` with msg `msg`. #[must_use] -pub(crate) fn span_err(span: impl MultiSpan, msg: &str) -> Diagnostic { +pub(crate) fn span_err<T: Into<String>>(span: impl MultiSpan, msg: T) -> Diagnostic { Diagnostic::spanned(span, Level::Error, msg) } @@ -77,11 +77,9 @@ pub(crate) fn invalid_attr(attr: &Attribute) -> Diagnostic { let span = attr.span().unwrap(); let path = path_to_string(attr.path()); match attr.meta { - Meta::Path(_) => span_err(span, &format!("`#[{path}]` is not a valid attribute")), - Meta::NameValue(_) => { - span_err(span, &format!("`#[{path} = ...]` is not a valid attribute")) - } - Meta::List(_) => span_err(span, &format!("`#[{path}(...)]` is not a valid attribute")), + Meta::Path(_) => span_err(span, format!("`#[{path}]` is not a valid attribute")), + Meta::NameValue(_) => span_err(span, format!("`#[{path} = ...]` is not a valid attribute")), + Meta::List(_) => span_err(span, format!("`#[{path}(...)]` is not a valid attribute")), } } diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index e3d9eb96574..e8dc986914e 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -200,7 +200,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { throw_span_err!( attr.span().unwrap(), - &format!( + format!( "diagnostic slug must be first argument of a `#[{name}(...)]` attribute" ) ); diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 85dd9f6a3ce..12563292181 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -347,7 +347,7 @@ pub(crate) trait HasFieldMap { None => { span_err( span.unwrap(), - &format!("`{field}` doesn't refer to a field on this type"), + format!("`{field}` doesn't refer to a field on this type"), ) .emit(); quote! { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 75a92af714b..67745f04641 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2382,17 +2382,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let Some(impl_def_id) = trait_impls.non_blanket_impls().values().flatten().next() { let non_blanket_impl_count = trait_impls.non_blanket_impls().values().flatten().count(); - let message = if non_blanket_impl_count == 1 { - "use the fully-qualified path to the only available implementation".to_string() - } else { + // If there is only one implementation of the trait, suggest using it. + // Otherwise, use a placeholder comment for the implementation. + let (message, impl_suggestion) = if non_blanket_impl_count == 1 {( + "use the fully-qualified path to the only available implementation".to_string(), + format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity()) + )} else {( format!( "use a fully-qualified path to a specific available implementation ({} found)", non_blanket_impl_count - ) - }; + ), + "</* self type */ as ".to_string() + )}; let mut suggestions = vec![( path.span.shrink_to_lo(), - format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity()) + impl_suggestion )]; if let Some(generic_arg) = trait_path_segment.args { let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext); |
