1
Fork 0

review comments

This commit is contained in:
Esteban Küber 2020-04-05 10:52:54 -07:00
parent 2c998aa8bb
commit 794b644f0b
3 changed files with 87 additions and 93 deletions

View file

@ -17,6 +17,7 @@
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(str_strip)] #![feature(str_strip)]
#![feature(option_zip)]
#![recursion_limit = "512"] // For rustdoc #![recursion_limit = "512"] // For rustdoc
#[macro_use] #[macro_use]

View file

@ -388,7 +388,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// which is somewhat confusing. // which is somewhat confusing.
self.suggest_restricting_param_bound( self.suggest_restricting_param_bound(
&mut err, &mut err,
&trait_ref, trait_ref,
obligation.cause.body_id, obligation.cause.body_id,
); );
} else { } else {

View file

@ -27,7 +27,7 @@ pub trait InferCtxtExt<'tcx> {
fn suggest_restricting_param_bound( fn suggest_restricting_param_bound(
&self, &self,
err: &mut DiagnosticBuilder<'_>, err: &mut DiagnosticBuilder<'_>,
trait_ref: &ty::PolyTraitRef<'_>, trait_ref: ty::PolyTraitRef<'_>,
body_id: hir::HirId, body_id: hir::HirId,
); );
@ -168,28 +168,24 @@ fn suggest_restriction(
err: &mut DiagnosticBuilder<'_>, err: &mut DiagnosticBuilder<'_>,
fn_sig: Option<&hir::FnSig<'_>>, fn_sig: Option<&hir::FnSig<'_>>,
projection: Option<&ty::ProjectionTy<'_>>, projection: Option<&ty::ProjectionTy<'_>>,
trait_ref: &ty::PolyTraitRef<'_>, trait_ref: ty::PolyTraitRef<'_>,
) { ) {
let span = generics.where_clause.span_for_predicates_or_empty_place(); let span = generics.where_clause.span_for_predicates_or_empty_place();
if !span.from_expansion() && span.desugaring_kind().is_none() { if span.from_expansion() || span.desugaring_kind().is_some() {
return;
}
// Given `fn foo(t: impl Trait)` where `Trait` requires assoc type `A`... // Given `fn foo(t: impl Trait)` where `Trait` requires assoc type `A`...
if let Some((name, fn_sig)) = fn_sig.and_then(|sig| { if let Some((name, fn_sig)) =
projection.and_then(|p| { fn_sig.zip(projection).and_then(|(sig, p)| match p.self_ty().kind {
// Shenanigans to get the `Trait` from the `impl Trait`. // Shenanigans to get the `Trait` from the `impl Trait`.
match p.self_ty().kind {
ty::Param(param) => { ty::Param(param) => {
// `fn foo(t: impl Trait)` // `fn foo(t: impl Trait)`
// ^^^^^ get this string // ^^^^^ get this string
param param.name.as_str().strip_prefix("impl").map(|s| (s.trim_start().to_string(), sig))
.name
.as_str()
.strip_prefix("impl")
.map(|s| (s.trim_start().to_string(), sig))
} }
_ => None, _ => None,
}
}) })
}) { {
// We know we have an `impl Trait` that doesn't satisfy a required projection. // We know we have an `impl Trait` that doesn't satisfy a required projection.
// Find all of the ocurrences of `impl Trait` for `Trait` in the function arguments' // Find all of the ocurrences of `impl Trait` for `Trait` in the function arguments'
@ -258,21 +254,18 @@ fn suggest_restriction(
); );
} else { } else {
// Trivial case: `T` needs an extra bound: `T: Bound`. // Trivial case: `T` needs an extra bound: `T: Bound`.
let (sp, s) = predicate_constraint( let (sp, s) =
generics, predicate_constraint(generics, trait_ref.without_const().to_predicate().to_string());
trait_ref.without_const().to_predicate().to_string(),
);
let appl = Applicability::MachineApplicable; let appl = Applicability::MachineApplicable;
err.span_suggestion(sp, &format!("consider further restricting {}", msg), s, appl); err.span_suggestion(sp, &format!("consider further restricting {}", msg), s, appl);
} }
} }
}
impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
fn suggest_restricting_param_bound( fn suggest_restricting_param_bound(
&self, &self,
mut err: &mut DiagnosticBuilder<'_>, mut err: &mut DiagnosticBuilder<'_>,
trait_ref: &ty::PolyTraitRef<'_>, trait_ref: ty::PolyTraitRef<'_>,
body_id: hir::HirId, body_id: hir::HirId,
) { ) {
let self_ty = trait_ref.self_ty(); let self_ty = trait_ref.self_ty();