Inside a pattern matching switch statement using a case for an explicit type is asking if the value in question is of that specific type, or a derived type.  It's the exact equivalent of is 
switch (someString) {
  case string s:
}
if (someString is string) 
The value null does not have a type and hence does not satisfy either of the above conditions.  The static type of someString doesn't come into play in either example. 
The var type though in pattern matching acts as a wild card and will match any value including null.  
The default case here is dead code.  The case var o will match any value, null or non-null.  A non-default case always wins over a default one hence default will never be hit.  If you look at the IL you'll see it's not even emitted.  
At a glance it may seem odd that this compiles without any warning (definitely threw me off).  But this is matching with C# behavior that goes back to 1.0.  The compiler allows default cases even when it can trivially prove that it will never be hit.  Consider as an example the following:
bool b = ...;
switch (b) {
  case true: ...
  case false: ...
  default: ...
}
Here default will never be hit (even for bool that have a value that isn't 1 or 0).  Yet C# has allowed this since 1.0 without warning.  Pattern matching is just falling in line with this behavior here.