Skip to content

Commit 0f530ec

Browse files
committed
review comments
1 parent 9fb446d commit 0f530ec

File tree

3 files changed

+81
-77
lines changed

3 files changed

+81
-77
lines changed

src/librustc/hir/mod.rs

+2-75
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ use crate::ty::AdtKind;
1616
use crate::ty::query::Providers;
1717
use crate::util::nodemap::{NodeMap, FxHashSet};
1818

19-
use errors::{Applicability, DiagnosticBuilder, FatalError};
19+
use errors::FatalError;
2020
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
21-
use syntax::source_map::{Spanned, SourceMap};
21+
use syntax::source_map::Spanned;
2222
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
2323
use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
2424
pub use syntax::ast::{Mutability, Constness, Unsafety, Movability, CaptureBy};
@@ -644,79 +644,6 @@ impl Generics {
644644
self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into()
645645
}
646646
}
647-
648-
/// Suggest restricting a type param with a new bound.
649-
pub fn suggest_constraining_type_param(
650-
&self,
651-
err: &mut DiagnosticBuilder<'_>,
652-
param_name: &str,
653-
constraint: &str,
654-
source_map: &SourceMap,
655-
span: Span,
656-
) -> bool {
657-
let restrict_msg = "consider further restricting this bound";
658-
if let Some(param) = self.params.iter().filter(|p| {
659-
p.name.ident().as_str() == param_name
660-
}).next() {
661-
if param_name.starts_with("impl ") {
662-
// `impl Trait` in argument:
663-
// `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}`
664-
err.span_suggestion(
665-
param.span,
666-
restrict_msg,
667-
// `impl CurrentTrait + MissingTrait`
668-
format!("{} + {}", param_name, constraint),
669-
Applicability::MachineApplicable,
670-
);
671-
} else if self.where_clause.predicates.is_empty() &&
672-
param.bounds.is_empty()
673-
{
674-
// If there are no bounds whatsoever, suggest adding a constraint
675-
// to the type parameter:
676-
// `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
677-
err.span_suggestion(
678-
param.span,
679-
"consider restricting this bound",
680-
format!("{}: {}", param_name, constraint),
681-
Applicability::MachineApplicable,
682-
);
683-
} else if !self.where_clause.predicates.is_empty() {
684-
// There is a `where` clause, so suggest expanding it:
685-
// `fn foo<T>(t: T) where T: Debug {}` →
686-
// `fn foo<T>(t: T) where T: Debug, T: Trait {}`
687-
err.span_suggestion(
688-
self.where_clause.span().unwrap().shrink_to_hi(),
689-
&format!("consider further restricting type parameter `{}`", param_name),
690-
format!(", {}: {}", param_name, constraint),
691-
Applicability::MachineApplicable,
692-
);
693-
} else {
694-
// If there is no `where` clause lean towards constraining to the
695-
// type parameter:
696-
// `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
697-
// `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
698-
let sp = param.span.with_hi(span.hi());
699-
let span = source_map.span_through_char(sp, ':');
700-
if sp != param.span && sp != span {
701-
// Only suggest if we have high certainty that the span
702-
// covers the colon in `foo<T: Trait>`.
703-
err.span_suggestion(
704-
span,
705-
restrict_msg,
706-
format!("{}: {} + ", param_name, constraint),
707-
Applicability::MachineApplicable,
708-
);
709-
} else {
710-
err.span_label(
711-
param.span,
712-
&format!("consider adding a `where {}: {}` bound", param_name, constraint),
713-
);
714-
}
715-
}
716-
return true;
717-
}
718-
false
719-
}
720647
}
721648

722649
/// Synthetic type parameters are converted to another form during lowering; this allows

src/librustc/traits/error_reporting.rs

+76-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use syntax::ast;
3939
use syntax::symbol::{sym, kw};
4040
use syntax_pos::{DUMMY_SP, Span, ExpnKind, MultiSpan};
4141
use rustc::hir::def_id::LOCAL_CRATE;
42+
use syntax_pos::source_map::SourceMap;
4243

4344
use rustc_error_codes::*;
4445

@@ -1189,7 +1190,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11891190
// Missing generic type parameter bound.
11901191
let param_name = self_ty.to_string();
11911192
let constraint = trait_ref.to_string();
1192-
if generics.suggest_constraining_type_param(
1193+
if suggest_constraining_type_param(
1194+
generics,
11931195
&mut err,
11941196
&param_name,
11951197
&constraint,
@@ -2497,3 +2499,76 @@ impl ArgKind {
24972499
}
24982500
}
24992501
}
2502+
2503+
/// Suggest restricting a type param with a new bound.
2504+
pub fn suggest_constraining_type_param(
2505+
generics: &hir::Generics,
2506+
err: &mut DiagnosticBuilder<'_>,
2507+
param_name: &str,
2508+
constraint: &str,
2509+
source_map: &SourceMap,
2510+
span: Span,
2511+
) -> bool {
2512+
let restrict_msg = "consider further restricting this bound";
2513+
if let Some(param) = generics.params.iter().filter(|p| {
2514+
p.name.ident().as_str() == param_name
2515+
}).next() {
2516+
if param_name.starts_with("impl ") {
2517+
// `impl Trait` in argument:
2518+
// `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}`
2519+
err.span_suggestion(
2520+
param.span,
2521+
restrict_msg,
2522+
// `impl CurrentTrait + MissingTrait`
2523+
format!("{} + {}", param_name, constraint),
2524+
Applicability::MachineApplicable,
2525+
);
2526+
} else if generics.where_clause.predicates.is_empty() &&
2527+
param.bounds.is_empty()
2528+
{
2529+
// If there are no bounds whatsoever, suggest adding a constraint
2530+
// to the type parameter:
2531+
// `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
2532+
err.span_suggestion(
2533+
param.span,
2534+
"consider restricting this bound",
2535+
format!("{}: {}", param_name, constraint),
2536+
Applicability::MachineApplicable,
2537+
);
2538+
} else if !generics.where_clause.predicates.is_empty() {
2539+
// There is a `where` clause, so suggest expanding it:
2540+
// `fn foo<T>(t: T) where T: Debug {}` →
2541+
// `fn foo<T>(t: T) where T: Debug, T: Trait {}`
2542+
err.span_suggestion(
2543+
generics.where_clause.span().unwrap().shrink_to_hi(),
2544+
&format!("consider further restricting type parameter `{}`", param_name),
2545+
format!(", {}: {}", param_name, constraint),
2546+
Applicability::MachineApplicable,
2547+
);
2548+
} else {
2549+
// If there is no `where` clause lean towards constraining to the
2550+
// type parameter:
2551+
// `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
2552+
// `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
2553+
let sp = param.span.with_hi(span.hi());
2554+
let span = source_map.span_through_char(sp, ':');
2555+
if sp != param.span && sp != span {
2556+
// Only suggest if we have high certainty that the span
2557+
// covers the colon in `foo<T: Trait>`.
2558+
err.span_suggestion(
2559+
span,
2560+
restrict_msg,
2561+
format!("{}: {} + ", param_name, constraint),
2562+
Applicability::MachineApplicable,
2563+
);
2564+
} else {
2565+
err.span_label(
2566+
param.span,
2567+
&format!("consider adding a `where {}: {}` bound", param_name, constraint),
2568+
);
2569+
}
2570+
}
2571+
return true;
2572+
}
2573+
false
2574+
}

src/librustc_mir/borrow_check/conflict_errors.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc::mir::{
77
PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
88
};
99
use rustc::ty::{self, Ty};
10+
use rustc::traits::error_reporting::suggest_constraining_type_param;
1011
use rustc_data_structures::fx::FxHashSet;
1112
use rustc_index::vec::Idx;
1213
use rustc_errors::{Applicability, DiagnosticBuilder};
@@ -233,7 +234,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
233234
let generics = tcx.generics_of(self.mir_def_id);
234235
let param = generics.type_param(&param_ty, tcx);
235236
let generics = tcx.hir().get_generics(self.mir_def_id).unwrap();
236-
generics.suggest_constraining_type_param(
237+
suggest_constraining_type_param(
238+
generics,
237239
&mut err,
238240
&param.name.as_str(),
239241
"Copy",

0 commit comments

Comments
 (0)