1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 // The job of the coherence phase of typechecking is to ensure that
14 // each trait has at most one implementation for each type. This is
15 // done by the orphan and overlap modules. Then we build up various
16 // mappings. That mapping code resides here.
18 use hir
::def_id
::{CrateNum, DefId, LOCAL_CRATE}
;
19 use rustc
::ty
::{self, TyCtxt, TypeFoldable}
;
20 use rustc
::ty
::maps
::Providers
;
21 use rustc
::dep_graph
::DepNode
;
24 use syntax_pos
::DUMMY_SP
;
32 fn check_impl
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>, node_id
: ast
::NodeId
) {
33 let impl_def_id
= tcx
.hir
.local_def_id(node_id
);
35 // If there are no traits, then this implementation must have a
38 if let Some(trait_ref
) = tcx
.impl_trait_ref(impl_def_id
) {
39 debug
!("(checking implementation) adding impl for trait '{:?}', item '{}'",
41 tcx
.item_path_str(impl_def_id
));
43 // Skip impls where one of the self type is an error type.
44 // This occurs with e.g. resolve failures (#30589).
45 if trait_ref
.references_error() {
49 enforce_trait_manually_implementable(tcx
, impl_def_id
, trait_ref
.def_id
);
50 let trait_def
= tcx
.lookup_trait_def(trait_ref
.def_id
);
51 trait_def
.record_local_impl(tcx
, impl_def_id
, trait_ref
);
55 fn enforce_trait_manually_implementable(tcx
: TyCtxt
, impl_def_id
: DefId
, trait_def_id
: DefId
) {
56 let did
= Some(trait_def_id
);
57 let li
= &tcx
.lang_items
;
59 // Disallow *all* explicit impls of `Sized` and `Unsize` for now.
60 if did
== li
.sized_trait() {
61 let span
= tcx
.span_of_impl(impl_def_id
).unwrap();
62 struct_span_err
!(tcx
.sess
,
65 "explicit impls for the `Sized` trait are not permitted")
66 .span_label(span
, &format
!("impl of 'Sized' not allowed"))
71 if did
== li
.unsize_trait() {
72 let span
= tcx
.span_of_impl(impl_def_id
).unwrap();
76 "explicit impls for the `Unsize` trait are not permitted");
80 if tcx
.sess
.features
.borrow().unboxed_closures
{
81 // the feature gate allows all Fn traits
85 let trait_name
= if did
== li
.fn_trait() {
87 } else if did
== li
.fn_mut_trait() {
89 } else if did
== li
.fn_once_trait() {
92 return; // everything OK
94 let mut err
= struct_span_err
!(tcx
.sess
,
95 tcx
.span_of_impl(impl_def_id
).unwrap(),
97 "manual implementations of `{}` are experimental",
100 "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
104 pub fn provide(providers
: &mut Providers
) {
105 *providers
= Providers
{
107 coherent_inherent_impls
,
112 fn coherent_trait
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
113 (_
, def_id
): (CrateNum
, DefId
)) {
114 tcx
.populate_implementations_for_trait_if_necessary(def_id
);
116 let impls
= tcx
.hir
.trait_impls(def_id
);
117 for &impl_id
in impls
{
118 check_impl(tcx
, impl_id
);
120 for &impl_id
in impls
{
121 overlap
::check_impl(tcx
, impl_id
);
123 builtin
::check_trait(tcx
, def_id
);
126 fn coherent_inherent_impls
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>, _
: CrateNum
) {
127 inherent
::check(tcx
);
130 pub fn check_coherence
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>) {
131 let _task
= tcx
.dep_graph
.in_task(DepNode
::Coherence
);
132 for &trait_def_id
in tcx
.hir
.krate().trait_impls
.keys() {
133 ty
::queries
::coherent_trait
::get(tcx
, DUMMY_SP
, (LOCAL_CRATE
, trait_def_id
));
136 unsafety
::check(tcx
);
138 overlap
::check_default_impls(tcx
);
140 ty
::queries
::coherent_inherent_impls
::get(tcx
, DUMMY_SP
, LOCAL_CRATE
);