1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Error Reporting for Anonymous Region Lifetime Errors
12 //! where one region is named and the other is anonymous.
14 use infer::region_inference::RegionResolutionError::*;
15 use infer::region_inference::RegionResolutionError;
18 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
19 // This method generates the error message for the case when
20 // the function arguments consist of a named region and an anonymous
21 // region and corresponds to `ConcreteFailure(..)`
22 pub fn try_report_named_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {
23 let (span, sub, sup) = match *error {
24 ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
25 _ => return false, // inapplicable
28 debug!("try_report_named_anon_conflict(sub={:?}, sup={:?})",
32 // Determine whether the sub and sup consist of one named region ('a)
33 // and one anonymous (elided) region. If so, find the parameter arg
34 // where the anonymous region appears (there must always be one; we
35 // only introduced anonymous regions in parameters) as well as a
36 // version new_ty of its type where the anonymous region is replaced
37 // with the named one.//scope_def_id
38 let (named, anon_arg_info, region_info) =
39 if self.is_named_region(sub) && self.is_suitable_region(sup).is_some() &&
40 self.find_arg_with_region(sup, sub).is_some() {
42 self.find_arg_with_region(sup, sub).unwrap(),
43 self.is_suitable_region(sup).unwrap())
44 } else if self.is_named_region(sup) && self.is_suitable_region(sub).is_some() &&
45 self.find_arg_with_region(sub, sup).is_some() {
47 self.find_arg_with_region(sub, sup).unwrap(),
48 self.is_suitable_region(sub).unwrap())
50 return false; // inapplicable
53 debug!("try_report_named_anon_conflict: named = {:?}", named);
54 debug!("try_report_named_anon_conflict: anon_arg_info = {:?}",
56 debug!("try_report_named_anon_conflict: region_info = {:?}",
59 let (arg, new_ty, br, is_first, scope_def_id, is_impl_item) = (anon_arg_info.arg,
61 anon_arg_info.bound_region,
62 anon_arg_info.is_first,
64 region_info.is_impl_item);
68 /* not an anonymous region */
69 debug!("try_report_named_anon_conflict: not an anonymous region");
75 debug!("try_report_named_anon_conflict: impl item, bail out");
79 if self.is_return_type_anon(scope_def_id, br) {
80 debug!("try_report_named_anon_conflict: is_return_type_anon({:?}, {:?}) = true",
84 } else if self.is_self_anon(is_first, scope_def_id) {
85 debug!("try_report_named_anon_conflict: is_self_anon({:?}, {:?}) = true",
90 let (error_var, span_label_var) = if let Some(simple_name) = arg.pat.simple_name() {
91 (format!("the type of `{}`", simple_name), format!("the type of `{}`", simple_name))
93 ("parameter type".to_owned(), "type".to_owned())
96 struct_span_err!(self.tcx.sess,
99 "explicit lifetime required in {}",
101 .span_label(arg.pat.span,
102 format!("consider changing {} to `{}`", span_label_var, new_ty))
103 .span_label(span, format!("lifetime `{}` required", named))