Re: [swift-dev] [Pitch] Remove "Default will never be executed" Warning?

2016-11-27 Thread Slava Pestov via swift-dev

> On Nov 26, 2016, at 3:25 PM, Robert Widmann via swift-dev 
>  wrote:
> 
> Hello all,
> 
> I’ve seen and been a part of a number of conversations recently where talk of 
> planning for “resilient enums”, or even just authors that ship frameworks 
> that will eventually offer a binary option that export enum-based APIs.  The 
> consensus seems to be that the only safe way to deal with this situation is 
> to always cover a `switch` statement with a default, regardless of whether 
> the totality checker thinks you’ve covered all cases.

This is not quite right. The totality checker only kicks in if the module 
containing the enum is not built with resilient interfaces. When built with 
resilience enabled (you can pass —swift-stdlib-enable-resilience=1 to 
build-script), the warning is gone, and the default case is required; without 
it, you get an error about a non-exhaustive switch.

>  Currently, the compiler warns when this is the case, as in stdlib
> 
> extension ProcessTerminationStatus {
>   var isSwiftTrap: Bool {
> switch self {
> case .exit(_):
>   return false
> case .signal(let signal):
>   return CInt(signal) == SIGILL || CInt(signal) == SIGTRAP
> default:
>   // This default case is needed for standard library builds where
>   // resilience is enabled
>   return false
> }
>   }
> }
> 
> I think this warning doesn’t actually serve a purpose and I’d like to remove 
> it, or at the very least curb it.  Currently, I see three paths forward:
> 
> 1) Do nothing.
> 2) Completely remove the diagnostic
> 3) Only emit the diagnostic when the case-tree is switching over enum(s) 
> declared inside the current module.

One workaround would be to define ProcessTerminationStatus as @_fixed_layout, 
but that attribute is not documented right now. The eventual goal is that the 
attribute will be renamed to @closed for enums, and the warning will be emitted 
even if the module was built non-resiliently.

However there’s a chance that at some point we will also be building the stdlib 
with resilience enabled by default, but I can’t comment on what the plans are 
in this area yet.

> 
> I’ve filed SR-3278  to track this as 
> well.
> 
> Thanks,
> 
> ~Robert Widmann
> ___
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] High-level SIL Optimization: How do I get a FuncRef from the stdlib?

2016-11-27 Thread Michael Gottesman via swift-dev
+CC Slava.

He has been messing around with this area in the past bit since many of us have 
looked at this. He is the person you want.

Michael

> On Nov 25, 2016, at 8:42 PM, Ben Ng  wrote:
> 
> Hi everyone,
> 
> I’ve made good progress with the information in this thread but I can’t 
> figure out how to create the proper set of substitutions for the method that 
> I’m calling.
> 
> The error I’m getting, as expected, is "SIL verification failed: callee of 
> apply without substitutions must not be polymorphic: !fnTy->isPolymorphic()"
> 
> I was hoping that there would be a way to delay specialization of the 
> function that I’m replacing so that I can simply reuse those substitutions, 
> but it doesn’t seem like that’s possible.
> 
> At a high level I assumed that I’d simply be able to substitute a type like 
> `Int` for `τ_0_0`, but it looks like I have to use a ProtocolConformanceRef, 
> which I don’t understand.
> 
> I looked into iterating through 
> `getLoweredFunctionType()->getGenericSignature()->getGenericParams()`, but I 
> don’t see how I can turn the information there into ProtocolConformanceRef.
> 
> Thanks for the help as always,
> 
> Ben
> 
>> On Nov 16, 2016, at 10:47 PM, Ben Ng  wrote:
>> 
>>> On Nov 16, 2016, at 7:11 PM, Arnold Schwaighofer  
>>> wrote:
>>> 
>>> 
 On Nov 16, 2016, at 2:58 PM, Ben Ng  wrote:
 
 Correct, that is what I am trying to do.
 
> On Nov 16, 2016, at 12:22 PM, Arnold Schwaighofer 
>  wrote:
> 
> // Really, by the time you look at this in array value prop
> // this call should have been inline and you would see a call
> // to:
> // a.append(contentsOf: [1])
 
 I do not understand this comment; I thought that inlining of stdlib 
 functions happened after high-level SIL optimizations are run. Is my 
 understanding incorrect?
>>> 
>>> 
>>> Inlining of functions with @_semantics is delayed until after high-level 
>>> SIL optimizations are run. Other functions are inlined.
>>> 
>>> https://github.com/apple/swift/blob/master/lib/SILOptimizer/PassManager/Passes.cpp#L221
>>> https://github.com/apple/swift/blob/master/lib/SILOptimizer/Transforms/PerformanceInliner.cpp#L722
>>> 
>>> 
>>> I recommend looking at the SIL function dump in 
>>> ArrayElementValuePropagation of an example function after adding 
>>> @semantics(“array.mutate_unknown”) to “append(contentsOf:)”.
>>> 
>>> 
>>> $ git diff HEAD~
>>> diff --git a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp 
>>> b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp
>>> index 76328a6..cb976f7 100644
>>> --- a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp
>>> +++ b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp
>>> @@ -259,6 +259,8 @@ public:
>>> void run() override {
>>>   auto  = *getFunction();
>>> 
>>> +Fn.dump();
>>> +
>>>   bool Changed = false;
>>> 
>>>   // Propagate the elements an of array value to its users.
>>> diff --git a/stdlib/public/core/Arrays.swift.gyb 
>>> b/stdlib/public/core/Arrays.swift.gyb
>>> index f00cc23..2acfd06 100644
>>> --- a/stdlib/public/core/Arrays.swift.gyb
>>> +++ b/stdlib/public/core/Arrays.swift.gyb
>>> @@ -1344,6 +1344,7 @@ extension ${Self} : RangeReplaceableCollection, 
>>> _ArrayProtocol {
>>> /// - Parameter newElements: The elements to append to the array.
>>> ///
>>> /// - Complexity: O(*n*), where *n* is the length of the resulting array.
>>> +  @_semantics("array.mutate_unknown")
>>> public mutating func append(contentsOf newElements: C)
>>>   where C.Iterator.Element == Element {
>>> 
>>> 
>>> # Rebuild the compiler and stdlib (without stdlib assertions).
>>> $ swift/utils/build-script -r  --assertions --no-swift-stdlib-assertions
>>> 
>>> 
>>> $ cat TestArray.swift 
>>> @inline(never)
>>> public func test() {
>>> var a = [1, 2, 3]
>>> a += [1]
>>> print(a)
>>> }
>>> 
>>> $ bin/swiftc -O 2>&1 | less
>>> ...
>>> sil shared [_semantics "array.mutate_unknown"] 
>>> @_TTSg5Si_GSaSi_GSaSi_s10Collections___TFSa6appenduRd__s10CollectionxzWd__8Iterator7Element_rfT10contentsOfqd___T_
>>>  : $@convention(method) (@owned Array>> nt>, @inout Array) -> () {
>>> 
>>> …
>>> // testArray() -> ()
>>> sil [noinline] @_TF9TestArray9testArrayFT_T_ : $@convention(thin) () -> () {
>>> bb0:
>>> %0 = alloc_stack $Array, var, name "a", loc "TestArray.swift":3:7, 
>>> scope 2 // users: %54, %32, %60, %23, %43
>>> %1 = integer_literal $Builtin.Word, 3, loc "TestArray.swift":3:12, scope 2 
>>> // user: %4
>>> %2 = integer_literal $Builtin.Int64, 3, scope 5 // user: %3
>>> %3 = struct $Int (%2 : $Builtin.Int64), scope 5 // users: %22, %7
>>> %4 = alloc_ref [tail_elems $Int * %1 : $Builtin.Word] 
>>> $_ContiguousArrayStorage, scope 5 // user: %7
>>> %5 = metatype $@thin Array.Type, scope 5   // users: %25, %7
>>> // function_ref specialized static 
>>> Array._adoptStorage(_ContiguousArrayStorage,