Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 4aac9ffe1aa65f199a4072676c0db437b8fa5539)
@@ -69,4 +69,5 @@
 		void postvisit( CastExpr * castExpr );
 		void postvisit( VirtualCastExpr * castExpr );
+		void postvisit( KeywordCastExpr * castExpr );
 		void postvisit( UntypedMemberExpr * memberExpr );
 		void postvisit( MemberExpr * memberExpr );
@@ -1255,4 +1256,61 @@
 	}
 
+	void AlternativeFinder::Finder::postvisit( KeywordCastExpr * castExpr ) {
+		assertf( castExpr->get_result(), "Cast target should have been set in Validate." );
+		auto ref = dynamic_cast<ReferenceType*>(castExpr->get_result());
+		assert(ref);
+		auto inst = dynamic_cast<StructInstType*>(ref->base);
+		assert(inst);
+		auto target = inst->baseStruct;
+
+		AlternativeFinder finder( indexer, env );
+
+		auto pick_alternatives = [target, this](AltList & found, bool expect_ref) {
+			for(auto & alt : found) {
+				Type * expr = alt.expr->get_result();
+				if(expect_ref) {
+					auto res = dynamic_cast<ReferenceType*>(expr);
+					if(!res) { continue; }
+					expr = res->base;
+				}
+
+				if(auto insttype = dynamic_cast<TypeInstType*>(expr)) {
+					auto td = alt.env.lookup(insttype->name);
+					if(!td) { continue; }
+					expr = td->type;
+				}
+
+				if(auto base = dynamic_cast<StructInstType*>(expr)) {
+					if(base->baseStruct == target) {
+						alternatives.push_back(
+							std::move(alt)
+						);
+					}
+				}
+			}
+		};
+
+		try {
+			// Attempt 1 : turn (thread&)X into (thread_desc&)X.__thrd
+			// Clone is purely for memory management
+			std::unique_ptr<Expression> tech1 { new UntypedMemberExpr(new NameExpr(castExpr->concrete_target.field), castExpr->arg->clone()) };
+
+			// don't prune here, since it's guaranteed all alternatives will have the same type
+			finder.findWithoutPrune( tech1.get() );
+			pick_alternatives(finder.alternatives, false);
+
+			return;
+		} catch(SemanticErrorException & ) {}
+
+		// Fallback : turn (thread&)X into (thread_desc&)get_thread(X)
+		std::unique_ptr<Expression> fallback { UntypedExpr::createDeref( new UntypedExpr(new NameExpr(castExpr->concrete_target.getter), { castExpr->arg->clone() })) };
+		// don't prune here, since it's guaranteed all alternatives will have the same type
+		finder.findWithoutPrune( fallback.get() );
+
+		pick_alternatives(finder.alternatives, true);
+
+		// Whatever happens here, we have no more fallbacks
+	}
+
 	namespace {
 		/// Gets name from untyped member expression (member must be NameExpr)
