1. 28 1月, 2015 20 次提交
  2. 27 1月, 2015 20 次提交
    • N
    • N
    • N
      Fix two type inference failures uncovered by japaric corresponding to · c7ef9c1e
      Niko Matsakis 提交于
      UFCS form. In both cases the problems came about because we were
      failing to process pending trait obligations. So change code to
      process pending trait obligations before coercions to ensure maximum
      type information is available (and also adjust shift to do something
      similar).
      
      Fixes #21245.
      c7ef9c1e
    • N
    • B
      Auto merge of #21586 - pyfisch:patch-1, r=alexcrichton · 77743599
      bors 提交于
      Spellfix for `Debug` trait documentation. Change "most all types should implement this" to "all types should implement this". Same fix for deprecated `Show` trait.
      77743599
    • B
      Auto merge of #21657 - pnkfelix:block-remainder-extents, r=nikomatsakis · d77f6d53
      bors 提交于
       Add `CodeExtent::Remainder` variant; pre-req for new scoping/drop rules.
      
      This new enum variant introduces finer-grain code extents, i.e. we now track that a binding lives only for a suffix of a block, and (importantly) will be dropped when it goes out of scope *before* the bindings that occurred earlier in the block.
      
      Both of these notions are neatly captured by marking the block (and each suffix) as an enclosing scope of the next suffix beneath it.
      
      This is work that is part of the foundation for issue #8861.
      
      (It actually has been seen in earlier posted pull requests, in particular #21022; I have just factored it out into its own PR to ease my own near-future rebasing, and also get people used to the new rules.)
      
      ----
      
      These finer grained scopes do mean that some code is newly rejected by `rustc`; for example:
      
      ```rust
      let mut map : HashMap<u8, &u8> = HashMap::new();
      let tmp = Box::new(2);
      map.insert(43, &*tmp);
      ```
      
      This will now fail to compile with a message that `*tmp` does not live long enough, because the scope of `tmp` is now strictly smaller than
      that of `map`, and the use of `&u8` in map's type requires that the borrowed references are all to data that live at least as long as the map.
      
      The usual fix for a case like this is to move the binding for `tmp` up above that of `map`; note that you can still leave the initialization in the original spot, like so:
      
      ```rust
      let tmp;
      let mut map : HashMap<u8, &u8> = HashMap::new();
      tmp = box 2;
      map.insert(43, &*tmp);
      ```
      
      Similarly, one can encounter an analogous situation with `Vec`: one would need to rewrite:
      
      ```rust
      let mut vec = Vec::new();
      let tmp = 'c';
      vec.push(&tmp);
      ```
      
      as:
      
      ```rust
      let tmp;
      let mut vec = Vec::new();
      tmp = 'c';
      vec.push(&tmp);
      ```
      
      ----
      
      In some corner cases, it does not suffice to reorder the bindings; in particular, when the types for both bindings need to reflect exactly the *same* code extent, and a parent/child relationship between them does not work.
      
      In pnkfelix's experience this has arisen most often when mixing uses of cyclic data structures while also allowing a lifetime parameter `'a` to flow into a type parameter context where the type is *invariant* with respect to the type parameter. An important instance of this is `arena::TypedArena<T>`, which is invariant with respect to `T`.
      
      (The reason that variance is relevant is this: *if* `TypedArena` were covariant with respect to its type parameter, then we could assign it
      the longer lifetime when it is initialized, and then convert it to a subtype (via covariance) with a shorter lifetime when necessary.  But `TypedArena` is invariant with respect to its type parameter, and thus if `S` is a subtype of `T` (in particular, if `S` has a lifetime parameter that is shorter than that of `T`), then a `TypedArena<S>` is unrelated to `TypedArena<T>`.)
      
      Concretely, consider code like this:
      
      ```rust
      struct Node<'a> { sibling: Option<&'a Node<'a>> }
      struct Context<'a> {
          // because of this field, `Context<'a>` is invariant with respect to `'a`.
          arena: &'a TypedArena<Node<'a>>,
          ...
      }
      fn new_ctxt<'a>(arena: &'a TypedArena<Node<'a>>) -> Context<'a> { ... }
      fn use_ctxt<'a>(fcx: &'a Context<'a>) { ... }
      
      let arena = TypedArena::new();
      let ctxt = new_ctxt(&arena);
      
      use_ctxt(&ctxt);
      ```
      
      In these situations, if you try to introduce two bindings via two distinct `let` statements, each is (with this commit) assigned a distinct extent, and the region inference system cannot find a single region to assign to the lifetime `'a` that works for both of the bindings. So you get an error that `ctxt` does not live long enough; but moving its binding up above that of `arena` just shifts the error so now the compiler complains that `arena` does not live long enough.
      
       * SO: What to do? The easiest fix in this case is to ensure that the two bindings *do* get assigned the same static extent, by stuffing both
      bindings into the same let statement, like so:
      
      ```rust
      let (arena, ctxt): (TypedArena, Context);
      arena = TypedArena::new();
      ctxt = new_ctxt(&arena);
      
      use_ctxt(&ctxt);
      ```
      
      ----
      
      Due to the new code restrictions outlined above, this is a ...
      
      [breaking-change]
      d77f6d53
    • F
      Add `CodeExtent::Remainder` variant; pre-req for new scoping/drop rules. · d6bf04a2
      Felix S. Klock II 提交于
      This new variant introduces finer-grain code extents, i.e. we now
      track that a binding lives only for a suffix of a block, and
      (importantly) will be dropped when it goes out of scope *before* the
      bindings that occurred earlier in the block.
      
      Both of these notions are neatly captured by marking the block (and
      each suffix) as an enclosing scope of the next suffix beneath it.
      
      This is work that is part of the foundation for issue #8861.
      
      (It actually has been seen in earlier posted pull requests; I have
      just factored it out into its own PR to ease my own rebasing.)
      
      ----
      
      These finer grained scopes do mean that some code is newly rejected by
      `rustc`; for example:
      
      ```rust
      let mut map : HashMap<u8, &u8> = HashMap::new();
      let tmp = Box::new(2);
      map.insert(43, &*tmp);
      ```
      
      This will now fail to compile with a message that `*tmp` does not live
      long enough, because the scope of `tmp` is now strictly smaller than
      that of `map`, and the use of `&u8` in map's type requires that the
      borrowed references are all to data that live at least as long as the
      map.
      
      The usual fix for a case like this is to move the binding for `tmp`
      up above that of `map`; note that you can still leave the initialization
      in the original spot, like so:
      
      ```rust
      let tmp;
      let mut map : HashMap<u8, &u8> = HashMap::new();
      tmp = box 2;
      map.insert(43, &*tmp);
      ```
      
      Similarly, one can encounter an analogous situation with `Vec`: one
      would need to rewrite:
      
      ```rust
      let mut vec = Vec::new();
      let tmp = 'c';
      vec.push(&tmp);
      ```
      
      as:
      
      ```
      let tmp;
      let mut vec = Vec::new();
      tmp = 'c';
      vec.push(&tmp);
      ```
      
      ----
      
      In some corner cases, it does not suffice to reorder the bindings; in
      particular, when the types for both bindings need to reflect exactly
      the *same* code extent, and a parent/child relationship between them
      does not work.
      
      In pnkfelix's experience this has arisen most often when mixing uses
      of cyclic data structures while also allowing a lifetime parameter
      `'a` to flow into a type parameter context where the type is
      *invariant* with respect to the type parameter. An important instance
      of this is `arena::TypedArena<T>`, which is invariant with respect
      to `T`.
      
      (The reason that variance is relevant is this: *if* `TypedArena` were
      covariant with respect to its type parameter, then we could assign it
      the longer lifetime when it is initialized, and then convert it to a
      subtype (via covariance) with a shorter lifetime when necessary.  But
      `TypedArena` is invariant with respect to its type parameter, and thus
      if `S` is a subtype of `T` (in particular, if `S` has a lifetime
      parameter that is shorter than that of `T`), then a `TypedArena<S>` is
      unrelated to `TypedArena<T>`.)
      
      Concretely, consider code like this:
      
      ```rust
      struct Node<'a> { sibling: Option<&'a Node<'a>> }
      struct Context<'a> {
          // because of this field, `Context<'a>` is invariant with respect to `'a`.
          arena: &'a TypedArena<Node<'a>>,
          ...
      }
      fn new_ctxt<'a>(arena: &'a TypedArena<Node<'a>>) -> Context<'a> { ... }
      fn use_ctxt<'a>(fcx: &'a Context<'a>) { ... }
      
      let arena = TypedArena::new();
      let ctxt = new_ctxt(&arena);
      
      use_ctxt(&ctxt);
      ```
      
      In these situations, if you try to introduce two bindings via two
      distinct `let` statements, each is (with this commit) assigned a
      distinct extent, and the region inference system cannot find a single
      region to assign to the lifetime `'a` that works for both of the
      bindings. So you get an error that `ctxt` does not live long enough;
      but moving its binding up above that of `arena` just shifts the error
      so now the compiler complains that `arena` does not live long enough.
      
      SO: What to do? The easiest fix in this case is to ensure that the two
      bindings *do* get assigned the same static extent, by stuffing both
      bindings into the same let statement, like so:
      
      ```rust
      let (arena, ctxt): (TypedArena, Context);
      arena = TypedArena::new();
      ctxt = new_ctxt(&arena);
      
      use_ctxt(&ctxt);
      ```
      
      Due to the new code rejections outlined above, this is a ...
      
      [breaking-change]
      d6bf04a2
    • F
      43d08f86
    • F
      2c2f0f12
    • F
      70192ab7
    • F
      accommodate new scoping rules in test/run-pass. · 9fe8d860
      Felix S. Klock II 提交于
      9fe8d860
    • F
      86bde933
    • B
      Auto merge of #21564 - steveklabnik:doc_cell, r=alexcrichton · e365e4c0
      bors 提交于
      e365e4c0
    • B
      Auto merge of #21646 - dotdash:default_target_cpu, r=Aatch · 1c87af2e
      bors 提交于
      Using `generic` as the target cpu limits the generated code to the bare basics for the arch, while we can probably assume that we'll actually be running on somewhat modern hardware. This updates the default target CPUs for the x86 and x86_64 archs to match clang's behaviour.
      
      Refs #20777
      1c87af2e
    • B
      Merge fixes · 3c172392
      Brian Anderson 提交于
      3c172392
    • B
      Auto merge of #21543 - alexcrichton:old-io, r=aturon · a6a6fadb
      bors 提交于
      In preparation for the I/O rejuvination of the standard library, this commit
      renames the current `io` module to `old_io` in order to make room for the new
      I/O modules. It is expected that the I/O RFCs will land incrementally over time
      instead of all at once, and this provides a fresh clean path for new modules to
      enter into as well as guaranteeing that all old infrastructure will remain in
      place for some time.
      
      As each `old_io` module is replaced it will be deprecated in-place for new
      structures in `std::{io, fs, net}` (as appropriate).
      
      This commit does *not* leave a reexport of `old_io as io` as the deprecation
      lint does not currently warn on this form of use. This is quite a large breaking
      change for all imports in existing code, but all functionality is retained
      precisely as-is and path statements simply need to be renamed from `io` to
      `old_io`.
      
      [breaking-change]
      a6a6fadb
    • B
    • A
      std: Rename Writer::write to Writer::write_all · 5d836cdf
      Alex Crichton 提交于
      In preparation for upcoming changes to the `Writer` trait (soon to be called
      `Write`) this commit renames the current `write` method to `write_all` to match
      the semantics of the upcoming `write_all` method. The `write` method will be
      repurposed to return a `usize` indicating how much data was written which
      differs from the current `write` semantics. In order to head off as much
      unintended breakage as possible, the method is being deprecated now in favor of
      a new name.
      
      [breaking-change]
      5d836cdf
    • A
      Fallout of io => old_io · 3a07f859
      Alex Crichton 提交于
      3a07f859
    • A
      std: Rename io to old_io · f72b1645
      Alex Crichton 提交于
      In preparation for the I/O rejuvination of the standard library, this commit
      renames the current `io` module to `old_io` in order to make room for the new
      I/O modules. It is expected that the I/O RFCs will land incrementally over time
      instead of all at once, and this provides a fresh clean path for new modules to
      enter into as well as guaranteeing that all old infrastructure will remain in
      place for some time.
      
      As each `old_io` module is replaced it will be deprecated in-place for new
      structures in `std::{io, fs, net}` (as appropriate).
      
      This commit does *not* leave a reexport of `old_io as io` as the deprecation
      lint does not currently warn on this form of use. This is quite a large breaking
      change for all imports in existing code, but all functionality is retained
      precisely as-is and path statements simply need to be renamed from `io` to
      `old_io`.
      
      [breaking-change]
      f72b1645