Say we have a player who's walking around in first person perspective. He would like to walk forward, but that would put him inside an object, and that's no good.

Right now what I do is... (pseudocode follows)
class Player(whatever):
def __move_by(this, displacement):
for object in scene:
if(object.hitbox.collides_with(displacement)):
return #nope.avi
this.position += displacement
This isn't really good however. Often times I need to watch the console debug output to understand what I would be walking into. Also, not moving at all isn't what happens in "real world" games. I am however in trouble when putting into words, or code, what is it that happens in "real world" games.
What I do with NPCs is calculate the projection of the movement towards their goal along the direction they're heading to, as well as rotating them towards their goal in the process. However, here there's no "goal" distinct from the heading - if we ignore strafing, all the player can do is walk back and forward along his heading exactly.
So... how to handle this?