Skip to content

Commit 81bce52

Browse files
committed
Auto merge of #22230 - nikomatsakis:object-lifetime-defaults-2, r=pnkfelix
Implement rules described in rust-lang/rfcs#599. Fixes #22211. ~~Based atop PR #22182, so the first few commits (up to and including "Pacify the mercilous nrc") have already been reviewed.~~
2 parents e4e7aa2 + 503e15b commit 81bce52

File tree

53 files changed

+1264
-272
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1264
-272
lines changed

src/librustc/metadata/tydecode.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -824,14 +824,32 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
824824
assert_eq!(next(st), '|');
825825
let bounds = parse_bounds_(st, conv);
826826
let default = parse_opt(st, |st| parse_ty_(st, conv));
827+
let object_lifetime_default = parse_object_lifetime_default(st, conv);
827828

828829
ty::TypeParameterDef {
829830
name: name,
830831
def_id: def_id,
831832
space: space,
832833
index: index,
833834
bounds: bounds,
834-
default: default
835+
default: default,
836+
object_lifetime_default: object_lifetime_default,
837+
}
838+
}
839+
840+
fn parse_object_lifetime_default<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
841+
conv: &mut F)
842+
-> Option<ty::ObjectLifetimeDefault>
843+
where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
844+
{
845+
match next(st) {
846+
'n' => None,
847+
'a' => Some(ty::ObjectLifetimeDefault::Ambiguous),
848+
's' => {
849+
let region = parse_region_(st, conv);
850+
Some(ty::ObjectLifetimeDefault::Specific(region))
851+
}
852+
_ => panic!("parse_object_lifetime_default: bad input")
835853
}
836854
}
837855

src/librustc/metadata/tyencode.rs

+15
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,21 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tc
414414
v.space.to_uint(), v.index);
415415
enc_bounds(w, cx, &v.bounds);
416416
enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
417+
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
418+
}
419+
420+
fn enc_object_lifetime_default<'a, 'tcx>(w: &mut SeekableMemWriter,
421+
cx: &ctxt<'a, 'tcx>,
422+
default: Option<ty::ObjectLifetimeDefault>)
423+
{
424+
match default {
425+
None => mywrite!(w, "n"),
426+
Some(ty::ObjectLifetimeDefault::Ambiguous) => mywrite!(w, "a"),
427+
Some(ty::ObjectLifetimeDefault::Specific(r)) => {
428+
mywrite!(w, "s");
429+
enc_region(w, cx, r);
430+
}
431+
}
417432
}
418433

419434
pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,

src/librustc/middle/infer/error_reporting.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
619619
infer::RelateRegionParamBound(span) => {
620620
self.tcx.sess.span_err(
621621
span,
622-
"declared lifetime bound not satisfied");
622+
"lifetime bound not satisfied");
623623
note_and_explain_region(
624624
self.tcx,
625625
"lifetime parameter instantiated with ",
@@ -1628,7 +1628,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
16281628
self.tcx.sess.span_note(
16291629
span,
16301630
&format!("...so that the type `{}` \
1631-
will meet the declared lifetime bounds",
1631+
will meet its required lifetime bounds",
16321632
self.ty_to_string(t))[]);
16331633
}
16341634
infer::RelateDefaultParamBound(span, t) => {

src/librustc/middle/ty.rs

+26-30
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,21 @@ impl fmt::Debug for IntVarValue {
17621762
}
17631763
}
17641764

1765+
/// Default region to use for the bound of objects that are
1766+
/// supplied as the value for this type parameter. This is derived
1767+
/// from `T:'a` annotations appearing in the type definition. If
1768+
/// this is `None`, then the default is inherited from the
1769+
/// surrounding context. See RFC #599 for details.
1770+
#[derive(Copy, Clone, Debug)]
1771+
pub enum ObjectLifetimeDefault {
1772+
/// Require an explicit annotation. Occurs when multiple
1773+
/// `T:'a` constraints are found.
1774+
Ambiguous,
1775+
1776+
/// Use the given region as the default.
1777+
Specific(Region),
1778+
}
1779+
17651780
#[derive(Clone, Debug)]
17661781
pub struct TypeParameterDef<'tcx> {
17671782
pub name: ast::Name,
@@ -1770,6 +1785,7 @@ pub struct TypeParameterDef<'tcx> {
17701785
pub index: u32,
17711786
pub bounds: ParamBounds<'tcx>,
17721787
pub default: Option<Ty<'tcx>>,
1788+
pub object_lifetime_default: Option<ObjectLifetimeDefault>,
17731789
}
17741790

17751791
#[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
@@ -5884,42 +5900,13 @@ pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
58845900
return true;
58855901
}
58865902

5887-
pub fn object_region_bounds<'tcx>(
5888-
tcx: &ctxt<'tcx>,
5889-
opt_principal: Option<&PolyTraitRef<'tcx>>, // None for closures
5890-
others: BuiltinBounds)
5891-
-> Vec<ty::Region>
5892-
{
5893-
// Since we don't actually *know* the self type for an object,
5894-
// this "open(err)" serves as a kind of dummy standin -- basically
5895-
// a skolemized type.
5896-
let open_ty = ty::mk_infer(tcx, FreshTy(0));
5897-
5898-
let opt_trait_ref = opt_principal.map_or(Vec::new(), |principal| {
5899-
// Note that we preserve the overall binding levels here.
5900-
assert!(!open_ty.has_escaping_regions());
5901-
let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
5902-
vec!(ty::Binder(Rc::new(ty::TraitRef::new(principal.0.def_id, substs))))
5903-
});
5904-
5905-
let param_bounds = ty::ParamBounds {
5906-
region_bounds: Vec::new(),
5907-
builtin_bounds: others,
5908-
trait_bounds: opt_trait_ref,
5909-
projection_bounds: Vec::new(), // not relevant to computing region bounds
5910-
};
5911-
5912-
let predicates = ty::predicates(tcx, open_ty, &param_bounds);
5913-
ty::required_region_bounds(tcx, open_ty, predicates)
5914-
}
5915-
59165903
/// Given a set of predicates that apply to an object type, returns
59175904
/// the region bounds that the (erased) `Self` type must
59185905
/// outlive. Precisely *because* the `Self` type is erased, the
59195906
/// parameter `erased_self_ty` must be supplied to indicate what type
59205907
/// has been used to represent `Self` in the predicates
59215908
/// themselves. This should really be a unique type; `FreshTy(0)` is a
5922-
/// popular choice (see `object_region_bounds` above).
5909+
/// popular choice.
59235910
///
59245911
/// Requires that trait definitions have been processed so that we can
59255912
/// elaborate predicates and walk supertraits.
@@ -7390,3 +7377,12 @@ impl<'a, 'tcx> Repr<'tcx> for ParameterEnvironment<'a, 'tcx> {
73907377
self.caller_bounds.repr(tcx))
73917378
}
73927379
}
7380+
7381+
impl<'tcx> Repr<'tcx> for ObjectLifetimeDefault {
7382+
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
7383+
match *self {
7384+
ObjectLifetimeDefault::Ambiguous => format!("Ambiguous"),
7385+
ObjectLifetimeDefault::Specific(ref r) => r.repr(tcx),
7386+
}
7387+
}
7388+
}

src/librustc/middle/ty_fold.rs

+13
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,19 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
379379
index: self.index,
380380
bounds: self.bounds.fold_with(folder),
381381
default: self.default.fold_with(folder),
382+
object_lifetime_default: self.object_lifetime_default.fold_with(folder),
383+
}
384+
}
385+
}
386+
387+
impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault {
388+
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ObjectLifetimeDefault {
389+
match *self {
390+
ty::ObjectLifetimeDefault::Ambiguous =>
391+
ty::ObjectLifetimeDefault::Ambiguous,
392+
393+
ty::ObjectLifetimeDefault::Specific(r) =>
394+
ty::ObjectLifetimeDefault::Specific(r.fold_with(folder)),
382395
}
383396
}
384397
}

0 commit comments

Comments
 (0)