[Git][ghc/ghc][wip/T20264] 23 commits: Implement QualifiedStrings (#26503)
Simon Peyton Jones pushed to branch wip/T20264 at Glasgow Haskell Compiler / GHC Commits: ea4c2cbd by Brandon Chinn at 2026-02-27T16:22:38-08:00 Implement QualifiedStrings (#26503) See Note [Implementation of QualifiedStrings] - - - - - 08bc245b by sheaf at 2026-03-01T11:11:54-05:00 Clean up join points, casts & ticks This commit shores up the logic dealing with casts and ticks occurring in between a join point binding and a jump. Fixes #26642 #26929 #26693 Makes progress on #14610 #26157 #26422 Changes: - Remove 'GHC.Types.Tickish.TickishScoping' in favour of simpler predicates 'tickishHasNoScope'/'tickishHasSoftScope', as things were before commit 993975d3. This makes the code easier to read and document (fewer indirections). - Introduce 'canCollectArgsThroughTick' for consistent handling of ticks around PrimOps and other 'Id's that cannot be eta-reduced. See overhauled Note [Ticks and mandatory eta expansion]. - New Note [JoinId vs TailCallInfo] in GHC.Core.SimpleOpt that explains robustness of JoinId vs fragility of TailCallInfo. - Allow casts/non-soft-scoped ticks to occur in between a join point binder and a jump, but only in Core Prep. See Note [Join points, casts, and ticks] and Note [Join points, casts, and ticks... in Core Prep] in GHC.Core.Opt.Simplify.Iteration. Also update Core Lint to account for this. See Note [Linting join points with casts or ticks] in GHC.Core.Lint. - Update 'GHC.Core.Utils.mergeCaseAlts' to avoid pushing a cast in between a join point binding and its jumps. This fixes #26642. See the new (MC5) and (MC6) in Note [Merge Nested Cases]. - Update float out to properly handle source note ticks. They are now properly floated out instead of being discarded. This increases the number of ticks in certain tests with -g. Test cases: T26642 and TrickyJoins. Metric increase due to more source note ticks with -g: ------------------------- Metric Increase: libdir size_hello_artifact size_hello_unicode ------------------------- - - - - - 476c4cdf by Sean D. Gillespie at 2026-03-02T10:14:37-05:00 Add SIMD absolute value on x86 and LLVM On x86, absolute value of 32 bits or less is implemented with PABSB/PABSW/PABSD if SSSE3 is available. Otherwise, there is a fallback for SSE2. For 64 bit integers it uses VPABSQ, required by AVX-512VL, with fallbacks for SSE4.2 and SSE2. There is no dedicated instruction for floating point absolute value on x86, so it is simulated using bitwise AND. Absolute value for signed integers and floats are implemented by the "llvm.abs/llvm.fabs" standard library intrinsics. This implementation uses MachOps constructors, unlike non-vector floating point absolute value, which uses CallishMachOps. - - - - - 709448c0 by Sean D. Gillespie at 2026-03-02T10:14:46-05:00 Add SIMD floating point square root On x86, this is implemented with the SQRTPS and SQRTPD instructions. On LLVM, it uses the sqrt library intrinstic. - - - - - 0deadf66 by Sean D. Gillespie at 2026-03-02T10:14:47-05:00 Improve error message for SIMD on aarch64 When encountering vector literals on aarch64, previously it would throw: <no location info>: error: panic! (the 'impossible' happened) GHC version 9.15.20251219: getRegister' (CmmLit:CmmVec): Now it is more consistent with the other vector operations: <no location info>: error: sorry! (unimplemented feature or known bug) GHC version 9.15.20251219: SIMD operations on AArch64 currently require the LLVM backend - - - - - 7d64031b by Vladislav Zavialov at 2026-03-03T11:09:28-05:00 Replace maybeAddSpace with spaceIfSingleQuote Simplify pretty-printing of HsTypes by using spaceIfSingleQuote. This allows us to drop the unwieldy lhsTypeHasLeadingPromotionQuote helper function. Follow-up to 178c1fd830c78377ef5d338406a41e1d8eb5f0da - - - - - 20b2d918 by Joseph Fourment at 2026-03-03T23:29:51+00:00 Add type-lets into Core The plan for #20264 is to introduce let-bound types to have observable sharing in types. To avoid the need to carry an environment when dealing with occurrences of these type variables, we embed the types they're bound to (if any) in a `tv_unfolding :: Maybe Type` attribute. This way, one can look through let-bound type variables using `coreView` and friends. In particular, definitional equality looks through unfoldings. simple-opt: don't inline type-lets specialise: fix type-lets in DFun unfoldings During specialisation, a dictionary being specialised gets a new unfolding by turning `DFun \ bndrs -> MkD @<T1> ... @<Tm> <op1> ... <opn>` into `DFun \ spec_bndrs -> MkD @((\ bndrs -> TYPE: <T1>) spec_args) ... ((\ bndrs -> <opn>) spec_args)` which in turns gets beta-reduced into `DFun \ spec_bndrs -> MkD (let { bndrs = spec_args } in TYPE: <T1>) ... (let { bndrs = spec_args } in <opn>)`. Previously, such let binders would immediately be substituted into the type so it didn't cause any issue, but now we want to avoid inlining. Arguments of the form `let { bndrs = spec_args } in TYPE: <T1>` are not considered as type arguments since they're not of the canonical form `TYPE: something`. This commit restores the previous behavior of substituting the specialised type arguments. Alternatively, we could attach some floated type bindings to `DFun`s. occur-anal: implement occurence analysis for type variables In order to find out let-bound type variables that are used only once, in the hope of inlining them, we need to track type variables as well in the occurrence analiser. Just like Id's, we attach an `OccInfo` to each (immutable) type variable, and we walk into types and coercions to accurately gather occurrences. simplifier: don't inline type-lets Keep propagating type-lets further down the pipeline, in the simplifier. We also update CallArity, CprAnal, DmdAnal, WorkWrap, and Specialise to ignore type-lets. prep: make type-lets pass through CorePrep As a first attempt, ignore type-lets in CorePrep to avoid crashes. However, this is not enough: CorePrep also does some let-floating. If we don't float type-lets along with value-level let-bindings, the latter can float out of the scope of a type variable in use. simple-opt: fix simple_type_bind Also: - Inline small types using a new typeIsSmallEnoughToInline predicate - Inline single-occurrence variables simple-opt: make beta-reduction use simple_bind_type iface: add IfaceTypeLetBndr to represent non-top-level type-let binders IfaceLetBndr isn't fit to represent type-let binders, as it includes a bunch of vacuous flags for Ids only. Instead of putting squares in circles, I added a new constructor for type binders. The downside is that it breaks existing iface files, so since we can't bootstrap yet so we have to bootstrap a cherry-picked branch and then checkout again to build with --freeze1. To avoid similar issues in the future, IfaceTyVarInfoItem serialises with a tag despite there being only one constructor for now. dmd-anal: prefix unused variable with _ to avoid warning type: inline unfoldView in sORTKind_maybe tidy: deal with type-lets notes: add Note [Type and coercion lets] notes: update Note [Comparing nullary type synonyms] to account for type variables While updating backlinks, I noticed the optimisation for type variables could be performed in more places. simplifier: inline single-occurring type-lets cleanup: remove NOINLINE on tyVarOccInfo Wibbles Wibbles Progress Progress More progress Progress ...doesn't compile though Mostly working now Aggressively create type-lets more progress More progress Temp debug printing Remove bogus assert Fix anoher couple of bugs in SimpleOpt and exprIsTrivial Improve zonking of foreign decls to avoid TcTyVars escaping Wibbles Some small wibbles Improvements Rmmove trace Wibbles Use lambda, not let, in WorkWrap Using type let did not work right with type lets and shadowing Requires Lint to be OK join points under beta redexes -- but it is! Needs better documentation Wibbles More improvements More improvements * Less cloning in SpecConstr * Lint checks RULES for imported binders Comments only Wibble Wibbles Wibbles .. getting Lint errors when compiling GHC.Internal.Classes Wibbles More improvements ..now getting to the back end an interface file generation Wibbles Wibble unsed var Missing case in tyThingEntityInfo Add IfaceExtTyVar Wibbles Start to make OccAnal count TyCoVars properly [skip ci] Proper occurrence analysis for TyCoVars Wibble imports Wibble imports again Fix two tricky buglets More small fixes Add missing mkAbsCoreApps ...which caused bad Lint errors More wibbles More wibbles exp around mkPolyAbsLams - - - - - 7ed656f2 by Simon Peyton Jones at 2026-03-03T23:29:54+00:00 Make it compile again - - - - - cc99af3a by Simon Peyton Jones at 2026-03-03T23:29:54+00:00 Simplify mkcoreAbsLams a bit ..Needs documentation - - - - - 65cdc8ed by Simon Peyton Jones at 2026-03-03T23:32:48+00:00 Fix build Several important fixes, need better docs - - - - - c63f69e8 by Simon Peyton Jones at 2026-03-03T23:32:51+00:00 Wibbles - - - - - 5e50af53 by Simon Peyton Jones at 2026-03-03T23:32:51+00:00 Make it compile - - - - - 66c8805b by Simon Peyton Jones at 2026-03-03T23:32:51+00:00 Improve Lint error message slightly - - - - - d90339ab by Simon Peyton Jones at 2026-03-03T23:32:51+00:00 Wibble lint rules - - - - - da7c3120 by Simon Peyton Jones at 2026-03-03T23:32:51+00:00 Wibbles - - - - - 30a4be88 by Simon Peyton Jones at 2026-03-03T23:33:49+00:00 Wibbles - - - - - 1538568e by Simon Peyton Jones at 2026-03-03T23:33:49+00:00 Expand tyvars in Specialise Pretty important! - - - - - 4eabfe97 by Simon Peyton Jones at 2026-03-03T23:33:49+00:00 Comments only - - - - - fb3ca68c by Simon Peyton Jones at 2026-03-03T23:33:50+00:00 More wibbles * `bindAuxiliaryTyVars` in Specialise * `trivial_expr_fold` needs to accept big coercions in CoreToStg because the binder-swap can duplicate big coercions (boo) Plus renaming in Specialise - - - - - f0bdb345 by Simon Peyton Jones at 2026-03-03T23:33:50+00:00 Onward - - - - - e2837f76 by Simon Peyton Jones at 2026-03-03T23:34:59+00:00 More wibbles - - - - - 84ddae32 by Simon Peyton Jones at 2026-03-03T23:35:02+00:00 Wibbles - - - - - f2d502b9 by Simon Peyton Jones at 2026-03-03T23:40:57+00:00 Wibbles - - - - - 208 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/LateCC/TopLevelBinds.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Seq.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Core/TyCo/Compare.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Ppr.hs-boot - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold/Make.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/Core/Lint.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Solver.hs - compiler/GHC/HsToCore/Pmc/Utils.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/String.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - + compiler/GHC/Rename/Lit.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Solver/Rewrite.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Types/BasicTypes.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Zonk/TcType.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/Tickish.hs - compiler/GHC/Types/TyThing.hs - compiler/GHC/Types/TypeEnv.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Outputable.hs - compiler/GHC/Utils/Trace.hs - compiler/Language/Haskell/Syntax/Decls/Foreign.hs - compiler/Language/Haskell/Syntax/Expr.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Lit.hs - compiler/Language/Haskell/Syntax/Pat.hs - compiler/ghc.cabal.in - docs/users_guide/9.16.1-notes.rst - + docs/users_guide/exts/qualified_strings.rst - ghc/GHCi/UI.hs - hadrian/src/Settings/Default.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-experimental/CHANGELOG.md - libraries/ghc-internal/src/GHC/Internal/LanguageExtensions.hs - testsuite/tests/codeGen/should_compile/debug.stdout - testsuite/tests/driver/T4437.hs - testsuite/tests/ghc-api/annotations-literals/literals.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - testsuite/tests/interface-stability/ghc-prim-exports.stdout - testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32 - testsuite/tests/interface-stability/template-haskell-exports.stdout - + testsuite/tests/qualified-strings/Makefile - + testsuite/tests/qualified-strings/should_compile/Example/Length.hs - + testsuite/tests/qualified-strings/should_compile/all.T - + testsuite/tests/qualified-strings/should_compile/qstrings_redundant_pattern.hs - + testsuite/tests/qualified-strings/should_compile/qstrings_redundant_pattern.stderr - + testsuite/tests/qualified-strings/should_fail/Example/Length.hs - + testsuite/tests/qualified-strings/should_fail/Makefile - + testsuite/tests/qualified-strings/should_fail/all.T - + testsuite/tests/qualified-strings/should_fail/qstrings_bad_expr.hs - + testsuite/tests/qualified-strings/should_fail/qstrings_bad_expr.stderr - + testsuite/tests/qualified-strings/should_fail/qstrings_bad_pat.hs - + testsuite/tests/qualified-strings/should_fail/qstrings_bad_pat.stderr - + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.hs - + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.stderr - + testsuite/tests/qualified-strings/should_run/Example/ByteStringAscii.hs - + testsuite/tests/qualified-strings/should_run/Example/ByteStringUtf8.hs - + testsuite/tests/qualified-strings/should_run/Example/Text.hs - + testsuite/tests/qualified-strings/should_run/Makefile - + testsuite/tests/qualified-strings/should_run/all.T - + testsuite/tests/qualified-strings/should_run/qstrings_expr.hs - + testsuite/tests/qualified-strings/should_run/qstrings_expr.stdout - + testsuite/tests/qualified-strings/should_run/qstrings_pat.hs - + testsuite/tests/qualified-strings/should_run/qstrings_pat.stdout - + testsuite/tests/qualified-strings/should_run/qstrings_th.hs - + testsuite/tests/qualified-strings/should_run/qstrings_th.stdout - testsuite/tests/simd/should_run/doublex2_arith.hs - testsuite/tests/simd/should_run/doublex2_arith.stdout - testsuite/tests/simd/should_run/doublex2_arith_baseline.hs - testsuite/tests/simd/should_run/doublex2_arith_baseline.stdout - testsuite/tests/simd/should_run/floatx4_arith.hs - testsuite/tests/simd/should_run/floatx4_arith.stdout - testsuite/tests/simd/should_run/floatx4_arith_baseline.hs - testsuite/tests/simd/should_run/floatx4_arith_baseline.stdout - testsuite/tests/simd/should_run/int16x8_arith.hs - testsuite/tests/simd/should_run/int16x8_arith.stdout - testsuite/tests/simd/should_run/int16x8_arith_baseline.hs - testsuite/tests/simd/should_run/int16x8_arith_baseline.stdout - testsuite/tests/simd/should_run/int32x4_arith.hs - testsuite/tests/simd/should_run/int32x4_arith.stdout - testsuite/tests/simd/should_run/int32x4_arith_baseline.hs - testsuite/tests/simd/should_run/int32x4_arith_baseline.stdout - testsuite/tests/simd/should_run/int64x2_arith.hs - testsuite/tests/simd/should_run/int64x2_arith.stdout - testsuite/tests/simd/should_run/int64x2_arith_baseline.hs - testsuite/tests/simd/should_run/int64x2_arith_baseline.stdout - testsuite/tests/simd/should_run/int8x16_arith.hs - testsuite/tests/simd/should_run/int8x16_arith.stdout - testsuite/tests/simd/should_run/int8x16_arith_baseline.hs - testsuite/tests/simd/should_run/int8x16_arith_baseline.stdout - + testsuite/tests/simplCore/should_compile/T26642.hs - + testsuite/tests/simplCore/should_compile/TrickyJoins.hs - testsuite/tests/simplCore/should_compile/all.T - utils/check-exact/ExactPrint.hs - utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs - utils/haddock/haddock-api/src/Haddock/Convert.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/687f3662c2f384dec27130862a3352a... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/687f3662c2f384dec27130862a3352a... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Simon Peyton Jones (@simonpj)