Auto merge of #48326 - RalfJung:generic-bounds, r=petrochenkov

Warn about ignored generic bounds in `for`

This adds a new lint to fix #42181. For consistency and to avoid code duplication, I also moved the existing "bounds in type aliases are ignored" here.

Questions to the reviewer:
* Is it okay to just remove a diagnostic error code like this? Should I instead keep the warning about type aliases where it is? The old code provided a detailed explanation of what's going on when asked, that information is now lost. On the other hand, `span_warn!` seems deprecated (after this patch, it has exactly one user left!).
* Did I miss any syntactic construct that can appear as `for` in the surface syntax? I covered function types (`for<'a> fn(...)`), generic traits (`for <'a> Fn(...)`, can appear both as bounds as as trait objects) and bounds (`for<'a> F: ...`).
* For the sake of backwards compatibility, this adds a warning, not an error. @nikomatsakis suggested an error in https://github.com/rust-lang/rust/issues/42181#issuecomment-306924389, but I feel that can only happen in a new epoch -- right?

Cc @eddyb
This commit is contained in:
bors 2018-03-09 10:45:29 +00:00
commit fedce67cd2
20 changed files with 325 additions and 109 deletions

View file

@ -824,6 +824,17 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
hir_visit::walk_generics(self, g);
}
fn visit_where_predicate(&mut self, p: &'tcx hir::WherePredicate) {
run_lints!(self, check_where_predicate, late_passes, p);
hir_visit::walk_where_predicate(self, p);
}
fn visit_poly_trait_ref(&mut self, t: &'tcx hir::PolyTraitRef,
m: hir::TraitBoundModifier) {
run_lints!(self, check_poly_trait_ref, late_passes, t, m);
hir_visit::walk_poly_trait_ref(self, t, m);
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
let generics = self.generics.take();
self.generics = Some(&trait_item.generics);
@ -986,6 +997,16 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
ast_visit::walk_generics(self, g);
}
fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
run_lints!(self, check_where_predicate, early_passes, p);
ast_visit::walk_where_predicate(self, p);
}
fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef, m: &'a ast::TraitBoundModifier) {
run_lints!(self, check_poly_trait_ref, early_passes, t, m);
ast_visit::walk_poly_trait_ref(self, t, m);
}
fn visit_trait_item(&mut self, trait_item: &'a ast::TraitItem) {
self.with_lint_attrs(trait_item.id, &trait_item.attrs, |cx| {
run_lints!(cx, check_trait_item, early_passes, trait_item);

View file

@ -181,6 +181,9 @@ pub trait LateLintPass<'a, 'tcx>: LintPass {
fn check_ty(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Ty) { }
fn check_generic_param(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::GenericParam) { }
fn check_generics(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Generics) { }
fn check_where_predicate(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::WherePredicate) { }
fn check_poly_trait_ref(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::PolyTraitRef,
_: hir::TraitBoundModifier) { }
fn check_fn(&mut self,
_: &LateContext<'a, 'tcx>,
_: FnKind<'tcx>,
@ -253,6 +256,9 @@ pub trait EarlyLintPass: LintPass {
fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
fn check_generic_param(&mut self, _: &EarlyContext, _: &ast::GenericParam) { }
fn check_generics(&mut self, _: &EarlyContext, _: &ast::Generics) { }
fn check_where_predicate(&mut self, _: &EarlyContext, _: &ast::WherePredicate) { }
fn check_poly_trait_ref(&mut self, _: &EarlyContext, _: &ast::PolyTraitRef,
_: &ast::TraitBoundModifier) { }
fn check_fn(&mut self, _: &EarlyContext,
_: ast_visit::FnKind, _: &ast::FnDecl, _: Span, _: ast::NodeId) { }
fn check_fn_post(&mut self, _: &EarlyContext,