Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/Common/PassVisitor.h	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -92,4 +92,5 @@
 	virtual void visit( NameExpr * nameExpr ) override final;
 	virtual void visit( CastExpr * castExpr ) override final;
+	virtual void visit( KeywordCastExpr * castExpr ) override final;
 	virtual void visit( VirtualCastExpr * castExpr ) override final;
 	virtual void visit( AddressExpr * addressExpr ) override final;
@@ -187,7 +188,8 @@
 	virtual Expression * mutate( UntypedExpr * untypedExpr ) override final;
 	virtual Expression * mutate( NameExpr * nameExpr ) override final;
-	virtual Expression * mutate( AddressExpr * castExpr ) override final;
+	virtual Expression * mutate( AddressExpr * addrExpr ) override final;
 	virtual Expression * mutate( LabelAddressExpr * labAddressExpr ) override final;
 	virtual Expression * mutate( CastExpr * castExpr ) override final;
+	virtual Expression * mutate( KeywordCastExpr * castExpr ) override final;
 	virtual Expression * mutate( VirtualCastExpr * castExpr ) override final;
 	virtual Expression * mutate( UntypedMemberExpr * memberExpr ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/Common/PassVisitor.impl.h	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -1259,4 +1259,27 @@
 
 //--------------------------------------------------------------------------
+// KeywordCastExpr
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( KeywordCastExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl        ( node->arg   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
+	MUTATE_START( node );
+
+	indexerScopedMutate( node->env   , *this );
+	indexerScopedMutate( node->result, *this );
+	maybeMutate_impl   ( node->arg   , *this );
+
+	MUTATE_END( Expression, node );
+}
+
+//--------------------------------------------------------------------------
 // VirtualCastExpr
 template< typename pass_type >
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/Concurrency/Keywords.cc	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -53,10 +53,10 @@
 	  public:
 
-	  	ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main ) :
-		  type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ) {}
+	  	ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, KeywordCastExpr::Target cast_target ) :
+		  type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ), cast_target( cast_target ) {}
 
 		virtual ~ConcurrentSueKeyword() {}
 
-		void postvisit( StructDecl * decl );
+		Declaration * postmutate( StructDecl * decl );
 
 		void handle( StructDecl * );
@@ -66,4 +66,6 @@
 
 		virtual bool is_target( StructDecl * decl ) = 0;
+
+		Expression * postmutate( KeywordCastExpr * cast );
 
 	  private:
@@ -73,4 +75,5 @@
 		const std::string context_error;
 		bool needs_main;
+		KeywordCastExpr::Target cast_target;
 
 		StructDecl* type_decl = nullptr;
@@ -95,5 +98,6 @@
 			"get_thread",
 			"thread keyword requires threads to be in scope, add #include <thread>",
-			true
+			true,
+			KeywordCastExpr::Thread
 		)
 		{}
@@ -105,5 +109,5 @@
 		static void implement( std::list< Declaration * > & translationUnit ) {
 			PassVisitor< ThreadKeyword > impl;
-			acceptAll( translationUnit, impl );
+			mutateAll( translationUnit, impl );
 		}
 	};
@@ -126,5 +130,6 @@
 			"get_coroutine",
 			"coroutine keyword requires coroutines to be in scope, add #include <coroutine>",
-			true
+			true,
+			KeywordCastExpr::Coroutine
 		)
 		{}
@@ -136,5 +141,5 @@
 		static void implement( std::list< Declaration * > & translationUnit ) {
 			PassVisitor< CoroutineKeyword > impl;
-			acceptAll( translationUnit, impl );
+			mutateAll( translationUnit, impl );
 		}
 	};
@@ -157,5 +162,6 @@
 			"get_monitor",
 			"monitor keyword requires monitors to be in scope, add #include <monitor>",
-			false
+			false,
+			KeywordCastExpr::Monitor
 		)
 		{}
@@ -167,5 +173,5 @@
 		static void implement( std::list< Declaration * > & translationUnit ) {
 			PassVisitor< MonitorKeyword > impl;
-			acceptAll( translationUnit, impl );
+			mutateAll( translationUnit, impl );
 		}
 	};
@@ -267,5 +273,5 @@
 	}
 
-	void ConcurrentSueKeyword::postvisit(StructDecl * decl) {
+	Declaration * ConcurrentSueKeyword::postmutate(StructDecl * decl) {
 		if( decl->name == type_name && decl->body ) {
 			assert( !type_decl );
@@ -275,5 +281,26 @@
 			handle( decl );
 		}
-	}
+		return decl;
+	}
+
+	Expression * ConcurrentSueKeyword::postmutate( KeywordCastExpr * cast ) {
+		if ( cast_target == cast->target ) {
+			// convert (thread &)t to (thread_desc &)*get_thread(t), etc.
+			if( !type_decl ) SemanticError( cast, context_error );
+			Expression * arg = cast->arg;
+			cast->arg = nullptr;
+			delete cast;
+			return new CastExpr(
+				UntypedExpr::createDeref(
+					new UntypedExpr( new NameExpr( getter_name ), { arg } )
+				),
+				new ReferenceType(
+					noQualifiers,
+					new StructInstType( noQualifiers, type_decl ) )
+				);
+		}
+		return cast;
+	}
+
 
 	void ConcurrentSueKeyword::handle( StructDecl * decl ) {
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/Parser/ExpressionNode.cc	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -414,4 +414,8 @@
 } // build_cast
 
+Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node ) {
+	return new KeywordCastExpr( maybeMoveBuild< Expression >(expr_node), target );
+}
+
 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
 	return new VirtualCastExpr( maybeMoveBuild< Expression >( expr_node ), maybeMoveBuildType( decl_node ) );
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/Parser/ParseNode.h	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -179,4 +179,5 @@
 
 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
+Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node );
 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/Parser/parser.yy	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -688,9 +688,9 @@
 		{ $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
 	| '(' COROUTINE '&' ')' cast_expression				// CFA
-		{ SemanticError( yylloc, "coroutine cast is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
 	| '(' THREAD '&' ')' cast_expression				// CFA
-		{ SemanticError( yylloc, "monitor cast is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Thread, $5 ) ); }
 	| '(' MONITOR '&' ')' cast_expression				// CFA
-		{ SemanticError( yylloc, "thread cast is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Monitor, $5 ) ); }
 		// VIRTUAL cannot be opt because of look ahead issues
 	| '(' VIRTUAL ')' cast_expression					// CFA
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/SynTree/Expression.cc	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -299,4 +299,33 @@
 }
 
+KeywordCastExpr::KeywordCastExpr( Expression *arg, Target target ) : Expression(), arg(arg), target( target ) {
+}
+
+KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) {
+}
+
+KeywordCastExpr::~KeywordCastExpr() {
+	delete arg;
+}
+
+const std::string & KeywordCastExpr::targetString() const {
+	static const std::string targetStrs[] = {
+		"coroutine", "thread", "monitor"
+	};
+	static_assert(
+		(sizeof(targetStrs) / sizeof(targetStrs[0])) == ((unsigned long)NUMBER_OF_TARGETS),
+		"Each KeywordCastExpr::Target should have a corresponding string representation"
+	);
+	return targetStrs[(unsigned long)target];
+}
+
+void KeywordCastExpr::print( std::ostream &os, Indenter indent ) const {
+	os << "Keyword Cast of:" << std::endl << indent+1;
+	arg->print(os, indent+1);
+	os << std::endl << indent << "... to: ";
+	os << targetString();
+	Expression::print( os, indent );
+}
+
 VirtualCastExpr::VirtualCastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) {
 	set_result(toType);
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/SynTree/Expression.h	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -192,4 +192,5 @@
 	CastExpr( Expression * arg, bool isGenerated = true );
 	CastExpr( Expression * arg, Type * toType, bool isGenerated = true );
+	CastExpr( Expression * arg, void * ) = delete; // prevent accidentally passing pointers for isGenerated in the first constructor
 	CastExpr( const CastExpr & other );
 	virtual ~CastExpr();
@@ -199,4 +200,24 @@
 
 	virtual CastExpr * clone() const { return new CastExpr( * this ); }
+	virtual void accept( Visitor & v ) { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+};
+
+/// KeywordCastExpr represents a cast to 'keyword types', e.g. (thread &)t
+class KeywordCastExpr : public Expression {
+public:
+	Expression * arg;
+	enum Target {
+		Coroutine, Thread, Monitor, NUMBER_OF_TARGETS
+	} target;
+
+	KeywordCastExpr( Expression * arg, Target target );
+	KeywordCastExpr( const KeywordCastExpr & other );
+	virtual ~KeywordCastExpr();
+
+	const std::string & targetString() const;
+
+	virtual KeywordCastExpr * clone() const { return new KeywordCastExpr( * this ); }
 	virtual void accept( Visitor & v ) { v.visit( this ); }
 	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/SynTree/Mutator.h	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -59,7 +59,8 @@
 	virtual Expression * mutate( UntypedExpr * untypedExpr ) = 0;
 	virtual Expression * mutate( NameExpr * nameExpr ) = 0;
-	virtual Expression * mutate( AddressExpr * castExpr ) = 0;
+	virtual Expression * mutate( AddressExpr * addrExpr ) = 0;
 	virtual Expression * mutate( LabelAddressExpr * labAddressExpr ) = 0;
 	virtual Expression * mutate( CastExpr * castExpr ) = 0;
+	virtual Expression * mutate( KeywordCastExpr * castExpr ) = 0;
 	virtual Expression * mutate( VirtualCastExpr * castExpr ) = 0;
 	virtual Expression * mutate( UntypedMemberExpr * memberExpr ) = 0;
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/SynTree/SynTree.h	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -69,4 +69,5 @@
 class LabelAddressExpr;
 class CastExpr;
+class KeywordCastExpr;
 class VirtualCastExpr;
 class MemberExpr;
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 60ba4569cfb8db589447f9e72b96e6e7ad2024a3)
+++ src/SynTree/Visitor.h	(revision 9a705dc89354e53ad54ff8ee372e6cc20c210e1e)
@@ -62,4 +62,5 @@
 	virtual void visit( NameExpr * nameExpr ) = 0;
 	virtual void visit( CastExpr * castExpr ) = 0;
+	virtual void visit( KeywordCastExpr * castExpr ) = 0;
 	virtual void visit( VirtualCastExpr * castExpr ) = 0;
 	virtual void visit( AddressExpr * addressExpr ) = 0;
