1. 22 3月, 2017 1 次提交
  2. 21 3月, 2017 22 次提交
  3. 20 3月, 2017 17 次提交
    • R
      Fix up tests · 728753d6
      Ravi Chande 提交于
      728753d6
    • T
      Fixing the test-result table in README.md · 4db7ba90
      Tanner Gooding 提交于
      4db7ba90
    • R
      Don't pass a language to DocumentOptions · 55bcc603
      Ravi Chande 提交于
      55bcc603
    • J
      Move to XCopy MSBuild · 28f7fed9
      Jared Parsons 提交于
      28f7fed9
    • J
      Move the machine images to base Windows VM · bb01afdd
      Jared Parsons 提交于
      bb01afdd
    • C
    • A
      Update the required frameworks in the description (#17942) · 78762859
      Andy Gocke 提交于
      The description of this package is vague and incorrect. We now require .NET 4.6, not
      .NET 4.5, and that is only a build-time requirement, not a deploy requirement.
      78762859
    • C
    • C
      Merge pull request #17975 from CyrusNajmabadi/pickMembersOptions · 9b60985b
      CyrusNajmabadi 提交于
      Add "Add null checks" option when a user tries to generate a constructor from members.
      9b60985b
    • A
      Allow closures to take both struct- and class-based capture environments (#16908) · d6e70325
      Andy Gocke 提交于
      Lambda rewriting currently allows frames to be structs in the instance
      where
      
      The variables in the frame are not captured by any closures
      converted to delegates.
      
      A closure nested inside the struct closure captures a separate
      variable that does require a class frame.
      
      This poses a problem when the "outer" closure is in the same frame as
      the variable that requires a class closure. The problem is that we treat
      scopes and frames as essentially the same thing -- if any scope is
      perceived to require a particular environment type, all captured
      variables in that scope will be captured on that frame and all closures
      will be lowered onto that frame.
      
      This creates a conflict between class-based environment capturing, where
      we want to capture the frame pointer as a field, and struct-based frame
      capturing, where we want to add arguments as ref parameters. Doing both
      results in breaking the delegate contract (no signature rewriting) or
      losing required struct arguments to intermediate closures.
      
      To elaborate on the problem here, let's consider the example:
      
      ```csharp
      using System;
      class C
      {
          public void M()
          {
              int x = 0;
              {
                  int y= 0;
                  void Local()
                  {
                      if (x == 0)
                      {
                          Action a = () => y++;
                          a();
                      }
                  }
                  Local();
              }
          }
      }
      ```
      
      The current problem in the compiler is in the code now in GetStructClosures. The previous implementation only built struct closure if the closure was being lowered onto a struct frame.
      
      However, in the example, y is being captured by a lambda, meaning that y must be in a class frame. Since Local lives in the same scope it also lives in the same frame and contains the lambda capturing y, meaning that it must live in a class frame as well. Of course, it is not converted to a delegate, nor does it capture any variables that are captured by closures converted to delegates, so its signature is free to be rewritten to take variables which are not captured by closures converted to delegates as struct environment parameters.
      
      Here is the expected lowering for the previous example:
      
      ```csharp
      void M()
      {
          var env1 = new Env1();
          env1.x = 0;
          var env2 = new Env2();
          env2.y = 0;
          env2.<>_L(ref env1);
      }
      
      struct Env1
      {
          public int x;
      }
      
      class Env2
      {
          public int y;
          public void <>_L(ref Env1 env1)
          {
              if (env1.x == 0)
              {
                  var env3 = new Env3();
                  env3.env2 = this;
                  Action a = env3.<>_anon;
                  a();
              }
          }
      }
      
      class Env3
      {
           Env2 env2;
           public void <>_anon() => this.env2.y++;
      }
      ```
      
      The problem comes when calculating the struct frames needed to be passed to Local. In the current implementation, unless the "container" is a struct, no struct frames are added. If we fix that to check for struct frames that are required as parent frames, regardless of the type of container we run into another problem.
      
      In this case, the lambda also includes struct frames in its parent "context", but adding any struct frames to a closure that is converted to a delegate is incorrect.
      
      The previous problem can be solved by a check to see if the closure can take new ref parameters. This is true for all closures except for ones marked async or iterators or ones converted to delegates. This works because of something we already know from the analysis: if we assume that struct environments are only created when the their capturing closure can take ref parameters, we can assume that any struct environments in scope are "safe" to use, even if those frames are in the "parent context" of the closure.
      
      Fixes #16895
      d6e70325
    • C
      b581d314
    • C
      Add comment. · b09a965e
      CyrusNajmabadi 提交于
      b09a965e
    • C
      Rename local. · 3bd27c20
      CyrusNajmabadi 提交于
      3bd27c20
    • C
      Add struct test. · d8143b5c
      CyrusNajmabadi 提交于
      d8143b5c
    • C
      b33fbd5a
    • C
      Add comment · b48ea48f
      CyrusNajmabadi 提交于
      b48ea48f
    • C
      Share more code. · d40bb861
      CyrusNajmabadi 提交于
      d40bb861