Returning local type as opaque return type of the function?

Is this code supposed to be valid?

protocol Shape {
    func draw() -> String
}

func weirdShape() -> some Shape {
    struct WeirdShape: Shape {
        func draw() -> String {
            return "*"
        }
    }

    return WeirdShape()
}

Compiling it fails with the following message:
error: compile command failed due to signal 4 (use -v to see invocation)

(I've tried to build with -v flag but couldn't extract anything informative).

If this is supposed to be a legal code? If not - why doesn't compiler provide specific reasons for failure?

1 Like

At first, I thought that one couldn’t define a struct from within a func (like one could a func). So moved the struct to outside of the func weirdShape()

protocol Shape {
	func draw() -> String
}

struct WeirdShape: Shape {
	func draw() -> String {
		return "*"
	}
}

func weirdShape() -> some Shape {
	return WeirdShape()
}

This compiled.

But I was curious. So I tried

protocol Shape {
	func draw() -> String
}

struct WeirdShape: Shape {
	func draw() -> String {
		return "*"
	}
}

func weirdShape() -> some Shape {
	struct Garbage {
		
	}
	return WeirdShape()
}

And this did compile. So I was wrong.

Then I tried

func ReturnsGarbage() -> Any {
	struct Garbage {
		
	}
	return Garbage()
}

This also compiles.

So then I tried

struct WeirdShape: Shape {
	func draw() -> String {
		return "*"
	}
}

func weirdShape() -> Shape {
	struct WeirdShape: Shape {
		func draw() -> String {
			return "*"
		}
	}
	return WeirdShape()
}

That ALSO compiles. I just removed some and made it func weirdShape() -> Shape

So, I think it's a bug having something to do with the struct being defined within the func and the return annotation being some.

1 Like

when i ran the example it looked like the compiler was crashing during IR generation on something having to do with symbol (de)mangling for debug info. compiling without debug info (i.e. adding the -gnone flag) seems to avoid that particular problem, at least in the one case i tested. i agree that this seems like a bug, and i'd encourage you to file a bug if you have a chance.

5 Likes

For some reason it only shows the backtrace if you run the frontend directly. It's an infinite recursion in emitting debug info:

Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.	Program arguments: /Users/slava/src/build/Ninja-RelWithDebInfoAssert/swift-macosx-arm64/bin/swift-frontend -emit-ir boo.swift -g
1.	Swift version 6.2-dev (LLVM 0dc2e2691f4f2cd, Swift 110e9270392d891)
2.	Compiling with effective version 5.10
3.	While evaluating request IRGenRequest(IR Generation for module boo)
4.	While emitting IR SIL function "@$s3boo10weirdShapeQryF".
 for 'weirdShape()' (at boo.swift:5:1)
5.	While mangling type for debugger type 'WeirdShape' (declared at [boo.swift:6:5 - line:10:5] RangeText="struct WeirdShape: Shape {
        func draw() -> String {
            return "*"
        }
    ")
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x0000000107d01c84 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000107d00318 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000107d022dc SignalHandler(int, __siginfo*, void*) + 312
3  libsystem_platform.dylib 0x0000000199e3f624 _sigtramp + 56
4  swift-frontend           0x00000001040ca4a0 swift::Demangle::mangleNode(swift::Demangle::Node*, llvm::function_ref<swift::Demangle::Node* (swift::Demangle::SymbolicReferenceKind, void const*)>, swift::Mangle::ManglingFlavor) + 44
5  swift-frontend           0x00000001040ca468 swift::Demangle::mangleNode(swift::Demangle::Node*, swift::Mangle::ManglingFlavor) + 32
6  swift-frontend           0x00000001040a46c4 llvm::StringRef llvm::function_ref<llvm::StringRef ()>::callback_fn<setParentForOpaqueReturnTypeNodes(swift::Demangle::Demangler&, swift::Demangle::Node*, swift::Demangle::Node*, swift::Mangle::ManglingFlavor)::$_0>(long) + 92
7  swift-frontend           0x00000001040a45dc setParentForOpaqueReturnTypeNodesImpl(swift::Demangle::Demangler&, swift::Demangle::Node&, llvm::function_ref<llvm::StringRef ()>) + 264
8  swift-frontend           0x00000001040a465c setParentForOpaqueReturnTypeNodesImpl(swift::Demangle::Demangler&, swift::Demangle::Node&, llvm::function_ref<llvm::StringRef ()>) + 392
9  swift-frontend           0x00000001040a465c setParentForOpaqueReturnTypeNodesImpl(swift::Demangle::Demangler&, swift::Demangle::Node&, llvm::function_ref<llvm::StringRef ()>) + 392
10 swift-frontend           0x00000001040a465c setParentForOpaqueReturnTypeNodesImpl(swift::Demangle::Demangler&, swift::Demangle::Node&, llvm::function_ref<llvm::StringRef ()>) + 392
11 swift-frontend           0x00000001040a465c setParentForOpaqueReturnTypeNodesImpl(swift::Demangle::Demangler&, swift::Demangle::Node&, llvm::function_ref<llvm::StringRef ()>) + 392
12 swift-frontend           0x0000000104097f3c swift::Demangle::Demangler::demanglePlainFunction() + 552
13 swift-frontend           0x0000000104095928 swift::Demangle::Demangler::demangleSymbol(llvm::StringRef, std::__1::function<swift::Demangle::Node* (swift::Demangle::SymbolicReferenceKind, swift::Demangle::Directness, int, void const*)>) + 352
14 swift-frontend           0x0000000104046484 swift::Mangle::Mangler::verify(llvm::StringRef, swift::Mangle::ManglingFlavor) + 408
15 swift-frontend           0x0000000103ca5318 swift::Mangle::ASTMangler::mangleTypeForDebugger(swift::Type, swift::GenericSignature) + 248
16 swift-frontend           0x0000000102d54a60 (anonymous namespace)::IRGenDebugInfoImpl::getMangledName(swift::irgen::DebugTypeInfo) + 716
17 swift-frontend           0x0000000102d521a0 (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateType(swift::irgen::DebugTypeInfo, llvm::DIScope*) + 456
18 swift-frontend           0x0000000102d52d68 (anonymous namespace)::IRGenDebugInfoImpl::createParameterTypes(swift::CanTypeWrapper<swift::SILFunctionType>) + 716
19 swift-frontend           0x0000000102d4c6fc (anonymous namespace)::IRGenDebugInfoImpl::emitFunction(swift::SILDebugScope const*, llvm::Function*, swift::SILFunctionTypeRepresentation, swift::SILType, swift::DeclContext*, llvm::StringRef) + 1720
20 swift-frontend           0x0000000102d4bf0c (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateScope(swift::SILDebugScope const*) + 844
21 swift-frontend           0x0000000102d51e58 (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateContext(swift::DeclContext*) + 144
22 swift-frontend           0x0000000102d553f8 (anonymous namespace)::IRGenDebugInfoImpl::updateScope(llvm::DIScope*, swift::irgen::DebugTypeInfo) + 864
23 swift-frontend           0x0000000102d5214c (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateType(swift::irgen::DebugTypeInfo, llvm::DIScope*) + 372
24 swift-frontend           0x0000000102d52d68 (anonymous namespace)::IRGenDebugInfoImpl::createParameterTypes(swift::CanTypeWrapper<swift::SILFunctionType>) + 716
25 swift-frontend           0x0000000102d4c6fc (anonymous namespace)::IRGenDebugInfoImpl::emitFunction(swift::SILDebugScope const*, llvm::Function*, swift::SILFunctionTypeRepresentation, swift::SILType, swift::DeclContext*, llvm::StringRef) + 1720
26 swift-frontend           0x0000000102d4bf0c (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateScope(swift::SILDebugScope const*) + 844
27 swift-frontend           0x0000000102d51e58 (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateContext(swift::DeclContext*) + 144
28 swift-frontend           0x0000000102d553f8 (anonymous namespace)::IRGenDebugInfoImpl::updateScope(llvm::DIScope*, swift::irgen::DebugTypeInfo) + 864
29 swift-frontend           0x0000000102d5214c (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateType(swift::irgen::DebugTypeInfo, llvm::DIScope*) + 372
30 swift-frontend           0x0000000102d52d68 (anonymous namespace)::IRGenDebugInfoImpl::createParameterTypes(swift::CanTypeWrapper<swift::SILFunctionType>) + 716
31 swift-frontend           0x0000000102d4c6fc (anonymous namespace)::IRGenDebugInfoImpl::emitFunction(swift::SILDebugScope const*, llvm::Function*, swift::SILFunctionTypeRepresentation, swift::SILType, swift::DeclContext*, llvm::StringRef) + 1720
32 swift-frontend           0x0000000102d4bf0c (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateScope(swift::SILDebugScope const*) + 844
33 swift-frontend           0x0000000102d51e58 (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateContext(swift::DeclContext*) + 144
34 swift-frontend           0x0000000102d553f8 (anonymous namespace)::IRGenDebugInfoImpl::updateScope(llvm::DIScope*, swift::irgen::DebugTypeInfo) + 864
35 swift-frontend           0x0000000102d5214c (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateType(swift::irgen::DebugTypeInfo, llvm::DIScope*) + 372
36 swift-frontend           0x0000000102d52d68 (anonymous namespace)::IRGenDebugInfoImpl::createParameterTypes(swift::CanTypeWrapper<swift::SILFunctionType>) + 716
37 swift-frontend           0x0000000102d4c6fc (anonymous namespace)::IRGenDebugInfoImpl::emitFunction(swift::SILDebugScope const*, llvm::Function*, swift::SILFunctionTypeRepresentation, swift::SILType, swift::DeclContext*, llvm::StringRef) + 1720
...
4 Likes