Skip to content

Commit 75ee8f1

Browse files
committed
Introduce a "origin/cause" for new requirements (or bugfixes...) introduced by RFC 1214,
and issue a warning (and explanatory note) when we encounter such a thing.
1 parent 39d164d commit 75ee8f1

File tree

7 files changed

+339
-132
lines changed

7 files changed

+339
-132
lines changed

src/librustc/middle/infer/error_reporting.rs

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,7 @@ pub trait ErrorReporting<'tcx> {
239239
fn report_generic_bound_failure(&self,
240240
origin: SubregionOrigin<'tcx>,
241241
kind: GenericKind<'tcx>,
242-
sub: Region,
243-
sups: Vec<Region>);
242+
sub: Region);
244243

245244
fn report_sub_sup_conflict(&self,
246245
var_origin: RegionVariableOrigin,
@@ -292,8 +291,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
292291
self.report_concrete_failure(origin, sub, sup);
293292
}
294293

295-
GenericBoundFailure(kind, param_ty, sub, sups) => {
296-
self.report_generic_bound_failure(kind, param_ty, sub, sups);
294+
GenericBoundFailure(kind, param_ty, sub) => {
295+
self.report_generic_bound_failure(kind, param_ty, sub);
297296
}
298297

299298
SubSupConflict(var_origin,
@@ -527,14 +526,18 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
527526
fn report_generic_bound_failure(&self,
528527
origin: SubregionOrigin<'tcx>,
529528
bound_kind: GenericKind<'tcx>,
530-
sub: Region,
531-
_sups: Vec<Region>)
529+
sub: Region)
532530
{
533531
// FIXME: it would be better to report the first error message
534532
// with the span of the parameter itself, rather than the span
535533
// where the error was detected. But that span is not readily
536534
// accessible.
537535

536+
let is_warning = match origin {
537+
infer::RFC1214Subregion(_) => true,
538+
_ => false,
539+
};
540+
538541
let labeled_user_string = match bound_kind {
539542
GenericKind::Param(ref p) =>
540543
format!("the parameter type `{}`", p),
@@ -545,7 +548,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
545548
match sub {
546549
ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => {
547550
// Does the required lifetime have a nice name we can print?
548-
span_err!(self.tcx.sess, origin.span(), E0309,
551+
span_err_or_warn!(
552+
is_warning, self.tcx.sess, origin.span(), E0309,
549553
"{} may not live long enough", labeled_user_string);
550554
self.tcx.sess.fileline_help(
551555
origin.span(),
@@ -557,7 +561,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
557561

558562
ty::ReStatic => {
559563
// Does the required lifetime have a nice name we can print?
560-
span_err!(self.tcx.sess, origin.span(), E0310,
564+
span_err_or_warn!(
565+
is_warning, self.tcx.sess, origin.span(), E0310,
561566
"{} may not live long enough", labeled_user_string);
562567
self.tcx.sess.fileline_help(
563568
origin.span(),
@@ -568,9 +573,10 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
568573

569574
_ => {
570575
// If not, be less specific.
571-
span_err!(self.tcx.sess, origin.span(), E0311,
572-
"{} may not live long enough",
573-
labeled_user_string);
576+
span_err_or_warn!(
577+
is_warning, self.tcx.sess, origin.span(), E0311,
578+
"{} may not live long enough",
579+
labeled_user_string);
574580
self.tcx.sess.fileline_help(
575581
origin.span(),
576582
&format!(
@@ -583,6 +589,10 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
583589
}
584590
}
585591

592+
if is_warning {
593+
self.tcx.sess.note_rfc_1214(origin.span());
594+
}
595+
586596
self.note_region_origin(&origin);
587597
}
588598

@@ -591,6 +601,13 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
591601
sub: Region,
592602
sup: Region) {
593603
match origin {
604+
infer::RFC1214Subregion(ref suborigin) => {
605+
// Ideally, this would be a warning, but it doesn't
606+
// seem to come up in practice, since the changes from
607+
// RFC1214 mostly trigger errors in type definitions
608+
// that don't wind up coming down this path.
609+
self.report_concrete_failure((**suborigin).clone(), sub, sup);
610+
}
594611
infer::Subtype(trace) => {
595612
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
596613
self.report_and_explain_type_error(trace, &terr);
@@ -819,6 +836,23 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
819836
sup,
820837
"");
821838
}
839+
infer::ParameterInScope(_, span) => {
840+
self.tcx.sess.span_err(
841+
span,
842+
&format!("type/lifetime parameter not in scope here"));
843+
self.tcx.note_and_explain_region(
844+
"the parameter is only valid for ",
845+
sub,
846+
"");
847+
}
848+
infer::DataBorrowed(ty, span) => {
849+
self.tcx.sess.span_err(
850+
span,
851+
&format!("a value of type `{}` is borrowed for too long",
852+
self.ty_to_string(ty)));
853+
self.tcx.note_and_explain_region("the type is valid for ", sub, "");
854+
self.tcx.note_and_explain_region("but the borrow lasts for ", sup, "");
855+
}
822856
infer::ReferenceOutlivesReferent(ty, span) => {
823857
self.tcx.sess.span_err(
824858
span,
@@ -1567,6 +1601,9 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
15671601

15681602
fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
15691603
match *origin {
1604+
infer::RFC1214Subregion(ref suborigin) => {
1605+
self.note_region_origin(suborigin);
1606+
}
15701607
infer::Subtype(ref trace) => {
15711608
let desc = match trace.origin {
15721609
infer::Misc(_) => {
@@ -1714,6 +1751,17 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
17141751
span,
17151752
"...so that variable is valid at time of its declaration");
17161753
}
1754+
infer::ParameterInScope(_, span) => {
1755+
self.tcx.sess.span_note(
1756+
span,
1757+
&format!("...so that a type/lifetime parameter is in scope here"));
1758+
}
1759+
infer::DataBorrowed(ty, span) => {
1760+
self.tcx.sess.span_note(
1761+
span,
1762+
&format!("...so that the type `{}` is not borrowed for too long",
1763+
self.ty_to_string(ty)));
1764+
}
17171765
infer::ReferenceOutlivesReferent(ty, span) => {
17181766
self.tcx.sess.span_note(
17191767
span,

src/librustc/middle/infer/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use middle::ty_relate::{Relate, RelateResult, TypeRelation};
3535
use rustc_data_structures::unify::{self, UnificationTable};
3636
use std::cell::{RefCell, Ref};
3737
use std::fmt;
38+
use std::rc::Rc;
3839
use syntax::ast;
3940
use syntax::codemap;
4041
use syntax::codemap::{Span, DUMMY_SP};
@@ -188,6 +189,8 @@ pub struct TypeTrace<'tcx> {
188189
/// See `error_reporting.rs` for more details
189190
#[derive(Clone, Debug)]
190191
pub enum SubregionOrigin<'tcx> {
192+
RFC1214Subregion(Rc<SubregionOrigin<'tcx>>),
193+
191194
// Arose from a subtyping relation
192195
Subtype(TypeTrace<'tcx>),
193196

@@ -229,9 +232,15 @@ pub enum SubregionOrigin<'tcx> {
229232
// Creating a pointer `b` to contents of an upvar
230233
ReborrowUpvar(Span, ty::UpvarId),
231234

235+
// Data with type `Ty<'tcx>` was borrowed
236+
DataBorrowed(Ty<'tcx>, Span),
237+
232238
// (&'a &'b T) where a >= b
233239
ReferenceOutlivesReferent(Ty<'tcx>, Span),
234240

241+
// Type or region parameters must be in scope.
242+
ParameterInScope(ParameterOrigin, Span),
243+
235244
// The type T of an expression E must outlive the lifetime for E.
236245
ExprTypeIsNotInScope(Ty<'tcx>, Span),
237246

@@ -260,6 +269,15 @@ pub enum SubregionOrigin<'tcx> {
260269
SafeDestructor(Span),
261270
}
262271

272+
/// Places that type/region parameters can appear.
273+
#[derive(Clone, Copy, Debug)]
274+
pub enum ParameterOrigin {
275+
Path, // foo::bar
276+
MethodCall, // foo.bar() <-- parameters on impl providing bar()
277+
OverloadedOperator, // a + b when overloaded
278+
OverloadedDeref, // *a when overloaded
279+
}
280+
263281
/// Times when we replace late-bound regions with variables:
264282
#[derive(Clone, Copy, Debug)]
265283
pub enum LateBoundRegionConversionTime {
@@ -1565,6 +1583,7 @@ impl TypeOrigin {
15651583
impl<'tcx> SubregionOrigin<'tcx> {
15661584
pub fn span(&self) -> Span {
15671585
match *self {
1586+
RFC1214Subregion(ref a) => a.span(),
15681587
Subtype(ref a) => a.span(),
15691588
InfStackClosure(a) => a,
15701589
InvokeClosure(a) => a,
@@ -1577,7 +1596,9 @@ impl<'tcx> SubregionOrigin<'tcx> {
15771596
RelateDefaultParamBound(a, _) => a,
15781597
Reborrow(a) => a,
15791598
ReborrowUpvar(a, _) => a,
1599+
DataBorrowed(_, a) => a,
15801600
ReferenceOutlivesReferent(_, a) => a,
1601+
ParameterInScope(_, a) => a,
15811602
ExprTypeIsNotInScope(_, a) => a,
15821603
BindingTypeIsNotValidAtDecl(a) => a,
15831604
CallRcvr(a) => a,

0 commit comments

Comments
 (0)