Skip to content

Commit 0c03a88

Browse files
committed
run compare method in old-broken-way and new-good-way
1 parent 84ac618 commit 0c03a88

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

src/librustc_typeck/check/compare_method.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use rustc::infer::{self, InferOk, TypeOrigin};
12+
use rustc::middle::free_region::FreeRegionMap;
1213
use rustc::ty;
1314
use rustc::traits::{self, Reveal};
1415
use rustc::ty::error::{ExpectedFound, TypeError};
@@ -39,8 +40,10 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
3940
impl_m_body_id: ast::NodeId,
4041
trait_m: &ty::Method<'tcx>,
4142
impl_trait_ref: &ty::TraitRef<'tcx>,
42-
trait_item_span: Option<Span>) {
43-
debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref);
43+
trait_item_span: Option<Span>,
44+
old_broken_mode: bool) {
45+
debug!("compare_impl_method(impl_trait_ref={:?})",
46+
impl_trait_ref);
4447

4548
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
4649
impl_trait_ref);
@@ -367,7 +370,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
367370
item_name: impl_m.name,
368371
impl_item_def_id: impl_m.def_id,
369372
trait_item_def_id: trait_m.def_id,
370-
lint_id: Some(impl_m_body_id),
373+
lint_id: if !old_broken_mode { Some(impl_m_body_id) } else { None },
371374
},
372375
};
373376

@@ -473,8 +476,20 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
473476

474477
// Finally, resolve all regions. This catches wily misuses of
475478
// lifetime parameters.
476-
let fcx = FnCtxt::new(&inh, tcx.types.err, impl_m_body_id);
477-
fcx.regionck_item(impl_m_body_id, impl_m_span, &[]);
479+
if old_broken_mode {
480+
// FIXME(#18937) -- this is how the code used to
481+
// work. This is buggy because the fulfillment cx creates
482+
// region obligations that get overlooked. The right
483+
// thing to do is the code below. But we keep this old
484+
// pass around temporarily.
485+
let mut free_regions = FreeRegionMap::new();
486+
free_regions.relate_free_regions_from_predicates(
487+
&infcx.parameter_environment.caller_bounds);
488+
infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id);
489+
} else {
490+
let fcx = FnCtxt::new(&inh, tcx.types.err, impl_m_body_id);
491+
fcx.regionck_item(impl_m_body_id, impl_m_span, &[]);
492+
}
478493
});
479494

480495
fn check_region_bounds_on_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,

src/librustc_typeck/check/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,13 +1028,26 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
10281028

10291029
let trait_span = tcx.map.span_if_local(ty_trait_item.def_id());
10301030
if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
1031+
let err_count = tcx.sess.err_count();
10311032
compare_impl_method(ccx,
10321033
&impl_method,
10331034
impl_item.span,
10341035
body.id,
10351036
&trait_method,
10361037
&impl_trait_ref,
1037-
trait_span);
1038+
trait_span,
1039+
true); // start with old-broken-mode
1040+
if err_count == tcx.sess.err_count() {
1041+
// old broken mode did not report an error. Try with the new mode.
1042+
compare_impl_method(ccx,
1043+
&impl_method,
1044+
impl_item.span,
1045+
body.id,
1046+
&trait_method,
1047+
&impl_trait_ref,
1048+
trait_span,
1049+
false); // use the new mode
1050+
}
10381051
} else {
10391052
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
10401053
"item `{}` is an associated method, \

0 commit comments

Comments
 (0)