Skip to content

[wip] Possible reversion of 3283 (Tuple<...> regression with Item* and Rest properties) #4029

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 47 additions & 48 deletions src/fsharp/TcGlobals.fs
Original file line number Diff line number Diff line change
Expand Up @@ -673,52 +673,54 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
let addFieldNeverAttrs (fdef:ILFieldDef) = {fdef with CustomAttrs = addNeverAttrs fdef.CustomAttrs}
let mkDebuggerTypeProxyAttribute (ty : ILType) = mkILCustomAttribute ilg (findSysILTypeRef tname_DebuggerTypeProxyAttribute, [ilg.typ_Type], [ILAttribElem.TypeRef (Some ty.TypeRef)], [])

let entries1 =
[| "Int32" , v_int_tcr
"IntPtr" , v_nativeint_tcr
"UIntPtr" , v_unativeint_tcr
"Int16" , v_int16_tcr
"Int64" , v_int64_tcr
"UInt16" , v_uint16_tcr
"UInt32" , v_uint32_tcr
"UInt64" , v_uint64_tcr
"SByte" , v_sbyte_tcr
"Decimal" , v_decimal_tcr
"Byte" , v_byte_tcr
"Boolean" , v_bool_tcr
"String" , v_string_tcr
"Object" , v_obj_tcr
"Exception", v_exn_tcr
"Char" , v_char_tcr
"Double" , v_float_tcr
"Single" , v_float32_tcr |]
|> Array.map (fun (nm, tcr) ->
let ty = mkNonGenericTy tcr
nm, findSysTyconRef sys nm, (fun _ -> ty))

let entries2 =
[|
"FSharpFunc`2" , v_fastFunc_tcr , (fun tinst -> mkFunTy (List.item 0 tinst) (List.item 1 tinst))
"Tuple`2" , v_ref_tuple2_tcr , decodeTupleTy tupInfoRef
"Tuple`3" , v_ref_tuple3_tcr , decodeTupleTy tupInfoRef
"Tuple`4" , v_ref_tuple4_tcr , decodeTupleTy tupInfoRef
"Tuple`5" , v_ref_tuple5_tcr , decodeTupleTy tupInfoRef
"Tuple`6" , v_ref_tuple6_tcr , decodeTupleTy tupInfoRef
"Tuple`7" , v_ref_tuple7_tcr , decodeTupleTy tupInfoRef
"Tuple`8" , v_ref_tuple8_tcr , decodeTupleTy tupInfoRef
"ValueTuple`2" , v_struct_tuple2_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`3" , v_struct_tuple3_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`4" , v_struct_tuple4_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`5" , v_struct_tuple5_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`6" , v_struct_tuple6_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`7" , v_struct_tuple7_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`8" , v_struct_tuple8_tcr , decodeTupleTy tupInfoStruct |]

// Build a map that uses the "canonical" F# type names and TyconRef's for these
// in preference to the .NET type names. Doing this normalization is a fairly performance critical
// piece of code as it is frequently invoked in the process of converting .NET metadata to F# internal
// compiler data structures (see import.fs).
let buildTyconMapper (entries: (string * TyconRef * _)[]) =
let betterTyconRefMap =
begin
let entries1 =
[| "Int32" , v_int_tcr
"IntPtr" , v_nativeint_tcr
"UIntPtr" , v_unativeint_tcr
"Int16" , v_int16_tcr
"Int64" , v_int64_tcr
"UInt16" , v_uint16_tcr
"UInt32" , v_uint32_tcr
"UInt64" , v_uint64_tcr
"SByte" , v_sbyte_tcr
"Decimal" , v_decimal_tcr
"Byte" , v_byte_tcr
"Boolean" , v_bool_tcr
"String" , v_string_tcr
"Object" , v_obj_tcr
"Exception", v_exn_tcr
"Char" , v_char_tcr
"Double" , v_float_tcr
"Single" , v_float32_tcr |]
|> Array.map (fun (nm, tcr) ->
let ty = mkNonGenericTy tcr
nm, findSysTyconRef sys nm, (fun _ -> ty))

let entries2 =
[|
"FSharpFunc`2" , v_fastFunc_tcr , (fun tinst -> mkFunTy (List.item 0 tinst) (List.item 1 tinst))
"Tuple`2" , v_ref_tuple2_tcr , decodeTupleTy tupInfoRef
"Tuple`3" , v_ref_tuple3_tcr , decodeTupleTy tupInfoRef
"Tuple`4" , v_ref_tuple4_tcr , decodeTupleTy tupInfoRef
"Tuple`5" , v_ref_tuple5_tcr , decodeTupleTy tupInfoRef
"Tuple`6" , v_ref_tuple6_tcr , decodeTupleTy tupInfoRef
"Tuple`7" , v_ref_tuple7_tcr , decodeTupleTy tupInfoRef
"Tuple`8" , v_ref_tuple8_tcr , decodeTupleTy tupInfoRef
"ValueTuple`2" , v_struct_tuple2_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`3" , v_struct_tuple3_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`4" , v_struct_tuple4_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`5" , v_struct_tuple5_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`6" , v_struct_tuple6_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`7" , v_struct_tuple7_tcr , decodeTupleTy tupInfoStruct
"ValueTuple`8" , v_struct_tuple8_tcr , decodeTupleTy tupInfoStruct |]

let entries = Array.append entries1 entries2
if compilingFslib then
// This map is for use when building FSharp.Core.dll. The backing Tycon's may not yet exist for
// the TyconRef's we have in our hands, hence we can't dereference them to find their stamps.
Expand Down Expand Up @@ -757,10 +759,8 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
let key = tcref2.Stamp
if dict.ContainsKey key then Some(dict.[key] tinst)
else None)

let betterTyconRefMapper = buildTyconMapper (Array.append entries1 entries2)

let decodeTyconRefMapper = buildTyconMapper entries2
end


override x.ToString() = "<TcGlobals>"
member __.ilg=ilg
Expand Down Expand Up @@ -1052,8 +1052,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
member val attrib_SecuritySafeCriticalAttribute = findSysAttrib "System.Security.SecuritySafeCriticalAttribute"
member val attrib_ComponentModelEditorBrowsableAttribute = findSysAttrib "System.ComponentModel.EditorBrowsableAttribute"

member __.betterTyconRefMap = betterTyconRefMapper
member __.decodeTyconRefMap = decodeTyconRefMapper
member __.better_tcref_map = betterTyconRefMap
member __.new_decimal_info = v_new_decimal_info
member __.seq_info = v_seq_info
member val seq_vref = (ValRefForIntrinsic v_seq_info)
Expand Down
30 changes: 12 additions & 18 deletions src/fsharp/TypeChecker.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4918,44 +4918,38 @@ and TcProvidedTypeApp cenv env tpenv tcref args m =
/// Note that the generic type may be a nested generic type List<T>.ListEnumerator<U>.
/// In this case, 'args' is only the instantiation of the suffix type arguments, and pathTypeArgs gives
/// the prefix of type arguments.
and TcTypeApp cenv newOk checkCxs occ env tpenv m tcref pathTypeArgs (synArgTys: SynType list) =
and TcTypeApp cenv newOk checkCxs occ env tpenv m tcref pathTypeArgs (synTypeArgs: SynType list) =
CheckTyconAccessible cenv.amap m env.eAccessRights tcref |> ignore
CheckEntityAttributes cenv.g tcref m |> CommitOperationResult

#if !NO_EXTENSIONTYPING
// Provided types are (currently) always non-generic. Their names may include mangled
// static parameters, which are passed by the provider.
if tcref.Deref.IsProvided then TcProvidedTypeApp cenv env tpenv tcref synArgTys m else
if tcref.Deref.IsProvided then TcProvidedTypeApp cenv env tpenv tcref synTypeArgs m else
#endif

let tps, _, tinst, _ = infoOfTyconRef m tcref

// If we're not checking constraints, i.e. when we first assert the super/interfaces of a type definition, then just
// clear the constraint lists of the freshly generated type variables. A little ugly but fairly localized.
if checkCxs = NoCheckCxs then tps |> List.iter (fun tp -> tp.typar_constraints <- [])
if tinst.Length <> pathTypeArgs.Length + synArgTys.Length then
error (TyconBadArgs(env.DisplayEnv, tcref, pathTypeArgs.Length + synArgTys.Length, m))

let argTys, tpenv =
if tinst.Length <> pathTypeArgs.Length + synTypeArgs.Length then
error (TyconBadArgs(env.DisplayEnv, tcref, pathTypeArgs.Length + synTypeArgs.Length, m))

let typeArgs, tpenv =

// Get the suffix of typars
let tpsForArgs = List.drop (tps.Length - synArgTys.Length) tps
let tpsForArgs = List.drop (tps.Length - synTypeArgs.Length) tps
let kindsForArgs = tpsForArgs |> List.map (fun tp -> tp.Kind)
TcTypesOrMeasures (Some kindsForArgs) cenv newOk checkCxs occ env tpenv synArgTys m
TcTypesOrMeasures (Some kindsForArgs) cenv newOk checkCxs occ env tpenv synTypeArgs m

// Add the types of the enclosing class for a nested type
let actualArgTys = pathTypeArgs @ argTys
let typeArgs = pathTypeArgs @ typeArgs

if checkCxs = CheckCxs then
List.iter2 (UnifyTypes cenv env m) tinst actualArgTys

// Try to decode System.Tuple --> F~ tuple types etc.
let ty =
let decode = if cenv.g.compilingFslib then None else cenv.g.decodeTyconRefMap tcref actualArgTys
match decode with
| Some res -> res
| None -> mkAppTy tcref actualArgTys
List.iter2 (UnifyTypes cenv env m) tinst typeArgs

ty, tpenv
mkAppTy tcref typeArgs, tpenv

and TcTypeOrMeasureAndRecover optKind cenv newOk checkCxs occ env tpenv ty =
try TcTypeOrMeasure optKind cenv newOk checkCxs occ env tpenv ty
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/import.fs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ let CanImportILTypeRef (env:ImportMap) m (tref:ILTypeRef) =
/// Prefer the F# abbreviation for some built-in types, e.g. 'string' rather than
/// 'System.String', since we prefer the F# abbreviation to the .NET equivalents.
let ImportTyconRefApp (env:ImportMap) tcref tyargs =
match env.g.betterTyconRefMap tcref tyargs with
match env.g.better_tcref_map tcref tyargs with
| Some res -> res
| None -> TType_app (tcref,tyargs)

Expand Down
8 changes: 0 additions & 8 deletions tests/fsharp/tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1678,14 +1678,6 @@ module TypecheckTests =
#endif

#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS
[<Test>]
let ``sigs pos27`` () =
let cfg = testConfig "typecheck/sigs"
fsc cfg "%s --target:exe -o:pos27.exe" cfg.fsc_flags ["pos27.fs"]
copy_y cfg (cfg.FSCBinPath ++ "System.ValueTuple.dll") ("." ++ "System.ValueTuple.dll")

peverify cfg "pos27.exe"

[<Test>]
let ``sigs pos28`` () =
let cfg = testConfig "typecheck/sigs"
Expand Down
12 changes: 6 additions & 6 deletions tests/fsharp/typecheck/sigs/neg23.bsl
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

neg23.fs(9,21,9,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure1.SomeClass'.
neg23.fs(9,21,9,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure1.SomeClass' once tuples, functions, units of measure and/or provided types are erased.

neg23.fs(7,21,7,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure1.SomeClass'.
neg23.fs(7,21,7,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure1.SomeClass' once tuples, functions, units of measure and/or provided types are erased.

neg23.fs(19,21,19,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure2.SomeClass'.
neg23.fs(19,21,19,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure2.SomeClass' once tuples, functions, units of measure and/or provided types are erased.

neg23.fs(17,21,17,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure2.SomeClass'.
neg23.fs(17,21,17,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure2.SomeClass' once tuples, functions, units of measure and/or provided types are erased.

neg23.fs(28,21,28,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure3.SomeClass'.
neg23.fs(28,21,28,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure3.SomeClass' once tuples, functions, units of measure and/or provided types are erased.

neg23.fs(26,21,26,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure3.SomeClass'.
neg23.fs(26,21,26,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure3.SomeClass' once tuples, functions, units of measure and/or provided types are erased.

neg23.fs(55,21,55,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure6.SomeClass' once tuples, functions, units of measure and/or provided types are erased.

Expand Down
25 changes: 0 additions & 25 deletions tests/fsharp/typecheck/sigs/pos27.fs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// #Regression #Conformance #DeclarationElements #MemberDefinitions #Overloading
// Regression test for FSharp1.0:3762 - Using FastFunc explicitly is not differentiate from function types, thus causing compiler to create bad method tables, maybe other problems
//<Expects span="(7,17-7,20)" id="FS0438" status="error">Duplicate method\. The method 'Foo' has the same name and signature as another method in type 'SomeClass'\.</Expects>
//<Expects span="(7,17-7,20)" id="FS0438" status="error">Duplicate method\. The method 'Foo' has the same name and signature as another method in type 'SomeClass' once tuples, functions, units of measure and/or provided types are erased\.</Expects>
// Note: as of Beta2, FastFunc became FSharpFunc
type SomeClass() =

Expand Down