diff options
Diffstat (limited to 'compiler/rustc_lint/src')
| -rw-r--r-- | compiler/rustc_lint/src/builtin.rs | 180 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/types.rs | 6 |
2 files changed, 70 insertions, 116 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 68658e2616e..3564f15e210 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1199,8 +1199,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { }); } } - hir::ItemKind::Impl(hir::Impl { ref generics, items, .. }) => { - for it in items { + hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => { + for it in *items { if let hir::AssocItemKind::Fn { .. } = it.kind { if let Some(no_mangle_attr) = cx .sess() @@ -1517,59 +1517,61 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { // Bounds are respected for `type X = impl Trait` return; } - let mut suggested_changing_assoc_types = false; // There must not be a where clause - if !type_alias_generics.where_clause.predicates.is_empty() { - cx.lint( - TYPE_ALIAS_BOUNDS, - |lint| { - let mut err = lint.build("where clauses are not enforced in type aliases"); - let spans: Vec<_> = type_alias_generics - .where_clause - .predicates - .iter() - .map(|pred| pred.span()) - .collect(); - err.set_span(spans); - err.span_suggestion( - type_alias_generics.where_clause.span_for_predicates_or_empty_place(), - "the clause will not be checked when the type alias is used, and should be removed", - String::new(), - Applicability::MachineApplicable, - ); - if !suggested_changing_assoc_types { - TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); - suggested_changing_assoc_types = true; - } - err.emit(); - }, - ); + if type_alias_generics.predicates.is_empty() { + return; } - // The parameters must not have bounds - for param in type_alias_generics.params.iter() { - let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); - let suggestion = spans - .iter() - .map(|sp| { - let start = param.span.between(*sp); // Include the `:` in `T: Bound`. - (start.to(*sp), String::new()) - }) - .collect(); - if !spans.is_empty() { - cx.struct_span_lint(TYPE_ALIAS_BOUNDS, spans, |lint| { - let mut err = - lint.build("bounds on generic parameters are not enforced in type aliases"); - let msg = "the bound will not be checked when the type alias is used, \ - and should be removed"; - err.multipart_suggestion(msg, suggestion, Applicability::MachineApplicable); - if !suggested_changing_assoc_types { - TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); - suggested_changing_assoc_types = true; - } - err.emit(); - }); + + let mut where_spans = Vec::new(); + let mut inline_spans = Vec::new(); + let mut inline_sugg = Vec::new(); + for p in type_alias_generics.predicates { + let span = p.span(); + if p.in_where_clause() { + where_spans.push(span); + } else { + for b in p.bounds() { + inline_spans.push(b.span()); + } + inline_sugg.push((span, String::new())); } } + + let mut suggested_changing_assoc_types = false; + if !where_spans.is_empty() { + cx.lint(TYPE_ALIAS_BOUNDS, |lint| { + let mut err = lint.build("where clauses are not enforced in type aliases"); + err.set_span(where_spans); + err.span_suggestion( + type_alias_generics.where_clause_span, + "the clause will not be checked when the type alias is used, and should be removed", + String::new(), + Applicability::MachineApplicable, + ); + if !suggested_changing_assoc_types { + TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); + suggested_changing_assoc_types = true; + } + err.emit(); + }); + } + + if !inline_spans.is_empty() { + cx.lint(TYPE_ALIAS_BOUNDS, |lint| { + let mut err = + lint.build("bounds on generic parameters are not enforced in type aliases"); + err.set_span(inline_spans); + err.multipart_suggestion( + "the bound will not be checked when the type alias is used, and should be removed", + inline_sugg, + Applicability::MachineApplicable, + ); + if !suggested_changing_assoc_types { + TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); + } + err.emit(); + }); + } } } @@ -2085,27 +2087,6 @@ impl ExplicitOutlivesRequirements { .collect() } - fn collect_outlived_lifetimes<'tcx>( - &self, - param: &'tcx hir::GenericParam<'tcx>, - tcx: TyCtxt<'tcx>, - inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], - ty_generics: &'tcx ty::Generics, - ) -> Vec<ty::Region<'tcx>> { - let index = - ty_generics.param_def_id_to_index[&tcx.hir().local_def_id(param.hir_id).to_def_id()]; - - match param.kind { - hir::GenericParamKind::Lifetime { .. } => { - Self::lifetimes_outliving_lifetime(inferred_outlives, index) - } - hir::GenericParamKind::Type { .. } => { - Self::lifetimes_outliving_type(inferred_outlives, index) - } - hir::GenericParamKind::Const { .. } => Vec::new(), - } - } - fn collect_outlives_bound_spans<'tcx>( &self, tcx: TyCtxt<'tcx>, @@ -2213,41 +2194,11 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { let mut bound_count = 0; let mut lint_spans = Vec::new(); - - for param in hir_generics.params { - let has_lifetime_bounds = param - .bounds - .iter() - .any(|bound| matches!(bound, hir::GenericBound::Outlives(_))); - if !has_lifetime_bounds { - continue; - } - - let relevant_lifetimes = - self.collect_outlived_lifetimes(param, cx.tcx, inferred_outlives, ty_generics); - if relevant_lifetimes.is_empty() { - continue; - } - - let bound_spans = self.collect_outlives_bound_spans( - cx.tcx, - ¶m.bounds, - &relevant_lifetimes, - infer_static, - ); - bound_count += bound_spans.len(); - lint_spans.extend(self.consolidate_outlives_bound_spans( - param.span.shrink_to_hi(), - ¶m.bounds, - bound_spans, - )); - } - let mut where_lint_spans = Vec::new(); let mut dropped_predicate_count = 0; - let num_predicates = hir_generics.where_clause.predicates.len(); - for (i, where_predicate) in hir_generics.where_clause.predicates.iter().enumerate() { - let (relevant_lifetimes, bounds, span) = match where_predicate { + let num_predicates = hir_generics.predicates.len(); + for (i, where_predicate) in hir_generics.predicates.iter().enumerate() { + let (relevant_lifetimes, bounds, span, in_where_clause) = match where_predicate { hir::WherePredicate::RegionPredicate(predicate) => { if let Some(Region::EarlyBound(index, ..)) = cx.tcx.named_region(predicate.lifetime.hir_id) @@ -2256,6 +2207,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { Self::lifetimes_outliving_lifetime(inferred_outlives, index), &predicate.bounds, predicate.span, + predicate.in_where_clause, ) } else { continue; @@ -2274,6 +2226,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { Self::lifetimes_outliving_type(inferred_outlives, index), &predicate.bounds, predicate.span, + predicate.in_where_clause, ) } _ => { @@ -2300,10 +2253,12 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { dropped_predicate_count += 1; } - // If all the bounds on a predicate were inferable and there are - // further predicates, we want to eat the trailing comma. - if drop_predicate && i + 1 < num_predicates { - let next_predicate_span = hir_generics.where_clause.predicates[i + 1].span(); + if drop_predicate && !in_where_clause { + lint_spans.push(span); + } else if drop_predicate && i + 1 < num_predicates { + // If all the bounds on a predicate were inferable and there are + // further predicates, we want to eat the trailing comma. + let next_predicate_span = hir_generics.predicates[i + 1].span(); where_lint_spans.push(span.to(next_predicate_span.shrink_to_lo())); } else { where_lint_spans.extend(self.consolidate_outlives_bound_spans( @@ -2316,10 +2271,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { // If all predicates are inferable, drop the entire clause // (including the `where`) - if num_predicates > 0 && dropped_predicate_count == num_predicates { + if hir_generics.has_where_clause && dropped_predicate_count == num_predicates { let where_span = hir_generics - .where_clause - .span() + .where_clause_span() .expect("span of (nonempty) where clause should exist"); // Extend the where clause back to the closing `>` of the // generics, except for tuple struct, which have the `where` @@ -2346,7 +2300,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { }, lint_spans .into_iter() - .map(|span| (span, "".to_owned())) + .map(|span| (span, String::new())) .collect::<Vec<_>>(), Applicability::MachineApplicable, ) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 437104d1aaf..dfce30171ff 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1471,7 +1471,7 @@ impl InvalidAtomicOrdering { && let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() // skip extension traits, only lint functions from the standard library && cx.tcx.trait_id_of_impl(impl_did).is_none() - && let Some(parent) = cx.tcx.parent(adt.did()) + && let parent = cx.tcx.parent(adt.did()) && cx.tcx.is_diagnostic_item(sym::atomic_mod, parent) && ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did())) { @@ -1486,9 +1486,9 @@ impl InvalidAtomicOrdering { orderings.iter().any(|ordering| { tcx.item_name(did) == *ordering && { let parent = tcx.parent(did); - parent == atomic_ordering + Some(parent) == atomic_ordering // needed in case this is a ctor, not a variant - || parent.map_or(false, |parent| tcx.parent(parent) == atomic_ordering) + || tcx.opt_parent(parent) == atomic_ordering } }) } |
