text:
Integrate adblocker functionality

Interesting tip from HN (for Dashblock):
Maybe you already do it, but I think integrating adblocker functionality when loading JS sites would be desirable to reduce load time. And if ads are what the API user is interested in, perhaps add a flag for whether or not one wants ads to load. Recommendation: https://github.com/cliqz-oss/adblocker Should be the fastest adblocker library (used by Ghostery, Cliqz and Brave)

This could be integrated into Apify.launchPuppeteer() function as useAdBlock: true option.
https://sdk.apify.com/docs/api/apify#module_Apify.launchPuppeteer

Greetings. So the thing would be to implement ad blocker to increase the speed of the scrap/crawl? I could work on this 🙏

Yes exactly, it could boost the speed especially for some websites that are heavy on ads (news sites). But it would be great to first test this assumption. Would you be interested also in trying this out? Use Apify SDK to run scraper with and without ad blocker against some websites?

Sure! I can set up a test and run it to check this first with some timing debug, I'll create it and run it, then attach it here for you to see, thank you 🚀

interesting. I manually block all the common ad networks using blockRequests, this would offload the task to the extension

Makes sense for a lot of users I guess but fyi it's an explicit anti-feature with usecase-killing effect for me. I'd need this off with zero sideeffects on current behavior.

Makes sense for a lot of users I guess but fyi it's an explicit anti-feature with usecase-killing effect for me. I'd need this off with zero sideeffects on current behavior.

In the small POC I proposed a while ago https://github.com/apify/apify-js/pull/600, the feature is completely disabled by default and only does some work when blocking is enabled by the user.

Yeah, sorry @remusao . We still have not figured out if the performance will improve or not. I apologize.

Yeah, sorry @remusao . We still have not figured out if the performance will improve or not. I apologize.

Of course, no worries at all, I just wanted to make clear to @matjaeck that there should be a way to integrate such a feature without any overhead when it's disabled.

authors: Darking360 jakubbalada matjaeck mnmkng mtrunkat pocesar remusao

repo: apify/apify-js


text:
🛑 Harbor is down

In dbf72db, Harbor (https://registry.openstorage.xyz) was down:

HTTP code: 521
Response time: 270 ms

Resolved: Harbor is back up in e07c713.

source: gharchive/issue

repo: apinter/OSC-mon

license: MIT

license_type: permissive

license_source: github-api


text:
optimizations for generated target code

the generated target code is rather verbose right now. for example, here is the spec program and output for the "dangerous" millionaires game:
spec:
/* the classic MPC problem */
a : {A};
c : {C};
c_richer : {(A|C)-> & (A&C)<-};
c_richer := declassify(a <= c, {(A|C)-> & (A&C)<-});

/* the dangerous version: if you have less money, you lose all of it */
if (c_richer) {
    a := 0;
} else {
    c := 0;
}

generated target code:
MPC({alice,chuck})_1 {
    c_1 <- recv chuck;
    a_1 <- recv alice;
    downgrade_1_1 := (a_1 <= c_1);
    send downgrade_1_1 to alice;
    send downgrade_1_1 to chuck;
}

alice {
    a : {⊥<-};
    c_richer : {⊥<-};
    send a to MPC({alice,chuck})_1;
    downgrade_1_2 <- recv MPC({alice,chuck})_1;
    assgn_1_1 := downgrade_1_2;
    c_richer := assgn_1_1;
    c_richer_1 := c_richer;
    guard_1_1 := c_richer_1;
    guard_1_4 := guard_1_1;
    if (guard_1_4) {
        assgn_2_1 := 0;
        a := assgn_2_1;
        a <- recv chuck;
    } else {
        assgn_3_1 := 0;
        send assgn_3_1 to chuck;
    }
}

chuck {
    c : {⊥<-};
    c_richer : {⊥<-};
    send c to MPC({alice,chuck})_1;
    downgrade_1_3 <- recv MPC({alice,chuck})_1;
    assgn_1_2 := downgrade_1_3;
    c_richer := assgn_1_2;
    c_richer_2 := c_richer;
    guard_1_2 := c_richer_2;
    guard_1_3 := guard_1_2;
    if (guard_1_3) {
        assgn_2_2 := 0;
        send assgn_2_2 to alice;
    } else {
        c <- recv alice;
        assgn_3_2 := 0;
        c := assgn_3_2;
    }
}

as you can see, there are a lot of unnecessary variables. we can run copy propagation, dead code elimination, and constant propagation to remove most of these and make the target a lot readable.

copy prop implemented in https://github.com/apl-cornell/viaduct/commit/347d4cac7362e8f16c3bd132486accea58f27348
constant prop not yet implemented

constant prop implemented in e3ccfd719801c6924b899335289b35280e6d2e6f

repo: apl-cornell/viaduct


text:
Correct license name

Usually "Apache License" means version 1, and according to other files, this library actually uses version 2.

Looks good, thanks.

source: gharchive/pull-request

authors: dlackty paolorotolo

repo: apl-devs/AppIntro


text:
Deprecating NGRX Cache

If someone is interested to maintain it, please let me know.
The whole idea behind that package and using ngrx with Apollo in general, makes no sense to me.
If anyone has any objections please comment here.

The reason to use ngrx is same as for using any other redux implementation. In particular using ngrx-store with angular-apollomakes sense in case of some part of an app would need to use ngrx/store and to avoid having two different redux implementation in the app (to my understanding that was general idea behind making new apollo client independent on redux implementation).
As for me for now I would like to relay fully on Apollo and hope to have no need to access directly underlying redux implementation.

What having a normalized cache inside of ngrx gives you? Do you use it inside ngrx as part of selectors? Having one single store that is a source of truth makes sense only if one data relies on another, if they are totally independent you can have multiple of them.

Main reason would be the size of an app and avoid pulling in one more dependency (well set of deps)

Also, when you're using ngrx/router-module in combination with apollo graphql that package is rather useful.

I was just exploring this library, here's what I thought the library was doing, maybe that'll be helpful.
Typically, most usages of ngrx store will look something like:

Ask to load some data using an action
Have an effect do the actual loading, and dispatch an action when the data has been loaded
Have a reducer update the store with the loaded data (and more specifically, resolve updating v.s. adding to lists, e.g. using ngrx entity)
Use a selector to get the updated data, if it was updated

Since with Apollo and GraphQL it's possible to identify entities, it would be possible to normalize the returned data in a store any time a query is made. Then I can simply use a selector to get it from the "cache". It would remove a lot of boilerplate for most use cases, and for any use cases where the store has more complex logic, the apollo ngrx store would only be used as a cache.
I agree that using ngrx store as a simple cache does not make a lot of sense by itself, but making it easier to update complex models in a store automatically could be very useful, at least in simpler apps.
This however would require "breaking down" the response in separate Entity lists, and to be useful you'd have to map these entities to a type (e.g. using graphql-code-generator). Then it would look something like:

Same
Same, except my service would use a graphqlquery, AND it would update the apollo store.
No reducer required (except if you need to do something fancy, you can alway use the response and do something with it but it's not necessary)
Use a selector to get the data (and it could be possible to generate those too for most cases, like "selected entry in a list", "all items in a list", etc.)

Hope that helps!

If someone wants to take care of apollo-angular-cache-ngrx then feel free to message me, do pull requests, I will merge all of that, right away.
Since I don't use it, I see no point of me maintaining it.

@kamilkisiela what's your suggested apollo, angular local state management stack?
Just a few thoughts: if you use just apollo client as ngrx replacement, how do you implement effects?
If you use apollo-client and ngrx than you have decent router and effects support but you have to transform the graphql responses into the ngrx store.
Is there any approach I am missing which solves these disadvantages?

IMO you should just use apollo for state management. What would be the case where you may need to access store directly?
effect in Apollo are just GraphQL queries/mutations and if you need i.e. access geolocation then you still can do this with @client resolvers

@ciekawy interesting approach. But isn't the idea of redux/ngrx to separate pure reducers from effects with side effects. With the approach you mentioned, it feels a bit like these two concepts are not clearly separated anymore.

Apollo is supposed to fully take over the state management. I moved to Apollo with similar concerns initially and now I am using only Apollo. Biggest benefits for me:

no more need for verbose boilerplate of reducers and effect. Initially I really liked the concept of redux for state management. Now I love Apollo even more :)
there are various integrations available for non-graphql data sources @client for anything client-side, @rest for REST endpoints you cannot move to GraphQL, also you can define your own as well.

here you can read more
https://blog.apollographql.com/the-future-of-state-management-dd410864cae2

another important value is that Apollo do also data normalization when keeping it in local store

Thx @ciekawy I will dig into that one more time.
Actually I thought that loonajs will be the solution to fill the gap between the redux approach and apollojs/graphql. But atm it seems like that the guild also lost its confidence in the loonajs approach. I would be really interested what the guild (@kamilkisiela, @urigo,...) is suggesting as best approach.

A usecase I have come across is about synchronisation of cache/store. I have a dumb component that emits two events in certain cases on a single browser UI event. The handler for first event mutates the client state, then second handler picks that state and performs server mutation. With ngrx store, the store update by first handler by action dispatch appears synchronous, and the effect for action from second handler gets the updated state. However, with apollo, the client only mutation is not synchronous, possibly because it uses promise api internally. Therefore, the mutation from second handler does not get updated data from cache.

If someone wants to maintain NGRX cache for Apollo I would be happy to see a fork so I could give an access to the package on npm.

authors: ceelian christianrondeau ciekawy kamilkisiela wesselvdv wolfvik

repo: apollographql/apollo-angular


text:
Add test for sdl field

This test will check that the sdl field inside the _service object type has the right type (non-nullable string).
Apollo Studio and potentially other Apollo tools check this field to enable/disable federation features.
TODO:

[ ] Add directives

@dariuszkuc I wonder if we should make a new table for directives (which I haven't added just yet), my main issue with this test is that it is hard to see what fails, since it stops at the first failure

@patrick91 if this is still an issue feel free to re-open this PR


text:
Can schema stitching be implemented in Python ?

Sorry, that wouldn't be in this library.

repo: apollographql/graphql-tools


text:
make afterware errors bubble up

This makes errors thrown from afterwares bubble up so that apollo don't try to parse bad responses.
TODO:

[ ] If this PR is a new feature, reference an issue where a consensus about the design was reached (not necessary for small changes)
[ ] Make sure all of the significant new logic is covered by tests
[x] Rebase your changes on master so that they can be merged easily
[ ] Make sure all tests and linter rules pass
[ ] Update CHANGELOG.md with your change
[x] Add your name and email to the AUTHORS file (optional)
[ ] If this was a change that affects the external API, update the docs and post a link to the PR in the discussion

@edvinerikson Thanks for the PR! Can you explain what problem this solves and add a test case if applicable? Right now it doesn't look like your PR would change any behavior.

Looks like the change makes it so that the promise returns the return value of the afterware. However this should definitely come with a test that ensures the behavior continues to work, especially since it's so easy to miss.

Yeah I will add a test. I just need to fix my local setup first. Can't run
it locally due to TS errors.
On Fri, 2 Dec 2016 at 23:55, Sashko Stubailo notifications@github.com
wrote:

Looks like the change makes it so that the promise returns the return
value of the afterware. However this should definitely come with a test
that ensures the behavior continues to work, especially since it's so easy
to miss.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/apollostack/apollo-client/pull/982#issuecomment-264584646,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADtdjIkVxD0gvTIVN8hR7lwS3Y2vvHcNks5rEKHHgaJpZM4LCi3H
.

@helfer the reason for the change is because I have a afterware which I check the response status and decide if Apollo will be able to parse the response. in some cases Apollo won't be able to do that and when that happens I throw a error which I can catch in my error handling but without this change I am not able to catch the error and instead Apollo will fail with when trying to parse the json body.
e.g getDataFromTree(app).catch(error => doSomethingWithErrorHere()) but currently the error I get there will be something like unexpected token < at 1:1 (due to a html response) instead of my own error.

maybe a improvement to the network layer would be to check response.ok before trying to parse / handle the response as well. will probably help fix some of the cryptic error messages that I get sometimes.

@edvinerikson Okay. Please add a test, and then we can merge it.
I think checking response.ok won't work, because some people return error codes that are not in the 200 range for responses that should be parsed and processed. It's unfortunate, but I think we have to live with that for now.

I think checking response.ok won't work, because some people return error codes that are not in the 200 range for responses that should be parsed and processed. It's unfortunate, but I think we have to live with that for now.

Yeah I will create my own network layer to handle my cases instead.
Still gonna try to add a test and get this merged.

test is added

Sweet, thanks a lot!

authors: edvinerikson helfer stubailo

repo: apollostack/apollo-client

license: mit

license_source: bigquery


text:
Add Whatsapp Icon

Description
Add a WhatsApp icon to connect with the admin on WhatsApp
Screenshots
No response
Additional information
No response

@apoorvaron Kindly assign me this issue

@Nishitbaria assigned
Now start solving issues😂

@apoorvaron I have done this one already i was just uploading video

https://github.com/apoorvaron/Shorty/assets/85815172/34d7e252-f599-4aed-a0cc-082196ee704e

@apoorvaron Since its Friday so last working day in my job and very less load so trying to create issue and finding some raw solution then full working from tomorrow

https://github.com/apoorvaron/Shorty/assets/85815172/c4a3c7ff-9f81-462d-85c5-ae6009b4aa65

@apoorvaron Thanks Man

authors: Nishitbaria apoorvaron

repo: apoorvaron/Shorty


text:
feat: apply stopwords by language

What does this do / why do we need it?
https://www.notion.so/appbase/Arc-Suggestions-API-enhancements-2a4c26df77d44a77b751d9e13cf4cb0f
What should your reviewer look out for in this PR?
Which issue(s) does this PR fix?
If this PR affects any API reference documentation, please share the updated endpoint references

@siddharthlatest Docs PR https://github.com/appbaseio/Docs/pull/246

If searchLanguage isn't explicitly passed in RS API, will this take the search relevance's language for stopwords? It should be this way.

Yes, review this PR https://github.com/appbaseio-confidential/arc-noss/pull/230

repo: appbaseio/reactivesearch-api


text:
Kafka is not reachable from amplifier

Amplifier is connecting to kafka through localhost:9092.
However, this hostname is used only for the first connection to kafka. On this first call, kafka gives its own hostname to the client (amplifier).
The problem is that the hostname given by kafka (which is actually the kafka container short id) is not reachable from amplifier because it's not part of amp-swarm network.
Possible fixes:

Running amplifier as a container and make it part of the amp-swarm network using docker run , however services and containers cannot be part of the same network.

docker run --network amp-swarm appcelerator/amp
docker: Error response from daemon: swarm-scoped network (amp-swarm) is not compatible with `docker create` or `docker run`. This network can only be used by a docker service.
See 'docker run --help'.

Giving the service a hostname, however, I don't think it's possible:

docker service create --help

Usage:	docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]

Create a new service

Options:
      --constraint value               Placement constraints (default [])
      --container-label value          Container labels (default [])
      --endpoint-mode string           Endpoint mode (vip or dnsrr)
  -e, --env value                      Set environment variables (default [])
      --help                           Print usage
  -l, --label value                    Service labels (default [])
      --limit-cpu value                Limit CPUs (default 0.000)
      --limit-memory value             Limit Memory (default 0 B)
      --log-driver string              Logging driver for service
      --log-opt value                  Logging driver options (default [])
      --mode string                    Service mode (replicated or global) (default "replicated")
      --mount value                    Attach a mount to the service
      --name string                    Service name
      --network value                  Network attachments (default [])
  -p, --publish value                  Publish a port as a node port (default [])
      --replicas value                 Number of tasks (default none)
      --reserve-cpu value              Reserve CPUs (default 0.000)
      --reserve-memory value           Reserve Memory (default 0 B)
      --restart-condition string       Restart when condition is met (none, on-failure, or any)
      --restart-delay value            Delay between restart attempts (default none)
      --restart-max-attempts value     Maximum number of restarts before giving up (default none)
      --restart-window value           Window used to evaluate the restart policy (default none)
      --stop-grace-period value        Time to wait before force killing a container (default none)
      --update-delay duration          Delay between updates
      --update-failure-action string   Action on update failure (pause|continue) (default "pause")
      --update-parallelism uint        Maximum number of tasks updated simultaneously (0 to update all at once) (default 1)
  -u, --user string                    Username or UID
      --with-registry-auth             Send registry authentication details to swarm agents
  -w, --workdir string                 Working directory inside the container

Running amplifier as a service: It's definitely possible, however, it's not compatible with development where you need to be able to quickly launch, fix, and repeat. Indeed, docker services are not using local images but instead pull images from the hub (or a private registry) on each start (check this issue https://github.com/docker/swarmkit/issues/1246). It would require to push, build and publish the image every time which defeats the purpose.

The only workaround I found so far is to add kafka container hostname to /etc/host:
Getting kafka hostname:
docker ps
docker inspect kafka_container_id | grep hostname
sudo cat /var/lib/docker/containers/a4424bcafbab110b67922994243aca15fc57ab3422fdec21f7460fe16b024456/hostname

Update /etc/hosts in order to assign 127.0.0.1 to kafka hostname:
127.0.0.1	localhost a4424bcafbab

Unfortunately the following doesn't work for Docker for Mac:
sudo cat /var/lib/docker/containers/a4424bcafbab110b67922994243aca15fc57ab3422fdec21f7460fe16b024456/hostname

On Docker for Mac these files are stored in the VM located here:
$HOME/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2

But since it looks like the hostname is just the short-id anyway, I think this will work (at least for our temporary workaround right now):
docker ps --filter "name=kafka\." --format '{{ .ID }}'

(The funky filter is to eliminate kafka-manager from the result.)
I'll test that out and report my results back here shortly.

We need a better interim strategy; asking everyone to help brainstorm on this.

It seems like advertised.listeners might be what we're looking for in the Broker Configs docs...

@bertrand-quenin @ndegory Can you two investigate further?

Regarding my last comment, I don't think the issue is advertising the hostname, it's making sure the hostname is available outside the swarm's network when we're developing ...

I suppose this is where kafka updates and then gets the server address for subsequent requests on the client broker:
https://github.com/Shopify/sarama/blob/master/broker.go#L83
https://github.com/Shopify/sarama/blob/master/broker.go#L161

@subfuzion Actually, I already tried this solution. It effectively makes kafka reachable from amplifier by advertising localhost. The problem is that other components (telegraf, amp-log-worker) are trying to reach kafka on localhost as well ... making them fail miserably.

@bertrand-quenin Unfortunately, that makes perfect sense.

We may have to create a script that can take the output of docker ps --filter "name=kafka\." --format '{{ .ID }}' and update the entry for 127.0.0.1 in /etc/hosts. We can call the script from the swarm script when we start up the swarm. @ndegory, we're all slammed preparing for our deadline on Monday; is there any way you can take this on for us?

I'll take a look

@bertrand-quenin Now that I think about it, can't we override the address in the client after it gets updated with the server's metadata, just to ensure we're using the address we want to use? After all, in the real swarm we would want to use the actual DNS name (kafka) anyway since swarm is load balancing for us. There isn't some special requirement for affinity to a particular server in the cluster, is there?

Thanks for the PR, @ndegory. It's working well for now. I'll leave this issue open while we consider our long term strategy for this and similar/related issues.

There is another solution which do not imply modify /etc/host.
If we have amplifier inside swarm network it works as explains above, but then the issue that we can't build locally an amplifier image to test.
Except, for the test need, we modify the amplifier image name 'appcelerator/amp' to 'appcelerator/amp_fr (for instance for me) and modify the swarm file to point on this image name instead of the normal.
Then, all work, docker see that appcelerator/amp_fr doesn't exist in repo and use the local image

@bertrand-quenin Can you respond to https://github.com/appcelerator/amp/issues/69#issuecomment-242868643?

Yes, it's an alternate solution to this issue. It can work as well.

@freignat91 @bertrand-quenin @ndegory Since I prefer that we switch to NATS, I'm not particularly concerned about the long term resolution for this particular issue at this point. However, it is definitely the case that amplifier will eventually expose its services on an overlay network (for example, amp-swarm-public), and it will also overlap with the backbone network (amp-swarm) to communicate with our infrastructure services. @freignat91, we should start moving toward this configuration this sprint, and also start incorporating haproxy for mapping exposed IPs to consumers (eg, the CLI).

It's interesting to be aware of how clusters and node discovery impact other services for client communication as well. For example, the etcd client when etcd is behind a load-balanced cluster: https://github.com/hashicorp/vault/pull/921.

Since we have a working solution in place for now thanks to @ndegory and our priority has shifted to transitioning to NATS (#113), I'm going to close this.

authors: bertrand-quenin freignat91 ndegory subfuzion

repo: appcelerator/amp


text:
Default retention policy for InfluxDB 1.0.0

Hi, I found an issue and came up with a way to fix it.
The issue: InfluxDB changed the name of the default retention policy in 1.0.0 from "default" to "autogen". The telegraf.conf.tpl file needs to be updated.
Proposed fix: To make this work and be backwards compatible I created an env variable for the policy name. I have it defaulting to "default". It could default to "", which is what the telegraf 1.0.0 telegraf.conf file has.
To make it clear how to use it I added it to the custom example at the top of the readme.

My pleasure.

repo: appcelerator/docker-telegraf


text:
How to test that a button is disabled

On Android, I have disabled a button being able to get clicked until a certain condition is met within the input.
(Python client)
The object currently has clickable="false" in the XML but the appium driver tells me different, because - button.is_enabled() returns True

In the case, you can get an arbitrary element with el.get_attribute('clickable').
https://github.com/appium/python-client/blob/f37733dbd3dd79be97452a9ad98eb4a9325755ce/test/functional/ios/find_by_ios_class_chain_tests.py#L32
If your xml says the element is disable, you can see false by el.get_attribute('clickable').
BTW, enable and clickable are https://stackoverflow.com/questions/15615823/setenabled-vs-setclickable-what-is-the-difference
If you have any issue, the page source and logs are helpful for us.

authors: Enether KazuCocoa

repo: appium/sample-code


text:
Generalize the removal of compiler argument options during indexing

The existing ad-hoc logic was not quite correct because it didn’t eg. remove -MT/depfile because it assumed that -MT was followed by a space. It also didn’t take into account that serialize-diagnostics can be spelled with a single dash or two dashes.
Create a CompilerCommandLineOption type that forces decisions to be made about the dash spelling and argument styles, which should help avoid problems like this in the future.

@swift-ci Please test

@swift-ci Please test

@swift-ci Please test Windows

@swift-ci Please test Windows

@swift-ci Please test Windows

repo: apple/sourcekit-lsp


text:
TestURLSession: Re-enable tests

Re-enable the TestURLSession tests which should no longer be flaky
however specifc tests are still disabled due to known issues.

Disable test_concurrentRequests() as this fails about 4% of the time.

Disable test_getAllTasks() as this causes other tests to fail.

@swift-ci test linux

@swift-ci test linux

@swift-ci test linux

repo: apple/swift-corelibs-foundation


text:
Convert DowningStrategyShell into a distributed actor

Resolves https://github.com/apple/swift-distributed-actors/issues/935

Only one thing about the logger: https://github.com/apple/swift-distributed-actors/pull/938#discussion_r889430590 otherwise ready to go, thank you!

authors: ktoso yim-lee

repo: apple/swift-distributed-actors


text:
Prevent scrolling on navigation event if router meta field preventScrolling is true

Bug/issue #, if applicable: rdar://103146273
Summary
If preventScrolling in the meta field is set to true, then we should not change the scroller location when navigating to a new page.
Dependencies
rdar://103119754
Testing
Steps:

set preventScrolling to true for a page (i.e. '/foo')
Scroll down a little bit on any page (i.e. '/bar').  ('/foo' should be longer than '/bar')
trigger a navigation event to '/foo'
Verify that the scroller did not move up/down nor left/right

Checklist
Make sure you check off the following items. If they cannot be completed, provide a reason.

[x] Added tests
[x] Ran npm test, and it succeeded
[ ] Updated documentation if necessary - NA

@swift-ci test

repo: apple/swift-docc-render


text:
[Collections] add should only add to config if fetch is successful

Motivation:
The code currently adds a collection source to the config even when initial fetch fails.
Modifications:
We should fetch collection first and make sure that's successful before adding to config.
Result:
Bad sources are not added to the config.

@swift-ci please smoke test

@swift-ci please smoke test

@swift-ci please smoke test

@swift-ci please smoke test

@swift-ci please smoke test

@swift-ci please smoke test

@swift-ci please smoke test

@swift-ci please smoke test

authors: abertelrud yim-lee

repo: apple/swift-package-manager


text:
Remove reference to AsTypePattern

Companion of https://github.com/apple/swift-syntax/pull/1178.

https://github.com/apple/swift-syntax/pull/1178
@swift-ci Please test

repo: apple/swift-stress-tester


text:
[SyntaxParse] Revert syntax parsing changes from the master branch

Update for https://github.com/apple/swift/pull/27675

@swift-ci Please test

repo: apple/swift-syntax


text:
Fix RawSyntax's leading/trailingTrivia computation to return nil if the outermost children don't have leading/trailing trivia

Previously they would skip over outer children that didn't have leading/trailing trivia until they found one that did. This was causing those trivia to be included twice when computing the totalLength/byteSize of the node; once in leading/trailingTrivia and again in contentLength, which only skipped the trivia of the outermost children.

@swift-ci please test

Good catch. Thanks. We should also cherry-pick this over to swift-4.2-branch once #6 is merged.

authors: ahoppen nathawes


text:
build: ignore deprecation warnings on Windows

Adjust the compile flags for TSCBasic on Windows.  Avoid the separate
checks and addition of flags in favour of generator expressions.

CC: @tomerd @neonichu @abertelrud

@swift-ci please test

do we have windows CI for this?

Not yet, but the nighters do build t-s-c, as we bring up more pieces we can enable them.

e.g. https://dev.azure.com/compnerd/swift-build/_build/results?buildId=35571&view=logs&s=4a582161-ef84-5ffa-1ff0-506a7473f086&j=73ce2acc-4df7-56ec-1894-6d2e45aae46f

authors: compnerd tomerd

repo: apple/swift-tools-support-core


text:
[SR-15154] ObjC projects using SPM fail when we expose our models into another module

Previous ID
SR-15154

Radar
rdar://problem/82827693

Original Reporter
taquitos (JIRA User)

Type
Bug

Attachment: Download

Additional Detail from JIRA

Votes
3

Component/s

Labels
Bug

Assignee
None

Priority
Medium

md5: 4659038e109b6bed99ec521e272addf0

Issue Description:
Setup:
We create an ObjC App that uses our SPM package "RevenueCat".
In our app, we create an object that uses an object from the "RevenueCat" package as part of its api.
We expose this object's header (which exposes the method containing the RevenueCat object as a parameter) as a public header.
We create a Swift test target that depends on the ObjC App and has a bridging header for that object we created.
We attempt to use the API in a test. API that doesn't include RevenueCat objects is fine, but any API that uses RevenueCat objects in the parameter is not found.
Environment:
Xcode 12.5.1 (Build version 12E507) & Xcode 13 Beta 5
M1 Mac as well as Intel mac.
Swift Package Manager - Swift 5.4.0
Swift Package Manager - Swift 5.5.0
Component: Package Manager
Reproduction project: https://github.com/taquitos/SPMBug
Attempt to build the test target.
You'll get
`Value of type 'TaquitosAreTheBest' has no member 'purchaserInfo'`

I have faced similar issue. This bug is also reproduces in mixed Swift/Objective-C project (not only in Test target).
Case: header file has forward class declaration from SPM and this type used for declare properties or parameters in this header.
Those properties and parameters won't be exposed into Swift.
You will receive build error:

👋 We have encountered this same issue while converting the Braintree SDK from Obj-C to Swift. Our SDK is comprised of several sub-modules, and while we thought we could convert to Swift module-by-module, this SPM bug has us blocked and forced to convert our entire SDK at once.
Our team has created a Swift Forum post on the issue here, for those that want to follow along / try to gain traction.

cc @tomerd

@tomerd Please help me transfer this if it is indeed a package manager issue.

cc @abertelrud @neonichu

Sounds like an Xcode issue to me.

authors: AnthonyLatsis neonichu oleksandryevdokymov scannillo swift-ci tomerd

repo: apple/swift


text:
Partial block result builder fails to pick correct overload and generates compiler error

Description
Partial block result builder fails to pick correct overload and generates a compiler error Ambiguous use of 'parser(of:)'
Steps to reproduce
Paste the following code into a new project
(This issue is a reduction of trying to compile an example (final 4 lines of the code below) of the swift-parsing package)
//MARK: Parsers
@rethrows public protocol Parser<Input> {
    associatedtype Input
}

extension String: Parser {
    public typealias Input = Substring
}

extension Int {
    static func parser(
        of inputType: Substring.Type = Substring.self
    ) -> FromSubstringToUTF8<IntParser<Substring.UTF8View>> {
        FromSubstringToUTF8 { IntParser<Substring.UTF8View>() }
    }

    static func parser(
        of inputType: Substring.UTF8View.Type = Substring.UTF8View.self
    ) -> IntParser<Substring.UTF8View> {
        .init()
    }
}

struct FromSubstringToUTF8<P: Parser>: Parser where P.Input == Substring.UTF8View {
    typealias Input = Substring

    let parser: P

    init(@ParserBuilder _ build: () -> P) { self.parser = build() }
}

struct IntParser<Input: Collection>: Parser where Input.SubSequence == Input, Input.Element == UTF8.CodeUnit {
    public init() { }
}

//MARK: ParserBuilder
struct Parse<Parsers: Parser>: Parser {
    typealias Input = Parsers.Input

    let parsers: Parsers

    init(@ParserBuilder with build: () -> Parsers) { self.parsers = build() }
}

@resultBuilder
struct ParserBuilder {
    public static func buildPartialBlock<P: Parser>(first: P) -> P { first }

    public static func buildPartialBlock<P0, P1>(accumulated: P0, next: P1) -> SkipFirst<P0, P1> {
        .init(p0: accumulated, p1: next)
    }
}

struct SkipFirst<P0: Parser, P1: Parser>: Parser where P0.Input == P1.Input {
    typealias Input = P0.Input

    let p0: P0
    let p1: P1
}

//MARK: main
let first = ParserBuilder.buildPartialBlock(first: ",")
let second = ParserBuilder.buildPartialBlock(accumulated: first, next: Int.parser())

let parser = Parse {
    ","
    Int.parser() // Ambiguous use of 'parser(of:)'
}

Expected behavior
This compiles for toolchain 2023-01-02 but breaks from 2023-01-07.
Expected to compile and choose the correct overload (in this case static func parser(of inputType: Substring.Type = Substring.self))
Since the first parser passed to the resultBuilder closure is of type String therefore the Parser associated type Input is of type Substring. Therefore the compiler should be able to infer that the parser returned by Int.parser() should have an Input of Substring as well.
Calling the individual partialBuildBlock functions does compile
works:
let first = ParserBuilder.buildPartialBlock(first: ",")
let second = ParserBuilder.buildPartialBlock(accumulated: first, next: Int.parser())

fails:
let parser = Parse {
    ","
    Int.parser() // Ambiguous use of 'parser(of:)'
}

Environment

Swift compiler version info Swift Development Snapshot 2023-01-09
Xcode version info Xcode 13.4.1 Build version 13F100
Deployment target: M1 running macOS 12.5

Ran using the 2023-01-06 snapshot as well and that fails to compile too.

@JaapWijnen We have changed implementation to be more strict about how the inference works (aligned with https://github.com/apple/swift-evolution/blob/main/proposals/0348-buildpartialblock.md) and as per proposal result builder is a source transform that works this way:
let parser = Parse {
    let __builder0 = ","
    let __builder1 = Int.parser()

    let __builder2 = ParserBuilder.buildPartialBlock(first: __builder0)
    let __builder3 = ParserBuilder.buildPartialBlock(accumulated: __builder2, next: __builder1)
    return __builder3
}

which means that buildPartialBlock cannot in any way affect type-checking behavior of Int.parser().

The fix here would be to use static func buildExpression<T: Parser>(_ expression: T) -> T { expression }

@Xedin
Hm I'm not sure I 100% follow. In the process of creating a reproduces I might have minimised my example a bit too much to convey what I'm actually trying to do. Let me know if your answer still applies after my explanation in that case I'm missing how I would have to implement your suggested fix.
What is actually happening in my use case is that on the Parser protocol there's a function that takes an inout input, produces an output and in the process modifies that input. The modified input is then passed to the next parser (In this case the Int parser). Therefore there's this dependency that both parsers have the same Input associatedtype. This restriction in this example is implemented by the type constraints on the SkipFirst parser.
The first parser is a string and it's defined to have an Input of Substring therefore SkipFirst<String, X> is required to have an Input of Substring which in turn requires X (in this case an IntParser) would be required to have Substring as input.
To describe, the full call hierarchy would be as follows: (This writing might be obvious and/or I'm not sure what's the best way of communicating this is) I'll add an updated version of my code below as well.)
I'd expect the Parse { } call to return a parser of type:
Parse<SkipFirst<String, FromSubstringToUTF8<IntParser<Substring.UTF8View>>>>
we can call parse(&input) on that which just passes it on to SkipFirst since that contains a single parser
This in turn will call two parsers

first p0.parse(&input) this runs removes the "," input and returns Void
second p1.parse(&input) // FromSubstringToUTF8<IntParser<Substring.UTF8View>>

this second call  in turn calls a parser that wraps a parser of a different input. Since the IntParser does not work for an input of SubString as it's requiring Input: Collection where where Input.SubSequence == Input, Input.Element == UTF8.CodeUnit
So this parser, FromSubstringToUTF8, transforms the input, calls parse(&transformedInput), modifying it and then transforms the modified input back to the original Input type and overwrites the input variable.
Finally propagating the returned value of the IntParser to the FromSubstringToUTF8 to the SkipFirst and finally returning the value.
I really hope this is helpful. Let me know if there's information missing/unclear or how I can help in any other way!
code:
struct ParsingError: Error { }

//MARK: Parsers
@rethrows public protocol Parser<Input, Output> {
    associatedtype Input
    associatedtype Output

    func parse(input: inout Input) throws -> Output
}

extension String: Parser {
    public typealias Input = Substring

    public func parse(input: inout Substring) throws {
        guard input.starts(with: self) else {
          throw ParsingError()
        }
        input.removeFirst(self.count)
    }
}

extension Int {
    static func parser(
        of inputType: Substring.Type = Substring.self
    ) -> FromSubstringToUTF8<IntParser<Substring.UTF8View>> {
        FromSubstringToUTF8 { IntParser<Substring.UTF8View>() }
    }

    static func parser(
        of inputType: Substring.UTF8View.Type = Substring.UTF8View.self
    ) -> IntParser<Substring.UTF8View> {
        .init()
    }
}

struct FromSubstringToUTF8<P: Parser>: Parser where P.Input == Substring.UTF8View {
    typealias Input = Substring

    let parser: P

    init(@ParserBuilder _ build: () -> P) { self.parser = build() }

    func parse(input: inout Substring) throws -> P.Output {
        var transformedInput = input.utf8
        let result = try parser.parse(input: &transformedInput)
        input = Substring(transformedInput)
        return result
    }
}

struct IntParser<Input: Collection>: Parser where Input.SubSequence == Input, Input.Element == UTF8.CodeUnit {
    public init() { }

    func parse(input: inout Input) throws -> Int {
        // some int parsing logic
        return 4
    }
}

//MARK: ParserBuilder
struct Parse<Parsers: Parser>: Parser {
    let parsers: Parsers

    init(@ParserBuilder with build: () -> Parsers) { self.parsers = build() }

    func parse(input: inout Parsers.Input) throws -> Parsers.Output {
        try parsers.parse(input: &input)
    }
}

@resultBuilder
struct ParserBuilder {
    public static func buildPartialBlock<P: Parser>(first: P) -> P { first }

    public static func buildPartialBlock<P0, P1>(accumulated: P0, next: P1) -> SkipFirst<P0, P1> {
        .init(p0: accumulated, p1: next)
    }
}

struct SkipFirst<P0: Parser, P1: Parser>: Parser where P0.Input == P1.Input {
    let p0: P0
    let p1: P1

    func parse(input: inout P0.Input) throws -> P1.Output {
        let _ = try p0.parse(input: &input)
        return try p1.parse(input: &input)
    }
}

//MARK: main
let first = ParserBuilder.buildPartialBlock(first: ",")
let second = ParserBuilder.buildPartialBlock(accumulated: first, next: Int.parser())

let parser = Parse {
    ","
    Int.parser() // Ambiguous use of 'parser(of:)'
}

var input = ",4"[...]
let result = try parser.parse(input: &input)
print(result) // 4

I understand what you mean, this kind of workflow is not what is going to be supported by result builder transform implementation going forward. The result builder transform semantics are such that each element in the body is type-checked independently from others and the resulting value is then passed to a final buildBlock or a series of buildPartialBlock calls and returned just like I outlined in my example, the old implementation failed to enforce the "solved independently" bit which caused all sorts of diagnostics and performance issues.
In your example there are two overloads of parser(of:) method, both have argument that accepts a default value which means that the type-checker won't be able to disambiguate between them without buildExpression or buildPartialBlock providing more context (via generic requirements) just like if you wrote _ = Int.parser() without using result builders.

So does this mean that code previously relying on this feature will fail to compile in a future release?
I've seen multiple uses of this in libraries that use resultBuilders to create sort of pipelines which might be an easier example than my above parser example.
// a pipeline has an input and output
let pipeline = Pipeline {
  Pipeline1 // input: A, output: B
  Pipeline2 // input: B, output: C
  Pipeline3 // input: C, output: D
}

These types Pipeline1, 2 and 3 are then no longer able to be defined using generics and type restrictions? Is that correct?
Or is there a fix for my example that I'm missing at the moment?

It’s not about generics or type restrictions, the problem is that implementation did not adhere to the proposed semantics and allowed invalid code to type-check, which would not longer be the same. There are ways to change the result builder itself to archive portion of what was allowed before but cross-element inference would not be supported.

Just to clarify you can still use buildParticalBlock to produce a chain you described A -> B -> C -> D but it would not operate on the original elements, the builder transform in your example is going to be:
var __builder0 = Pipeline1()
var __builder1 = Pipeline2()
var __builder2 = Pipeline3()

var r0 = Pipeline.buildPartialBlock(first: __builder0)
var r1 = Pipeline.buildPartialBlock(accumulated: r0, next: __builder1)
var r2 = Pipeline.buildPartialBlock(accumulated: r1, next: __builder2)

return r2

not:
var r0 = Pipeline.buildPartialBlock(first: Pipeline1())
var r1 = Pipeline.buildPartialBlock(accumulated: r0, next: Pipeline2())
var r2 = Pipeline.buildPartialBlock(accumulated: r1, next: Pipeline3())

return r2

because that violates the code principle behind result builders - type-checking of Pipeline{1, 2, 3} initializers would be affected by buildPartialBlock.
If either Pipeline1, Pipeline2 or Pipeline3 initializers are ambiguous all you can do is to use buildExpression to provide additional context.
This is exactly how the transform is described in the proposal that I've mentioned.

Aha that is very helpful! What I then finally perhaps fail to understand is how to use 'buildExpression' to add context could you elaborate a little bit on that?

Sure! static func buildExpression when declared is going to be called for every element, back to your previous example:
var __builder0 = Pipeline.buildExpression(Pipeline1())
var __builder1 = Pipeline.buildExpression(Pipeline2())
var __builder2 = Pipeline.buildExpression(Pipeline3())

var r0 = Pipeline.buildPartialBlock(first: __builder0)
var r1 = Pipeline.buildPartialBlock(accumulated: r0, next: __builder1)
var r2 = Pipeline.buildPartialBlock(accumulated: r1, next: __builder2)

return r2

So you could declare that method in Pipeline to have any kind of generic parameters and return type, for example:
static func buildExpression<T: SomeProtoocol>(_ expression: T) -> T { expression }

This would make sure that Pipeline{1, 2, 3} all conform to SomeProtocol.

Got it! Thanks @xedin. One final question in that case. Is there then a possibility to also restrict associated types of that protocol? As in I'd like for all types supplied to the result builder that A they conform to SomeProtocol and B that their associated types SomeType (contained in SomeProtocol) are equal? Or is that not possible?

Yes, you can place whatever generic requirements are necessary i.e. <T: SomeProtocol>(...) where T.SomeType == ..., T.SomeOtherMember : OtherProtocol etc.

Hmm I don't fully follow. I can't make the requirement for the following example:
protocol: SomeProtocol {
  associatedtype Input
  associatedtype Output
}

struct P1<Input>: SomeProtocol {
  typealias Output = Int
}
struct P2<Input>: SomeProtocol {
  typealias Output = String
}

//When using these in a result builder:
let object = Builder {
  P1()
  P2()
}

Can I force the Input associated type to be the same for all entries given to the builder? I don't see how to do that with restrictions on buildExpression that seems to me to only put restrictions on the individual entries is that correct?

There are a couple of ways depending on what you want.

You can make your builder generic like this:

@resultBuilder
struct Builder<T> {
  static func buildExpression<U: SomeProtocol>(_ e: U) -> U where U.Input == T { e }

  ...
}

This would make sure that Input is the same for all the elements eagerly.

You could also enforce that requirement in a buildBlock:

@resultBuilder
struct Builder<T> {
  static func buildBlock<Input, T0: SomeProtocol, T1: SomeProtocol, ...>(_ t0: T0, _ t1: T1) -> <#Result#> where T0.Input == Input, T1.Input == Intput, T<N> == Input { e }

  ...
}

The caveat here is that element type-checking is free to pick what ever overload for actual elements.

@xedin ah yes Nr 1 is exactly what I've been trying the last few minutes! It seems to work for my minimum example fine. I've also applied it to the library as a whole but unfortunately haven't had success of getting it to fully work as before.
Thanks for all the help!

No problem! I'm going to resolve this one, feel free to reach out on forums as well if you need more help with result builders.

@xedin Do you happen to remember which recent PRs were involved in the change? Would be interested in reading up on that context.

The implementation is https://github.com/apple/swift/pull/60065 and there are a few smaller follow-up PRs. Enablement is https://github.com/apple/swift/pull/62734. I’m also working on a forums post to announce the change and describe some of the situations that were allowed before but wouldn’t be now.

@xedin Thanks! Will be interested to see how it improves result builder compile times generally :smile:

@xedin @stephencelis Might be interesting: I've worked on making the result builder generic over Input for swift-parsing But am running into long build times for some parsers and some even times out with The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

Do you have a branch where you are making these changes? I can probably take a look and give you suggestions.

@xedin that would be great! My changes can be found here: https://github.com/jaapwijnen/swift-parsing/tree/generic-parser-builder
I've commented out some tests (which you can see in the changes) these were the ones that were mostly acting up.

No worries, I'll try to take a look tomorrow. If you could reduce a problematic case together with the builder and post here that would be very helpful as well.

Hmm it's hard to isolate the builder from the library in a singular case. Which is what makes it so hard for me to debug why it's having trouble compiling the parser. Is there any way to identify which resultBuilder methods are used under the hood?
Here's an example of a parser that's not compiling at the moment however (taken from one of the tests I commented out in the PR I linked):
var parser = Parse {
  "Hello"
  if parseComma {
    ","
  }
  " "
  Prefix { $0 != "!" }
  "!"
}

The Prefix parser is the one causing trouble in this case I believe, although not sure why.

It's something like:
var parser = Parse {
  var v0 = ParserBuilder.buildExpression("Hello")
  var v1: ?
  if parseComma {
    var v2 = ParserBuilder.buildExpression(",")
    v1 = ParserBuilder.buildBlock(v2)
  } else {
    v1 = ParserBuilder.buidBlock(Optional<???>.none)
  }

  var v3 = ParserBuilder.buildExpression(" ")
  var v4 = ParserBuilder.buildExpression(Prefix { $0 != "!" })
  var v5 = ParserBuilder.buildExpression("!")

  var r0 = ParserBuilder.buildPartialBlock(first: v0)
  var r1 = ParserBuilder.buildPartialBlock(accumulated: r0, next: v1)
  var r2 = ParserBuilder.buildPartialBlock(accumulated: r1, next: v3)
  var r3 = ParserBuilder.buildPartialBlock(accumulated: r2, next: v4)
  var r4 = ParserBuilder.buildPartialBlock(accumulated: r3, next: v5)
  return r4
}

Not sure if Prefix { $0 != "!" } is transformed or not. The place marked with ??? is the type of v2, this interaction cannot be expressed in the surface language as stated by the proposal.

Hm interestingly it seems to be the combination of the parser wrapped in an if statement and the Prefix parser. Since when I delete either of them the parser does compile.

What is $0 supposed to be? I see that Input associated with Prefix supposed to conform to Collection protocol.

Substring in this case I believe

It's Input.Element:
https://github.com/pointfreeco/swift-parsing/blob/a3d52c666982f7cc9f243b910151cdb9f6283db1/Sources/Parsing/ParserPrinters/Prefix.swift#L55
Which is Substring.Element, or Character.

Ah my bad thanks @stephencelis

The good news is that the performance issues are not due to result builder implementation, old one is too complex too on that example. Just need to figure out what exactly is causing this, I suspect it's multiple overloads of buildIf.

Huh that is strange, @stephencelis this used to compile fine right? It's part of the library's tests.

I think you might be building with old compiler where transform is disabled actually because with transform I get the following diagnostic:
error: generic parameter 'Parsers' could not be inferred
    let parser = Parse {
                 ^
swift-parsing/Sources/Parsing/ParserPrinters/Parse.swift:23:21: note: 'Parsers' declared as parameter to type 'Parse'
public struct Parse<Parsers: Parser>: Parser {
                    ^
swift-parsing/Sources/Parsing/ParserPrinters/Prefix.swift:225:18: note: explicitly specify the generic arguments to fix this issue
    let parser = Parse {
                 ^
                      <<#Parsers: Parser#>>

@JaapWijnen Looks like all you might need to do is to fix init declaration in Parse.swift line 46 to:
@inlinable
  public init<Input>(@ParserBuilder<Input> with build: () -> Parsers) where Parsers.Input == Input {
    self.parsers = build()
  }

Parsers.Input cannot be used directly because the concrete type for Parsers is not known until the whole body of build: is type-checked, instead you want the Input to inferred from the body and passed up to the Parsers.Input if that generic parameter is not specified explicitly.
Also make sure that the toolchain you are using actually has result builder transform enabled :)

That did help :) Now I'm running into the ambiguity issue again unfortunately haha.

Must be a different example then since the one you pasted builds just fine for me after that init change.

Hmm not entirely for me. Made some changes to the parsers in the library to all accept an Input generic. Now I'm having trouble to get it to compile on the 2022-10-09 toolchain however:
This one times out again:
var parser = Parse {
      "Hello"
      if parseComma {
        ","
      }
      " "
      Prefix { $0 != "!" }
      "!"
    }

And for this one I get the following error
let p = ParsePrint {
      Prefix { $0 != "\n" } // Ambiguous use of 'init(while:)'
      First()
    }

And another very similar one but slightly different:
let p = ParsePrint {
      Prefix(3) { $0.isNumber }
      First() //Ambiguous use of 'init()'
    }

My latest changes can be found here if you're interested! : https://github.com/JaapWijnen/swift-parsing/commit/edcdf2d98c00dd4b210c7e904d05b9e151ff6b4e

I think you might want to pick up a newer toolchain maybe because I pulled your branch and couldn't reproduce anything except to:
func testSkipSuccess() {
    var input = "42 Hello, world!"[...].utf8
    XCTAssert(try () == XCTUnwrap(Skip { Int.parser() }.parse(&input))) // Ambiguous use of 'parser(of:radix:)'
    XCTAssertEqual(" Hello, world!", Substring(input))
  }

This is indeed ambiguous because both overloads that match are marked as @_disfavoredOverload, have all their parameters defaulted and produce a type that conforms to Parser - From conforms to Parser via ParserPrinter, IntParser conforms to parser directly.

Downloading the newest now!
Ah ok interesting, I thought because the input is included which is of type Substring.UTF8View the Skip parser would know it's input generic is of that same type therefore the result builder will use that as it's Input generic which in turn will pick that specific Int.parser() overload. But I guess it doesn't work like that. Could you point me towards where my logic breaks down/how that type inference actually works in this case?
Thanks for all the help!

The ranking of overloads would check the number of defaulted parameters (which is the same) and whether any of the parameters have subtyping relationship, none of this is applicable in this case.

Ah ok thanks @xedin! Then indeed some of the ergonomics of doing it like this are simply lost due to this regression (at least in their current form) Thanks for helping me understand!
Hope this is useful to you as well @stephencelis. Not sure what useful next steps are in terms of getting swift-parsing to compile for new toolchains (probably not an immediate priority to you?) But I'd love to help if you do have ideas about that!
We're using swift-parsing with snapshots so I'd love for it to work as it did before but right now at least we can get around the problem by just annotating all the parsers with a lot more type information.

This is definitely helpful! While we knew a lot of changes we needed to make based off more recent result builder projects we've taken on, this thread provided a lot of additional food for thought. Thanks, @xedin!

Looks like all you might need to do is to fix init declaration in Parse.swift line 46 to:
@inlinable
  public init<Input>(@ParserBuilder<Input> with build: () -> Parsers) where Parsers.Input == Input {
    self.parsers = build()
  }

Parsers.Input cannot be used directly because the concrete type for Parsers is not known until the whole body of build: is type-checked, instead you want the Input to inferred from the body and passed up to the Parsers.Input if that generic parameter is not specified explicitly.
Also make sure that the toolchain you are using actually has result builder transform enabled :)

@xedin I tried to apply this technique (on Swift Development Snapshot 2023-01-23) to a similar generic builder, but get "Generic parameter 'X' could not be inferred" where 'X' is the builder's generic.
Here's a basic example demonstrating the problem:
@resultBuilder
enum Builder<A> {
  static func buildExpression<T: P>(_ expression: T) -> T where T.A == A {
    expression
  }

  static func buildBlock() -> E<A> {
    E()
  }

  static func buildBlock<T: P>(_ component: T) -> T where T.A == A {
    component
  }

  static func buildPartialBlock<T: P>(first: T) -> T where T.A == A {
    first
  }

  static func buildPartialBlock<T0: P, T1: P>(accumulated: T0, next: T1) -> T1
  where T0.A == A, T1.A == A {
    next
  }
}

protocol P<A> {
  associatedtype A
  associatedtype Body
  @Builder<A>
  var body: Body { get }
}

extension P where Body == Never {
  var body: Body { fatalError() }
}

struct E<A>: P {}

struct C<T: P>: P {
  typealias A = T.A
  let t: T
  init<A>(@Builder<A> build: () -> T) where T.A == A {
    self.t = build()
  }
}

struct S: P {
  struct A {}
  @Builder<A>
  var body: some P<A> {
    C {   // 🛑 Generic parameter 'A' could not be inferred
      E()
    }
    C {}  // 🛑 Generic parameter 'A' could not be inferred
  }
}

Am I maybe missing something? Is there an -Xfrontend setting (or otherwise) I need to enabled on this snapshot? Or is this a potential bug?

There is no where to infer A from in C { E() } or C {} though right?

@xedin Shouldn't the A generic in @Builder<A> flow through the body context and hydrate C's init<A>, which in turn will know that its @Builder is generic over A and flow into the E? Or is this going in the wrong direction?
I don't quite know how to precisely translate builder code to the equivalent buildBlock (I can approximate it, but I'm not sure if I'm missing anything).

@stephencelis No, this is actually the whole point. The body is not solved as a unit, it's solved piece-by-piece just like a regular multi-statement closure so @Builder<A> affects only final return build{Partial}Block(...):
struct S: P {
  struct A {}
  @Builder<A>
  var body: some P<A> {
    var $__builder0 = Builder.buildExpression(C {
      var $__builder0 = Builder.buildExpression(E())
      return Builder.buildBlock($__builder0)
    })

    var $__builder1 = Builder.buildExpression(C {
      return Builder.buildBlock()
    })

    let r1 = Builder.buildPartialBlock(first: $__builder0)
    let r2 = Builder.buildPartialBlock(accumulated: r1, next: $__builder1)

    return r2
  }
}

In here Builder in Builder.buildExpression(E()) is different from Builder<A> attached to var body, there is no connection between them.

Maybe this is going to be more helpful: buildExpression states that T.A == A where T: P - to be able to solve that we need to first solve the expression C.init { E() }, C.init again tries to propagate A "up" (to the context) from the body of the result builder because in where T.A == A the right-hand side is not yet resolved - it's waiting for the { E() } to get resolved (as stated at the very beginning).
Note that buildExpression requirement T.A == A cannot propagate information down from @Builder<A> until T is resolved and that is only resolved when the expression is solved and part of that expression is solved in isolation because argument is a result builder.

@xedin I might be missing some nuance here, but doesn't this place a pretty big limitation on generic result builders? I would hope that the generic Builder<A> would propagate into the context and be used to anchor all of the buildExpressions, etc., and allow a generic type like E() to resolve without specifying generics explicitly. Why wouldn't the following be preferable?
struct S: P {
  struct A {}
  @Builder<A>
  var body: some P<A> {
    var $__builder0 = Builder<A>.buildExpression(C { @Builder<A> in
      var $__builder0 = Builder<A>.buildExpression(E())
      return Builder<A>.buildBlock($__builder0)
    })

    var $__builder1 = Builder<A>.buildExpression(C { @Builder<A> in
      return Builder<A>.buildBlock()
    })

    let r1 = Builder<A>.buildPartialBlock(first: $__builder0)
    let r2 = Builder<A>.buildPartialBlock(accumulated: r1, next: $__builder1)

    return r2
  }
}

Wouldn't dragging the <A> into things make this code compile just fine and without taking a big toll on the type checker?

would propagate into the context and be used to anchor all of the buildExpression

It does propagate into the context but that context is top-level things and the closure associated with C.init` because that is a completely different builder.

Is there a reason why the A couldn't trickle into the inner @Builder<???> context to resolve? All the type information seems to be there... Is there any way to make generic builders compose nicely?

For it to get into C.init closure it needs to get connected to something which would resolve it without relying on bi-directional inference which I don't think is possible because the language cannot pick up relations from context. Also it's very important to note that the example you've posted is not accepted by the original implementation either so this is not a regression.

@xedin So it's just impossible for C.init's builder to be influenced by the parent buildExpression? While I understand that result builder type inference is limited for performance reasons, I thought buildExpression was specifically designed to provide context to work around some of these limitations. Is there any reason why buildExpression couldn't still use bidirectional inference while the rest of the result builder APIs remain limited?
This limitation is quite a bummer if there's no workaround, and it prevents us from shipping an API that isn't cumbersome to use and difficult to troubleshoot or needlessly verbose, e.g.:
C(for: A.self) { // Worse when multiple generics are involved
  // ...
}

I thought buildExpression was specifically designed to provide context to work around some of these limitations. Is there any reason why buildExpression couldn't still use bidirectional inference while the rest of the result builder APIs remain limited?

buildExpression can and does provide context, but the way you have defined it, there is no context it could pass down. The problem here is not the luck on bi-directional inference inside of buildExpression argument, the problem is that the builder associated with C.init has Builder<???>.buildExpression(E()) expression where inference fails because { E() } is treated as a transformed multi-statement closure (as per result builder proposal). The generic parameter cannot be transferred into the body of { E() }, that didn't work before and it won't work with new transform.

Also it's very important to note that the example you've posted is not accepted by the original implementation either so this is not a regression.

Do you mean existing code should continue to compile? Or do you mean it's not a regression as far as the original evolution proposal conveyed? Given the swift-parsing code that used to compile, as well as some swift-composable-architecture code that used to compile, these changes definitely introduce source breaking changes and regressions, no?
While I get a compiler crash with my example above when I run with Xcode 14.2's built-in toolchain, I have some very similar library code that compiles fine in Xcode 14.2 but does not on the 5.8 (or development) toolchain.
If you clone https://github.com/pointfreeco/swift-composable-architecture (main branch), and paste the following code somewhere into the project:
struct R: ReducerProtocol {
  struct State {}
  enum Action {}
  @ReducerBuilder<State, Action>
  var body: some ReducerProtocol<State, Action> {
    CombineReducers {}
    CombineReducers {
      EmptyReducer()
    }
  }
}

...it compiles just fine.
However, if I switch to a 5.8 or development toolchain, it doesn't. These are pretty unfortunate source breaking changes to introduce to library users, especially if there's nothing we can do as library maintainers to make the upgrade to Swift 5.8 painless:
I also began to sketch out another branch with some adjustments for some of the changes coming:
https://github.com/pointfreeco/swift-composable-architecture/compare/builder-updates
Here, too, of course, the above won't compile (and still compiles fine in Xcode 14.2), but I was hoping the changes would at least address some problems with the existing implementation.

This example is problematic because ReducerBuilderOf is declared as:
public typealias ReducerBuilderOf<R: ReducerProtocol> = ReducerBuilder<R.State, R.Action>

and CombineReducers.init is declared as:
public init(
    @ReducerBuilderOf<Reducers> _ build: () -> Reducers
  )

which means that:
CombineReducers {
  var $__builder0 = ReducerBuilderOf<$T>.builderExpression(EmptyReducer())
  return ReducerBuilderOf<$T>.buildBlock($__builder0)
}

$T inference depends on the result type of buildBlock. The only way to infer that would be to attempt to solve whole body as a unit.

@xedin See the second link, where I've deprecated ReducerBuilderOf and refactored away usage.

@stephencelis Even without that explicit R: ReducerProtocol the type of ReducerBuilder still depends on the type produced by the body, although it's unpacked directly now.

@xedin I think I understand that, but what I'm trying to show you is that this statements you made don't appear to be true (as I'm understanding them):

Also it's very important to note that the example you've posted is not accepted by the original implementation either so this is not a regression.

The generic parameter cannot be transferred into the body of { E() }, that didn't work before and it won't work with new transform.

(Emphasis mine.) The code does currently compile, so this does seem like a regression.
See my earlier comment again for more context.

The code does currently compile, so this does seem like a regression.

@stephencelis I was referring to the code in https://github.com/apple/swift/issues/62978#issuecomment-1402356383

@xedin Hm, OK. So seeing as this is a regression with no current workaround, should I start a forum discussion to get wider visibility? Currently, these changes could break a lot of userland code.

This is currently being discussed by the language group. There is a workaround here though - specify generic arguments explicitly.

I guess I meant workaround that wouldn't be passed on to library users and become a new support vector for us 😅
And ideally one that doesn't make every nested generic builder more verbose than folks expect in Swift.

As a side note, I guess better compiler diagnostics and support would help here. If the compiler could help users migrate (or we could provide such migration APIs as fix-its) that'd make this change less painful.

Well, that the problem, compiler cannot determine what the type should be here so we cannot suggest one, it really is very unfortunate that declarations like that used to be accepted by the compiler because they result in performance issues as bodies grow and bad diagnostics because whole body is type-checked together.

@xedin Since the compiler can figure it out today, one would hope that the diagnostic could do this work when compilation fails in a post-compilation phase, at least during a migratory period...

Unfortunately no, otherwise we wouldn’t be spending time re-implementing the transform. The principle issue here is that type-checking everything together is too expensive especially for invalid code.

So seeing as this is a regression with no current workaround, should I start a forum discussion to get wider visibility? Currently, these changes could break a lot of userland code.

@stephencelis I'm going to take a look at the result builders in TCA to see whether I can figure out a tweak to the builder to enable the same call-site ergonomics. I think leaving this issue open is the best course of action for now. Pavel and I are working on a post for the Swift Forums to widely communicate the motivation, compile-time improvements, and the source compatibility impact of this change. Thank you for your patience and for reporting the impact on your project!

Thanks @hborla and @xedin for the communication, in general! We do appreciate the need and reasoning behind the changes, and we hope that the majority of TCA result builder usage will remain unaffected. We just wanted to do what we could to signal potential breakage to the core team and minimize frustration for end users of the library that hit what we hope are edge cases. We also hope there's a clear way to communicate to users when they need to do:
Reduce { state, action in
// or
CombineReducers {

vs.
Reduce<State, Action> { state, action in

Or if we should just enforce specifying via argument wherever there may be ambiguity, which is more verbose than needed a lot of the time, but at least avoids the problematic case:
Reduce(into: State.self, action: Action.self) { state, action in

@stephencelis I actually found a solution for CombineReducers problem (based on builder-updates branch):
diff --git a/Sources/ComposableArchitecture/Reducer/Reducers/CombineReducers.swift b/Sources/ComposableArchitecture/Reducer/Reducers/CombineReducers.swift
index bb569e8dc..031a8dc51 100644
--- a/Sources/ComposableArchitecture/Reducer/Reducers/CombineReducers.swift
+++ b/Sources/ComposableArchitecture/Reducer/Reducers/CombineReducers.swift
@@ -15,7 +15,8 @@
 ///   .ifLet(\.child, action: /Action.child)
 /// }
 /// ```
-public struct CombineReducers<Reducers: ReducerProtocol>: ReducerProtocol {
+public struct CombineReducers<Action, State, Reducers: ReducerProtocol>: ReducerProtocol
+    where Action == Reducers.Action, State == Reducers.State {
   @usableFromInline
   let reducers: Reducers

@@ -23,9 +24,9 @@ public struct CombineReducers<Reducers: ReducerProtocol>: ReducerProtocol {
   ///
   /// - Parameter build: A reducer builder.
   @inlinable
-  public init<State, Action>(
+  public init(
     @ReducerBuilder<State, Action> _ build: () -> Reducers
-  ) where State == Reducers.State, Action == Reducers.Action {
+  ) {
     self.init(internal: build())
   }

Adding this indirection for State/Action generic parameter makes sure that when CombineReducers() is wrapped in buildExpression declared as:
static func buildExpression(_: some ReducerProtocol<State, Action>) -> some ReducerProtocol<State, Action> {
    return expression
  }

State Action could be infer for it based on the "builder self": ReducerBuilder<State, Action>.builderExpression(CombineReducers()) where State and Action are struct and enum from your example.
Example you have posted previously type-checks with these changes.

@xedin Wow! Thanks! That actually gets the one regression in our test suite building again without needing to be explicit with \State.path and allowing abbreviation in \.path again!
https://github.com/pointfreeco/swift-composable-architecture/commit/feae99aa459f47962a01289682ee8468e2dc969a

@stephencelis No problem! Any other issues I can help with?

@xedin Will let you know if anything else comes up! Really appreciate the help along the way!

No worries, happy to help!

@xedin One more question... :smile:
We have this generic Reduce<State, Action> type:
https://github.com/pointfreeco/swift-composable-architecture/blob/main/Sources/ComposableArchitecture/Reducer/Reducers/Reduce.swift
When used from a builder with a single build block, e.g. here:
https://github.com/pointfreeco/swift-composable-architecture/blob/5e4caa89ee7e1add70557f77c7c35cfad73ff024/Examples/TicTacToe/tic-tac-toe/Sources/LoginCore/LoginCore.swift#L33
The closure seems to be type-checked efficiently, and Xcode autocomplete works just great when trying to autocomplete state.<ESC> parameter names and case .<ESC> action names.
However as soon as we add another reducer to the build block (like EmptyReducer()), above or below this Reduce, things still compile just fine, but we lose all autocompletion help in the closure. state.<ESC> and case .<ESC> are of no help till we explicitly specify Reduce<State, Action>.
Do you happen to have a tip we can employ to keep the compiler happy without this extra busy work?

Cc @ahoppen

Hi @stephencelis,
Thanks for sharing the code completion issue. I hope I can find time to take a look at it sometime next week.

@ahoppen Thanks!

I have managed to reduce the code completion issue down to the following. Checking with Xcode 14, the issue already existed in that release, so it’s not a regression.
The problem here appears to be that code completion is getting confused which closures it needs to type check. Specifically, the result builder with multiple statements the closure is not in the ReadyForTypeCheck body state here and thus we don’t continue.
https://github.com/apple/swift/blob/4ceec83cd87acc140e0e5d93956036861de88589/lib/Sema/TypeCheckStmt.cpp#L2419-L2420
I think this should resolve itself after we

Get rid of LeaveClosuresUnchecked (https://github.com/apple/swift/pull/59944)
Migrate the remaining code completion types to solver-based (https://github.com/apple/swift/pull/42280 and https://github.com/apple/swift/pull/42156)
Get rid of the the code path mentioned above entirely

There’s still some way to go on that journey but it’s something I am doing right now anyway.
// RUN: %swift-ide-test -code-completion -source-filename %s -code-completion-token COMPLETE

@resultBuilder
enum ReducerBuilder2<Action> {
  static func buildBlock(_ r: Reduce2<Action>) -> Reduce2<Action> { r }
  static func buildBlock(_ r0: Reduce2<Action>, _ r1: Reduce2<Action>) -> Reduce2<Action> { r0 }
  static func buildExpression(_ r: Reduce2<Action>) -> Reduce2<Action> { r }
}

enum Action {
  case alertDismissed
}

struct Reduce2<Action> {
  init() {}

  init(_ reduce: (Action) -> Int) {}
}

struct Login2 {
  @ReducerBuilder2<Action>
  var body: Reduce2<Action> {
    Reduce2() // Remove this to receive code completion results get code completion working again
    Reduce2 { action in
      switch action {
      case .#^COMPLETE^# alertDismissed:
        return 0
      }
    }
  }
}

@ahoppen That's great news! Thanks for looking into this :smile:

I stumbled across a similar issue today and this will be fixed by https://github.com/apple/swift/pull/59944. The test case I mentioned above is included in that PR.

authors: JaapWijnen ahoppen hborla stephencelis xedin