@jspahrsummers I feel like I'm being a pain in the ass, so I'll reply to your above comment and then say nothing more.

> because you're not passing in arguments that would make valid arguments in the absence of the protocol.

The flip side of this argument is that when a protocol is present, the fact that its type encoding take precedence means that you cannot call the method with "valid arguments". For example, this code fails:

```objc
it(@"should send correct arguments for invocation of optional delegate methods", ^{
	RACTestObject *object = [[RACTestObject alloc] init];

	// Declares - (void)makeHay:(CGFloat)bundles whileSunShines:(BOOL)sunshine;
	class_addProtocol(object.class, @protocol(RACTestProtocol));

	__block id hay;
	__block id sunshine;
	[[object rac_signalForSelector:@selector(makeHay:whileSunShines:)] subscribeNext:^(RACTuple *x) {
		hay = x.first;
		sunshine = x.second;
	}];

	// According to the docs, this should be valid, but it crashes.
	[object performSelector:@selector(makeHay:whileSunShines:) withObject:@3.0 withObject:@YES];

	expect(hay).to.equal(@3.0);
	expect(sunshine).to.equal(@YES);
});
```

> The compiler only sees the protocol's method signature, so it uses the calling conventions for those.

Yep, the point of the test is to pose as a caller of the protocol. That test confirms that callers of the protocol will continue to function even after we've gone in and injected a method with a differing signature. If this behavior were to ever change, we would need to know, and `-rac_signalForSelector:` would need to start explicitly looking up signatures on protocols to actively avoid incompatibility.

Right now, the fact that this all works is implicit in the docs and code.

It's kind of a regression test.