{"owner":"facebook","repo":"pyrefly","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# Guidance for Project Agents\n\n## Project Overview\n\nPyrefly is a fast language server and type checker for Python.\n\nArchitecture:\n\n- Written in Rust using Buck (mostly for meta developers) and cargo (mostly for\n  open-source developers)\n- Minimal dependencies, framework-free\n\nAs described in the README, our architecture follows 3 phases:\n\n- figuring out exports\n- making bindings\n- solving the bindings\n\nHere's an overview of some important directories:\n\n- pyrefly/lib/alt - Solving step\n- pyrefly/lib/binding - Binding step\n- pyrefly/lib/commands - CLI\n- pyrefly/lib/config - Config file format & config options\n- pyrefly/lib/error - How we collect and emit errors\n- pyrefly/lib/export - Exports step\n- pyrefly/lib/module - Import resolution/module finding logic\n- pyrefly/lib/solver - Solving type variables and checking if a type is\n  assignable to another type\n- pyrefly/lib/state - Internal state for the language server\n- pyrefly/lib/test - Integration tests for the typechecker\n- pyrefly/lib/test/lsp - Integration tests for the language server\n- pyrefly/lib/test/lsp/lsp_interaction - Heavyweight integration tests for the\n  language server (only add tests here if it's impossible to add them in the\n  lightweight tests)\n- crates/pyrefly_types/src - Our internal representation for Python types\n- conformance - Typing conformance tests pulled from python/typing. Don't edit\n  these manually. Instead, run test.py and include any generated changes with\n  your PR.\n- test - Markdown end-to-end tests for our IDE features\n- website - Source code for pyrefly.org\n- lsp - vscode extension written in typescript\n\n## Codebase style and guidelines\n\nCoding style: All code must be clean, documented and minimal. That means:\n\n- Keep It Simple Stupid (KISS) by reducing the \"Concept Count\". That means,\n  strive for fewer functions or methods, fewer helpers. If a helper is only\n  called by a single callsite, then prefer to inline it into the caller.\n- At the same time, Don't Repeat Yourself (DRY)\n- There is a tension between KISS and DRY. If you find yourself in a situation\n  where you're forced to make a helper method just to avoid repeating yourself,\n  the best solution is to look for a way to avoid even having to do the\n  complicated work at all.\n- If some code looks heavyweight, perhaps with lots of conditionals, then think\n  harder for a more elegant way of achieving it.\n- **Avoid unreachable state.** It is a code smell for a state that ought to be\n  impossible due to surrounding invariants to look reachable.\n  - Prefer to either encode the invariants in the Rust types so that the\n    unreachable state is inexpressible, or refactor so that the code does not\n    depend on implicit assumptions.\n  - As a last resort, use `unreachable!(\"explanation\")` or\n    `.expect(\"explanation\")` to make assumptions explicit.\n  - Never hide the unreachable state through a silent fallback like\n    `_ => default` or `.unwrap_or_default()`.\n- Check for existing helpers in the `pyrefly_types` crate before manually\n  creating or destructuring a `Type`.\n- Minimize the number of places `Expr` nodes are passed around and the number of\n  times they are parsed. Generally, this means extracting semantic information\n  as early as possible.\n- **Imports:** Always add `use` imports at the top of the file rather than using\n  inline qualified paths (e.g., write `use crate::foo::Bar;` and then `Bar`,\n  not `crate::foo::Bar` inline). The only exception is when there is a name\n  collision between two imports, which is rare.\n- **Line-level code quality matters:** Sloppy code introduces unnecessary reviewer\n  overhead. Even if a piece of code is logically correct, it is not ready for\n  review until it is also clean, elegant, and maintainable.\n\n## Comments and Documentation\n\n- Code should have comments and functions should have docstrings, but both should be\n  concise. The best comments are ones that introduce invariants, or prove that invariants are being upheld, or indicate which invariants the code relies upon. Don't write duplicate comments, overly long comments, or comments for things that are obvious from\n  reading the code.\n- Prioritize readability over brevity. Reduce comments by omitting irrelevant\n  information, not by compressing necessary information into fewer words. Use\n  complete sentences, and do not drop words or use sentence fragments to save\n  space or tokens.\n- Use established, standard terminology. Do not coin new terms or shorthand for\n  concepts, because doing so reduces comprehensibility.\n- Write comments and documentation as statements of current truth. Never narrate\n  corrections, prior framings, or what changed.\n- When adding or modifying configuration options or command line flags, the corresponding\n  docs should be updated.\n\n## Commit Messages\n\nThe purpose of a commit message is to convey a commit's intent and rationale to the reader.\nUse simple, plain language; keep it concise; and avoid jargon.\n\nDo not write a laundry list of implementation changes. Focus on:\n\n- **Why**: what problem or design gap motivated the change\n- **What** (high level): the approach or solution, not individual file edits\n- **Why it works**: how the code changes realize the solution\n\n## Development environments\n\nPyrefly is developed both on GitHub and inside Meta's monorepo, and the\navailable tooling differs. **How to detect which one you are in:** check for a\n`BUCK` file in the project root — BUCK files are not exported to GitHub.\n\n- No `BUCK` → GitHub checkout. Only `cargo` is available, `buck` and `arc` do\n  not exist, and source control is git. The rest of this file assumes this case.\n- `BUCK` present → Meta-internal checkout. Read `facebook/AGENTS.md`, which\n  covers the internal tooling and conventions (buck, arc, Sapling, Phabricator\n  diffs) and overrides this file where they conflict.\n\n## Feature guidelines\n\n- When working on a feature, the first commit should be a failing test if\n  possible\n\n### Running tests\n\n- `cargo test <name of test>`\n\n### Running the full test suite\n\n- `./test.py` runs linters and tests. It is heavyweight, so only run it when\n  you are confident the feature is complete.\n- For external builds, always use `python3 test.py` instead of `./test.py`.\n- To run just formatting and linting (much faster than running tests):\n  `./test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema`\n\n### Before committing\n\n**Always run formatting and linting before committing, updating a commit, or\nhanding code off to a human for review:**\n`./test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema`\n\nThis applies whether you are committing autonomously or preparing code for a\nhuman to commit. Do not skip this step during human-in-the-loop iteration.\n\n- Running full tests before committing is ideal but optional since CI will run\n  them. However, you must never skip formatting and linting.\n- Lints may not always be fully clean due to pre-existing issues. The key\n  requirement is: do not introduce *new* lint errors. If linting fails, check\n  whether the errors are in code you modified. If so, fix them before\n  committing.\n\n## Writing tests\n\n### The `bug` marker in tests\n\nThe `testcase!` macro supports a `bug = \"<description>\"` marker to indicate that\na test captures undesirable behavior. Important points:\n\n- **Tests with `bug` must pass.** The marker documents that the *behavior* is\n  wrong, not that the test itself should fail. Do not expect a `bug`-marked test\n  to be a failing test.\n- **Workflow for documenting known issues:** Add a passing test that shows the\n  undesired behavior, using `bug = \"...\"` to explain what's wrong. This can be\n  done to track issues or as part of a stack where a later diff fixes the bug.\n- **Workflow for fixing bugs:** When the bug is fixed, remove the `bug` marker\n  and update the test expectations to reflect the correct behavior.\n- **Partial fixes:** If a test shows multiple undesired behaviors and a diff\n  fixes only some of them, keep the `bug` marker but update the message if it\n  has become stale.\n- **Message length:** Keep the `bug` message concise. For complicated bugs, add\n  detailed explanations as comments inside the test body rather than making the\n  marker message very long. If there is an associated Github issue, linking to it\n  in a comment is often sufficient without paraphrasing the issue in the test.\n\n### `testcase!` header hygiene\n\nThe macro uses `line!()` to map errors in the embedded source back to the test file,\nassuming a fixed layout. Extra lines in the header shift every reported line number.\n\n- Put comments above `testcase!(`, never between it and the `r#\"...\"#` content.\n- Keep `bug = \"...\"` on one line, with no blank lines in the header.\n- `rustfmt` re-splits a `bug = ` line past 100 cols, so keep the message short\n  enough to fit; put longer detail in a comment above the macro.\n\n### Prefer `assert_type` over `reveal_type`\n\n`assert_type` checks for type equivalence, whereas `reveal_type` expectations\ndo a more fragile text-based match. Prefer to use `assert_type` when possible.\nIt's acceptable to use `reveal_type` in cases in which the expected type cannot\nbe expressed in a type annotation - for example, a complex function signature.\n"},"files":{"AGENTS.md":"# Guidance for Project Agents\n\n## Project Overview\n\nPyrefly is a fast language server and type checker for Python.\n\nArchitecture:\n\n- Written in Rust using Buck (mostly for meta developers) and cargo (mostly for\n  open-source developers)\n- Minimal dependencies, framework-free\n\nAs described in the README, our architecture follows 3 phases:\n\n- figuring out exports\n- making bindings\n- solving the bindings\n\nHere's an overview of some important directories:\n\n- pyrefly/lib/alt - Solving step\n- pyrefly/lib/binding - Binding step\n- pyrefly/lib/commands - CLI\n- pyrefly/lib/config - Config file format & config options\n- pyrefly/lib/error - How we collect and emit errors\n- pyrefly/lib/export - Exports step\n- pyrefly/lib/module - Import resolution/module finding logic\n- pyrefly/lib/solver - Solving type variables and checking if a type is\n  assignable to another type\n- pyrefly/lib/state - Internal state for the language server\n- pyrefly/lib/test - Integration tests for the typechecker\n- pyrefly/lib/test/lsp - Integration tests for the language server\n- pyrefly/lib/test/lsp/lsp_interaction - Heavyweight integration tests for the\n  language server (only add tests here if it's impossible to add them in the\n  lightweight tests)\n- crates/pyrefly_types/src - Our internal representation for Python types\n- conformance - Typing conformance tests pulled from python/typing. Don't edit\n  these manually. Instead, run test.py and include any generated changes with\n  your PR.\n- test - Markdown end-to-end tests for our IDE features\n- website - Source code for pyrefly.org\n- lsp - vscode extension written in typescript\n\n## Codebase style and guidelines\n\nCoding style: All code must be clean, documented and minimal. That means:\n\n- Keep It Simple Stupid (KISS) by reducing the \"Concept Count\". That means,\n  strive for fewer functions or methods, fewer helpers. If a helper is only\n  called by a single callsite, then prefer to inline it into the caller.\n- At the same time, Don't Repeat Yourself (DRY)\n- There is a tension between KISS and DRY. If you find yourself in a situation\n  where you're forced to make a helper method just to avoid repeating yourself,\n  the best solution is to look for a way to avoid even having to do the\n  complicated work at all.\n- If some code looks heavyweight, perhaps with lots of conditionals, then think\n  harder for a more elegant way of achieving it.\n- **Avoid unreachable state.** It is a code smell for a state that ought to be\n  impossible due to surrounding invariants to look reachable.\n  - Prefer to either encode the invariants in the Rust types so that the\n    unreachable state is inexpressible, or refactor so that the code does not\n    depend on implicit assumptions.\n  - As a last resort, use `unreachable!(\"explanation\")` or\n    `.expect(\"explanation\")` to make assumptions explicit.\n  - Never hide the unreachable state through a silent fallback like\n    `_ => default` or `.unwrap_or_default()`.\n- Check for existing helpers in the `pyrefly_types` crate before manually\n  creating or destructuring a `Type`.\n- Minimize the number of places `Expr` nodes are passed around and the number of\n  times they are parsed. Generally, this means extracting semantic information\n  as early as possible.\n- **Imports:** Always add `use` imports at the top of the file rather than using\n  inline qualified paths (e.g., write `use crate::foo::Bar;` and then `Bar`,\n  not `crate::foo::Bar` inline). The only exception is when there is a name\n  collision between two imports, which is rare.\n- **Line-level code quality matters:** Sloppy code introduces unnecessary reviewer\n  overhead. Even if a piece of code is logically correct, it is not ready for\n  review until it is also clean, elegant, and maintainable.\n\n## Comments and Documentation\n\n- Code should have comments and functions should have docstrings, but both should be\n  concise. The best comments are ones that introduce invariants, or prove that invariants are being upheld, or indicate which invariants the code relies upon. Don't write duplicate comments, overly long comments, or comments for things that are obvious from\n  reading the code.\n- Prioritize readability over brevity. Reduce comments by omitting irrelevant\n  information, not by compressing necessary information into fewer words. Use\n  complete sentences, and do not drop words or use sentence fragments to save\n  space or tokens.\n- Use established, standard terminology. Do not coin new terms or shorthand for\n  concepts, because doing so reduces comprehensibility.\n- Write comments and documentation as statements of current truth. Never narrate\n  corrections, prior framings, or what changed.\n- When adding or modifying configuration options or command line flags, the corresponding\n  docs should be updated.\n\n## Commit Messages\n\nThe purpose of a commit message is to convey a commit's intent and rationale to the reader.\nUse simple, plain language; keep it concise; and avoid jargon.\n\nDo not write a laundry list of implementation changes. Focus on:\n\n- **Why**: what problem or design gap motivated the change\n- **What** (high level): the approach or solution, not individual file edits\n- **Why it works**: how the code changes realize the solution\n\n## Development environments\n\nPyrefly is developed both on GitHub and inside Meta's monorepo, and the\navailable tooling differs. **How to detect which one you are in:** check for a\n`BUCK` file in the project root — BUCK files are not exported to GitHub.\n\n- No `BUCK` → GitHub checkout. Only `cargo` is available, `buck` and `arc` do\n  not exist, and source control is git. The rest of this file assumes this case.\n- `BUCK` present → Meta-internal checkout. Read `facebook/AGENTS.md`, which\n  covers the internal tooling and conventions (buck, arc, Sapling, Phabricator\n  diffs) and overrides this file where they conflict.\n\n## Feature guidelines\n\n- When working on a feature, the first commit should be a failing test if\n  possible\n\n### Running tests\n\n- `cargo test <name of test>`\n\n### Running the full test suite\n\n- `./test.py` runs linters and tests. It is heavyweight, so only run it when\n  you are confident the feature is complete.\n- For external builds, always use `python3 test.py` instead of `./test.py`.\n- To run just formatting and linting (much faster than running tests):\n  `./test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema`\n\n### Before committing\n\n**Always run formatting and linting before committing, updating a commit, or\nhanding code off to a human for review:**\n`./test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema`\n\nThis applies whether you are committing autonomously or preparing code for a\nhuman to commit. Do not skip this step during human-in-the-loop iteration.\n\n- Running full tests before committing is ideal but optional since CI will run\n  them. However, you must never skip formatting and linting.\n- Lints may not always be fully clean due to pre-existing issues. The key\n  requirement is: do not introduce *new* lint errors. If linting fails, check\n  whether the errors are in code you modified. If so, fix them before\n  committing.\n\n## Writing tests\n\n### The `bug` marker in tests\n\nThe `testcase!` macro supports a `bug = \"<description>\"` marker to indicate that\na test captures undesirable behavior. Important points:\n\n- **Tests with `bug` must pass.** The marker documents that the *behavior* is\n  wrong, not that the test itself should fail. Do not expect a `bug`-marked test\n  to be a failing test.\n- **Workflow for documenting known issues:** Add a passing test that shows the\n  undesired behavior, using `bug = \"...\"` to explain what's wrong. This can be\n  done to track issues or as part of a stack where a later diff fixes the bug.\n- **Workflow for fixing bugs:** When the bug is fixed, remove the `bug` marker\n  and update the test expectations to reflect the correct behavior.\n- **Partial fixes:** If a test shows multiple undesired behaviors and a diff\n  fixes only some of them, keep the `bug` marker but update the message if it\n  has become stale.\n- **Message length:** Keep the `bug` message concise. For complicated bugs, add\n  detailed explanations as comments inside the test body rather than making the\n  marker message very long. If there is an associated Github issue, linking to it\n  in a comment is often sufficient without paraphrasing the issue in the test.\n\n### `testcase!` header hygiene\n\nThe macro uses `line!()` to map errors in the embedded source back to the test file,\nassuming a fixed layout. Extra lines in the header shift every reported line number.\n\n- Put comments above `testcase!(`, never between it and the `r#\"...\"#` content.\n- Keep `bug = \"...\"` on one line, with no blank lines in the header.\n- `rustfmt` re-splits a `bug = ` line past 100 cols, so keep the message short\n  enough to fit; put longer detail in a comment above the macro.\n\n### Prefer `assert_type` over `reveal_type`\n\n`assert_type` checks for type equivalence, whereas `reveal_type` expectations\ndo a more fragile text-based match. Prefer to use `assert_type` when possible.\nIt's acceptable to use `reveal_type` in cases in which the expected type cannot\nbe expressed in a type annotation - for example, a complex function signature.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Guidance for Project Agents\n\n## Project Overview\n\nPyrefly is a fast language server and type checker for Python.\n\nArchitecture:\n\n- Written in Rust using Buck (mostly for meta developers) and cargo (mostly for\n  open-source developers)\n- Minimal dependencies, framework-free\n\nAs described in the README, our architecture follows 3 phases:\n\n- figuring out exports\n- making bindings\n- solving the bindings\n\nHere's an overview of some important directories:\n\n- pyrefly/lib/alt - Solving step\n- pyrefly/lib/binding - Binding step\n- pyrefly/lib/commands - CLI\n- pyrefly/lib/config - Config file format & config options\n- pyrefly/lib/error - How we collect and emit errors\n- pyrefly/lib/export - Exports step\n- pyrefly/lib/module - Import resolution/module finding logic\n- pyrefly/lib/solver - Solving type variables and checking if a type is\n  assignable to another type\n- pyrefly/lib/state - Internal state for the language server\n- pyrefly/lib/test - Integration tests for the typechecker\n- pyrefly/lib/test/lsp - Integration tests for the language server\n- pyrefly/lib/test/lsp/lsp_interaction - Heavyweight integration tests for the\n  language server (only add tests here if it's impossible to add them in the\n  lightweight tests)\n- crates/pyrefly_types/src - Our internal representation for Python types\n- conformance - Typing conformance tests pulled from python/typing. Don't edit\n  these manually. Instead, run test.py and include any generated changes with\n  your PR.\n- test - Markdown end-to-end tests for our IDE features\n- website - Source code for pyrefly.org\n- lsp - vscode extension written in typescript\n\n## Codebase style and guidelines\n\nCoding style: All code must be clean, documented and minimal. That means:\n\n- Keep It Simple Stupid (KISS) by reducing the \"Concept Count\". That means,\n  strive for fewer functions or methods, fewer helpers. If a helper is only\n  called by a single callsite, then prefer to inline it into the caller.\n- At the same time, Don't Repeat Yourself (DRY)\n- There is a tension between KISS and DRY. If you find yourself in a situation\n  where you're forced to make a helper method just to avoid repeating yourself,\n  the best solution is to look for a way to avoid even having to do the\n  complicated work at all.\n- If some code looks heavyweight, perhaps with lots of conditionals, then think\n  harder for a more elegant way of achieving it.\n- **Avoid unreachable state.** It is a code smell for a state that ought to be\n  impossible due to surrounding invariants to look reachable.\n  - Prefer to either encode the invariants in the Rust types so that the\n    unreachable state is inexpressible, or refactor so that the code does not\n    depend on implicit assumptions.\n  - As a last resort, use `unreachable!(\"explanation\")` or\n    `.expect(\"explanation\")` to make assumptions explicit.\n  - Never hide the unreachable state through a silent fallback like\n    `_ => default` or `.unwrap_or_default()`.\n- Check for existing helpers in the `pyrefly_types` crate before manually\n  creating or destructuring a `Type`.\n- Minimize the number of places `Expr` nodes are passed around and the number of\n  times they are parsed. Generally, this means extracting semantic information\n  as early as possible.\n- **Imports:** Always add `use` imports at the top of the file rather than using\n  inline qualified paths (e.g., write `use crate::foo::Bar;` and then `Bar`,\n  not `crate::foo::Bar` inline). The only exception is when there is a name\n  collision between two imports, which is rare.\n- **Line-level code quality matters:** Sloppy code introduces unnecessary reviewer\n  overhead. Even if a piece of code is logically correct, it is not ready for\n  review until it is also clean, elegant, and maintainable.\n\n## Comments and Documentation\n\n- Code should have comments and functions should have docstrings, but both should be\n  concise. The best comments are ones that introduce invariants, or prove that invariants are being upheld, or indicate which invariants the code relies upon. Don't write duplicate comments, overly long comments, or comments for things that are obvious from\n  reading the code.\n- Prioritize readability over brevity. Reduce comments by omitting irrelevant\n  information, not by compressing necessary information into fewer words. Use\n  complete sentences, and do not drop words or use sentence fragments to save\n  space or tokens.\n- Use established, standard terminology. Do not coin new terms or shorthand for\n  concepts, because doing so reduces comprehensibility.\n- Write comments and documentation as statements of current truth. Never narrate\n  corrections, prior framings, or what changed.\n- When adding or modifying configuration options or command line flags, the corresponding\n  docs should be updated.\n\n## Commit Messages\n\nThe purpose of a commit message is to convey a commit's intent and rationale to the reader.\nUse simple, plain language; keep it concise; and avoid jargon.\n\nDo not write a laundry list of implementation changes. Focus on:\n\n- **Why**: what problem or design gap motivated the change\n- **What** (high level): the approach or solution, not individual file edits\n- **Why it works**: how the code changes realize the solution\n\n## Development environments\n\nPyrefly is developed both on GitHub and inside Meta's monorepo, and the\navailable tooling differs. **How to detect which one you are in:** check for a\n`BUCK` file in the project root — BUCK files are not exported to GitHub.\n\n- No `BUCK` → GitHub checkout. Only `cargo` is available, `buck` and `arc` do\n  not exist, and source control is git. The rest of this file assumes this case.\n- `BUCK` present → Meta-internal checkout. Read `facebook/AGENTS.md`, which\n  covers the internal tooling and conventions (buck, arc, Sapling, Phabricator\n  diffs) and overrides this file where they conflict.\n\n## Feature guidelines\n\n- When working on a feature, the first commit should be a failing test if\n  possible\n\n### Running tests\n\n- `cargo test <name of test>`\n\n### Running the full test suite\n\n- `./test.py` runs linters and tests. It is heavyweight, so only run it when\n  you are confident the feature is complete.\n- For external builds, always use `python3 test.py` instead of `./test.py`.\n- To run just formatting and linting (much faster than running tests):\n  `./test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema`\n\n### Before committing\n\n**Always run formatting and linting before committing, updating a commit, or\nhanding code off to a human for review:**\n`./test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema`\n\nThis applies whether you are committing autonomously or preparing code for a\nhuman to commit. Do not skip this step during human-in-the-loop iteration.\n\n- Running full tests before committing is ideal but optional since CI will run\n  them. However, you must never skip formatting and linting.\n- Lints may not always be fully clean due to pre-existing issues. The key\n  requirement is: do not introduce *new* lint errors. If linting fails, check\n  whether the errors are in code you modified. If so, fix them before\n  committing.\n\n## Writing tests\n\n### The `bug` marker in tests\n\nThe `testcase!` macro supports a `bug = \"<description>\"` marker to indicate that\na test captures undesirable behavior. Important points:\n\n- **Tests with `bug` must pass.** The marker documents that the *behavior* is\n  wrong, not that the test itself should fail. Do not expect a `bug`-marked test\n  to be a failing test.\n- **Workflow for documenting known issues:** Add a passing test that shows the\n  undesired behavior, using `bug = \"...\"` to explain what's wrong. This can be\n  done to track issues or as part of a stack where a later diff fixes the bug.\n- **Workflow for fixing bugs:** When the bug is fixed, remove the `bug` marker\n  and update the test expectations to reflect the correct behavior.\n- **Partial fixes:** If a test shows multiple undesired behaviors and a diff\n  fixes only some of them, keep the `bug` marker but update the message if it\n  has become stale.\n- **Message length:** Keep the `bug` message concise. For complicated bugs, add\n  detailed explanations as comments inside the test body rather than making the\n  marker message very long. If there is an associated Github issue, linking to it\n  in a comment is often sufficient without paraphrasing the issue in the test.\n\n### `testcase!` header hygiene\n\nThe macro uses `line!()` to map errors in the embedded source back to the test file,\nassuming a fixed layout. Extra lines in the header shift every reported line number.\n\n- Put comments above `testcase!(`, never between it and the `r#\"...\"#` content.\n- Keep `bug = \"...\"` on one line, with no blank lines in the header.\n- `rustfmt` re-splits a `bug = ` line past 100 cols, so keep the message short\n  enough to fit; put longer detail in a comment above the macro.\n\n### Prefer `assert_type` over `reveal_type`\n\n`assert_type` checks for type equivalence, whereas `reveal_type` expectations\ndo a more fragile text-based match. Prefer to use `assert_type` when possible.\nIt's acceptable to use `reveal_type` in cases in which the expected type cannot\nbe expressed in a type annotation - for example, a complex function signature.\n","category":"root","tokens":2309}]}