Skip to content

Commit

Permalink
Rollup merge of rust-lang#54641 - ljedrz:cleanup_rustc_infer, r=estebank
Browse files Browse the repository at this point in the history
A few cleanups and minor improvements to rustc/infer

- use unwrap_or(_else) where applicable
- convert single-branch matches to if-let
- use to_owned instead of to_string with string literals
- improve vector allocations
- readability improvements
- miscellaneous minor code improvements
  • Loading branch information
kennytm authored Oct 1, 2018
2 parents 5bfd085 + 52da886 commit 41706ff
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 200 deletions.
120 changes: 56 additions & 64 deletions src/librustc/infer/canonical/query_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
);

// Select everything, returning errors.
let true_errors = match fulfill_cx.select_where_possible(self) {
Ok(()) => vec![],
Err(errors) => errors,
};
let true_errors = fulfill_cx.select_where_possible(self).err().unwrap_or_else(Vec::new);
debug!("true_errors = {:#?}", true_errors);

if !true_errors.is_empty() {
Expand All @@ -148,10 +145,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
}

// Anything left unselected *now* must be an ambiguity.
let ambig_errors = match fulfill_cx.select_all_or_error(self) {
Ok(()) => vec![],
Err(errors) => errors,
};
let ambig_errors = fulfill_cx.select_all_or_error(self).err().unwrap_or_else(Vec::new);
debug!("ambig_errors = {:#?}", ambig_errors);

let region_obligations = self.take_registered_region_obligations();
Expand Down Expand Up @@ -316,16 +310,18 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
}

// ...also include the other query region constraints from the query.
output_query_region_constraints.reserve(query_result.value.region_constraints.len());
for r_c in query_result.value.region_constraints.iter() {
let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
let k1 = substitute_value(self.tcx, &result_subst, &k1);
let r2 = substitute_value(self.tcx, &result_subst, &r2);
if k1 != r2.into() {
output_query_region_constraints
.push(ty::Binder::bind(ty::OutlivesPredicate(k1, r2)));
}
}
output_query_region_constraints.extend(
query_result.value.region_constraints.iter().filter_map(|r_c| {
let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
let k1 = substitute_value(self.tcx, &result_subst, &k1);
let r2 = substitute_value(self.tcx, &result_subst, &r2);
if k1 != r2.into() {
Some(ty::Binder::bind(ty::OutlivesPredicate(k1, r2)))
} else {
None
}
})
);

let user_result: R =
query_result.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
Expand Down Expand Up @@ -448,10 +444,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
.variables
.iter()
.enumerate()
.map(|(index, info)| match opt_values[CanonicalVar::new(index)] {
Some(k) => k,
None => self.fresh_inference_var_for_canonical_var(cause.span, *info),
})
.map(|(index, info)| opt_values[CanonicalVar::new(index)].unwrap_or_else(||
self.fresh_inference_var_for_canonical_var(cause.span, *info)
))
.collect(),
};

Expand Down Expand Up @@ -504,24 +499,22 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
let k1 = substitute_value(self.tcx, result_subst, k1);
let r2 = substitute_value(self.tcx, result_subst, r2);
match k1.unpack() {
UnpackedKind::Lifetime(r1) => Obligation::new(
cause.clone(),
param_env,
ty::Predicate::RegionOutlives(ty::Binder::dummy(
ty::OutlivesPredicate(r1, r2),

Obligation::new(
cause.clone(),
param_env,
match k1.unpack() {
UnpackedKind::Lifetime(r1) => ty::Predicate::RegionOutlives(
ty::Binder::dummy(
ty::OutlivesPredicate(r1, r2)
)),
),

UnpackedKind::Type(t1) => Obligation::new(
cause.clone(),
param_env,
ty::Predicate::TypeOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
t1, r2,
))),
),
}
}),
UnpackedKind::Type(t1) => ty::Predicate::TypeOutlives(
ty::Binder::dummy(ty::OutlivesPredicate(
t1, r2
)))
}
)
})
) as Box<dyn Iterator<Item = _>>
}

Expand Down Expand Up @@ -583,31 +576,30 @@ pub fn make_query_outlives<'tcx>(
assert!(verifys.is_empty());
assert!(givens.is_empty());

let mut outlives: Vec<_> = constraints
.into_iter()
.map(|(k, _)| match *k {
// Swap regions because we are going from sub (<=) to outlives
// (>=).
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
tcx.mk_region(ty::ReVar(v2)).into(),
tcx.mk_region(ty::ReVar(v1)),
),
Constraint::VarSubReg(v1, r2) => {
ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
}
Constraint::RegSubVar(r1, v2) => {
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
}
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
})
.map(ty::Binder::dummy) // no bound regions in the code above
.collect();

outlives.extend(
outlives_obligations
.map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
.map(ty::Binder::dummy), // no bound regions in the code above
);
let outlives: Vec<_> = constraints
.into_iter()
.map(|(k, _)| match *k {
// Swap regions because we are going from sub (<=) to outlives
// (>=).
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
tcx.mk_region(ty::ReVar(v2)).into(),
tcx.mk_region(ty::ReVar(v1)),
),
Constraint::VarSubReg(v1, r2) => {
ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
}
Constraint::RegSubVar(r1, v2) => {
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
}
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
})
.map(ty::Binder::dummy) // no bound regions in the code above
.chain(
outlives_obligations
.map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
.map(ty::Binder::dummy), // no bound regions in the code above
)
.collect();

outlives
}
6 changes: 2 additions & 4 deletions src/librustc/infer/equate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,22 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
match (&a.sty, &b.sty) {
(&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
infcx.type_variables.borrow_mut().equate(a_id, b_id);
Ok(a)
}

(&ty::Infer(TyVar(a_id)), _) => {
self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?;
Ok(a)
}

(_, &ty::Infer(TyVar(b_id))) => {
self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?;
Ok(a)
}

_ => {
self.fields.infcx.super_combine_tys(self, a, b)?;
Ok(a)
}
}

Ok(a)
}

fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
Expand Down
17 changes: 8 additions & 9 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
errors.clone()
} else {
errors
.iter()
.filter(|&e| !is_bound_failure(e))
.cloned()
.collect()
.iter()
.filter(|&e| !is_bound_failure(e))
.cloned()
.collect()
};

// sort the errors by span, for better error message stability.
Expand Down Expand Up @@ -455,11 +455,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
TypeError::Sorts(ref exp_found) => {
// if they are both "path types", there's a chance of ambiguity
// due to different versions of the same crate
match (&exp_found.expected.sty, &exp_found.found.sty) {
(&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) => {
report_path_match(err, exp_adt.did, found_adt.did);
}
_ => (),
if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _))
= (&exp_found.expected.sty, &exp_found.found.sty)
{
report_path_match(err, exp_adt.did, found_adt.did);
}
}
TypeError::Traits(ref exp_found) => {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let mut labels = vec![(
span,
if &name == "_" {
"cannot infer type".to_string()
"cannot infer type".to_owned()
} else {
format!("cannot infer type for `{}`", name)
},
Expand Down Expand Up @@ -138,20 +138,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// ```
labels.clear();
labels.push(
(pattern.span, "consider giving this closure parameter a type".to_string()));
(pattern.span, "consider giving this closure parameter a type".to_owned()));
} else if let Some(pattern) = local_visitor.found_local_pattern {
if let Some(simple_ident) = pattern.simple_ident() {
match pattern.span.compiler_desugaring_kind() {
None => labels.push((pattern.span,
format!("consider giving `{}` a type", simple_ident))),
Some(CompilerDesugaringKind::ForLoop) => labels.push((
pattern.span,
"the element type for this iterator is not specified".to_string(),
"the element type for this iterator is not specified".to_owned(),
)),
_ => {}
}
} else {
labels.push((pattern.span, "consider giving the pattern a type".to_string()));
labels.push((pattern.span, "consider giving the pattern a type".to_owned()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
(None, None) => {
let (main_label_1, span_label_1) = if ty_sup.id == ty_sub.id {
(
"this type is declared with multiple lifetimes...".to_string(),
"...but data with one lifetime flows into the other here".to_string()
"this type is declared with multiple lifetimes...".to_owned(),
"...but data with one lifetime flows into the other here".to_owned()
)
} else {
(
"these two types are declared with different lifetimes...".to_string(),
"these two types are declared with different lifetimes...".to_owned(),
format!(
"...but data{} flows{} here",
span_label_var1,
Expand All @@ -133,15 +133,15 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
ty_sub.span,
ret_span,
"this parameter and the return type are declared \
with different lifetimes...".to_string()
with different lifetimes...".to_owned()
,
format!("...but data{} is returned here", span_label_var1),
),
(_, Some(ret_span)) => (
ty_sup.span,
ret_span,
"this parameter and the return type are declared \
with different lifetimes...".to_string()
with different lifetimes...".to_owned()
,
format!("...but data{} is returned here", span_label_var1),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,17 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
&RegionKind::ReFree(ref free_region)) = (&sub_origin, sup_region) {
let hir = &self.tcx.hir;
if let Some(node_id) = hir.as_local_node_id(free_region.scope) {
match hir.get(node_id) {
Node::Expr(Expr {
node: Closure(_, _, _, closure_span, None),
..
}) => {
let sup_sp = sup_origin.span();
let origin_sp = origin.span();
let mut err = self.tcx.sess.struct_span_err(
sup_sp,
"borrowed data cannot be stored outside of its closure");
err.span_label(sup_sp, "cannot be stored outside of its closure");
if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
if let Node::Expr(Expr {
node: Closure(_, _, _, closure_span, None),
..
}) = hir.get(node_id) {
let sup_sp = sup_origin.span();
let origin_sp = origin.span();
let mut err = self.tcx.sess.struct_span_err(
sup_sp,
"borrowed data cannot be stored outside of its closure");
err.span_label(sup_sp, "cannot be stored outside of its closure");
if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
// // sup_sp == origin.span():
//
// let mut x = None;
Expand All @@ -87,11 +86,11 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
// ------------ ... because it cannot outlive this closure
// f = Some(x);
// ^ cannot be stored outside of its closure
err.span_label(*external_span,
"borrowed data cannot be stored into here...");
err.span_label(*closure_span,
"...because it cannot outlive this closure");
} else {
err.span_label(*external_span,
"borrowed data cannot be stored into here...");
err.span_label(*closure_span,
"...because it cannot outlive this closure");
} else {
// FIXME: the wording for this case could be much improved
//
// let mut lines_to_use: Vec<&CrateId> = Vec::new();
Expand All @@ -102,18 +101,16 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
// ...so that variable is valid at time of its declaration
// lines_to_use.push(installed_id);
// ^^^^^^^^^^^^ cannot be stored outside of its closure
err.span_label(origin_sp,
"cannot infer an appropriate lifetime...");
err.span_label(*external_span,
"...so that variable is valid at time of its \
declaration");
err.span_label(*closure_span,
"borrowed data cannot outlive this closure");
}
err.emit();
return Some(ErrorReported);
err.span_label(origin_sp,
"cannot infer an appropriate lifetime...");
err.span_label(*external_span,
"...so that variable is valid at time of its \
declaration");
err.span_label(*closure_span,
"borrowed data cannot outlive this closure");
}
_ => {}
err.emit();
return Some(ErrorReported);
}
}
}
Expand Down
Loading

0 comments on commit 41706ff

Please sign in to comment.