|
4 | 4 | //! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
|
5 | 5 | //! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
|
6 | 6 |
|
| 7 | +use infer::CombinedSnapshot; |
7 | 8 | use hir::def_id::{DefId, LOCAL_CRATE};
|
8 | 9 | use syntax_pos::DUMMY_SP;
|
9 | 10 | use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
|
@@ -33,6 +34,17 @@ pub enum Conflict {
|
33 | 34 | pub struct OverlapResult<'tcx> {
|
34 | 35 | pub impl_header: ty::ImplHeader<'tcx>,
|
35 | 36 | pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>,
|
| 37 | + |
| 38 | + /// True if the overlap might've been permitted before the shift |
| 39 | + /// to universes. |
| 40 | + pub involves_placeholder: bool, |
| 41 | +} |
| 42 | + |
| 43 | +pub fn add_placeholder_note(err: &mut ::errors::DiagnosticBuilder<'_>) { |
| 44 | + err.note(&format!( |
| 45 | + "this behavior recently changed as a result of a bug fix; \ |
| 46 | + see rust-lang/rust#56105 for details" |
| 47 | + )); |
36 | 48 | }
|
37 | 49 |
|
38 | 50 | /// If there are types that satisfy both impls, invokes `on_overlap`
|
@@ -104,13 +116,22 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, '
|
104 | 116 |
|
105 | 117 | /// Can both impl `a` and impl `b` be satisfied by a common type (including
|
106 | 118 | /// `where` clauses)? If so, returns an `ImplHeader` that unifies the two impls.
|
107 |
| -fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, |
108 |
| - a_def_id: DefId, |
109 |
| - b_def_id: DefId) |
110 |
| - -> Option<OverlapResult<'tcx>> |
111 |
| -{ |
| 119 | +fn overlap<'cx, 'gcx, 'tcx>( |
| 120 | + selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, |
| 121 | + a_def_id: DefId, |
| 122 | + b_def_id: DefId, |
| 123 | +) -> Option<OverlapResult<'tcx>> { |
112 | 124 | debug!("overlap(a_def_id={:?}, b_def_id={:?})", a_def_id, b_def_id);
|
113 | 125 |
|
| 126 | + selcx.infcx().probe(|snapshot| overlap_within_probe(selcx, a_def_id, b_def_id, snapshot)) |
| 127 | +} |
| 128 | + |
| 129 | +fn overlap_within_probe( |
| 130 | + selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, |
| 131 | + a_def_id: DefId, |
| 132 | + b_def_id: DefId, |
| 133 | + snapshot: &CombinedSnapshot<'_, 'tcx>, |
| 134 | +) -> Option<OverlapResult<'tcx>> { |
114 | 135 | // For the purposes of this check, we don't bring any placeholder
|
115 | 136 | // types into scope; instead, we replace the generic types with
|
116 | 137 | // fresh type variables, and hence we do our evaluations in an
|
@@ -158,7 +179,13 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
158 | 179 | let impl_header = selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
|
159 | 180 | let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
|
160 | 181 | debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
|
161 |
| - Some(OverlapResult { impl_header, intercrate_ambiguity_causes }) |
| 182 | + |
| 183 | + let involves_placeholder = match selcx.infcx().region_constraints_added_in_snapshot(snapshot) { |
| 184 | + Some(true) => true, |
| 185 | + _ => false, |
| 186 | + }; |
| 187 | + |
| 188 | + Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder }) |
162 | 189 | }
|
163 | 190 |
|
164 | 191 | pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|
0 commit comments