X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_infer%2Fsrc%2Finfer%2Ferror_reporting%2Fmod.rs;h=ccd860ce2428aa33f3b214ec7abce7aaa01aed73;hb=7907385999b4a83d37ed31d334f3ed9ca02983a1;hp=14555ad92559d2d89dfb340f9d94e460f7cad077;hpb=73fa217bc11fbac76f730223f6766c8e03513b5e;p=rust.git diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 14555ad9255..ccd860ce242 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -889,7 +889,7 @@ fn highlight_outer( /// /// For the following code: /// - /// ```no_run + /// ```ignore (illustrative) /// let x: Foo> = foo::>(); /// ``` /// @@ -1872,7 +1872,7 @@ pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option u32 { /// 22 /// } @@ -2327,6 +2327,7 @@ pub fn construct_generic_bound_failure( _ => span, }; + // type_param_span is (span, has_bounds) let type_param_span = match (generics, bound_kind) { (Some((_, ref generics, _)), GenericKind::Param(ref param)) => { // Account for the case where `param` corresponds to `Self`, @@ -2337,25 +2338,18 @@ pub fn construct_generic_bound_failure( // Get the `hir::Param` to verify whether it already has any bounds. // We do this to avoid suggesting code that ends up as `T: 'a'b`, // instead we suggest `T: 'a + 'b` in that case. - let id = hir.local_def_id_to_hir_id(def_id); - let mut has_bounds = false; - if let Node::GenericParam(param) = hir.get(id) { - has_bounds = !param.bounds.is_empty(); - } - let sp = self.tcx.def_span(def_id); + let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); + let ast_generics = self.tcx.hir().get_generics(hir_id.owner); + let bounds = + ast_generics.and_then(|g| g.bounds_span_for_suggestions(def_id)); // `sp` only covers `T`, change it so that it covers // `T:` when appropriate - let is_impl_trait = bound_kind.to_string().starts_with("impl "); - let sp = if has_bounds && !is_impl_trait { - sp.to(self - .tcx - .sess - .source_map() - .next_point(self.tcx.sess.source_map().next_point(sp))) + if let Some(span) = bounds { + (span, true) } else { - sp - }; - (sp, has_bounds, is_impl_trait) + let sp = self.tcx.def_span(def_id); + (sp.shrink_to_hi(), false) + } }) } else { None @@ -2411,52 +2405,37 @@ pub fn construct_generic_bound_failure( fn binding_suggestion<'tcx, S: fmt::Display>( err: &mut Diagnostic, - type_param_span: Option<(Span, bool, bool)>, + type_param_span: Option<(Span, bool)>, bound_kind: GenericKind<'tcx>, sub: S, ) { let msg = "consider adding an explicit lifetime bound"; - if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span { - let suggestion = if is_impl_trait { - format!("{} + {}", bound_kind, sub) - } else { - let tail = if has_lifetimes { " + " } else { "" }; - format!("{}: {}{}", bound_kind, sub, tail) - }; - err.span_suggestion( + if let Some((sp, has_lifetimes)) = type_param_span { + let suggestion = + if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) }; + err.span_suggestion_verbose( sp, &format!("{}...", msg), suggestion, Applicability::MaybeIncorrect, // Issue #41966 ); } else { - let consider = format!( - "{} {}...", - msg, - if type_param_span.map_or(false, |(_, _, is_impl_trait)| is_impl_trait) { - format!(" `{}` to `{}`", sub, bound_kind) - } else { - format!("`{}: {}`", bound_kind, sub) - }, - ); + let consider = format!("{} `{}: {}`...", msg, bound_kind, sub,); err.help(&consider); } } let new_binding_suggestion = - |err: &mut Diagnostic, - type_param_span: Option<(Span, bool, bool)>, - bound_kind: GenericKind<'tcx>| { + |err: &mut Diagnostic, type_param_span: Option<(Span, bool)>| { let msg = "consider introducing an explicit lifetime bound"; - if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span { - let suggestion = if is_impl_trait { - (sp.shrink_to_hi(), format!(" + {}", new_lt)) + if let Some((sp, has_lifetimes)) = type_param_span { + let suggestion = if has_lifetimes { + format!(" + {}", new_lt) } else { - let tail = if has_lifetimes { " +" } else { "" }; - (sp, format!("{}: {}{}", bound_kind, new_lt, tail)) + format!(": {}", new_lt) }; let mut sugg = - vec![suggestion, (span.shrink_to_hi(), format!(" + {}", new_lt))]; + vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))]; if let Some(lt) = add_lt_sugg { sugg.push(lt); sugg.rotate_right(1); @@ -2543,11 +2522,11 @@ enum SubOrigin<'hir> { let pred = format!("{}: {}", bound_kind, sub); let suggestion = format!( "{} {}", - if !generics.where_clause.predicates.is_empty() { "," } else { " where" }, + if !generics.predicates.is_empty() { "," } else { " where" }, pred, ); err.span_suggestion( - generics.where_clause.tail_span_for_suggestion(), + generics.tail_span_for_predicate_suggestion(), "consider adding a where clause", suggestion, Applicability::MaybeIncorrect, @@ -2615,7 +2594,7 @@ enum SubOrigin<'hir> { // suggest: // fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a ty::Closure(_, _substs) | ty::Opaque(_, _substs) if return_impl_trait => { - new_binding_suggestion(&mut err, type_param_span, bound_kind); + new_binding_suggestion(&mut err, type_param_span); } _ => { binding_suggestion(&mut err, type_param_span, bound_kind, new_lt);