Skip to content

Commit 08071c2

Browse files
committed
Revert "Cleanup some remains of hr_lifetime_in_assoc_type compatibility lint"
This reverts commit 80cf3f9.
1 parent 7b54e83 commit 08071c2

File tree

18 files changed

+298
-111
lines changed

18 files changed

+298
-111
lines changed

src/librustc/ich/impls_ty.rs

+1
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ for ty::RegionParameterDef {
374374
name,
375375
def_id,
376376
index,
377+
issue_32330: _,
377378
pure_wrt_drop
378379
} = *self;
379380

src/librustc/infer/error_reporting/mod.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ use hir::map as hir_map;
6666
use hir::def_id::DefId;
6767
use middle::region;
6868
use traits::{ObligationCause, ObligationCauseCode};
69-
use ty::{self, Region, TyCtxt, TypeFoldable};
69+
use ty::{self, TyCtxt, TypeFoldable};
70+
use ty::{Region, Issue32330};
7071
use ty::error::TypeError;
7172
use syntax::ast::DUMMY_NODE_ID;
7273
use syntax_pos::{Pos, Span};
@@ -714,6 +715,35 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
714715
self.tcx.note_and_explain_type_err(diag, terr, span);
715716
}
716717

718+
pub fn note_issue_32330(&self,
719+
diag: &mut DiagnosticBuilder<'tcx>,
720+
terr: &TypeError<'tcx>)
721+
{
722+
debug!("note_issue_32330: terr={:?}", terr);
723+
match *terr {
724+
TypeError::RegionsInsufficientlyPolymorphic(_, _, Some(box Issue32330 {
725+
fn_def_id, region_name
726+
})) |
727+
TypeError::RegionsOverlyPolymorphic(_, _, Some(box Issue32330 {
728+
fn_def_id, region_name
729+
})) => {
730+
diag.note(
731+
&format!("lifetime parameter `{0}` declared on fn `{1}` \
732+
appears only in the return type, \
733+
but here is required to be higher-ranked, \
734+
which means that `{0}` must appear in both \
735+
argument and return types",
736+
region_name,
737+
self.tcx.item_path_str(fn_def_id)));
738+
diag.note(
739+
&format!("this error is the result of a recent bug fix; \
740+
for more information, see issue #33685 \
741+
<https://github.com/rust-lang/rust/issues/33685>"));
742+
}
743+
_ => {}
744+
}
745+
}
746+
717747
pub fn report_and_explain_type_error(&self,
718748
trace: TypeTrace<'tcx>,
719749
terr: &TypeError<'tcx>)
@@ -733,6 +763,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
733763
}
734764
};
735765
self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr);
766+
self.note_issue_32330(&mut diag, terr);
736767
diag
737768
}
738769

@@ -905,7 +936,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
905936
format!(" for lifetime parameter {}in trait containing associated type `{}`",
906937
br_string(br), self.tcx.associated_item(def_id).name)
907938
}
908-
infer::EarlyBoundRegion(_, name) => {
939+
infer::EarlyBoundRegion(_, name, _) => {
909940
format!(" for lifetime parameter `{}`",
910941
name)
911942
}

src/librustc/infer/higher_ranked/mod.rs

+49-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
1414
use super::{CombinedSnapshot,
1515
InferCtxt,
16+
LateBoundRegion,
1617
HigherRankedType,
18+
RegionVariableOrigin,
1719
SubregionOrigin,
1820
SkolemizationMap};
1921
use super::combine::CombineFields;
@@ -27,6 +29,15 @@ use util::nodemap::{FxHashMap, FxHashSet};
2729

2830
pub struct HrMatchResult<U> {
2931
pub value: U,
32+
33+
/// Normally, when we do a higher-ranked match operation, we
34+
/// expect all higher-ranked regions to be constrained as part of
35+
/// the match operation. However, in the transition period for
36+
/// #32330, it can happen that we sometimes have unconstrained
37+
/// regions that get instantiated with fresh variables. In that
38+
/// case, we collect the set of unconstrained bound regions here
39+
/// and replace them with fresh variables.
40+
pub unconstrained_regions: Vec<ty::BoundRegion>,
3041
}
3142

3243
impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
@@ -97,6 +108,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
97108
/// that do not appear in `T`. If that happens, those regions are
98109
/// unconstrained, and this routine replaces them with `'static`.
99110
pub fn higher_ranked_match<T, U>(&mut self,
111+
span: Span,
100112
a_pair: &Binder<(T, U)>,
101113
b_match: &T,
102114
a_is_expected: bool)
@@ -146,16 +158,28 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
146158
// be any region from the sets above, except for other members of
147159
// `skol_map`. There should always be a representative if things
148160
// are properly well-formed.
161+
let mut unconstrained_regions = vec![];
149162
let skol_representatives: FxHashMap<_, _> =
150163
skol_resolution_map
151164
.iter()
152-
.map(|(&skol, &(_, ref regions))| {
165+
.map(|(&skol, &(br, ref regions))| {
153166
let representative =
154167
regions.iter()
155168
.filter(|&&r| !skol_resolution_map.contains_key(r))
156169
.cloned()
157170
.next()
158-
.expect("no representative region");
171+
.unwrap_or_else(|| { // [1]
172+
unconstrained_regions.push(br);
173+
self.infcx.next_region_var(
174+
LateBoundRegion(span, br, HigherRankedType))
175+
});
176+
177+
// [1] There should always be a representative,
178+
// unless the higher-ranked region did not appear
179+
// in the values being matched. We should reject
180+
// as ill-formed cases that can lead to this, but
181+
// right now we sometimes issue warnings (see
182+
// #32330).
159183

160184
(skol, representative)
161185
})
@@ -192,7 +216,10 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
192216
// We are now done with these skolemized variables.
193217
self.infcx.pop_skolemized(skol_map, snapshot);
194218

195-
Ok(HrMatchResult { value: a_value })
219+
Ok(HrMatchResult {
220+
value: a_value,
221+
unconstrained_regions,
222+
})
196223
});
197224
}
198225

@@ -630,13 +657,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
630657
skol_br,
631658
tainted_region);
632659

633-
return Err(if overly_polymorphic {
660+
let issue_32330 = if let &ty::ReVar(vid) = tainted_region {
661+
match self.region_vars.var_origin(vid) {
662+
RegionVariableOrigin::EarlyBoundRegion(_, _, issue_32330) => {
663+
issue_32330.map(Box::new)
664+
}
665+
_ => None
666+
}
667+
} else {
668+
None
669+
};
670+
671+
if overly_polymorphic {
634672
debug!("Overly polymorphic!");
635-
TypeError::RegionsOverlyPolymorphic(skol_br, tainted_region)
673+
return Err(TypeError::RegionsOverlyPolymorphic(skol_br,
674+
tainted_region,
675+
issue_32330));
636676
} else {
637677
debug!("Not as polymorphic!");
638-
TypeError::RegionsInsufficientlyPolymorphic(skol_br, tainted_region)
639-
})
678+
return Err(TypeError::RegionsInsufficientlyPolymorphic(skol_br,
679+
tainted_region,
680+
issue_32330));
681+
}
640682
}
641683
}
642684

src/librustc/infer/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ pub enum RegionVariableOrigin {
299299
Coercion(Span),
300300

301301
// Region variables created as the values for early-bound regions
302-
EarlyBoundRegion(Span, ast::Name),
302+
EarlyBoundRegion(Span, ast::Name, Option<ty::Issue32330>),
303303

304304
// Region variables created for bound regions
305305
// in a function or method that is called
@@ -989,7 +989,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
989989
span: Span,
990990
def: &ty::RegionParameterDef)
991991
-> ty::Region<'tcx> {
992-
self.next_region_var(EarlyBoundRegion(span, def.name))
992+
self.next_region_var(EarlyBoundRegion(span, def.name, def.issue_32330))
993993
}
994994

995995
/// Create a type inference variable for the given
@@ -1290,13 +1290,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12901290
-> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
12911291
{
12921292
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref(self.tcx), p.ty));
1293+
let span = cause.span;
12931294
let trace = TypeTrace {
12941295
cause,
12951296
values: TraitRefs(ExpectedFound::new(true, match_pair.skip_binder().0, match_b))
12961297
};
12971298

12981299
let mut combine = self.combine_fields(trace, param_env);
1299-
let result = combine.higher_ranked_match(&match_pair, &match_b, true)?;
1300+
let result = combine.higher_ranked_match(span, &match_pair, &match_b, true)?;
13001301
Ok(InferOk { value: result, obligations: combine.obligations })
13011302
}
13021303

src/librustc/middle/resolve_lifetime.rs

+32-6
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ pub struct NamedRegionMap {
153153
// (b) it DOES appear in the arguments.
154154
pub late_bound: NodeSet,
155155

156+
// Contains the node-ids for lifetimes that were (incorrectly) categorized
157+
// as late-bound, until #32330 was fixed.
158+
pub issue_32330: NodeMap<ty::Issue32330>,
159+
156160
// For each type and trait definition, maps type parameters
157161
// to the trait object lifetime defaults computed from them.
158162
pub object_lifetime_defaults: NodeMap<Vec<ObjectLifetimeDefault>>,
@@ -257,6 +261,7 @@ pub fn krate(sess: &Session,
257261
let mut map = NamedRegionMap {
258262
defs: NodeMap(),
259263
late_bound: NodeSet(),
264+
issue_32330: NodeMap(),
260265
object_lifetime_defaults: compute_object_lifetime_defaults(sess, hir_map),
261266
};
262267
sess.track_errors(|| {
@@ -298,7 +303,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
298303
fn visit_item(&mut self, item: &'tcx hir::Item) {
299304
match item.node {
300305
hir::ItemFn(ref decl, _, _, _, ref generics, _) => {
301-
self.visit_early_late(None, decl, generics, |this| {
306+
self.visit_early_late(item.id, None, decl, generics, |this| {
302307
intravisit::walk_item(this, item);
303308
});
304309
}
@@ -350,7 +355,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
350355
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
351356
match item.node {
352357
hir::ForeignItemFn(ref decl, _, ref generics) => {
353-
self.visit_early_late(None, decl, generics, |this| {
358+
self.visit_early_late(item.id, None, decl, generics, |this| {
354359
intravisit::walk_foreign_item(this, item);
355360
})
356361
}
@@ -401,6 +406,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
401406
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
402407
if let hir::TraitItemKind::Method(ref sig, _) = trait_item.node {
403408
self.visit_early_late(
409+
trait_item.id,
404410
Some(self.hir_map.get_parent(trait_item.id)),
405411
&sig.decl, &sig.generics,
406412
|this| intravisit::walk_trait_item(this, trait_item))
@@ -412,6 +418,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
412418
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
413419
if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
414420
self.visit_early_late(
421+
impl_item.id,
415422
Some(self.hir_map.get_parent(impl_item.id)),
416423
&sig.decl, &sig.generics,
417424
|this| intravisit::walk_impl_item(this, impl_item))
@@ -804,13 +811,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
804811
/// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
805812
/// ordering is not important there.
806813
fn visit_early_late<F>(&mut self,
814+
fn_id: ast::NodeId,
807815
parent_id: Option<ast::NodeId>,
808816
decl: &'tcx hir::FnDecl,
809817
generics: &'tcx hir::Generics,
810818
walk: F) where
811819
F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
812820
{
813-
insert_late_bound_lifetimes(self.map, decl, generics);
821+
let fn_def_id = self.hir_map.local_def_id(fn_id);
822+
insert_late_bound_lifetimes(self.map,
823+
fn_def_id,
824+
decl,
825+
generics);
814826

815827
// Find the start of nested early scopes, e.g. in methods.
816828
let mut index = 0;
@@ -1522,6 +1534,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
15221534
/// not amongst the inputs to a projection. In other words, `<&'a
15231535
/// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
15241536
fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
1537+
fn_def_id: DefId,
15251538
decl: &hir::FnDecl,
15261539
generics: &hir::Generics) {
15271540
debug!("insert_late_bound_lifetimes(decl={:?}, generics={:?})", decl, generics);
@@ -1579,9 +1592,22 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
15791592
// any `impl Trait` in the return type? early-bound.
15801593
if appears_in_output.impl_trait { continue; }
15811594

1582-
// does not appear in the inputs, but appears in the return type? early-bound.
1583-
if !constrained_by_input.regions.contains(&name) &&
1584-
appears_in_output.regions.contains(&name) {
1595+
// does not appear in the inputs, but appears in the return
1596+
// type? eventually this will be early-bound, but for now we
1597+
// just mark it so we can issue warnings.
1598+
let constrained_by_input = constrained_by_input.regions.contains(&name);
1599+
let appears_in_output = appears_in_output.regions.contains(&name);
1600+
if !constrained_by_input && appears_in_output {
1601+
debug!("inserting issue_32330 entry for {:?}, {:?} on {:?}",
1602+
lifetime.lifetime.id,
1603+
name,
1604+
fn_def_id);
1605+
map.issue_32330.insert(
1606+
lifetime.lifetime.id,
1607+
ty::Issue32330 {
1608+
fn_def_id,
1609+
region_name: name,
1610+
});
15851611
continue;
15861612
}
15871613

0 commit comments

Comments
 (0)