Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent match type reduction #12974

Closed
johnynek opened this issue Jun 28, 2021 · 2 comments
Closed

Inconsistent match type reduction #12974

johnynek opened this issue Jun 28, 2021 · 2 comments
Assignees
Milestone

Comments

@johnynek
Copy link

compiler version 3.0.1-RC2

This compiles without warning

package example    
    
object RecMap {                                            
                                                                                   
  object Record {                               
    // use this scope to bound who can see inside the opaque type
    opaque type Rec[A <: Tuple] = Map[String, Any]
                                                   
    object Rec {                          
      type HasKey[A <: Tuple, K] =
        A match
          case (K, t) *: _ => t
          case _ *: t => HasKey[t, K]

      val empty: Rec[EmptyTuple] = Map.empty
                                                                
      extension [A <: Tuple](toMap: Rec[A])                     
        def fetch[K <: String & Singleton](key: K): HasKey[A, K] =
          toMap(key).asInstanceOf[HasKey[A, K]]
    }                                              
  }                                                                      
                                 
  def main(args: Array[String]) =
    import Record._                                                    
                               
    val foo: Any = Rec.empty.fetch("foo")          
    //summon[Rec.HasKey[EmptyTuple, "foo"] =:= Any]
                                    
  end main
}

but I don't think it should. Rec.empty has type Rec[EmptyTuple] and there is no value of HasKey[EmptyTuple, Any].

When you uncomment the summon you get the correct result:

[error] -- Error: /Users/oboykin/oss_code/scala3_examples/src/main/scala/RecMap.scala:48:49 
[error] 48 |    summon[Rec.HasKey[EmptyTuple, "foo"] =:= Any]
[error]    |                                                 ^
[error]    |Cannot prove that example.RecMap.Record.Rec.HasKey[EmptyTuple, ("foo" : String)] =:= Any.
[error]    |
[error]    |Note: a match type could not be fully reduced:
[error]    |
[error]    |  trying to reduce  example.RecMap.Record.Rec.HasKey[EmptyTuple, ("foo" : String)]
[error]    |  failed since selector  EmptyTuple
[error]    |  matches none of the cases
[error]    |
[error]    |    case (("foo" : String), t) *: _ => t
[error]    |    case _ *: t => example.RecMap.Record.Rec.HasKey[t, ("foo" : String)]
[error] one error found
@johnynek
Copy link
Author

a fuller working example is here:

https://gist.github.com/johnynek/1e3cbddf461bd3da9b00e2f4f126c253

(but this only shows positive cases, it didn't exercise showing a compile failure for invalid keys or types).

@johnynek
Copy link
Author

related to #10747 and #12768

anatoliykmetyuk pushed a commit to dotty-staging/dotty that referenced this issue Sep 14, 2021
@dwijnand dwijnand added this to the 3.1.0 milestone Sep 14, 2021
olsdavis pushed a commit to olsdavis/dotty that referenced this issue Apr 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants