1 use crate::infer
::error_reporting
::{note_and_explain_region, ObligationCauseExt}
;
2 use crate::infer
::{self, InferCtxt, SubregionOrigin}
;
3 use rustc_errors
::{struct_span_err, DiagnosticBuilder}
;
4 use rustc_middle
::ty
::error
::TypeError
;
5 use rustc_middle
::ty
::{self, Region}
;
7 impl<'a
, 'tcx
> InferCtxt
<'a
, 'tcx
> {
8 pub(super) fn note_region_origin(
10 err
: &mut DiagnosticBuilder
<'_
>,
11 origin
: &SubregionOrigin
<'tcx
>,
13 let mut label_or_note
= |span
, msg
| {
14 let sub_count
= err
.children
.iter().filter(|d
| d
.span
.is_dummy()).count();
15 let expanded_sub_count
= err
.children
.iter().filter(|d
| !d
.span
.is_dummy()).count();
16 let span_is_primary
= err
.span
.primary_spans().iter().all(|&sp
| sp
== span
);
17 if span_is_primary
&& sub_count
== 0 && expanded_sub_count
== 0 {
18 err
.span_label(span
, msg
);
19 } else if span_is_primary
&& expanded_sub_count
== 0 {
22 err
.span_note(span
, msg
);
26 infer
::Subtype(ref trace
) => {
27 if let Some((expected
, found
)) = self.values_str(&trace
.values
) {
30 &format
!("...so that the {}", trace
.cause
.as_requirement_str()),
33 err
.note_expected_found(&"", expected
, &"", found
);
35 // FIXME: this really should be handled at some earlier stage. Our
36 // handling of region checking when type errors are present is
41 &format
!("...so that {}", trace
.cause
.as_requirement_str()),
45 infer
::Reborrow(span
) => {
46 label_or_note(span
, "...so that reference does not outlive borrowed content");
48 infer
::ReborrowUpvar(span
, ref upvar_id
) => {
49 let var_name
= self.tcx
.hir().name(upvar_id
.var_path
.hir_id
);
50 label_or_note(span
, &format
!("...so that closure can access `{}`", var_name
));
52 infer
::RelateObjectBound(span
) => {
53 label_or_note(span
, "...so that it can be closed over into an object");
55 infer
::CallReturn(span
) => {
56 label_or_note(span
, "...so that return value is valid for the call");
58 infer
::DataBorrowed(ty
, span
) => {
62 "...so that the type `{}` is not borrowed for too long",
67 infer
::ReferenceOutlivesReferent(ty
, span
) => {
71 "...so that the reference type `{}` does not outlive the data it points at",
76 infer
::RelateParamBound(span
, t
) => {
80 "...so that the type `{}` will meet its required lifetime bounds",
85 infer
::RelateRegionParamBound(span
) => {
88 "...so that the declared lifetime parameter bounds are satisfied",
91 infer
::CompareImplMethodObligation { span, .. }
=> {
94 "...so that the definition in impl matches the definition from the trait",
100 pub(super) fn report_concrete_failure(
102 origin
: SubregionOrigin
<'tcx
>,
105 ) -> DiagnosticBuilder
<'tcx
> {
107 infer
::Subtype(box trace
) => {
108 let terr
= TypeError
::RegionsDoesNotOutlive(sup
, sub
);
109 let mut err
= self.report_and_explain_type_error(trace
, &terr
);
110 note_and_explain_region(self.tcx
, &mut err
, "", sup
, "...");
111 note_and_explain_region(
114 "...does not necessarily outlive ",
120 infer
::Reborrow(span
) => {
121 let mut err
= struct_span_err
!(
125 "lifetime of reference outlives lifetime of borrowed content..."
127 note_and_explain_region(
130 "...the reference is valid for ",
134 note_and_explain_region(
137 "...but the borrowed content is only valid for ",
143 infer
::ReborrowUpvar(span
, ref upvar_id
) => {
144 let var_name
= self.tcx
.hir().name(upvar_id
.var_path
.hir_id
);
145 let mut err
= struct_span_err
!(
149 "lifetime of borrowed pointer outlives lifetime of captured variable `{}`...",
152 note_and_explain_region(
155 "...the borrowed pointer is valid for ",
159 note_and_explain_region(
162 &format
!("...but `{}` is only valid for ", var_name
),
168 infer
::RelateObjectBound(span
) => {
169 let mut err
= struct_span_err
!(
173 "lifetime of the source pointer does not outlive lifetime bound of the \
176 note_and_explain_region(self.tcx
, &mut err
, "object type is valid for ", sub
, "");
177 note_and_explain_region(
180 "source pointer is only valid for ",
186 infer
::RelateParamBound(span
, ty
) => {
187 let mut err
= struct_span_err
!(
191 "the type `{}` does not fulfill the required lifetime",
192 self.ty_to_string(ty
)
196 note_and_explain_region(self.tcx
, &mut err
, "type must satisfy ", sub
, "")
198 _
=> note_and_explain_region(self.tcx
, &mut err
, "type must outlive ", sub
, ""),
202 infer
::RelateRegionParamBound(span
) => {
204 struct_span_err
!(self.tcx
.sess
, span
, E0478
, "lifetime bound not satisfied");
205 note_and_explain_region(
208 "lifetime parameter instantiated with ",
212 note_and_explain_region(
215 "but lifetime parameter must outlive ",
221 infer
::CallReturn(span
) => {
222 let mut err
= struct_span_err
!(
226 "lifetime of return value does not outlive the function call"
228 note_and_explain_region(
231 "the return value is only valid for ",
237 infer
::DataBorrowed(ty
, span
) => {
238 let mut err
= struct_span_err
!(
242 "a value of type `{}` is borrowed for too long",
243 self.ty_to_string(ty
)
245 note_and_explain_region(self.tcx
, &mut err
, "the type is valid for ", sub
, "");
246 note_and_explain_region(self.tcx
, &mut err
, "but the borrow lasts for ", sup
, "");
249 infer
::ReferenceOutlivesReferent(ty
, span
) => {
250 let mut err
= struct_span_err
!(
254 "in type `{}`, reference has a longer lifetime than the data it references",
255 self.ty_to_string(ty
)
257 note_and_explain_region(self.tcx
, &mut err
, "the pointer is valid for ", sub
, "");
258 note_and_explain_region(
261 "but the referenced data is only valid for ",
267 infer
::CompareImplMethodObligation
{
272 } => self.report_extra_impl_obligation(
277 &format
!("`{}: {}`", sup
, sub
),
282 pub(super) fn report_placeholder_failure(
284 placeholder_origin
: SubregionOrigin
<'tcx
>,
287 ) -> DiagnosticBuilder
<'tcx
> {
288 // I can't think how to do better than this right now. -nikomatsakis
289 match placeholder_origin
{
290 infer
::Subtype(box trace
) => {
291 let terr
= TypeError
::RegionsPlaceholderMismatch
;
292 self.report_and_explain_type_error(trace
, &terr
)
295 _
=> self.report_concrete_failure(placeholder_origin
, sub
, sup
),