Skip to content

Clean up some code #43006

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 2 commits into from
Jul 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1947,35 +1947,34 @@ 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 {
if x > y { x } else { y }
}
```

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 {
Expand Down
56 changes: 25 additions & 31 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
}
}
}
}
Expand Down
9 changes: 1 addition & 8 deletions src/librustc/infer/error_reporting/named_anon_conflict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -69,15 +68,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
}
_ => None,

}
}

// This method generates the error message for the case when
// 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
Expand Down Expand Up @@ -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 {
}
}
_ => {}
Expand All @@ -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,
Expand All @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
1 change: 0 additions & 1 deletion src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down