use crate::ty::query::Providers;
use crate::util::nodemap::{NodeMap, FxHashSet};
-use errors::{Applicability, DiagnosticBuilder, FatalError};
+use errors::FatalError;
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
-use syntax::source_map::{Spanned, SourceMap};
+use syntax::source_map::Spanned;
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
pub use syntax::ast::{Mutability, Constness, Unsafety, Movability, CaptureBy};
self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into()
}
}
-
- /// Suggest restricting a type param with a new bound.
- pub fn suggest_constraining_type_param(
- &self,
- err: &mut DiagnosticBuilder<'_>,
- param_name: &str,
- constraint: &str,
- source_map: &SourceMap,
- span: Span,
- ) -> bool {
- let restrict_msg = "consider further restricting this bound";
- if let Some(param) = self.params.iter().filter(|p| {
- p.name.ident().as_str() == param_name
- }).next() {
- if param_name.starts_with("impl ") {
- // `impl Trait` in argument:
- // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}`
- err.span_suggestion(
- param.span,
- restrict_msg,
- // `impl CurrentTrait + MissingTrait`
- format!("{} + {}", param_name, constraint),
- Applicability::MachineApplicable,
- );
- } else if self.where_clause.predicates.is_empty() &&
- param.bounds.is_empty()
- {
- // If there are no bounds whatsoever, suggest adding a constraint
- // to the type parameter:
- // `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
- err.span_suggestion(
- param.span,
- "consider restricting this bound",
- format!("{}: {}", param_name, constraint),
- Applicability::MachineApplicable,
- );
- } else if !self.where_clause.predicates.is_empty() {
- // There is a `where` clause, so suggest expanding it:
- // `fn foo<T>(t: T) where T: Debug {}` →
- // `fn foo<T>(t: T) where T: Debug, T: Trait {}`
- err.span_suggestion(
- self.where_clause.span().unwrap().shrink_to_hi(),
- &format!("consider further restricting type parameter `{}`", param_name),
- format!(", {}: {}", param_name, constraint),
- Applicability::MachineApplicable,
- );
- } else {
- // If there is no `where` clause lean towards constraining to the
- // type parameter:
- // `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
- // `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
- let sp = param.span.with_hi(span.hi());
- let span = source_map.span_through_char(sp, ':');
- if sp != param.span && sp != span {
- // Only suggest if we have high certainty that the span
- // covers the colon in `foo<T: Trait>`.
- err.span_suggestion(
- span,
- restrict_msg,
- format!("{}: {} + ", param_name, constraint),
- Applicability::MachineApplicable,
- );
- } else {
- err.span_label(
- param.span,
- &format!("consider adding a `where {}: {}` bound", param_name, constraint),
- );
- }
- }
- return true;
- }
- false
- }
}
/// Synthetic type parameters are converted to another form during lowering; this allows