Skip to content

Commit 9e0171f

Browse files
committed
remove vestiges of the old suggestion machinery
1 parent 5167ac8 commit 9e0171f

File tree

6 files changed

+117
-260
lines changed

6 files changed

+117
-260
lines changed

src/librustc/infer/error_reporting.rs

+24-221
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,6 @@ use super::region_inference::ConcreteFailure;
6565
use super::region_inference::SubSupConflict;
6666
use super::region_inference::GenericBoundFailure;
6767
use super::region_inference::GenericKind;
68-
use super::region_inference::ProcessedErrors;
69-
use super::region_inference::ProcessedErrorOrigin;
70-
use super::region_inference::SameRegions;
7168

7269
use hir::map as hir_map;
7370
use hir;
@@ -77,11 +74,10 @@ use infer;
7774
use middle::region;
7875
use traits::{ObligationCause, ObligationCauseCode};
7976
use ty::{self, TyCtxt, TypeFoldable};
80-
use ty::{Region, ReFree, Issue32330};
77+
use ty::{Region, Issue32330};
8178
use ty::error::TypeError;
8279

8380
use std::fmt;
84-
use syntax::ast;
8581
use syntax_pos::{Pos, Span};
8682
use errors::DiagnosticBuilder;
8783

@@ -255,8 +251,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
255251

256252
// try to pre-process the errors, which will group some of them
257253
// together into a `ProcessedErrors` group:
258-
let processed_errors = self.process_errors(errors);
259-
let errors = processed_errors.as_ref().unwrap_or(errors);
254+
let errors = self.process_errors(errors);
260255

261256
debug!("report_region_errors: {} errors after preprocessing", errors.len());
262257

@@ -278,13 +273,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
278273
sub_origin, sub_r,
279274
sup_origin, sup_r);
280275
}
281-
282-
ProcessedErrors(ref origins,
283-
ref same_regions) => {
284-
if !same_regions.is_empty() {
285-
self.report_processed_errors(origins);
286-
}
287-
}
288276
}
289277
}
290278
}
@@ -300,202 +288,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
300288
// duplicates that will be unhelpful to the end-user. But
301289
// obviously it never weeds out ALL errors.
302290
fn process_errors(&self, errors: &Vec<RegionResolutionError<'tcx>>)
303-
-> Option<Vec<RegionResolutionError<'tcx>>> {
291+
-> Vec<RegionResolutionError<'tcx>> {
304292
debug!("process_errors()");
305-
let mut origins = Vec::new();
306-
307-
// we collect up ConcreteFailures and SubSupConflicts that are
308-
// relating free-regions bound on the fn-header and group them
309-
// together into this vector
310-
let mut same_regions = Vec::new();
311-
312-
// here we put errors that we will not be able to process nicely
313-
let mut other_errors = Vec::new();
314-
315-
// we collect up GenericBoundFailures in here.
316-
let mut bound_failures = Vec::new();
317-
318-
for error in errors {
319-
// Check whether we can process this error into some other
320-
// form; if not, fall through.
321-
match *error {
322-
ConcreteFailure(ref origin, sub, sup) => {
323-
debug!("processing ConcreteFailure");
324-
if let SubregionOrigin::CompareImplMethodObligation { .. } = *origin {
325-
// When comparing an impl method against a
326-
// trait method, it is not helpful to suggest
327-
// changes to the impl method. This is
328-
// because the impl method signature is being
329-
// checked using the trait's environment, so
330-
// usually the changes we suggest would
331-
// actually have to be applied to the *trait*
332-
// method (and it's not clear that the trait
333-
// method is even under the user's control).
334-
} else if let Some(same_frs) = free_regions_from_same_fn(self.tcx, sub, sup) {
335-
origins.push(
336-
ProcessedErrorOrigin::ConcreteFailure(
337-
origin.clone(),
338-
sub,
339-
sup));
340-
append_to_same_regions(&mut same_regions, &same_frs);
341-
continue;
342-
}
343-
}
344-
SubSupConflict(ref var_origin, ref sub_origin, sub, ref sup_origin, sup) => {
345-
debug!("processing SubSupConflict sub: {:?} sup: {:?}", sub, sup);
346-
match (sub_origin, sup_origin) {
347-
(&SubregionOrigin::CompareImplMethodObligation { .. }, _) => {
348-
// As above, when comparing an impl method
349-
// against a trait method, it is not helpful
350-
// to suggest changes to the impl method.
351-
}
352-
(_, &SubregionOrigin::CompareImplMethodObligation { .. }) => {
353-
// See above.
354-
}
355-
_ => {
356-
if let Some(same_frs) = free_regions_from_same_fn(self.tcx, sub, sup) {
357-
origins.push(
358-
ProcessedErrorOrigin::VariableFailure(
359-
var_origin.clone()));
360-
append_to_same_regions(&mut same_regions, &same_frs);
361-
continue;
362-
}
363-
}
364-
}
365-
}
366-
GenericBoundFailure(ref origin, ref kind, region) => {
367-
bound_failures.push((origin.clone(), kind.clone(), region));
368-
continue;
369-
}
370-
ProcessedErrors(..) => {
371-
bug!("should not encounter a `ProcessedErrors` yet: {:?}", error)
372-
}
373-
}
374-
375-
// No changes to this error.
376-
other_errors.push(error.clone());
377-
}
378-
379-
// ok, let's pull together the errors, sorted in an order that
380-
// we think will help user the best
381-
let mut processed_errors = vec![];
382-
383-
// first, put the processed errors, if any
384-
if !same_regions.is_empty() {
385-
let common_scope_id = same_regions[0].scope_id;
386-
for sr in &same_regions {
387-
// Since ProcessedErrors is used to reconstruct the function
388-
// declaration, we want to make sure that they are, in fact,
389-
// from the same scope
390-
if sr.scope_id != common_scope_id {
391-
debug!("returning empty result from process_errors because
392-
{} != {}", sr.scope_id, common_scope_id);
393-
return None;
394-
}
395-
}
396-
assert!(origins.len() > 0);
397-
let pe = ProcessedErrors(origins, same_regions);
398-
debug!("errors processed: {:?}", pe);
399-
processed_errors.push(pe);
400-
}
401-
402-
// next, put the other misc errors
403-
processed_errors.extend(other_errors);
404-
405-
// finally, put the `T: 'a` errors, but only if there were no
406-
// other errors. otherwise, these have a very high rate of
407-
// being unhelpful in practice. This is because they are
408-
// basically secondary checks that test the state of the
409-
// region graph after the rest of inference is done, and the
410-
// other kinds of errors indicate that the region constraint
411-
// graph is internally inconsistent, so these test results are
412-
// likely to be meaningless.
413-
if processed_errors.is_empty() {
414-
for (origin, kind, region) in bound_failures {
415-
processed_errors.push(GenericBoundFailure(origin, kind, region));
416-
}
417-
}
418293

419-
// we should always wind up with SOME errors, unless there were no
420-
// errors to start
421-
assert!(if errors.len() > 0 {processed_errors.len() > 0} else {true});
422-
423-
return Some(processed_errors);
424-
425-
#[derive(Debug)]
426-
struct FreeRegionsFromSameFn {
427-
sub_fr: ty::FreeRegion,
428-
sup_fr: ty::FreeRegion,
429-
scope_id: ast::NodeId
430-
}
431-
432-
impl FreeRegionsFromSameFn {
433-
fn new(sub_fr: ty::FreeRegion,
434-
sup_fr: ty::FreeRegion,
435-
scope_id: ast::NodeId)
436-
-> FreeRegionsFromSameFn {
437-
FreeRegionsFromSameFn {
438-
sub_fr: sub_fr,
439-
sup_fr: sup_fr,
440-
scope_id: scope_id
441-
}
442-
}
443-
}
444-
445-
fn free_regions_from_same_fn<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
446-
sub: &'tcx Region,
447-
sup: &'tcx Region)
448-
-> Option<FreeRegionsFromSameFn> {
449-
debug!("free_regions_from_same_fn(sub={:?}, sup={:?})", sub, sup);
450-
let (scope_id, fr1, fr2) = match (sub, sup) {
451-
(&ReFree(fr1), &ReFree(fr2)) => {
452-
if fr1.scope != fr2.scope {
453-
return None
454-
}
455-
assert!(fr1.scope == fr2.scope);
456-
(fr1.scope.node_id(&tcx.region_maps), fr1, fr2)
457-
},
458-
_ => return None
459-
};
460-
let parent = tcx.hir.get_parent(scope_id);
461-
let parent_node = tcx.hir.find(parent);
462-
match parent_node {
463-
Some(node) => match node {
464-
hir_map::NodeItem(item) => match item.node {
465-
hir::ItemFn(..) => {
466-
Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id))
467-
},
468-
_ => None
469-
},
470-
hir_map::NodeImplItem(..) |
471-
hir_map::NodeTraitItem(..) => {
472-
Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id))
473-
},
474-
_ => None
475-
},
476-
None => {
477-
debug!("no parent node of scope_id {}", scope_id);
478-
None
479-
}
480-
}
481-
}
294+
// We want to avoid reporting generic-bound failures if we can
295+
// avoid it: these have a very high rate of being unhelpful in
296+
// practice. This is because they are basically secondary
297+
// checks that test the state of the region graph after the
298+
// rest of inference is done, and the other kinds of errors
299+
// indicate that the region constraint graph is internally
300+
// inconsistent, so these test results are likely to be
301+
// meaningless.
302+
//
303+
// Therefore, we filter them out of the list unless they are
304+
// the only thing in the list.
305+
306+
let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e {
307+
ConcreteFailure(..) => false,
308+
SubSupConflict(..) => false,
309+
GenericBoundFailure(..) => true,
310+
};
482311

483-
fn append_to_same_regions(same_regions: &mut Vec<SameRegions>,
484-
same_frs: &FreeRegionsFromSameFn) {
485-
debug!("append_to_same_regions(same_regions={:?}, same_frs={:?})",
486-
same_regions, same_frs);
487-
let scope_id = same_frs.scope_id;
488-
let (sub_fr, sup_fr) = (same_frs.sub_fr, same_frs.sup_fr);
489-
for sr in same_regions.iter_mut() {
490-
if sr.contains(&sup_fr.bound_region) && scope_id == sr.scope_id {
491-
sr.push(sub_fr.bound_region);
492-
return
493-
}
494-
}
495-
same_regions.push(SameRegions {
496-
scope_id: scope_id,
497-
regions: vec![sub_fr.bound_region, sup_fr.bound_region]
498-
})
312+
if errors.iter().all(|e| is_bound_failure(e)) {
313+
errors.clone()
314+
} else {
315+
errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
499316
}
500317
}
501318

@@ -1072,20 +889,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1072889
self.note_region_origin(&mut err, &sub_origin);
1073890
err.emit();
1074891
}
1075-
1076-
fn report_processed_errors(&self,
1077-
origins: &[ProcessedErrorOrigin<'tcx>]) {
1078-
for origin in origins.iter() {
1079-
let mut err = match *origin {
1080-
ProcessedErrorOrigin::VariableFailure(ref var_origin) =>
1081-
self.report_inference_failure(var_origin.clone()),
1082-
ProcessedErrorOrigin::ConcreteFailure(ref sr_origin, sub, sup) =>
1083-
self.report_concrete_failure(sr_origin.clone(), sub, sup),
1084-
};
1085-
1086-
err.emit();
1087-
}
1088-
}
1089892
}
1090893

1091894
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {

src/librustc/infer/region_inference/mod.rs

+1-35
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING};
2424
use rustc_data_structures::unify::{self, UnificationTable};
2525
use middle::free_region::FreeRegionMap;
2626
use ty::{self, Ty, TyCtxt};
27-
use ty::{BoundRegion, Region, RegionVid};
27+
use ty::{Region, RegionVid};
2828
use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased};
2929
use ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
3030

@@ -171,13 +171,6 @@ pub enum RegionResolutionError<'tcx> {
171171
&'tcx Region,
172172
SubregionOrigin<'tcx>,
173173
&'tcx Region),
174-
175-
/// For subsets of `ConcreteFailure` and `SubSupConflict`, we can derive
176-
/// more specific errors message by suggesting to the user where they
177-
/// should put a lifetime. In those cases we process and put those errors
178-
/// into `ProcessedErrors` before we do any reporting.
179-
ProcessedErrors(Vec<ProcessedErrorOrigin<'tcx>>,
180-
Vec<SameRegions>),
181174
}
182175

183176
#[derive(Clone, Debug)]
@@ -186,33 +179,6 @@ pub enum ProcessedErrorOrigin<'tcx> {
186179
VariableFailure(RegionVariableOrigin),
187180
}
188181

189-
/// SameRegions is used to group regions that we think are the same and would
190-
/// like to indicate so to the user.
191-
/// For example, the following function
192-
/// ```
193-
/// struct Foo { bar: i32 }
194-
/// fn foo2<'a, 'b>(x: &'a Foo) -> &'b i32 {
195-
/// &x.bar
196-
/// }
197-
/// ```
198-
/// would report an error because we expect 'a and 'b to match, and so we group
199-
/// 'a and 'b together inside a SameRegions struct
200-
#[derive(Clone, Debug)]
201-
pub struct SameRegions {
202-
pub scope_id: ast::NodeId,
203-
pub regions: Vec<BoundRegion>,
204-
}
205-
206-
impl SameRegions {
207-
pub fn contains(&self, other: &BoundRegion) -> bool {
208-
self.regions.contains(other)
209-
}
210-
211-
pub fn push(&mut self, other: BoundRegion) {
212-
self.regions.push(other);
213-
}
214-
}
215-
216182
pub type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
217183

218184
pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {

src/test/compile-fail/issue-17728.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,6 @@ impl Debug for Player {
108108

109109
fn str_to_direction(to_parse: &str) -> RoomDirection {
110110
match to_parse { //~ ERROR match arms have incompatible types
111-
//~^ expected enum `RoomDirection`, found enum `std::option::Option`
112-
//~| expected type `RoomDirection`
113-
//~| found type `std::option::Option<_>`
114111
"w" | "west" => RoomDirection::West,
115112
"e" | "east" => RoomDirection::East,
116113
"n" | "north" => RoomDirection::North,
@@ -119,7 +116,7 @@ fn str_to_direction(to_parse: &str) -> RoomDirection {
119116
"out" => RoomDirection::Out,
120117
"up" => RoomDirection::Up,
121118
"down" => RoomDirection::Down,
122-
_ => None //~ NOTE match arm with an incompatible type
119+
_ => None
123120
}
124121
}
125122

0 commit comments

Comments
 (0)