What are the rules for ```min_specialization```?

Hello everyone!

Recently I've found out about the specialization and min_specialization features that allow some type eligible for some generic trait implementation to have a different implementation of the trait. The former is considered unsound, the latter has stricter rules but is considered safe. For example, this code compiles with specialization, but not with min_specialization:

pub trait IsBuffered
{
   fn is_buffered(&self) -> bool;
}

impl<T> IsBuffered for T where T: std::io::Read
{
   default fn is_buffered(&self) -> bool { false }
}

impl<T> IsBuffered for T where T: std::io::BufRead
{
   fn is_buffered(&self) -> bool { true }
}

Compiler error is "cannot specialize on trait BufRead".

The same applies to generic types:

pub trait IsBuffered
{
   fn is_buffered(&self) -> bool;
}

impl<T> IsBuffered for T where T: std::io::Read
{
   default fn is_buffered(&self) -> bool { false }
}

impl<T> IsBuffered for std::io::BufReader<T> where T: std::io::Read
{
   fn is_buffered(&self) -> bool { true }
}

The error is "cannot specialize on trait Read". However, this code:

pub trait IsBuffered
{
   fn is_buffered(&self) -> bool;
}

impl<T> IsBuffered for T where T: std::io::Read
{
   default fn is_buffered(&self) -> bool { false }
}

impl<T> IsBuffered for std::io::BufReader<std::fs::File>
{
   fn is_buffered(&self) -> bool { true }
}

is allowed in min_specialization. I wonder, what are exact rules for min_specialization? Do they mean that default fn implementations can only be overridden for concrete types but not generic types?

The PR description for Implement a feature for a sound specialization subset by matthewjasper · Pull Request #68970 · rust-lang/rust · GitHub explains the rules. As for the specific reason why the first two code blocks are not allowed: It is possible to implement BufRead only for specific lifetimes, which would be unsound as codegen erases lifetimes and thus cause typeck and codegen to disagree about if the specializing impl applies.