Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement (most of) RFC 1214 #27641

Merged
merged 38 commits into from
Aug 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4561607
Don't report a hard error if there are inference failures until
nikomatsakis Aug 7, 2015
9289552
Define the `wf` and `outlives` relation separately, unlike the existing
nikomatsakis Aug 6, 2015
b196315
Add two new kinds of predicates, WellFormed and ObjectSafe.
nikomatsakis Aug 7, 2015
ad47bd8
Extend ParameterEnvironment to remember the free_id, and to be usable
nikomatsakis Aug 7, 2015
8d98877
Implement a new wfcheck to replace the old wf; this new code only issues
nikomatsakis Aug 7, 2015
6bb1e22
New WF condition requires checking that argument types are WF
nikomatsakis Aug 7, 2015
39d164d
New tests --- check that wf relation is being checked in various posi…
nikomatsakis Aug 7, 2015
75ee8f1
Introduce a "origin/cause" for new requirements (or bugfixes...) intr…
nikomatsakis Aug 7, 2015
d159977
Generalize the outlives rule for projections to handle the new cases;
nikomatsakis Aug 7, 2015
788a802
New tests --- projection outlives relation
nikomatsakis Aug 7, 2015
91b3e9c
Fallout in libs -- misc missing bounds uncovered by WF checks.
nikomatsakis Aug 7, 2015
d15d743
Add FIXME for apparent stage0 regression
nikomatsakis Aug 7, 2015
09bf2fe
Fallout in tests -- we now report an error if you even reference a type
nikomatsakis Aug 7, 2015
92d16d9
Fallout in tests -- break the object safety part into a separate file…
nikomatsakis Aug 7, 2015
532fcb2
Fallout in tests -- break this test into three tests, since we later saw
nikomatsakis Aug 7, 2015
f4aaedb
Fallout in tests -- break test into a run-pass and compile-fail compo…
nikomatsakis Aug 7, 2015
dee8b54
Fallout in tests --- misc error message changes, WF fixes
nikomatsakis Aug 7, 2015
7ed39c6
Fallout in tests -- explain an interesting test failure having to
nikomatsakis Aug 7, 2015
ff39ee9
wip 082a011e2bd5c8254e6c1b2fdc97a6fcb2927a7f rm binary
nikomatsakis Aug 11, 2015
b7e849b
infer/mod.rs: add doc comment to RFC1214 variant
nikomatsakis Aug 11, 2015
0582fed
middle/outlives.rs: fix typo
nikomatsakis Aug 11, 2015
9c3a866
middle/outlives.rs: s/temp/subcomponents/
nikomatsakis Aug 11, 2015
c9a49f9
regionck.rs: remove dead fn type_strictly_outlives
nikomatsakis Aug 11, 2015
fb1b6fc
regionck.rs: correct misuse of ty.regions() rather than regions()
nikomatsakis Aug 11, 2015
9c5cfea
traits: consider whether origin is RFC1214 when caching, ensuring
nikomatsakis Aug 11, 2015
a264440
outlives: convert outlives to use an exhaustive match, for better
nikomatsakis Aug 11, 2015
a7c9a15
outlives.rs: remove use of ty.walk and replace with recursive of
nikomatsakis Aug 11, 2015
2b2a113
check/wf.rs: change to use correct span and older WF algorithm;
nikomatsakis Aug 11, 2015
157422a
Update test error messages based on changes to wfcheck; also, break
nikomatsakis Aug 11, 2015
c106dd4
traits/error_reporting.rs: always note obligation cause
nikomatsakis Aug 11, 2015
213326c
outlives.rs: correct typo
nikomatsakis Aug 11, 2015
fda9b83
regionck.rs: add a delayed_span_bug call to validate an asserrtion
nikomatsakis Aug 12, 2015
ad700ab
ty.rs: document/cleanup required_region_bounds a bit
nikomatsakis Aug 12, 2015
9f3f69e
regionck.rs: experimentally adopt a more conservative strategy for
nikomatsakis Aug 12, 2015
e1fa00b
add regression test for #27592. Fixes #27592.
nikomatsakis Aug 13, 2015
33200a3
expr_use_visitor: Remove FIXME that is no longer needed (and in fact
nikomatsakis Aug 13, 2015
401a243
astconv.rs: extended ast_ty_to_ty debugging
nikomatsakis Aug 13, 2015
7f8942c
Correct nits from @nrc
nikomatsakis Aug 14, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2623,7 +2623,7 @@ impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
/// two `Step` objects.
#[unstable(feature = "step_trait",
reason = "likely to be replaced by finer-grained traits")]
pub trait Step: PartialOrd {
pub trait Step: PartialOrd+Sized {
/// Steps `self` if possible.
fn step(&self, by: &Self) -> Option<Self>;

Expand Down
2 changes: 1 addition & 1 deletion src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub trait Sized {
/// Types that can be "unsized" to a dynamically sized type.
#[unstable(feature = "unsize")]
#[lang="unsize"]
pub trait Unsize<T> {
pub trait Unsize<T: ?Sized> {
// Empty.
}

Expand Down
4 changes: 2 additions & 2 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use char::CharExt;
use cmp::{Eq, PartialOrd};
use fmt;
use intrinsics;
use marker::Copy;
use marker::{Copy, Sized};
use mem::size_of;
use option::Option::{self, Some, None};
use result::Result::{self, Ok, Err};
Expand Down Expand Up @@ -1264,7 +1264,7 @@ pub enum FpCategory {
#[doc(hidden)]
#[unstable(feature = "core_float",
reason = "stable interface is via `impl f{32,64}` in later crates")]
pub trait Float {
pub trait Float: Sized {
/// Returns the NaN value.
fn nan() -> Self;
/// Returns the infinite value.
Expand Down
3 changes: 2 additions & 1 deletion src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use default::Default;
use fmt;
use iter::ExactSizeIterator;
use iter::{Map, Iterator, DoubleEndedIterator};
use marker::Sized;
use mem;
use ops::{Fn, FnMut, FnOnce};
use option::Option::{self, None, Some};
Expand All @@ -37,7 +38,7 @@ pub mod pattern;
/// A trait to abstract the idea of creating a new instance of a type from a
/// string.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait FromStr {
pub trait FromStr: Sized {
/// The associated error which can be returned from parsing.
#[stable(feature = "rust1", since = "1.0.0")]
type Err;
Expand Down
2 changes: 1 addition & 1 deletion src/libgraphviz/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ pub type Edges<'a,E> = Cow<'a,[E]>;
/// `Cow<[T]>` to leave implementers the freedom to create
/// entirely new vectors or to pass back slices into internally owned
/// vectors.
pub trait GraphWalk<'a, N, E> {
pub trait GraphWalk<'a, N: Clone, E: Clone> {
/// Returns all the nodes in this graph.
fn nodes(&'a self) -> Nodes<'a, N>;
/// Returns all of the edges in this graph.
Expand Down
3 changes: 2 additions & 1 deletion src/librand/distributions/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

// this is surprisingly complicated to be both generic & correct

use core::marker::Sized;
use Rng;
use distributions::{Sample, IndependentSample};

Expand Down Expand Up @@ -57,7 +58,7 @@ impl<Sup: SampleRange> IndependentSample<Sup> for Range<Sup> {
/// uniformly between two values. This should not be used directly,
/// and is only to facilitate `Range`.
#[doc(hidden)]
pub trait SampleRange {
pub trait SampleRange: Sized {
/// Construct the `Range` object that `sample_range`
/// requires. This should not ever be called directly, only via
/// `Range::new`, which will check that `low < high`, so this
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub mod middle {
pub mod lang_items;
pub mod liveness;
pub mod mem_categorization;
pub mod outlives;
pub mod pat_util;
pub mod privacy;
pub mod reachable;
Expand All @@ -144,6 +145,7 @@ pub mod middle {
pub mod ty_match;
pub mod ty_relate;
pub mod ty_walk;
pub mod wf;
pub mod weak_lang_items;
}

Expand Down
6 changes: 6 additions & 0 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,12 @@ fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
'o' => ty::Binder(ty::OutlivesPredicate(parse_ty_(st, conv),
parse_region_(st, conv))).to_predicate(),
'p' => ty::Binder(parse_projection_predicate_(st, conv)).to_predicate(),
'w' => ty::Predicate::WellFormed(parse_ty_(st, conv)),
'O' => {
let def_id = parse_def_(st, NominalType, conv);
assert_eq!(next(st), '|');
ty::Predicate::ObjectSafe(def_id)
}
c => panic!("Encountered invalid character in metadata: {}", c)
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,13 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
mywrite!(w, "p");
enc_projection_predicate(w, cx, data)
}
ty::Predicate::WellFormed(data) => {
mywrite!(w, "w");
enc_ty(w, cx, data);
}
ty::Predicate::ObjectSafe(trait_def_id) => {
mywrite!(w, "O{}|", (cx.ds)(trait_def_id));
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
}
}

trait doc_decoder_helpers {
trait doc_decoder_helpers: Sized {
fn as_int(&self) -> isize;
fn opt_child(&self, tag: c::astencode_tag) -> Option<Self>;
}
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl OverloadedCallType {
// supplies types from the tree. After type checking is complete, you
// can just use the tcx as the typer.

pub struct ExprUseVisitor<'d,'t,'a: 't, 'tcx:'a> {
pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d> {
typer: &'t infer::InferCtxt<'a, 'tcx>,
mc: mc::MemCategorizationContext<'t, 'a, 'tcx>,
delegate: &'d mut (Delegate<'tcx>+'d),
Expand Down Expand Up @@ -273,7 +273,8 @@ enum PassArgs {
impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
pub fn new(delegate: &'d mut Delegate<'tcx>,
typer: &'t infer::InferCtxt<'a, 'tcx>)
-> ExprUseVisitor<'d,'t,'a, 'tcx> {
-> ExprUseVisitor<'d,'t,'a,'tcx>
{
ExprUseVisitor {
typer: typer,
mc: mc::MemCategorizationContext::new(typer),
Expand Down
23 changes: 13 additions & 10 deletions src/librustc/middle/free_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

//! This file defines

use middle::implicator::Implication;
use middle::wf::ImpliedBound;
use middle::ty::{self, FreeRegion};
use util::common::can_reach;
use util::nodemap::{FnvHashMap, FnvHashSet};
Expand All @@ -30,18 +30,19 @@ impl FreeRegionMap {
FreeRegionMap { map: FnvHashMap(), statics: FnvHashSet() }
}

pub fn relate_free_regions_from_implications<'tcx>(&mut self,
implications: &[Implication<'tcx>])
pub fn relate_free_regions_from_implied_bounds<'tcx>(&mut self,
implied_bounds: &[ImpliedBound<'tcx>])
{
for implication in implications {
debug!("implication: {:?}", implication);
match *implication {
Implication::RegionSubRegion(_, ty::ReFree(free_a), ty::ReFree(free_b)) => {
debug!("relate_free_regions_from_implied_bounds()");
for implied_bound in implied_bounds {
debug!("implied bound: {:?}", implied_bound);
match *implied_bound {
ImpliedBound::RegionSubRegion(ty::ReFree(free_a), ty::ReFree(free_b)) => {
self.relate_free_regions(free_a, free_b);
}
Implication::RegionSubRegion(..) |
Implication::RegionSubGeneric(..) |
Implication::Predicate(..) => {
ImpliedBound::RegionSubRegion(..) |
ImpliedBound::RegionSubParam(..) |
ImpliedBound::RegionSubProjection(..) => {
}
}
}
Expand All @@ -56,6 +57,8 @@ impl FreeRegionMap {
ty::Predicate::Projection(..) |
ty::Predicate::Trait(..) |
ty::Predicate::Equate(..) |
ty::Predicate::WellFormed(..) |
ty::Predicate::ObjectSafe(..) |
ty::Predicate::TypeOutlives(..) => {
// No region bounds here
}
Expand Down
56 changes: 5 additions & 51 deletions src/librustc/middle/implicator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use middle::infer::{InferCtxt, GenericKind};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the role of implicator now? just backwards compatibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arielb1

what is the role of implicator now? just backwards compatibility?

yes, it can be removed once we change from warnings to hard errors.

use middle::subst::Substs;
use middle::traits;
use middle::ty::{self, RegionEscape, ToPolyTraitRef, ToPredicate, Ty};
use middle::ty::{self, RegionEscape, ToPredicate, Ty};
use middle::ty_fold::{TypeFoldable, TypeFolder};

use syntax::ast;
Expand Down Expand Up @@ -278,9 +278,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {

for predicate in predicates.predicates.as_slice() {
match *predicate {
ty::Predicate::Trait(ref data) => {
self.accumulate_from_assoc_types_transitive(data);
}
ty::Predicate::Trait(..) => { }
ty::Predicate::Equate(..) => { }
ty::Predicate::Projection(..) => { }
ty::Predicate::RegionOutlives(ref data) => {
Expand All @@ -301,6 +299,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
}
}
}
ty::Predicate::ObjectSafe(_) |
ty::Predicate::WellFormed(_) => {
}
}
}

Expand Down Expand Up @@ -349,53 +350,6 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
}
}

/// Given that there is a requirement that `Foo<X> : 'a`, where
/// `Foo` is declared like `struct Foo<T> where T : SomeTrait`,
/// this code finds all the associated types defined in
/// `SomeTrait` (and supertraits) and adds a requirement that `<X
/// as SomeTrait>::N : 'a` (where `N` is some associated type
/// defined in `SomeTrait`). This rule only applies to
/// trait-bounds that are not higher-ranked, because we cannot
/// project out of a HRTB. This rule helps code using associated
/// types to compile, see Issue #22246 for an example.
fn accumulate_from_assoc_types_transitive(&mut self,
data: &ty::PolyTraitPredicate<'tcx>)
{
debug!("accumulate_from_assoc_types_transitive({:?})",
data);

for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) {
match self.tcx().no_late_bound_regions(&poly_trait_ref) {
Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); }
None => { }
}
}
}

fn accumulate_from_assoc_types(&mut self,
trait_ref: ty::TraitRef<'tcx>)
{
debug!("accumulate_from_assoc_types({:?})",
trait_ref);

let trait_def_id = trait_ref.def_id;
let trait_def = self.tcx().lookup_trait_def(trait_def_id);
let assoc_type_projections: Vec<_> =
trait_def.associated_type_names
.iter()
.map(|&name| self.tcx().mk_projection(trait_ref.clone(), name))
.collect();
debug!("accumulate_from_assoc_types: assoc_type_projections={:?}",
assoc_type_projections);
let tys = match self.fully_normalize(&assoc_type_projections) {
Ok(tys) => { tys }
Err(ErrorReported) => { return; }
};
for ty in tys {
self.accumulate_from_ty(ty);
}
}

fn accumulate_from_object_ty(&mut self,
ty: Ty<'tcx>,
region_bound: ty::Region,
Expand Down
Loading