Simon Jakobi pushed to branch wip/sjakobi/multi-caret at Glasgow Haskell Compiler / GHC Commits: f36bb9d0 by Simon Jakobi at 2026-06-10T15:46:09+02:00 Diagnostics: adopt a rightmost-primary convention for duplicate diagnostics When a diagnostic reports the same entity occurring at several sites (TcRnDuplicateDecls, TcRnBindingNameConflict, TcRnDuplicateExport, TcRnDuplicateNamedDefaultExport), make the primary span the last occurrence in source order, with the earlier occurrences as related locations in ascending order. Duplicates usually arise because the later occurrence was just added, so the primary span -- the location the user is sent to, and the one an editor marks -- is the occurrence they most likely need to act on. This matches other compilers (clang's "redefinition of 'x' / note: previous definition is here", and similarly rustc and TypeScript), and it gives the unlabelled carets a reading: the first caret is the site to fix, the following ones are the prior sites in source order. The convention is documented in Note [The source span model for diagnostics], including a remark on how rustc-style file-order display could be reintroduced once per-span labels (#23414) exist. Concretely: * addDupDeclErr reports at NE.last again (as on master), and dupNamesErr now reports at the last occurrence rather than the first; the related locations for both become NE.init. * The duplicate-export warnings already comply: they are raised at the second occurrence with the first as the related location. * The expected outputs of the duplicate-export tests (ExportWarnings6, haddock.Test, mod128, T11959, T23318, T25901_exp_dup_wc_3/4) had become stale when the renderer stopped sorting the "At:" list; their "At:" entries are now in author order (primary first). * MultiCaretFallback's phantom file is renamed so that it sorts before the real file, keeping the phantom span a related location and the test exercising the "At:" fallback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> - - - - - 45554a02 by Simon Jakobi at 2026-06-10T15:52:00+02:00 Split Note [The source span model for diagnostics] The Note had grown to cover two audiences at once: what the primary/related span model is and how the rendering layer treats it, versus how a message author should pick and order the spans. Move the author-facing guidance (pick one real location rather than a synthetic combined span, order related spans deterministically, the rightmost-primary convention for duplicate diagnostics) into a new Note [Choosing the primary and related spans], and retarget the references at the emission sites accordingly. No content changes beyond the reorganisation and a slight tightening of the ordering bullet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> - - - - - a858aea9 by Simon Jakobi at 2026-06-10T16:21:58+02:00 Note [Choosing the primary and related spans]: trim constructor list Give two examples of duplicate diagnostics rather than enumerating all four, so the Note does not need updating whenever one is added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> - - - - - 672e43e1 by Simon Jakobi at 2026-06-10T16:25:48+02:00 Tighten the diagnostic span notes In Note [Choosing the primary and related spans], fold the three paragraphs of the duplicate-diagnostics convention into one: the squiggle/jump-target explanation restated the model note, and the two rustc passages said the same thing twice. Also compress the LSP correspondence and the "At:" fallback bullet in Note [The source span model for diagnostics]. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> - - - - - 59 changed files: - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Types/Error.hs - testsuite/tests/ghci/scripts/T4127a.stderr - testsuite/tests/ghci/scripts/ghci048.stderr - testsuite/tests/haddock/haddock_examples/haddock.Test.stderr - testsuite/tests/indexed-types/should_fail/SimpleFail6.stderr - testsuite/tests/indexed-types/should_fail/T16110_Fail1.stderr - testsuite/tests/mdo/should_fail/mdofail002.stderr - testsuite/tests/mdo/should_fail/mdofail003.stderr - testsuite/tests/module/mod128.stderr - testsuite/tests/module/mod18.stderr - testsuite/tests/module/mod19.stderr - testsuite/tests/module/mod20.stderr - testsuite/tests/module/mod21.stderr - testsuite/tests/module/mod22.stderr - testsuite/tests/module/mod23.stderr - testsuite/tests/module/mod24.stderr - testsuite/tests/module/mod38.stderr - testsuite/tests/module/mod66.stderr - testsuite/tests/overloadedrecflds/should_fail/FieldSelectors.stderr - testsuite/tests/overloadedrecflds/should_fail/NFSDuplicate.stderr - testsuite/tests/overloadedrecflds/should_fail/T17965.stderr - testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail03.stderr - testsuite/tests/patsyn/should_compile/T11959.stderr - testsuite/tests/patsyn/should_compile/T9975a.stderr - testsuite/tests/patsyn/should_fail/T14114.stderr - testsuite/tests/rename/should_compile/ExportWarnings6.stderr - testsuite/tests/rename/should_compile/T23318.stderr - testsuite/tests/rename/should_fail/MultiCaretFallback.hs - testsuite/tests/rename/should_fail/MultiCaretFallback.stderr - testsuite/tests/rename/should_fail/T22478b.stderr - testsuite/tests/rename/should_fail/T7164.stderr - testsuite/tests/rename/should_fail/rn_dup.stderr - testsuite/tests/rename/should_fail/rnfail001.stderr - testsuite/tests/rename/should_fail/rnfail002.stderr - testsuite/tests/rename/should_fail/rnfail003.stderr - testsuite/tests/rename/should_fail/rnfail004.stderr - testsuite/tests/rename/should_fail/rnfail009.stderr - testsuite/tests/rename/should_fail/rnfail010.stderr - testsuite/tests/rename/should_fail/rnfail011.stderr - testsuite/tests/rename/should_fail/rnfail012.stderr - testsuite/tests/rename/should_fail/rnfail013.stderr - testsuite/tests/rename/should_fail/rnfail015.stderr - testsuite/tests/rename/should_fail/rnfail043.stderr - testsuite/tests/th/T8932.stderr - testsuite/tests/th/TH_dupdecl.stderr - testsuite/tests/type-data/should_fail/TDMultiple01.stderr - testsuite/tests/type-data/should_fail/TDMultiple02.stderr - testsuite/tests/type-data/should_fail/TDPunning.stderr - testsuite/tests/typecheck/should_fail/T22560_fail_c.stderr - testsuite/tests/typecheck/should_fail/TyAppPat_NonlinearMultiAppPat.stderr - testsuite/tests/typecheck/should_fail/TyAppPat_NonlinearMultiPat.stderr - testsuite/tests/typecheck/should_fail/TyAppPat_NonlinearSinglePat.stderr - testsuite/tests/typecheck/should_fail/tcfail038.stderr - testsuite/tests/vdq-rta/should_fail/T22326_fail_nonlinear.stderr - testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_3.stderr - testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_4.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b4d9842a48c4b8fcf942ef6a1a2eb4f... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b4d9842a48c4b8fcf942ef6a1a2eb4f... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Simon Jakobi (@sjakobi2)