3 // The job of the coherence phase of typechecking is to ensure that
4 // each trait has at most one implementation for each type. This is
5 // done by the orphan and overlap modules. Then we build up various
6 // mappings. That mapping code resides here.
8 use rustc_errors
::{error_code, struct_span_err}
;
9 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
10 use rustc_middle
::ty
::query
::Providers
;
11 use rustc_middle
::ty
::{self, TyCtxt, TypeVisitableExt}
;
13 use rustc_trait_selection
::traits
;
17 mod inherent_impls_overlap
;
21 fn check_impl(tcx
: TyCtxt
<'_
>, impl_def_id
: LocalDefId
, trait_ref
: ty
::TraitRef
<'_
>) {
23 "(checking implementation) adding impl for trait '{:?}', item '{}'",
25 tcx
.def_path_str(impl_def_id
.to_def_id())
28 // Skip impls where one of the self type is an error type.
29 // This occurs with e.g., resolve failures (#30589).
30 if trait_ref
.references_error() {
34 enforce_trait_manually_implementable(tcx
, impl_def_id
, trait_ref
.def_id
);
35 enforce_empty_impls_for_marker_traits(tcx
, impl_def_id
, trait_ref
.def_id
);
38 fn enforce_trait_manually_implementable(
40 impl_def_id
: LocalDefId
,
43 let impl_header_span
= tcx
.def_span(impl_def_id
);
45 // Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
46 if tcx
.has_attr(trait_def_id
, sym
::rustc_deny_explicit_impl
) {
47 let trait_name
= tcx
.item_name(trait_def_id
);
48 let mut err
= struct_span_err
!(
52 "explicit impls for the `{trait_name}` trait are not permitted"
54 err
.span_label(impl_header_span
, format
!("impl of `{trait_name}` not allowed"));
56 // Maintain explicit error code for `Unsize`, since it has a useful
57 // explanation about using `CoerceUnsized` instead.
58 if Some(trait_def_id
) == tcx
.lang_items().unsize_trait() {
59 err
.code(error_code
!(E0328
));
66 if let ty
::trait_def
::TraitSpecializationKind
::AlwaysApplicable
=
67 tcx
.trait_def(trait_def_id
).specialization_kind
69 if !tcx
.features().specialization
&& !tcx
.features().min_specialization
{
73 "implementing `rustc_specialization_trait` traits is unstable",
75 .help("add `#![feature(min_specialization)]` to the crate attributes to enable")
82 /// We allow impls of marker traits to overlap, so they can't override impls
83 /// as that could make it ambiguous which associated item to use.
84 fn enforce_empty_impls_for_marker_traits(
86 impl_def_id
: LocalDefId
,
89 if !tcx
.trait_def(trait_def_id
).is_marker
{
93 if tcx
.associated_item_def_ids(trait_def_id
).is_empty() {
99 tcx
.def_span(impl_def_id
),
101 "impls for marker traits cannot contain items"
106 pub fn provide(providers
: &mut Providers
) {
107 use self::builtin
::coerce_unsized_info
;
108 use self::inherent_impls
::{crate_incoherent_impls, crate_inherent_impls, inherent_impls}
;
109 use self::inherent_impls_overlap
::crate_inherent_impls_overlap_check
;
110 use self::orphan
::orphan_check_impl
;
112 *providers
= Providers
{
114 crate_inherent_impls
,
115 crate_incoherent_impls
,
117 crate_inherent_impls_overlap_check
,
124 fn coherent_trait(tcx
: TyCtxt
<'_
>, def_id
: DefId
) {
125 // Trigger building the specialization graph for the trait. This will detect and report any
127 tcx
.ensure().specialization_graph_of(def_id
);
129 let impls
= tcx
.hir().trait_impls(def_id
);
130 for &impl_def_id
in impls
{
131 let trait_ref
= tcx
.impl_trait_ref(impl_def_id
).unwrap().subst_identity();
133 check_impl(tcx
, impl_def_id
, trait_ref
);
134 check_object_overlap(tcx
, impl_def_id
, trait_ref
);
136 unsafety
::check_item(tcx
, impl_def_id
);
137 tcx
.ensure().orphan_check_impl(impl_def_id
);
140 builtin
::check_trait(tcx
, def_id
);
143 /// Checks whether an impl overlaps with the automatic `impl Trait for dyn Trait`.
144 fn check_object_overlap
<'tcx
>(
146 impl_def_id
: LocalDefId
,
147 trait_ref
: ty
::TraitRef
<'tcx
>,
149 let trait_def_id
= trait_ref
.def_id
;
151 if trait_ref
.references_error() {
152 debug
!("coherence: skipping impl {:?} with error {:?}", impl_def_id
, trait_ref
);
156 // check for overlap with the automatic `impl Trait for dyn Trait`
157 if let ty
::Dynamic(data
, ..) = trait_ref
.self_ty().kind() {
158 // This is something like impl Trait1 for Trait2. Illegal
159 // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
161 let component_def_ids
= data
.iter().flat_map(|predicate
| {
162 match predicate
.skip_binder() {
163 ty
::ExistentialPredicate
::Trait(tr
) => Some(tr
.def_id
),
164 ty
::ExistentialPredicate
::AutoTrait(def_id
) => Some(def_id
),
165 // An associated type projection necessarily comes with
166 // an additional `Trait` requirement.
167 ty
::ExistentialPredicate
::Projection(..) => None
,
171 for component_def_id
in component_def_ids
{
172 if !tcx
.check_is_object_safe(component_def_id
) {
173 // Without the 'object_safe_for_dispatch' feature this is an error
174 // which will be reported by wfcheck. Ignore it here.
175 // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
176 // With the feature enabled, the trait is not implemented automatically,
179 let mut supertrait_def_ids
= traits
::supertrait_def_ids(tcx
, component_def_id
);
180 if supertrait_def_ids
.any(|d
| d
== trait_def_id
) {
181 let span
= tcx
.def_span(impl_def_id
);
186 "the object type `{}` automatically implements the trait `{}`",
188 tcx
.def_path_str(trait_def_id
)
193 "`{}` automatically implements trait `{}`",
195 tcx
.def_path_str(trait_def_id
)