1
Fork 0

Auto merge of #43006 - GuillaumeGomez:e0611-cleanup, r=nikomatsakis

Clean up some code

From #42669.

r? @nikomatsakis
This commit is contained in:
bors 2017-07-11 10:07:24 +00:00
commit dddf24d96f
5 changed files with 41 additions and 55 deletions

View file

@ -1947,27 +1947,25 @@ Either way, try to update/remove it in order to fix the error.
"##,
E0621: r##"
This error code indicates a mismatch between the function signature (i.e.,
the parameter types and the return type) and the function body. Most of
the time, this indicates that the function signature needs to be changed to
match the body, but it may be that the body needs to be changed to match
the signature.
This error code indicates a mismatch between the lifetimes appearing in the
function signature (i.e., the parameter types and the return type) and the
data-flow found in the function body.
Specifically, one or more of the parameters contain borrowed data that
needs to have a named lifetime in order for the body to type-check. Most of
the time, this is because the borrowed data is being returned from the
function, as in this example:
Erroneous code example:
```compile_fail,E0621
fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { // explicit lifetime required
// in the type of `y`
fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { // error: explicit lifetime
// required in the type of
// `y`
if x > y { x } else { y }
}
```
Here, the function is returning data borrowed from either x or y, but the
'a annotation indicates that it is returning data only from x. We can make
the signature match the body by changing the type of y to &'a i32, like so:
In the code above, the function is returning data borrowed from either `x` or
`y`, but the `'a` annotation indicates that it is returning data only from `x`.
To fix the error, the signature and the body must be made to match. Typically,
this is done by updating the function signature. So, in this case, we change
the type of `y` to `&'a i32`, like so:
```
fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
@ -1975,7 +1973,8 @@ fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
}
```
Alternatively, you could change the body not to return data from y:
Now the signature indicates that the function data borrowed from either `x` or
`y`. Alternatively, you could change the body to not return data from `y`:
```
fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {

View file

@ -72,12 +72,12 @@ use ty::error::TypeError;
use syntax::ast::DUMMY_NODE_ID;
use syntax_pos::{Pos, Span};
use errors::{DiagnosticBuilder, DiagnosticStyledString};
mod note;
mod need_type_info;
mod named_anon_conflict;
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn note_and_explain_region(self,
err: &mut DiagnosticBuilder,
@ -265,40 +265,34 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// together into a `ProcessedErrors` group:
let errors = self.process_errors(errors);
debug!("report_region_errors: {} errors after preprocessing",
errors.len());
debug!("report_region_errors: {} errors after preprocessing", errors.len());
for error in errors {
debug!("report_region_errors: error = {:?}", error);
if !self.try_report_named_anon_conflict(&error){
match error.clone() {
// These errors could indicate all manner of different
// problems with many different solutions. Rather
// than generate a "one size fits all" error, what we
// attempt to do is go through a number of specific
// scenarios and try to find the best way to present
// the error. If all of these fails, we fall back to a rather
// general bit of code that displays the error information
ConcreteFailure(origin, sub, sup) => {
self.report_concrete_failure(origin, sub, sup).emit();
}
GenericBoundFailure(kind, param_ty, sub) => {
self.report_generic_bound_failure(kind, param_ty, sub);
}
SubSupConflict(var_origin,
sub_origin, sub_r,
sup_origin, sup_r) => {
self.report_sub_sup_conflict(var_origin,
sub_origin, sub_r,
sup_origin, sup_r);
}
}
if !self.try_report_named_anon_conflict(&error) {
match error.clone() {
// These errors could indicate all manner of different
// problems with many different solutions. Rather
// than generate a "one size fits all" error, what we
// attempt to do is go through a number of specific
// scenarios and try to find the best way to present
// the error. If all of these fails, we fall back to a rather
// general bit of code that displays the error information
ConcreteFailure(origin, sub, sup) => {
self.report_concrete_failure(origin, sub, sup).emit();
}
GenericBoundFailure(kind, param_ty, sub) => {
self.report_generic_bound_failure(kind, param_ty, sub);
}
SubSupConflict(var_origin,
sub_origin, sub_r,
sup_origin, sup_r) => {
self.report_sub_sup_conflict(var_origin,
sub_origin, sub_r,
sup_origin, sup_r);
}
}
}
}
}

View file

@ -37,7 +37,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
match *anon_region {
ty::ReFree(ref free_region) => {
let id = free_region.scope;
let node_id = self.tcx.hir.as_local_node_id(id).unwrap();
let body_id = self.tcx.hir.maybe_body_owned_by(node_id).unwrap();
@ -69,7 +68,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
}
_ => None,
}
}
@ -77,7 +75,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// the function arguments consist of a named region and an anonymous
// region and corresponds to `ConcreteFailure(..)`
pub fn try_report_named_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {
let (span, sub, sup) = match *error {
ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
_ => return false, // inapplicable
@ -113,7 +110,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.collect_referenced_late_bound_regions(&sig.output());
if late_bound_regions.iter().any(|r| *r == br) {
return false;
} else {
}
}
_ => {}
@ -134,10 +130,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let (error_var, span_label_var) = if let Some(simple_name) = arg.pat.simple_name() {
(format!("the type of `{}`", simple_name), format!("the type of `{}`", simple_name))
} else {
(format!("parameter type"), format!("type"))
("parameter type".to_owned(), "type".to_owned())
};
struct_span_err!(self.tcx.sess,
span,
E0621,
@ -149,13 +144,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.emit();
return true;
}
// This method returns whether the given Region is Anonymous
// and returns the DefId corresponding to the region.
pub fn is_suitable_anonymous_region(&self, region: Region<'tcx>) -> Option<DefId> {
match *region {
ty::ReFree(ref free_region) => {
match free_region.bound_region {

View file

@ -38,6 +38,7 @@ use errors::DiagnosticBuilder;
use syntax_pos::{self, Span, DUMMY_SP};
use util::nodemap::FxHashMap;
use arena::DroplessArena;
use self::combine::CombineFields;
use self::higher_ranked::HrMatchResult;
use self::region_inference::{RegionVarBindings, RegionSnapshot};

View file

@ -993,7 +993,6 @@ impl RegionKind {
// This method returns whether the given Region is Named
pub fn is_named_region(&self) -> bool {
match *self {
ty::ReFree(ref free_region) => {
match free_region.bound_region {