Auto merge of #43006 - GuillaumeGomez:e0611-cleanup, r=nikomatsakis
Clean up some code From #42669. r? @nikomatsakis
This commit is contained in:
commit
dddf24d96f
5 changed files with 41 additions and 55 deletions
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue