mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Lint now-unnecessary associated type bounds
This commit is contained in:
parent
ca581f9161
commit
a49b736568
@ -288,6 +288,11 @@ hir_analysis_unrecognized_intrinsic_function =
|
|||||||
unrecognized intrinsic function: `{$name}`
|
unrecognized intrinsic function: `{$name}`
|
||||||
.label = unrecognized intrinsic
|
.label = unrecognized intrinsic
|
||||||
|
|
||||||
|
hir_analysis_unused_associated_type_bounds =
|
||||||
|
unnecessary associated type bound for not object safe associated type
|
||||||
|
.note = this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
|
||||||
|
.suggestion = remove this bound
|
||||||
|
|
||||||
hir_analysis_value_of_associated_struct_already_specified =
|
hir_analysis_value_of_associated_struct_already_specified =
|
||||||
the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified
|
the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified
|
||||||
.label = re-bound here
|
.label = re-bound here
|
||||||
|
@ -29,6 +29,7 @@ use rustc_hir::intravisit::{walk_generics, Visitor as _};
|
|||||||
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
|
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
|
||||||
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
|
use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
|
||||||
use rustc_middle::middle::stability::AllowUnstable;
|
use rustc_middle::middle::stability::AllowUnstable;
|
||||||
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
|
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
|
||||||
use rustc_middle::ty::DynKind;
|
use rustc_middle::ty::DynKind;
|
||||||
@ -929,6 +930,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
fn conv_object_ty_poly_trait_ref(
|
fn conv_object_ty_poly_trait_ref(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
hir_id: hir::HirId,
|
||||||
hir_trait_bounds: &[hir::PolyTraitRef<'_>],
|
hir_trait_bounds: &[hir::PolyTraitRef<'_>],
|
||||||
lifetime: &hir::Lifetime,
|
lifetime: &hir::Lifetime,
|
||||||
borrowed: bool,
|
borrowed: bool,
|
||||||
@ -1125,9 +1127,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
// So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
|
// So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
|
||||||
// types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
|
// types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
|
||||||
// corresponding `Projection` clause
|
// corresponding `Projection` clause
|
||||||
for (projection_bound, _) in &projection_bounds {
|
for (projection_bound, span) in &projection_bounds {
|
||||||
for def_ids in associated_types.values_mut() {
|
for def_ids in associated_types.values_mut() {
|
||||||
def_ids.remove(&projection_bound.projection_def_id());
|
let def_id = projection_bound.projection_def_id();
|
||||||
|
def_ids.remove(&def_id);
|
||||||
|
if tcx.generics_require_sized_self(def_id) {
|
||||||
|
tcx.emit_spanned_lint(
|
||||||
|
UNUSED_ASSOCIATED_TYPE_BOUNDS,
|
||||||
|
hir_id,
|
||||||
|
*span,
|
||||||
|
crate::errors::UnusedAssociatedTypeBounds { span: *span },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2812,7 +2823,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
TraitObjectSyntax::DynStar => ty::DynStar,
|
TraitObjectSyntax::DynStar => ty::DynStar,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
|
self.conv_object_ty_poly_trait_ref(
|
||||||
|
ast_ty.span,
|
||||||
|
ast_ty.hir_id,
|
||||||
|
bounds,
|
||||||
|
lifetime,
|
||||||
|
borrowed,
|
||||||
|
repr,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
||||||
debug!(?maybe_qself, ?path);
|
debug!(?maybe_qself, ?path);
|
||||||
|
@ -5,7 +5,7 @@ use rustc_errors::{
|
|||||||
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
|
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
|
||||||
MultiSpan,
|
MultiSpan,
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::{self, print::TraitRefPrintOnlyTraitPath, Ty};
|
use rustc_middle::ty::{self, print::TraitRefPrintOnlyTraitPath, Ty};
|
||||||
use rustc_span::{symbol::Ident, Span, Symbol};
|
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||||
|
|
||||||
@ -900,3 +900,11 @@ pub(crate) enum LateBoundInApit {
|
|||||||
param_span: Span,
|
param_span: Span,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(hir_analysis_unused_associated_type_bounds)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnusedAssociatedTypeBounds {
|
||||||
|
#[suggestion(code = "")]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
@ -3468,6 +3468,32 @@ declare_lint! {
|
|||||||
report_in_external_macro
|
report_in_external_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `unused_associated_type_bounds` lint is emitted when an
|
||||||
|
/// associated type bound is added to a trait object, but the associated
|
||||||
|
/// type has a `where Self: Sized` bound, and is thus unavailable on the
|
||||||
|
/// trait object anyway.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// trait Foo {
|
||||||
|
/// type Bar where Self: Sized;
|
||||||
|
/// }
|
||||||
|
/// type Mop = dyn Foo<Bar = ()>;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// Just like methods with `Self: Sized` bounds are unavailable on trait
|
||||||
|
/// objects, associated types can be removed from the trait object.
|
||||||
|
pub UNUSED_ASSOCIATED_TYPE_BOUNDS,
|
||||||
|
Warn,
|
||||||
|
"detects unused `Foo = Bar` bounds in `dyn Trait<Foo = Bar>`"
|
||||||
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `unused_doc_comments` lint detects doc comments that aren't used
|
/// The `unused_doc_comments` lint detects doc comments that aren't used
|
||||||
/// by `rustdoc`.
|
/// by `rustdoc`.
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
type Bar
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(_: &dyn Foo<Bar = ()>) {}
|
||||||
|
//~^ WARN: unnecessary associated type bound for not object safe associated type
|
||||||
|
//~| WARN: unnecessary associated type bound for not object safe associated type
|
||||||
|
//~| WARN: unnecessary associated type bound for not object safe associated type
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,27 @@
|
|||||||
|
warning: unnecessary associated type bound for not object safe associated type
|
||||||
|
--> $DIR/assoc_type_bounds_sized_unnecessary.rs:9:20
|
||||||
|
|
|
||||||
|
LL | fn foo(_: &dyn Foo<Bar = ()>) {}
|
||||||
|
| ^^^^^^^^ help: remove this bound
|
||||||
|
|
|
||||||
|
= note: this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
|
||||||
|
= note: `#[warn(unused_associated_type_bounds)]` on by default
|
||||||
|
|
||||||
|
warning: unnecessary associated type bound for not object safe associated type
|
||||||
|
--> $DIR/assoc_type_bounds_sized_unnecessary.rs:9:20
|
||||||
|
|
|
||||||
|
LL | fn foo(_: &dyn Foo<Bar = ()>) {}
|
||||||
|
| ^^^^^^^^ help: remove this bound
|
||||||
|
|
|
||||||
|
= note: this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
|
||||||
|
|
||||||
|
warning: unnecessary associated type bound for not object safe associated type
|
||||||
|
--> $DIR/assoc_type_bounds_sized_unnecessary.rs:9:20
|
||||||
|
|
|
||||||
|
LL | fn foo(_: &dyn Foo<Bar = ()>) {}
|
||||||
|
| ^^^^^^^^ help: remove this bound
|
||||||
|
|
|
||||||
|
= note: this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
|
||||||
|
|
||||||
|
warning: 3 warnings emitted
|
||||||
|
|
Loading…
Reference in New Issue
Block a user