Skip to content

Commit

Permalink
simplify HR subtyping back to what we did before
Browse files Browse the repository at this point in the history
A lot of the refactors, however, seem helpful, so leave those in,
particularly since we may want to make this change in the future.
  • Loading branch information
nikomatsakis committed May 17, 2016
1 parent 2eca6d6 commit cfa3471
Show file tree
Hide file tree
Showing 9 changed files with 14 additions and 101 deletions.
3 changes: 1 addition & 2 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,5 @@ register_diagnostics! {
E0490, // a value of type `..` is borrowed for too long
E0491, // in type `..`, reference has a longer lifetime than the data it...
E0495, // cannot infer an appropriate lifetime due to conflicting requirements
E0525, // expected a closure that implements `..` but this closure only implements `..`
E0526, // skolemization subtype
E0525 // expected a closure that implements `..` but this closure only implements `..`
}
16 changes: 0 additions & 16 deletions src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -919,17 +919,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"");
err
}
infer::SkolemizeSuccessor(span) => {
let mut err =
struct_span_err!(self.tcx.sess, span, E0526,
"to satisfy higher-ranked bounds, \
a static lifetime is required");
self.tcx.note_and_explain_region(&mut err,
"but the lifetime is only valid for ",
sub,
"");
err
}
}
}

Expand Down Expand Up @@ -1817,11 +1806,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"...so that references are valid when the destructor \
runs");
}
infer::SkolemizeSuccessor(span) => {
err.span_note(
span,
"...so that higher-ranked bounds are satisfied");
}
}
}
}
Expand Down
70 changes: 2 additions & 68 deletions src/librustc/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use super::{CombinedSnapshot,
InferCtxt,
LateBoundRegion,
HigherRankedType,
SubregionOrigin,
SkolemizationMap};
use super::combine::CombineFields;
use super::region_inference::{TaintDirections};
Expand Down Expand Up @@ -527,7 +526,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// be itself or other new variables.
let incoming_taints = self.tainted_regions(snapshot,
skol,
TaintDirections::incoming());
TaintDirections::both());
for &tainted_region in &incoming_taints {
// Each skolemized should only be relatable to itself
// or new variables:
Expand Down Expand Up @@ -568,71 +567,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {

self.issue_32330_warnings(span, &warnings);

for (_, &skol) in skol_map {
// The outputs from a skolemized variable must all be
// equatable with `'static`.
let outgoing_taints = self.tainted_regions(snapshot,
skol,
TaintDirections::outgoing());
for &tainted_region in &outgoing_taints {
match tainted_region {
ty::ReVar(vid) if new_vars.contains(&vid) => {
// There is a path from a skolemized variable
// to some region variable that doesn't escape
// this snapshot:
//
// [skol] -> [tainted_region]
//
// We can ignore this. The reasoning relies on
// the fact that the preivous loop
// completed. There are two possible cases
// here.
//
// - `tainted_region` eventually reaches a
// skolemized variable, which *must* be `skol`
// (because otherwise we would have already
// returned `Err`). In that case,
// `tainted_region` could be inferred to `skol`.
//
// - `tainted_region` never reaches a
// skolemized variable. In that case, we can
// safely choose `'static` as an upper bound
// incoming edges. This is a conservative
// choice -- the LUB might be one of the
// incoming skolemized variables, which we
// might know by ambient bounds. We can
// consider a more clever choice of upper
// bound later (modulo some theoretical
// breakage).
//
// We used to force such `tainted_region` to be
// `'static`, but that leads to problems when
// combined with `plug_leaks`. If you have a case
// where `[skol] -> [tainted_region] -> [skol]`,
// then `plug_leaks` concludes it should replace
// `'static` with a late-bound region, which is
// clearly wrong. (Well, what actually happens is
// you get assertion failures because it WOULD
// have to replace 'static with a late-bound
// region.)
}
ty::ReSkolemized(..) => {
// the only skolemized region we find in the
// successors of X can be X; if there was another
// region Y, then X would have been in the preds
// of Y, and we would have aborted above
assert_eq!(skol, tainted_region);
}
_ => {
self.region_vars.make_subregion(
SubregionOrigin::SkolemizeSuccessor(span),
ty::ReStatic,
tainted_region);
}
}
}
}

Ok(())
}

Expand Down Expand Up @@ -682,7 +616,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
skol_map
.iter()
.flat_map(|(&skol_br, &skol)| {
self.tainted_regions(snapshot, skol, TaintDirections::incoming())
self.tainted_regions(snapshot, skol, TaintDirections::both())
.into_iter()
.map(move |tainted_region| (tainted_region, skol_br))
})
Expand Down
6 changes: 0 additions & 6 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,6 @@ pub enum SubregionOrigin<'tcx> {

// Region constraint arriving from destructor safety
SafeDestructor(Span),

// When doing a higher-ranked comparison, this region was a
// successor from a skolemized region, which means that it must be
// `'static` to be sound.
SkolemizeSuccessor(Span),
}

/// Places that type/region parameters can appear.
Expand Down Expand Up @@ -1775,7 +1770,6 @@ impl<'tcx> SubregionOrigin<'tcx> {
AddrOf(a) => a,
AutoBorrow(a) => a,
SafeDestructor(a) => a,
SkolemizeSuccessor(a) => a,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1699,7 +1699,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
lint::builtin::HR_LIFETIME_IN_ASSOC_TYPE,
ast_ty.id,
ast_ty.span,
format!("fn type references lifetime `{}`, \
format!("return type references lifetime `{}`, \
which does not appear in the trait input types",
br_name));
}
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
base::MacEager::expr(expanded)
}

pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
pub fn expand_quote_item<'cx>(cx: &'cx mut ExtCtxt,
sp: Span,
tts: &[TokenTree])
-> Box<base::MacResult+'cx> {
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax_ext/concat_idents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use syntax::parse::token;
use syntax::parse::token::str_to_ident;
use syntax::ptr::P;

pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree])
-> Box<base::MacResult+'cx> {
if !cx.ecfg.enable_concat_idents() {
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
Expand Down
11 changes: 7 additions & 4 deletions src/test/compile-fail/hr-subtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ macro_rules! check {
//[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR mismatched types
//[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR mismatched types
//[free_inv_x_vs_free_inv_y]~^^^^^ ERROR mismatched types
//[bound_a_b_vs_bound_a]~^^^^^^ ERROR mismatched types
//[bound_co_a_b_vs_bound_co_a]~^^^^^^^ ERROR mismatched types
//[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR mismatched types
//[bound_co_a_co_b_ret_contra_a]~^^^^^^^^^ ERROR mismatched types
}
}
}
Expand Down Expand Up @@ -87,6 +91,9 @@ check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
// - if we are covariant, then 'a and 'b can be set to the call-site
// intersection;
// - if we are contravariant, then 'a can be inferred to 'static.
//
// FIXME(#32330) this is true, but we are not currently impl'ing this
// full semantics
check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32),
for<'a> fn(&'a u32, &'a u32)) }
check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>),
Expand All @@ -109,8 +116,4 @@ fn main() {
//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful
//[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful
//[free_x_vs_free_x]~^^^^^ ERROR compilation successful
//[bound_a_b_vs_bound_a]~^^^^^^ ERROR compilation successful
//[bound_co_a_b_vs_bound_co_a]~^^^^^^^ ERROR compilation successful
//[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR compilation successful
//[bound_co_a_co_b_ret_contra_a]~^^^^^^^^^ ERROR compilation successful
}
3 changes: 1 addition & 2 deletions src/test/compile-fail/regions-trait-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ impl<'a> get_ctxt for has_ctxt<'a> {
// Here an error occurs because we used `&self` but
// the definition used `&`:
fn get_ctxt(&self) -> &'a ctxt {
//~^ ERROR E0308
//~| ERROR E0526
//~^ ERROR E0053
self.c
}

Expand Down

0 comments on commit cfa3471

Please sign in to comment.