Skip to content

Commit 3bb2ff0

Browse files
leoyvenspetrochenkov
authored andcommitted
Move coherence/overlap.rs into coherence/mod.rs
`fn check_impl` was feeling lonely with a file all for itself.
1 parent edd52b1 commit 3bb2ff0

File tree

2 files changed

+45
-60
lines changed

2 files changed

+45
-60
lines changed

src/librustc_typeck/coherence/mod.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// mappings. That mapping code resides here.
1717

1818
use hir::def_id::{DefId, LOCAL_CRATE};
19+
use rustc::traits;
1920
use rustc::ty::{self, TyCtxt, TypeFoldable};
2021
use rustc::ty::maps::Providers;
2122

@@ -25,7 +26,6 @@ mod builtin;
2526
mod inherent_impls;
2627
mod inherent_impls_overlap;
2728
mod orphan;
28-
mod overlap;
2929
mod unsafety;
3030

3131
fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
@@ -119,7 +119,7 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
119119
check_impl(tcx, impl_id);
120120
}
121121
for &impl_id in impls {
122-
overlap::check_impl(tcx, impl_id);
122+
check_impl_overlap(tcx, impl_id);
123123
}
124124
builtin::check_trait(tcx, def_id);
125125
}
@@ -136,3 +136,46 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
136136
ty::maps::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
137137
ty::maps::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE);
138138
}
139+
140+
/// Overlap: No two impls for the same trait are implemented for the
141+
/// same type. Likewise, no two inherent impls for a given type
142+
/// constructor provide a method with the same name.
143+
fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
144+
let impl_def_id = tcx.hir.local_def_id(node_id);
145+
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
146+
let trait_def_id = trait_ref.def_id;
147+
148+
if trait_ref.references_error() {
149+
debug!("coherence: skipping impl {:?} with error {:?}",
150+
impl_def_id, trait_ref);
151+
return
152+
}
153+
154+
// Trigger building the specialization graph for the trait of this impl.
155+
// This will detect any overlap errors.
156+
tcx.specialization_graph_of(trait_def_id);
157+
158+
// check for overlap with the automatic `impl Trait for Trait`
159+
if let ty::TyDynamic(ref data, ..) = trait_ref.self_ty().sty {
160+
// This is something like impl Trait1 for Trait2. Illegal
161+
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
162+
163+
if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
164+
// This is an error, but it will be reported by wfcheck. Ignore it here.
165+
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
166+
} else {
167+
let mut supertrait_def_ids =
168+
traits::supertrait_def_ids(tcx,
169+
data.principal().unwrap().def_id());
170+
if supertrait_def_ids.any(|d| d == trait_def_id) {
171+
span_err!(tcx.sess,
172+
tcx.span_of_impl(impl_def_id).unwrap(),
173+
E0371,
174+
"the object type `{}` automatically \
175+
implements the trait `{}`",
176+
trait_ref.self_ty(),
177+
tcx.item_path_str(trait_def_id));
178+
}
179+
}
180+
}
181+
}

src/librustc_typeck/coherence/overlap.rs

Lines changed: 0 additions & 58 deletions
This file was deleted.

0 commit comments

Comments
 (0)