Skip to content

Commit 5067f54

Browse files
committed
Intersection impls
check if the intersection impl is complete
1 parent a5c707a commit 5067f54

File tree

6 files changed

+197
-178
lines changed

6 files changed

+197
-178
lines changed

src/librustc/traits/coherence.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! See `README.md` for high-level documentation
11+
//! See rustc guide chapters on [trait-resolution] and [trait-specialization] for more info on how
12+
//! this works.
13+
//!
14+
//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html
15+
//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/trait-specialization.html
1216
1317
use hir::def_id::{DefId, LOCAL_CRATE};
1418
use syntax_pos::DUMMY_SP;
15-
use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause, Reveal};
19+
use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
1620
use traits::IntercrateMode;
1721
use traits::select::IntercrateAmbiguityCause;
1822
use ty::{self, Ty, TyCtxt};
@@ -119,7 +123,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
119123
// types into scope; instead, we replace the generic types with
120124
// fresh type variables, and hence we do our evaluations in an
121125
// empty environment.
122-
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
126+
let param_env = ty::ParamEnv::empty();
123127

124128
let a_impl_header = with_fresh_ty_vars(selcx, param_env, a_def_id);
125129
let b_impl_header = with_fresh_ty_vars(selcx, param_env, b_def_id);
@@ -136,7 +140,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
136140
Err(_) => return None
137141
};
138142

139-
debug!("overlap: unification check succeeded {:?}", obligations);
143+
debug!("overlap: unification check succeeded");
140144

141145
// Are any of the obligations unsatisfiable? If so, no overlap.
142146
let infcx = selcx.infcx();
@@ -277,7 +281,7 @@ pub fn orphan_check<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
277281
/// is bad, because the only local type with `T` as a subtree is
278282
/// `LocalType<T>`, and `Vec<->` is between it and the type parameter.
279283
/// - similarly, `FundamentalPair<LocalType<T>, T>` is bad, because
280-
/// the second occurence of `T` is not a subtree of *any* local type.
284+
/// the second occurrence of `T` is not a subtree of *any* local type.
281285
/// - however, `LocalType<Vec<T>>` is OK, because `T` is a subtree of
282286
/// `LocalType<Vec<T>>`, which is local and has no types between it and
283287
/// the type parameter.

src/librustc/traits/specialize/mod.rs

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,9 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
339339
for opt_overlap in opt_overlaps {
340340
overlaps.push((impl_def_id, opt_overlap));
341341
}
342-
},
343-
_ => {},
342+
}
343+
_ => {}
344344
};
345-
346345
} else {
347346
let parent = tcx.impl_parent(impl_def_id).unwrap_or(trait_id);
348347
sg.record_impl_from_cstore(tcx, parent, impl_def_id)
@@ -353,47 +352,55 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
353352
// Build the graph only if there is at least an overlap
354353
let (graph, nodes_idx) = sg.build_graph();
355354
for (impl_def_id, overlap) in overlaps {
356-
if !sg.check_overlap(&graph, &nodes_idx, impl_def_id, overlap.with_impl) {
357-
358-
let msg = format!("conflicting implementations of trait `{}`{}:{}",
355+
if !sg.check_overlap(&graph, &nodes_idx, impl_def_id, overlap.with_impl, tcx) {
356+
let msg = format!(
357+
"conflicting implementations of trait `{}`{}:{}",
359358
overlap.trait_desc,
360-
overlap.self_desc.clone().map_or(
361-
String::new(), |ty| {
362-
format!(" for type `{}`", ty)
363-
}),
364-
if overlap.used_to_be_allowed { " (E0119)" } else { "" }
365-
);
366-
let impl_span = tcx.sess.codemap().def_span(
367-
tcx.span_of_impl(impl_def_id).unwrap()
359+
overlap
360+
.self_desc
361+
.clone()
362+
.map_or(String::new(), |ty| format!(" for type `{}`", ty)),
363+
if overlap.used_to_be_allowed {
364+
" (E0119)"
365+
} else {
366+
""
367+
}
368368
);
369+
let impl_span = tcx.sess
370+
.codemap()
371+
.def_span(tcx.span_of_impl(impl_def_id).unwrap());
369372
let mut err = if overlap.used_to_be_allowed {
370373
tcx.struct_span_lint_node(
371374
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
372375
tcx.hir.as_local_node_id(impl_def_id).unwrap(),
373376
impl_span,
374-
&msg)
377+
&msg,
378+
)
375379
} else {
376-
struct_span_err!(tcx.sess,
377-
impl_span,
378-
E0119,
379-
"{}",
380-
msg)
380+
struct_span_err!(tcx.sess, impl_span, E0119, "{}", msg)
381381
};
382382

383383
match tcx.span_of_impl(overlap.with_impl) {
384384
Ok(span) => {
385-
err.span_label(tcx.sess.codemap().def_span(span),
386-
format!("first implementation here"));
387-
err.span_label(impl_span,
388-
format!("conflicting implementation{}",
389-
overlap.self_desc
390-
.map_or(String::new(),
391-
|ty| format!(" for `{}`", ty))));
385+
err.span_label(
386+
tcx.sess.codemap().def_span(span),
387+
format!("first implementation here"),
388+
);
389+
err.span_label(
390+
impl_span,
391+
format!(
392+
"conflicting implementation{}",
393+
overlap
394+
.self_desc
395+
.map_or(String::new(), |ty| format!(" for `{}`", ty))
396+
),
397+
);
392398
}
393399
Err(cname) => {
394400
let msg = match to_pretty_impl_header(tcx, overlap.with_impl) {
395-
Some(s) => format!(
396-
"conflicting implementation in crate `{}`:\n- {}", cname, s),
401+
Some(s) => {
402+
format!("conflicting implementation in crate `{}`:\n- {}", cname, s)
403+
}
397404
None => format!("conflicting implementation in crate `{}`", cname),
398405
};
399406
err.note(&msg);

0 commit comments

Comments
 (0)