$q promise from function not getting its value propagated into the Angular view when resolved

For some reason, when I return a $q promise from a scope function, the value never gets propagated on resolution:

app.controller('MainCtrl', function($scope, $q) {
    var deferred = $q.defer();
    deferred.resolve("hello");
    var promise = deferred.promise;

    $scope.promiseReturn = function() {
        return promise;
    };
});

And the view:

<body ng-controller="MainCtrl">
    <p>promiseReturn: {{promiseReturn()}}</p>
</body>

Here's a Plunker for this code. The view ends up looking like:

promiseReturn: {}

My understanding seemed to be that the templating engine would deal with $q promises fairly transparently.

$q promises can be attached to the scope directly, and when resolved, their value will be cause the view to be updated (and their resolved value will be used), but they cannot be the return value of a scope function.

If you return a promise from a function on a scope, the return value is used as-is. A promise looks like an object {then: function() { ... }}, and Angular's JSON serialiser ignores keys with function values, so you just get {} in the view. Here's a Plunker demonstrating this.

Angular deals with this in a few locations; you can see some in parse.js (search for .then).