Integer and floating point literals are separate concepts to the parser. 1 is valid for either. Thus 1.foo tries an integer literal as Int, finds nothing, and then tries a floating point literal as Double and it works. But it is still just using the default for that type of literal. If you change the extension to UInt8 or Float32, it won’t work.
I think the answer to why "str" is considered a String, and not a StaticString, is historical and a result of the need, at least for Apple, to have Swift interoperate with Objective-C/C++/C/C++/et al. StaticString is a pure Swift value type. Considering "str" as a StaticString would probably break a lot code out there that relies on Swift/non-Swift language interoperability. If you tried StaticString(stringliteral: "str").foo, everything would probably work out like you wanted.
The type of a base expression has to be resolved before its members can be looked up. "str" by itself has no type context to direct the type checker, so it uses the default type for string literals, which is String. You'd have to write ("str" as StaticString).foo to direct the type checker to resolve the literal as a StaticString.
What do you want to use StaticString for? There's little reason to use it anymore.
I'm not using StaticString currently but when reading Pavel's recent blog post about diagnostics and inference, I was reminded of a past project where I saw this behavior. IIRC, we wanted to create a StaticString extension for localization purposes.
If you scroll up a couple cases you will notice ExpressibleByStringLiteral and ExpressibleByExtendedGraphemeClusterLiteral are not given any alternatives, so a String literal will not be resolved to a Character without context either.
extension Character {
var foo: Bool { true }
}
"a".foo // error: value of type 'String' has no member 'foo'
let char: Character = "a" // OK