aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md9
-rw-r--r--.github/workflows/release.yaml49
-rw-r--r--.vscode/launch.json6
-rw-r--r--Cargo.lock779
-rw-r--r--README.md1
-rw-r--r--bench_data/glorious_old_parser8562
-rw-r--r--bench_data/numerous_macro_rules560
-rw-r--r--crates/assists/src/utils.rs250
-rw-r--r--crates/base_db/src/change.rs2
-rw-r--r--crates/base_db/src/fixture.rs11
-rw-r--r--crates/base_db/src/input.rs2
-rw-r--r--crates/completion/src/completions/flyimport.rs291
-rw-r--r--crates/completion/src/generated_lint_completions.rs5
-rw-r--r--crates/flycheck/Cargo.toml4
-rw-r--r--crates/flycheck/src/lib.rs21
-rw-r--r--crates/hir/src/attrs.rs6
-rw-r--r--crates/hir/src/code_model.rs297
-rw-r--r--crates/hir/src/db.rs14
-rw-r--r--crates/hir/src/diagnostics.rs6
-rw-r--r--crates/hir/src/from_id.rs21
-rw-r--r--crates/hir/src/has_source.rs6
-rw-r--r--crates/hir/src/semantics.rs12
-rw-r--r--crates/hir/src/semantics/source_to_def.rs14
-rw-r--r--crates/hir/src/source_analyzer.rs89
-rw-r--r--crates/hir_def/src/adt.rs2
-rw-r--r--crates/hir_def/src/attr.rs13
-rw-r--r--crates/hir_def/src/body.rs36
-rw-r--r--crates/hir_def/src/body/lower.rs61
-rw-r--r--crates/hir_def/src/body/scope.rs22
-rw-r--r--crates/hir_def/src/body/tests.rs56
-rw-r--r--crates/hir_def/src/body/tests/block.rs290
-rw-r--r--crates/hir_def/src/builtin_type.rs132
-rw-r--r--crates/hir_def/src/child_by_source.rs2
-rw-r--r--crates/hir_def/src/data.rs18
-rw-r--r--crates/hir_def/src/db.rs39
-rw-r--r--crates/hir_def/src/diagnostics.rs28
-rw-r--r--crates/hir_def/src/expr.rs5
-rw-r--r--crates/hir_def/src/find_path.rs201
-rw-r--r--crates/hir_def/src/import_map.rs70
-rw-r--r--crates/hir_def/src/item_scope.rs47
-rw-r--r--crates/hir_def/src/item_tree.rs120
-rw-r--r--crates/hir_def/src/item_tree/lower.rs95
-rw-r--r--crates/hir_def/src/lang_item.rs2
-rw-r--r--crates/hir_def/src/lib.rs179
-rw-r--r--crates/hir_def/src/nameres.rs242
-rw-r--r--crates/hir_def/src/nameres/collector.rs212
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs163
-rw-r--r--crates/hir_def/src/nameres/tests.rs15
-rw-r--r--crates/hir_def/src/nameres/tests/diagnostics.rs16
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs14
-rw-r--r--crates/hir_def/src/path.rs38
-rw-r--r--crates/hir_def/src/path/lower.rs15
-rw-r--r--crates/hir_def/src/path/lower/lower_use.rs7
-rw-r--r--crates/hir_def/src/resolver.rs294
-rw-r--r--crates/hir_def/src/test_db.rs111
-rw-r--r--crates/hir_def/src/visibility.rs53
-rw-r--r--crates/hir_expand/src/ast_id_map.rs24
-rw-r--r--crates/hir_expand/src/builtin_derive.rs2
-rw-r--r--crates/hir_expand/src/builtin_macro.rs90
-rw-r--r--crates/hir_expand/src/db.rs2
-rw-r--r--crates/hir_expand/src/name.rs12
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/autoderef.rs11
-rw-r--r--crates/hir_ty/src/diagnostics.rs177
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs279
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check/case_conv.rs34
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs96
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs37
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs16
-rw-r--r--crates/hir_ty/src/display.rs237
-rw-r--r--crates/hir_ty/src/infer.rs48
-rw-r--r--crates/hir_ty/src/infer/coerce.rs87
-rw-r--r--crates/hir_ty/src/infer/expr.rs280
-rw-r--r--crates/hir_ty/src/infer/pat.rs34
-rw-r--r--crates/hir_ty/src/infer/unify.rs200
-rw-r--r--crates/hir_ty/src/lib.rs608
-rw-r--r--crates/hir_ty/src/lower.rs138
-rw-r--r--crates/hir_ty/src/method_resolution.rs186
-rw-r--r--crates/hir_ty/src/op.rs50
-rw-r--r--crates/hir_ty/src/primitive.rs160
-rw-r--r--crates/hir_ty/src/test_db.rs6
-rw-r--r--crates/hir_ty/src/tests.rs14
-rw-r--r--crates/hir_ty/src/tests/macros.rs23
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs67
-rw-r--r--crates/hir_ty/src/tests/simple.rs155
-rw-r--r--crates/hir_ty/src/tests/traits.rs60
-rw-r--r--crates/hir_ty/src/traits.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk.rs32
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs5
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs332
-rw-r--r--crates/ide/Cargo.toml6
-rw-r--r--crates/ide/src/annotations.rs937
-rw-r--r--crates/ide/src/call_hierarchy.rs8
-rw-r--r--crates/ide/src/diagnostics.rs70
-rw-r--r--crates/ide/src/diagnostics/fixes.rs35
-rw-r--r--crates/ide/src/display/navigation_target.rs53
-rw-r--r--crates/ide/src/display/short_label.rs16
-rw-r--r--crates/ide/src/doc_links.rs36
-rw-r--r--crates/ide/src/extend_selection.rs12
-rw-r--r--crates/ide/src/file_structure.rs3
-rw-r--r--crates/ide/src/fixture.rs16
-rw-r--r--crates/ide/src/fn_references.rs2
-rw-r--r--crates/ide/src/goto_definition.rs105
-rw-r--r--crates/ide/src/goto_implementation.rs10
-rw-r--r--crates/ide/src/hover.rs128
-rw-r--r--crates/ide/src/inlay_hints.rs61
-rw-r--r--crates/ide/src/join_lines.rs45
-rw-r--r--crates/ide/src/lib.rs47
-rw-r--r--crates/ide/src/parent_module.rs71
-rw-r--r--crates/ide/src/references.rs686
-rw-r--r--crates/ide/src/references/rename.rs932
-rw-r--r--crates/ide/src/runnables.rs236
-rw-r--r--crates/ide/src/status.rs2
-rw-r--r--crates/ide/src/syntax_highlighting.rs6
-rw-r--r--crates/ide/src/syntax_highlighting/format.rs5
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs4
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html4
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs55
-rw-r--r--crates/ide/src/syntax_tree.rs366
-rw-r--r--crates/ide/src/view_hir.rs2
-rw-r--r--crates/ide_assists/Cargo.toml (renamed from crates/assists/Cargo.toml)5
-rw-r--r--crates/ide_assists/src/assist_config.rs (renamed from crates/assists/src/assist_config.rs)0
-rw-r--r--crates/ide_assists/src/assist_context.rs (renamed from crates/assists/src/assist_context.rs)4
-rw-r--r--crates/ide_assists/src/ast_transform.rs (renamed from crates/assists/src/ast_transform.rs)0
-rw-r--r--crates/ide_assists/src/handlers/add_explicit_type.rs (renamed from crates/assists/src/handlers/add_explicit_type.rs)0
-rw-r--r--crates/ide_assists/src/handlers/add_lifetime_to_type.rs228
-rw-r--r--crates/ide_assists/src/handlers/add_missing_impl_members.rs (renamed from crates/assists/src/handlers/add_missing_impl_members.rs)0
-rw-r--r--crates/ide_assists/src/handlers/add_turbo_fish.rs (renamed from crates/assists/src/handlers/add_turbo_fish.rs)0
-rw-r--r--crates/ide_assists/src/handlers/apply_demorgan.rs (renamed from crates/assists/src/handlers/apply_demorgan.rs)78
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs (renamed from crates/assists/src/handlers/auto_import.rs)47
-rw-r--r--crates/ide_assists/src/handlers/change_visibility.rs (renamed from crates/assists/src/handlers/change_visibility.rs)0
-rw-r--r--crates/ide_assists/src/handlers/convert_comment_block.rs419
-rw-r--r--crates/ide_assists/src/handlers/convert_integer_literal.rs (renamed from crates/assists/src/handlers/convert_integer_literal.rs)0
-rw-r--r--crates/ide_assists/src/handlers/early_return.rs (renamed from crates/assists/src/handlers/early_return.rs)4
-rw-r--r--crates/ide_assists/src/handlers/expand_glob_import.rs (renamed from crates/assists/src/handlers/expand_glob_import.rs)0
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs3378
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs (renamed from crates/assists/src/handlers/extract_struct_from_enum_variant.rs)4
-rw-r--r--crates/ide_assists/src/handlers/extract_variable.rs (renamed from crates/assists/src/handlers/extract_variable.rs)208
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs (renamed from crates/assists/src/handlers/fill_match_arms.rs)87
-rw-r--r--crates/ide_assists/src/handlers/fix_visibility.rs (renamed from crates/assists/src/handlers/fix_visibility.rs)0
-rw-r--r--crates/ide_assists/src/handlers/flip_binexpr.rs (renamed from crates/assists/src/handlers/flip_binexpr.rs)0
-rw-r--r--crates/ide_assists/src/handlers/flip_comma.rs (renamed from crates/assists/src/handlers/flip_comma.rs)26
-rw-r--r--crates/ide_assists/src/handlers/flip_trait_bound.rs (renamed from crates/assists/src/handlers/flip_trait_bound.rs)0
-rw-r--r--crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs (renamed from crates/assists/src/handlers/generate_default_from_enum_variant.rs)0
-rw-r--r--crates/ide_assists/src/handlers/generate_derive.rs (renamed from crates/assists/src/handlers/generate_derive.rs)4
-rw-r--r--crates/ide_assists/src/handlers/generate_enum_is_method.rs250
-rw-r--r--crates/ide_assists/src/handlers/generate_enum_projection_method.rs331
-rw-r--r--crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs (renamed from crates/assists/src/handlers/generate_from_impl_for_enum.rs)131
-rw-r--r--crates/ide_assists/src/handlers/generate_function.rs (renamed from crates/assists/src/handlers/generate_function.rs)26
-rw-r--r--crates/ide_assists/src/handlers/generate_getter.rs192
-rw-r--r--crates/ide_assists/src/handlers/generate_getter_mut.rs195
-rw-r--r--crates/ide_assists/src/handlers/generate_impl.rs (renamed from crates/assists/src/handlers/generate_impl.rs)94
-rw-r--r--crates/ide_assists/src/handlers/generate_new.rs (renamed from crates/assists/src/handlers/generate_new.rs)144
-rw-r--r--crates/ide_assists/src/handlers/generate_setter.rs198
-rw-r--r--crates/ide_assists/src/handlers/infer_function_return_type.rs (renamed from crates/assists/src/handlers/infer_function_return_type.rs)0
-rw-r--r--crates/ide_assists/src/handlers/inline_function.rs (renamed from crates/assists/src/handlers/inline_function.rs)0
-rw-r--r--crates/ide_assists/src/handlers/inline_local_variable.rs (renamed from crates/assists/src/handlers/inline_local_variable.rs)108
-rw-r--r--crates/ide_assists/src/handlers/introduce_named_lifetime.rs (renamed from crates/assists/src/handlers/introduce_named_lifetime.rs)0
-rw-r--r--crates/ide_assists/src/handlers/invert_if.rs (renamed from crates/assists/src/handlers/invert_if.rs)2
-rw-r--r--crates/ide_assists/src/handlers/merge_imports.rs (renamed from crates/assists/src/handlers/merge_imports.rs)0
-rw-r--r--crates/ide_assists/src/handlers/merge_match_arms.rs (renamed from crates/assists/src/handlers/merge_match_arms.rs)0
-rw-r--r--crates/ide_assists/src/handlers/move_bounds.rs (renamed from crates/assists/src/handlers/move_bounds.rs)0
-rw-r--r--crates/ide_assists/src/handlers/move_guard.rs (renamed from crates/assists/src/handlers/move_guard.rs)0
-rw-r--r--crates/ide_assists/src/handlers/move_module_to_file.rs (renamed from crates/assists/src/handlers/move_module_to_file.rs)47
-rw-r--r--crates/ide_assists/src/handlers/pull_assignment_up.rs (renamed from crates/assists/src/handlers/pull_assignment_up.rs)0
-rw-r--r--crates/ide_assists/src/handlers/qualify_path.rs (renamed from crates/assists/src/handlers/qualify_path.rs)43
-rw-r--r--crates/ide_assists/src/handlers/raw_string.rs (renamed from crates/assists/src/handlers/raw_string.rs)2
-rw-r--r--crates/ide_assists/src/handlers/remove_dbg.rs (renamed from crates/assists/src/handlers/remove_dbg.rs)0
-rw-r--r--crates/ide_assists/src/handlers/remove_mut.rs (renamed from crates/assists/src/handlers/remove_mut.rs)0
-rw-r--r--crates/ide_assists/src/handlers/remove_unused_param.rs (renamed from crates/assists/src/handlers/remove_unused_param.rs)0
-rw-r--r--crates/ide_assists/src/handlers/reorder_fields.rs (renamed from crates/assists/src/handlers/reorder_fields.rs)0
-rw-r--r--crates/ide_assists/src/handlers/reorder_impl.rs (renamed from crates/assists/src/handlers/reorder_impl.rs)0
-rw-r--r--crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs (renamed from crates/assists/src/handlers/replace_derive_with_manual_impl.rs)43
-rw-r--r--crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs321
-rw-r--r--crates/ide_assists/src/handlers/replace_if_let_with_match.rs (renamed from crates/assists/src/handlers/replace_if_let_with_match.rs)73
-rw-r--r--crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs (renamed from crates/assists/src/handlers/replace_impl_trait_with_generic.rs)0
-rw-r--r--crates/ide_assists/src/handlers/replace_let_with_if_let.rs (renamed from crates/assists/src/handlers/replace_let_with_if_let.rs)2
-rw-r--r--crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs (renamed from crates/assists/src/handlers/replace_qualified_name_with_use.rs)0
-rw-r--r--crates/ide_assists/src/handlers/replace_string_with_char.rs (renamed from crates/assists/src/handlers/replace_string_with_char.rs)0
-rw-r--r--crates/ide_assists/src/handlers/replace_unwrap_with_match.rs (renamed from crates/assists/src/handlers/replace_unwrap_with_match.rs)0
-rw-r--r--crates/ide_assists/src/handlers/split_import.rs (renamed from crates/assists/src/handlers/split_import.rs)0
-rw-r--r--crates/ide_assists/src/handlers/toggle_ignore.rs (renamed from crates/assists/src/handlers/toggle_ignore.rs)0
-rw-r--r--crates/ide_assists/src/handlers/unmerge_use.rs (renamed from crates/assists/src/handlers/unmerge_use.rs)0
-rw-r--r--crates/ide_assists/src/handlers/unwrap_block.rs (renamed from crates/assists/src/handlers/unwrap_block.rs)0
-rw-r--r--crates/ide_assists/src/handlers/wrap_return_type_in_result.rs (renamed from crates/assists/src/handlers/wrap_return_type_in_result.rs)0
-rw-r--r--crates/ide_assists/src/lib.rs (renamed from crates/assists/src/lib.rs)29
-rw-r--r--crates/ide_assists/src/tests.rs (renamed from crates/assists/src/tests.rs)155
-rw-r--r--crates/ide_assists/src/tests/generated.rs (renamed from crates/assists/src/tests/generated.rs)232
-rw-r--r--crates/ide_assists/src/utils.rs490
-rw-r--r--crates/ide_assists/src/utils/suggest_name.rs877
-rw-r--r--crates/ide_completion/Cargo.toml (renamed from crates/completion/Cargo.toml)2
-rw-r--r--crates/ide_completion/src/completions.rs (renamed from crates/completion/src/completions.rs)60
-rw-r--r--crates/ide_completion/src/completions/attribute.rs (renamed from crates/completion/src/completions/attribute.rs)12
-rw-r--r--crates/ide_completion/src/completions/dot.rs (renamed from crates/completion/src/completions/dot.rs)50
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs778
-rw-r--r--crates/ide_completion/src/completions/fn_param.rs (renamed from crates/completion/src/completions/fn_param.rs)4
-rw-r--r--crates/ide_completion/src/completions/keyword.rs (renamed from crates/completion/src/completions/keyword.rs)8
-rw-r--r--crates/ide_completion/src/completions/macro_in_item_position.rs (renamed from crates/completion/src/completions/macro_in_item_position.rs)0
-rw-r--r--crates/ide_completion/src/completions/mod_.rs (renamed from crates/completion/src/completions/mod_.rs)10
-rw-r--r--crates/ide_completion/src/completions/pattern.rs (renamed from crates/completion/src/completions/pattern.rs)56
-rw-r--r--crates/ide_completion/src/completions/postfix.rs (renamed from crates/completion/src/completions/postfix.rs)0
-rw-r--r--crates/ide_completion/src/completions/postfix/format_like.rs (renamed from crates/completion/src/completions/postfix/format_like.rs)0
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs (renamed from crates/completion/src/completions/qualified_path.rs)88
-rw-r--r--crates/ide_completion/src/completions/record.rs (renamed from crates/completion/src/completions/record.rs)8
-rw-r--r--crates/ide_completion/src/completions/snippet.rs (renamed from crates/completion/src/completions/snippet.rs)0
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs (renamed from crates/completion/src/completions/trait_impl.rs)13
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs (renamed from crates/completion/src/completions/unqualified_path.rs)162
-rw-r--r--crates/ide_completion/src/config.rs (renamed from crates/completion/src/config.rs)2
-rw-r--r--crates/ide_completion/src/context.rs (renamed from crates/completion/src/context.rs)16
-rw-r--r--crates/ide_completion/src/generated_lint_completions.rs6380
-rw-r--r--crates/ide_completion/src/item.rs (renamed from crates/completion/src/item.rs)98
-rw-r--r--crates/ide_completion/src/lib.rs (renamed from crates/completion/src/lib.rs)104
-rw-r--r--crates/ide_completion/src/patterns.rs (renamed from crates/completion/src/patterns.rs)0
-rw-r--r--crates/ide_completion/src/render.rs (renamed from crates/completion/src/render.rs)202
-rw-r--r--crates/ide_completion/src/render/builder_ext.rs (renamed from crates/completion/src/render/builder_ext.rs)0
-rw-r--r--crates/ide_completion/src/render/const_.rs (renamed from crates/completion/src/render/const_.rs)10
-rw-r--r--crates/ide_completion/src/render/enum_variant.rs (renamed from crates/completion/src/render/enum_variant.rs)9
-rw-r--r--crates/ide_completion/src/render/function.rs (renamed from crates/completion/src/render/function.rs)14
-rw-r--r--crates/ide_completion/src/render/macro_.rs (renamed from crates/completion/src/render/macro_.rs)5
-rw-r--r--crates/ide_completion/src/render/pattern.rs (renamed from crates/completion/src/render/pattern.rs)6
-rw-r--r--crates/ide_completion/src/render/type_alias.rs (renamed from crates/completion/src/render/type_alias.rs)10
-rw-r--r--crates/ide_completion/src/test_utils.rs (renamed from crates/completion/src/test_utils.rs)5
-rw-r--r--crates/ide_db/Cargo.toml3
-rw-r--r--crates/ide_db/src/apply_change.rs5
-rw-r--r--crates/ide_db/src/defs.rs16
-rw-r--r--crates/ide_db/src/helpers.rs6
-rw-r--r--crates/ide_db/src/helpers/famous_defs_fixture.rs11
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs356
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs2
-rw-r--r--crates/ide_db/src/imports_locator.rs76
-rw-r--r--crates/ide_db/src/lib.rs24
-rw-r--r--crates/ide_db/src/line_index.rs29
-rw-r--r--crates/ide_db/src/line_index/tests.rs33
-rw-r--r--crates/ide_db/src/search.rs152
-rw-r--r--crates/ide_db/src/source_change.rs9
-rw-r--r--crates/ide_db/src/symbol_index.rs20
-rw-r--r--crates/ide_db/src/ty_filter.rs15
-rw-r--r--crates/ide_ssr/Cargo.toml (renamed from crates/ssr/Cargo.toml)2
-rw-r--r--crates/ide_ssr/src/errors.rs (renamed from crates/ssr/src/errors.rs)0
-rw-r--r--crates/ide_ssr/src/lib.rs (renamed from crates/ssr/src/lib.rs)0
-rw-r--r--crates/ide_ssr/src/matching.rs (renamed from crates/ssr/src/matching.rs)13
-rw-r--r--crates/ide_ssr/src/nester.rs (renamed from crates/ssr/src/nester.rs)0
-rw-r--r--crates/ide_ssr/src/parsing.rs (renamed from crates/ssr/src/parsing.rs)0
-rw-r--r--crates/ide_ssr/src/replacing.rs (renamed from crates/ssr/src/replacing.rs)2
-rw-r--r--crates/ide_ssr/src/resolving.rs (renamed from crates/ssr/src/resolving.rs)2
-rw-r--r--crates/ide_ssr/src/search.rs (renamed from crates/ssr/src/search.rs)0
-rw-r--r--crates/ide_ssr/src/tests.rs (renamed from crates/ssr/src/tests.rs)0
-rw-r--r--crates/mbe/Cargo.toml4
-rw-r--r--crates/mbe/src/benchmark.rs225
-rw-r--r--crates/mbe/src/expander.rs (renamed from crates/mbe/src/mbe_expander.rs)34
-rw-r--r--crates/mbe/src/expander/matcher.rs737
-rw-r--r--crates/mbe/src/expander/transcriber.rs (renamed from crates/mbe/src/mbe_expander/transcriber.rs)37
-rw-r--r--crates/mbe/src/lib.rs130
-rw-r--r--crates/mbe/src/mbe_expander/matcher.rs502
-rw-r--r--crates/mbe/src/parser.rs130
-rw-r--r--crates/mbe/src/syntax_bridge.rs73
-rw-r--r--crates/mbe/src/tests.rs296
-rw-r--r--crates/mbe/src/tt_iter.rs77
-rw-r--r--crates/parser/src/event.rs5
-rw-r--r--crates/parser/src/grammar/items.rs28
-rw-r--r--crates/parser/src/grammar/items/consts.rs2
-rw-r--r--crates/parser/src/grammar/items/traits.rs4
-rw-r--r--crates/paths/src/lib.rs51
-rw-r--r--crates/proc_macro_api/Cargo.toml1
-rw-r--r--crates/proc_macro_api/src/process.rs11
-rw-r--r--crates/proc_macro_api/src/rpc.rs2
-rw-r--r--crates/proc_macro_srv/Cargo.toml6
-rw-r--r--crates/proc_macro_srv/src/dylib.rs6
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs46
-rw-r--r--crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt8
-rw-r--r--crates/proc_macro_srv/src/tests/utils.rs3
-rw-r--r--crates/profile/Cargo.toml3
-rw-r--r--crates/profile/src/hprof.rs4
-rw-r--r--crates/profile/src/lib.rs7
-rw-r--r--crates/profile/src/memory_usage.rs7
-rw-r--r--crates/project_model/Cargo.toml10
-rw-r--r--crates/project_model/src/build_data.rs254
-rw-r--r--crates/project_model/src/cargo_workspace.rs249
-rw-r--r--crates/project_model/src/lib.rs6
-rw-r--r--crates/project_model/src/sysroot.rs40
-rw-r--r--crates/project_model/src/workspace.rs79
-rw-r--r--crates/rust-analyzer/Cargo.toml14
-rw-r--r--crates/rust-analyzer/src/bin/args.rs228
-rw-r--r--crates/rust-analyzer/src/bin/flags.rs251
-rw-r--r--crates/rust-analyzer/src/bin/logger.rs39
-rw-r--r--crates/rust-analyzer/src/bin/main.rs109
-rw-r--r--crates/rust-analyzer/src/caps.rs3
-rw-r--r--crates/rust-analyzer/src/cli.rs2
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs19
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs27
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs16
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs86
-rw-r--r--crates/rust-analyzer/src/cli/ssr.rs19
-rw-r--r--crates/rust-analyzer/src/config.rs112
-rw-r--r--crates/rust-analyzer/src/diagnostics.rs11
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt69
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt4
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt6
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt4
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt4
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt10
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt10
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt10
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt12
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt22
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs8
-rw-r--r--crates/rust-analyzer/src/from_proto.rs64
-rw-r--r--crates/rust-analyzer/src/global_state.rs25
-rw-r--r--crates/rust-analyzer/src/handlers.rs429
-rw-r--r--crates/rust-analyzer/src/lib.rs2
-rw-r--r--crates/rust-analyzer/src/line_index.rs (renamed from crates/rust-analyzer/src/line_endings.rs)18
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs15
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs19
-rw-r--r--crates/rust-analyzer/src/main_loop.rs52
-rw-r--r--crates/rust-analyzer/src/op_queue.rs28
-rw-r--r--crates/rust-analyzer/src/reload.rs153
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs1
-rw-r--r--crates/rust-analyzer/src/to_proto.rs330
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/main.rs18
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/support.rs80
-rw-r--r--crates/stdx/Cargo.toml1
-rw-r--r--crates/stdx/src/lib.rs5
-rw-r--r--crates/stdx/src/macros.rs51
-rw-r--r--crates/syntax/Cargo.toml7
-rw-r--r--crates/syntax/fuzz/Cargo.toml4
-rw-r--r--crates/syntax/src/algo.rs7
-rw-r--r--crates/syntax/src/ast.rs6
-rw-r--r--crates/syntax/src/ast/edit.rs11
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs38
-rw-r--r--crates/syntax/src/ast/make.rs74
-rw-r--r--crates/syntax/src/ast/node_ext.rs106
-rw-r--r--crates/syntax/src/ast/token_ext.rs36
-rw-r--r--crates/syntax/src/lib.rs4
-rw-r--r--crates/syntax/src/parsing/reparsing.rs3
-rw-r--r--crates/syntax/src/parsing/text_tree_sink.rs4
-rw-r--r--crates/syntax/src/syntax_node.rs4
-rw-r--r--crates/syntax/src/tests.rs28
-rw-r--r--crates/syntax/src/validation.rs18
-rw-r--r--crates/syntax/test_data/accidentally_quadratic3980
-rw-r--r--crates/syntax/test_data/parser/err/0047_mutable_const_item.rast22
-rw-r--r--crates/syntax/test_data/parser/err/0047_mutable_const_item.rs1
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0161_impl_def_const.rast24
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0161_impl_def_const.rs1
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0162_default_async_unsafe_fn.rast42
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0162_default_async_unsafe_fn.rs3
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0163_default_async_fn.rast40
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0163_default_async_fn.rs3
-rw-r--r--crates/syntax/test_data/parser/ok/0024_const_item.rast23
-rw-r--r--crates/syntax/test_data/parser/ok/0024_const_item.rs1
-rw-r--r--crates/test_utils/Cargo.toml1
-rw-r--r--crates/test_utils/src/bench_fixture.rs42
-rw-r--r--crates/test_utils/src/fixture.rs11
-rw-r--r--crates/test_utils/src/lib.rs43
-rw-r--r--crates/vfs-notify/src/lib.rs10
-rw-r--r--crates/vfs/src/loader.rs8
-rw-r--r--docs/dev/README.md117
-rw-r--r--docs/dev/architecture.md503
-rw-r--r--docs/dev/debugging.md10
-rw-r--r--docs/dev/guide.md10
-rw-r--r--docs/dev/lsp-extensions.md12
-rw-r--r--docs/dev/style.md154
-rw-r--r--docs/dev/syntax.md29
-rw-r--r--docs/user/generated_config.adoc14
-rw-r--r--docs/user/manual.adoc125
-rw-r--r--editors/code/.eslintrc.js5
-rw-r--r--editors/code/README.md70
-rw-r--r--editors/code/package-lock.json5030
-rw-r--r--editors/code/package.json86
-rw-r--r--editors/code/src/client.ts23
-rw-r--r--editors/code/src/commands.ts32
-rw-r--r--editors/code/src/config.ts1
-rw-r--r--editors/code/src/ctx.ts6
-rw-r--r--editors/code/src/debug.ts12
-rw-r--r--editors/code/src/inlay_hints.ts2
-rw-r--r--editors/code/src/lsp_ext.ts2
-rw-r--r--editors/code/src/main.ts36
-rw-r--r--editors/code/src/net.ts25
-rw-r--r--editors/code/src/run.ts26
-rw-r--r--editors/code/src/snippets.ts4
-rw-r--r--xtask/Cargo.toml7
-rw-r--r--xtask/src/codegen.rs14
-rw-r--r--xtask/src/codegen/gen_assists_docs.rs10
-rw-r--r--xtask/src/codegen/gen_diagnostic_docs.rs4
-rw-r--r--xtask/src/codegen/gen_feature_docs.rs4
-rw-r--r--xtask/src/codegen/gen_features.rs48
-rw-r--r--xtask/src/codegen/gen_lint_completions.rs71
-rw-r--r--xtask/src/codegen/gen_parser_tests.rs2
-rw-r--r--xtask/src/codegen/gen_syntax.rs2
-rw-r--r--xtask/src/dist.rs10
-rw-r--r--xtask/src/flags.rs139
-rw-r--r--xtask/src/install.rs28
-rw-r--r--xtask/src/lib.rs118
-rw-r--r--xtask/src/main.rs282
-rw-r--r--xtask/src/metrics.rs10
-rw-r--r--xtask/src/pre_cache.rs6
-rw-r--r--xtask/src/pre_commit.rs38
-rw-r--r--xtask/src/release.rs75
-rw-r--r--xtask/src/tidy.rs (renamed from xtask/tests/tidy.rs)66
400 files changed, 42414 insertions, 13375 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index dddc82f80..b5160eaa3 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -13,12 +13,9 @@ Forum for questions: https://users.rust-lang.org/c/ide/14
13 13
14Before submitting, please make sure that you're not running into one of these known issues: 14Before submitting, please make sure that you're not running into one of these known issues:
15 15
16 1. local imports (`use` statements) don't work: #1165 16 1. on-the-fly diagnostics are mostly unimplemented (`cargo check` diagnostics will be shown when saving a file)
17 2. local items don't work: #1559 17 2. some settings are required for procedural macro and build script support (`rust-analyzer.cargo.loadOutDirsFromCheck`, `rust-analyzer.procMacro.enable`): #6448
18 3. on-the-fly diagnostics are mostly unimplemented (`cargo check` diagnostics will be shown when saving a file) 18 3. some platform-specific imports are not resolved: #6038
19 4. some settings are required for procedural macro and build script support (`rust-analyzer.cargo.loadOutDirsFromCheck`, `rust-analyzer.procMacro.enable`): #6448
20 5. some platform-specific imports are not resolved: #6038
21 6. the official `rust-lang.rust` VS Code extension conflicts with `rust-analyzer`: #6463
22 19
23Otherwise please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3. 20Otherwise please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3.
24--> 21-->
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index a97ed24ba..32c7cf7ef 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -94,6 +94,7 @@ jobs:
94 toolchain: stable 94 toolchain: stable
95 profile: minimal 95 profile: minimal
96 override: true 96 override: true
97 components: rust-src
97 98
98 - name: Install Nodejs 99 - name: Install Nodejs
99 uses: actions/setup-node@v1 100 uses: actions/setup-node@v1
@@ -108,16 +109,46 @@ jobs:
108 if: github.ref != 'refs/heads/release' 109 if: github.ref != 'refs/heads/release'
109 run: cargo xtask dist --nightly --client 0.3.$GITHUB_RUN_NUMBER-nightly 110 run: cargo xtask dist --nightly --client 0.3.$GITHUB_RUN_NUMBER-nightly
110 111
111 - name: Nightly analysis-stats check 112 - name: Run analysis-stats on rust-analyzer
112 if: github.ref != 'refs/heads/release'
113 run: target/${{ env.RA_TARGET }}/release/rust-analyzer analysis-stats . 113 run: target/${{ env.RA_TARGET }}/release/rust-analyzer analysis-stats .
114 114
115 - name: Run analysis-stats on rust std library
116 run: target/${{ env.RA_TARGET }}/release/rust-analyzer analysis-stats --with-deps $(rustc --print sysroot)/lib/rustlib/src/rust/library/std
117
115 - name: Upload artifacts 118 - name: Upload artifacts
116 uses: actions/upload-artifact@v1 119 uses: actions/upload-artifact@v1
117 with: 120 with:
118 name: dist-x86_64-unknown-linux-gnu 121 name: dist-x86_64-unknown-linux-gnu
119 path: ./dist 122 path: ./dist
120 123
124 dist-x86_64-unknown-linux-musl:
125 name: dist (x86_64-unknown-linux-musl)
126 runs-on: ubuntu-20.04
127 env:
128 RA_TARGET: x86_64-unknown-linux-musl
129 # For some reason `-crt-static` is not working for clang without lld
130 RUSTFLAGS: "-C link-arg=-fuse-ld=lld -C target-feature=-crt-static"
131 container:
132 image: rust:alpine
133 volumes:
134 - /usr/local/cargo/registry
135
136 steps:
137 - name: Install dependencies
138 run: apk add --no-cache git clang lld musl-dev
139
140 - name: Checkout repository
141 uses: actions/checkout@v2
142
143 - name: Dist
144 run: cargo xtask dist
145
146 - name: Upload artifacts
147 uses: actions/upload-artifact@v1
148 with:
149 name: dist-x86_64-unknown-linux-musl
150 path: ./dist
151
121 dist-aarch64-unknown-linux-gnu: 152 dist-aarch64-unknown-linux-gnu:
122 name: dist (aarch64-unknown-linux-gnu) 153 name: dist (aarch64-unknown-linux-gnu)
123 runs-on: ubuntu-16.04 154 runs-on: ubuntu-16.04
@@ -154,8 +185,12 @@ jobs:
154 runs-on: macos-latest 185 runs-on: macos-latest
155 env: 186 env:
156 RA_TARGET: x86_64-apple-darwin 187 RA_TARGET: x86_64-apple-darwin
188 SELECT_XCODE: /Applications/Xcode_12.2.app
157 189
158 steps: 190 steps:
191 - name: Select XCode version
192 run: sudo xcode-select -s "${SELECT_XCODE}"
193
159 - name: Checkout repository 194 - name: Checkout repository
160 uses: actions/checkout@v2 195 uses: actions/checkout@v2
161 196
@@ -180,8 +215,12 @@ jobs:
180 runs-on: macos-latest 215 runs-on: macos-latest
181 env: 216 env:
182 RA_TARGET: aarch64-apple-darwin 217 RA_TARGET: aarch64-apple-darwin
218 SELECT_XCODE: /Applications/Xcode_12.2.app
183 219
184 steps: 220 steps:
221 - name: Select XCode version
222 run: sudo xcode-select -s "${SELECT_XCODE}"
223
185 - name: Checkout repository 224 - name: Checkout repository
186 uses: actions/checkout@v2 225 uses: actions/checkout@v2
187 226
@@ -205,7 +244,7 @@ jobs:
205 publish: 244 publish:
206 name: publish 245 name: publish
207 runs-on: ubuntu-16.04 246 runs-on: ubuntu-16.04
208 needs: ['dist-x86_64-pc-windows-msvc', 'dist-aarch64-pc-windows-msvc', 'dist-x86_64-unknown-linux-gnu', 'dist-aarch64-unknown-linux-gnu', 'dist-x86_64-apple-darwin', 'dist-aarch64-apple-darwin'] 247 needs: ['dist-x86_64-pc-windows-msvc', 'dist-aarch64-pc-windows-msvc', 'dist-x86_64-unknown-linux-gnu', 'dist-x86_64-unknown-linux-musl', 'dist-aarch64-unknown-linux-gnu', 'dist-x86_64-apple-darwin', 'dist-aarch64-apple-darwin']
209 steps: 248 steps:
210 - name: Install Nodejs 249 - name: Install Nodejs
211 uses: actions/setup-node@v1 250 uses: actions/setup-node@v1
@@ -238,6 +277,10 @@ jobs:
238 path: dist 277 path: dist
239 - uses: actions/download-artifact@v1 278 - uses: actions/download-artifact@v1
240 with: 279 with:
280 name: dist-x86_64-unknown-linux-musl
281 path: dist
282 - uses: actions/download-artifact@v1
283 with:
241 name: dist-aarch64-unknown-linux-gnu 284 name: dist-aarch64-unknown-linux-gnu
242 path: dist 285 path: dist
243 - uses: actions/download-artifact@v1 286 - uses: actions/download-artifact@v1
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 8ca27d878..021b8f048 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -120,6 +120,12 @@
120 "sourceMaps": true, 120 "sourceMaps": true,
121 "outFiles": [ "${workspaceFolder}/editors/code/out/tests/unit/**/*.js" ], 121 "outFiles": [ "${workspaceFolder}/editors/code/out/tests/unit/**/*.js" ],
122 "preLaunchTask": "Pretest" 122 "preLaunchTask": "Pretest"
123 },
124 {
125 "name": "Win Attach to Server",
126 "type": "cppvsdbg",
127 "processId":"${command:pickProcess}",
128 "request": "attach"
123 } 129 }
124 ] 130 ]
125} 131}
diff --git a/Cargo.lock b/Cargo.lock
index d6af5e563..ec5aecfa0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,5 +1,7 @@
1# This file is automatically @generated by Cargo. 1# This file is automatically @generated by Cargo.
2# It is not intended for manual editing. 2# It is not intended for manual editing.
3version = 3
4
3[[package]] 5[[package]]
4name = "addr2line" 6name = "addr2line"
5version = "0.14.1" 7version = "0.14.1"
@@ -11,9 +13,18 @@ dependencies = [
11 13
12[[package]] 14[[package]]
13name = "adler" 15name = "adler"
14version = "0.2.3" 16version = "1.0.2"
17source = "registry+https://github.com/rust-lang/crates.io-index"
18checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
19
20[[package]]
21name = "always-assert"
22version = "0.1.2"
15source = "registry+https://github.com/rust-lang/crates.io-index" 23source = "registry+https://github.com/rust-lang/crates.io-index"
16checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" 24checksum = "fbf688625d06217d5b1bb0ea9d9c44a1635fd0ee3534466388d18203174f4d11"
25dependencies = [
26 "log",
27]
17 28
18[[package]] 29[[package]]
19name = "ansi_term" 30name = "ansi_term"
@@ -21,14 +32,14 @@ version = "0.12.1"
21source = "registry+https://github.com/rust-lang/crates.io-index" 32source = "registry+https://github.com/rust-lang/crates.io-index"
22checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 33checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
23dependencies = [ 34dependencies = [
24 "winapi 0.3.9", 35 "winapi",
25] 36]
26 37
27[[package]] 38[[package]]
28name = "anyhow" 39name = "anyhow"
29version = "1.0.37" 40version = "1.0.38"
30source = "registry+https://github.com/rust-lang/crates.io-index" 41source = "registry+https://github.com/rust-lang/crates.io-index"
31checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" 42checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
32 43
33[[package]] 44[[package]]
34name = "anymap" 45name = "anymap"
@@ -43,22 +54,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
43checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 54checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
44 55
45[[package]] 56[[package]]
46name = "assists"
47version = "0.0.0"
48dependencies = [
49 "either",
50 "hir",
51 "ide_db",
52 "itertools 0.10.0",
53 "profile",
54 "rustc-hash",
55 "stdx",
56 "syntax",
57 "test_utils",
58 "text_edit",
59]
60
61[[package]]
62name = "atty" 57name = "atty"
63version = "0.2.14" 58version = "0.2.14"
64source = "registry+https://github.com/rust-lang/crates.io-index" 59source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -66,7 +61,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
66dependencies = [ 61dependencies = [
67 "hermit-abi", 62 "hermit-abi",
68 "libc", 63 "libc",
69 "winapi 0.3.9", 64 "winapi",
70] 65]
71 66
72[[package]] 67[[package]]
@@ -77,25 +72,19 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
77 72
78[[package]] 73[[package]]
79name = "backtrace" 74name = "backtrace"
80version = "0.3.55" 75version = "0.3.56"
81source = "registry+https://github.com/rust-lang/crates.io-index" 76source = "registry+https://github.com/rust-lang/crates.io-index"
82checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" 77checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc"
83dependencies = [ 78dependencies = [
84 "addr2line", 79 "addr2line",
85 "cfg-if 1.0.0", 80 "cfg-if",
86 "libc", 81 "libc",
87 "miniz_oxide", 82 "miniz_oxide",
88 "object 0.22.0", 83 "object",
89 "rustc-demangle", 84 "rustc-demangle",
90] 85]
91 86
92[[package]] 87[[package]]
93name = "base64"
94version = "0.12.3"
95source = "registry+https://github.com/rust-lang/crates.io-index"
96checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
97
98[[package]]
99name = "base_db" 88name = "base_db"
100version = "0.0.0" 89version = "0.0.0"
101dependencies = [ 90dependencies = [
@@ -118,9 +107,18 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
118 107
119[[package]] 108[[package]]
120name = "byteorder" 109name = "byteorder"
121version = "1.3.4" 110version = "1.4.2"
111source = "registry+https://github.com/rust-lang/crates.io-index"
112checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
113
114[[package]]
115name = "camino"
116version = "1.0.1"
122source = "registry+https://github.com/rust-lang/crates.io-index" 117source = "registry+https://github.com/rust-lang/crates.io-index"
123checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 118checksum = "9bb47ab72bdba43021afa16dc1ef4d80c980d366b17ed37ea8d2ebe2087075b9"
119dependencies = [
120 "serde",
121]
124 122
125[[package]] 123[[package]]
126name = "cargo-platform" 124name = "cargo-platform"
@@ -133,10 +131,11 @@ dependencies = [
133 131
134[[package]] 132[[package]]
135name = "cargo_metadata" 133name = "cargo_metadata"
136version = "0.12.2" 134version = "0.13.1"
137source = "registry+https://github.com/rust-lang/crates.io-index" 135source = "registry+https://github.com/rust-lang/crates.io-index"
138checksum = "11a47b6286279a9998588ef7050d1ebc2500c69892a557c90fe5d071c64415dc" 136checksum = "081e3f0755c1f380c2d010481b6fa2e02973586d5f2b24eebb7a2a1d98b143d8"
139dependencies = [ 137dependencies = [
138 "camino",
140 "cargo-platform", 139 "cargo-platform",
141 "semver", 140 "semver",
142 "semver-parser", 141 "semver-parser",
@@ -146,9 +145,9 @@ dependencies = [
146 145
147[[package]] 146[[package]]
148name = "cc" 147name = "cc"
149version = "1.0.66" 148version = "1.0.67"
150source = "registry+https://github.com/rust-lang/crates.io-index" 149source = "registry+https://github.com/rust-lang/crates.io-index"
151checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" 150checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
152 151
153[[package]] 152[[package]]
154name = "cfg" 153name = "cfg"
@@ -163,21 +162,15 @@ dependencies = [
163 162
164[[package]] 163[[package]]
165name = "cfg-if" 164name = "cfg-if"
166version = "0.1.10"
167source = "registry+https://github.com/rust-lang/crates.io-index"
168checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
169
170[[package]]
171name = "cfg-if"
172version = "1.0.0" 165version = "1.0.0"
173source = "registry+https://github.com/rust-lang/crates.io-index" 166source = "registry+https://github.com/rust-lang/crates.io-index"
174checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 167checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
175 168
176[[package]] 169[[package]]
177name = "chalk-derive" 170name = "chalk-derive"
178version = "0.47.0" 171version = "0.59.0"
179source = "registry+https://github.com/rust-lang/crates.io-index" 172source = "registry+https://github.com/rust-lang/crates.io-index"
180checksum = "3f00f6342a387edc822002d36a381e117afcac9f744951ff75fbf4a218edea5c" 173checksum = "4b9000fbcb67353dc8973ab9fd136277d321d85b79bd36b8756bb3ae0979a94a"
181dependencies = [ 174dependencies = [
182 "proc-macro2", 175 "proc-macro2",
183 "quote", 176 "quote",
@@ -187,9 +180,9 @@ dependencies = [
187 180
188[[package]] 181[[package]]
189name = "chalk-ir" 182name = "chalk-ir"
190version = "0.47.0" 183version = "0.59.0"
191source = "registry+https://github.com/rust-lang/crates.io-index" 184source = "registry+https://github.com/rust-lang/crates.io-index"
192checksum = "c686e69913591ae753e5526e73cbee39db3d9b0a92cc9078ab780cabf1c70aa9" 185checksum = "b23528d61b3557c676eccf508fa0771a38453b379f0b780154eaa7f70afe8dfc"
193dependencies = [ 186dependencies = [
194 "bitflags", 187 "bitflags",
195 "chalk-derive", 188 "chalk-derive",
@@ -198,9 +191,9 @@ dependencies = [
198 191
199[[package]] 192[[package]]
200name = "chalk-recursive" 193name = "chalk-recursive"
201version = "0.47.0" 194version = "0.59.0"
202source = "registry+https://github.com/rust-lang/crates.io-index" 195source = "registry+https://github.com/rust-lang/crates.io-index"
203checksum = "310fdcac0340dab4163b766baa8067266e3b909108d1ac1b5246c033bde63975" 196checksum = "a8bdd37afc666b771de8b4429fe014363d0e74aae5cc26f320f60a3eab34d744"
204dependencies = [ 197dependencies = [
205 "chalk-derive", 198 "chalk-derive",
206 "chalk-ir", 199 "chalk-ir",
@@ -211,14 +204,14 @@ dependencies = [
211 204
212[[package]] 205[[package]]
213name = "chalk-solve" 206name = "chalk-solve"
214version = "0.47.0" 207version = "0.59.0"
215source = "registry+https://github.com/rust-lang/crates.io-index" 208source = "registry+https://github.com/rust-lang/crates.io-index"
216checksum = "c3c3252116111c3548f1164ab8d98c67c49848b3bde10dd11b650fd023e91c72" 209checksum = "4182c42ca319cb71c89898ebc3d2671d1fa7d928123b171b66f1797a2000b9c8"
217dependencies = [ 210dependencies = [
218 "chalk-derive", 211 "chalk-derive",
219 "chalk-ir", 212 "chalk-ir",
220 "ena", 213 "ena",
221 "itertools 0.9.0", 214 "itertools",
222 "petgraph", 215 "petgraph",
223 "rustc-hash", 216 "rustc-hash",
224 "tracing", 217 "tracing",
@@ -235,8 +228,7 @@ dependencies = [
235 "libc", 228 "libc",
236 "num-integer", 229 "num-integer",
237 "num-traits", 230 "num-traits",
238 "time", 231 "winapi",
239 "winapi 0.3.9",
240] 232]
241 233
242[[package]] 234[[package]]
@@ -249,47 +241,23 @@ dependencies = [
249] 241]
250 242
251[[package]] 243[[package]]
252name = "completion" 244name = "countme"
253version = "0.0.0" 245version = "2.0.4"
246source = "registry+https://github.com/rust-lang/crates.io-index"
247checksum = "328b822bdcba4d4e402be8d9adb6eebf269f969f8eadef977a553ff3c4fbcb58"
254dependencies = [ 248dependencies = [
255 "base_db", 249 "dashmap",
256 "either", 250 "once_cell",
257 "expect-test",
258 "hir",
259 "ide_db",
260 "itertools 0.10.0",
261 "log",
262 "profile",
263 "rustc-hash", 251 "rustc-hash",
264 "stdx",
265 "syntax",
266 "test_utils",
267 "text_edit",
268] 252]
269 253
270[[package]] 254[[package]]
271name = "const_fn"
272version = "0.4.4"
273source = "registry+https://github.com/rust-lang/crates.io-index"
274checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
275
276[[package]]
277name = "crc32fast" 255name = "crc32fast"
278version = "1.2.1" 256version = "1.2.1"
279source = "registry+https://github.com/rust-lang/crates.io-index" 257source = "registry+https://github.com/rust-lang/crates.io-index"
280checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" 258checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
281dependencies = [ 259dependencies = [
282 "cfg-if 1.0.0", 260 "cfg-if",
283]
284
285[[package]]
286name = "crossbeam-channel"
287version = "0.4.4"
288source = "registry+https://github.com/rust-lang/crates.io-index"
289checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
290dependencies = [
291 "crossbeam-utils 0.7.2",
292 "maybe-uninit",
293] 261]
294 262
295[[package]] 263[[package]]
@@ -298,8 +266,8 @@ version = "0.5.0"
298source = "registry+https://github.com/rust-lang/crates.io-index" 266source = "registry+https://github.com/rust-lang/crates.io-index"
299checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" 267checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
300dependencies = [ 268dependencies = [
301 "cfg-if 1.0.0", 269 "cfg-if",
302 "crossbeam-utils 0.8.1", 270 "crossbeam-utils",
303] 271]
304 272
305[[package]] 273[[package]]
@@ -308,45 +276,43 @@ version = "0.8.0"
308source = "registry+https://github.com/rust-lang/crates.io-index" 276source = "registry+https://github.com/rust-lang/crates.io-index"
309checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" 277checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
310dependencies = [ 278dependencies = [
311 "cfg-if 1.0.0", 279 "cfg-if",
312 "crossbeam-epoch", 280 "crossbeam-epoch",
313 "crossbeam-utils 0.8.1", 281 "crossbeam-utils",
314] 282]
315 283
316[[package]] 284[[package]]
317name = "crossbeam-epoch" 285name = "crossbeam-epoch"
318version = "0.9.1" 286version = "0.9.3"
319source = "registry+https://github.com/rust-lang/crates.io-index" 287source = "registry+https://github.com/rust-lang/crates.io-index"
320checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" 288checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
321dependencies = [ 289dependencies = [
322 "cfg-if 1.0.0", 290 "cfg-if",
323 "const_fn", 291 "crossbeam-utils",
324 "crossbeam-utils 0.8.1",
325 "lazy_static", 292 "lazy_static",
326 "memoffset 0.6.1", 293 "memoffset",
327 "scopeguard", 294 "scopeguard",
328] 295]
329 296
330[[package]] 297[[package]]
331name = "crossbeam-utils" 298name = "crossbeam-utils"
332version = "0.7.2" 299version = "0.8.3"
333source = "registry+https://github.com/rust-lang/crates.io-index" 300source = "registry+https://github.com/rust-lang/crates.io-index"
334checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 301checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
335dependencies = [ 302dependencies = [
336 "autocfg", 303 "autocfg",
337 "cfg-if 0.1.10", 304 "cfg-if",
338 "lazy_static", 305 "lazy_static",
339] 306]
340 307
341[[package]] 308[[package]]
342name = "crossbeam-utils" 309name = "dashmap"
343version = "0.8.1" 310version = "4.0.2"
344source = "registry+https://github.com/rust-lang/crates.io-index" 311source = "registry+https://github.com/rust-lang/crates.io-index"
345checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" 312checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
346dependencies = [ 313dependencies = [
347 "autocfg", 314 "cfg-if",
348 "cfg-if 1.0.0", 315 "num_cpus",
349 "lazy_static",
350] 316]
351 317
352[[package]] 318[[package]]
@@ -378,9 +344,9 @@ dependencies = [
378 344
379[[package]] 345[[package]]
380name = "env_logger" 346name = "env_logger"
381version = "0.8.2" 347version = "0.8.3"
382source = "registry+https://github.com/rust-lang/crates.io-index" 348source = "registry+https://github.com/rust-lang/crates.io-index"
383checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" 349checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
384dependencies = [ 350dependencies = [
385 "log", 351 "log",
386] 352]
@@ -397,14 +363,14 @@ dependencies = [
397 363
398[[package]] 364[[package]]
399name = "filetime" 365name = "filetime"
400version = "0.2.13" 366version = "0.2.14"
401source = "registry+https://github.com/rust-lang/crates.io-index" 367source = "registry+https://github.com/rust-lang/crates.io-index"
402checksum = "0c122a393ea57648015bf06fbd3d372378992e86b9ff5a7a497b076a28c79efe" 368checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
403dependencies = [ 369dependencies = [
404 "cfg-if 1.0.0", 370 "cfg-if",
405 "libc", 371 "libc",
406 "redox_syscall", 372 "redox_syscall",
407 "winapi 0.3.9", 373 "winapi",
408] 374]
409 375
410[[package]] 376[[package]]
@@ -415,11 +381,11 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
415 381
416[[package]] 382[[package]]
417name = "flate2" 383name = "flate2"
418version = "1.0.19" 384version = "1.0.20"
419source = "registry+https://github.com/rust-lang/crates.io-index" 385source = "registry+https://github.com/rust-lang/crates.io-index"
420checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" 386checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
421dependencies = [ 387dependencies = [
422 "cfg-if 1.0.0", 388 "cfg-if",
423 "crc32fast", 389 "crc32fast",
424 "libc", 390 "libc",
425 "miniz_oxide", 391 "miniz_oxide",
@@ -430,7 +396,7 @@ name = "flycheck"
430version = "0.0.0" 396version = "0.0.0"
431dependencies = [ 397dependencies = [
432 "cargo_metadata", 398 "cargo_metadata",
433 "crossbeam-channel 0.5.0", 399 "crossbeam-channel",
434 "jod-thread", 400 "jod-thread",
435 "log", 401 "log",
436 "serde_json", 402 "serde_json",
@@ -440,15 +406,21 @@ dependencies = [
440 406
441[[package]] 407[[package]]
442name = "form_urlencoded" 408name = "form_urlencoded"
443version = "1.0.0" 409version = "1.0.1"
444source = "registry+https://github.com/rust-lang/crates.io-index" 410source = "registry+https://github.com/rust-lang/crates.io-index"
445checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" 411checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
446dependencies = [ 412dependencies = [
447 "matches", 413 "matches",
448 "percent-encoding", 414 "percent-encoding",
449] 415]
450 416
451[[package]] 417[[package]]
418name = "fs_extra"
419version = "1.2.0"
420source = "registry+https://github.com/rust-lang/crates.io-index"
421checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
422
423[[package]]
452name = "fsevent" 424name = "fsevent"
453version = "2.0.2" 425version = "2.0.2"
454source = "registry+https://github.com/rust-lang/crates.io-index" 426source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -474,22 +446,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
474checksum = "d79238883cf0307100b90aba4a755d8051a3182305dfe7f649a1e9dc0517006f" 446checksum = "d79238883cf0307100b90aba4a755d8051a3182305dfe7f649a1e9dc0517006f"
475 447
476[[package]] 448[[package]]
477name = "fuchsia-zircon"
478version = "0.3.3"
479source = "registry+https://github.com/rust-lang/crates.io-index"
480checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
481dependencies = [
482 "bitflags",
483 "fuchsia-zircon-sys",
484]
485
486[[package]]
487name = "fuchsia-zircon-sys"
488version = "0.3.3"
489source = "registry+https://github.com/rust-lang/crates.io-index"
490checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
491
492[[package]]
493name = "gimli" 449name = "gimli"
494version = "0.23.0" 450version = "0.23.0"
495source = "registry+https://github.com/rust-lang/crates.io-index" 451source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -502,12 +458,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
502checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" 458checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
503 459
504[[package]] 460[[package]]
505name = "hashbrown"
506version = "0.10.0"
507source = "registry+https://github.com/rust-lang/crates.io-index"
508checksum = "2140e9c963869f01789fa4fef4805211081ec794af5fc77c0d5b377906118853"
509
510[[package]]
511name = "heck" 461name = "heck"
512version = "0.3.2" 462version = "0.3.2"
513source = "registry+https://github.com/rust-lang/crates.io-index" 463source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -518,9 +468,9 @@ dependencies = [
518 468
519[[package]] 469[[package]]
520name = "hermit-abi" 470name = "hermit-abi"
521version = "0.1.17" 471version = "0.1.18"
522source = "registry+https://github.com/rust-lang/crates.io-index" 472source = "registry+https://github.com/rust-lang/crates.io-index"
523checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" 473checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
524dependencies = [ 474dependencies = [
525 "libc", 475 "libc",
526] 476]
@@ -535,7 +485,7 @@ dependencies = [
535 "hir_def", 485 "hir_def",
536 "hir_expand", 486 "hir_expand",
537 "hir_ty", 487 "hir_ty",
538 "itertools 0.10.0", 488 "itertools",
539 "log", 489 "log",
540 "profile", 490 "profile",
541 "rustc-hash", 491 "rustc-hash",
@@ -557,7 +507,7 @@ dependencies = [
557 "fst", 507 "fst",
558 "hir_expand", 508 "hir_expand",
559 "indexmap", 509 "indexmap",
560 "itertools 0.10.0", 510 "itertools",
561 "la-arena", 511 "la-arena",
562 "log", 512 "log",
563 "mbe", 513 "mbe",
@@ -601,7 +551,7 @@ dependencies = [
601 "expect-test", 551 "expect-test",
602 "hir_def", 552 "hir_def",
603 "hir_expand", 553 "hir_expand",
604 "itertools 0.10.0", 554 "itertools",
605 "la-arena", 555 "la-arena",
606 "log", 556 "log",
607 "once_cell", 557 "once_cell",
@@ -623,29 +573,29 @@ version = "0.5.3"
623source = "registry+https://github.com/rust-lang/crates.io-index" 573source = "registry+https://github.com/rust-lang/crates.io-index"
624checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" 574checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
625dependencies = [ 575dependencies = [
626 "winapi 0.3.9", 576 "winapi",
627] 577]
628 578
629[[package]] 579[[package]]
630name = "ide" 580name = "ide"
631version = "0.0.0" 581version = "0.0.0"
632dependencies = [ 582dependencies = [
633 "assists",
634 "cfg", 583 "cfg",
635 "completion",
636 "either", 584 "either",
637 "expect-test", 585 "expect-test",
638 "hir", 586 "hir",
587 "ide_assists",
588 "ide_completion",
639 "ide_db", 589 "ide_db",
590 "ide_ssr",
640 "indexmap", 591 "indexmap",
641 "itertools 0.10.0", 592 "itertools",
642 "log", 593 "log",
643 "oorandom", 594 "oorandom",
644 "profile", 595 "profile",
645 "pulldown-cmark", 596 "pulldown-cmark",
646 "pulldown-cmark-to-cmark", 597 "pulldown-cmark-to-cmark",
647 "rustc-hash", 598 "rustc-hash",
648 "ssr",
649 "stdx", 599 "stdx",
650 "syntax", 600 "syntax",
651 "test_utils", 601 "test_utils",
@@ -654,6 +604,42 @@ dependencies = [
654] 604]
655 605
656[[package]] 606[[package]]
607name = "ide_assists"
608version = "0.0.0"
609dependencies = [
610 "either",
611 "expect-test",
612 "hir",
613 "ide_db",
614 "itertools",
615 "profile",
616 "rustc-hash",
617 "stdx",
618 "syntax",
619 "test_utils",
620 "text_edit",
621]
622
623[[package]]
624name = "ide_completion"
625version = "0.0.0"
626dependencies = [
627 "base_db",
628 "either",
629 "expect-test",
630 "hir",
631 "ide_db",
632 "itertools",
633 "log",
634 "profile",
635 "rustc-hash",
636 "stdx",
637 "syntax",
638 "test_utils",
639 "text_edit",
640]
641
642[[package]]
657name = "ide_db" 643name = "ide_db"
658version = "0.0.0" 644version = "0.0.0"
659dependencies = [ 645dependencies = [
@@ -662,7 +648,7 @@ dependencies = [
662 "expect-test", 648 "expect-test",
663 "fst", 649 "fst",
664 "hir", 650 "hir",
665 "itertools 0.10.0", 651 "itertools",
666 "log", 652 "log",
667 "once_cell", 653 "once_cell",
668 "profile", 654 "profile",
@@ -675,10 +661,24 @@ dependencies = [
675] 661]
676 662
677[[package]] 663[[package]]
664name = "ide_ssr"
665version = "0.0.0"
666dependencies = [
667 "expect-test",
668 "hir",
669 "ide_db",
670 "itertools",
671 "rustc-hash",
672 "syntax",
673 "test_utils",
674 "text_edit",
675]
676
677[[package]]
678name = "idna" 678name = "idna"
679version = "0.2.0" 679version = "0.2.2"
680source = "registry+https://github.com/rust-lang/crates.io-index" 680source = "registry+https://github.com/rust-lang/crates.io-index"
681checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 681checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21"
682dependencies = [ 682dependencies = [
683 "matches", 683 "matches",
684 "unicode-bidi", 684 "unicode-bidi",
@@ -692,14 +692,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
692checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b" 692checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
693dependencies = [ 693dependencies = [
694 "autocfg", 694 "autocfg",
695 "hashbrown 0.9.1", 695 "hashbrown",
696] 696]
697 697
698[[package]] 698[[package]]
699name = "inotify" 699name = "inotify"
700version = "0.8.3" 700version = "0.9.2"
701source = "registry+https://github.com/rust-lang/crates.io-index" 701source = "registry+https://github.com/rust-lang/crates.io-index"
702checksum = "46dd0a94b393c730779ccfd2a872b67b1eb67be3fc33082e733bdb38b5fde4d4" 702checksum = "d19f57db1baad9d09e43a3cd76dcf82ebdafd37d75c9498b87762dba77c93f15"
703dependencies = [ 703dependencies = [
704 "bitflags", 704 "bitflags",
705 "inotify-sys", 705 "inotify-sys",
@@ -708,9 +708,9 @@ dependencies = [
708 708
709[[package]] 709[[package]]
710name = "inotify-sys" 710name = "inotify-sys"
711version = "0.1.4" 711version = "0.1.5"
712source = "registry+https://github.com/rust-lang/crates.io-index" 712source = "registry+https://github.com/rust-lang/crates.io-index"
713checksum = "c4563555856585ab3180a5bf0b2f9f8d301a728462afffc8195b3f5394229c55" 713checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
714dependencies = [ 714dependencies = [
715 "libc", 715 "libc",
716] 716]
@@ -721,41 +721,55 @@ version = "0.1.9"
721source = "registry+https://github.com/rust-lang/crates.io-index" 721source = "registry+https://github.com/rust-lang/crates.io-index"
722checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" 722checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
723dependencies = [ 723dependencies = [
724 "cfg-if 1.0.0", 724 "cfg-if",
725] 725]
726 726
727[[package]] 727[[package]]
728name = "iovec" 728name = "itertools"
729version = "0.1.4" 729version = "0.10.0"
730source = "registry+https://github.com/rust-lang/crates.io-index" 730source = "registry+https://github.com/rust-lang/crates.io-index"
731checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 731checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
732dependencies = [ 732dependencies = [
733 "libc", 733 "either",
734] 734]
735 735
736[[package]] 736[[package]]
737name = "itertools" 737name = "itoa"
738version = "0.9.0" 738version = "0.4.7"
739source = "registry+https://github.com/rust-lang/crates.io-index" 739source = "registry+https://github.com/rust-lang/crates.io-index"
740checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" 740checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
741
742[[package]]
743name = "jemalloc-ctl"
744version = "0.3.3"
745source = "registry+https://github.com/rust-lang/crates.io-index"
746checksum = "c502a5ff9dd2924f1ed32ba96e3b65735d837b4bfd978d3161b1702e66aca4b7"
741dependencies = [ 747dependencies = [
742 "either", 748 "jemalloc-sys",
749 "libc",
750 "paste",
743] 751]
744 752
745[[package]] 753[[package]]
746name = "itertools" 754name = "jemalloc-sys"
747version = "0.10.0" 755version = "0.3.2"
748source = "registry+https://github.com/rust-lang/crates.io-index" 756source = "registry+https://github.com/rust-lang/crates.io-index"
749checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" 757checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45"
750dependencies = [ 758dependencies = [
751 "either", 759 "cc",
760 "fs_extra",
761 "libc",
752] 762]
753 763
754[[package]] 764[[package]]
755name = "itoa" 765name = "jemallocator"
756version = "0.4.7" 766version = "0.3.2"
757source = "registry+https://github.com/rust-lang/crates.io-index" 767source = "registry+https://github.com/rust-lang/crates.io-index"
758checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" 768checksum = "43ae63fcfc45e99ab3d1b29a46782ad679e98436c3169d15a167a1108a724b69"
769dependencies = [
770 "jemalloc-sys",
771 "libc",
772]
759 773
760[[package]] 774[[package]]
761name = "jod-thread" 775name = "jod-thread"
@@ -764,16 +778,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
764checksum = "8b23360e99b8717f20aaa4598f5a6541efbe30630039fbc7706cf954a87947ae" 778checksum = "8b23360e99b8717f20aaa4598f5a6541efbe30630039fbc7706cf954a87947ae"
765 779
766[[package]] 780[[package]]
767name = "kernel32-sys"
768version = "0.2.2"
769source = "registry+https://github.com/rust-lang/crates.io-index"
770checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
771dependencies = [
772 "winapi 0.2.8",
773 "winapi-build",
774]
775
776[[package]]
777name = "la-arena" 781name = "la-arena"
778version = "0.2.0" 782version = "0.2.0"
779 783
@@ -784,32 +788,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
784checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 788checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
785 789
786[[package]] 790[[package]]
787name = "lazycell"
788version = "1.3.0"
789source = "registry+https://github.com/rust-lang/crates.io-index"
790checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
791
792[[package]]
793name = "libc" 791name = "libc"
794version = "0.2.81" 792version = "0.2.87"
795source = "registry+https://github.com/rust-lang/crates.io-index" 793source = "registry+https://github.com/rust-lang/crates.io-index"
796checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" 794checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213"
797 795
798[[package]] 796[[package]]
799name = "libloading" 797name = "libloading"
800version = "0.6.6" 798version = "0.7.0"
801source = "registry+https://github.com/rust-lang/crates.io-index" 799source = "registry+https://github.com/rust-lang/crates.io-index"
802checksum = "e9367bdfa836b7e3cf895867f7a570283444da90562980ec2263d6e1569b16bc" 800checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
803dependencies = [ 801dependencies = [
804 "cfg-if 1.0.0", 802 "cfg-if",
805 "winapi 0.3.9", 803 "winapi",
806] 804]
807 805
808[[package]] 806[[package]]
809name = "libmimalloc-sys" 807name = "libmimalloc-sys"
810version = "0.1.18" 808version = "0.1.20"
811source = "registry+https://github.com/rust-lang/crates.io-index" 809source = "registry+https://github.com/rust-lang/crates.io-index"
812checksum = "82151ff13433c4d403cb15d0e6fbda14b24d65bd1a5b33f7d52ec983cc00752d" 810checksum = "e58f42b6424a0ed536678c65fd97cd64b4344bcf86251e284f7c0ce9eee40e64"
813dependencies = [ 811dependencies = [
814 "cmake", 812 "cmake",
815] 813]
@@ -825,11 +823,11 @@ dependencies = [
825 823
826[[package]] 824[[package]]
827name = "log" 825name = "log"
828version = "0.4.11" 826version = "0.4.14"
829source = "registry+https://github.com/rust-lang/crates.io-index" 827source = "registry+https://github.com/rust-lang/crates.io-index"
830checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" 828checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
831dependencies = [ 829dependencies = [
832 "cfg-if 0.1.10", 830 "cfg-if",
833] 831]
834 832
835[[package]] 833[[package]]
@@ -838,7 +836,7 @@ version = "0.5.0"
838source = "registry+https://github.com/rust-lang/crates.io-index" 836source = "registry+https://github.com/rust-lang/crates.io-index"
839checksum = "69b18dfe0e4a380b872aa79d8e0ee6c3d7a9682466e84b83ad807c88b3545f79" 837checksum = "69b18dfe0e4a380b872aa79d8e0ee6c3d7a9682466e84b83ad807c88b3545f79"
840dependencies = [ 838dependencies = [
841 "crossbeam-channel 0.5.0", 839 "crossbeam-channel",
842 "log", 840 "log",
843 "serde", 841 "serde",
844 "serde_json", 842 "serde_json",
@@ -846,11 +844,10 @@ dependencies = [
846 844
847[[package]] 845[[package]]
848name = "lsp-types" 846name = "lsp-types"
849version = "0.86.0" 847version = "0.88.0"
850source = "registry+https://github.com/rust-lang/crates.io-index" 848source = "registry+https://github.com/rust-lang/crates.io-index"
851checksum = "f2a5c40d566f2704dac30859bca152217583fc94fd5b178d8baba915e1abd382" 849checksum = "d8e8e042772e4e10b3785822f63c82399d0dd233825de44d2596f7fa86e023e0"
852dependencies = [ 850dependencies = [
853 "base64",
854 "bitflags", 851 "bitflags",
855 "serde", 852 "serde",
856 "serde_json", 853 "serde_json",
@@ -874,19 +871,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
874checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 871checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
875 872
876[[package]] 873[[package]]
877name = "maybe-uninit"
878version = "2.0.0"
879source = "registry+https://github.com/rust-lang/crates.io-index"
880checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
881
882[[package]]
883name = "mbe" 874name = "mbe"
884version = "0.0.0" 875version = "0.0.0"
885dependencies = [ 876dependencies = [
886 "log", 877 "log",
887 "parser", 878 "parser",
879 "profile",
888 "rustc-hash", 880 "rustc-hash",
889 "smallvec", 881 "smallvec",
882 "stdx",
890 "syntax", 883 "syntax",
891 "test_utils", 884 "test_utils",
892 "tt", 885 "tt",
@@ -899,22 +892,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
899checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" 892checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
900 893
901[[package]] 894[[package]]
902name = "memmap" 895name = "memmap2"
903version = "0.7.0" 896version = "0.2.1"
904source = "registry+https://github.com/rust-lang/crates.io-index" 897source = "registry+https://github.com/rust-lang/crates.io-index"
905checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" 898checksum = "04e3e85b970d650e2ae6d70592474087051c11c54da7f7b4949725c5735fbcc6"
906dependencies = [ 899dependencies = [
907 "libc", 900 "libc",
908 "winapi 0.3.9",
909]
910
911[[package]]
912name = "memoffset"
913version = "0.5.6"
914source = "registry+https://github.com/rust-lang/crates.io-index"
915checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
916dependencies = [
917 "autocfg",
918] 901]
919 902
920[[package]] 903[[package]]
@@ -928,18 +911,18 @@ dependencies = [
928 911
929[[package]] 912[[package]]
930name = "mimalloc" 913name = "mimalloc"
931version = "0.1.22" 914version = "0.1.24"
932source = "registry+https://github.com/rust-lang/crates.io-index" 915source = "registry+https://github.com/rust-lang/crates.io-index"
933checksum = "4a5d2c9cb18f9cdc6d88f4aca6d3d8ea89c4c8202d6facfc7e56efdee97b80fa" 916checksum = "757efec188b3d2088949d912e01ea2fe87164ed6376b6c5d7dd4f3ce1668a93d"
934dependencies = [ 917dependencies = [
935 "libmimalloc-sys", 918 "libmimalloc-sys",
936] 919]
937 920
938[[package]] 921[[package]]
939name = "miniz_oxide" 922name = "miniz_oxide"
940version = "0.4.3" 923version = "0.4.4"
941source = "registry+https://github.com/rust-lang/crates.io-index" 924source = "registry+https://github.com/rust-lang/crates.io-index"
942checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" 925checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
943dependencies = [ 926dependencies = [
944 "adler", 927 "adler",
945 "autocfg", 928 "autocfg",
@@ -947,76 +930,53 @@ dependencies = [
947 930
948[[package]] 931[[package]]
949name = "mio" 932name = "mio"
950version = "0.6.23" 933version = "0.7.9"
951source = "registry+https://github.com/rust-lang/crates.io-index" 934source = "registry+https://github.com/rust-lang/crates.io-index"
952checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" 935checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a"
953dependencies = [ 936dependencies = [
954 "cfg-if 0.1.10",
955 "fuchsia-zircon",
956 "fuchsia-zircon-sys",
957 "iovec",
958 "kernel32-sys",
959 "libc", 937 "libc",
960 "log", 938 "log",
961 "miow", 939 "miow",
962 "net2", 940 "ntapi",
963 "slab", 941 "winapi",
964 "winapi 0.2.8",
965]
966
967[[package]]
968name = "mio-extras"
969version = "2.0.6"
970source = "registry+https://github.com/rust-lang/crates.io-index"
971checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
972dependencies = [
973 "lazycell",
974 "log",
975 "mio",
976 "slab",
977] 942]
978 943
979[[package]] 944[[package]]
980name = "miow" 945name = "miow"
981version = "0.2.2" 946version = "0.3.6"
982source = "registry+https://github.com/rust-lang/crates.io-index"
983checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
984dependencies = [
985 "kernel32-sys",
986 "net2",
987 "winapi 0.2.8",
988 "ws2_32-sys",
989]
990
991[[package]]
992name = "net2"
993version = "0.2.37"
994source = "registry+https://github.com/rust-lang/crates.io-index" 947source = "registry+https://github.com/rust-lang/crates.io-index"
995checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" 948checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
996dependencies = [ 949dependencies = [
997 "cfg-if 0.1.10", 950 "socket2",
998 "libc", 951 "winapi",
999 "winapi 0.3.9",
1000] 952]
1001 953
1002[[package]] 954[[package]]
1003name = "notify" 955name = "notify"
1004version = "5.0.0-pre.4" 956version = "5.0.0-pre.6"
1005source = "registry+https://github.com/rust-lang/crates.io-index" 957source = "registry+https://github.com/rust-lang/crates.io-index"
1006checksum = "a8b946889dfdad884379cd56367d93b6d0ce8889cc027d26a69a3a31c0a03bb5" 958checksum = "e5fd82b93434edb9c00ae65ee741e0e081cdc8c63346ab9f687935a629aaf4c3"
1007dependencies = [ 959dependencies = [
1008 "anymap", 960 "anymap",
1009 "bitflags", 961 "bitflags",
1010 "crossbeam-channel 0.4.4", 962 "crossbeam-channel",
1011 "filetime", 963 "filetime",
1012 "fsevent", 964 "fsevent",
1013 "fsevent-sys", 965 "fsevent-sys",
1014 "inotify", 966 "inotify",
1015 "libc", 967 "libc",
1016 "mio", 968 "mio",
1017 "mio-extras",
1018 "walkdir", 969 "walkdir",
1019 "winapi 0.3.9", 970 "winapi",
971]
972
973[[package]]
974name = "ntapi"
975version = "0.3.6"
976source = "registry+https://github.com/rust-lang/crates.io-index"
977checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
978dependencies = [
979 "winapi",
1020] 980]
1021 981
1022[[package]] 982[[package]]
@@ -1050,21 +1010,15 @@ dependencies = [
1050 1010
1051[[package]] 1011[[package]]
1052name = "object" 1012name = "object"
1053version = "0.22.0"
1054source = "registry+https://github.com/rust-lang/crates.io-index"
1055checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
1056
1057[[package]]
1058name = "object"
1059version = "0.23.0" 1013version = "0.23.0"
1060source = "registry+https://github.com/rust-lang/crates.io-index" 1014source = "registry+https://github.com/rust-lang/crates.io-index"
1061checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" 1015checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
1062 1016
1063[[package]] 1017[[package]]
1064name = "once_cell" 1018name = "once_cell"
1065version = "1.5.2" 1019version = "1.7.1"
1066source = "registry+https://github.com/rust-lang/crates.io-index" 1020source = "registry+https://github.com/rust-lang/crates.io-index"
1067checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" 1021checksum = "ea78b9742c52ac729753c1590e9adc5248ea9bdaf974597efd46c74cfaa5fb54"
1068 1022
1069[[package]] 1023[[package]]
1070name = "oorandom" 1024name = "oorandom"
@@ -1085,16 +1039,16 @@ dependencies = [
1085 1039
1086[[package]] 1040[[package]]
1087name = "parking_lot_core" 1041name = "parking_lot_core"
1088version = "0.8.2" 1042version = "0.8.3"
1089source = "registry+https://github.com/rust-lang/crates.io-index" 1043source = "registry+https://github.com/rust-lang/crates.io-index"
1090checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272" 1044checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
1091dependencies = [ 1045dependencies = [
1092 "cfg-if 1.0.0", 1046 "cfg-if",
1093 "instant", 1047 "instant",
1094 "libc", 1048 "libc",
1095 "redox_syscall", 1049 "redox_syscall",
1096 "smallvec", 1050 "smallvec",
1097 "winapi 0.3.9", 1051 "winapi",
1098] 1052]
1099 1053
1100[[package]] 1054[[package]]
@@ -1105,6 +1059,25 @@ dependencies = [
1105] 1059]
1106 1060
1107[[package]] 1061[[package]]
1062name = "paste"
1063version = "0.1.18"
1064source = "registry+https://github.com/rust-lang/crates.io-index"
1065checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
1066dependencies = [
1067 "paste-impl",
1068 "proc-macro-hack",
1069]
1070
1071[[package]]
1072name = "paste-impl"
1073version = "0.1.18"
1074source = "registry+https://github.com/rust-lang/crates.io-index"
1075checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
1076dependencies = [
1077 "proc-macro-hack",
1078]
1079
1080[[package]]
1108name = "paths" 1081name = "paths"
1109version = "0.0.0" 1082version = "0.0.0"
1110 1083
@@ -1153,16 +1126,16 @@ dependencies = [
1153] 1126]
1154 1127
1155[[package]] 1128[[package]]
1156name = "pico-args" 1129name = "pin-project-lite"
1157version = "0.3.4" 1130version = "0.2.5"
1158source = "registry+https://github.com/rust-lang/crates.io-index" 1131source = "registry+https://github.com/rust-lang/crates.io-index"
1159checksum = "28b9b4df73455c861d7cbf8be42f01d3b373ed7f02e378d55fa84eafc6f638b1" 1132checksum = "0cf491442e4b033ed1c722cb9f0df5fcfcf4de682466c46469c36bc47dc5548a"
1160 1133
1161[[package]] 1134[[package]]
1162name = "pin-project-lite" 1135name = "proc-macro-hack"
1163version = "0.2.0" 1136version = "0.5.19"
1164source = "registry+https://github.com/rust-lang/crates.io-index" 1137source = "registry+https://github.com/rust-lang/crates.io-index"
1165checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c" 1138checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
1166 1139
1167[[package]] 1140[[package]]
1168name = "proc-macro2" 1141name = "proc-macro2"
@@ -1178,11 +1151,12 @@ name = "proc_macro_api"
1178version = "0.0.0" 1151version = "0.0.0"
1179dependencies = [ 1152dependencies = [
1180 "base_db", 1153 "base_db",
1181 "crossbeam-channel 0.5.0", 1154 "crossbeam-channel",
1182 "jod-thread", 1155 "jod-thread",
1183 "log", 1156 "log",
1184 "serde", 1157 "serde",
1185 "serde_json", 1158 "serde_json",
1159 "stdx",
1186 "tt", 1160 "tt",
1187] 1161]
1188 1162
@@ -1193,8 +1167,8 @@ dependencies = [
1193 "cargo_metadata", 1167 "cargo_metadata",
1194 "libloading", 1168 "libloading",
1195 "mbe", 1169 "mbe",
1196 "memmap", 1170 "memmap2",
1197 "object 0.23.0", 1171 "object",
1198 "proc_macro_api", 1172 "proc_macro_api",
1199 "proc_macro_test", 1173 "proc_macro_test",
1200 "serde_derive", 1174 "serde_derive",
@@ -1211,7 +1185,9 @@ version = "0.0.0"
1211name = "profile" 1185name = "profile"
1212version = "0.0.0" 1186version = "0.0.0"
1213dependencies = [ 1187dependencies = [
1214 "cfg-if 1.0.0", 1188 "cfg-if",
1189 "countme",
1190 "jemalloc-ctl",
1215 "la-arena", 1191 "la-arena",
1216 "libc", 1192 "libc",
1217 "once_cell", 1193 "once_cell",
@@ -1226,7 +1202,7 @@ dependencies = [
1226 "base_db", 1202 "base_db",
1227 "cargo_metadata", 1203 "cargo_metadata",
1228 "cfg", 1204 "cfg",
1229 "itertools 0.10.0", 1205 "itertools",
1230 "la-arena", 1206 "la-arena",
1231 "log", 1207 "log",
1232 "paths", 1208 "paths",
@@ -1261,9 +1237,9 @@ dependencies = [
1261 1237
1262[[package]] 1238[[package]]
1263name = "quote" 1239name = "quote"
1264version = "1.0.8" 1240version = "1.0.9"
1265source = "registry+https://github.com/rust-lang/crates.io-index" 1241source = "registry+https://github.com/rust-lang/crates.io-index"
1266checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" 1242checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
1267dependencies = [ 1243dependencies = [
1268 "proc-macro2", 1244 "proc-macro2",
1269] 1245]
@@ -1286,18 +1262,21 @@ version = "1.9.0"
1286source = "registry+https://github.com/rust-lang/crates.io-index" 1262source = "registry+https://github.com/rust-lang/crates.io-index"
1287checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" 1263checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
1288dependencies = [ 1264dependencies = [
1289 "crossbeam-channel 0.5.0", 1265 "crossbeam-channel",
1290 "crossbeam-deque", 1266 "crossbeam-deque",
1291 "crossbeam-utils 0.8.1", 1267 "crossbeam-utils",
1292 "lazy_static", 1268 "lazy_static",
1293 "num_cpus", 1269 "num_cpus",
1294] 1270]
1295 1271
1296[[package]] 1272[[package]]
1297name = "redox_syscall" 1273name = "redox_syscall"
1298version = "0.1.57" 1274version = "0.2.5"
1299source = "registry+https://github.com/rust-lang/crates.io-index" 1275source = "registry+https://github.com/rust-lang/crates.io-index"
1300checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" 1276checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
1277dependencies = [
1278 "bitflags",
1279]
1301 1280
1302[[package]] 1281[[package]]
1303name = "regex" 1282name = "regex"
@@ -1326,24 +1305,25 @@ checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
1326 1305
1327[[package]] 1306[[package]]
1328name = "rowan" 1307name = "rowan"
1329version = "0.10.5" 1308version = "0.12.6"
1330source = "registry+https://github.com/rust-lang/crates.io-index" 1309source = "registry+https://github.com/rust-lang/crates.io-index"
1331checksum = "e1898adeafc7d3c69913b33ee1acbbb39c726a9dbe05ff77c08b52957643e8db" 1310checksum = "a1b36e449f3702f3b0c821411db1cbdf30fb451726a9456dce5dabcd44420043"
1332dependencies = [ 1311dependencies = [
1333 "hashbrown 0.10.0", 1312 "countme",
1313 "hashbrown",
1314 "memoffset",
1334 "rustc-hash", 1315 "rustc-hash",
1335 "smol_str",
1336 "text-size", 1316 "text-size",
1337 "triomphe",
1338] 1317]
1339 1318
1340[[package]] 1319[[package]]
1341name = "rust-analyzer" 1320name = "rust-analyzer"
1342version = "0.0.0" 1321version = "0.0.0"
1343dependencies = [ 1322dependencies = [
1323 "always-assert",
1344 "anyhow", 1324 "anyhow",
1345 "cfg", 1325 "cfg",
1346 "crossbeam-channel 0.5.0", 1326 "crossbeam-channel",
1347 "dissimilar", 1327 "dissimilar",
1348 "env_logger", 1328 "env_logger",
1349 "expect-test", 1329 "expect-test",
@@ -1353,7 +1333,9 @@ dependencies = [
1353 "hir_ty", 1333 "hir_ty",
1354 "ide", 1334 "ide",
1355 "ide_db", 1335 "ide_db",
1356 "itertools 0.10.0", 1336 "ide_ssr",
1337 "itertools",
1338 "jemallocator",
1357 "jod-thread", 1339 "jod-thread",
1358 "log", 1340 "log",
1359 "lsp-server", 1341 "lsp-server",
@@ -1362,7 +1344,6 @@ dependencies = [
1362 "mimalloc", 1344 "mimalloc",
1363 "oorandom", 1345 "oorandom",
1364 "parking_lot", 1346 "parking_lot",
1365 "pico-args",
1366 "proc_macro_srv", 1347 "proc_macro_srv",
1367 "profile", 1348 "profile",
1368 "project_model", 1349 "project_model",
@@ -1371,7 +1352,6 @@ dependencies = [
1371 "serde", 1352 "serde",
1372 "serde_json", 1353 "serde_json",
1373 "serde_path_to_error", 1354 "serde_path_to_error",
1374 "ssr",
1375 "stdx", 1355 "stdx",
1376 "syntax", 1356 "syntax",
1377 "test_utils", 1357 "test_utils",
@@ -1384,14 +1364,15 @@ dependencies = [
1384 "tt", 1364 "tt",
1385 "vfs", 1365 "vfs",
1386 "vfs-notify", 1366 "vfs-notify",
1387 "winapi 0.3.9", 1367 "winapi",
1368 "xflags",
1388] 1369]
1389 1370
1390[[package]] 1371[[package]]
1391name = "rustc-ap-rustc_lexer" 1372name = "rustc-ap-rustc_lexer"
1392version = "697.0.0" 1373version = "708.0.0"
1393source = "registry+https://github.com/rust-lang/crates.io-index" 1374source = "registry+https://github.com/rust-lang/crates.io-index"
1394checksum = "67adbe260a0a11910624d6d28c0304fcf7b063e666682111005c83b09f73429d" 1375checksum = "2706fc7106c75eaea49efe9f35f719a6fdfdb95212122ec2b543659406bae7ea"
1395dependencies = [ 1376dependencies = [
1396 "unicode-xid", 1377 "unicode-xid",
1397] 1378]
@@ -1420,7 +1401,7 @@ version = "0.16.0"
1420source = "registry+https://github.com/rust-lang/crates.io-index" 1401source = "registry+https://github.com/rust-lang/crates.io-index"
1421checksum = "d8fadca2ab5de17acf66d744f4888049ca8f1bb9b8a1ab8afd9d032cc959c5dc" 1402checksum = "d8fadca2ab5de17acf66d744f4888049ca8f1bb9b8a1ab8afd9d032cc959c5dc"
1422dependencies = [ 1403dependencies = [
1423 "crossbeam-utils 0.8.1", 1404 "crossbeam-utils",
1424 "indexmap", 1405 "indexmap",
1425 "lock_api", 1406 "lock_api",
1426 "log", 1407 "log",
@@ -1485,18 +1466,18 @@ dependencies = [
1485 1466
1486[[package]] 1467[[package]]
1487name = "serde" 1468name = "serde"
1488version = "1.0.118" 1469version = "1.0.123"
1489source = "registry+https://github.com/rust-lang/crates.io-index" 1470source = "registry+https://github.com/rust-lang/crates.io-index"
1490checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" 1471checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
1491dependencies = [ 1472dependencies = [
1492 "serde_derive", 1473 "serde_derive",
1493] 1474]
1494 1475
1495[[package]] 1476[[package]]
1496name = "serde_derive" 1477name = "serde_derive"
1497version = "1.0.118" 1478version = "1.0.123"
1498source = "registry+https://github.com/rust-lang/crates.io-index" 1479source = "registry+https://github.com/rust-lang/crates.io-index"
1499checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" 1480checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
1500dependencies = [ 1481dependencies = [
1501 "proc-macro2", 1482 "proc-macro2",
1502 "quote", 1483 "quote",
@@ -1505,9 +1486,9 @@ dependencies = [
1505 1486
1506[[package]] 1487[[package]]
1507name = "serde_json" 1488name = "serde_json"
1508version = "1.0.61" 1489version = "1.0.64"
1509source = "registry+https://github.com/rust-lang/crates.io-index" 1490source = "registry+https://github.com/rust-lang/crates.io-index"
1510checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" 1491checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
1511dependencies = [ 1492dependencies = [
1512 "indexmap", 1493 "indexmap",
1513 "itoa", 1494 "itoa",
@@ -1545,16 +1526,10 @@ dependencies = [
1545] 1526]
1546 1527
1547[[package]] 1528[[package]]
1548name = "slab"
1549version = "0.4.2"
1550source = "registry+https://github.com/rust-lang/crates.io-index"
1551checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
1552
1553[[package]]
1554name = "smallvec" 1529name = "smallvec"
1555version = "1.6.0" 1530version = "1.6.1"
1556source = "registry+https://github.com/rust-lang/crates.io-index" 1531source = "registry+https://github.com/rust-lang/crates.io-index"
1557checksum = "1a55ca5f3b68e41c979bf8c46a6f1da892ca4db8f94023ce0bd32407573b1ac0" 1532checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
1558 1533
1559[[package]] 1534[[package]]
1560name = "smol_str" 1535name = "smol_str"
@@ -1566,37 +1541,29 @@ dependencies = [
1566] 1541]
1567 1542
1568[[package]] 1543[[package]]
1569name = "ssr" 1544name = "socket2"
1570version = "0.0.0" 1545version = "0.3.19"
1546source = "registry+https://github.com/rust-lang/crates.io-index"
1547checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
1571dependencies = [ 1548dependencies = [
1572 "expect-test", 1549 "cfg-if",
1573 "hir", 1550 "libc",
1574 "ide_db", 1551 "winapi",
1575 "itertools 0.10.0",
1576 "rustc-hash",
1577 "syntax",
1578 "test_utils",
1579 "text_edit",
1580] 1552]
1581 1553
1582[[package]] 1554[[package]]
1583name = "stable_deref_trait"
1584version = "1.2.0"
1585source = "registry+https://github.com/rust-lang/crates.io-index"
1586checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
1587
1588[[package]]
1589name = "stdx" 1555name = "stdx"
1590version = "0.0.0" 1556version = "0.0.0"
1591dependencies = [ 1557dependencies = [
1558 "always-assert",
1592 "backtrace", 1559 "backtrace",
1593] 1560]
1594 1561
1595[[package]] 1562[[package]]
1596name = "syn" 1563name = "syn"
1597version = "1.0.57" 1564version = "1.0.60"
1598source = "registry+https://github.com/rust-lang/crates.io-index" 1565source = "registry+https://github.com/rust-lang/crates.io-index"
1599checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6" 1566checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
1600dependencies = [ 1567dependencies = [
1601 "proc-macro2", 1568 "proc-macro2",
1602 "quote", 1569 "quote",
@@ -1622,7 +1589,7 @@ dependencies = [
1622 "arrayvec", 1589 "arrayvec",
1623 "expect-test", 1590 "expect-test",
1624 "indexmap", 1591 "indexmap",
1625 "itertools 0.10.0", 1592 "itertools",
1626 "once_cell", 1593 "once_cell",
1627 "parser", 1594 "parser",
1628 "profile", 1595 "profile",
@@ -1652,6 +1619,7 @@ name = "test_utils"
1652version = "0.0.0" 1619version = "0.0.0"
1653dependencies = [ 1620dependencies = [
1654 "dissimilar", 1621 "dissimilar",
1622 "profile",
1655 "rustc-hash", 1623 "rustc-hash",
1656 "serde_json", 1624 "serde_json",
1657 "stdx", 1625 "stdx",
@@ -1673,11 +1641,11 @@ dependencies = [
1673 1641
1674[[package]] 1642[[package]]
1675name = "thread_local" 1643name = "thread_local"
1676version = "1.0.1" 1644version = "1.1.3"
1677source = "registry+https://github.com/rust-lang/crates.io-index" 1645source = "registry+https://github.com/rust-lang/crates.io-index"
1678checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 1646checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
1679dependencies = [ 1647dependencies = [
1680 "lazy_static", 1648 "once_cell",
1681] 1649]
1682 1650
1683[[package]] 1651[[package]]
@@ -1690,21 +1658,10 @@ dependencies = [
1690] 1658]
1691 1659
1692[[package]] 1660[[package]]
1693name = "time"
1694version = "0.1.44"
1695source = "registry+https://github.com/rust-lang/crates.io-index"
1696checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
1697dependencies = [
1698 "libc",
1699 "wasi",
1700 "winapi 0.3.9",
1701]
1702
1703[[package]]
1704name = "tinyvec" 1661name = "tinyvec"
1705version = "1.1.0" 1662version = "1.1.1"
1706source = "registry+https://github.com/rust-lang/crates.io-index" 1663source = "registry+https://github.com/rust-lang/crates.io-index"
1707checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f" 1664checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023"
1708dependencies = [ 1665dependencies = [
1709 "tinyvec_macros", 1666 "tinyvec_macros",
1710] 1667]
@@ -1724,11 +1681,11 @@ dependencies = [
1724 1681
1725[[package]] 1682[[package]]
1726name = "tracing" 1683name = "tracing"
1727version = "0.1.22" 1684version = "0.1.25"
1728source = "registry+https://github.com/rust-lang/crates.io-index" 1685source = "registry+https://github.com/rust-lang/crates.io-index"
1729checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" 1686checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
1730dependencies = [ 1687dependencies = [
1731 "cfg-if 1.0.0", 1688 "cfg-if",
1732 "pin-project-lite", 1689 "pin-project-lite",
1733 "tracing-attributes", 1690 "tracing-attributes",
1734 "tracing-core", 1691 "tracing-core",
@@ -1736,9 +1693,9 @@ dependencies = [
1736 1693
1737[[package]] 1694[[package]]
1738name = "tracing-attributes" 1695name = "tracing-attributes"
1739version = "0.1.11" 1696version = "0.1.13"
1740source = "registry+https://github.com/rust-lang/crates.io-index" 1697source = "registry+https://github.com/rust-lang/crates.io-index"
1741checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada" 1698checksum = "a8a9bd1db7706f2373a190b0d067146caa39350c486f3d455b0e33b431f94c07"
1742dependencies = [ 1699dependencies = [
1743 "proc-macro2", 1700 "proc-macro2",
1744 "quote", 1701 "quote",
@@ -1756,9 +1713,9 @@ dependencies = [
1756 1713
1757[[package]] 1714[[package]]
1758name = "tracing-log" 1715name = "tracing-log"
1759version = "0.1.1" 1716version = "0.1.2"
1760source = "registry+https://github.com/rust-lang/crates.io-index" 1717source = "registry+https://github.com/rust-lang/crates.io-index"
1761checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9" 1718checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
1762dependencies = [ 1719dependencies = [
1763 "lazy_static", 1720 "lazy_static",
1764 "log", 1721 "log",
@@ -1777,9 +1734,9 @@ dependencies = [
1777 1734
1778[[package]] 1735[[package]]
1779name = "tracing-subscriber" 1736name = "tracing-subscriber"
1780version = "0.2.15" 1737version = "0.2.16"
1781source = "registry+https://github.com/rust-lang/crates.io-index" 1738source = "registry+https://github.com/rust-lang/crates.io-index"
1782checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401" 1739checksum = "8ab8966ac3ca27126141f7999361cc97dd6fb4b71da04c02044fa9045d98bb96"
1783dependencies = [ 1740dependencies = [
1784 "ansi_term", 1741 "ansi_term",
1785 "chrono", 1742 "chrono",
@@ -1799,13 +1756,12 @@ dependencies = [
1799 1756
1800[[package]] 1757[[package]]
1801name = "tracing-tree" 1758name = "tracing-tree"
1802version = "0.1.7" 1759version = "0.1.8"
1803source = "registry+https://github.com/rust-lang/crates.io-index" 1760source = "registry+https://github.com/rust-lang/crates.io-index"
1804checksum = "023e80cdb7c8468b7aade1d756afa2acbe2ae0a6142a25ec664b5239d6ef2794" 1761checksum = "1a60657cfbf397c603257a8230b3f427e6a2a4e5911a59331b9bb4dffff5b608"
1805dependencies = [ 1762dependencies = [
1806 "ansi_term", 1763 "ansi_term",
1807 "atty", 1764 "atty",
1808 "chrono",
1809 "termcolor", 1765 "termcolor",
1810 "tracing", 1766 "tracing",
1811 "tracing-log", 1767 "tracing-log",
@@ -1813,17 +1769,6 @@ dependencies = [
1813] 1769]
1814 1770
1815[[package]] 1771[[package]]
1816name = "triomphe"
1817version = "0.1.2"
1818source = "registry+https://github.com/rust-lang/crates.io-index"
1819checksum = "6e9d872053cf9e5a833d8c1dd772cdc38ab66a908129d6f73c049c986161d07c"
1820dependencies = [
1821 "memoffset 0.5.6",
1822 "serde",
1823 "stable_deref_trait",
1824]
1825
1826[[package]]
1827name = "tt" 1772name = "tt"
1828version = "0.0.0" 1773version = "0.0.0"
1829dependencies = [ 1774dependencies = [
@@ -1839,9 +1784,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
1839 1784
1840[[package]] 1785[[package]]
1841name = "ungrammar" 1786name = "ungrammar"
1842version = "1.9.2" 1787version = "1.11.0"
1843source = "registry+https://github.com/rust-lang/crates.io-index" 1788source = "registry+https://github.com/rust-lang/crates.io-index"
1844checksum = "58a02e2041a872d56354e843e8e86e6b946fc8e7dc32982fcdc335e29eb4cc8b" 1789checksum = "84c629795d377049f2a1dc5f42cf505dc5ba8b28a5df0a03f4183a24480e4a6a"
1845 1790
1846[[package]] 1791[[package]]
1847name = "unicase" 1792name = "unicase"
@@ -1863,9 +1808,9 @@ dependencies = [
1863 1808
1864[[package]] 1809[[package]]
1865name = "unicode-normalization" 1810name = "unicode-normalization"
1866version = "0.1.16" 1811version = "0.1.17"
1867source = "registry+https://github.com/rust-lang/crates.io-index" 1812source = "registry+https://github.com/rust-lang/crates.io-index"
1868checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" 1813checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef"
1869dependencies = [ 1814dependencies = [
1870 "tinyvec", 1815 "tinyvec",
1871] 1816]
@@ -1884,9 +1829,9 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
1884 1829
1885[[package]] 1830[[package]]
1886name = "url" 1831name = "url"
1887version = "2.2.0" 1832version = "2.2.1"
1888source = "registry+https://github.com/rust-lang/crates.io-index" 1833source = "registry+https://github.com/rust-lang/crates.io-index"
1889checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" 1834checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
1890dependencies = [ 1835dependencies = [
1891 "form_urlencoded", 1836 "form_urlencoded",
1892 "idna", 1837 "idna",
@@ -1914,7 +1859,7 @@ dependencies = [
1914name = "vfs-notify" 1859name = "vfs-notify"
1915version = "0.0.0" 1860version = "0.0.0"
1916dependencies = [ 1861dependencies = [
1917 "crossbeam-channel 0.5.0", 1862 "crossbeam-channel",
1918 "jod-thread", 1863 "jod-thread",
1919 "log", 1864 "log",
1920 "notify", 1865 "notify",
@@ -1931,23 +1876,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1931checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 1876checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
1932dependencies = [ 1877dependencies = [
1933 "same-file", 1878 "same-file",
1934 "winapi 0.3.9", 1879 "winapi",
1935 "winapi-util", 1880 "winapi-util",
1936] 1881]
1937 1882
1938[[package]] 1883[[package]]
1939name = "wasi"
1940version = "0.10.0+wasi-snapshot-preview1"
1941source = "registry+https://github.com/rust-lang/crates.io-index"
1942checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1943
1944[[package]]
1945name = "winapi"
1946version = "0.2.8"
1947source = "registry+https://github.com/rust-lang/crates.io-index"
1948checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
1949
1950[[package]]
1951name = "winapi" 1884name = "winapi"
1952version = "0.3.9" 1885version = "0.3.9"
1953source = "registry+https://github.com/rust-lang/crates.io-index" 1886source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1958,12 +1891,6 @@ dependencies = [
1958] 1891]
1959 1892
1960[[package]] 1893[[package]]
1961name = "winapi-build"
1962version = "0.1.1"
1963source = "registry+https://github.com/rust-lang/crates.io-index"
1964checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
1965
1966[[package]]
1967name = "winapi-i686-pc-windows-gnu" 1894name = "winapi-i686-pc-windows-gnu"
1968version = "0.4.0" 1895version = "0.4.0"
1969source = "registry+https://github.com/rust-lang/crates.io-index" 1896source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1975,7 +1902,7 @@ version = "0.1.5"
1975source = "registry+https://github.com/rust-lang/crates.io-index" 1902source = "registry+https://github.com/rust-lang/crates.io-index"
1976checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1903checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1977dependencies = [ 1904dependencies = [
1978 "winapi 0.3.9", 1905 "winapi",
1979] 1906]
1980 1907
1981[[package]] 1908[[package]]
@@ -1991,29 +1918,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1991checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3" 1918checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3"
1992 1919
1993[[package]] 1920[[package]]
1994name = "ws2_32-sys" 1921name = "xflags"
1995version = "0.2.1" 1922version = "0.1.3"
1996source = "registry+https://github.com/rust-lang/crates.io-index" 1923source = "registry+https://github.com/rust-lang/crates.io-index"
1997checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 1924checksum = "ddb4b07c0db813f8e2b5e1b2189ef56fcddb27a6f9ef71314dbf8cc50096a5db"
1998dependencies = [ 1925dependencies = [
1999 "winapi 0.2.8", 1926 "xflags-macros",
2000 "winapi-build", 1927]
1928
1929[[package]]
1930name = "xflags-macros"
1931version = "0.1.3"
1932source = "registry+https://github.com/rust-lang/crates.io-index"
1933checksum = "f8e168a99d6ce9d5dd0d0913f1bded279377843952dd8ff83f81b862a1dad0e1"
1934dependencies = [
1935 "proc-macro2",
2001] 1936]
2002 1937
2003[[package]] 1938[[package]]
2004name = "xshell" 1939name = "xshell"
2005version = "0.1.8" 1940version = "0.1.9"
2006source = "registry+https://github.com/rust-lang/crates.io-index" 1941source = "registry+https://github.com/rust-lang/crates.io-index"
2007checksum = "ed373ede30cea03e8c0af22f48ee1ba80efbf06fec8b4746977e6ee703878de0" 1942checksum = "6f18102278453c8f70ea5c514ac78cb4c73a0ef72a8273d17094b52f9584c0c1"
2008dependencies = [ 1943dependencies = [
2009 "xshell-macros", 1944 "xshell-macros",
2010] 1945]
2011 1946
2012[[package]] 1947[[package]]
2013name = "xshell-macros" 1948name = "xshell-macros"
2014version = "0.1.8" 1949version = "0.1.9"
2015source = "registry+https://github.com/rust-lang/crates.io-index" 1950source = "registry+https://github.com/rust-lang/crates.io-index"
2016checksum = "7f6af9f8119104697b0105989a73c578ce33f922d9d6f3dae0e8ae3d538db321" 1951checksum = "6093c460064572007f885facc70bb0ca5e40a83ea7ff8b16c1abbee56fd2e767"
2017 1952
2018[[package]] 1953[[package]]
2019name = "xtask" 1954name = "xtask"
@@ -2021,11 +1956,11 @@ version = "0.1.0"
2021dependencies = [ 1956dependencies = [
2022 "anyhow", 1957 "anyhow",
2023 "flate2", 1958 "flate2",
2024 "pico-args",
2025 "proc-macro2", 1959 "proc-macro2",
2026 "quote", 1960 "quote",
2027 "ungrammar", 1961 "ungrammar",
2028 "walkdir", 1962 "walkdir",
2029 "write-json", 1963 "write-json",
1964 "xflags",
2030 "xshell", 1965 "xshell",
2031] 1966]
diff --git a/README.md b/README.md
index a499a1651..74f944ae4 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,7 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frls-2.2E0
42* Website: https://rust-analyzer.github.io/ 42* Website: https://rust-analyzer.github.io/
43* Metrics: https://rust-analyzer.github.io/metrics/ 43* Metrics: https://rust-analyzer.github.io/metrics/
44* API docs: https://rust-analyzer.github.io/rust-analyzer/ide/ 44* API docs: https://rust-analyzer.github.io/rust-analyzer/ide/
45* Changelog: https://rust-analyzer.github.io/thisweek
45 46
46## License 47## License
47 48
diff --git a/bench_data/glorious_old_parser b/bench_data/glorious_old_parser
new file mode 100644
index 000000000..7e900dfeb
--- /dev/null
+++ b/bench_data/glorious_old_parser
@@ -0,0 +1,8562 @@
1use crate::ast::{AngleBracketedArgs, ParenthesizedArgs, AttrStyle, BareFnTy};
2use crate::ast::{GenericBound, TraitBoundModifier};
3use crate::ast::Unsafety;
4use crate::ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind};
5use crate::ast::Block;
6use crate::ast::{BlockCheckMode, CaptureBy, Movability};
7use crate::ast::{Constness, Crate};
8use crate::ast::Defaultness;
9use crate::ast::EnumDef;
10use crate::ast::{Expr, ExprKind, RangeLimits};
11use crate::ast::{Field, FnDecl, FnHeader};
12use crate::ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
13use crate::ast::{GenericParam, GenericParamKind};
14use crate::ast::GenericArg;
15use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
16use crate::ast::{Label, Lifetime, Lit, LitKind};
17use crate::ast::Local;
18use crate::ast::MacStmtStyle;
19use crate::ast::{Mac, Mac_, MacDelimiter};
20use crate::ast::{MutTy, Mutability};
21use crate::ast::{Pat, PatKind, PathSegment};
22use crate::ast::{PolyTraitRef, QSelf};
23use crate::ast::{Stmt, StmtKind};
24use crate::ast::{VariantData, StructField};
25use crate::ast::StrStyle;
26use crate::ast::SelfKind;
27use crate::ast::{TraitItem, TraitRef, TraitObjectSyntax};
28use crate::ast::{Ty, TyKind, TypeBinding, GenericBounds};
29use crate::ast::{Visibility, VisibilityKind, WhereClause, CrateSugar};
30use crate::ast::{UseTree, UseTreeKind};
31use crate::ast::{BinOpKind, UnOp};
32use crate::ast::{RangeEnd, RangeSyntax};
33use crate::{ast, attr};
34use crate::ext::base::DummyResult;
35use crate::source_map::{self, SourceMap, Spanned, respan};
36use crate::parse::{self, SeqSep, classify, token};
37use crate::parse::lexer::{TokenAndSpan, UnmatchedBrace};
38use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
39use crate::parse::token::DelimToken;
40use crate::parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership};
41use crate::util::parser::{AssocOp, Fixity};
42use crate::print::pprust;
43use crate::ptr::P;
44use crate::parse::PResult;
45use crate::ThinVec;
46use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
47use crate::symbol::{Symbol, keywords};
48
49use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
50use rustc_target::spec::abi::{self, Abi};
51use syntax_pos::{Span, MultiSpan, BytePos, FileName};
52use log::{debug, trace};
53
54use std::borrow::Cow;
55use std::cmp;
56use std::mem;
57use std::path::{self, Path, PathBuf};
58use std::slice;
59
60#[derive(Debug)]
61/// Whether the type alias or associated type is a concrete type or an existential type
62pub enum AliasKind {
63 /// Just a new name for the same type
64 Weak(P<Ty>),
65 /// Only trait impls of the type will be usable, not the actual type itself
66 Existential(GenericBounds),
67}
68
69bitflags::bitflags! {
70 struct Restrictions: u8 {
71 const STMT_EXPR = 1 << 0;
72 const NO_STRUCT_LITERAL = 1 << 1;
73 }
74}
75
76type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>);
77
78/// Specifies how to parse a path.
79#[derive(Copy, Clone, PartialEq)]
80pub enum PathStyle {
81 /// In some contexts, notably in expressions, paths with generic arguments are ambiguous
82 /// with something else. For example, in expressions `segment < ....` can be interpreted
83 /// as a comparison and `segment ( ....` can be interpreted as a function call.
84 /// In all such contexts the non-path interpretation is preferred by default for practical
85 /// reasons, but the path interpretation can be forced by the disambiguator `::`, e.g.
86 /// `x<y>` - comparisons, `x::<y>` - unambiguously a path.
87 Expr,
88 /// In other contexts, notably in types, no ambiguity exists and paths can be written
89 /// without the disambiguator, e.g., `x<y>` - unambiguously a path.
90 /// Paths with disambiguators are still accepted, `x::<Y>` - unambiguously a path too.
91 Type,
92 /// A path with generic arguments disallowed, e.g., `foo::bar::Baz`, used in imports,
93 /// visibilities or attributes.
94 /// Technically, this variant is unnecessary and e.g., `Expr` can be used instead
95 /// (paths in "mod" contexts have to be checked later for absence of generic arguments
96 /// anyway, due to macros), but it is used to avoid weird suggestions about expected
97 /// tokens when something goes wrong.
98 Mod,
99}
100
101#[derive(Clone, Copy, PartialEq, Debug)]
102enum SemiColonMode {
103 Break,
104 Ignore,
105 Comma,
106}
107
108#[derive(Clone, Copy, PartialEq, Debug)]
109enum BlockMode {
110 Break,
111 Ignore,
112}
113
114/// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
115/// dropped into the token stream, which happens while parsing the result of
116/// macro expansion). Placement of these is not as complex as I feared it would
117/// be. The important thing is to make sure that lookahead doesn't balk at
118/// `token::Interpolated` tokens.
119macro_rules! maybe_whole_expr {
120 ($p:expr) => {
121 if let token::Interpolated(nt) = $p.token.clone() {
122 match *nt {
123 token::NtExpr(ref e) | token::NtLiteral(ref e) => {
124 $p.bump();
125 return Ok((*e).clone());
126 }
127 token::NtPath(ref path) => {
128 $p.bump();
129 let span = $p.span;
130 let kind = ExprKind::Path(None, (*path).clone());
131 return Ok($p.mk_expr(span, kind, ThinVec::new()));
132 }
133 token::NtBlock(ref block) => {
134 $p.bump();
135 let span = $p.span;
136 let kind = ExprKind::Block((*block).clone(), None);
137 return Ok($p.mk_expr(span, kind, ThinVec::new()));
138 }
139 _ => {},
140 };
141 }
142 }
143}
144
145/// As maybe_whole_expr, but for things other than expressions
146macro_rules! maybe_whole {
147 ($p:expr, $constructor:ident, |$x:ident| $e:expr) => {
148 if let token::Interpolated(nt) = $p.token.clone() {
149 if let token::$constructor($x) = (*nt).clone() {
150 $p.bump();
151 return Ok($e);
152 }
153 }
154 };
155}
156
157fn maybe_append(mut lhs: Vec<Attribute>, mut rhs: Option<Vec<Attribute>>) -> Vec<Attribute> {
158 if let Some(ref mut rhs) = rhs {
159 lhs.append(rhs);
160 }
161 lhs
162}
163
164#[derive(Debug, Clone, Copy, PartialEq)]
165enum PrevTokenKind {
166 DocComment,
167 Comma,
168 Plus,
169 Interpolated,
170 Eof,
171 Ident,
172 Other,
173}
174
175trait RecoverQPath: Sized {
176 const PATH_STYLE: PathStyle = PathStyle::Expr;
177 fn to_ty(&self) -> Option<P<Ty>>;
178 fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self;
179 fn to_string(&self) -> String;
180}
181
182impl RecoverQPath for Ty {
183 const PATH_STYLE: PathStyle = PathStyle::Type;
184 fn to_ty(&self) -> Option<P<Ty>> {
185 Some(P(self.clone()))
186 }
187 fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
188 Self { span: path.span, node: TyKind::Path(qself, path), id: self.id }
189 }
190 fn to_string(&self) -> String {
191 pprust::ty_to_string(self)
192 }
193}
194
195impl RecoverQPath for Pat {
196 fn to_ty(&self) -> Option<P<Ty>> {
197 self.to_ty()
198 }
199 fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
200 Self { span: path.span, node: PatKind::Path(qself, path), id: self.id }
201 }
202 fn to_string(&self) -> String {
203 pprust::pat_to_string(self)
204 }
205}
206
207impl RecoverQPath for Expr {
208 fn to_ty(&self) -> Option<P<Ty>> {
209 self.to_ty()
210 }
211 fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
212 Self { span: path.span, node: ExprKind::Path(qself, path),
213 id: self.id, attrs: self.attrs.clone() }
214 }
215 fn to_string(&self) -> String {
216 pprust::expr_to_string(self)
217 }
218}
219
220/* ident is handled by common.rs */
221
222#[derive(Clone)]
223pub struct Parser<'a> {
224 pub sess: &'a ParseSess,
225 /// the current token:
226 pub token: token::Token,
227 /// the span of the current token:
228 pub span: Span,
229 /// the span of the previous token:
230 meta_var_span: Option<Span>,
231 pub prev_span: Span,
232 /// the previous token kind
233 prev_token_kind: PrevTokenKind,
234 restrictions: Restrictions,
235 /// Used to determine the path to externally loaded source files
236 crate directory: Directory<'a>,
237 /// Whether to parse sub-modules in other files.
238 pub recurse_into_file_modules: bool,
239 /// Name of the root module this parser originated from. If `None`, then the
240 /// name is not known. This does not change while the parser is descending
241 /// into modules, and sub-parsers have new values for this name.
242 pub root_module_name: Option<String>,
243 crate expected_tokens: Vec<TokenType>,
244 token_cursor: TokenCursor,
245 desugar_doc_comments: bool,
246 /// Whether we should configure out of line modules as we parse.
247 pub cfg_mods: bool,
248 /// This field is used to keep track of how many left angle brackets we have seen. This is
249 /// required in order to detect extra leading left angle brackets (`<` characters) and error
250 /// appropriately.
251 ///
252 /// See the comments in the `parse_path_segment` function for more details.
253 crate unmatched_angle_bracket_count: u32,
254 crate max_angle_bracket_count: u32,
255 /// List of all unclosed delimiters found by the lexer. If an entry is used for error recovery
256 /// it gets removed from here. Every entry left at the end gets emitted as an independent
257 /// error.
258 crate unclosed_delims: Vec<UnmatchedBrace>,
259}
260
261
262#[derive(Clone)]
263struct TokenCursor {
264 frame: TokenCursorFrame,
265 stack: Vec<TokenCursorFrame>,
266}
267
268#[derive(Clone)]
269struct TokenCursorFrame {
270 delim: token::DelimToken,
271 span: DelimSpan,
272 open_delim: bool,
273 tree_cursor: tokenstream::Cursor,
274 close_delim: bool,
275 last_token: LastToken,
276}
277
278/// This is used in `TokenCursorFrame` above to track tokens that are consumed
279/// by the parser, and then that's transitively used to record the tokens that
280/// each parse AST item is created with.
281///
282/// Right now this has two states, either collecting tokens or not collecting
283/// tokens. If we're collecting tokens we just save everything off into a local
284/// `Vec`. This should eventually though likely save tokens from the original
285/// token stream and just use slicing of token streams to avoid creation of a
286/// whole new vector.
287///
288/// The second state is where we're passively not recording tokens, but the last
289/// token is still tracked for when we want to start recording tokens. This
290/// "last token" means that when we start recording tokens we'll want to ensure
291/// that this, the first token, is included in the output.
292///
293/// You can find some more example usage of this in the `collect_tokens` method
294/// on the parser.
295#[derive(Clone)]
296enum LastToken {
297 Collecting(Vec<TreeAndJoint>),
298 Was(Option<TreeAndJoint>),
299}
300
301impl TokenCursorFrame {
302 fn new(sp: DelimSpan, delim: DelimToken, tts: &TokenStream) -> Self {
303 TokenCursorFrame {
304 delim: delim,
305 span: sp,
306 open_delim: delim == token::NoDelim,
307 tree_cursor: tts.clone().into_trees(),
308 close_delim: delim == token::NoDelim,
309 last_token: LastToken::Was(None),
310 }
311 }
312}
313
314impl TokenCursor {
315 fn next(&mut self) -> TokenAndSpan {
316 loop {
317 let tree = if !self.frame.open_delim {
318 self.frame.open_delim = true;
319 TokenTree::open_tt(self.frame.span.open, self.frame.delim)
320 } else if let Some(tree) = self.frame.tree_cursor.next() {
321 tree
322 } else if !self.frame.close_delim {
323 self.frame.close_delim = true;
324 TokenTree::close_tt(self.frame.span.close, self.frame.delim)
325 } else if let Some(frame) = self.stack.pop() {
326 self.frame = frame;
327 continue
328 } else {
329 return TokenAndSpan { tok: token::Eof, sp: syntax_pos::DUMMY_SP }
330 };
331
332 match self.frame.last_token {
333 LastToken::Collecting(ref mut v) => v.push(tree.clone().into()),
334 LastToken::Was(ref mut t) => *t = Some(tree.clone().into()),
335 }
336
337 match tree {
338 TokenTree::Token(sp, tok) => return TokenAndSpan { tok: tok, sp: sp },
339 TokenTree::Delimited(sp, delim, tts) => {
340 let frame = TokenCursorFrame::new(sp, delim, &tts);
341 self.stack.push(mem::replace(&mut self.frame, frame));
342 }
343 }
344 }
345 }
346
347 fn next_desugared(&mut self) -> TokenAndSpan {
348 let (sp, name) = match self.next() {
349 TokenAndSpan { sp, tok: token::DocComment(name) } => (sp, name),
350 tok => return tok,
351 };
352
353 let stripped = strip_doc_comment_decoration(&name.as_str());
354
355 // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
356 // required to wrap the text.
357 let mut num_of_hashes = 0;
358 let mut count = 0;
359 for ch in stripped.chars() {
360 count = match ch {
361 '"' => 1,
362 '#' if count > 0 => count + 1,
363 _ => 0,
364 };
365 num_of_hashes = cmp::max(num_of_hashes, count);
366 }
367
368 let delim_span = DelimSpan::from_single(sp);
369 let body = TokenTree::Delimited(
370 delim_span,
371 token::Bracket,
372 [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"), false)),
373 TokenTree::Token(sp, token::Eq),
374 TokenTree::Token(sp, token::Literal(
375 token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))
376 ]
377 .iter().cloned().collect::<TokenStream>().into(),
378 );
379
380 self.stack.push(mem::replace(&mut self.frame, TokenCursorFrame::new(
381 delim_span,
382 token::NoDelim,
383 &if doc_comment_style(&name.as_str()) == AttrStyle::Inner {
384 [TokenTree::Token(sp, token::Pound), TokenTree::Token(sp, token::Not), body]
385 .iter().cloned().collect::<TokenStream>().into()
386 } else {
387 [TokenTree::Token(sp, token::Pound), body]
388 .iter().cloned().collect::<TokenStream>().into()
389 },
390 )));
391
392 self.next()
393 }
394}
395
396#[derive(Clone, PartialEq)]
397crate enum TokenType {
398 Token(token::Token),
399 Keyword(keywords::Keyword),
400 Operator,
401 Lifetime,
402 Ident,
403 Path,
404 Type,
405 Const,
406}
407
408impl TokenType {
409 fn to_string(&self) -> String {
410 match *self {
411 TokenType::Token(ref t) => format!("`{}`", pprust::token_to_string(t)),
412 TokenType::Keyword(kw) => format!("`{}`", kw.name()),
413 TokenType::Operator => "an operator".to_string(),
414 TokenType::Lifetime => "lifetime".to_string(),
415 TokenType::Ident => "identifier".to_string(),
416 TokenType::Path => "path".to_string(),
417 TokenType::Type => "type".to_string(),
418 TokenType::Const => "const".to_string(),
419 }
420 }
421}
422
423/// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
424/// `IDENT<<u8 as Trait>::AssocTy>`.
425///
426/// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes
427/// that `IDENT` is not the ident of a fn trait.
428fn can_continue_type_after_non_fn_ident(t: &token::Token) -> bool {
429 t == &token::ModSep || t == &token::Lt ||
430 t == &token::BinOp(token::Shl)
431}
432
433/// Information about the path to a module.
434pub struct ModulePath {
435 name: String,
436 path_exists: bool,
437 pub result: Result<ModulePathSuccess, Error>,
438}
439
440pub struct ModulePathSuccess {
441 pub path: PathBuf,
442 pub directory_ownership: DirectoryOwnership,
443 warn: bool,
444}
445
446pub enum Error {
447 FileNotFoundForModule {
448 mod_name: String,
449 default_path: String,
450 secondary_path: String,
451 dir_path: String,
452 },
453 DuplicatePaths {
454 mod_name: String,
455 default_path: String,
456 secondary_path: String,
457 },
458 UselessDocComment,
459 InclusiveRangeWithNoEnd,
460}
461
462impl Error {
463 fn span_err<S: Into<MultiSpan>>(self,
464 sp: S,
465 handler: &errors::Handler) -> DiagnosticBuilder<'_> {
466 match self {
467 Error::FileNotFoundForModule { ref mod_name,
468 ref default_path,
469 ref secondary_path,
470 ref dir_path } => {
471 let mut err = struct_span_err!(handler, sp, E0583,
472 "file not found for module `{}`", mod_name);
473 err.help(&format!("name the file either {} or {} inside the directory \"{}\"",
474 default_path,
475 secondary_path,
476 dir_path));
477 err
478 }
479 Error::DuplicatePaths { ref mod_name, ref default_path, ref secondary_path } => {
480 let mut err = struct_span_err!(handler, sp, E0584,
481 "file for module `{}` found at both {} and {}",
482 mod_name,
483 default_path,
484 secondary_path);
485 err.help("delete or rename one of them to remove the ambiguity");
486 err
487 }
488 Error::UselessDocComment => {
489 let mut err = struct_span_err!(handler, sp, E0585,
490 "found a documentation comment that doesn't document anything");
491 err.help("doc comments must come before what they document, maybe a comment was \
492 intended with `//`?");
493 err
494 }
495 Error::InclusiveRangeWithNoEnd => {
496 let mut err = struct_span_err!(handler, sp, E0586,
497 "inclusive range with no end");
498 err.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)");
499 err
500 }
501 }
502 }
503}
504
505#[derive(Debug)]
506enum LhsExpr {
507 NotYetParsed,
508 AttributesParsed(ThinVec<Attribute>),
509 AlreadyParsed(P<Expr>),
510}
511
512impl From<Option<ThinVec<Attribute>>> for LhsExpr {
513 fn from(o: Option<ThinVec<Attribute>>) -> Self {
514 if let Some(attrs) = o {
515 LhsExpr::AttributesParsed(attrs)
516 } else {
517 LhsExpr::NotYetParsed
518 }
519 }
520}
521
522impl From<P<Expr>> for LhsExpr {
523 fn from(expr: P<Expr>) -> Self {
524 LhsExpr::AlreadyParsed(expr)
525 }
526}
527
528/// Creates a placeholder argument.
529fn dummy_arg(span: Span) -> Arg {
530 let ident = Ident::new(keywords::Invalid.name(), span);
531 let pat = P(Pat {
532 id: ast::DUMMY_NODE_ID,
533 node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None),
534 span,
535 });
536 let ty = Ty {
537 node: TyKind::Err,
538 span,
539 id: ast::DUMMY_NODE_ID
540 };
541 Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID }
542}
543
544#[derive(Copy, Clone, Debug)]
545enum TokenExpectType {
546 Expect,
547 NoExpect,
548}
549
550impl<'a> Parser<'a> {
551 pub fn new(sess: &'a ParseSess,
552 tokens: TokenStream,
553 directory: Option<Directory<'a>>,
554 recurse_into_file_modules: bool,
555 desugar_doc_comments: bool)
556 -> Self {
557 let mut parser = Parser {
558 sess,
559 token: token::Whitespace,
560 span: syntax_pos::DUMMY_SP,
561 prev_span: syntax_pos::DUMMY_SP,
562 meta_var_span: None,
563 prev_token_kind: PrevTokenKind::Other,
564 restrictions: Restrictions::empty(),
565 recurse_into_file_modules,
566 directory: Directory {
567 path: Cow::from(PathBuf::new()),
568 ownership: DirectoryOwnership::Owned { relative: None }
569 },
570 root_module_name: None,
571 expected_tokens: Vec::new(),
572 token_cursor: TokenCursor {
573 frame: TokenCursorFrame::new(
574 DelimSpan::dummy(),
575 token::NoDelim,
576 &tokens.into(),
577 ),
578 stack: Vec::new(),
579 },
580 desugar_doc_comments,
581 cfg_mods: true,
582 unmatched_angle_bracket_count: 0,
583 max_angle_bracket_count: 0,
584 unclosed_delims: Vec::new(),
585 };
586
587 let tok = parser.next_tok();
588 parser.token = tok.tok;
589 parser.span = tok.sp;
590
591 if let Some(directory) = directory {
592 parser.directory = directory;
593 } else if !parser.span.is_dummy() {
594 if let FileName::Real(mut path) = sess.source_map().span_to_unmapped_path(parser.span) {
595 path.pop();
596 parser.directory.path = Cow::from(path);
597 }
598 }
599
600 parser.process_potential_macro_variable();
601 parser
602 }
603
604 fn next_tok(&mut self) -> TokenAndSpan {
605 let mut next = if self.desugar_doc_comments {
606 self.token_cursor.next_desugared()
607 } else {
608 self.token_cursor.next()
609 };
610 if next.sp.is_dummy() {
611 // Tweak the location for better diagnostics, but keep syntactic context intact.
612 next.sp = self.prev_span.with_ctxt(next.sp.ctxt());
613 }
614 next
615 }
616
617 /// Converts the current token to a string using `self`'s reader.
618 pub fn this_token_to_string(&self) -> String {
619 pprust::token_to_string(&self.token)
620 }
621
622 fn token_descr(&self) -> Option<&'static str> {
623 Some(match &self.token {
624 t if t.is_special_ident() => "reserved identifier",
625 t if t.is_used_keyword() => "keyword",
626 t if t.is_unused_keyword() => "reserved keyword",
627 token::DocComment(..) => "doc comment",
628 _ => return None,
629 })
630 }
631
632 fn this_token_descr(&self) -> String {
633 if let Some(prefix) = self.token_descr() {
634 format!("{} `{}`", prefix, self.this_token_to_string())
635 } else {
636 format!("`{}`", self.this_token_to_string())
637 }
638 }
639
640 fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
641 let token_str = pprust::token_to_string(t);
642 Err(self.span_fatal(self.prev_span, &format!("unexpected token: `{}`", token_str)))
643 }
644
645 crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
646 match self.expect_one_of(&[], &[]) {
647 Err(e) => Err(e),
648 Ok(_) => unreachable!(),
649 }
650 }
651
652 /// Expects and consumes the token `t`. Signals an error if the next token is not `t`.
653 pub fn expect(&mut self, t: &token::Token) -> PResult<'a, bool /* recovered */> {
654 if self.expected_tokens.is_empty() {
655 if self.token == *t {
656 self.bump();
657 Ok(false)
658 } else {
659 let token_str = pprust::token_to_string(t);
660 let this_token_str = self.this_token_descr();
661 let mut err = self.fatal(&format!("expected `{}`, found {}",
662 token_str,
663 this_token_str));
664
665 let sp = if self.token == token::Token::Eof {
666 // EOF, don't want to point at the following char, but rather the last token
667 self.prev_span
668 } else {
669 self.sess.source_map().next_point(self.prev_span)
670 };
671 let label_exp = format!("expected `{}`", token_str);
672 match self.recover_closing_delimiter(&[t.clone()], err) {
673 Err(e) => err = e,
674 Ok(recovered) => {
675 return Ok(recovered);
676 }
677 }
678 let cm = self.sess.source_map();
679 match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
680 (Ok(ref a), Ok(ref b)) if a.line == b.line => {
681 // When the spans are in the same line, it means that the only content
682 // between them is whitespace, point only at the found token.
683 err.span_label(self.span, label_exp);
684 }
685 _ => {
686 err.span_label(sp, label_exp);
687 err.span_label(self.span, "unexpected token");
688 }
689 }
690 Err(err)
691 }
692 } else {
693 self.expect_one_of(slice::from_ref(t), &[])
694 }
695 }
696
697 fn recover_closing_delimiter(
698 &mut self,
699 tokens: &[token::Token],
700 mut err: DiagnosticBuilder<'a>,
701 ) -> PResult<'a, bool> {
702 let mut pos = None;
703 // we want to use the last closing delim that would apply
704 for (i, unmatched) in self.unclosed_delims.iter().enumerate().rev() {
705 if tokens.contains(&token::CloseDelim(unmatched.expected_delim))
706 && Some(self.span) > unmatched.unclosed_span
707 {
708 pos = Some(i);
709 }
710 }
711 match pos {
712 Some(pos) => {
713 // Recover and assume that the detected unclosed delimiter was meant for
714 // this location. Emit the diagnostic and act as if the delimiter was
715 // present for the parser's sake.
716
717 // Don't attempt to recover from this unclosed delimiter more than once.
718 let unmatched = self.unclosed_delims.remove(pos);
719 let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim));
720
721 // We want to suggest the inclusion of the closing delimiter where it makes
722 // the most sense, which is immediately after the last token:
723 //
724 // {foo(bar {}}
725 // - ^
726 // | |
727 // | help: `)` may belong here (FIXME: #58270)
728 // |
729 // unclosed delimiter
730 if let Some(sp) = unmatched.unclosed_span {
731 err.span_label(sp, "unclosed delimiter");
732 }
733 err.span_suggestion_short(
734 self.sess.source_map().next_point(self.prev_span),
735 &format!("{} may belong here", delim.to_string()),
736 delim.to_string(),
737 Applicability::MaybeIncorrect,
738 );
739 err.emit();
740 self.expected_tokens.clear(); // reduce errors
741 Ok(true)
742 }
743 _ => Err(err),
744 }
745 }
746
747 /// Expect next token to be edible or inedible token. If edible,
748 /// then consume it; if inedible, then return without consuming
749 /// anything. Signal a fatal error if next token is unexpected.
750 pub fn expect_one_of(
751 &mut self,
752 edible: &[token::Token],
753 inedible: &[token::Token],
754 ) -> PResult<'a, bool /* recovered */> {
755 fn tokens_to_string(tokens: &[TokenType]) -> String {
756 let mut i = tokens.iter();
757 // This might be a sign we need a connect method on Iterator.
758 let b = i.next()
759 .map_or(String::new(), |t| t.to_string());
760 i.enumerate().fold(b, |mut b, (i, a)| {
761 if tokens.len() > 2 && i == tokens.len() - 2 {
762 b.push_str(", or ");
763 } else if tokens.len() == 2 && i == tokens.len() - 2 {
764 b.push_str(" or ");
765 } else {
766 b.push_str(", ");
767 }
768 b.push_str(&a.to_string());
769 b
770 })
771 }
772 if edible.contains(&self.token) {
773 self.bump();
774 Ok(false)
775 } else if inedible.contains(&self.token) {
776 // leave it in the input
777 Ok(false)
778 } else {
779 let mut expected = edible.iter()
780 .map(|x| TokenType::Token(x.clone()))
781 .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
782 .chain(self.expected_tokens.iter().cloned())
783 .collect::<Vec<_>>();
784 expected.sort_by_cached_key(|x| x.to_string());
785 expected.dedup();
786 let expect = tokens_to_string(&expected[..]);
787 let actual = self.this_token_to_string();
788 let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
789 let short_expect = if expected.len() > 6 {
790 format!("{} possible tokens", expected.len())
791 } else {
792 expect.clone()
793 };
794 (format!("expected one of {}, found `{}`", expect, actual),
795 (self.sess.source_map().next_point(self.prev_span),
796 format!("expected one of {} here", short_expect)))
797 } else if expected.is_empty() {
798 (format!("unexpected token: `{}`", actual),
799 (self.prev_span, "unexpected token after this".to_string()))
800 } else {
801 (format!("expected {}, found `{}`", expect, actual),
802 (self.sess.source_map().next_point(self.prev_span),
803 format!("expected {} here", expect)))
804 };
805 let mut err = self.fatal(&msg_exp);
806 if self.token.is_ident_named("and") {
807 err.span_suggestion_short(
808 self.span,
809 "use `&&` instead of `and` for the boolean operator",
810 "&&".to_string(),
811 Applicability::MaybeIncorrect,
812 );
813 }
814 if self.token.is_ident_named("or") {
815 err.span_suggestion_short(
816 self.span,
817 "use `||` instead of `or` for the boolean operator",
818 "||".to_string(),
819 Applicability::MaybeIncorrect,
820 );
821 }
822 let sp = if self.token == token::Token::Eof {
823 // This is EOF, don't want to point at the following char, but rather the last token
824 self.prev_span
825 } else {
826 label_sp
827 };
828 match self.recover_closing_delimiter(&expected.iter().filter_map(|tt| match tt {
829 TokenType::Token(t) => Some(t.clone()),
830 _ => None,
831 }).collect::<Vec<_>>(), err) {
832 Err(e) => err = e,
833 Ok(recovered) => {
834 return Ok(recovered);
835 }
836 }
837
838 let cm = self.sess.source_map();
839 match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
840 (Ok(ref a), Ok(ref b)) if a.line == b.line => {
841 // When the spans are in the same line, it means that the only content between
842 // them is whitespace, point at the found token in that case:
843 //
844 // X | () => { syntax error };
845 // | ^^^^^ expected one of 8 possible tokens here
846 //
847 // instead of having:
848 //
849 // X | () => { syntax error };
850 // | -^^^^^ unexpected token
851 // | |
852 // | expected one of 8 possible tokens here
853 err.span_label(self.span, label_exp);
854 }
855 _ if self.prev_span == syntax_pos::DUMMY_SP => {
856 // Account for macro context where the previous span might not be
857 // available to avoid incorrect output (#54841).
858 err.span_label(self.span, "unexpected token");
859 }
860 _ => {
861 err.span_label(sp, label_exp);
862 err.span_label(self.span, "unexpected token");
863 }
864 }
865 Err(err)
866 }
867 }
868
869 /// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
870 fn interpolated_or_expr_span(&self,
871 expr: PResult<'a, P<Expr>>)
872 -> PResult<'a, (Span, P<Expr>)> {
873 expr.map(|e| {
874 if self.prev_token_kind == PrevTokenKind::Interpolated {
875 (self.prev_span, e)
876 } else {
877 (e.span, e)
878 }
879 })
880 }
881
882 fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
883 let mut err = self.struct_span_err(self.span,
884 &format!("expected identifier, found {}",
885 self.this_token_descr()));
886 if let token::Ident(ident, false) = &self.token {
887 if ident.is_reserved() && !ident.is_path_segment_keyword() &&
888 ident.name != keywords::Underscore.name()
889 {
890 err.span_suggestion(
891 self.span,
892 "you can escape reserved keywords to use them as identifiers",
893 format!("r#{}", ident),
894 Applicability::MaybeIncorrect,
895 );
896 }
897 }
898 if let Some(token_descr) = self.token_descr() {
899 err.span_label(self.span, format!("expected identifier, found {}", token_descr));
900 } else {
901 err.span_label(self.span, "expected identifier");
902 if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
903 err.span_suggestion(
904 self.span,
905 "remove this comma",
906 String::new(),
907 Applicability::MachineApplicable,
908 );
909 }
910 }
911 err
912 }
913
914 pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
915 self.parse_ident_common(true)
916 }
917
918 fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
919 match self.token {
920 token::Ident(ident, _) => {
921 if self.token.is_reserved_ident() {
922 let mut err = self.expected_ident_found();
923 if recover {
924 err.emit();
925 } else {
926 return Err(err);
927 }
928 }
929 let span = self.span;
930 self.bump();
931 Ok(Ident::new(ident.name, span))
932 }
933 _ => {
934 Err(if self.prev_token_kind == PrevTokenKind::DocComment {
935 self.span_fatal_err(self.prev_span, Error::UselessDocComment)
936 } else {
937 self.expected_ident_found()
938 })
939 }
940 }
941 }
942
943 /// Checks if the next token is `tok`, and returns `true` if so.
944 ///
945 /// This method will automatically add `tok` to `expected_tokens` if `tok` is not
946 /// encountered.
947 crate fn check(&mut self, tok: &token::Token) -> bool {
948 let is_present = self.token == *tok;
949 if !is_present { self.expected_tokens.push(TokenType::Token(tok.clone())); }
950 is_present
951 }
952
953 /// Consumes a token 'tok' if it exists. Returns whether the given token was present.
954 pub fn eat(&mut self, tok: &token::Token) -> bool {
955 let is_present = self.check(tok);
956 if is_present { self.bump() }
957 is_present
958 }
959
960 fn check_keyword(&mut self, kw: keywords::Keyword) -> bool {
961 self.expected_tokens.push(TokenType::Keyword(kw));
962 self.token.is_keyword(kw)
963 }
964
965 /// If the next token is the given keyword, eats it and returns
966 /// `true`. Otherwise, returns `false`.
967 pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
968 if self.check_keyword(kw) {
969 self.bump();
970 true
971 } else {
972 false
973 }
974 }
975
976 fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> bool {
977 if self.token.is_keyword(kw) {
978 self.bump();
979 true
980 } else {
981 false
982 }
983 }
984
985 /// If the given word is not a keyword, signals an error.
986 /// If the next token is not the given word, signals an error.
987 /// Otherwise, eats it.
988 fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, ()> {
989 if !self.eat_keyword(kw) {
990 self.unexpected()
991 } else {
992 Ok(())
993 }
994 }
995
996 fn check_ident(&mut self) -> bool {
997 if self.token.is_ident() {
998 true
999 } else {
1000 self.expected_tokens.push(TokenType::Ident);
1001 false
1002 }
1003 }
1004
1005 fn check_path(&mut self) -> bool {
1006 if self.token.is_path_start() {
1007 true
1008 } else {
1009 self.expected_tokens.push(TokenType::Path);
1010 false
1011 }
1012 }
1013
1014 fn check_type(&mut self) -> bool {
1015 if self.token.can_begin_type() {
1016 true
1017 } else {
1018 self.expected_tokens.push(TokenType::Type);
1019 false
1020 }
1021 }
1022
1023 fn check_const_arg(&mut self) -> bool {
1024 if self.token.can_begin_const_arg() {
1025 true
1026 } else {
1027 self.expected_tokens.push(TokenType::Const);
1028 false
1029 }
1030 }
1031
1032 /// Expects and consumes a `+`. if `+=` is seen, replaces it with a `=`
1033 /// and continues. If a `+` is not seen, returns `false`.
1034 ///
1035 /// This is used when token-splitting `+=` into `+`.
1036 /// See issue #47856 for an example of when this may occur.
1037 fn eat_plus(&mut self) -> bool {
1038 self.expected_tokens.push(TokenType::Token(token::BinOp(token::Plus)));
1039 match self.token {
1040 token::BinOp(token::Plus) => {
1041 self.bump();
1042 true
1043 }
1044 token::BinOpEq(token::Plus) => {
1045 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1046 self.bump_with(token::Eq, span);
1047 true
1048 }
1049 _ => false,
1050 }
1051 }
1052
1053
1054 /// Checks to see if the next token is either `+` or `+=`.
1055 /// Otherwise returns `false`.
1056 fn check_plus(&mut self) -> bool {
1057 if self.token.is_like_plus() {
1058 true
1059 }
1060 else {
1061 self.expected_tokens.push(TokenType::Token(token::BinOp(token::Plus)));
1062 false
1063 }
1064 }
1065
1066 /// Expects and consumes an `&`. If `&&` is seen, replaces it with a single
1067 /// `&` and continues. If an `&` is not seen, signals an error.
1068 fn expect_and(&mut self) -> PResult<'a, ()> {
1069 self.expected_tokens.push(TokenType::Token(token::BinOp(token::And)));
1070 match self.token {
1071 token::BinOp(token::And) => {
1072 self.bump();
1073 Ok(())
1074 }
1075 token::AndAnd => {
1076 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1077 Ok(self.bump_with(token::BinOp(token::And), span))
1078 }
1079 _ => self.unexpected()
1080 }
1081 }
1082
1083 /// Expects and consumes an `|`. If `||` is seen, replaces it with a single
1084 /// `|` and continues. If an `|` is not seen, signals an error.
1085 fn expect_or(&mut self) -> PResult<'a, ()> {
1086 self.expected_tokens.push(TokenType::Token(token::BinOp(token::Or)));
1087 match self.token {
1088 token::BinOp(token::Or) => {
1089 self.bump();
1090 Ok(())
1091 }
1092 token::OrOr => {
1093 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1094 Ok(self.bump_with(token::BinOp(token::Or), span))
1095 }
1096 _ => self.unexpected()
1097 }
1098 }
1099
1100 fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>) {
1101 match suffix {
1102 None => {/* everything ok */}
1103 Some(suf) => {
1104 let text = suf.as_str();
1105 if text.is_empty() {
1106 self.span_bug(sp, "found empty literal suffix in Some")
1107 }
1108 let msg = format!("{} with a suffix is invalid", kind);
1109 self.struct_span_err(sp, &msg)
1110 .span_label(sp, msg)
1111 .emit();
1112 }
1113 }
1114 }
1115
1116 /// Attempts to consume a `<`. If `<<` is seen, replaces it with a single
1117 /// `<` and continue. If `<-` is seen, replaces it with a single `<`
1118 /// and continue. If a `<` is not seen, returns false.
1119 ///
1120 /// This is meant to be used when parsing generics on a path to get the
1121 /// starting token.
1122 fn eat_lt(&mut self) -> bool {
1123 self.expected_tokens.push(TokenType::Token(token::Lt));
1124 let ate = match self.token {
1125 token::Lt => {
1126 self.bump();
1127 true
1128 }
1129 token::BinOp(token::Shl) => {
1130 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1131 self.bump_with(token::Lt, span);
1132 true
1133 }
1134 token::LArrow => {
1135 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1136 self.bump_with(token::BinOp(token::Minus), span);
1137 true
1138 }
1139 _ => false,
1140 };
1141
1142 if ate {
1143 // See doc comment for `unmatched_angle_bracket_count`.
1144 self.unmatched_angle_bracket_count += 1;
1145 self.max_angle_bracket_count += 1;
1146 debug!("eat_lt: (increment) count={:?}", self.unmatched_angle_bracket_count);
1147 }
1148
1149 ate
1150 }
1151
1152 fn expect_lt(&mut self) -> PResult<'a, ()> {
1153 if !self.eat_lt() {
1154 self.unexpected()
1155 } else {
1156 Ok(())
1157 }
1158 }
1159
1160 /// Expects and consumes a single `>` token. if a `>>` is seen, replaces it
1161 /// with a single `>` and continues. If a `>` is not seen, signals an error.
1162 fn expect_gt(&mut self) -> PResult<'a, ()> {
1163 self.expected_tokens.push(TokenType::Token(token::Gt));
1164 let ate = match self.token {
1165 token::Gt => {
1166 self.bump();
1167 Some(())
1168 }
1169 token::BinOp(token::Shr) => {
1170 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1171 Some(self.bump_with(token::Gt, span))
1172 }
1173 token::BinOpEq(token::Shr) => {
1174 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1175 Some(self.bump_with(token::Ge, span))
1176 }
1177 token::Ge => {
1178 let span = self.span.with_lo(self.span.lo() + BytePos(1));
1179 Some(self.bump_with(token::Eq, span))
1180 }
1181 _ => None,
1182 };
1183
1184 match ate {
1185 Some(_) => {
1186 // See doc comment for `unmatched_angle_bracket_count`.
1187 if self.unmatched_angle_bracket_count > 0 {
1188 self.unmatched_angle_bracket_count -= 1;
1189 debug!("expect_gt: (decrement) count={:?}", self.unmatched_angle_bracket_count);
1190 }
1191
1192 Ok(())
1193 },
1194 None => self.unexpected(),
1195 }
1196 }
1197
1198 /// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
1199 /// passes through any errors encountered. Used for error recovery.
1200 fn eat_to_tokens(&mut self, kets: &[&token::Token]) {
1201 let handler = self.diagnostic();
1202
1203 if let Err(ref mut err) = self.parse_seq_to_before_tokens(kets,
1204 SeqSep::none(),
1205 TokenExpectType::Expect,
1206 |p| Ok(p.parse_token_tree())) {
1207 handler.cancel(err);
1208 }
1209 }
1210
1211 /// Parses a sequence, including the closing delimiter. The function
1212 /// `f` must consume tokens until reaching the next separator or
1213 /// closing bracket.
1214 pub fn parse_seq_to_end<T, F>(&mut self,
1215 ket: &token::Token,
1216 sep: SeqSep,
1217 f: F)
1218 -> PResult<'a, Vec<T>> where
1219 F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
1220 {
1221 let (val, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
1222 if !recovered {
1223 self.bump();
1224 }
1225 Ok(val)
1226 }
1227
1228 /// Parses a sequence, not including the closing delimiter. The function
1229 /// `f` must consume tokens until reaching the next separator or
1230 /// closing bracket.
1231 pub fn parse_seq_to_before_end<T, F>(
1232 &mut self,
1233 ket: &token::Token,
1234 sep: SeqSep,
1235 f: F,
1236 ) -> PResult<'a, (Vec<T>, bool)>
1237 where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>
1238 {
1239 self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
1240 }
1241
1242 fn parse_seq_to_before_tokens<T, F>(
1243 &mut self,
1244 kets: &[&token::Token],
1245 sep: SeqSep,
1246 expect: TokenExpectType,
1247 mut f: F,
1248 ) -> PResult<'a, (Vec<T>, bool /* recovered */)>
1249 where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>
1250 {
1251 let mut first = true;
1252 let mut recovered = false;
1253 let mut v = vec![];
1254 while !kets.iter().any(|k| {
1255 match expect {
1256 TokenExpectType::Expect => self.check(k),
1257 TokenExpectType::NoExpect => self.token == **k,
1258 }
1259 }) {
1260 match self.token {
1261 token::CloseDelim(..) | token::Eof => break,
1262 _ => {}
1263 };
1264 if let Some(ref t) = sep.sep {
1265 if first {
1266 first = false;
1267 } else {
1268 match self.expect(t) {
1269 Ok(false) => {}
1270 Ok(true) => {
1271 recovered = true;
1272 break;
1273 }
1274 Err(mut e) => {
1275 // Attempt to keep parsing if it was a similar separator
1276 if let Some(ref tokens) = t.similar_tokens() {
1277 if tokens.contains(&self.token) {
1278 self.bump();
1279 }
1280 }
1281 e.emit();
1282 // Attempt to keep parsing if it was an omitted separator
1283 match f(self) {
1284 Ok(t) => {
1285 v.push(t);
1286 continue;
1287 },
1288 Err(mut e) => {
1289 e.cancel();
1290 break;
1291 }
1292 }
1293 }
1294 }
1295 }
1296 }
1297 if sep.trailing_sep_allowed && kets.iter().any(|k| {
1298 match expect {
1299 TokenExpectType::Expect => self.check(k),
1300 TokenExpectType::NoExpect => self.token == **k,
1301 }
1302 }) {
1303 break;
1304 }
1305
1306 let t = f(self)?;
1307 v.push(t);
1308 }
1309
1310 Ok((v, recovered))
1311 }
1312
1313 /// Parses a sequence, including the closing delimiter. The function
1314 /// `f` must consume tokens until reaching the next separator or
1315 /// closing bracket.
1316 fn parse_unspanned_seq<T, F>(
1317 &mut self,
1318 bra: &token::Token,
1319 ket: &token::Token,
1320 sep: SeqSep,
1321 f: F,
1322 ) -> PResult<'a, Vec<T>> where
1323 F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
1324 {
1325 self.expect(bra)?;
1326 let (result, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
1327 if !recovered {
1328 self.eat(ket);
1329 }
1330 Ok(result)
1331 }
1332
1333 /// Advance the parser by one token
1334 pub fn bump(&mut self) {
1335 if self.prev_token_kind == PrevTokenKind::Eof {
1336 // Bumping after EOF is a bad sign, usually an infinite loop.
1337 self.bug("attempted to bump the parser past EOF (may be stuck in a loop)");
1338 }
1339
1340 self.prev_span = self.meta_var_span.take().unwrap_or(self.span);
1341
1342 // Record last token kind for possible error recovery.
1343 self.prev_token_kind = match self.token {
1344 token::DocComment(..) => PrevTokenKind::DocComment,
1345 token::Comma => PrevTokenKind::Comma,
1346 token::BinOp(token::Plus) => PrevTokenKind::Plus,
1347 token::Interpolated(..) => PrevTokenKind::Interpolated,
1348 token::Eof => PrevTokenKind::Eof,
1349 token::Ident(..) => PrevTokenKind::Ident,
1350 _ => PrevTokenKind::Other,
1351 };
1352
1353 let next = self.next_tok();
1354 self.span = next.sp;
1355 self.token = next.tok;
1356 self.expected_tokens.clear();
1357 // check after each token
1358 self.process_potential_macro_variable();
1359 }
1360
1361 /// Advance the parser using provided token as a next one. Use this when
1362 /// consuming a part of a token. For example a single `<` from `<<`.
1363 fn bump_with(&mut self, next: token::Token, span: Span) {
1364 self.prev_span = self.span.with_hi(span.lo());
1365 // It would be incorrect to record the kind of the current token, but
1366 // fortunately for tokens currently using `bump_with`, the
1367 // prev_token_kind will be of no use anyway.
1368 self.prev_token_kind = PrevTokenKind::Other;
1369 self.span = span;
1370 self.token = next;
1371 self.expected_tokens.clear();
1372 }
1373
1374 pub fn look_ahead<R, F>(&self, dist: usize, f: F) -> R where
1375 F: FnOnce(&token::Token) -> R,
1376 {
1377 if dist == 0 {
1378 return f(&self.token)
1379 }
1380
1381 f(&match self.token_cursor.frame.tree_cursor.look_ahead(dist - 1) {
1382 Some(tree) => match tree {
1383 TokenTree::Token(_, tok) => tok,
1384 TokenTree::Delimited(_, delim, _) => token::OpenDelim(delim),
1385 },
1386 None => token::CloseDelim(self.token_cursor.frame.delim),
1387 })
1388 }
1389
1390 fn look_ahead_span(&self, dist: usize) -> Span {
1391 if dist == 0 {
1392 return self.span
1393 }
1394
1395 match self.token_cursor.frame.tree_cursor.look_ahead(dist - 1) {
1396 Some(TokenTree::Token(span, _)) => span,
1397 Some(TokenTree::Delimited(span, ..)) => span.entire(),
1398 None => self.look_ahead_span(dist - 1),
1399 }
1400 }
1401 pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
1402 self.sess.span_diagnostic.struct_span_fatal(self.span, m)
1403 }
1404 pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
1405 self.sess.span_diagnostic.struct_span_fatal(sp, m)
1406 }
1407 fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
1408 err.span_err(sp, self.diagnostic())
1409 }
1410 fn bug(&self, m: &str) -> ! {
1411 self.sess.span_diagnostic.span_bug(self.span, m)
1412 }
1413 fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
1414 self.sess.span_diagnostic.span_err(sp, m)
1415 }
1416 fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
1417 self.sess.span_diagnostic.struct_span_err(sp, m)
1418 }
1419 crate fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
1420 self.sess.span_diagnostic.span_bug(sp, m)
1421 }
1422
1423 fn cancel(&self, err: &mut DiagnosticBuilder<'_>) {
1424 self.sess.span_diagnostic.cancel(err)
1425 }
1426
1427 crate fn diagnostic(&self) -> &'a errors::Handler {
1428 &self.sess.span_diagnostic
1429 }
1430
1431 /// Is the current token one of the keywords that signals a bare function type?
1432 fn token_is_bare_fn_keyword(&mut self) -> bool {
1433 self.check_keyword(keywords::Fn) ||
1434 self.check_keyword(keywords::Unsafe) ||
1435 self.check_keyword(keywords::Extern)
1436 }
1437
1438 /// Parses a `TyKind::BareFn` type.
1439 fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a, TyKind> {
1440 /*
1441
1442 [unsafe] [extern "ABI"] fn (S) -> T
1443 ^~~~^ ^~~~^ ^~^ ^
1444 | | | |
1445 | | | Return type
1446 | | Argument types
1447 | |
1448 | ABI
1449 Function Style
1450 */
1451
1452 let unsafety = self.parse_unsafety();
1453 let abi = if self.eat_keyword(keywords::Extern) {
1454 self.parse_opt_abi()?.unwrap_or(Abi::C)
1455 } else {
1456 Abi::Rust
1457 };
1458
1459 self.expect_keyword(keywords::Fn)?;
1460 let (inputs, variadic) = self.parse_fn_args(false, true)?;
1461 let ret_ty = self.parse_ret_ty(false)?;
1462 let decl = P(FnDecl {
1463 inputs,
1464 output: ret_ty,
1465 variadic,
1466 });
1467 Ok(TyKind::BareFn(P(BareFnTy {
1468 abi,
1469 unsafety,
1470 generic_params,
1471 decl,
1472 })))
1473 }
1474
1475 /// Parses asyncness: `async` or nothing.
1476 fn parse_asyncness(&mut self) -> IsAsync {
1477 if self.eat_keyword(keywords::Async) {
1478 IsAsync::Async {
1479 closure_id: ast::DUMMY_NODE_ID,
1480 return_impl_trait_id: ast::DUMMY_NODE_ID,
1481 }
1482 } else {
1483 IsAsync::NotAsync
1484 }
1485 }
1486
1487 /// Parses unsafety: `unsafe` or nothing.
1488 fn parse_unsafety(&mut self) -> Unsafety {
1489 if self.eat_keyword(keywords::Unsafe) {
1490 Unsafety::Unsafe
1491 } else {
1492 Unsafety::Normal
1493 }
1494 }
1495
1496 /// Parses the items in a trait declaration.
1497 pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
1498 maybe_whole!(self, NtTraitItem, |x| x);
1499 let attrs = self.parse_outer_attributes()?;
1500 let (mut item, tokens) = self.collect_tokens(|this| {
1501 this.parse_trait_item_(at_end, attrs)
1502 })?;
1503 // See `parse_item` for why this clause is here.
1504 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
1505 item.tokens = Some(tokens);
1506 }
1507 Ok(item)
1508 }
1509
1510 fn parse_trait_item_(&mut self,
1511 at_end: &mut bool,
1512 mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
1513 let lo = self.span;
1514
1515 let (name, node, generics) = if self.eat_keyword(keywords::Type) {
1516 self.parse_trait_item_assoc_ty()?
1517 } else if self.is_const_item() {
1518 self.expect_keyword(keywords::Const)?;
1519 let ident = self.parse_ident()?;
1520 self.expect(&token::Colon)?;
1521 let ty = self.parse_ty()?;
1522 let default = if self.eat(&token::Eq) {
1523 let expr = self.parse_expr()?;
1524 self.expect(&token::Semi)?;
1525 Some(expr)
1526 } else {
1527 self.expect(&token::Semi)?;
1528 None
1529 };
1530 (ident, TraitItemKind::Const(ty, default), ast::Generics::default())
1531 } else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
1532 // trait item macro.
1533 (keywords::Invalid.ident(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
1534 } else {
1535 let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
1536
1537 let ident = self.parse_ident()?;
1538 let mut generics = self.parse_generics()?;
1539
1540 let d = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
1541 // This is somewhat dubious; We don't want to allow
1542 // argument names to be left off if there is a
1543 // definition...
1544
1545 // We don't allow argument names to be left off in edition 2018.
1546 p.parse_arg_general(p.span.rust_2018(), true)
1547 })?;
1548 generics.where_clause = self.parse_where_clause()?;
1549
1550 let sig = ast::MethodSig {
1551 header: FnHeader {
1552 unsafety,
1553 constness,
1554 abi,
1555 asyncness,
1556 },
1557 decl: d,
1558 };
1559
1560 let body = match self.token {
1561 token::Semi => {
1562 self.bump();
1563 *at_end = true;
1564 debug!("parse_trait_methods(): parsing required method");
1565 None
1566 }
1567 token::OpenDelim(token::Brace) => {
1568 debug!("parse_trait_methods(): parsing provided method");
1569 *at_end = true;
1570 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1571 attrs.extend(inner_attrs.iter().cloned());
1572 Some(body)
1573 }
1574 token::Interpolated(ref nt) => {
1575 match **nt {
1576 token::NtBlock(..) => {
1577 *at_end = true;
1578 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1579 attrs.extend(inner_attrs.iter().cloned());
1580 Some(body)
1581 }
1582 _ => {
1583 let token_str = self.this_token_descr();
1584 let mut err = self.fatal(&format!("expected `;` or `{{`, found {}",
1585 token_str));
1586 err.span_label(self.span, "expected `;` or `{`");
1587 return Err(err);
1588 }
1589 }
1590 }
1591 _ => {
1592 let token_str = self.this_token_descr();
1593 let mut err = self.fatal(&format!("expected `;` or `{{`, found {}",
1594 token_str));
1595 err.span_label(self.span, "expected `;` or `{`");
1596 return Err(err);
1597 }
1598 };
1599 (ident, ast::TraitItemKind::Method(sig, body), generics)
1600 };
1601
1602 Ok(TraitItem {
1603 id: ast::DUMMY_NODE_ID,
1604 ident: name,
1605 attrs,
1606 generics,
1607 node,
1608 span: lo.to(self.prev_span),
1609 tokens: None,
1610 })
1611 }
1612
1613 /// Parses an optional return type `[ -> TY ]` in a function declaration.
1614 fn parse_ret_ty(&mut self, allow_plus: bool) -> PResult<'a, FunctionRetTy> {
1615 if self.eat(&token::RArrow) {
1616 Ok(FunctionRetTy::Ty(self.parse_ty_common(allow_plus, true)?))
1617 } else {
1618 Ok(FunctionRetTy::Default(self.span.shrink_to_lo()))
1619 }
1620 }
1621
1622 /// Parses a type.
1623 pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
1624 self.parse_ty_common(true, true)
1625 }
1626
1627 /// Parses a type in restricted contexts where `+` is not permitted.
1628 ///
1629 /// Example 1: `&'a TYPE`
1630 /// `+` is prohibited to maintain operator priority (P(+) < P(&)).
1631 /// Example 2: `value1 as TYPE + value2`
1632 /// `+` is prohibited to avoid interactions with expression grammar.
1633 fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
1634 self.parse_ty_common(false, true)
1635 }
1636
1637 fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
1638 -> PResult<'a, P<Ty>> {
1639 maybe_whole!(self, NtTy, |x| x);
1640
1641 let lo = self.span;
1642 let mut impl_dyn_multi = false;
1643 let node = if self.eat(&token::OpenDelim(token::Paren)) {
1644 // `(TYPE)` is a parenthesized type.
1645 // `(TYPE,)` is a tuple with a single field of type TYPE.
1646 let mut ts = vec![];
1647 let mut last_comma = false;
1648 while self.token != token::CloseDelim(token::Paren) {
1649 ts.push(self.parse_ty()?);
1650 if self.eat(&token::Comma) {
1651 last_comma = true;
1652 } else {
1653 last_comma = false;
1654 break;
1655 }
1656 }
1657 let trailing_plus = self.prev_token_kind == PrevTokenKind::Plus;
1658 self.expect(&token::CloseDelim(token::Paren))?;
1659
1660 if ts.len() == 1 && !last_comma {
1661 let ty = ts.into_iter().nth(0).unwrap().into_inner();
1662 let maybe_bounds = allow_plus && self.token.is_like_plus();
1663 match ty.node {
1664 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
1665 TyKind::Path(None, ref path) if maybe_bounds => {
1666 self.parse_remaining_bounds(Vec::new(), path.clone(), lo, true)?
1667 }
1668 TyKind::TraitObject(ref bounds, TraitObjectSyntax::None)
1669 if maybe_bounds && bounds.len() == 1 && !trailing_plus => {
1670 let path = match bounds[0] {
1671 GenericBound::Trait(ref pt, ..) => pt.trait_ref.path.clone(),
1672 GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"),
1673 };
1674 self.parse_remaining_bounds(Vec::new(), path, lo, true)?
1675 }
1676 // `(TYPE)`
1677 _ => TyKind::Paren(P(ty))
1678 }
1679 } else {
1680 TyKind::Tup(ts)
1681 }
1682 } else if self.eat(&token::Not) {
1683 // Never type `!`
1684 TyKind::Never
1685 } else if self.eat(&token::BinOp(token::Star)) {
1686 // Raw pointer
1687 TyKind::Ptr(self.parse_ptr()?)
1688 } else if self.eat(&token::OpenDelim(token::Bracket)) {
1689 // Array or slice
1690 let t = self.parse_ty()?;
1691 // Parse optional `; EXPR` in `[TYPE; EXPR]`
1692 let t = match self.maybe_parse_fixed_length_of_vec()? {
1693 None => TyKind::Slice(t),
1694 Some(length) => TyKind::Array(t, AnonConst {
1695 id: ast::DUMMY_NODE_ID,
1696 value: length,
1697 }),
1698 };
1699 self.expect(&token::CloseDelim(token::Bracket))?;
1700 t
1701 } else if self.check(&token::BinOp(token::And)) || self.check(&token::AndAnd) {
1702 // Reference
1703 self.expect_and()?;
1704 self.parse_borrowed_pointee()?
1705 } else if self.eat_keyword_noexpect(keywords::Typeof) {
1706 // `typeof(EXPR)`
1707 // In order to not be ambiguous, the type must be surrounded by parens.
1708 self.expect(&token::OpenDelim(token::Paren))?;
1709 let e = AnonConst {
1710 id: ast::DUMMY_NODE_ID,
1711 value: self.parse_expr()?,
1712 };
1713 self.expect(&token::CloseDelim(token::Paren))?;
1714 TyKind::Typeof(e)
1715 } else if self.eat_keyword(keywords::Underscore) {
1716 // A type to be inferred `_`
1717 TyKind::Infer
1718 } else if self.token_is_bare_fn_keyword() {
1719 // Function pointer type
1720 self.parse_ty_bare_fn(Vec::new())?
1721 } else if self.check_keyword(keywords::For) {
1722 // Function pointer type or bound list (trait object type) starting with a poly-trait.
1723 // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
1724 // `for<'lt> Trait1<'lt> + Trait2 + 'a`
1725 let lo = self.span;
1726 let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
1727 if self.token_is_bare_fn_keyword() {
1728 self.parse_ty_bare_fn(lifetime_defs)?
1729 } else {
1730 let path = self.parse_path(PathStyle::Type)?;
1731 let parse_plus = allow_plus && self.check_plus();
1732 self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)?
1733 }
1734 } else if self.eat_keyword(keywords::Impl) {
1735 // Always parse bounds greedily for better error recovery.
1736 let bounds = self.parse_generic_bounds(None)?;
1737 impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
1738 TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
1739 } else if self.check_keyword(keywords::Dyn) &&
1740 (self.span.rust_2018() ||
1741 self.look_ahead(1, |t| t.can_begin_bound() &&
1742 !can_continue_type_after_non_fn_ident(t))) {
1743 self.bump(); // `dyn`
1744 // Always parse bounds greedily for better error recovery.
1745 let bounds = self.parse_generic_bounds(None)?;
1746 impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
1747 TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
1748 } else if self.check(&token::Question) ||
1749 self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus()) {
1750 // Bound list (trait object type)
1751 TyKind::TraitObject(self.parse_generic_bounds_common(allow_plus, None)?,
1752 TraitObjectSyntax::None)
1753 } else if self.eat_lt() {
1754 // Qualified path
1755 let (qself, path) = self.parse_qpath(PathStyle::Type)?;
1756 TyKind::Path(Some(qself), path)
1757 } else if self.token.is_path_start() {
1758 // Simple path
1759 let path = self.parse_path(PathStyle::Type)?;
1760 if self.eat(&token::Not) {
1761 // Macro invocation in type position
1762 let (delim, tts) = self.expect_delimited_token_tree()?;
1763 let node = Mac_ { path, tts, delim };
1764 TyKind::Mac(respan(lo.to(self.prev_span), node))
1765 } else {
1766 // Just a type path or bound list (trait object type) starting with a trait.
1767 // `Type`
1768 // `Trait1 + Trait2 + 'a`
1769 if allow_plus && self.check_plus() {
1770 self.parse_remaining_bounds(Vec::new(), path, lo, true)?
1771 } else {
1772 TyKind::Path(None, path)
1773 }
1774 }
1775 } else {
1776 let msg = format!("expected type, found {}", self.this_token_descr());
1777 return Err(self.fatal(&msg));
1778 };
1779
1780 let span = lo.to(self.prev_span);
1781 let ty = Ty { node, span, id: ast::DUMMY_NODE_ID };
1782
1783 // Try to recover from use of `+` with incorrect priority.
1784 self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty);
1785 self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
1786 let ty = self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)?;
1787
1788 Ok(P(ty))
1789 }
1790
1791 fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path,
1792 lo: Span, parse_plus: bool) -> PResult<'a, TyKind> {
1793 let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
1794 let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
1795 if parse_plus {
1796 self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
1797 bounds.append(&mut self.parse_generic_bounds(None)?);
1798 }
1799 Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
1800 }
1801
1802 fn maybe_report_ambiguous_plus(&mut self, allow_plus: bool, impl_dyn_multi: bool, ty: &Ty) {
1803 if !allow_plus && impl_dyn_multi {
1804 let sum_with_parens = format!("({})", pprust::ty_to_string(&ty));
1805 self.struct_span_err(ty.span, "ambiguous `+` in a type")
1806 .span_suggestion(
1807 ty.span,
1808 "use parentheses to disambiguate",
1809 sum_with_parens,
1810 Applicability::MachineApplicable
1811 ).emit();
1812 }
1813 }
1814
1815 fn maybe_recover_from_bad_type_plus(&mut self, allow_plus: bool, ty: &Ty) -> PResult<'a, ()> {
1816 // Do not add `+` to expected tokens.
1817 if !allow_plus || !self.token.is_like_plus() {
1818 return Ok(())
1819 }
1820
1821 self.bump(); // `+`
1822 let bounds = self.parse_generic_bounds(None)?;
1823 let sum_span = ty.span.to(self.prev_span);
1824
1825 let mut err = struct_span_err!(self.sess.span_diagnostic, sum_span, E0178,
1826 "expected a path on the left-hand side of `+`, not `{}`", pprust::ty_to_string(ty));
1827
1828 match ty.node {
1829 TyKind::Rptr(ref lifetime, ref mut_ty) => {
1830 let sum_with_parens = pprust::to_string(|s| {
1831 use crate::print::pprust::PrintState;
1832
1833 s.s.word("&")?;
1834 s.print_opt_lifetime(lifetime)?;
1835 s.print_mutability(mut_ty.mutbl)?;
1836 s.popen()?;
1837 s.print_type(&mut_ty.ty)?;
1838 s.print_type_bounds(" +", &bounds)?;
1839 s.pclose()
1840 });
1841 err.span_suggestion(
1842 sum_span,
1843 "try adding parentheses",
1844 sum_with_parens,
1845 Applicability::MachineApplicable
1846 );
1847 }
1848 TyKind::Ptr(..) | TyKind::BareFn(..) => {
1849 err.span_label(sum_span, "perhaps you forgot parentheses?");
1850 }
1851 _ => {
1852 err.span_label(sum_span, "expected a path");
1853 },
1854 }
1855 err.emit();
1856 Ok(())
1857 }
1858
1859 // Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
1860 fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T, allow_recovery: bool)
1861 -> PResult<'a, T> {
1862 // Do not add `::` to expected tokens.
1863 if !allow_recovery || self.token != token::ModSep {
1864 return Ok(base);
1865 }
1866 let ty = match base.to_ty() {
1867 Some(ty) => ty,
1868 None => return Ok(base),
1869 };
1870
1871 self.bump(); // `::`
1872 let mut segments = Vec::new();
1873 self.parse_path_segments(&mut segments, T::PATH_STYLE, true)?;
1874
1875 let span = ty.span.to(self.prev_span);
1876 let path_span = span.to(span); // use an empty path since `position` == 0
1877 let recovered = base.to_recovered(
1878 Some(QSelf { ty, path_span, position: 0 }),
1879 ast::Path { segments, span },
1880 );
1881
1882 self.diagnostic()
1883 .struct_span_err(span, "missing angle brackets in associated item path")
1884 .span_suggestion( // this is a best-effort recovery
1885 span, "try", recovered.to_string(), Applicability::MaybeIncorrect
1886 ).emit();
1887
1888 Ok(recovered)
1889 }
1890
1891 fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
1892 let opt_lifetime = if self.check_lifetime() { Some(self.expect_lifetime()) } else { None };
1893 let mutbl = self.parse_mutability();
1894 let ty = self.parse_ty_no_plus()?;
1895 return Ok(TyKind::Rptr(opt_lifetime, MutTy { ty: ty, mutbl: mutbl }));
1896 }
1897
1898 fn parse_ptr(&mut self) -> PResult<'a, MutTy> {
1899 let mutbl = if self.eat_keyword(keywords::Mut) {
1900 Mutability::Mutable
1901 } else if self.eat_keyword(keywords::Const) {
1902 Mutability::Immutable
1903 } else {
1904 let span = self.prev_span;
1905 let msg = "expected mut or const in raw pointer type";
1906 self.struct_span_err(span, msg)
1907 .span_label(span, msg)
1908 .help("use `*mut T` or `*const T` as appropriate")
1909 .emit();
1910 Mutability::Immutable
1911 };
1912 let t = self.parse_ty_no_plus()?;
1913 Ok(MutTy { ty: t, mutbl: mutbl })
1914 }
1915
1916 fn is_named_argument(&mut self) -> bool {
1917 let offset = match self.token {
1918 token::Interpolated(ref nt) => match **nt {
1919 token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
1920 _ => 0,
1921 }
1922 token::BinOp(token::And) | token::AndAnd => 1,
1923 _ if self.token.is_keyword(keywords::Mut) => 1,
1924 _ => 0,
1925 };
1926
1927 self.look_ahead(offset, |t| t.is_ident()) &&
1928 self.look_ahead(offset + 1, |t| t == &token::Colon)
1929 }
1930
1931 /// Skips unexpected attributes and doc comments in this position and emits an appropriate
1932 /// error.
1933 fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
1934 if let token::DocComment(_) = self.token {
1935 let mut err = self.diagnostic().struct_span_err(
1936 self.span,
1937 &format!("documentation comments cannot be applied to {}", applied_to),
1938 );
1939 err.span_label(self.span, "doc comments are not allowed here");
1940 err.emit();
1941 self.bump();
1942 } else if self.token == token::Pound && self.look_ahead(1, |t| {
1943 *t == token::OpenDelim(token::Bracket)
1944 }) {
1945 let lo = self.span;
1946 // Skip every token until next possible arg.
1947 while self.token != token::CloseDelim(token::Bracket) {
1948 self.bump();
1949 }
1950 let sp = lo.to(self.span);
1951 self.bump();
1952 let mut err = self.diagnostic().struct_span_err(
1953 sp,
1954 &format!("attributes cannot be applied to {}", applied_to),
1955 );
1956 err.span_label(sp, "attributes are not allowed here");
1957 err.emit();
1958 }
1959 }
1960
1961 /// This version of parse arg doesn't necessarily require identifier names.
1962 fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool) -> PResult<'a, Arg> {
1963 maybe_whole!(self, NtArg, |x| x);
1964
1965 if let Ok(Some(_)) = self.parse_self_arg() {
1966 let mut err = self.struct_span_err(self.prev_span,
1967 "unexpected `self` argument in function");
1968 err.span_label(self.prev_span,
1969 "`self` is only valid as the first argument of an associated function");
1970 return Err(err);
1971 }
1972
1973 let (pat, ty) = if require_name || self.is_named_argument() {
1974 debug!("parse_arg_general parse_pat (require_name:{})",
1975 require_name);
1976 self.eat_incorrect_doc_comment("method arguments");
1977 let pat = self.parse_pat(Some("argument name"))?;
1978
1979 if let Err(mut err) = self.expect(&token::Colon) {
1980 // If we find a pattern followed by an identifier, it could be an (incorrect)
1981 // C-style parameter declaration.
1982 if self.check_ident() && self.look_ahead(1, |t| {
1983 *t == token::Comma || *t == token::CloseDelim(token::Paren)
1984 }) {
1985 let ident = self.parse_ident().unwrap();
1986 let span = pat.span.with_hi(ident.span.hi());
1987
1988 err.span_suggestion(
1989 span,
1990 "declare the type after the parameter binding",
1991 String::from("<identifier>: <type>"),
1992 Applicability::HasPlaceholders,
1993 );
1994 } else if require_name && is_trait_item {
1995 if let PatKind::Ident(_, ident, _) = pat.node {
1996 err.span_suggestion(
1997 pat.span,
1998 "explicitly ignore parameter",
1999 format!("_: {}", ident),
2000 Applicability::MachineApplicable,
2001 );
2002 }
2003
2004 err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
2005 }
2006
2007 return Err(err);
2008 }
2009
2010 self.eat_incorrect_doc_comment("a method argument's type");
2011 (pat, self.parse_ty()?)
2012 } else {
2013 debug!("parse_arg_general ident_to_pat");
2014 let parser_snapshot_before_ty = self.clone();
2015 self.eat_incorrect_doc_comment("a method argument's type");
2016 let mut ty = self.parse_ty();
2017 if ty.is_ok() && self.token != token::Comma &&
2018 self.token != token::CloseDelim(token::Paren) {
2019 // This wasn't actually a type, but a pattern looking like a type,
2020 // so we are going to rollback and re-parse for recovery.
2021 ty = self.unexpected();
2022 }
2023 match ty {
2024 Ok(ty) => {
2025 let ident = Ident::new(keywords::Invalid.name(), self.prev_span);
2026 let pat = P(Pat {
2027 id: ast::DUMMY_NODE_ID,
2028 node: PatKind::Ident(
2029 BindingMode::ByValue(Mutability::Immutable), ident, None),
2030 span: ty.span,
2031 });
2032 (pat, ty)
2033 }
2034 Err(mut err) => {
2035 // Recover from attempting to parse the argument as a type without pattern.
2036 err.cancel();
2037 mem::replace(self, parser_snapshot_before_ty);
2038 let pat = self.parse_pat(Some("argument name"))?;
2039 self.expect(&token::Colon)?;
2040 let ty = self.parse_ty()?;
2041
2042 let mut err = self.diagnostic().struct_span_err_with_code(
2043 pat.span,
2044 "patterns aren't allowed in methods without bodies",
2045 DiagnosticId::Error("E0642".into()),
2046 );
2047 err.span_suggestion_short(
2048 pat.span,
2049 "give this argument a name or use an underscore to ignore it",
2050 "_".to_owned(),
2051 Applicability::MachineApplicable,
2052 );
2053 err.emit();
2054
2055 // Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
2056 let pat = P(Pat {
2057 node: PatKind::Wild,
2058 span: pat.span,
2059 id: ast::DUMMY_NODE_ID
2060 });
2061 (pat, ty)
2062 }
2063 }
2064 };
2065
2066 Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID })
2067 }
2068
2069 /// Parses a single function argument.
2070 crate fn parse_arg(&mut self) -> PResult<'a, Arg> {
2071 self.parse_arg_general(true, false)
2072 }
2073
2074 /// Parses an argument in a lambda header (e.g., `|arg, arg|`).
2075 fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
2076 let pat = self.parse_pat(Some("argument name"))?;
2077 let t = if self.eat(&token::Colon) {
2078 self.parse_ty()?
2079 } else {
2080 P(Ty {
2081 id: ast::DUMMY_NODE_ID,
2082 node: TyKind::Infer,
2083 span: self.prev_span,
2084 })
2085 };
2086 Ok(Arg {
2087 ty: t,
2088 pat,
2089 id: ast::DUMMY_NODE_ID
2090 })
2091 }
2092
2093 fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>>> {
2094 if self.eat(&token::Semi) {
2095 Ok(Some(self.parse_expr()?))
2096 } else {
2097 Ok(None)
2098 }
2099 }
2100
2101 /// Matches `token_lit = LIT_INTEGER | ...`.
2102 fn parse_lit_token(&mut self) -> PResult<'a, LitKind> {
2103 let out = match self.token {
2104 token::Interpolated(ref nt) => match **nt {
2105 token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node {
2106 ExprKind::Lit(ref lit) => { lit.node.clone() }
2107 _ => { return self.unexpected_last(&self.token); }
2108 },
2109 _ => { return self.unexpected_last(&self.token); }
2110 },
2111 token::Literal(lit, suf) => {
2112 let diag = Some((self.span, &self.sess.span_diagnostic));
2113 let (suffix_illegal, result) = parse::lit_token(lit, suf, diag);
2114
2115 if suffix_illegal {
2116 let sp = self.span;
2117 self.expect_no_suffix(sp, lit.literal_name(), suf)
2118 }
2119
2120 result.unwrap()
2121 }
2122 token::Dot if self.look_ahead(1, |t| match t {
2123 token::Literal(parse::token::Lit::Integer(_) , _) => true,
2124 _ => false,
2125 }) => { // recover from `let x = .4;`
2126 let lo = self.span;
2127 self.bump();
2128 if let token::Literal(
2129 parse::token::Lit::Integer(val),
2130 suffix,
2131 ) = self.token {
2132 let suffix = suffix.and_then(|s| {
2133 let s = s.as_str().get();
2134 if ["f32", "f64"].contains(&s) {
2135 Some(s)
2136 } else {
2137 None
2138 }
2139 }).unwrap_or("");
2140 self.bump();
2141 let sp = lo.to(self.prev_span);
2142 let mut err = self.diagnostic()
2143 .struct_span_err(sp, "float literals must have an integer part");
2144 err.span_suggestion(
2145 sp,
2146 "must have an integer part",
2147 format!("0.{}{}", val, suffix),
2148 Applicability::MachineApplicable,
2149 );
2150 err.emit();
2151 return Ok(match suffix {
2152 "f32" => ast::LitKind::Float(val, ast::FloatTy::F32),
2153 "f64" => ast::LitKind::Float(val, ast::FloatTy::F64),
2154 _ => ast::LitKind::FloatUnsuffixed(val),
2155 });
2156 } else {
2157 unreachable!();
2158 };
2159 }
2160 _ => { return self.unexpected_last(&self.token); }
2161 };
2162
2163 self.bump();
2164 Ok(out)
2165 }
2166
2167 /// Matches `lit = true | false | token_lit`.
2168 crate fn parse_lit(&mut self) -> PResult<'a, Lit> {
2169 let lo = self.span;
2170 let lit = if self.eat_keyword(keywords::True) {
2171 LitKind::Bool(true)
2172 } else if self.eat_keyword(keywords::False) {
2173 LitKind::Bool(false)
2174 } else {
2175 let lit = self.parse_lit_token()?;
2176 lit
2177 };
2178 Ok(source_map::Spanned { node: lit, span: lo.to(self.prev_span) })
2179 }
2180
2181 /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
2182 crate fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
2183 maybe_whole_expr!(self);
2184
2185 let minus_lo = self.span;
2186 let minus_present = self.eat(&token::BinOp(token::Minus));
2187 let lo = self.span;
2188 let literal = self.parse_lit()?;
2189 let hi = self.prev_span;
2190 let expr = self.mk_expr(lo.to(hi), ExprKind::Lit(literal), ThinVec::new());
2191
2192 if minus_present {
2193 let minus_hi = self.prev_span;
2194 let unary = self.mk_unary(UnOp::Neg, expr);
2195 Ok(self.mk_expr(minus_lo.to(minus_hi), unary, ThinVec::new()))
2196 } else {
2197 Ok(expr)
2198 }
2199 }
2200
2201 fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> {
2202 match self.token {
2203 token::Ident(ident, _) if self.token.is_path_segment_keyword() => {
2204 let span = self.span;
2205 self.bump();
2206 Ok(Ident::new(ident.name, span))
2207 }
2208 _ => self.parse_ident(),
2209 }
2210 }
2211
2212 fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
2213 match self.token {
2214 token::Ident(ident, false) if ident.name == keywords::Underscore.name() => {
2215 let span = self.span;
2216 self.bump();
2217 Ok(Ident::new(ident.name, span))
2218 }
2219 _ => self.parse_ident(),
2220 }
2221 }
2222
2223 /// Parses a qualified path.
2224 /// Assumes that the leading `<` has been parsed already.
2225 ///
2226 /// `qualified_path = <type [as trait_ref]>::path`
2227 ///
2228 /// # Examples
2229 /// `<T>::default`
2230 /// `<T as U>::a`
2231 /// `<T as U>::F::a<S>` (without disambiguator)
2232 /// `<T as U>::F::a::<S>` (with disambiguator)
2233 fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, ast::Path)> {
2234 let lo = self.prev_span;
2235 let ty = self.parse_ty()?;
2236
2237 // `path` will contain the prefix of the path up to the `>`,
2238 // if any (e.g., `U` in the `<T as U>::*` examples
2239 // above). `path_span` has the span of that path, or an empty
2240 // span in the case of something like `<T>::Bar`.
2241 let (mut path, path_span);
2242 if self.eat_keyword(keywords::As) {
2243 let path_lo = self.span;
2244 path = self.parse_path(PathStyle::Type)?;
2245 path_span = path_lo.to(self.prev_span);
2246 } else {
2247 path = ast::Path { segments: Vec::new(), span: syntax_pos::DUMMY_SP };
2248 path_span = self.span.to(self.span);
2249 }
2250
2251 // See doc comment for `unmatched_angle_bracket_count`.
2252 self.expect(&token::Gt)?;
2253 if self.unmatched_angle_bracket_count > 0 {
2254 self.unmatched_angle_bracket_count -= 1;
2255 debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count);
2256 }
2257
2258 self.expect(&token::ModSep)?;
2259
2260 let qself = QSelf { ty, path_span, position: path.segments.len() };
2261 self.parse_path_segments(&mut path.segments, style, true)?;
2262
2263 Ok((qself, ast::Path { segments: path.segments, span: lo.to(self.prev_span) }))
2264 }
2265
2266 /// Parses simple paths.
2267 ///
2268 /// `path = [::] segment+`
2269 /// `segment = ident | ident[::]<args> | ident[::](args) [-> type]`
2270 ///
2271 /// # Examples
2272 /// `a::b::C<D>` (without disambiguator)
2273 /// `a::b::C::<D>` (with disambiguator)
2274 /// `Fn(Args)` (without disambiguator)
2275 /// `Fn::(Args)` (with disambiguator)
2276 pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, ast::Path> {
2277 self.parse_path_common(style, true)
2278 }
2279
2280 crate fn parse_path_common(&mut self, style: PathStyle, enable_warning: bool)
2281 -> PResult<'a, ast::Path> {
2282 maybe_whole!(self, NtPath, |path| {
2283 if style == PathStyle::Mod &&
2284 path.segments.iter().any(|segment| segment.args.is_some()) {
2285 self.diagnostic().span_err(path.span, "unexpected generic arguments in path");
2286 }
2287 path
2288 });
2289
2290 let lo = self.meta_var_span.unwrap_or(self.span);
2291 let mut segments = Vec::new();
2292 let mod_sep_ctxt = self.span.ctxt();
2293 if self.eat(&token::ModSep) {
2294 segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
2295 }
2296 self.parse_path_segments(&mut segments, style, enable_warning)?;
2297
2298 Ok(ast::Path { segments, span: lo.to(self.prev_span) })
2299 }
2300
2301 /// Like `parse_path`, but also supports parsing `Word` meta items into paths for
2302 /// backwards-compatibility. This is used when parsing derive macro paths in `#[derive]`
2303 /// attributes.
2304 pub fn parse_path_allowing_meta(&mut self, style: PathStyle) -> PResult<'a, ast::Path> {
2305 let meta_ident = match self.token {
2306 token::Interpolated(ref nt) => match **nt {
2307 token::NtMeta(ref meta) => match meta.node {
2308 ast::MetaItemKind::Word => Some(meta.ident.clone()),
2309 _ => None,
2310 },
2311 _ => None,
2312 },
2313 _ => None,
2314 };
2315 if let Some(path) = meta_ident {
2316 self.bump();
2317 return Ok(path);
2318 }
2319 self.parse_path(style)
2320 }
2321
2322 fn parse_path_segments(&mut self,
2323 segments: &mut Vec<PathSegment>,
2324 style: PathStyle,
2325 enable_warning: bool)
2326 -> PResult<'a, ()> {
2327 loop {
2328 let segment = self.parse_path_segment(style, enable_warning)?;
2329 if style == PathStyle::Expr {
2330 // In order to check for trailing angle brackets, we must have finished
2331 // recursing (`parse_path_segment` can indirectly call this function),
2332 // that is, the next token must be the highlighted part of the below example:
2333 //
2334 // `Foo::<Bar as Baz<T>>::Qux`
2335 // ^ here
2336 //
2337 // As opposed to the below highlight (if we had only finished the first
2338 // recursion):
2339 //
2340 // `Foo::<Bar as Baz<T>>::Qux`
2341 // ^ here
2342 //
2343 // `PathStyle::Expr` is only provided at the root invocation and never in
2344 // `parse_path_segment` to recurse and therefore can be checked to maintain
2345 // this invariant.
2346 self.check_trailing_angle_brackets(&segment, token::ModSep);
2347 }
2348 segments.push(segment);
2349
2350 if self.is_import_coupler() || !self.eat(&token::ModSep) {
2351 return Ok(());
2352 }
2353 }
2354 }
2355
2356 fn parse_path_segment(&mut self, style: PathStyle, enable_warning: bool)
2357 -> PResult<'a, PathSegment> {
2358 let ident = self.parse_path_segment_ident()?;
2359
2360 let is_args_start = |token: &token::Token| match *token {
2361 token::Lt | token::BinOp(token::Shl) | token::OpenDelim(token::Paren) => true,
2362 _ => false,
2363 };
2364 let check_args_start = |this: &mut Self| {
2365 this.expected_tokens.extend_from_slice(
2366 &[TokenType::Token(token::Lt), TokenType::Token(token::OpenDelim(token::Paren))]
2367 );
2368 is_args_start(&this.token)
2369 };
2370
2371 Ok(if style == PathStyle::Type && check_args_start(self) ||
2372 style != PathStyle::Mod && self.check(&token::ModSep)
2373 && self.look_ahead(1, |t| is_args_start(t)) {
2374 // Generic arguments are found - `<`, `(`, `::<` or `::(`.
2375 if self.eat(&token::ModSep) && style == PathStyle::Type && enable_warning {
2376 self.diagnostic().struct_span_warn(self.prev_span, "unnecessary path disambiguator")
2377 .span_label(self.prev_span, "try removing `::`").emit();
2378 }
2379 let lo = self.span;
2380
2381 // We use `style == PathStyle::Expr` to check if this is in a recursion or not. If
2382 // it isn't, then we reset the unmatched angle bracket count as we're about to start
2383 // parsing a new path.
2384 if style == PathStyle::Expr {
2385 self.unmatched_angle_bracket_count = 0;
2386 self.max_angle_bracket_count = 0;
2387 }
2388
2389 let args = if self.eat_lt() {
2390 // `<'a, T, A = U>`
2391 let (args, bindings) =
2392 self.parse_generic_args_with_leaning_angle_bracket_recovery(style, lo)?;
2393 self.expect_gt()?;
2394 let span = lo.to(self.prev_span);
2395 AngleBracketedArgs { args, bindings, span }.into()
2396 } else {
2397 // `(T, U) -> R`
2398 self.bump(); // `(`
2399 let (inputs, recovered) = self.parse_seq_to_before_tokens(
2400 &[&token::CloseDelim(token::Paren)],
2401 SeqSep::trailing_allowed(token::Comma),
2402 TokenExpectType::Expect,
2403 |p| p.parse_ty())?;
2404 if !recovered {
2405 self.bump(); // `)`
2406 }
2407 let span = lo.to(self.prev_span);
2408 let output = if self.eat(&token::RArrow) {
2409 Some(self.parse_ty_common(false, false)?)
2410 } else {
2411 None
2412 };
2413 ParenthesizedArgs { inputs, output, span }.into()
2414 };
2415
2416 PathSegment { ident, args, id: ast::DUMMY_NODE_ID }
2417 } else {
2418 // Generic arguments are not found.
2419 PathSegment::from_ident(ident)
2420 })
2421 }
2422
2423 crate fn check_lifetime(&mut self) -> bool {
2424 self.expected_tokens.push(TokenType::Lifetime);
2425 self.token.is_lifetime()
2426 }
2427
2428 /// Parses a single lifetime `'a` or panics.
2429 crate fn expect_lifetime(&mut self) -> Lifetime {
2430 if let Some(ident) = self.token.lifetime() {
2431 let span = self.span;
2432 self.bump();
2433 Lifetime { ident: Ident::new(ident.name, span), id: ast::DUMMY_NODE_ID }
2434 } else {
2435 self.span_bug(self.span, "not a lifetime")
2436 }
2437 }
2438
2439 fn eat_label(&mut self) -> Option<Label> {
2440 if let Some(ident) = self.token.lifetime() {
2441 let span = self.span;
2442 self.bump();
2443 Some(Label { ident: Ident::new(ident.name, span) })
2444 } else {
2445 None
2446 }
2447 }
2448
2449 /// Parses mutability (`mut` or nothing).
2450 fn parse_mutability(&mut self) -> Mutability {
2451 if self.eat_keyword(keywords::Mut) {
2452 Mutability::Mutable
2453 } else {
2454 Mutability::Immutable
2455 }
2456 }
2457
2458 fn parse_field_name(&mut self) -> PResult<'a, Ident> {
2459 if let token::Literal(token::Integer(name), None) = self.token {
2460 self.bump();
2461 Ok(Ident::new(name, self.prev_span))
2462 } else {
2463 self.parse_ident_common(false)
2464 }
2465 }
2466
2467 /// Parse ident (COLON expr)?
2468 fn parse_field(&mut self) -> PResult<'a, Field> {
2469 let attrs = self.parse_outer_attributes()?;
2470 let lo = self.span;
2471
2472 // Check if a colon exists one ahead. This means we're parsing a fieldname.
2473 let (fieldname, expr, is_shorthand) = if self.look_ahead(1, |t| {
2474 t == &token::Colon || t == &token::Eq
2475 }) {
2476 let fieldname = self.parse_field_name()?;
2477
2478 // Check for an equals token. This means the source incorrectly attempts to
2479 // initialize a field with an eq rather than a colon.
2480 if self.token == token::Eq {
2481 self.diagnostic()
2482 .struct_span_err(self.span, "expected `:`, found `=`")
2483 .span_suggestion(
2484 fieldname.span.shrink_to_hi().to(self.span),
2485 "replace equals symbol with a colon",
2486 ":".to_string(),
2487 Applicability::MachineApplicable,
2488 )
2489 .emit();
2490 }
2491 self.bump(); // `:`
2492 (fieldname, self.parse_expr()?, false)
2493 } else {
2494 let fieldname = self.parse_ident_common(false)?;
2495
2496 // Mimic `x: x` for the `x` field shorthand.
2497 let path = ast::Path::from_ident(fieldname);
2498 let expr = self.mk_expr(fieldname.span, ExprKind::Path(None, path), ThinVec::new());
2499 (fieldname, expr, true)
2500 };
2501 Ok(ast::Field {
2502 ident: fieldname,
2503 span: lo.to(expr.span),
2504 expr,
2505 is_shorthand,
2506 attrs: attrs.into(),
2507 })
2508 }
2509
2510 fn mk_expr(&mut self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
2511 P(Expr { node, span, attrs, id: ast::DUMMY_NODE_ID })
2512 }
2513
2514 fn mk_unary(&mut self, unop: ast::UnOp, expr: P<Expr>) -> ast::ExprKind {
2515 ExprKind::Unary(unop, expr)
2516 }
2517
2518 fn mk_binary(&mut self, binop: ast::BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
2519 ExprKind::Binary(binop, lhs, rhs)
2520 }
2521
2522 fn mk_call(&mut self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::ExprKind {
2523 ExprKind::Call(f, args)
2524 }
2525
2526 fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::ExprKind {
2527 ExprKind::Index(expr, idx)
2528 }
2529
2530 fn mk_range(&mut self,
2531 start: Option<P<Expr>>,
2532 end: Option<P<Expr>>,
2533 limits: RangeLimits)
2534 -> PResult<'a, ast::ExprKind> {
2535 if end.is_none() && limits == RangeLimits::Closed {
2536 Err(self.span_fatal_err(self.span, Error::InclusiveRangeWithNoEnd))
2537 } else {
2538 Ok(ExprKind::Range(start, end, limits))
2539 }
2540 }
2541
2542 fn mk_assign_op(&mut self, binop: ast::BinOp,
2543 lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
2544 ExprKind::AssignOp(binop, lhs, rhs)
2545 }
2546
2547 pub fn mk_mac_expr(&mut self, span: Span, m: Mac_, attrs: ThinVec<Attribute>) -> P<Expr> {
2548 P(Expr {
2549 id: ast::DUMMY_NODE_ID,
2550 node: ExprKind::Mac(source_map::Spanned {node: m, span: span}),
2551 span,
2552 attrs,
2553 })
2554 }
2555
2556 fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, TokenStream)> {
2557 let delim = match self.token {
2558 token::OpenDelim(delim) => delim,
2559 _ => {
2560 let msg = "expected open delimiter";
2561 let mut err = self.fatal(msg);
2562 err.span_label(self.span, msg);
2563 return Err(err)
2564 }
2565 };
2566 let tts = match self.parse_token_tree() {
2567 TokenTree::Delimited(_, _, tts) => tts,
2568 _ => unreachable!(),
2569 };
2570 let delim = match delim {
2571 token::Paren => MacDelimiter::Parenthesis,
2572 token::Bracket => MacDelimiter::Bracket,
2573 token::Brace => MacDelimiter::Brace,
2574 token::NoDelim => self.bug("unexpected no delimiter"),
2575 };
2576 Ok((delim, tts.into()))
2577 }
2578
2579 /// At the bottom (top?) of the precedence hierarchy,
2580 /// Parses things like parenthesized exprs, macros, `return`, etc.
2581 ///
2582 /// N.B., this does not parse outer attributes, and is private because it only works
2583 /// correctly if called from `parse_dot_or_call_expr()`.
2584 fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
2585 maybe_whole_expr!(self);
2586
2587 // Outer attributes are already parsed and will be
2588 // added to the return value after the fact.
2589 //
2590 // Therefore, prevent sub-parser from parsing
2591 // attributes by giving them a empty "already parsed" list.
2592 let mut attrs = ThinVec::new();
2593
2594 let lo = self.span;
2595 let mut hi = self.span;
2596
2597 let ex: ExprKind;
2598
2599 // Note: when adding new syntax here, don't forget to adjust Token::can_begin_expr().
2600 match self.token {
2601 token::OpenDelim(token::Paren) => {
2602 self.bump();
2603
2604 attrs.extend(self.parse_inner_attributes()?);
2605
2606 // (e) is parenthesized e
2607 // (e,) is a tuple with only one field, e
2608 let mut es = vec![];
2609 let mut trailing_comma = false;
2610 let mut recovered = false;
2611 while self.token != token::CloseDelim(token::Paren) {
2612 es.push(self.parse_expr()?);
2613 recovered = self.expect_one_of(
2614 &[],
2615 &[token::Comma, token::CloseDelim(token::Paren)],
2616 )?;
2617 if self.eat(&token::Comma) {
2618 trailing_comma = true;
2619 } else {
2620 trailing_comma = false;
2621 break;
2622 }
2623 }
2624 if !recovered {
2625 self.bump();
2626 }
2627
2628 hi = self.prev_span;
2629 ex = if es.len() == 1 && !trailing_comma {
2630 ExprKind::Paren(es.into_iter().nth(0).unwrap())
2631 } else {
2632 ExprKind::Tup(es)
2633 };
2634 }
2635 token::OpenDelim(token::Brace) => {
2636 return self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs);
2637 }
2638 token::BinOp(token::Or) | token::OrOr => {
2639 return self.parse_lambda_expr(attrs);
2640 }
2641 token::OpenDelim(token::Bracket) => {
2642 self.bump();
2643
2644 attrs.extend(self.parse_inner_attributes()?);
2645
2646 if self.eat(&token::CloseDelim(token::Bracket)) {
2647 // Empty vector.
2648 ex = ExprKind::Array(Vec::new());
2649 } else {
2650 // Nonempty vector.
2651 let first_expr = self.parse_expr()?;
2652 if self.eat(&token::Semi) {
2653 // Repeating array syntax: [ 0; 512 ]
2654 let count = AnonConst {
2655 id: ast::DUMMY_NODE_ID,
2656 value: self.parse_expr()?,
2657 };
2658 self.expect(&token::CloseDelim(token::Bracket))?;
2659 ex = ExprKind::Repeat(first_expr, count);
2660 } else if self.eat(&token::Comma) {
2661 // Vector with two or more elements.
2662 let remaining_exprs = self.parse_seq_to_end(
2663 &token::CloseDelim(token::Bracket),
2664 SeqSep::trailing_allowed(token::Comma),
2665 |p| Ok(p.parse_expr()?)
2666 )?;
2667 let mut exprs = vec![first_expr];
2668 exprs.extend(remaining_exprs);
2669 ex = ExprKind::Array(exprs);
2670 } else {
2671 // Vector with one element.
2672 self.expect(&token::CloseDelim(token::Bracket))?;
2673 ex = ExprKind::Array(vec![first_expr]);
2674 }
2675 }
2676 hi = self.prev_span;
2677 }
2678 _ => {
2679 if self.eat_lt() {
2680 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
2681 hi = path.span;
2682 return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
2683 }
2684 if self.span.rust_2018() && self.check_keyword(keywords::Async)
2685 {
2686 if self.is_async_block() { // check for `async {` and `async move {`
2687 return self.parse_async_block(attrs);
2688 } else {
2689 return self.parse_lambda_expr(attrs);
2690 }
2691 }
2692 if self.check_keyword(keywords::Move) || self.check_keyword(keywords::Static) {
2693 return self.parse_lambda_expr(attrs);
2694 }
2695 if self.eat_keyword(keywords::If) {
2696 return self.parse_if_expr(attrs);
2697 }
2698 if self.eat_keyword(keywords::For) {
2699 let lo = self.prev_span;
2700 return self.parse_for_expr(None, lo, attrs);
2701 }
2702 if self.eat_keyword(keywords::While) {
2703 let lo = self.prev_span;
2704 return self.parse_while_expr(None, lo, attrs);
2705 }
2706 if let Some(label) = self.eat_label() {
2707 let lo = label.ident.span;
2708 self.expect(&token::Colon)?;
2709 if self.eat_keyword(keywords::While) {
2710 return self.parse_while_expr(Some(label), lo, attrs)
2711 }
2712 if self.eat_keyword(keywords::For) {
2713 return self.parse_for_expr(Some(label), lo, attrs)
2714 }
2715 if self.eat_keyword(keywords::Loop) {
2716 return self.parse_loop_expr(Some(label), lo, attrs)
2717 }
2718 if self.token == token::OpenDelim(token::Brace) {
2719 return self.parse_block_expr(Some(label),
2720 lo,
2721 BlockCheckMode::Default,
2722 attrs);
2723 }
2724 let msg = "expected `while`, `for`, `loop` or `{` after a label";
2725 let mut err = self.fatal(msg);
2726 err.span_label(self.span, msg);
2727 return Err(err);
2728 }
2729 if self.eat_keyword(keywords::Loop) {
2730 let lo = self.prev_span;
2731 return self.parse_loop_expr(None, lo, attrs);
2732 }
2733 if self.eat_keyword(keywords::Continue) {
2734 let label = self.eat_label();
2735 let ex = ExprKind::Continue(label);
2736 let hi = self.prev_span;
2737 return Ok(self.mk_expr(lo.to(hi), ex, attrs));
2738 }
2739 if self.eat_keyword(keywords::Match) {
2740 let match_sp = self.prev_span;
2741 return self.parse_match_expr(attrs).map_err(|mut err| {
2742 err.span_label(match_sp, "while parsing this match expression");
2743 err
2744 });
2745 }
2746 if self.eat_keyword(keywords::Unsafe) {
2747 return self.parse_block_expr(
2748 None,
2749 lo,
2750 BlockCheckMode::Unsafe(ast::UserProvided),
2751 attrs);
2752 }
2753 if self.is_do_catch_block() {
2754 let mut db = self.fatal("found removed `do catch` syntax");
2755 db.help("Following RFC #2388, the new non-placeholder syntax is `try`");
2756 return Err(db);
2757 }
2758 if self.is_try_block() {
2759 let lo = self.span;
2760 assert!(self.eat_keyword(keywords::Try));
2761 return self.parse_try_block(lo, attrs);
2762 }
2763 if self.eat_keyword(keywords::Return) {
2764 if self.token.can_begin_expr() {
2765 let e = self.parse_expr()?;
2766 hi = e.span;
2767 ex = ExprKind::Ret(Some(e));
2768 } else {
2769 ex = ExprKind::Ret(None);
2770 }
2771 } else if self.eat_keyword(keywords::Break) {
2772 let label = self.eat_label();
2773 let e = if self.token.can_begin_expr()
2774 && !(self.token == token::OpenDelim(token::Brace)
2775 && self.restrictions.contains(
2776 Restrictions::NO_STRUCT_LITERAL)) {
2777 Some(self.parse_expr()?)
2778 } else {
2779 None
2780 };
2781 ex = ExprKind::Break(label, e);
2782 hi = self.prev_span;
2783 } else if self.eat_keyword(keywords::Yield) {
2784 if self.token.can_begin_expr() {
2785 let e = self.parse_expr()?;
2786 hi = e.span;
2787 ex = ExprKind::Yield(Some(e));
2788 } else {
2789 ex = ExprKind::Yield(None);
2790 }
2791 } else if self.token.is_keyword(keywords::Let) {
2792 // Catch this syntax error here, instead of in `parse_ident`, so
2793 // that we can explicitly mention that let is not to be used as an expression
2794 let mut db = self.fatal("expected expression, found statement (`let`)");
2795 db.span_label(self.span, "expected expression");
2796 db.note("variable declaration using `let` is a statement");
2797 return Err(db);
2798 } else if self.token.is_path_start() {
2799 let pth = self.parse_path(PathStyle::Expr)?;
2800
2801 // `!`, as an operator, is prefix, so we know this isn't that
2802 if self.eat(&token::Not) {
2803 // MACRO INVOCATION expression
2804 let (delim, tts) = self.expect_delimited_token_tree()?;
2805 let hi = self.prev_span;
2806 let node = Mac_ { path: pth, tts, delim };
2807 return Ok(self.mk_mac_expr(lo.to(hi), node, attrs))
2808 }
2809 if self.check(&token::OpenDelim(token::Brace)) {
2810 // This is a struct literal, unless we're prohibited
2811 // from parsing struct literals here.
2812 let prohibited = self.restrictions.contains(
2813 Restrictions::NO_STRUCT_LITERAL
2814 );
2815 if !prohibited {
2816 return self.parse_struct_expr(lo, pth, attrs);
2817 }
2818 }
2819
2820 hi = pth.span;
2821 ex = ExprKind::Path(None, pth);
2822 } else {
2823 if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
2824 // Don't complain about bare semicolons after unclosed braces
2825 // recovery in order to keep the error count down. Fixing the
2826 // delimiters will possibly also fix the bare semicolon found in
2827 // expression context. For example, silence the following error:
2828 // ```
2829 // error: expected expression, found `;`
2830 // --> file.rs:2:13
2831 // |
2832 // 2 | foo(bar(;
2833 // | ^ expected expression
2834 // ```
2835 self.bump();
2836 return Ok(self.mk_expr(self.span, ExprKind::Err, ThinVec::new()));
2837 }
2838 match self.parse_literal_maybe_minus() {
2839 Ok(expr) => {
2840 hi = expr.span;
2841 ex = expr.node.clone();
2842 }
2843 Err(mut err) => {
2844 self.cancel(&mut err);
2845 let msg = format!("expected expression, found {}",
2846 self.this_token_descr());
2847 let mut err = self.fatal(&msg);
2848 err.span_label(self.span, "expected expression");
2849 return Err(err);
2850 }
2851 }
2852 }
2853 }
2854 }
2855
2856 let expr = Expr { node: ex, span: lo.to(hi), id: ast::DUMMY_NODE_ID, attrs };
2857 let expr = self.maybe_recover_from_bad_qpath(expr, true)?;
2858
2859 return Ok(P(expr));
2860 }
2861
2862 fn parse_struct_expr(&mut self, lo: Span, pth: ast::Path, mut attrs: ThinVec<Attribute>)
2863 -> PResult<'a, P<Expr>> {
2864 let struct_sp = lo.to(self.prev_span);
2865 self.bump();
2866 let mut fields = Vec::new();
2867 let mut base = None;
2868
2869 attrs.extend(self.parse_inner_attributes()?);
2870
2871 while self.token != token::CloseDelim(token::Brace) {
2872 if self.eat(&token::DotDot) {
2873 let exp_span = self.prev_span;
2874 match self.parse_expr() {
2875 Ok(e) => {
2876 base = Some(e);
2877 }
2878 Err(mut e) => {
2879 e.emit();
2880 self.recover_stmt();
2881 }
2882 }
2883 if self.token == token::Comma {
2884 let mut err = self.sess.span_diagnostic.mut_span_err(
2885 exp_span.to(self.prev_span),
2886 "cannot use a comma after the base struct",
2887 );
2888 err.span_suggestion_short(
2889 self.span,
2890 "remove this comma",
2891 String::new(),
2892 Applicability::MachineApplicable
2893 );
2894 err.note("the base struct must always be the last field");
2895 err.emit();
2896 self.recover_stmt();
2897 }
2898 break;
2899 }
2900
2901 let mut recovery_field = None;
2902 if let token::Ident(ident, _) = self.token {
2903 if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) {
2904 // Use in case of error after field-looking code: `S { foo: () with a }`
2905 let mut ident = ident.clone();
2906 ident.span = self.span;
2907 recovery_field = Some(ast::Field {
2908 ident,
2909 span: self.span,
2910 expr: self.mk_expr(self.span, ExprKind::Err, ThinVec::new()),
2911 is_shorthand: false,
2912 attrs: ThinVec::new(),
2913 });
2914 }
2915 }
2916 let mut parsed_field = None;
2917 match self.parse_field() {
2918 Ok(f) => parsed_field = Some(f),
2919 Err(mut e) => {
2920 e.span_label(struct_sp, "while parsing this struct");
2921 e.emit();
2922
2923 // If the next token is a comma, then try to parse
2924 // what comes next as additional fields, rather than
2925 // bailing out until next `}`.
2926 if self.token != token::Comma {
2927 self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
2928 if self.token != token::Comma {
2929 break;
2930 }
2931 }
2932 }
2933 }
2934
2935 match self.expect_one_of(&[token::Comma],
2936 &[token::CloseDelim(token::Brace)]) {
2937 Ok(_) => if let Some(f) = parsed_field.or(recovery_field) {
2938 // only include the field if there's no parse error for the field name
2939 fields.push(f);
2940 }
2941 Err(mut e) => {
2942 if let Some(f) = recovery_field {
2943 fields.push(f);
2944 }
2945 e.span_label(struct_sp, "while parsing this struct");
2946 e.emit();
2947 self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
2948 self.eat(&token::Comma);
2949 }
2950 }
2951 }
2952
2953 let span = lo.to(self.span);
2954 self.expect(&token::CloseDelim(token::Brace))?;
2955 return Ok(self.mk_expr(span, ExprKind::Struct(pth, fields, base), attrs));
2956 }
2957
2958 fn parse_or_use_outer_attributes(&mut self,
2959 already_parsed_attrs: Option<ThinVec<Attribute>>)
2960 -> PResult<'a, ThinVec<Attribute>> {
2961 if let Some(attrs) = already_parsed_attrs {
2962 Ok(attrs)
2963 } else {
2964 self.parse_outer_attributes().map(|a| a.into())
2965 }
2966 }
2967
2968 /// Parses a block or unsafe block.
2969 fn parse_block_expr(&mut self, opt_label: Option<Label>,
2970 lo: Span, blk_mode: BlockCheckMode,
2971 outer_attrs: ThinVec<Attribute>)
2972 -> PResult<'a, P<Expr>> {
2973 self.expect(&token::OpenDelim(token::Brace))?;
2974
2975 let mut attrs = outer_attrs;
2976 attrs.extend(self.parse_inner_attributes()?);
2977
2978 let blk = self.parse_block_tail(lo, blk_mode)?;
2979 return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs));
2980 }
2981
2982 /// Parses `a.b` or `a(13)` or `a[4]` or just `a`.
2983 fn parse_dot_or_call_expr(&mut self,
2984 already_parsed_attrs: Option<ThinVec<Attribute>>)
2985 -> PResult<'a, P<Expr>> {
2986 let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
2987
2988 let b = self.parse_bottom_expr();
2989 let (span, b) = self.interpolated_or_expr_span(b)?;
2990 self.parse_dot_or_call_expr_with(b, span, attrs)
2991 }
2992
2993 fn parse_dot_or_call_expr_with(&mut self,
2994 e0: P<Expr>,
2995 lo: Span,
2996 mut attrs: ThinVec<Attribute>)
2997 -> PResult<'a, P<Expr>> {
2998 // Stitch the list of outer attributes onto the return value.
2999 // A little bit ugly, but the best way given the current code
3000 // structure
3001 self.parse_dot_or_call_expr_with_(e0, lo)
3002 .map(|expr|
3003 expr.map(|mut expr| {
3004 attrs.extend::<Vec<_>>(expr.attrs.into());
3005 expr.attrs = attrs;
3006 match expr.node {
3007 ExprKind::If(..) | ExprKind::IfLet(..) => {
3008 if !expr.attrs.is_empty() {
3009 // Just point to the first attribute in there...
3010 let span = expr.attrs[0].span;
3011
3012 self.span_err(span,
3013 "attributes are not yet allowed on `if` \
3014 expressions");
3015 }
3016 }
3017 _ => {}
3018 }
3019 expr
3020 })
3021 )
3022 }
3023
3024 // Assuming we have just parsed `.`, continue parsing into an expression.
3025 fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
3026 let segment = self.parse_path_segment(PathStyle::Expr, true)?;
3027 self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren));
3028
3029 Ok(match self.token {
3030 token::OpenDelim(token::Paren) => {
3031 // Method call `expr.f()`
3032 let mut args = self.parse_unspanned_seq(
3033 &token::OpenDelim(token::Paren),
3034 &token::CloseDelim(token::Paren),
3035 SeqSep::trailing_allowed(token::Comma),
3036 |p| Ok(p.parse_expr()?)
3037 )?;
3038 args.insert(0, self_arg);
3039
3040 let span = lo.to(self.prev_span);
3041 self.mk_expr(span, ExprKind::MethodCall(segment, args), ThinVec::new())
3042 }
3043 _ => {
3044 // Field access `expr.f`
3045 if let Some(args) = segment.args {
3046 self.span_err(args.span(),
3047 "field expressions may not have generic arguments");
3048 }
3049
3050 let span = lo.to(self.prev_span);
3051 self.mk_expr(span, ExprKind::Field(self_arg, segment.ident), ThinVec::new())
3052 }
3053 })
3054 }
3055
3056 /// This function checks if there are trailing angle brackets and produces
3057 /// a diagnostic to suggest removing them.
3058 ///
3059 /// ```ignore (diagnostic)
3060 /// let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
3061 /// ^^ help: remove extra angle brackets
3062 /// ```
3063 fn check_trailing_angle_brackets(&mut self, segment: &PathSegment, end: token::Token) {
3064 // This function is intended to be invoked after parsing a path segment where there are two
3065 // cases:
3066 //
3067 // 1. A specific token is expected after the path segment.
3068 // eg. `x.foo(`, `x.foo::<u32>(` (parenthesis - method call),
3069 // `Foo::`, or `Foo::<Bar>::` (mod sep - continued path).
3070 // 2. No specific token is expected after the path segment.
3071 // eg. `x.foo` (field access)
3072 //
3073 // This function is called after parsing `.foo` and before parsing the token `end` (if
3074 // present). This includes any angle bracket arguments, such as `.foo::<u32>` or
3075 // `Foo::<Bar>`.
3076
3077 // We only care about trailing angle brackets if we previously parsed angle bracket
3078 // arguments. This helps stop us incorrectly suggesting that extra angle brackets be
3079 // removed in this case:
3080 //
3081 // `x.foo >> (3)` (where `x.foo` is a `u32` for example)
3082 //
3083 // This case is particularly tricky as we won't notice it just looking at the tokens -
3084 // it will appear the same (in terms of upcoming tokens) as below (since the `::<u32>` will
3085 // have already been parsed):
3086 //
3087 // `x.foo::<u32>>>(3)`
3088 let parsed_angle_bracket_args = segment.args
3089 .as_ref()
3090 .map(|args| args.is_angle_bracketed())
3091 .unwrap_or(false);
3092
3093 debug!(
3094 "check_trailing_angle_brackets: parsed_angle_bracket_args={:?}",
3095 parsed_angle_bracket_args,
3096 );
3097 if !parsed_angle_bracket_args {
3098 return;
3099 }
3100
3101 // Keep the span at the start so we can highlight the sequence of `>` characters to be
3102 // removed.
3103 let lo = self.span;
3104
3105 // We need to look-ahead to see if we have `>` characters without moving the cursor forward
3106 // (since we might have the field access case and the characters we're eating are
3107 // actual operators and not trailing characters - ie `x.foo >> 3`).
3108 let mut position = 0;
3109
3110 // We can encounter `>` or `>>` tokens in any order, so we need to keep track of how
3111 // many of each (so we can correctly pluralize our error messages) and continue to
3112 // advance.
3113 let mut number_of_shr = 0;
3114 let mut number_of_gt = 0;
3115 while self.look_ahead(position, |t| {
3116 trace!("check_trailing_angle_brackets: t={:?}", t);
3117 if *t == token::BinOp(token::BinOpToken::Shr) {
3118 number_of_shr += 1;
3119 true
3120 } else if *t == token::Gt {
3121 number_of_gt += 1;
3122 true
3123 } else {
3124 false
3125 }
3126 }) {
3127 position += 1;
3128 }
3129
3130 // If we didn't find any trailing `>` characters, then we have nothing to error about.
3131 debug!(
3132 "check_trailing_angle_brackets: number_of_gt={:?} number_of_shr={:?}",
3133 number_of_gt, number_of_shr,
3134 );
3135 if number_of_gt < 1 && number_of_shr < 1 {
3136 return;
3137 }
3138
3139 // Finally, double check that we have our end token as otherwise this is the
3140 // second case.
3141 if self.look_ahead(position, |t| {
3142 trace!("check_trailing_angle_brackets: t={:?}", t);
3143 *t == end
3144 }) {
3145 // Eat from where we started until the end token so that parsing can continue
3146 // as if we didn't have those extra angle brackets.
3147 self.eat_to_tokens(&[&end]);
3148 let span = lo.until(self.span);
3149
3150 let plural = number_of_gt > 1 || number_of_shr >= 1;
3151 self.diagnostic()
3152 .struct_span_err(
3153 span,
3154 &format!("unmatched angle bracket{}", if plural { "s" } else { "" }),
3155 )
3156 .span_suggestion(
3157 span,
3158 &format!("remove extra angle bracket{}", if plural { "s" } else { "" }),
3159 String::new(),
3160 Applicability::MachineApplicable,
3161 )
3162 .emit();
3163 }
3164 }
3165
3166 fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
3167 let mut e = e0;
3168 let mut hi;
3169 loop {
3170 // expr?
3171 while self.eat(&token::Question) {
3172 let hi = self.prev_span;
3173 e = self.mk_expr(lo.to(hi), ExprKind::Try(e), ThinVec::new());
3174 }
3175
3176 // expr.f
3177 if self.eat(&token::Dot) {
3178 match self.token {
3179 token::Ident(..) => {
3180 e = self.parse_dot_suffix(e, lo)?;
3181 }
3182 token::Literal(token::Integer(name), _) => {
3183 let span = self.span;
3184 self.bump();
3185 let field = ExprKind::Field(e, Ident::new(name, span));
3186 e = self.mk_expr(lo.to(span), field, ThinVec::new());
3187 }
3188 token::Literal(token::Float(n), _suf) => {
3189 self.bump();
3190 let fstr = n.as_str();
3191 let mut err = self.diagnostic()
3192 .struct_span_err(self.prev_span, &format!("unexpected token: `{}`", n));
3193 err.span_label(self.prev_span, "unexpected token");
3194 if fstr.chars().all(|x| "0123456789.".contains(x)) {
3195 let float = match fstr.parse::<f64>().ok() {
3196 Some(f) => f,
3197 None => continue,
3198 };
3199 let sugg = pprust::to_string(|s| {
3200 use crate::print::pprust::PrintState;
3201 s.popen()?;
3202 s.print_expr(&e)?;
3203 s.s.word( ".")?;
3204 s.print_usize(float.trunc() as usize)?;
3205 s.pclose()?;
3206 s.s.word(".")?;
3207 s.s.word(fstr.splitn(2, ".").last().unwrap().to_string())
3208 });
3209 err.span_suggestion(
3210 lo.to(self.prev_span),
3211 "try parenthesizing the first index",
3212 sugg,
3213 Applicability::MachineApplicable
3214 );
3215 }
3216 return Err(err);
3217
3218 }
3219 _ => {
3220 // FIXME Could factor this out into non_fatal_unexpected or something.
3221 let actual = self.this_token_to_string();
3222 self.span_err(self.span, &format!("unexpected token: `{}`", actual));
3223 }
3224 }
3225 continue;
3226 }
3227 if self.expr_is_complete(&e) { break; }
3228 match self.token {
3229 // expr(...)
3230 token::OpenDelim(token::Paren) => {
3231 let es = self.parse_unspanned_seq(
3232 &token::OpenDelim(token::Paren),
3233 &token::CloseDelim(token::Paren),
3234 SeqSep::trailing_allowed(token::Comma),
3235 |p| Ok(p.parse_expr()?)
3236 )?;
3237 hi = self.prev_span;
3238
3239 let nd = self.mk_call(e, es);
3240 e = self.mk_expr(lo.to(hi), nd, ThinVec::new());
3241 }
3242
3243 // expr[...]
3244 // Could be either an index expression or a slicing expression.
3245 token::OpenDelim(token::Bracket) => {
3246 self.bump();
3247 let ix = self.parse_expr()?;
3248 hi = self.span;
3249 self.expect(&token::CloseDelim(token::Bracket))?;
3250 let index = self.mk_index(e, ix);
3251 e = self.mk_expr(lo.to(hi), index, ThinVec::new())
3252 }
3253 _ => return Ok(e)
3254 }
3255 }
3256 return Ok(e);
3257 }
3258
3259 crate fn process_potential_macro_variable(&mut self) {
3260 let (token, span) = match self.token {
3261 token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() &&
3262 self.look_ahead(1, |t| t.is_ident()) => {
3263 self.bump();
3264 let name = match self.token {
3265 token::Ident(ident, _) => ident,
3266 _ => unreachable!()
3267 };
3268 let mut err = self.fatal(&format!("unknown macro variable `{}`", name));
3269 err.span_label(self.span, "unknown macro variable");
3270 err.emit();
3271 self.bump();
3272 return
3273 }
3274 token::Interpolated(ref nt) => {
3275 self.meta_var_span = Some(self.span);
3276 // Interpolated identifier and lifetime tokens are replaced with usual identifier
3277 // and lifetime tokens, so the former are never encountered during normal parsing.
3278 match **nt {
3279 token::NtIdent(ident, is_raw) => (token::Ident(ident, is_raw), ident.span),
3280 token::NtLifetime(ident) => (token::Lifetime(ident), ident.span),
3281 _ => return,
3282 }
3283 }
3284 _ => return,
3285 };
3286 self.token = token;
3287 self.span = span;
3288 }
3289
3290 /// Parses a single token tree from the input.
3291 crate fn parse_token_tree(&mut self) -> TokenTree {
3292 match self.token {
3293 token::OpenDelim(..) => {
3294 let frame = mem::replace(&mut self.token_cursor.frame,
3295 self.token_cursor.stack.pop().unwrap());
3296 self.span = frame.span.entire();
3297 self.bump();
3298 TokenTree::Delimited(
3299 frame.span,
3300 frame.delim,
3301 frame.tree_cursor.stream.into(),
3302 )
3303 },
3304 token::CloseDelim(_) | token::Eof => unreachable!(),
3305 _ => {
3306 let (token, span) = (mem::replace(&mut self.token, token::Whitespace), self.span);
3307 self.bump();
3308 TokenTree::Token(span, token)
3309 }
3310 }
3311 }
3312
3313 // parse a stream of tokens into a list of TokenTree's,
3314 // up to EOF.
3315 pub fn parse_all_token_trees(&mut self) -> PResult<'a, Vec<TokenTree>> {
3316 let mut tts = Vec::new();
3317 while self.token != token::Eof {
3318 tts.push(self.parse_token_tree());
3319 }
3320 Ok(tts)
3321 }
3322
3323 pub fn parse_tokens(&mut self) -> TokenStream {
3324 let mut result = Vec::new();
3325 loop {
3326 match self.token {
3327 token::Eof | token::CloseDelim(..) => break,
3328 _ => result.push(self.parse_token_tree().into()),
3329 }
3330 }
3331 TokenStream::new(result)
3332 }
3333
3334 /// Parse a prefix-unary-operator expr
3335 fn parse_prefix_expr(&mut self,
3336 already_parsed_attrs: Option<ThinVec<Attribute>>)
3337 -> PResult<'a, P<Expr>> {
3338 let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
3339 let lo = self.span;
3340 // Note: when adding new unary operators, don't forget to adjust Token::can_begin_expr()
3341 let (hi, ex) = match self.token {
3342 token::Not => {
3343 self.bump();
3344 let e = self.parse_prefix_expr(None);
3345 let (span, e) = self.interpolated_or_expr_span(e)?;
3346 (lo.to(span), self.mk_unary(UnOp::Not, e))
3347 }
3348 // Suggest `!` for bitwise negation when encountering a `~`
3349 token::Tilde => {
3350 self.bump();
3351 let e = self.parse_prefix_expr(None);
3352 let (span, e) = self.interpolated_or_expr_span(e)?;
3353 let span_of_tilde = lo;
3354 let mut err = self.diagnostic()
3355 .struct_span_err(span_of_tilde, "`~` cannot be used as a unary operator");
3356 err.span_suggestion_short(
3357 span_of_tilde,
3358 "use `!` to perform bitwise negation",
3359 "!".to_owned(),
3360 Applicability::MachineApplicable
3361 );
3362 err.emit();
3363 (lo.to(span), self.mk_unary(UnOp::Not, e))
3364 }
3365 token::BinOp(token::Minus) => {
3366 self.bump();
3367 let e = self.parse_prefix_expr(None);
3368 let (span, e) = self.interpolated_or_expr_span(e)?;
3369 (lo.to(span), self.mk_unary(UnOp::Neg, e))
3370 }
3371 token::BinOp(token::Star) => {
3372 self.bump();
3373 let e = self.parse_prefix_expr(None);
3374 let (span, e) = self.interpolated_or_expr_span(e)?;
3375 (lo.to(span), self.mk_unary(UnOp::Deref, e))
3376 }
3377 token::BinOp(token::And) | token::AndAnd => {
3378 self.expect_and()?;
3379 let m = self.parse_mutability();
3380 let e = self.parse_prefix_expr(None);
3381 let (span, e) = self.interpolated_or_expr_span(e)?;
3382 (lo.to(span), ExprKind::AddrOf(m, e))
3383 }
3384 token::Ident(..) if self.token.is_keyword(keywords::In) => {
3385 self.bump();
3386 let place = self.parse_expr_res(
3387 Restrictions::NO_STRUCT_LITERAL,
3388 None,
3389 )?;
3390 let blk = self.parse_block()?;
3391 let span = blk.span;
3392 let blk_expr = self.mk_expr(span, ExprKind::Block(blk, None), ThinVec::new());
3393 (lo.to(span), ExprKind::ObsoleteInPlace(place, blk_expr))
3394 }
3395 token::Ident(..) if self.token.is_keyword(keywords::Box) => {
3396 self.bump();
3397 let e = self.parse_prefix_expr(None);
3398 let (span, e) = self.interpolated_or_expr_span(e)?;
3399 (lo.to(span), ExprKind::Box(e))
3400 }
3401 token::Ident(..) if self.token.is_ident_named("not") => {
3402 // `not` is just an ordinary identifier in Rust-the-language,
3403 // but as `rustc`-the-compiler, we can issue clever diagnostics
3404 // for confused users who really want to say `!`
3405 let token_cannot_continue_expr = |t: &token::Token| match *t {
3406 // These tokens can start an expression after `!`, but
3407 // can't continue an expression after an ident
3408 token::Ident(ident, is_raw) => token::ident_can_begin_expr(ident, is_raw),
3409 token::Literal(..) | token::Pound => true,
3410 token::Interpolated(ref nt) => match **nt {
3411 token::NtIdent(..) | token::NtExpr(..) |
3412 token::NtBlock(..) | token::NtPath(..) => true,
3413 _ => false,
3414 },
3415 _ => false
3416 };
3417 let cannot_continue_expr = self.look_ahead(1, token_cannot_continue_expr);
3418 if cannot_continue_expr {
3419 self.bump();
3420 // Emit the error ...
3421 let mut err = self.diagnostic()
3422 .struct_span_err(self.span,
3423 &format!("unexpected {} after identifier",
3424 self.this_token_descr()));
3425 // span the `not` plus trailing whitespace to avoid
3426 // trailing whitespace after the `!` in our suggestion
3427 let to_replace = self.sess.source_map()
3428 .span_until_non_whitespace(lo.to(self.span));
3429 err.span_suggestion_short(
3430 to_replace,
3431 "use `!` to perform logical negation",
3432 "!".to_owned(),
3433 Applicability::MachineApplicable
3434 );
3435 err.emit();
3436 // —and recover! (just as if we were in the block
3437 // for the `token::Not` arm)
3438 let e = self.parse_prefix_expr(None);
3439 let (span, e) = self.interpolated_or_expr_span(e)?;
3440 (lo.to(span), self.mk_unary(UnOp::Not, e))
3441 } else {
3442 return self.parse_dot_or_call_expr(Some(attrs));
3443 }
3444 }
3445 _ => { return self.parse_dot_or_call_expr(Some(attrs)); }
3446 };
3447 return Ok(self.mk_expr(lo.to(hi), ex, attrs));
3448 }
3449
3450 /// Parses an associative expression.
3451 ///
3452 /// This parses an expression accounting for associativity and precedence of the operators in
3453 /// the expression.
3454 #[inline]
3455 fn parse_assoc_expr(&mut self,
3456 already_parsed_attrs: Option<ThinVec<Attribute>>)
3457 -> PResult<'a, P<Expr>> {
3458 self.parse_assoc_expr_with(0, already_parsed_attrs.into())
3459 }
3460
3461 /// Parses an associative expression with operators of at least `min_prec` precedence.
3462 fn parse_assoc_expr_with(&mut self,
3463 min_prec: usize,
3464 lhs: LhsExpr)
3465 -> PResult<'a, P<Expr>> {
3466 let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
3467 expr
3468 } else {
3469 let attrs = match lhs {
3470 LhsExpr::AttributesParsed(attrs) => Some(attrs),
3471 _ => None,
3472 };
3473 if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token) {
3474 return self.parse_prefix_range_expr(attrs);
3475 } else {
3476 self.parse_prefix_expr(attrs)?
3477 }
3478 };
3479
3480 if self.expr_is_complete(&lhs) {
3481 // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
3482 return Ok(lhs);
3483 }
3484 self.expected_tokens.push(TokenType::Operator);
3485 while let Some(op) = AssocOp::from_token(&self.token) {
3486
3487 // Adjust the span for interpolated LHS to point to the `$lhs` token and not to what
3488 // it refers to. Interpolated identifiers are unwrapped early and never show up here
3489 // as `PrevTokenKind::Interpolated` so if LHS is a single identifier we always process
3490 // it as "interpolated", it doesn't change the answer for non-interpolated idents.
3491 let lhs_span = match (self.prev_token_kind, &lhs.node) {
3492 (PrevTokenKind::Interpolated, _) => self.prev_span,
3493 (PrevTokenKind::Ident, &ExprKind::Path(None, ref path))
3494 if path.segments.len() == 1 => self.prev_span,
3495 _ => lhs.span,
3496 };
3497
3498 let cur_op_span = self.span;
3499 let restrictions = if op.is_assign_like() {
3500 self.restrictions & Restrictions::NO_STRUCT_LITERAL
3501 } else {
3502 self.restrictions
3503 };
3504 if op.precedence() < min_prec {
3505 break;
3506 }
3507 // Check for deprecated `...` syntax
3508 if self.token == token::DotDotDot && op == AssocOp::DotDotEq {
3509 self.err_dotdotdot_syntax(self.span);
3510 }
3511
3512 self.bump();
3513 if op.is_comparison() {
3514 self.check_no_chained_comparison(&lhs, &op);
3515 }
3516 // Special cases:
3517 if op == AssocOp::As {
3518 lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?;
3519 continue
3520 } else if op == AssocOp::Colon {
3521 lhs = match self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type) {
3522 Ok(lhs) => lhs,
3523 Err(mut err) => {
3524 err.span_label(self.span,
3525 "expecting a type here because of type ascription");
3526 let cm = self.sess.source_map();
3527 let cur_pos = cm.lookup_char_pos(self.span.lo());
3528 let op_pos = cm.lookup_char_pos(cur_op_span.hi());
3529 if cur_pos.line != op_pos.line {
3530 err.span_suggestion(
3531 cur_op_span,
3532 "try using a semicolon",
3533 ";".to_string(),
3534 Applicability::MaybeIncorrect // speculative
3535 );
3536 }
3537 return Err(err);
3538 }
3539 };
3540 continue
3541 } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
3542 // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
3543 // generalise it to the Fixity::None code.
3544 //
3545 // We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other
3546 // two variants are handled with `parse_prefix_range_expr` call above.
3547 let rhs = if self.is_at_start_of_range_notation_rhs() {
3548 Some(self.parse_assoc_expr_with(op.precedence() + 1,
3549 LhsExpr::NotYetParsed)?)
3550 } else {
3551 None
3552 };
3553 let (lhs_span, rhs_span) = (lhs.span, if let Some(ref x) = rhs {
3554 x.span
3555 } else {
3556 cur_op_span
3557 });
3558 let limits = if op == AssocOp::DotDot {
3559 RangeLimits::HalfOpen
3560 } else {
3561 RangeLimits::Closed
3562 };
3563
3564 let r = self.mk_range(Some(lhs), rhs, limits)?;
3565 lhs = self.mk_expr(lhs_span.to(rhs_span), r, ThinVec::new());
3566 break
3567 }
3568
3569 let rhs = match op.fixity() {
3570 Fixity::Right => self.with_res(
3571 restrictions - Restrictions::STMT_EXPR,
3572 |this| {
3573 this.parse_assoc_expr_with(op.precedence(),
3574 LhsExpr::NotYetParsed)
3575 }),
3576 Fixity::Left => self.with_res(
3577 restrictions - Restrictions::STMT_EXPR,
3578 |this| {
3579 this.parse_assoc_expr_with(op.precedence() + 1,
3580 LhsExpr::NotYetParsed)
3581 }),
3582 // We currently have no non-associative operators that are not handled above by
3583 // the special cases. The code is here only for future convenience.
3584 Fixity::None => self.with_res(
3585 restrictions - Restrictions::STMT_EXPR,
3586 |this| {
3587 this.parse_assoc_expr_with(op.precedence() + 1,
3588 LhsExpr::NotYetParsed)
3589 }),
3590 }?;
3591
3592 // Make sure that the span of the parent node is larger than the span of lhs and rhs,
3593 // including the attributes.
3594 let lhs_span = lhs
3595 .attrs
3596 .iter()
3597 .filter(|a| a.style == AttrStyle::Outer)
3598 .next()
3599 .map_or(lhs_span, |a| a.span);
3600 let span = lhs_span.to(rhs.span);
3601 lhs = match op {
3602 AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide |
3603 AssocOp::Modulus | AssocOp::LAnd | AssocOp::LOr | AssocOp::BitXor |
3604 AssocOp::BitAnd | AssocOp::BitOr | AssocOp::ShiftLeft | AssocOp::ShiftRight |
3605 AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual |
3606 AssocOp::Greater | AssocOp::GreaterEqual => {
3607 let ast_op = op.to_ast_binop().unwrap();
3608 let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs);
3609 self.mk_expr(span, binary, ThinVec::new())
3610 }
3611 AssocOp::Assign =>
3612 self.mk_expr(span, ExprKind::Assign(lhs, rhs), ThinVec::new()),
3613 AssocOp::ObsoleteInPlace =>
3614 self.mk_expr(span, ExprKind::ObsoleteInPlace(lhs, rhs), ThinVec::new()),
3615 AssocOp::AssignOp(k) => {
3616 let aop = match k {
3617 token::Plus => BinOpKind::Add,
3618 token::Minus => BinOpKind::Sub,
3619 token::Star => BinOpKind::Mul,
3620 token::Slash => BinOpKind::Div,
3621 token::Percent => BinOpKind::Rem,
3622 token::Caret => BinOpKind::BitXor,
3623 token::And => BinOpKind::BitAnd,
3624 token::Or => BinOpKind::BitOr,
3625 token::Shl => BinOpKind::Shl,
3626 token::Shr => BinOpKind::Shr,
3627 };
3628 let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs);
3629 self.mk_expr(span, aopexpr, ThinVec::new())
3630 }
3631 AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => {
3632 self.bug("AssocOp should have been handled by special case")
3633 }
3634 };
3635
3636 if op.fixity() == Fixity::None { break }
3637 }
3638 Ok(lhs)
3639 }
3640
3641 fn parse_assoc_op_cast(&mut self, lhs: P<Expr>, lhs_span: Span,
3642 expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind)
3643 -> PResult<'a, P<Expr>> {
3644 let mk_expr = |this: &mut Self, rhs: P<Ty>| {
3645 this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs), ThinVec::new())
3646 };
3647
3648 // Save the state of the parser before parsing type normally, in case there is a
3649 // LessThan comparison after this cast.
3650 let parser_snapshot_before_type = self.clone();
3651 match self.parse_ty_no_plus() {
3652 Ok(rhs) => {
3653 Ok(mk_expr(self, rhs))
3654 }
3655 Err(mut type_err) => {
3656 // Rewind to before attempting to parse the type with generics, to recover
3657 // from situations like `x as usize < y` in which we first tried to parse
3658 // `usize < y` as a type with generic arguments.
3659 let parser_snapshot_after_type = self.clone();
3660 mem::replace(self, parser_snapshot_before_type);
3661
3662 match self.parse_path(PathStyle::Expr) {
3663 Ok(path) => {
3664 let (op_noun, op_verb) = match self.token {
3665 token::Lt => ("comparison", "comparing"),
3666 token::BinOp(token::Shl) => ("shift", "shifting"),
3667 _ => {
3668 // We can end up here even without `<` being the next token, for
3669 // example because `parse_ty_no_plus` returns `Err` on keywords,
3670 // but `parse_path` returns `Ok` on them due to error recovery.
3671 // Return original error and parser state.
3672 mem::replace(self, parser_snapshot_after_type);
3673 return Err(type_err);
3674 }
3675 };
3676
3677 // Successfully parsed the type path leaving a `<` yet to parse.
3678 type_err.cancel();
3679
3680 // Report non-fatal diagnostics, keep `x as usize` as an expression
3681 // in AST and continue parsing.
3682 let msg = format!("`<` is interpreted as a start of generic \
3683 arguments for `{}`, not a {}", path, op_noun);
3684 let mut err = self.sess.span_diagnostic.struct_span_err(self.span, &msg);
3685 err.span_label(self.look_ahead_span(1).to(parser_snapshot_after_type.span),
3686 "interpreted as generic arguments");
3687 err.span_label(self.span, format!("not interpreted as {}", op_noun));
3688
3689 let expr = mk_expr(self, P(Ty {
3690 span: path.span,
3691 node: TyKind::Path(None, path),
3692 id: ast::DUMMY_NODE_ID
3693 }));
3694
3695 let expr_str = self.sess.source_map().span_to_snippet(expr.span)
3696 .unwrap_or_else(|_| pprust::expr_to_string(&expr));
3697 err.span_suggestion(
3698 expr.span,
3699 &format!("try {} the cast value", op_verb),
3700 format!("({})", expr_str),
3701 Applicability::MachineApplicable
3702 );
3703 err.emit();
3704
3705 Ok(expr)
3706 }
3707 Err(mut path_err) => {
3708 // Couldn't parse as a path, return original error and parser state.
3709 path_err.cancel();
3710 mem::replace(self, parser_snapshot_after_type);
3711 Err(type_err)
3712 }
3713 }
3714 }
3715 }
3716 }
3717
3718 /// Produce an error if comparison operators are chained (RFC #558).
3719 /// We only need to check lhs, not rhs, because all comparison ops
3720 /// have same precedence and are left-associative
3721 fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) {
3722 debug_assert!(outer_op.is_comparison(),
3723 "check_no_chained_comparison: {:?} is not comparison",
3724 outer_op);
3725 match lhs.node {
3726 ExprKind::Binary(op, _, _) if op.node.is_comparison() => {
3727 // respan to include both operators
3728 let op_span = op.span.to(self.span);
3729 let mut err = self.diagnostic().struct_span_err(op_span,
3730 "chained comparison operators require parentheses");
3731 if op.node == BinOpKind::Lt &&
3732 *outer_op == AssocOp::Less || // Include `<` to provide this recommendation
3733 *outer_op == AssocOp::Greater // even in a case like the following:
3734 { // Foo<Bar<Baz<Qux, ()>>>
3735 err.help(
3736 "use `::<...>` instead of `<...>` if you meant to specify type arguments");
3737 err.help("or use `(...)` if you meant to specify fn arguments");
3738 }
3739 err.emit();
3740 }
3741 _ => {}
3742 }
3743 }
3744
3745 /// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr`
3746 fn parse_prefix_range_expr(&mut self,
3747 already_parsed_attrs: Option<ThinVec<Attribute>>)
3748 -> PResult<'a, P<Expr>> {
3749 // Check for deprecated `...` syntax
3750 if self.token == token::DotDotDot {
3751 self.err_dotdotdot_syntax(self.span);
3752 }
3753
3754 debug_assert!([token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token),
3755 "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq",
3756 self.token);
3757 let tok = self.token.clone();
3758 let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
3759 let lo = self.span;
3760 let mut hi = self.span;
3761 self.bump();
3762 let opt_end = if self.is_at_start_of_range_notation_rhs() {
3763 // RHS must be parsed with more associativity than the dots.
3764 let next_prec = AssocOp::from_token(&tok).unwrap().precedence() + 1;
3765 Some(self.parse_assoc_expr_with(next_prec,
3766 LhsExpr::NotYetParsed)
3767 .map(|x|{
3768 hi = x.span;
3769 x
3770 })?)
3771 } else {
3772 None
3773 };
3774 let limits = if tok == token::DotDot {
3775 RangeLimits::HalfOpen
3776 } else {
3777 RangeLimits::Closed
3778 };
3779
3780 let r = self.mk_range(None, opt_end, limits)?;
3781 Ok(self.mk_expr(lo.to(hi), r, attrs))
3782 }
3783
3784 fn is_at_start_of_range_notation_rhs(&self) -> bool {
3785 if self.token.can_begin_expr() {
3786 // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
3787 if self.token == token::OpenDelim(token::Brace) {
3788 return !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
3789 }
3790 true
3791 } else {
3792 false
3793 }
3794 }
3795
3796 /// Parses an `if` or `if let` expression (`if` token already eaten).
3797 fn parse_if_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3798 if self.check_keyword(keywords::Let) {
3799 return self.parse_if_let_expr(attrs);
3800 }
3801 let lo = self.prev_span;
3802 let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3803
3804 // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
3805 // verify that the last statement is either an implicit return (no `;`) or an explicit
3806 // return. This won't catch blocks with an explicit `return`, but that would be caught by
3807 // the dead code lint.
3808 if self.eat_keyword(keywords::Else) || !cond.returns() {
3809 let sp = self.sess.source_map().next_point(lo);
3810 let mut err = self.diagnostic()
3811 .struct_span_err(sp, "missing condition for `if` statemement");
3812 err.span_label(sp, "expected if condition here");
3813 return Err(err)
3814 }
3815 let not_block = self.token != token::OpenDelim(token::Brace);
3816 let thn = self.parse_block().map_err(|mut err| {
3817 if not_block {
3818 err.span_label(lo, "this `if` statement has a condition, but no block");
3819 }
3820 err
3821 })?;
3822 let mut els: Option<P<Expr>> = None;
3823 let mut hi = thn.span;
3824 if self.eat_keyword(keywords::Else) {
3825 let elexpr = self.parse_else_expr()?;
3826 hi = elexpr.span;
3827 els = Some(elexpr);
3828 }
3829 Ok(self.mk_expr(lo.to(hi), ExprKind::If(cond, thn, els), attrs))
3830 }
3831
3832 /// Parses an `if let` expression (`if` token already eaten).
3833 fn parse_if_let_expr(&mut self, attrs: ThinVec<Attribute>)
3834 -> PResult<'a, P<Expr>> {
3835 let lo = self.prev_span;
3836 self.expect_keyword(keywords::Let)?;
3837 let pats = self.parse_pats()?;
3838 self.expect(&token::Eq)?;
3839 let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3840 let thn = self.parse_block()?;
3841 let (hi, els) = if self.eat_keyword(keywords::Else) {
3842 let expr = self.parse_else_expr()?;
3843 (expr.span, Some(expr))
3844 } else {
3845 (thn.span, None)
3846 };
3847 Ok(self.mk_expr(lo.to(hi), ExprKind::IfLet(pats, expr, thn, els), attrs))
3848 }
3849
3850 /// Parses `move |args| expr`.
3851 fn parse_lambda_expr(&mut self,
3852 attrs: ThinVec<Attribute>)
3853 -> PResult<'a, P<Expr>>
3854 {
3855 let lo = self.span;
3856 let movability = if self.eat_keyword(keywords::Static) {
3857 Movability::Static
3858 } else {
3859 Movability::Movable
3860 };
3861 let asyncness = if self.span.rust_2018() {
3862 self.parse_asyncness()
3863 } else {
3864 IsAsync::NotAsync
3865 };
3866 let capture_clause = if self.eat_keyword(keywords::Move) {
3867 CaptureBy::Value
3868 } else {
3869 CaptureBy::Ref
3870 };
3871 let decl = self.parse_fn_block_decl()?;
3872 let decl_hi = self.prev_span;
3873 let body = match decl.output {
3874 FunctionRetTy::Default(_) => {
3875 let restrictions = self.restrictions - Restrictions::STMT_EXPR;
3876 self.parse_expr_res(restrictions, None)?
3877 },
3878 _ => {
3879 // If an explicit return type is given, require a
3880 // block to appear (RFC 968).
3881 let body_lo = self.span;
3882 self.parse_block_expr(None, body_lo, BlockCheckMode::Default, ThinVec::new())?
3883 }
3884 };
3885
3886 Ok(self.mk_expr(
3887 lo.to(body.span),
3888 ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)),
3889 attrs))
3890 }
3891
3892 // `else` token already eaten
3893 fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
3894 if self.eat_keyword(keywords::If) {
3895 return self.parse_if_expr(ThinVec::new());
3896 } else {
3897 let blk = self.parse_block()?;
3898 return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None), ThinVec::new()));
3899 }
3900 }
3901
3902 /// Parse a 'for' .. 'in' expression ('for' token already eaten)
3903 fn parse_for_expr(&mut self, opt_label: Option<Label>,
3904 span_lo: Span,
3905 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3906 // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
3907
3908 let pat = self.parse_top_level_pat()?;
3909 if !self.eat_keyword(keywords::In) {
3910 let in_span = self.prev_span.between(self.span);
3911 let mut err = self.sess.span_diagnostic
3912 .struct_span_err(in_span, "missing `in` in `for` loop");
3913 err.span_suggestion_short(
3914 in_span, "try adding `in` here", " in ".into(),
3915 // has been misleading, at least in the past (closed Issue #48492)
3916 Applicability::MaybeIncorrect
3917 );
3918 err.emit();
3919 }
3920 let in_span = self.prev_span;
3921 if self.eat_keyword(keywords::In) {
3922 // a common typo: `for _ in in bar {}`
3923 let mut err = self.sess.span_diagnostic.struct_span_err(
3924 self.prev_span,
3925 "expected iterable, found keyword `in`",
3926 );
3927 err.span_suggestion_short(
3928 in_span.until(self.prev_span),
3929 "remove the duplicated `in`",
3930 String::new(),
3931 Applicability::MachineApplicable,
3932 );
3933 err.note("if you meant to use emplacement syntax, it is obsolete (for now, anyway)");
3934 err.note("for more information on the status of emplacement syntax, see <\
3935 https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>");
3936 err.emit();
3937 }
3938 let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3939 let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
3940 attrs.extend(iattrs);
3941
3942 let hi = self.prev_span;
3943 Ok(self.mk_expr(span_lo.to(hi), ExprKind::ForLoop(pat, expr, loop_block, opt_label), attrs))
3944 }
3945
3946 /// Parses a `while` or `while let` expression (`while` token already eaten).
3947 fn parse_while_expr(&mut self, opt_label: Option<Label>,
3948 span_lo: Span,
3949 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3950 if self.token.is_keyword(keywords::Let) {
3951 return self.parse_while_let_expr(opt_label, span_lo, attrs);
3952 }
3953 let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3954 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3955 attrs.extend(iattrs);
3956 let span = span_lo.to(body.span);
3957 return Ok(self.mk_expr(span, ExprKind::While(cond, body, opt_label), attrs));
3958 }
3959
3960 /// Parses a `while let` expression (`while` token already eaten).
3961 fn parse_while_let_expr(&mut self, opt_label: Option<Label>,
3962 span_lo: Span,
3963 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3964 self.expect_keyword(keywords::Let)?;
3965 let pats = self.parse_pats()?;
3966 self.expect(&token::Eq)?;
3967 let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
3968 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3969 attrs.extend(iattrs);
3970 let span = span_lo.to(body.span);
3971 return Ok(self.mk_expr(span, ExprKind::WhileLet(pats, expr, body, opt_label), attrs));
3972 }
3973
3974 // parse `loop {...}`, `loop` token already eaten
3975 fn parse_loop_expr(&mut self, opt_label: Option<Label>,
3976 span_lo: Span,
3977 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
3978 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3979 attrs.extend(iattrs);
3980 let span = span_lo.to(body.span);
3981 Ok(self.mk_expr(span, ExprKind::Loop(body, opt_label), attrs))
3982 }
3983
3984 /// Parses an `async move {...}` expression.
3985 pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>)
3986 -> PResult<'a, P<Expr>>
3987 {
3988 let span_lo = self.span;
3989 self.expect_keyword(keywords::Async)?;
3990 let capture_clause = if self.eat_keyword(keywords::Move) {
3991 CaptureBy::Value
3992 } else {
3993 CaptureBy::Ref
3994 };
3995 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
3996 attrs.extend(iattrs);
3997 Ok(self.mk_expr(
3998 span_lo.to(body.span),
3999 ExprKind::Async(capture_clause, ast::DUMMY_NODE_ID, body), attrs))
4000 }
4001
4002 /// Parses a `try {...}` expression (`try` token already eaten).
4003 fn parse_try_block(&mut self, span_lo: Span, mut attrs: ThinVec<Attribute>)
4004 -> PResult<'a, P<Expr>>
4005 {
4006 let (iattrs, body) = self.parse_inner_attrs_and_block()?;
4007 attrs.extend(iattrs);
4008 Ok(self.mk_expr(span_lo.to(body.span), ExprKind::TryBlock(body), attrs))
4009 }
4010
4011 // `match` token already eaten
4012 fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
4013 let match_span = self.prev_span;
4014 let lo = self.prev_span;
4015 let discriminant = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL,
4016 None)?;
4017 if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) {
4018 if self.token == token::Token::Semi {
4019 e.span_suggestion_short(
4020 match_span,
4021 "try removing this `match`",
4022 String::new(),
4023 Applicability::MaybeIncorrect // speculative
4024 );
4025 }
4026 return Err(e)
4027 }
4028 attrs.extend(self.parse_inner_attributes()?);
4029
4030 let mut arms: Vec<Arm> = Vec::new();
4031 while self.token != token::CloseDelim(token::Brace) {
4032 match self.parse_arm() {
4033 Ok(arm) => arms.push(arm),
4034 Err(mut e) => {
4035 // Recover by skipping to the end of the block.
4036 e.emit();
4037 self.recover_stmt();
4038 let span = lo.to(self.span);
4039 if self.token == token::CloseDelim(token::Brace) {
4040 self.bump();
4041 }
4042 return Ok(self.mk_expr(span, ExprKind::Match(discriminant, arms), attrs));
4043 }
4044 }
4045 }
4046 let hi = self.span;
4047 self.bump();
4048 return Ok(self.mk_expr(lo.to(hi), ExprKind::Match(discriminant, arms), attrs));
4049 }
4050
4051 crate fn parse_arm(&mut self) -> PResult<'a, Arm> {
4052 maybe_whole!(self, NtArm, |x| x);
4053
4054 let attrs = self.parse_outer_attributes()?;
4055 let pats = self.parse_pats()?;
4056 let guard = if self.eat_keyword(keywords::If) {
4057 Some(Guard::If(self.parse_expr()?))
4058 } else {
4059 None
4060 };
4061 let arrow_span = self.span;
4062 self.expect(&token::FatArrow)?;
4063 let arm_start_span = self.span;
4064
4065 let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None)
4066 .map_err(|mut err| {
4067 err.span_label(arrow_span, "while parsing the `match` arm starting here");
4068 err
4069 })?;
4070
4071 let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
4072 && self.token != token::CloseDelim(token::Brace);
4073
4074 if require_comma {
4075 let cm = self.sess.source_map();
4076 self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])
4077 .map_err(|mut err| {
4078 match (cm.span_to_lines(expr.span), cm.span_to_lines(arm_start_span)) {
4079 (Ok(ref expr_lines), Ok(ref arm_start_lines))
4080 if arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col
4081 && expr_lines.lines.len() == 2
4082 && self.token == token::FatArrow => {
4083 // We check whether there's any trailing code in the parse span,
4084 // if there isn't, we very likely have the following:
4085 //
4086 // X | &Y => "y"
4087 // | -- - missing comma
4088 // | |
4089 // | arrow_span
4090 // X | &X => "x"
4091 // | - ^^ self.span
4092 // | |
4093 // | parsed until here as `"y" & X`
4094 err.span_suggestion_short(
4095 cm.next_point(arm_start_span),
4096 "missing a comma here to end this `match` arm",
4097 ",".to_owned(),
4098 Applicability::MachineApplicable
4099 );
4100 }
4101 _ => {
4102 err.span_label(arrow_span,
4103 "while parsing the `match` arm starting here");
4104 }
4105 }
4106 err
4107 })?;
4108 } else {
4109 self.eat(&token::Comma);
4110 }
4111
4112 Ok(ast::Arm {
4113 attrs,
4114 pats,
4115 guard,
4116 body: expr,
4117 })
4118 }
4119
4120 /// Parses an expression.
4121 #[inline]
4122 pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
4123 self.parse_expr_res(Restrictions::empty(), None)
4124 }
4125
4126 /// Evaluates the closure with restrictions in place.
4127 ///
4128 /// Afters the closure is evaluated, restrictions are reset.
4129 fn with_res<F, T>(&mut self, r: Restrictions, f: F) -> T
4130 where F: FnOnce(&mut Self) -> T
4131 {
4132 let old = self.restrictions;
4133 self.restrictions = r;
4134 let r = f(self);
4135 self.restrictions = old;
4136 return r;
4137
4138 }
4139
4140 /// Parses an expression, subject to the given restrictions.
4141 #[inline]
4142 fn parse_expr_res(&mut self, r: Restrictions,
4143 already_parsed_attrs: Option<ThinVec<Attribute>>)
4144 -> PResult<'a, P<Expr>> {
4145 self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
4146 }
4147
4148 /// Parses the RHS of a local variable declaration (e.g., '= 14;').
4149 fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option<P<Expr>>> {
4150 if self.eat(&token::Eq) {
4151 Ok(Some(self.parse_expr()?))
4152 } else if skip_eq {
4153 Ok(Some(self.parse_expr()?))
4154 } else {
4155 Ok(None)
4156 }
4157 }
4158
4159 /// Parses patterns, separated by '|' s.
4160 fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
4161 // Allow a '|' before the pats (RFC 1925 + RFC 2530)
4162 self.eat(&token::BinOp(token::Or));
4163
4164 let mut pats = Vec::new();
4165 loop {
4166 pats.push(self.parse_top_level_pat()?);
4167
4168 if self.token == token::OrOr {
4169 let mut err = self.struct_span_err(self.span,
4170 "unexpected token `||` after pattern");
4171 err.span_suggestion(
4172 self.span,
4173 "use a single `|` to specify multiple patterns",
4174 "|".to_owned(),
4175 Applicability::MachineApplicable
4176 );
4177 err.emit();
4178 self.bump();
4179 } else if self.eat(&token::BinOp(token::Or)) {
4180 // This is a No-op. Continue the loop to parse the next
4181 // pattern.
4182 } else {
4183 return Ok(pats);
4184 }
4185 };
4186 }
4187
4188 // Parses a parenthesized list of patterns like
4189 // `()`, `(p)`, `(p,)`, `(p, q)`, or `(p, .., q)`. Returns:
4190 // - a vector of the patterns that were parsed
4191 // - an option indicating the index of the `..` element
4192 // - a boolean indicating whether a trailing comma was present.
4193 // Trailing commas are significant because (p) and (p,) are different patterns.
4194 fn parse_parenthesized_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<usize>, bool)> {
4195 self.expect(&token::OpenDelim(token::Paren))?;
4196 let result = self.parse_pat_list()?;
4197 self.expect(&token::CloseDelim(token::Paren))?;
4198 Ok(result)
4199 }
4200
4201 fn parse_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<usize>, bool)> {
4202 let mut fields = Vec::new();
4203 let mut ddpos = None;
4204 let mut trailing_comma = false;
4205 loop {
4206 if self.eat(&token::DotDot) {
4207 if ddpos.is_none() {
4208 ddpos = Some(fields.len());
4209 } else {
4210 // Emit a friendly error, ignore `..` and continue parsing
4211 self.struct_span_err(
4212 self.prev_span,
4213 "`..` can only be used once per tuple or tuple struct pattern",
4214 )
4215 .span_label(self.prev_span, "can only be used once per pattern")
4216 .emit();
4217 }
4218 } else if !self.check(&token::CloseDelim(token::Paren)) {
4219 fields.push(self.parse_pat(None)?);
4220 } else {
4221 break
4222 }
4223
4224 trailing_comma = self.eat(&token::Comma);
4225 if !trailing_comma {
4226 break
4227 }
4228 }
4229
4230 if ddpos == Some(fields.len()) && trailing_comma {
4231 // `..` needs to be followed by `)` or `, pat`, `..,)` is disallowed.
4232 let msg = "trailing comma is not permitted after `..`";
4233 self.struct_span_err(self.prev_span, msg)
4234 .span_label(self.prev_span, msg)
4235 .emit();
4236 }
4237
4238 Ok((fields, ddpos, trailing_comma))
4239 }
4240
4241 fn parse_pat_vec_elements(
4242 &mut self,
4243 ) -> PResult<'a, (Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>)> {
4244 let mut before = Vec::new();
4245 let mut slice = None;
4246 let mut after = Vec::new();
4247 let mut first = true;
4248 let mut before_slice = true;
4249
4250 while self.token != token::CloseDelim(token::Bracket) {
4251 if first {
4252 first = false;
4253 } else {
4254 self.expect(&token::Comma)?;
4255
4256 if self.token == token::CloseDelim(token::Bracket)
4257 && (before_slice || !after.is_empty()) {
4258 break
4259 }
4260 }
4261
4262 if before_slice {
4263 if self.eat(&token::DotDot) {
4264
4265 if self.check(&token::Comma) ||
4266 self.check(&token::CloseDelim(token::Bracket)) {
4267 slice = Some(P(Pat {
4268 id: ast::DUMMY_NODE_ID,
4269 node: PatKind::Wild,
4270 span: self.prev_span,
4271 }));
4272 before_slice = false;
4273 }
4274 continue
4275 }
4276 }
4277
4278 let subpat = self.parse_pat(None)?;
4279 if before_slice && self.eat(&token::DotDot) {
4280 slice = Some(subpat);
4281 before_slice = false;
4282 } else if before_slice {
4283 before.push(subpat);
4284 } else {
4285 after.push(subpat);
4286 }
4287 }
4288
4289 Ok((before, slice, after))
4290 }
4291
4292 fn parse_pat_field(
4293 &mut self,
4294 lo: Span,
4295 attrs: Vec<Attribute>
4296 ) -> PResult<'a, source_map::Spanned<ast::FieldPat>> {
4297 // Check if a colon exists one ahead. This means we're parsing a fieldname.
4298 let hi;
4299 let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
4300 // Parsing a pattern of the form "fieldname: pat"
4301 let fieldname = self.parse_field_name()?;
4302 self.bump();
4303 let pat = self.parse_pat(None)?;
4304 hi = pat.span;
4305 (pat, fieldname, false)
4306 } else {
4307 // Parsing a pattern of the form "(box) (ref) (mut) fieldname"
4308 let is_box = self.eat_keyword(keywords::Box);
4309 let boxed_span = self.span;
4310 let is_ref = self.eat_keyword(keywords::Ref);
4311 let is_mut = self.eat_keyword(keywords::Mut);
4312 let fieldname = self.parse_ident()?;
4313 hi = self.prev_span;
4314
4315 let bind_type = match (is_ref, is_mut) {
4316 (true, true) => BindingMode::ByRef(Mutability::Mutable),
4317 (true, false) => BindingMode::ByRef(Mutability::Immutable),
4318 (false, true) => BindingMode::ByValue(Mutability::Mutable),
4319 (false, false) => BindingMode::ByValue(Mutability::Immutable),
4320 };
4321 let fieldpat = P(Pat {
4322 id: ast::DUMMY_NODE_ID,
4323 node: PatKind::Ident(bind_type, fieldname, None),
4324 span: boxed_span.to(hi),
4325 });
4326
4327 let subpat = if is_box {
4328 P(Pat {
4329 id: ast::DUMMY_NODE_ID,
4330 node: PatKind::Box(fieldpat),
4331 span: lo.to(hi),
4332 })
4333 } else {
4334 fieldpat
4335 };
4336 (subpat, fieldname, true)
4337 };
4338
4339 Ok(source_map::Spanned {
4340 span: lo.to(hi),
4341 node: ast::FieldPat {
4342 ident: fieldname,
4343 pat: subpat,
4344 is_shorthand,
4345 attrs: attrs.into(),
4346 }
4347 })
4348 }
4349
4350 /// Parses the fields of a struct-like pattern.
4351 fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<source_map::Spanned<ast::FieldPat>>, bool)> {
4352 let mut fields = Vec::new();
4353 let mut etc = false;
4354 let mut ate_comma = true;
4355 let mut delayed_err: Option<DiagnosticBuilder<'a>> = None;
4356 let mut etc_span = None;
4357
4358 while self.token != token::CloseDelim(token::Brace) {
4359 let attrs = self.parse_outer_attributes()?;
4360 let lo = self.span;
4361
4362 // check that a comma comes after every field
4363 if !ate_comma {
4364 let err = self.struct_span_err(self.prev_span, "expected `,`");
4365 if let Some(mut delayed) = delayed_err {
4366 delayed.emit();
4367 }
4368 return Err(err);
4369 }
4370 ate_comma = false;
4371
4372 if self.check(&token::DotDot) || self.token == token::DotDotDot {
4373 etc = true;
4374 let mut etc_sp = self.span;
4375
4376 if self.token == token::DotDotDot { // Issue #46718
4377 // Accept `...` as if it were `..` to avoid further errors
4378 let mut err = self.struct_span_err(self.span,
4379 "expected field pattern, found `...`");
4380 err.span_suggestion(
4381 self.span,
4382 "to omit remaining fields, use one fewer `.`",
4383 "..".to_owned(),
4384 Applicability::MachineApplicable
4385 );
4386 err.emit();
4387 }
4388 self.bump(); // `..` || `...`
4389
4390 if self.token == token::CloseDelim(token::Brace) {
4391 etc_span = Some(etc_sp);
4392 break;
4393 }
4394 let token_str = self.this_token_descr();
4395 let mut err = self.fatal(&format!("expected `}}`, found {}", token_str));
4396
4397 err.span_label(self.span, "expected `}`");
4398 let mut comma_sp = None;
4399 if self.token == token::Comma { // Issue #49257
4400 etc_sp = etc_sp.to(self.sess.source_map().span_until_non_whitespace(self.span));
4401 err.span_label(etc_sp,
4402 "`..` must be at the end and cannot have a trailing comma");
4403 comma_sp = Some(self.span);
4404 self.bump();
4405 ate_comma = true;
4406 }
4407
4408 etc_span = Some(etc_sp.until(self.span));
4409 if self.token == token::CloseDelim(token::Brace) {
4410 // If the struct looks otherwise well formed, recover and continue.
4411 if let Some(sp) = comma_sp {
4412 err.span_suggestion_short(
4413 sp,
4414 "remove this comma",
4415 String::new(),
4416 Applicability::MachineApplicable,
4417 );
4418 }
4419 err.emit();
4420 break;
4421 } else if self.token.is_ident() && ate_comma {
4422 // Accept fields coming after `..,`.
4423 // This way we avoid "pattern missing fields" errors afterwards.
4424 // We delay this error until the end in order to have a span for a
4425 // suggested fix.
4426 if let Some(mut delayed_err) = delayed_err {
4427 delayed_err.emit();
4428 return Err(err);
4429 } else {
4430 delayed_err = Some(err);
4431 }
4432 } else {
4433 if let Some(mut err) = delayed_err {
4434 err.emit();
4435 }
4436 return Err(err);
4437 }
4438 }
4439
4440 fields.push(match self.parse_pat_field(lo, attrs) {
4441 Ok(field) => field,
4442 Err(err) => {
4443 if let Some(mut delayed_err) = delayed_err {
4444 delayed_err.emit();
4445 }
4446 return Err(err);
4447 }
4448 });
4449 ate_comma = self.eat(&token::Comma);
4450 }
4451
4452 if let Some(mut err) = delayed_err {
4453 if let Some(etc_span) = etc_span {
4454 err.multipart_suggestion(
4455 "move the `..` to the end of the field list",
4456 vec![
4457 (etc_span, String::new()),
4458 (self.span, format!("{}.. }}", if ate_comma { "" } else { ", " })),
4459 ],
4460 Applicability::MachineApplicable,
4461 );
4462 }
4463 err.emit();
4464 }
4465 return Ok((fields, etc));
4466 }
4467
4468 fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
4469 if self.token.is_path_start() {
4470 let lo = self.span;
4471 let (qself, path) = if self.eat_lt() {
4472 // Parse a qualified path
4473 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
4474 (Some(qself), path)
4475 } else {
4476 // Parse an unqualified path
4477 (None, self.parse_path(PathStyle::Expr)?)
4478 };
4479 let hi = self.prev_span;
4480 Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path), ThinVec::new()))
4481 } else {
4482 self.parse_literal_maybe_minus()
4483 }
4484 }
4485
4486 // helper function to decide whether to parse as ident binding or to try to do
4487 // something more complex like range patterns
4488 fn parse_as_ident(&mut self) -> bool {
4489 self.look_ahead(1, |t| match *t {
4490 token::OpenDelim(token::Paren) | token::OpenDelim(token::Brace) |
4491 token::DotDotDot | token::DotDotEq | token::ModSep | token::Not => Some(false),
4492 // ensure slice patterns [a, b.., c] and [a, b, c..] don't go into the
4493 // range pattern branch
4494 token::DotDot => None,
4495 _ => Some(true),
4496 }).unwrap_or_else(|| self.look_ahead(2, |t| match *t {
4497 token::Comma | token::CloseDelim(token::Bracket) => true,
4498 _ => false,
4499 }))
4500 }
4501
4502 /// A wrapper around `parse_pat` with some special error handling for the
4503 /// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast
4504 /// to subpatterns within such).
4505 fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
4506 let pat = self.parse_pat(None)?;
4507 if self.token == token::Comma {
4508 // An unexpected comma after a top-level pattern is a clue that the
4509 // user (perhaps more accustomed to some other language) forgot the
4510 // parentheses in what should have been a tuple pattern; return a
4511 // suggestion-enhanced error here rather than choking on the comma
4512 // later.
4513 let comma_span = self.span;
4514 self.bump();
4515 if let Err(mut err) = self.parse_pat_list() {
4516 // We didn't expect this to work anyway; we just wanted
4517 // to advance to the end of the comma-sequence so we know
4518 // the span to suggest parenthesizing
4519 err.cancel();
4520 }
4521 let seq_span = pat.span.to(self.prev_span);
4522 let mut err = self.struct_span_err(comma_span,
4523 "unexpected `,` in pattern");
4524 if let Ok(seq_snippet) = self.sess.source_map().span_to_snippet(seq_span) {
4525 err.span_suggestion(
4526 seq_span,
4527 "try adding parentheses to match on a tuple..",
4528 format!("({})", seq_snippet),
4529 Applicability::MachineApplicable
4530 ).span_suggestion(
4531 seq_span,
4532 "..or a vertical bar to match on multiple alternatives",
4533 format!("{}", seq_snippet.replace(",", " |")),
4534 Applicability::MachineApplicable
4535 );
4536 }
4537 return Err(err);
4538 }
4539 Ok(pat)
4540 }
4541
4542 /// Parses a pattern.
4543 pub fn parse_pat(&mut self, expected: Option<&'static str>) -> PResult<'a, P<Pat>> {
4544 self.parse_pat_with_range_pat(true, expected)
4545 }
4546
4547 /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
4548 /// allowed).
4549 fn parse_pat_with_range_pat(
4550 &mut self,
4551 allow_range_pat: bool,
4552 expected: Option<&'static str>,
4553 ) -> PResult<'a, P<Pat>> {
4554 maybe_whole!(self, NtPat, |x| x);
4555
4556 let lo = self.span;
4557 let pat;
4558 match self.token {
4559 token::BinOp(token::And) | token::AndAnd => {
4560 // Parse &pat / &mut pat
4561 self.expect_and()?;
4562 let mutbl = self.parse_mutability();
4563 if let token::Lifetime(ident) = self.token {
4564 let mut err = self.fatal(&format!("unexpected lifetime `{}` in pattern",
4565 ident));
4566 err.span_label(self.span, "unexpected lifetime");
4567 return Err(err);
4568 }
4569 let subpat = self.parse_pat_with_range_pat(false, expected)?;
4570 pat = PatKind::Ref(subpat, mutbl);
4571 }
4572 token::OpenDelim(token::Paren) => {
4573 // Parse (pat,pat,pat,...) as tuple pattern
4574 let (fields, ddpos, trailing_comma) = self.parse_parenthesized_pat_list()?;
4575 pat = if fields.len() == 1 && ddpos.is_none() && !trailing_comma {
4576 PatKind::Paren(fields.into_iter().nth(0).unwrap())
4577 } else {
4578 PatKind::Tuple(fields, ddpos)
4579 };
4580 }
4581 token::OpenDelim(token::Bracket) => {
4582 // Parse [pat,pat,...] as slice pattern
4583 self.bump();
4584 let (before, slice, after) = self.parse_pat_vec_elements()?;
4585 self.expect(&token::CloseDelim(token::Bracket))?;
4586 pat = PatKind::Slice(before, slice, after);
4587 }
4588 // At this point, token != &, &&, (, [
4589 _ => if self.eat_keyword(keywords::Underscore) {
4590 // Parse _
4591 pat = PatKind::Wild;
4592 } else if self.eat_keyword(keywords::Mut) {
4593 // Parse mut ident @ pat / mut ref ident @ pat
4594 let mutref_span = self.prev_span.to(self.span);
4595 let binding_mode = if self.eat_keyword(keywords::Ref) {
4596 self.diagnostic()
4597 .struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect")
4598 .span_suggestion(
4599 mutref_span,
4600 "try switching the order",
4601 "ref mut".into(),
4602 Applicability::MachineApplicable
4603 ).emit();
4604 BindingMode::ByRef(Mutability::Mutable)
4605 } else {
4606 BindingMode::ByValue(Mutability::Mutable)
4607 };
4608 pat = self.parse_pat_ident(binding_mode)?;
4609 } else if self.eat_keyword(keywords::Ref) {
4610 // Parse ref ident @ pat / ref mut ident @ pat
4611 let mutbl = self.parse_mutability();
4612 pat = self.parse_pat_ident(BindingMode::ByRef(mutbl))?;
4613 } else if self.eat_keyword(keywords::Box) {
4614 // Parse box pat
4615 let subpat = self.parse_pat_with_range_pat(false, None)?;
4616 pat = PatKind::Box(subpat);
4617 } else if self.token.is_ident() && !self.token.is_reserved_ident() &&
4618 self.parse_as_ident() {
4619 // Parse ident @ pat
4620 // This can give false positives and parse nullary enums,
4621 // they are dealt with later in resolve
4622 let binding_mode = BindingMode::ByValue(Mutability::Immutable);
4623 pat = self.parse_pat_ident(binding_mode)?;
4624 } else if self.token.is_path_start() {
4625 // Parse pattern starting with a path
4626 let (qself, path) = if self.eat_lt() {
4627 // Parse a qualified path
4628 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
4629 (Some(qself), path)
4630 } else {
4631 // Parse an unqualified path
4632 (None, self.parse_path(PathStyle::Expr)?)
4633 };
4634 match self.token {
4635 token::Not if qself.is_none() => {
4636 // Parse macro invocation
4637 self.bump();
4638 let (delim, tts) = self.expect_delimited_token_tree()?;
4639 let mac = respan(lo.to(self.prev_span), Mac_ { path, tts, delim });
4640 pat = PatKind::Mac(mac);
4641 }
4642 token::DotDotDot | token::DotDotEq | token::DotDot => {
4643 let end_kind = match self.token {
4644 token::DotDot => RangeEnd::Excluded,
4645 token::DotDotDot => RangeEnd::Included(RangeSyntax::DotDotDot),
4646 token::DotDotEq => RangeEnd::Included(RangeSyntax::DotDotEq),
4647 _ => panic!("can only parse `..`/`...`/`..=` for ranges \
4648 (checked above)"),
4649 };
4650 let op_span = self.span;
4651 // Parse range
4652 let span = lo.to(self.prev_span);
4653 let begin = self.mk_expr(span, ExprKind::Path(qself, path), ThinVec::new());
4654 self.bump();
4655 let end = self.parse_pat_range_end()?;
4656 let op = Spanned { span: op_span, node: end_kind };
4657 pat = PatKind::Range(begin, end, op);
4658 }
4659 token::OpenDelim(token::Brace) => {
4660 if qself.is_some() {
4661 let msg = "unexpected `{` after qualified path";
4662 let mut err = self.fatal(msg);
4663 err.span_label(self.span, msg);
4664 return Err(err);
4665 }
4666 // Parse struct pattern
4667 self.bump();
4668 let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
4669 e.emit();
4670 self.recover_stmt();
4671 (vec![], false)
4672 });
4673 self.bump();
4674 pat = PatKind::Struct(path, fields, etc);
4675 }
4676 token::OpenDelim(token::Paren) => {
4677 if qself.is_some() {
4678 let msg = "unexpected `(` after qualified path";
4679 let mut err = self.fatal(msg);
4680 err.span_label(self.span, msg);
4681 return Err(err);
4682 }
4683 // Parse tuple struct or enum pattern
4684 let (fields, ddpos, _) = self.parse_parenthesized_pat_list()?;
4685 pat = PatKind::TupleStruct(path, fields, ddpos)
4686 }
4687 _ => pat = PatKind::Path(qself, path),
4688 }
4689 } else {
4690 // Try to parse everything else as literal with optional minus
4691 match self.parse_literal_maybe_minus() {
4692 Ok(begin) => {
4693 let op_span = self.span;
4694 if self.check(&token::DotDot) || self.check(&token::DotDotEq) ||
4695 self.check(&token::DotDotDot) {
4696 let end_kind = if self.eat(&token::DotDotDot) {
4697 RangeEnd::Included(RangeSyntax::DotDotDot)
4698 } else if self.eat(&token::DotDotEq) {
4699 RangeEnd::Included(RangeSyntax::DotDotEq)
4700 } else if self.eat(&token::DotDot) {
4701 RangeEnd::Excluded
4702 } else {
4703 panic!("impossible case: we already matched \
4704 on a range-operator token")
4705 };
4706 let end = self.parse_pat_range_end()?;
4707 let op = Spanned { span: op_span, node: end_kind };
4708 pat = PatKind::Range(begin, end, op);
4709 } else {
4710 pat = PatKind::Lit(begin);
4711 }
4712 }
4713 Err(mut err) => {
4714 self.cancel(&mut err);
4715 let expected = expected.unwrap_or("pattern");
4716 let msg = format!(
4717 "expected {}, found {}",
4718 expected,
4719 self.this_token_descr(),
4720 );
4721 let mut err = self.fatal(&msg);
4722 err.span_label(self.span, format!("expected {}", expected));
4723 return Err(err);
4724 }
4725 }
4726 }
4727 }
4728
4729 let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID };
4730 let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
4731
4732 if !allow_range_pat {
4733 match pat.node {
4734 PatKind::Range(
4735 _, _, Spanned { node: RangeEnd::Included(RangeSyntax::DotDotDot), .. }
4736 ) => {},
4737 PatKind::Range(..) => {
4738 let mut err = self.struct_span_err(
4739 pat.span,
4740 "the range pattern here has ambiguous interpretation",
4741 );
4742 err.span_suggestion(
4743 pat.span,
4744 "add parentheses to clarify the precedence",
4745 format!("({})", pprust::pat_to_string(&pat)),
4746 // "ambiguous interpretation" implies that we have to be guessing
4747 Applicability::MaybeIncorrect
4748 );
4749 return Err(err);
4750 }
4751 _ => {}
4752 }
4753 }
4754
4755 Ok(P(pat))
4756 }
4757
4758 /// Parses `ident` or `ident @ pat`.
4759 /// used by the copy foo and ref foo patterns to give a good
4760 /// error message when parsing mistakes like `ref foo(a, b)`.
4761 fn parse_pat_ident(&mut self,
4762 binding_mode: ast::BindingMode)
4763 -> PResult<'a, PatKind> {
4764 let ident = self.parse_ident()?;
4765 let sub = if self.eat(&token::At) {
4766 Some(self.parse_pat(Some("binding pattern"))?)
4767 } else {
4768 None
4769 };
4770
4771 // just to be friendly, if they write something like
4772 // ref Some(i)
4773 // we end up here with ( as the current token. This shortly
4774 // leads to a parse error. Note that if there is no explicit
4775 // binding mode then we do not end up here, because the lookahead
4776 // will direct us over to parse_enum_variant()
4777 if self.token == token::OpenDelim(token::Paren) {
4778 return Err(self.span_fatal(
4779 self.prev_span,
4780 "expected identifier, found enum pattern"))
4781 }
4782
4783 Ok(PatKind::Ident(binding_mode, ident, sub))
4784 }
4785
4786 /// Parses a local variable declaration.
4787 fn parse_local(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Local>> {
4788 let lo = self.prev_span;
4789 let pat = self.parse_top_level_pat()?;
4790
4791 let (err, ty) = if self.eat(&token::Colon) {
4792 // Save the state of the parser before parsing type normally, in case there is a `:`
4793 // instead of an `=` typo.
4794 let parser_snapshot_before_type = self.clone();
4795 let colon_sp = self.prev_span;
4796 match self.parse_ty() {
4797 Ok(ty) => (None, Some(ty)),
4798 Err(mut err) => {
4799 // Rewind to before attempting to parse the type and continue parsing
4800 let parser_snapshot_after_type = self.clone();
4801 mem::replace(self, parser_snapshot_before_type);
4802
4803 let snippet = self.sess.source_map().span_to_snippet(pat.span).unwrap();
4804 err.span_label(pat.span, format!("while parsing the type for `{}`", snippet));
4805 (Some((parser_snapshot_after_type, colon_sp, err)), None)
4806 }
4807 }
4808 } else {
4809 (None, None)
4810 };
4811 let init = match (self.parse_initializer(err.is_some()), err) {
4812 (Ok(init), None) => { // init parsed, ty parsed
4813 init
4814 }
4815 (Ok(init), Some((_, colon_sp, mut err))) => { // init parsed, ty error
4816 // Could parse the type as if it were the initializer, it is likely there was a
4817 // typo in the code: `:` instead of `=`. Add suggestion and emit the error.
4818 err.span_suggestion_short(
4819 colon_sp,
4820 "use `=` if you meant to assign",
4821 "=".to_string(),
4822 Applicability::MachineApplicable
4823 );
4824 err.emit();
4825 // As this was parsed successfully, continue as if the code has been fixed for the
4826 // rest of the file. It will still fail due to the emitted error, but we avoid
4827 // extra noise.
4828 init
4829 }
4830 (Err(mut init_err), Some((snapshot, _, ty_err))) => { // init error, ty error
4831 init_err.cancel();
4832 // Couldn't parse the type nor the initializer, only raise the type error and
4833 // return to the parser state before parsing the type as the initializer.
4834 // let x: <parse_error>;
4835 mem::replace(self, snapshot);
4836 return Err(ty_err);
4837 }
4838 (Err(err), None) => { // init error, ty parsed
4839 // Couldn't parse the initializer and we're not attempting to recover a failed
4840 // parse of the type, return the error.
4841 return Err(err);
4842 }
4843 };
4844 let hi = if self.token == token::Semi {
4845 self.span
4846 } else {
4847 self.prev_span
4848 };
4849 Ok(P(ast::Local {
4850 ty,
4851 pat,
4852 init,
4853 id: ast::DUMMY_NODE_ID,
4854 span: lo.to(hi),
4855 attrs,
4856 }))
4857 }
4858
4859 /// Parses a structure field.
4860 fn parse_name_and_ty(&mut self,
4861 lo: Span,
4862 vis: Visibility,
4863 attrs: Vec<Attribute>)
4864 -> PResult<'a, StructField> {
4865 let name = self.parse_ident()?;
4866 self.expect(&token::Colon)?;
4867 let ty = self.parse_ty()?;
4868 Ok(StructField {
4869 span: lo.to(self.prev_span),
4870 ident: Some(name),
4871 vis,
4872 id: ast::DUMMY_NODE_ID,
4873 ty,
4874 attrs,
4875 })
4876 }
4877
4878 /// Emits an expected-item-after-attributes error.
4879 fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
4880 let message = match attrs.last() {
4881 Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
4882 _ => "expected item after attributes",
4883 };
4884
4885 let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
4886 if attrs.last().unwrap().is_sugared_doc {
4887 err.span_label(self.prev_span, "this doc comment doesn't document anything");
4888 }
4889 Err(err)
4890 }
4891
4892 /// Parse a statement. This stops just before trailing semicolons on everything but items.
4893 /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
4894 pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
4895 Ok(self.parse_stmt_(true))
4896 }
4897
4898 // Eat tokens until we can be relatively sure we reached the end of the
4899 // statement. This is something of a best-effort heuristic.
4900 //
4901 // We terminate when we find an unmatched `}` (without consuming it).
4902 fn recover_stmt(&mut self) {
4903 self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore)
4904 }
4905
4906 // If `break_on_semi` is `Break`, then we will stop consuming tokens after
4907 // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
4908 // approximate - it can mean we break too early due to macros, but that
4909 // should only lead to sub-optimal recovery, not inaccurate parsing).
4910 //
4911 // If `break_on_block` is `Break`, then we will stop consuming tokens
4912 // after finding (and consuming) a brace-delimited block.
4913 fn recover_stmt_(&mut self, break_on_semi: SemiColonMode, break_on_block: BlockMode) {
4914 let mut brace_depth = 0;
4915 let mut bracket_depth = 0;
4916 let mut in_block = false;
4917 debug!("recover_stmt_ enter loop (semi={:?}, block={:?})",
4918 break_on_semi, break_on_block);
4919 loop {
4920 debug!("recover_stmt_ loop {:?}", self.token);
4921 match self.token {
4922 token::OpenDelim(token::DelimToken::Brace) => {
4923 brace_depth += 1;
4924 self.bump();
4925 if break_on_block == BlockMode::Break &&
4926 brace_depth == 1 &&
4927 bracket_depth == 0 {
4928 in_block = true;
4929 }
4930 }
4931 token::OpenDelim(token::DelimToken::Bracket) => {
4932 bracket_depth += 1;
4933 self.bump();
4934 }
4935 token::CloseDelim(token::DelimToken::Brace) => {
4936 if brace_depth == 0 {
4937 debug!("recover_stmt_ return - close delim {:?}", self.token);
4938 break;
4939 }
4940 brace_depth -= 1;
4941 self.bump();
4942 if in_block && bracket_depth == 0 && brace_depth == 0 {
4943 debug!("recover_stmt_ return - block end {:?}", self.token);
4944 break;
4945 }
4946 }
4947 token::CloseDelim(token::DelimToken::Bracket) => {
4948 bracket_depth -= 1;
4949 if bracket_depth < 0 {
4950 bracket_depth = 0;
4951 }
4952 self.bump();
4953 }
4954 token::Eof => {
4955 debug!("recover_stmt_ return - Eof");
4956 break;
4957 }
4958 token::Semi => {
4959 self.bump();
4960 if break_on_semi == SemiColonMode::Break &&
4961 brace_depth == 0 &&
4962 bracket_depth == 0 {
4963 debug!("recover_stmt_ return - Semi");
4964 break;
4965 }
4966 }
4967 token::Comma => {
4968 if break_on_semi == SemiColonMode::Comma &&
4969 brace_depth == 0 &&
4970 bracket_depth == 0 {
4971 debug!("recover_stmt_ return - Semi");
4972 break;
4973 } else {
4974 self.bump();
4975 }
4976 }
4977 _ => {
4978 self.bump()
4979 }
4980 }
4981 }
4982 }
4983
4984 fn parse_stmt_(&mut self, macro_legacy_warnings: bool) -> Option<Stmt> {
4985 self.parse_stmt_without_recovery(macro_legacy_warnings).unwrap_or_else(|mut e| {
4986 e.emit();
4987 self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
4988 None
4989 })
4990 }
4991
4992 fn is_async_block(&mut self) -> bool {
4993 self.token.is_keyword(keywords::Async) &&
4994 (
4995 ( // `async move {`
4996 self.look_ahead(1, |t| t.is_keyword(keywords::Move)) &&
4997 self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))
4998 ) || ( // `async {`
4999 self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace))
5000 )
5001 )
5002 }
5003
5004 fn is_do_catch_block(&mut self) -> bool {
5005 self.token.is_keyword(keywords::Do) &&
5006 self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) &&
5007 self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) &&
5008 !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
5009 }
5010
5011 fn is_try_block(&mut self) -> bool {
5012 self.token.is_keyword(keywords::Try) &&
5013 self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
5014 self.span.rust_2018() &&
5015 // prevent `while try {} {}`, `if try {} {} else {}`, etc.
5016 !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
5017 }
5018
5019 fn is_union_item(&self) -> bool {
5020 self.token.is_keyword(keywords::Union) &&
5021 self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
5022 }
5023
5024 fn is_crate_vis(&self) -> bool {
5025 self.token.is_keyword(keywords::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
5026 }
5027
5028 fn is_existential_type_decl(&self) -> bool {
5029 self.token.is_keyword(keywords::Existential) &&
5030 self.look_ahead(1, |t| t.is_keyword(keywords::Type))
5031 }
5032
5033 fn is_auto_trait_item(&mut self) -> bool {
5034 // auto trait
5035 (self.token.is_keyword(keywords::Auto)
5036 && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
5037 || // unsafe auto trait
5038 (self.token.is_keyword(keywords::Unsafe) &&
5039 self.look_ahead(1, |t| t.is_keyword(keywords::Auto)) &&
5040 self.look_ahead(2, |t| t.is_keyword(keywords::Trait)))
5041 }
5042
5043 fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span)
5044 -> PResult<'a, Option<P<Item>>> {
5045 let token_lo = self.span;
5046 let (ident, def) = match self.token {
5047 token::Ident(ident, false) if ident.name == keywords::Macro.name() => {
5048 self.bump();
5049 let ident = self.parse_ident()?;
5050 let tokens = if self.check(&token::OpenDelim(token::Brace)) {
5051 match self.parse_token_tree() {
5052 TokenTree::Delimited(_, _, tts) => tts,
5053 _ => unreachable!(),
5054 }
5055 } else if self.check(&token::OpenDelim(token::Paren)) {
5056 let args = self.parse_token_tree();
5057 let body = if self.check(&token::OpenDelim(token::Brace)) {
5058 self.parse_token_tree()
5059 } else {
5060 self.unexpected()?;
5061 unreachable!()
5062 };
5063 TokenStream::new(vec![
5064 args.into(),
5065 TokenTree::Token(token_lo.to(self.prev_span), token::FatArrow).into(),
5066 body.into(),
5067 ])
5068 } else {
5069 self.unexpected()?;
5070 unreachable!()
5071 };
5072
5073 (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
5074 }
5075 token::Ident(ident, _) if ident.name == "macro_rules" &&
5076 self.look_ahead(1, |t| *t == token::Not) => {
5077 let prev_span = self.prev_span;
5078 self.complain_if_pub_macro(&vis.node, prev_span);
5079 self.bump();
5080 self.bump();
5081
5082 let ident = self.parse_ident()?;
5083 let (delim, tokens) = self.expect_delimited_token_tree()?;
5084 if delim != MacDelimiter::Brace {
5085 if !self.eat(&token::Semi) {
5086 let msg = "macros that expand to items must either \
5087 be surrounded with braces or followed by a semicolon";
5088 self.span_err(self.prev_span, msg);
5089 }
5090 }
5091
5092 (ident, ast::MacroDef { tokens: tokens, legacy: true })
5093 }
5094 _ => return Ok(None),
5095 };
5096
5097 let span = lo.to(self.prev_span);
5098 Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
5099 }
5100
5101 fn parse_stmt_without_recovery(&mut self,
5102 macro_legacy_warnings: bool)
5103 -> PResult<'a, Option<Stmt>> {
5104 maybe_whole!(self, NtStmt, |x| Some(x));
5105
5106 let attrs = self.parse_outer_attributes()?;
5107 let lo = self.span;
5108
5109 Ok(Some(if self.eat_keyword(keywords::Let) {
5110 Stmt {
5111 id: ast::DUMMY_NODE_ID,
5112 node: StmtKind::Local(self.parse_local(attrs.into())?),
5113 span: lo.to(self.prev_span),
5114 }
5115 } else if let Some(macro_def) = self.eat_macro_def(
5116 &attrs,
5117 &source_map::respan(lo, VisibilityKind::Inherited),
5118 lo,
5119 )? {
5120 Stmt {
5121 id: ast::DUMMY_NODE_ID,
5122 node: StmtKind::Item(macro_def),
5123 span: lo.to(self.prev_span),
5124 }
5125 // Starts like a simple path, being careful to avoid contextual keywords
5126 // such as a union items, item with `crate` visibility or auto trait items.
5127 // Our goal here is to parse an arbitrary path `a::b::c` but not something that starts
5128 // like a path (1 token), but it fact not a path.
5129 // `union::b::c` - path, `union U { ... }` - not a path.
5130 // `crate::b::c` - path, `crate struct S;` - not a path.
5131 } else if self.token.is_path_start() &&
5132 !self.token.is_qpath_start() &&
5133 !self.is_union_item() &&
5134 !self.is_crate_vis() &&
5135 !self.is_existential_type_decl() &&
5136 !self.is_auto_trait_item() {
5137 let pth = self.parse_path(PathStyle::Expr)?;
5138
5139 if !self.eat(&token::Not) {
5140 let expr = if self.check(&token::OpenDelim(token::Brace)) {
5141 self.parse_struct_expr(lo, pth, ThinVec::new())?
5142 } else {
5143 let hi = self.prev_span;
5144 self.mk_expr(lo.to(hi), ExprKind::Path(None, pth), ThinVec::new())
5145 };
5146
5147 let expr = self.with_res(Restrictions::STMT_EXPR, |this| {
5148 let expr = this.parse_dot_or_call_expr_with(expr, lo, attrs.into())?;
5149 this.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(expr))
5150 })?;
5151
5152 return Ok(Some(Stmt {
5153 id: ast::DUMMY_NODE_ID,
5154 node: StmtKind::Expr(expr),
5155 span: lo.to(self.prev_span),
5156 }));
5157 }
5158
5159 // it's a macro invocation
5160 let id = match self.token {
5161 token::OpenDelim(_) => keywords::Invalid.ident(), // no special identifier
5162 _ => self.parse_ident()?,
5163 };
5164
5165 // check that we're pointing at delimiters (need to check
5166 // again after the `if`, because of `parse_ident`
5167 // consuming more tokens).
5168 match self.token {
5169 token::OpenDelim(_) => {}
5170 _ => {
5171 // we only expect an ident if we didn't parse one
5172 // above.
5173 let ident_str = if id.name == keywords::Invalid.name() {
5174 "identifier, "
5175 } else {
5176 ""
5177 };
5178 let tok_str = self.this_token_descr();
5179 let mut err = self.fatal(&format!("expected {}`(` or `{{`, found {}",
5180 ident_str,
5181 tok_str));
5182 err.span_label(self.span, format!("expected {}`(` or `{{`", ident_str));
5183 return Err(err)
5184 },
5185 }
5186
5187 let (delim, tts) = self.expect_delimited_token_tree()?;
5188 let hi = self.prev_span;
5189
5190 let style = if delim == MacDelimiter::Brace {
5191 MacStmtStyle::Braces
5192 } else {
5193 MacStmtStyle::NoBraces
5194 };
5195
5196 if id.name == keywords::Invalid.name() {
5197 let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim });
5198 let node = if delim == MacDelimiter::Brace ||
5199 self.token == token::Semi || self.token == token::Eof {
5200 StmtKind::Mac(P((mac, style, attrs.into())))
5201 }
5202 // We used to incorrectly stop parsing macro-expanded statements here.
5203 // If the next token will be an error anyway but could have parsed with the
5204 // earlier behavior, stop parsing here and emit a warning to avoid breakage.
5205 else if macro_legacy_warnings && self.token.can_begin_expr() && match self.token {
5206 // These can continue an expression, so we can't stop parsing and warn.
5207 token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) |
5208 token::BinOp(token::Minus) | token::BinOp(token::Star) |
5209 token::BinOp(token::And) | token::BinOp(token::Or) |
5210 token::AndAnd | token::OrOr |
5211 token::DotDot | token::DotDotDot | token::DotDotEq => false,
5212 _ => true,
5213 } {
5214 self.warn_missing_semicolon();
5215 StmtKind::Mac(P((mac, style, attrs.into())))
5216 } else {
5217 let e = self.mk_mac_expr(lo.to(hi), mac.node, ThinVec::new());
5218 let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
5219 let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
5220 StmtKind::Expr(e)
5221 };
5222 Stmt {
5223 id: ast::DUMMY_NODE_ID,
5224 span: lo.to(hi),
5225 node,
5226 }
5227 } else {
5228 // if it has a special ident, it's definitely an item
5229 //
5230 // Require a semicolon or braces.
5231 if style != MacStmtStyle::Braces {
5232 if !self.eat(&token::Semi) {
5233 self.span_err(self.prev_span,
5234 "macros that expand to items must \
5235 either be surrounded with braces or \
5236 followed by a semicolon");
5237 }
5238 }
5239 let span = lo.to(hi);
5240 Stmt {
5241 id: ast::DUMMY_NODE_ID,
5242 span,
5243 node: StmtKind::Item({
5244 self.mk_item(
5245 span, id /*id is good here*/,
5246 ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })),
5247 respan(lo, VisibilityKind::Inherited),
5248 attrs)
5249 }),
5250 }
5251 }
5252 } else {
5253 // FIXME: Bad copy of attrs
5254 let old_directory_ownership =
5255 mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock);
5256 let item = self.parse_item_(attrs.clone(), false, true)?;
5257 self.directory.ownership = old_directory_ownership;
5258
5259 match item {
5260 Some(i) => Stmt {
5261 id: ast::DUMMY_NODE_ID,
5262 span: lo.to(i.span),
5263 node: StmtKind::Item(i),
5264 },
5265 None => {
5266 let unused_attrs = |attrs: &[Attribute], s: &mut Self| {
5267 if !attrs.is_empty() {
5268 if s.prev_token_kind == PrevTokenKind::DocComment {
5269 s.span_fatal_err(s.prev_span, Error::UselessDocComment).emit();
5270 } else if attrs.iter().any(|a| a.style == AttrStyle::Outer) {
5271 s.span_err(s.span, "expected statement after outer attribute");
5272 }
5273 }
5274 };
5275
5276 // Do not attempt to parse an expression if we're done here.
5277 if self.token == token::Semi {
5278 unused_attrs(&attrs, self);
5279 self.bump();
5280 return Ok(None);
5281 }
5282
5283 if self.token == token::CloseDelim(token::Brace) {
5284 unused_attrs(&attrs, self);
5285 return Ok(None);
5286 }
5287
5288 // Remainder are line-expr stmts.
5289 let e = self.parse_expr_res(
5290 Restrictions::STMT_EXPR, Some(attrs.into()))?;
5291 Stmt {
5292 id: ast::DUMMY_NODE_ID,
5293 span: lo.to(e.span),
5294 node: StmtKind::Expr(e),
5295 }
5296 }
5297 }
5298 }))
5299 }
5300
5301 /// Checks if this expression is a successfully parsed statement.
5302 fn expr_is_complete(&mut self, e: &Expr) -> bool {
5303 self.restrictions.contains(Restrictions::STMT_EXPR) &&
5304 !classify::expr_requires_semi_to_be_stmt(e)
5305 }
5306
5307 /// Parses a block. No inner attributes are allowed.
5308 pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
5309 maybe_whole!(self, NtBlock, |x| x);
5310
5311 let lo = self.span;
5312
5313 if !self.eat(&token::OpenDelim(token::Brace)) {
5314 let sp = self.span;
5315 let tok = self.this_token_descr();
5316 let mut e = self.span_fatal(sp, &format!("expected `{{`, found {}", tok));
5317 let do_not_suggest_help =
5318 self.token.is_keyword(keywords::In) || self.token == token::Colon;
5319
5320 if self.token.is_ident_named("and") {
5321 e.span_suggestion_short(
5322 self.span,
5323 "use `&&` instead of `and` for the boolean operator",
5324 "&&".to_string(),
5325 Applicability::MaybeIncorrect,
5326 );
5327 }
5328 if self.token.is_ident_named("or") {
5329 e.span_suggestion_short(
5330 self.span,
5331 "use `||` instead of `or` for the boolean operator",
5332 "||".to_string(),
5333 Applicability::MaybeIncorrect,
5334 );
5335 }
5336
5337 // Check to see if the user has written something like
5338 //
5339 // if (cond)
5340 // bar;
5341 //
5342 // Which is valid in other languages, but not Rust.
5343 match self.parse_stmt_without_recovery(false) {
5344 Ok(Some(stmt)) => {
5345 if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace))
5346 || do_not_suggest_help {
5347 // if the next token is an open brace (e.g., `if a b {`), the place-
5348 // inside-a-block suggestion would be more likely wrong than right
5349 e.span_label(sp, "expected `{`");
5350 return Err(e);
5351 }
5352 let mut stmt_span = stmt.span;
5353 // expand the span to include the semicolon, if it exists
5354 if self.eat(&token::Semi) {
5355 stmt_span = stmt_span.with_hi(self.prev_span.hi());
5356 }
5357 let sugg = pprust::to_string(|s| {
5358 use crate::print::pprust::{PrintState, INDENT_UNIT};
5359 s.ibox(INDENT_UNIT)?;
5360 s.bopen()?;
5361 s.print_stmt(&stmt)?;
5362 s.bclose_maybe_open(stmt.span, INDENT_UNIT, false)
5363 });
5364 e.span_suggestion(
5365 stmt_span,
5366 "try placing this code inside a block",
5367 sugg,
5368 // speculative, has been misleading in the past (closed Issue #46836)
5369 Applicability::MaybeIncorrect
5370 );
5371 }
5372 Err(mut e) => {
5373 self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
5374 self.cancel(&mut e);
5375 }
5376 _ => ()
5377 }
5378 e.span_label(sp, "expected `{`");
5379 return Err(e);
5380 }
5381
5382 self.parse_block_tail(lo, BlockCheckMode::Default)
5383 }
5384
5385 /// Parses a block. Inner attributes are allowed.
5386 fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
5387 maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
5388
5389 let lo = self.span;
5390 self.expect(&token::OpenDelim(token::Brace))?;
5391 Ok((self.parse_inner_attributes()?,
5392 self.parse_block_tail(lo, BlockCheckMode::Default)?))
5393 }
5394
5395 /// Parses the rest of a block expression or function body.
5396 /// Precondition: already parsed the '{'.
5397 fn parse_block_tail(&mut self, lo: Span, s: BlockCheckMode) -> PResult<'a, P<Block>> {
5398 let mut stmts = vec![];
5399 while !self.eat(&token::CloseDelim(token::Brace)) {
5400 let stmt = match self.parse_full_stmt(false) {
5401 Err(mut err) => {
5402 err.emit();
5403 self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore);
5404 Some(Stmt {
5405 id: ast::DUMMY_NODE_ID,
5406 node: StmtKind::Expr(DummyResult::raw_expr(self.span, true)),
5407 span: self.span,
5408 })
5409 }
5410 Ok(stmt) => stmt,
5411 };
5412 if let Some(stmt) = stmt {
5413 stmts.push(stmt);
5414 } else if self.token == token::Eof {
5415 break;
5416 } else {
5417 // Found only `;` or `}`.
5418 continue;
5419 };
5420 }
5421 Ok(P(ast::Block {
5422 stmts,
5423 id: ast::DUMMY_NODE_ID,
5424 rules: s,
5425 span: lo.to(self.prev_span),
5426 }))
5427 }
5428
5429 /// Parses a statement, including the trailing semicolon.
5430 crate fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
5431 // skip looking for a trailing semicolon when we have an interpolated statement
5432 maybe_whole!(self, NtStmt, |x| Some(x));
5433
5434 let mut stmt = match self.parse_stmt_without_recovery(macro_legacy_warnings)? {
5435 Some(stmt) => stmt,
5436 None => return Ok(None),
5437 };
5438
5439 match stmt.node {
5440 StmtKind::Expr(ref expr) if self.token != token::Eof => {
5441 // expression without semicolon
5442 if classify::expr_requires_semi_to_be_stmt(expr) {
5443 // Just check for errors and recover; do not eat semicolon yet.
5444 if let Err(mut e) =
5445 self.expect_one_of(&[], &[token::Semi, token::CloseDelim(token::Brace)])
5446 {
5447 e.emit();
5448 self.recover_stmt();
5449 }
5450 }
5451 }
5452 StmtKind::Local(..) => {
5453 // We used to incorrectly allow a macro-expanded let statement to lack a semicolon.
5454 if macro_legacy_warnings && self.token != token::Semi {
5455 self.warn_missing_semicolon();
5456 } else {
5457 self.expect_one_of(&[], &[token::Semi])?;
5458 }
5459 }
5460 _ => {}
5461 }
5462
5463 if self.eat(&token::Semi) {
5464 stmt = stmt.add_trailing_semicolon();
5465 }
5466
5467 stmt.span = stmt.span.with_hi(self.prev_span.hi());
5468 Ok(Some(stmt))
5469 }
5470
5471 fn warn_missing_semicolon(&self) {
5472 self.diagnostic().struct_span_warn(self.span, {
5473 &format!("expected `;`, found {}", self.this_token_descr())
5474 }).note({
5475 "This was erroneously allowed and will become a hard error in a future release"
5476 }).emit();
5477 }
5478
5479 fn err_dotdotdot_syntax(&self, span: Span) {
5480 self.diagnostic().struct_span_err(span, {
5481 "unexpected token: `...`"
5482 }).span_suggestion(
5483 span, "use `..` for an exclusive range", "..".to_owned(),
5484 Applicability::MaybeIncorrect
5485 ).span_suggestion(
5486 span, "or `..=` for an inclusive range", "..=".to_owned(),
5487 Applicability::MaybeIncorrect
5488 ).emit();
5489 }
5490
5491 /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
5492 ///
5493 /// ```
5494 /// BOUND = TY_BOUND | LT_BOUND
5495 /// LT_BOUND = LIFETIME (e.g., `'a`)
5496 /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
5497 /// TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
5498 /// ```
5499 fn parse_generic_bounds_common(&mut self,
5500 allow_plus: bool,
5501 colon_span: Option<Span>) -> PResult<'a, GenericBounds> {
5502 let mut bounds = Vec::new();
5503 let mut negative_bounds = Vec::new();
5504 let mut last_plus_span = None;
5505 loop {
5506 // This needs to be synchronized with `Token::can_begin_bound`.
5507 let is_bound_start = self.check_path() || self.check_lifetime() ||
5508 self.check(&token::Not) || // used for error reporting only
5509 self.check(&token::Question) ||
5510 self.check_keyword(keywords::For) ||
5511 self.check(&token::OpenDelim(token::Paren));
5512 if is_bound_start {
5513 let lo = self.span;
5514 let has_parens = self.eat(&token::OpenDelim(token::Paren));
5515 let inner_lo = self.span;
5516 let is_negative = self.eat(&token::Not);
5517 let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None };
5518 if self.token.is_lifetime() {
5519 if let Some(question_span) = question {
5520 self.span_err(question_span,
5521 "`?` may only modify trait bounds, not lifetime bounds");
5522 }
5523 bounds.push(GenericBound::Outlives(self.expect_lifetime()));
5524 if has_parens {
5525 let inner_span = inner_lo.to(self.prev_span);
5526 self.expect(&token::CloseDelim(token::Paren))?;
5527 let mut err = self.struct_span_err(
5528 lo.to(self.prev_span),
5529 "parenthesized lifetime bounds are not supported"
5530 );
5531 if let Ok(snippet) = self.sess.source_map().span_to_snippet(inner_span) {
5532 err.span_suggestion_short(
5533 lo.to(self.prev_span),
5534 "remove the parentheses",
5535 snippet.to_owned(),
5536 Applicability::MachineApplicable
5537 );
5538 }
5539 err.emit();
5540 }
5541 } else {
5542 let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
5543 let path = self.parse_path(PathStyle::Type)?;
5544 if has_parens {
5545 self.expect(&token::CloseDelim(token::Paren))?;
5546 }
5547 let poly_span = lo.to(self.prev_span);
5548 if is_negative {
5549 negative_bounds.push(
5550 last_plus_span.or(colon_span).unwrap()
5551 .to(poly_span));
5552 } else {
5553 let poly_trait = PolyTraitRef::new(lifetime_defs, path, poly_span);
5554 let modifier = if question.is_some() {
5555 TraitBoundModifier::Maybe
5556 } else {
5557 TraitBoundModifier::None
5558 };
5559 bounds.push(GenericBound::Trait(poly_trait, modifier));
5560 }
5561 }
5562 } else {
5563 break
5564 }
5565
5566 if !allow_plus || !self.eat_plus() {
5567 break
5568 } else {
5569 last_plus_span = Some(self.prev_span);
5570 }
5571 }
5572
5573 if !negative_bounds.is_empty() {
5574 let plural = negative_bounds.len() > 1;
5575 let mut err = self.struct_span_err(negative_bounds,
5576 "negative trait bounds are not supported");
5577 let bound_list = colon_span.unwrap().to(self.prev_span);
5578 let mut new_bound_list = String::new();
5579 if !bounds.is_empty() {
5580 let mut snippets = bounds.iter().map(|bound| bound.span())
5581 .map(|span| self.sess.source_map().span_to_snippet(span));
5582 while let Some(Ok(snippet)) = snippets.next() {
5583 new_bound_list.push_str(" + ");
5584 new_bound_list.push_str(&snippet);
5585 }
5586 new_bound_list = new_bound_list.replacen(" +", ":", 1);
5587 }
5588 err.span_suggestion_short(bound_list,
5589 &format!("remove the trait bound{}",
5590 if plural { "s" } else { "" }),
5591 new_bound_list,
5592 Applicability::MachineApplicable);
5593 err.emit();
5594 }
5595
5596 return Ok(bounds);
5597 }
5598
5599 fn parse_generic_bounds(&mut self, colon_span: Option<Span>) -> PResult<'a, GenericBounds> {
5600 self.parse_generic_bounds_common(true, colon_span)
5601 }
5602
5603 /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
5604 ///
5605 /// ```
5606 /// BOUND = LT_BOUND (e.g., `'a`)
5607 /// ```
5608 fn parse_lt_param_bounds(&mut self) -> GenericBounds {
5609 let mut lifetimes = Vec::new();
5610 while self.check_lifetime() {
5611 lifetimes.push(ast::GenericBound::Outlives(self.expect_lifetime()));
5612
5613 if !self.eat_plus() {
5614 break
5615 }
5616 }
5617 lifetimes
5618 }
5619
5620 /// Matches `typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?`.
5621 fn parse_ty_param(&mut self,
5622 preceding_attrs: Vec<Attribute>)
5623 -> PResult<'a, GenericParam> {
5624 let ident = self.parse_ident()?;
5625
5626 // Parse optional colon and param bounds.
5627 let bounds = if self.eat(&token::Colon) {
5628 self.parse_generic_bounds(None)?
5629 } else {
5630 Vec::new()
5631 };
5632
5633 let default = if self.eat(&token::Eq) {
5634 Some(self.parse_ty()?)
5635 } else {
5636 None
5637 };
5638
5639 Ok(GenericParam {
5640 ident,
5641 id: ast::DUMMY_NODE_ID,
5642 attrs: preceding_attrs.into(),
5643 bounds,
5644 kind: GenericParamKind::Type {
5645 default,
5646 }
5647 })
5648 }
5649
5650 /// Parses the following grammar:
5651 ///
5652 /// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
5653 fn parse_trait_item_assoc_ty(&mut self)
5654 -> PResult<'a, (Ident, TraitItemKind, ast::Generics)> {
5655 let ident = self.parse_ident()?;
5656 let mut generics = self.parse_generics()?;
5657
5658 // Parse optional colon and param bounds.
5659 let bounds = if self.eat(&token::Colon) {
5660 self.parse_generic_bounds(None)?
5661 } else {
5662 Vec::new()
5663 };
5664 generics.where_clause = self.parse_where_clause()?;
5665
5666 let default = if self.eat(&token::Eq) {
5667 Some(self.parse_ty()?)
5668 } else {
5669 None
5670 };
5671 self.expect(&token::Semi)?;
5672
5673 Ok((ident, TraitItemKind::Type(bounds, default), generics))
5674 }
5675
5676 fn parse_const_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, GenericParam> {
5677 self.expect_keyword(keywords::Const)?;
5678 let ident = self.parse_ident()?;
5679 self.expect(&token::Colon)?;
5680 let ty = self.parse_ty()?;
5681
5682 Ok(GenericParam {
5683 ident,
5684 id: ast::DUMMY_NODE_ID,
5685 attrs: preceding_attrs.into(),
5686 bounds: Vec::new(),
5687 kind: GenericParamKind::Const {
5688 ty,
5689 }
5690 })
5691 }
5692
5693 /// Parses a (possibly empty) list of lifetime and type parameters, possibly including
5694 /// a trailing comma and erroneous trailing attributes.
5695 crate fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
5696 let mut params = Vec::new();
5697 loop {
5698 let attrs = self.parse_outer_attributes()?;
5699 if self.check_lifetime() {
5700 let lifetime = self.expect_lifetime();
5701 // Parse lifetime parameter.
5702 let bounds = if self.eat(&token::Colon) {
5703 self.parse_lt_param_bounds()
5704 } else {
5705 Vec::new()
5706 };
5707 params.push(ast::GenericParam {
5708 ident: lifetime.ident,
5709 id: lifetime.id,
5710 attrs: attrs.into(),
5711 bounds,
5712 kind: ast::GenericParamKind::Lifetime,
5713 });
5714 } else if self.check_keyword(keywords::Const) {
5715 // Parse const parameter.
5716 params.push(self.parse_const_param(attrs)?);
5717 } else if self.check_ident() {
5718 // Parse type parameter.
5719 params.push(self.parse_ty_param(attrs)?);
5720 } else {
5721 // Check for trailing attributes and stop parsing.
5722 if !attrs.is_empty() {
5723 if !params.is_empty() {
5724 self.struct_span_err(
5725 attrs[0].span,
5726 &format!("trailing attribute after generic parameter"),
5727 )
5728 .span_label(attrs[0].span, "attributes must go before parameters")
5729 .emit();
5730 } else {
5731 self.struct_span_err(
5732 attrs[0].span,
5733 &format!("attribute without generic parameters"),
5734 )
5735 .span_label(
5736 attrs[0].span,
5737 "attributes are only permitted when preceding parameters",
5738 )
5739 .emit();
5740 }
5741 }
5742 break
5743 }
5744
5745 if !self.eat(&token::Comma) {
5746 break
5747 }
5748 }
5749 Ok(params)
5750 }
5751
5752 /// Parses a set of optional generic type parameter declarations. Where
5753 /// clauses are not parsed here, and must be added later via
5754 /// `parse_where_clause()`.
5755 ///
5756 /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
5757 /// | ( < lifetimes , typaramseq ( , )? > )
5758 /// where typaramseq = ( typaram ) | ( typaram , typaramseq )
5759 fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
5760 maybe_whole!(self, NtGenerics, |x| x);
5761
5762 let span_lo = self.span;
5763 if self.eat_lt() {
5764 let params = self.parse_generic_params()?;
5765 self.expect_gt()?;
5766 Ok(ast::Generics {
5767 params,
5768 where_clause: WhereClause {
5769 id: ast::DUMMY_NODE_ID,
5770 predicates: Vec::new(),
5771 span: syntax_pos::DUMMY_SP,
5772 },
5773 span: span_lo.to(self.prev_span),
5774 })
5775 } else {
5776 Ok(ast::Generics::default())
5777 }
5778 }
5779
5780 /// Parses generic args (within a path segment) with recovery for extra leading angle brackets.
5781 /// For the purposes of understanding the parsing logic of generic arguments, this function
5782 /// can be thought of being the same as just calling `self.parse_generic_args()` if the source
5783 /// had the correct amount of leading angle brackets.
5784 ///
5785 /// ```ignore (diagnostics)
5786 /// bar::<<<<T as Foo>::Output>();
5787 /// ^^ help: remove extra angle brackets
5788 /// ```
5789 fn parse_generic_args_with_leaning_angle_bracket_recovery(
5790 &mut self,
5791 style: PathStyle,
5792 lo: Span,
5793 ) -> PResult<'a, (Vec<GenericArg>, Vec<TypeBinding>)> {
5794 // We need to detect whether there are extra leading left angle brackets and produce an
5795 // appropriate error and suggestion. This cannot be implemented by looking ahead at
5796 // upcoming tokens for a matching `>` character - if there are unmatched `<` tokens
5797 // then there won't be matching `>` tokens to find.
5798 //
5799 // To explain how this detection works, consider the following example:
5800 //
5801 // ```ignore (diagnostics)
5802 // bar::<<<<T as Foo>::Output>();
5803 // ^^ help: remove extra angle brackets
5804 // ```
5805 //
5806 // Parsing of the left angle brackets starts in this function. We start by parsing the
5807 // `<` token (incrementing the counter of unmatched angle brackets on `Parser` via
5808 // `eat_lt`):
5809 //
5810 // *Upcoming tokens:* `<<<<T as Foo>::Output>;`
5811 // *Unmatched count:* 1
5812 // *`parse_path_segment` calls deep:* 0
5813 //
5814 // This has the effect of recursing as this function is called if a `<` character
5815 // is found within the expected generic arguments:
5816 //
5817 // *Upcoming tokens:* `<<<T as Foo>::Output>;`
5818 // *Unmatched count:* 2
5819 // *`parse_path_segment` calls deep:* 1
5820 //
5821 // Eventually we will have recursed until having consumed all of the `<` tokens and
5822 // this will be reflected in the count:
5823 //
5824 // *Upcoming tokens:* `T as Foo>::Output>;`
5825 // *Unmatched count:* 4
5826 // `parse_path_segment` calls deep:* 3
5827 //
5828 // The parser will continue until reaching the first `>` - this will decrement the
5829 // unmatched angle bracket count and return to the parent invocation of this function
5830 // having succeeded in parsing:
5831 //
5832 // *Upcoming tokens:* `::Output>;`
5833 // *Unmatched count:* 3
5834 // *`parse_path_segment` calls deep:* 2
5835 //
5836 // This will continue until the next `>` character which will also return successfully
5837 // to the parent invocation of this function and decrement the count:
5838 //
5839 // *Upcoming tokens:* `;`
5840 // *Unmatched count:* 2
5841 // *`parse_path_segment` calls deep:* 1
5842 //
5843 // At this point, this function will expect to find another matching `>` character but
5844 // won't be able to and will return an error. This will continue all the way up the
5845 // call stack until the first invocation:
5846 //
5847 // *Upcoming tokens:* `;`
5848 // *Unmatched count:* 2
5849 // *`parse_path_segment` calls deep:* 0
5850 //
5851 // In doing this, we have managed to work out how many unmatched leading left angle
5852 // brackets there are, but we cannot recover as the unmatched angle brackets have
5853 // already been consumed. To remedy this, we keep a snapshot of the parser state
5854 // before we do the above. We can then inspect whether we ended up with a parsing error
5855 // and unmatched left angle brackets and if so, restore the parser state before we
5856 // consumed any `<` characters to emit an error and consume the erroneous tokens to
5857 // recover by attempting to parse again.
5858 //
5859 // In practice, the recursion of this function is indirect and there will be other
5860 // locations that consume some `<` characters - as long as we update the count when
5861 // this happens, it isn't an issue.
5862
5863 let is_first_invocation = style == PathStyle::Expr;
5864 // Take a snapshot before attempting to parse - we can restore this later.
5865 let snapshot = if is_first_invocation {
5866 Some(self.clone())
5867 } else {
5868 None
5869 };
5870
5871 debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)");
5872 match self.parse_generic_args() {
5873 Ok(value) => Ok(value),
5874 Err(ref mut e) if is_first_invocation && self.unmatched_angle_bracket_count > 0 => {
5875 // Cancel error from being unable to find `>`. We know the error
5876 // must have been this due to a non-zero unmatched angle bracket
5877 // count.
5878 e.cancel();
5879
5880 // Swap `self` with our backup of the parser state before attempting to parse
5881 // generic arguments.
5882 let snapshot = mem::replace(self, snapshot.unwrap());
5883
5884 debug!(
5885 "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot failure) \
5886 snapshot.count={:?}",
5887 snapshot.unmatched_angle_bracket_count,
5888 );
5889
5890 // Eat the unmatched angle brackets.
5891 for _ in 0..snapshot.unmatched_angle_bracket_count {
5892 self.eat_lt();
5893 }
5894
5895 // Make a span over ${unmatched angle bracket count} characters.
5896 let span = lo.with_hi(
5897 lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count)
5898 );
5899 let plural = snapshot.unmatched_angle_bracket_count > 1;
5900 self.diagnostic()
5901 .struct_span_err(
5902 span,
5903 &format!(
5904 "unmatched angle bracket{}",
5905 if plural { "s" } else { "" }
5906 ),
5907 )
5908 .span_suggestion(
5909 span,
5910 &format!(
5911 "remove extra angle bracket{}",
5912 if plural { "s" } else { "" }
5913 ),
5914 String::new(),
5915 Applicability::MachineApplicable,
5916 )
5917 .emit();
5918
5919 // Try again without unmatched angle bracket characters.
5920 self.parse_generic_args()
5921 },
5922 Err(e) => Err(e),
5923 }
5924 }
5925
5926 /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
5927 /// possibly including trailing comma.
5928 fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<TypeBinding>)> {
5929 let mut args = Vec::new();
5930 let mut bindings = Vec::new();
5931 let mut misplaced_assoc_ty_bindings: Vec<Span> = Vec::new();
5932 let mut assoc_ty_bindings: Vec<Span> = Vec::new();
5933
5934 let args_lo = self.span;
5935
5936 loop {
5937 if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
5938 // Parse lifetime argument.
5939 args.push(GenericArg::Lifetime(self.expect_lifetime()));
5940 misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings);
5941 } else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) {
5942 // Parse associated type binding.
5943 let lo = self.span;
5944 let ident = self.parse_ident()?;
5945 self.bump();
5946 let ty = self.parse_ty()?;
5947 let span = lo.to(self.prev_span);
5948 bindings.push(TypeBinding {
5949 id: ast::DUMMY_NODE_ID,
5950 ident,
5951 ty,
5952 span,
5953 });
5954 assoc_ty_bindings.push(span);
5955 } else if self.check_const_arg() {
5956 // FIXME(const_generics): to distinguish between idents for types and consts,
5957 // we should introduce a GenericArg::Ident in the AST and distinguish when
5958 // lowering to the HIR. For now, idents for const args are not permitted.
5959
5960 // Parse const argument.
5961 let expr = if let token::OpenDelim(token::Brace) = self.token {
5962 self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())?
5963 } else if self.token.is_ident() {
5964 // FIXME(const_generics): to distinguish between idents for types and consts,
5965 // we should introduce a GenericArg::Ident in the AST and distinguish when
5966 // lowering to the HIR. For now, idents for const args are not permitted.
5967 return Err(
5968 self.fatal("identifiers may currently not be used for const generics")
5969 );
5970 } else {
5971 // FIXME(const_generics): this currently conflicts with emplacement syntax
5972 // with negative integer literals.
5973 self.parse_literal_maybe_minus()?
5974 };
5975 let value = AnonConst {
5976 id: ast::DUMMY_NODE_ID,
5977 value: expr,
5978 };
5979 args.push(GenericArg::Const(value));
5980 misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings);
5981 } else if self.check_type() {
5982 // Parse type argument.
5983 args.push(GenericArg::Type(self.parse_ty()?));
5984 misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings);
5985 } else {
5986 break
5987 }
5988
5989 if !self.eat(&token::Comma) {
5990 break
5991 }
5992 }
5993
5994 // FIXME: we would like to report this in ast_validation instead, but we currently do not
5995 // preserve ordering of generic parameters with respect to associated type binding, so we
5996 // lose that information after parsing.
5997 if misplaced_assoc_ty_bindings.len() > 0 {
5998 let mut err = self.struct_span_err(
5999 args_lo.to(self.prev_span),
6000 "associated type bindings must be declared after generic parameters",
6001 );
6002 for span in misplaced_assoc_ty_bindings {
6003 err.span_label(
6004 span,
6005 "this associated type binding should be moved after the generic parameters",
6006 );
6007 }
6008 err.emit();
6009 }
6010
6011 Ok((args, bindings))
6012 }
6013
6014 /// Parses an optional where-clause and places it in `generics`.
6015 ///
6016 /// ```ignore (only-for-syntax-highlight)
6017 /// where T : Trait<U, V> + 'b, 'a : 'b
6018 /// ```
6019 fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
6020 maybe_whole!(self, NtWhereClause, |x| x);
6021
6022 let mut where_clause = WhereClause {
6023 id: ast::DUMMY_NODE_ID,
6024 predicates: Vec::new(),
6025 span: syntax_pos::DUMMY_SP,
6026 };
6027
6028 if !self.eat_keyword(keywords::Where) {
6029 return Ok(where_clause);
6030 }
6031 let lo = self.prev_span;
6032
6033 // We are considering adding generics to the `where` keyword as an alternative higher-rank
6034 // parameter syntax (as in `where<'a>` or `where<T>`. To avoid that being a breaking
6035 // change we parse those generics now, but report an error.
6036 if self.choose_generics_over_qpath() {
6037 let generics = self.parse_generics()?;
6038 self.struct_span_err(
6039 generics.span,
6040 "generic parameters on `where` clauses are reserved for future use",
6041 )
6042 .span_label(generics.span, "currently unsupported")
6043 .emit();
6044 }
6045
6046 loop {
6047 let lo = self.span;
6048 if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
6049 let lifetime = self.expect_lifetime();
6050 // Bounds starting with a colon are mandatory, but possibly empty.
6051 self.expect(&token::Colon)?;
6052 let bounds = self.parse_lt_param_bounds();
6053 where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
6054 ast::WhereRegionPredicate {
6055 span: lo.to(self.prev_span),
6056 lifetime,
6057 bounds,
6058 }
6059 ));
6060 } else if self.check_type() {
6061 // Parse optional `for<'a, 'b>`.
6062 // This `for` is parsed greedily and applies to the whole predicate,
6063 // the bounded type can have its own `for` applying only to it.
6064 // Example 1: for<'a> Trait1<'a>: Trait2<'a /*ok*/>
6065 // Example 2: (for<'a> Trait1<'a>): Trait2<'a /*not ok*/>
6066 // Example 3: for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /*ok*/, 'b /*not ok*/>
6067 let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
6068
6069 // Parse type with mandatory colon and (possibly empty) bounds,
6070 // or with mandatory equality sign and the second type.
6071 let ty = self.parse_ty()?;
6072 if self.eat(&token::Colon) {
6073 let bounds = self.parse_generic_bounds(None)?;
6074 where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
6075 ast::WhereBoundPredicate {
6076 span: lo.to(self.prev_span),
6077 bound_generic_params: lifetime_defs,
6078 bounded_ty: ty,
6079 bounds,
6080 }
6081 ));
6082 // FIXME: Decide what should be used here, `=` or `==`.
6083 // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
6084 } else if self.eat(&token::Eq) || self.eat(&token::EqEq) {
6085 let rhs_ty = self.parse_ty()?;
6086 where_clause.predicates.push(ast::WherePredicate::EqPredicate(
6087 ast::WhereEqPredicate {
6088 span: lo.to(self.prev_span),
6089 lhs_ty: ty,
6090 rhs_ty,
6091 id: ast::DUMMY_NODE_ID,
6092 }
6093 ));
6094 } else {
6095 return self.unexpected();
6096 }
6097 } else {
6098 break
6099 }
6100
6101 if !self.eat(&token::Comma) {
6102 break
6103 }
6104 }
6105
6106 where_clause.span = lo.to(self.prev_span);
6107 Ok(where_clause)
6108 }
6109
6110 fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
6111 -> PResult<'a, (Vec<Arg> , bool)> {
6112 self.expect(&token::OpenDelim(token::Paren))?;
6113
6114 let sp = self.span;
6115 let mut variadic = false;
6116 let (args, recovered): (Vec<Option<Arg>>, bool) =
6117 self.parse_seq_to_before_end(
6118 &token::CloseDelim(token::Paren),
6119 SeqSep::trailing_allowed(token::Comma),
6120 |p| {
6121 if p.token == token::DotDotDot {
6122 p.bump();
6123 variadic = true;
6124 if allow_variadic {
6125 if p.token != token::CloseDelim(token::Paren) {
6126 let span = p.span;
6127 p.span_err(span,
6128 "`...` must be last in argument list for variadic function");
6129 }
6130 Ok(None)
6131 } else {
6132 let span = p.prev_span;
6133 if p.token == token::CloseDelim(token::Paren) {
6134 // continue parsing to present any further errors
6135 p.struct_span_err(
6136 span,
6137 "only foreign functions are allowed to be variadic"
6138 ).emit();
6139 Ok(Some(dummy_arg(span)))
6140 } else {
6141 // this function definition looks beyond recovery, stop parsing
6142 p.span_err(span,
6143 "only foreign functions are allowed to be variadic");
6144 Ok(None)
6145 }
6146 }
6147 } else {
6148 match p.parse_arg_general(named_args, false) {
6149 Ok(arg) => Ok(Some(arg)),
6150 Err(mut e) => {
6151 e.emit();
6152 let lo = p.prev_span;
6153 // Skip every token until next possible arg or end.
6154 p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
6155 // Create a placeholder argument for proper arg count (#34264).
6156 let span = lo.to(p.prev_span);
6157 Ok(Some(dummy_arg(span)))
6158 }
6159 }
6160 }
6161 }
6162 )?;
6163
6164 if !recovered {
6165 self.eat(&token::CloseDelim(token::Paren));
6166 }
6167
6168 let args: Vec<_> = args.into_iter().filter_map(|x| x).collect();
6169
6170 if variadic && args.is_empty() {
6171 self.span_err(sp,
6172 "variadic function must be declared with at least one named argument");
6173 }
6174
6175 Ok((args, variadic))
6176 }
6177
6178 /// Parses the argument list and result type of a function declaration.
6179 fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<'a, P<FnDecl>> {
6180
6181 let (args, variadic) = self.parse_fn_args(true, allow_variadic)?;
6182 let ret_ty = self.parse_ret_ty(true)?;
6183
6184 Ok(P(FnDecl {
6185 inputs: args,
6186 output: ret_ty,
6187 variadic,
6188 }))
6189 }
6190
6191 /// Returns the parsed optional self argument and whether a self shortcut was used.
6192 fn parse_self_arg(&mut self) -> PResult<'a, Option<Arg>> {
6193 let expect_ident = |this: &mut Self| match this.token {
6194 // Preserve hygienic context.
6195 token::Ident(ident, _) =>
6196 { let span = this.span; this.bump(); Ident::new(ident.name, span) }
6197 _ => unreachable!()
6198 };
6199 let isolated_self = |this: &mut Self, n| {
6200 this.look_ahead(n, |t| t.is_keyword(keywords::SelfLower)) &&
6201 this.look_ahead(n + 1, |t| t != &token::ModSep)
6202 };
6203
6204 // Parse optional self parameter of a method.
6205 // Only a limited set of initial token sequences is considered self parameters, anything
6206 // else is parsed as a normal function parameter list, so some lookahead is required.
6207 let eself_lo = self.span;
6208 let (eself, eself_ident, eself_hi) = match self.token {
6209 token::BinOp(token::And) => {
6210 // &self
6211 // &mut self
6212 // &'lt self
6213 // &'lt mut self
6214 // &not_self
6215 (if isolated_self(self, 1) {
6216 self.bump();
6217 SelfKind::Region(None, Mutability::Immutable)
6218 } else if self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
6219 isolated_self(self, 2) {
6220 self.bump();
6221 self.bump();
6222 SelfKind::Region(None, Mutability::Mutable)
6223 } else if self.look_ahead(1, |t| t.is_lifetime()) &&
6224 isolated_self(self, 2) {
6225 self.bump();
6226 let lt = self.expect_lifetime();
6227 SelfKind::Region(Some(lt), Mutability::Immutable)
6228 } else if self.look_ahead(1, |t| t.is_lifetime()) &&
6229 self.look_ahead(2, |t| t.is_keyword(keywords::Mut)) &&
6230 isolated_self(self, 3) {
6231 self.bump();
6232 let lt = self.expect_lifetime();
6233 self.bump();
6234 SelfKind::Region(Some(lt), Mutability::Mutable)
6235 } else {
6236 return Ok(None);
6237 }, expect_ident(self), self.prev_span)
6238 }
6239 token::BinOp(token::Star) => {
6240 // *self
6241 // *const self
6242 // *mut self
6243 // *not_self
6244 // Emit special error for `self` cases.
6245 let msg = "cannot pass `self` by raw pointer";
6246 (if isolated_self(self, 1) {
6247 self.bump();
6248 self.struct_span_err(self.span, msg)
6249 .span_label(self.span, msg)
6250 .emit();
6251 SelfKind::Value(Mutability::Immutable)
6252 } else if self.look_ahead(1, |t| t.is_mutability()) &&
6253 isolated_self(self, 2) {
6254 self.bump();
6255 self.bump();
6256 self.struct_span_err(self.span, msg)
6257 .span_label(self.span, msg)
6258 .emit();
6259 SelfKind::Value(Mutability::Immutable)
6260 } else {
6261 return Ok(None);
6262 }, expect_ident(self), self.prev_span)
6263 }
6264 token::Ident(..) => {
6265 if isolated_self(self, 0) {
6266 // self
6267 // self: TYPE
6268 let eself_ident = expect_ident(self);
6269 let eself_hi = self.prev_span;
6270 (if self.eat(&token::Colon) {
6271 let ty = self.parse_ty()?;
6272 SelfKind::Explicit(ty, Mutability::Immutable)
6273 } else {
6274 SelfKind::Value(Mutability::Immutable)
6275 }, eself_ident, eself_hi)
6276 } else if self.token.is_keyword(keywords::Mut) &&
6277 isolated_self(self, 1) {
6278 // mut self
6279 // mut self: TYPE
6280 self.bump();
6281 let eself_ident = expect_ident(self);
6282 let eself_hi = self.prev_span;
6283 (if self.eat(&token::Colon) {
6284 let ty = self.parse_ty()?;
6285 SelfKind::Explicit(ty, Mutability::Mutable)
6286 } else {
6287 SelfKind::Value(Mutability::Mutable)
6288 }, eself_ident, eself_hi)
6289 } else {
6290 return Ok(None);
6291 }
6292 }
6293 _ => return Ok(None),
6294 };
6295
6296 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
6297 Ok(Some(Arg::from_self(eself, eself_ident)))
6298 }
6299
6300 /// Parses the parameter list and result type of a function that may have a `self` parameter.
6301 fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> PResult<'a, P<FnDecl>>
6302 where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>,
6303 {
6304 self.expect(&token::OpenDelim(token::Paren))?;
6305
6306 // Parse optional self argument
6307 let self_arg = self.parse_self_arg()?;
6308
6309 // Parse the rest of the function parameter list.
6310 let sep = SeqSep::trailing_allowed(token::Comma);
6311 let (fn_inputs, recovered) = if let Some(self_arg) = self_arg {
6312 if self.check(&token::CloseDelim(token::Paren)) {
6313 (vec![self_arg], false)
6314 } else if self.eat(&token::Comma) {
6315 let mut fn_inputs = vec![self_arg];
6316 let (mut input, recovered) = self.parse_seq_to_before_end(
6317 &token::CloseDelim(token::Paren), sep, parse_arg_fn)?;
6318 fn_inputs.append(&mut input);
6319 (fn_inputs, recovered)
6320 } else {
6321 return self.unexpected();
6322 }
6323 } else {
6324 self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?
6325 };
6326
6327 if !recovered {
6328 // Parse closing paren and return type.
6329 self.expect(&token::CloseDelim(token::Paren))?;
6330 }
6331 Ok(P(FnDecl {
6332 inputs: fn_inputs,
6333 output: self.parse_ret_ty(true)?,
6334 variadic: false
6335 }))
6336 }
6337
6338 /// Parses the `|arg, arg|` header of a closure.
6339 fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
6340 let inputs_captures = {
6341 if self.eat(&token::OrOr) {
6342 Vec::new()
6343 } else {
6344 self.expect(&token::BinOp(token::Or))?;
6345 let args = self.parse_seq_to_before_tokens(
6346 &[&token::BinOp(token::Or), &token::OrOr],
6347 SeqSep::trailing_allowed(token::Comma),
6348 TokenExpectType::NoExpect,
6349 |p| p.parse_fn_block_arg()
6350 )?.0;
6351 self.expect_or()?;
6352 args
6353 }
6354 };
6355 let output = self.parse_ret_ty(true)?;
6356
6357 Ok(P(FnDecl {
6358 inputs: inputs_captures,
6359 output,
6360 variadic: false
6361 }))
6362 }
6363
6364 /// Parses the name and optional generic types of a function header.
6365 fn parse_fn_header(&mut self) -> PResult<'a, (Ident, ast::Generics)> {
6366 let id = self.parse_ident()?;
6367 let generics = self.parse_generics()?;
6368 Ok((id, generics))
6369 }
6370
6371 fn mk_item(&mut self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
6372 attrs: Vec<Attribute>) -> P<Item> {
6373 P(Item {
6374 ident,
6375 attrs,
6376 id: ast::DUMMY_NODE_ID,
6377 node,
6378 vis,
6379 span,
6380 tokens: None,
6381 })
6382 }
6383
6384 /// Parses an item-position function declaration.
6385 fn parse_item_fn(&mut self,
6386 unsafety: Unsafety,
6387 asyncness: IsAsync,
6388 constness: Spanned<Constness>,
6389 abi: Abi)
6390 -> PResult<'a, ItemInfo> {
6391 let (ident, mut generics) = self.parse_fn_header()?;
6392 let decl = self.parse_fn_decl(false)?;
6393 generics.where_clause = self.parse_where_clause()?;
6394 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
6395 let header = FnHeader { unsafety, asyncness, constness, abi };
6396 Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
6397 }
6398
6399 /// Returns `true` if we are looking at `const ID`
6400 /// (returns `false` for things like `const fn`, etc.).
6401 fn is_const_item(&mut self) -> bool {
6402 self.token.is_keyword(keywords::Const) &&
6403 !self.look_ahead(1, |t| t.is_keyword(keywords::Fn)) &&
6404 !self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe))
6405 }
6406
6407 /// Parses all the "front matter" for a `fn` declaration, up to
6408 /// and including the `fn` keyword:
6409 ///
6410 /// - `const fn`
6411 /// - `unsafe fn`
6412 /// - `const unsafe fn`
6413 /// - `extern fn`
6414 /// - etc.
6415 fn parse_fn_front_matter(&mut self)
6416 -> PResult<'a, (
6417 Spanned<Constness>,
6418 Unsafety,
6419 IsAsync,
6420 Abi
6421 )>
6422 {
6423 let is_const_fn = self.eat_keyword(keywords::Const);
6424 let const_span = self.prev_span;
6425 let unsafety = self.parse_unsafety();
6426 let asyncness = self.parse_asyncness();
6427 let (constness, unsafety, abi) = if is_const_fn {
6428 (respan(const_span, Constness::Const), unsafety, Abi::Rust)
6429 } else {
6430 let abi = if self.eat_keyword(keywords::Extern) {
6431 self.parse_opt_abi()?.unwrap_or(Abi::C)
6432 } else {
6433 Abi::Rust
6434 };
6435 (respan(self.prev_span, Constness::NotConst), unsafety, abi)
6436 };
6437 self.expect_keyword(keywords::Fn)?;
6438 Ok((constness, unsafety, asyncness, abi))
6439 }
6440
6441 /// Parses an impl item.
6442 pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
6443 maybe_whole!(self, NtImplItem, |x| x);
6444 let attrs = self.parse_outer_attributes()?;
6445 let (mut item, tokens) = self.collect_tokens(|this| {
6446 this.parse_impl_item_(at_end, attrs)
6447 })?;
6448
6449 // See `parse_item` for why this clause is here.
6450 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
6451 item.tokens = Some(tokens);
6452 }
6453 Ok(item)
6454 }
6455
6456 fn parse_impl_item_(&mut self,
6457 at_end: &mut bool,
6458 mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> {
6459 let lo = self.span;
6460 let vis = self.parse_visibility(false)?;
6461 let defaultness = self.parse_defaultness();
6462 let (name, node, generics) = if let Some(type_) = self.eat_type() {
6463 let (name, alias, generics) = type_?;
6464 let kind = match alias {
6465 AliasKind::Weak(typ) => ast::ImplItemKind::Type(typ),
6466 AliasKind::Existential(bounds) => ast::ImplItemKind::Existential(bounds),
6467 };
6468 (name, kind, generics)
6469 } else if self.is_const_item() {
6470 // This parses the grammar:
6471 // ImplItemConst = "const" Ident ":" Ty "=" Expr ";"
6472 self.expect_keyword(keywords::Const)?;
6473 let name = self.parse_ident()?;
6474 self.expect(&token::Colon)?;
6475 let typ = self.parse_ty()?;
6476 self.expect(&token::Eq)?;
6477 let expr = self.parse_expr()?;
6478 self.expect(&token::Semi)?;
6479 (name, ast::ImplItemKind::Const(typ, expr), ast::Generics::default())
6480 } else {
6481 let (name, inner_attrs, generics, node) = self.parse_impl_method(&vis, at_end)?;
6482 attrs.extend(inner_attrs);
6483 (name, node, generics)
6484 };
6485
6486 Ok(ImplItem {
6487 id: ast::DUMMY_NODE_ID,
6488 span: lo.to(self.prev_span),
6489 ident: name,
6490 vis,
6491 defaultness,
6492 attrs,
6493 generics,
6494 node,
6495 tokens: None,
6496 })
6497 }
6498
6499 fn complain_if_pub_macro(&mut self, vis: &VisibilityKind, sp: Span) {
6500 match *vis {
6501 VisibilityKind::Inherited => {}
6502 _ => {
6503 let is_macro_rules: bool = match self.token {
6504 token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"),
6505 _ => false,
6506 };
6507 let mut err = if is_macro_rules {
6508 let mut err = self.diagnostic()
6509 .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
6510 err.span_suggestion(
6511 sp,
6512 "try exporting the macro",
6513 "#[macro_export]".to_owned(),
6514 Applicability::MaybeIncorrect // speculative
6515 );
6516 err
6517 } else {
6518 let mut err = self.diagnostic()
6519 .struct_span_err(sp, "can't qualify macro invocation with `pub`");
6520 err.help("try adjusting the macro to put `pub` inside the invocation");
6521 err
6522 };
6523 err.emit();
6524 }
6525 }
6526 }
6527
6528 fn missing_assoc_item_kind_err(&mut self, item_type: &str, prev_span: Span)
6529 -> DiagnosticBuilder<'a>
6530 {
6531 let expected_kinds = if item_type == "extern" {
6532 "missing `fn`, `type`, or `static`"
6533 } else {
6534 "missing `fn`, `type`, or `const`"
6535 };
6536
6537 // Given this code `path(`, it seems like this is not
6538 // setting the visibility of a macro invocation, but rather
6539 // a mistyped method declaration.
6540 // Create a diagnostic pointing out that `fn` is missing.
6541 //
6542 // x | pub path(&self) {
6543 // | ^ missing `fn`, `type`, or `const`
6544 // pub path(
6545 // ^^ `sp` below will point to this
6546 let sp = prev_span.between(self.prev_span);
6547 let mut err = self.diagnostic().struct_span_err(
6548 sp,
6549 &format!("{} for {}-item declaration",
6550 expected_kinds, item_type));
6551 err.span_label(sp, expected_kinds);
6552 err
6553 }
6554
6555 /// Parse a method or a macro invocation in a trait impl.
6556 fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
6557 -> PResult<'a, (Ident, Vec<Attribute>, ast::Generics,
6558 ast::ImplItemKind)> {
6559 // code copied from parse_macro_use_or_failure... abstraction!
6560 if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
6561 // method macro
6562 Ok((keywords::Invalid.ident(), vec![], ast::Generics::default(),
6563 ast::ImplItemKind::Macro(mac)))
6564 } else {
6565 let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
6566 let ident = self.parse_ident()?;
6567 let mut generics = self.parse_generics()?;
6568 let decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
6569 generics.where_clause = self.parse_where_clause()?;
6570 *at_end = true;
6571 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
6572 let header = ast::FnHeader { abi, unsafety, constness, asyncness };
6573 Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(
6574 ast::MethodSig { header, decl },
6575 body
6576 )))
6577 }
6578 }
6579
6580 /// Parses `trait Foo { ... }` or `trait Foo = Bar;`.
6581 fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
6582 let ident = self.parse_ident()?;
6583 let mut tps = self.parse_generics()?;
6584
6585 // Parse optional colon and supertrait bounds.
6586 let bounds = if self.eat(&token::Colon) {
6587 self.parse_generic_bounds(Some(self.prev_span))?
6588 } else {
6589 Vec::new()
6590 };
6591
6592 if self.eat(&token::Eq) {
6593 // it's a trait alias
6594 let bounds = self.parse_generic_bounds(None)?;
6595 tps.where_clause = self.parse_where_clause()?;
6596 self.expect(&token::Semi)?;
6597 if is_auto == IsAuto::Yes {
6598 let msg = "trait aliases cannot be `auto`";
6599 self.struct_span_err(self.prev_span, msg)
6600 .span_label(self.prev_span, msg)
6601 .emit();
6602 }
6603 if unsafety != Unsafety::Normal {
6604 let msg = "trait aliases cannot be `unsafe`";
6605 self.struct_span_err(self.prev_span, msg)
6606 .span_label(self.prev_span, msg)
6607 .emit();
6608 }
6609 Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
6610 } else {
6611 // it's a normal trait
6612 tps.where_clause = self.parse_where_clause()?;
6613 self.expect(&token::OpenDelim(token::Brace))?;
6614 let mut trait_items = vec![];
6615 while !self.eat(&token::CloseDelim(token::Brace)) {
6616 let mut at_end = false;
6617 match self.parse_trait_item(&mut at_end) {
6618 Ok(item) => trait_items.push(item),
6619 Err(mut e) => {
6620 e.emit();
6621 if !at_end {
6622 self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
6623 }
6624 }
6625 }
6626 }
6627 Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
6628 }
6629 }
6630
6631 fn choose_generics_over_qpath(&self) -> bool {
6632 // There's an ambiguity between generic parameters and qualified paths in impls.
6633 // If we see `<` it may start both, so we have to inspect some following tokens.
6634 // The following combinations can only start generics,
6635 // but not qualified paths (with one exception):
6636 // `<` `>` - empty generic parameters
6637 // `<` `#` - generic parameters with attributes
6638 // `<` (LIFETIME|IDENT) `>` - single generic parameter
6639 // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
6640 // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
6641 // `<` (LIFETIME|IDENT) `=` - generic parameter with a default
6642 // `<` const - generic const parameter
6643 // The only truly ambiguous case is
6644 // `<` IDENT `>` `::` IDENT ...
6645 // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
6646 // because this is what almost always expected in practice, qualified paths in impls
6647 // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
6648 self.token == token::Lt &&
6649 (self.look_ahead(1, |t| t == &token::Pound || t == &token::Gt) ||
6650 self.look_ahead(1, |t| t.is_lifetime() || t.is_ident()) &&
6651 self.look_ahead(2, |t| t == &token::Gt || t == &token::Comma ||
6652 t == &token::Colon || t == &token::Eq) ||
6653 self.look_ahead(1, |t| t.is_keyword(keywords::Const)))
6654 }
6655
6656 fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
6657 self.expect(&token::OpenDelim(token::Brace))?;
6658 let attrs = self.parse_inner_attributes()?;
6659
6660 let mut impl_items = Vec::new();
6661 while !self.eat(&token::CloseDelim(token::Brace)) {
6662 let mut at_end = false;
6663 match self.parse_impl_item(&mut at_end) {
6664 Ok(impl_item) => impl_items.push(impl_item),
6665 Err(mut err) => {
6666 err.emit();
6667 if !at_end {
6668 self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
6669 }
6670 }
6671 }
6672 }
6673 Ok((impl_items, attrs))
6674 }
6675
6676 /// Parses an implementation item, `impl` keyword is already parsed.
6677 ///
6678 /// impl<'a, T> TYPE { /* impl items */ }
6679 /// impl<'a, T> TRAIT for TYPE { /* impl items */ }
6680 /// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
6681 ///
6682 /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
6683 /// `impl` GENERICS `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}`
6684 /// `impl` GENERICS `!`? TYPE (`where` PREDICATES)? `{` BODY `}`
6685 fn parse_item_impl(&mut self, unsafety: Unsafety, defaultness: Defaultness)
6686 -> PResult<'a, ItemInfo> {
6687 // First, parse generic parameters if necessary.
6688 let mut generics = if self.choose_generics_over_qpath() {
6689 self.parse_generics()?
6690 } else {
6691 ast::Generics::default()
6692 };
6693
6694 // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
6695 let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
6696 self.bump(); // `!`
6697 ast::ImplPolarity::Negative
6698 } else {
6699 ast::ImplPolarity::Positive
6700 };
6701
6702 // Parse both types and traits as a type, then reinterpret if necessary.
6703 let ty_first = self.parse_ty()?;
6704
6705 // If `for` is missing we try to recover.
6706 let has_for = self.eat_keyword(keywords::For);
6707 let missing_for_span = self.prev_span.between(self.span);
6708
6709 let ty_second = if self.token == token::DotDot {
6710 // We need to report this error after `cfg` expansion for compatibility reasons
6711 self.bump(); // `..`, do not add it to expected tokens
6712 Some(P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID }))
6713 } else if has_for || self.token.can_begin_type() {
6714 Some(self.parse_ty()?)
6715 } else {
6716 None
6717 };
6718
6719 generics.where_clause = self.parse_where_clause()?;
6720
6721 let (impl_items, attrs) = self.parse_impl_body()?;
6722
6723 let item_kind = match ty_second {
6724 Some(ty_second) => {
6725 // impl Trait for Type
6726 if !has_for {
6727 self.struct_span_err(missing_for_span, "missing `for` in a trait impl")
6728 .span_suggestion_short(
6729 missing_for_span,
6730 "add `for` here",
6731 " for ".to_string(),
6732 Applicability::MachineApplicable,
6733 ).emit();
6734 }
6735
6736 let ty_first = ty_first.into_inner();
6737 let path = match ty_first.node {
6738 // This notably includes paths passed through `ty` macro fragments (#46438).
6739 TyKind::Path(None, path) => path,
6740 _ => {
6741 self.span_err(ty_first.span, "expected a trait, found type");
6742 ast::Path::from_ident(Ident::new(keywords::Invalid.name(), ty_first.span))
6743 }
6744 };
6745 let trait_ref = TraitRef { path, ref_id: ty_first.id };
6746
6747 ItemKind::Impl(unsafety, polarity, defaultness,
6748 generics, Some(trait_ref), ty_second, impl_items)
6749 }
6750 None => {
6751 // impl Type
6752 ItemKind::Impl(unsafety, polarity, defaultness,
6753 generics, None, ty_first, impl_items)
6754 }
6755 };
6756
6757 Ok((keywords::Invalid.ident(), item_kind, Some(attrs)))
6758 }
6759
6760 fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
6761 if self.eat_keyword(keywords::For) {
6762 self.expect_lt()?;
6763 let params = self.parse_generic_params()?;
6764 self.expect_gt()?;
6765 // We rely on AST validation to rule out invalid cases: There must not be type
6766 // parameters, and the lifetime parameters must not have bounds.
6767 Ok(params)
6768 } else {
6769 Ok(Vec::new())
6770 }
6771 }
6772
6773 /// Parses `struct Foo { ... }`.
6774 fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
6775 let class_name = self.parse_ident()?;
6776
6777 let mut generics = self.parse_generics()?;
6778
6779 // There is a special case worth noting here, as reported in issue #17904.
6780 // If we are parsing a tuple struct it is the case that the where clause
6781 // should follow the field list. Like so:
6782 //
6783 // struct Foo<T>(T) where T: Copy;
6784 //
6785 // If we are parsing a normal record-style struct it is the case
6786 // that the where clause comes before the body, and after the generics.
6787 // So if we look ahead and see a brace or a where-clause we begin
6788 // parsing a record style struct.
6789 //
6790 // Otherwise if we look ahead and see a paren we parse a tuple-style
6791 // struct.
6792
6793 let vdata = if self.token.is_keyword(keywords::Where) {
6794 generics.where_clause = self.parse_where_clause()?;
6795 if self.eat(&token::Semi) {
6796 // If we see a: `struct Foo<T> where T: Copy;` style decl.
6797 VariantData::Unit(ast::DUMMY_NODE_ID)
6798 } else {
6799 // If we see: `struct Foo<T> where T: Copy { ... }`
6800 VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
6801 }
6802 // No `where` so: `struct Foo<T>;`
6803 } else if self.eat(&token::Semi) {
6804 VariantData::Unit(ast::DUMMY_NODE_ID)
6805 // Record-style struct definition
6806 } else if self.token == token::OpenDelim(token::Brace) {
6807 VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
6808 // Tuple-style struct definition with optional where-clause.
6809 } else if self.token == token::OpenDelim(token::Paren) {
6810 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, ast::DUMMY_NODE_ID);
6811 generics.where_clause = self.parse_where_clause()?;
6812 self.expect(&token::Semi)?;
6813 body
6814 } else {
6815 let token_str = self.this_token_descr();
6816 let mut err = self.fatal(&format!(
6817 "expected `where`, `{{`, `(`, or `;` after struct name, found {}",
6818 token_str
6819 ));
6820 err.span_label(self.span, "expected `where`, `{`, `(`, or `;` after struct name");
6821 return Err(err);
6822 };
6823
6824 Ok((class_name, ItemKind::Struct(vdata, generics), None))
6825 }
6826
6827 /// Parses `union Foo { ... }`.
6828 fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
6829 let class_name = self.parse_ident()?;
6830
6831 let mut generics = self.parse_generics()?;
6832
6833 let vdata = if self.token.is_keyword(keywords::Where) {
6834 generics.where_clause = self.parse_where_clause()?;
6835 VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
6836 } else if self.token == token::OpenDelim(token::Brace) {
6837 VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
6838 } else {
6839 let token_str = self.this_token_descr();
6840 let mut err = self.fatal(&format!(
6841 "expected `where` or `{{` after union name, found {}", token_str));
6842 err.span_label(self.span, "expected `where` or `{` after union name");
6843 return Err(err);
6844 };
6845
6846 Ok((class_name, ItemKind::Union(vdata, generics), None))
6847 }
6848
6849 fn consume_block(&mut self, delim: token::DelimToken) {
6850 let mut brace_depth = 0;
6851 loop {
6852 if self.eat(&token::OpenDelim(delim)) {
6853 brace_depth += 1;
6854 } else if self.eat(&token::CloseDelim(delim)) {
6855 if brace_depth == 0 {
6856 return;
6857 } else {
6858 brace_depth -= 1;
6859 continue;
6860 }
6861 } else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) {
6862 return;
6863 } else {
6864 self.bump();
6865 }
6866 }
6867 }
6868
6869 fn parse_record_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
6870 let mut fields = Vec::new();
6871 if self.eat(&token::OpenDelim(token::Brace)) {
6872 while self.token != token::CloseDelim(token::Brace) {
6873 let field = self.parse_struct_decl_field().map_err(|e| {
6874 self.recover_stmt();
6875 e
6876 });
6877 match field {
6878 Ok(field) => fields.push(field),
6879 Err(mut err) => {
6880 err.emit();
6881 }
6882 }
6883 }
6884 self.eat(&token::CloseDelim(token::Brace));
6885 } else {
6886 let token_str = self.this_token_descr();
6887 let mut err = self.fatal(&format!(
6888 "expected `where`, or `{{` after struct name, found {}", token_str));
6889 err.span_label(self.span, "expected `where`, or `{` after struct name");
6890 return Err(err);
6891 }
6892
6893 Ok(fields)
6894 }
6895
6896 fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
6897 // This is the case where we find `struct Foo<T>(T) where T: Copy;`
6898 // Unit like structs are handled in parse_item_struct function
6899 let fields = self.parse_unspanned_seq(
6900 &token::OpenDelim(token::Paren),
6901 &token::CloseDelim(token::Paren),
6902 SeqSep::trailing_allowed(token::Comma),
6903 |p| {
6904 let attrs = p.parse_outer_attributes()?;
6905 let lo = p.span;
6906 let vis = p.parse_visibility(true)?;
6907 let ty = p.parse_ty()?;
6908 Ok(StructField {
6909 span: lo.to(ty.span),
6910 vis,
6911 ident: None,
6912 id: ast::DUMMY_NODE_ID,
6913 ty,
6914 attrs,
6915 })
6916 })?;
6917
6918 Ok(fields)
6919 }
6920
6921 /// Parses a structure field declaration.
6922 fn parse_single_struct_field(&mut self,
6923 lo: Span,
6924 vis: Visibility,
6925 attrs: Vec<Attribute> )
6926 -> PResult<'a, StructField> {
6927 let mut seen_comma: bool = false;
6928 let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
6929 if self.token == token::Comma {
6930 seen_comma = true;
6931 }
6932 match self.token {
6933 token::Comma => {
6934 self.bump();
6935 }
6936 token::CloseDelim(token::Brace) => {}
6937 token::DocComment(_) => {
6938 let previous_span = self.prev_span;
6939 let mut err = self.span_fatal_err(self.span, Error::UselessDocComment);
6940 self.bump(); // consume the doc comment
6941 let comma_after_doc_seen = self.eat(&token::Comma);
6942 // `seen_comma` is always false, because we are inside doc block
6943 // condition is here to make code more readable
6944 if seen_comma == false && comma_after_doc_seen == true {
6945 seen_comma = true;
6946 }
6947 if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) {
6948 err.emit();
6949 } else {
6950 if seen_comma == false {
6951 let sp = self.sess.source_map().next_point(previous_span);
6952 err.span_suggestion(
6953 sp,
6954 "missing comma here",
6955 ",".into(),
6956 Applicability::MachineApplicable
6957 );
6958 }
6959 return Err(err);
6960 }
6961 }
6962 _ => {
6963 let sp = self.sess.source_map().next_point(self.prev_span);
6964 let mut err = self.struct_span_err(sp, &format!("expected `,`, or `}}`, found {}",
6965 self.this_token_descr()));
6966 if self.token.is_ident() {
6967 // This is likely another field; emit the diagnostic and keep going
6968 err.span_suggestion(
6969 sp,
6970 "try adding a comma",
6971 ",".into(),
6972 Applicability::MachineApplicable,
6973 );
6974 err.emit();
6975 } else {
6976 return Err(err)
6977 }
6978 }
6979 }
6980 Ok(a_var)
6981 }
6982
6983 /// Parses an element of a struct declaration.
6984 fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
6985 let attrs = self.parse_outer_attributes()?;
6986 let lo = self.span;
6987 let vis = self.parse_visibility(false)?;
6988 self.parse_single_struct_field(lo, vis, attrs)
6989 }
6990
6991 /// Parses `pub`, `pub(crate)` and `pub(in path)` plus shortcuts `crate` for `pub(crate)`,
6992 /// `pub(self)` for `pub(in self)` and `pub(super)` for `pub(in super)`.
6993 /// If the following element can't be a tuple (i.e., it's a function definition), then
6994 /// it's not a tuple struct field), and the contents within the parentheses isn't valid,
6995 /// so emit a proper diagnostic.
6996 pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibility> {
6997 maybe_whole!(self, NtVis, |x| x);
6998
6999 self.expected_tokens.push(TokenType::Keyword(keywords::Crate));
7000 if self.is_crate_vis() {
7001 self.bump(); // `crate`
7002 return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate)));
7003 }
7004
7005 if !self.eat_keyword(keywords::Pub) {
7006 // We need a span for our `Spanned<VisibilityKind>`, but there's inherently no
7007 // keyword to grab a span from for inherited visibility; an empty span at the
7008 // beginning of the current token would seem to be the "Schelling span".
7009 return Ok(respan(self.span.shrink_to_lo(), VisibilityKind::Inherited))
7010 }
7011 let lo = self.prev_span;
7012
7013 if self.check(&token::OpenDelim(token::Paren)) {
7014 // We don't `self.bump()` the `(` yet because this might be a struct definition where
7015 // `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
7016 // Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
7017 // by the following tokens.
7018 if self.look_ahead(1, |t| t.is_keyword(keywords::Crate)) {
7019 // `pub(crate)`
7020 self.bump(); // `(`
7021 self.bump(); // `crate`
7022 self.expect(&token::CloseDelim(token::Paren))?; // `)`
7023 let vis = respan(
7024 lo.to(self.prev_span),
7025 VisibilityKind::Crate(CrateSugar::PubCrate),
7026 );
7027 return Ok(vis)
7028 } else if self.look_ahead(1, |t| t.is_keyword(keywords::In)) {
7029 // `pub(in path)`
7030 self.bump(); // `(`
7031 self.bump(); // `in`
7032 let path = self.parse_path(PathStyle::Mod)?; // `path`
7033 self.expect(&token::CloseDelim(token::Paren))?; // `)`
7034 let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
7035 path: P(path),
7036 id: ast::DUMMY_NODE_ID,
7037 });
7038 return Ok(vis)
7039 } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) &&
7040 self.look_ahead(1, |t| t.is_keyword(keywords::Super) ||
7041 t.is_keyword(keywords::SelfLower))
7042 {
7043 // `pub(self)` or `pub(super)`
7044 self.bump(); // `(`
7045 let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
7046 self.expect(&token::CloseDelim(token::Paren))?; // `)`
7047 let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
7048 path: P(path),
7049 id: ast::DUMMY_NODE_ID,
7050 });
7051 return Ok(vis)
7052 } else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct
7053 // `pub(something) fn ...` or `struct X { pub(something) y: Z }`
7054 self.bump(); // `(`
7055 let msg = "incorrect visibility restriction";
7056 let suggestion = r##"some possible visibility restrictions are:
7057`pub(crate)`: visible only on the current crate
7058`pub(super)`: visible only in the current module's parent
7059`pub(in path::to::module)`: visible only on the specified path"##;
7060 let path = self.parse_path(PathStyle::Mod)?;
7061 let sp = self.prev_span;
7062 let help_msg = format!("make this visible only to module `{}` with `in`", path);
7063 self.expect(&token::CloseDelim(token::Paren))?; // `)`
7064 let mut err = struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg);
7065 err.help(suggestion);
7066 err.span_suggestion(
7067 sp, &help_msg, format!("in {}", path), Applicability::MachineApplicable
7068 );
7069 err.emit(); // emit diagnostic, but continue with public visibility
7070 }
7071 }
7072
7073 Ok(respan(lo, VisibilityKind::Public))
7074 }
7075
7076 /// Parses defaultness (i.e., `default` or nothing).
7077 fn parse_defaultness(&mut self) -> Defaultness {
7078 // `pub` is included for better error messages
7079 if self.check_keyword(keywords::Default) &&
7080 self.look_ahead(1, |t| t.is_keyword(keywords::Impl) ||
7081 t.is_keyword(keywords::Const) ||
7082 t.is_keyword(keywords::Fn) ||
7083 t.is_keyword(keywords::Unsafe) ||
7084 t.is_keyword(keywords::Extern) ||
7085 t.is_keyword(keywords::Type) ||
7086 t.is_keyword(keywords::Pub)) {
7087 self.bump(); // `default`
7088 Defaultness::Default
7089 } else {
7090 Defaultness::Final
7091 }
7092 }
7093
7094 fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
7095 if self.eat(&token::Semi) {
7096 let mut err = self.struct_span_err(self.prev_span, "expected item, found `;`");
7097 err.span_suggestion_short(
7098 self.prev_span,
7099 "remove this semicolon",
7100 String::new(),
7101 Applicability::MachineApplicable,
7102 );
7103 if !items.is_empty() {
7104 let previous_item = &items[items.len()-1];
7105 let previous_item_kind_name = match previous_item.node {
7106 // say "braced struct" because tuple-structs and
7107 // braceless-empty-struct declarations do take a semicolon
7108 ItemKind::Struct(..) => Some("braced struct"),
7109 ItemKind::Enum(..) => Some("enum"),
7110 ItemKind::Trait(..) => Some("trait"),
7111 ItemKind::Union(..) => Some("union"),
7112 _ => None,
7113 };
7114 if let Some(name) = previous_item_kind_name {
7115 err.help(&format!("{} declarations are not followed by a semicolon", name));
7116 }
7117 }
7118 err.emit();
7119 true
7120 } else {
7121 false
7122 }
7123 }
7124
7125 /// Given a termination token, parses all of the items in a module.
7126 fn parse_mod_items(&mut self, term: &token::Token, inner_lo: Span) -> PResult<'a, Mod> {
7127 let mut items = vec![];
7128 while let Some(item) = self.parse_item()? {
7129 items.push(item);
7130 self.maybe_consume_incorrect_semicolon(&items);
7131 }
7132
7133 if !self.eat(term) {
7134 let token_str = self.this_token_descr();
7135 if !self.maybe_consume_incorrect_semicolon(&items) {
7136 let mut err = self.fatal(&format!("expected item, found {}", token_str));
7137 err.span_label(self.span, "expected item");
7138 return Err(err);
7139 }
7140 }
7141
7142 let hi = if self.span.is_dummy() {
7143 inner_lo
7144 } else {
7145 self.prev_span
7146 };
7147
7148 Ok(ast::Mod {
7149 inner: inner_lo.to(hi),
7150 items,
7151 inline: true
7152 })
7153 }
7154
7155 fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
7156 let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
7157 self.expect(&token::Colon)?;
7158 let ty = self.parse_ty()?;
7159 self.expect(&token::Eq)?;
7160 let e = self.parse_expr()?;
7161 self.expect(&token::Semi)?;
7162 let item = match m {
7163 Some(m) => ItemKind::Static(ty, m, e),
7164 None => ItemKind::Const(ty, e),
7165 };
7166 Ok((id, item, None))
7167 }
7168
7169 /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
7170 fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
7171 let (in_cfg, outer_attrs) = {
7172 let mut strip_unconfigured = crate::config::StripUnconfigured {
7173 sess: self.sess,
7174 features: None, // don't perform gated feature checking
7175 };
7176 let mut outer_attrs = outer_attrs.to_owned();
7177 strip_unconfigured.process_cfg_attrs(&mut outer_attrs);
7178 (!self.cfg_mods || strip_unconfigured.in_cfg(&outer_attrs), outer_attrs)
7179 };
7180
7181 let id_span = self.span;
7182 let id = self.parse_ident()?;
7183 if self.eat(&token::Semi) {
7184 if in_cfg && self.recurse_into_file_modules {
7185 // This mod is in an external file. Let's go get it!
7186 let ModulePathSuccess { path, directory_ownership, warn } =
7187 self.submod_path(id, &outer_attrs, id_span)?;
7188 let (module, mut attrs) =
7189 self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
7190 // Record that we fetched the mod from an external file
7191 if warn {
7192 let attr = Attribute {
7193 id: attr::mk_attr_id(),
7194 style: ast::AttrStyle::Outer,
7195 path: ast::Path::from_ident(Ident::from_str("warn_directory_ownership")),
7196 tokens: TokenStream::empty(),
7197 is_sugared_doc: false,
7198 span: syntax_pos::DUMMY_SP,
7199 };
7200 attr::mark_known(&attr);
7201 attrs.push(attr);
7202 }
7203 Ok((id, ItemKind::Mod(module), Some(attrs)))
7204 } else {
7205 let placeholder = ast::Mod {
7206 inner: syntax_pos::DUMMY_SP,
7207 items: Vec::new(),
7208 inline: false
7209 };
7210 Ok((id, ItemKind::Mod(placeholder), None))
7211 }
7212 } else {
7213 let old_directory = self.directory.clone();
7214 self.push_directory(id, &outer_attrs);
7215
7216 self.expect(&token::OpenDelim(token::Brace))?;
7217 let mod_inner_lo = self.span;
7218 let attrs = self.parse_inner_attributes()?;
7219 let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
7220
7221 self.directory = old_directory;
7222 Ok((id, ItemKind::Mod(module), Some(attrs)))
7223 }
7224 }
7225
7226 fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
7227 if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") {
7228 self.directory.path.to_mut().push(&path.as_str());
7229 self.directory.ownership = DirectoryOwnership::Owned { relative: None };
7230 } else {
7231 // We have to push on the current module name in the case of relative
7232 // paths in order to ensure that any additional module paths from inline
7233 // `mod x { ... }` come after the relative extension.
7234 //
7235 // For example, a `mod z { ... }` inside `x/y.rs` should set the current
7236 // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
7237 if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
7238 if let Some(ident) = relative.take() { // remove the relative offset
7239 self.directory.path.to_mut().push(ident.as_str());
7240 }
7241 }
7242 self.directory.path.to_mut().push(&id.as_str());
7243 }
7244 }
7245
7246 pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
7247 if let Some(s) = attr::first_attr_value_str_by_name(attrs, "path") {
7248 let s = s.as_str();
7249
7250 // On windows, the base path might have the form
7251 // `\\?\foo\bar` in which case it does not tolerate
7252 // mixed `/` and `\` separators, so canonicalize
7253 // `/` to `\`.
7254 #[cfg(windows)]
7255 let s = s.replace("/", "\\");
7256 Some(dir_path.join(s))
7257 } else {
7258 None
7259 }
7260 }
7261
7262 /// Returns a path to a module.
7263 pub fn default_submod_path(
7264 id: ast::Ident,
7265 relative: Option<ast::Ident>,
7266 dir_path: &Path,
7267 source_map: &SourceMap) -> ModulePath
7268 {
7269 // If we're in a foo.rs file instead of a mod.rs file,
7270 // we need to look for submodules in
7271 // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than
7272 // `./<id>.rs` and `./<id>/mod.rs`.
7273 let relative_prefix_string;
7274 let relative_prefix = if let Some(ident) = relative {
7275 relative_prefix_string = format!("{}{}", ident.as_str(), path::MAIN_SEPARATOR);
7276 &relative_prefix_string
7277 } else {
7278 ""
7279 };
7280
7281 let mod_name = id.to_string();
7282 let default_path_str = format!("{}{}.rs", relative_prefix, mod_name);
7283 let secondary_path_str = format!("{}{}{}mod.rs",
7284 relative_prefix, mod_name, path::MAIN_SEPARATOR);
7285 let default_path = dir_path.join(&default_path_str);
7286 let secondary_path = dir_path.join(&secondary_path_str);
7287 let default_exists = source_map.file_exists(&default_path);
7288 let secondary_exists = source_map.file_exists(&secondary_path);
7289
7290 let result = match (default_exists, secondary_exists) {
7291 (true, false) => Ok(ModulePathSuccess {
7292 path: default_path,
7293 directory_ownership: DirectoryOwnership::Owned {
7294 relative: Some(id),
7295 },
7296 warn: false,
7297 }),
7298 (false, true) => Ok(ModulePathSuccess {
7299 path: secondary_path,
7300 directory_ownership: DirectoryOwnership::Owned {
7301 relative: None,
7302 },
7303 warn: false,
7304 }),
7305 (false, false) => Err(Error::FileNotFoundForModule {
7306 mod_name: mod_name.clone(),
7307 default_path: default_path_str,
7308 secondary_path: secondary_path_str,
7309 dir_path: dir_path.display().to_string(),
7310 }),
7311 (true, true) => Err(Error::DuplicatePaths {
7312 mod_name: mod_name.clone(),
7313 default_path: default_path_str,
7314 secondary_path: secondary_path_str,
7315 }),
7316 };
7317
7318 ModulePath {
7319 name: mod_name,
7320 path_exists: default_exists || secondary_exists,
7321 result,
7322 }
7323 }
7324
7325 fn submod_path(&mut self,
7326 id: ast::Ident,
7327 outer_attrs: &[Attribute],
7328 id_sp: Span)
7329 -> PResult<'a, ModulePathSuccess> {
7330 if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
7331 return Ok(ModulePathSuccess {
7332 directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
7333 // All `#[path]` files are treated as though they are a `mod.rs` file.
7334 // This means that `mod foo;` declarations inside `#[path]`-included
7335 // files are siblings,
7336 //
7337 // Note that this will produce weirdness when a file named `foo.rs` is
7338 // `#[path]` included and contains a `mod foo;` declaration.
7339 // If you encounter this, it's your own darn fault :P
7340 Some(_) => DirectoryOwnership::Owned { relative: None },
7341 _ => DirectoryOwnership::UnownedViaMod(true),
7342 },
7343 path,
7344 warn: false,
7345 });
7346 }
7347
7348 let relative = match self.directory.ownership {
7349 DirectoryOwnership::Owned { relative } => relative,
7350 DirectoryOwnership::UnownedViaBlock |
7351 DirectoryOwnership::UnownedViaMod(_) => None,
7352 };
7353 let paths = Parser::default_submod_path(
7354 id, relative, &self.directory.path, self.sess.source_map());
7355
7356 match self.directory.ownership {
7357 DirectoryOwnership::Owned { .. } => {
7358 paths.result.map_err(|err| self.span_fatal_err(id_sp, err))
7359 },
7360 DirectoryOwnership::UnownedViaBlock => {
7361 let msg =
7362 "Cannot declare a non-inline module inside a block \
7363 unless it has a path attribute";
7364 let mut err = self.diagnostic().struct_span_err(id_sp, msg);
7365 if paths.path_exists {
7366 let msg = format!("Maybe `use` the module `{}` instead of redeclaring it",
7367 paths.name);
7368 err.span_note(id_sp, &msg);
7369 }
7370 Err(err)
7371 }
7372 DirectoryOwnership::UnownedViaMod(warn) => {
7373 if warn {
7374 if let Ok(result) = paths.result {
7375 return Ok(ModulePathSuccess { warn: true, ..result });
7376 }
7377 }
7378 let mut err = self.diagnostic().struct_span_err(id_sp,
7379 "cannot declare a new module at this location");
7380 if !id_sp.is_dummy() {
7381 let src_path = self.sess.source_map().span_to_filename(id_sp);
7382 if let FileName::Real(src_path) = src_path {
7383 if let Some(stem) = src_path.file_stem() {
7384 let mut dest_path = src_path.clone();
7385 dest_path.set_file_name(stem);
7386 dest_path.push("mod.rs");
7387 err.span_note(id_sp,
7388 &format!("maybe move this module `{}` to its own \
7389 directory via `{}`", src_path.display(),
7390 dest_path.display()));
7391 }
7392 }
7393 }
7394 if paths.path_exists {
7395 err.span_note(id_sp,
7396 &format!("... or maybe `use` the module `{}` instead \
7397 of possibly redeclaring it",
7398 paths.name));
7399 }
7400 Err(err)
7401 }
7402 }
7403 }
7404
7405 /// Reads a module from a source file.
7406 fn eval_src_mod(&mut self,
7407 path: PathBuf,
7408 directory_ownership: DirectoryOwnership,
7409 name: String,
7410 id_sp: Span)
7411 -> PResult<'a, (ast::Mod, Vec<Attribute> )> {
7412 let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
7413 if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
7414 let mut err = String::from("circular modules: ");
7415 let len = included_mod_stack.len();
7416 for p in &included_mod_stack[i.. len] {
7417 err.push_str(&p.to_string_lossy());
7418 err.push_str(" -> ");
7419 }
7420 err.push_str(&path.to_string_lossy());
7421 return Err(self.span_fatal(id_sp, &err[..]));
7422 }
7423 included_mod_stack.push(path.clone());
7424 drop(included_mod_stack);
7425
7426 let mut p0 =
7427 new_sub_parser_from_file(self.sess, &path, directory_ownership, Some(name), id_sp);
7428 p0.cfg_mods = self.cfg_mods;
7429 let mod_inner_lo = p0.span;
7430 let mod_attrs = p0.parse_inner_attributes()?;
7431 let mut m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?;
7432 m0.inline = false;
7433 self.sess.included_mod_stack.borrow_mut().pop();
7434 Ok((m0, mod_attrs))
7435 }
7436
7437 /// Parses a function declaration from a foreign module.
7438 fn parse_item_foreign_fn(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
7439 -> PResult<'a, ForeignItem> {
7440 self.expect_keyword(keywords::Fn)?;
7441
7442 let (ident, mut generics) = self.parse_fn_header()?;
7443 let decl = self.parse_fn_decl(true)?;
7444 generics.where_clause = self.parse_where_clause()?;
7445 let hi = self.span;
7446 self.expect(&token::Semi)?;
7447 Ok(ast::ForeignItem {
7448 ident,
7449 attrs,
7450 node: ForeignItemKind::Fn(decl, generics),
7451 id: ast::DUMMY_NODE_ID,
7452 span: lo.to(hi),
7453 vis,
7454 })
7455 }
7456
7457 /// Parses a static item from a foreign module.
7458 /// Assumes that the `static` keyword is already parsed.
7459 fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
7460 -> PResult<'a, ForeignItem> {
7461 let mutbl = self.eat_keyword(keywords::Mut);
7462 let ident = self.parse_ident()?;
7463 self.expect(&token::Colon)?;
7464 let ty = self.parse_ty()?;
7465 let hi = self.span;
7466 self.expect(&token::Semi)?;
7467 Ok(ForeignItem {
7468 ident,
7469 attrs,
7470 node: ForeignItemKind::Static(ty, mutbl),
7471 id: ast::DUMMY_NODE_ID,
7472 span: lo.to(hi),
7473 vis,
7474 })
7475 }
7476
7477 /// Parses a type from a foreign module.
7478 fn parse_item_foreign_type(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
7479 -> PResult<'a, ForeignItem> {
7480 self.expect_keyword(keywords::Type)?;
7481
7482 let ident = self.parse_ident()?;
7483 let hi = self.span;
7484 self.expect(&token::Semi)?;
7485 Ok(ast::ForeignItem {
7486 ident: ident,
7487 attrs: attrs,
7488 node: ForeignItemKind::Ty,
7489 id: ast::DUMMY_NODE_ID,
7490 span: lo.to(hi),
7491 vis: vis
7492 })
7493 }
7494
7495 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
7496 let error_msg = "crate name using dashes are not valid in `extern crate` statements";
7497 let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
7498 in the code";
7499 let mut ident = if self.token.is_keyword(keywords::SelfLower) {
7500 self.parse_path_segment_ident()
7501 } else {
7502 self.parse_ident()
7503 }?;
7504 let mut idents = vec![];
7505 let mut replacement = vec![];
7506 let mut fixed_crate_name = false;
7507 // Accept `extern crate name-like-this` for better diagnostics
7508 let dash = token::Token::BinOp(token::BinOpToken::Minus);
7509 if self.token == dash { // Do not include `-` as part of the expected tokens list
7510 while self.eat(&dash) {
7511 fixed_crate_name = true;
7512 replacement.push((self.prev_span, "_".to_string()));
7513 idents.push(self.parse_ident()?);
7514 }
7515 }
7516 if fixed_crate_name {
7517 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
7518 let mut fixed_name = format!("{}", ident.name);
7519 for part in idents {
7520 fixed_name.push_str(&format!("_{}", part.name));
7521 }
7522 ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp);
7523
7524 let mut err = self.struct_span_err(fixed_name_sp, error_msg);
7525 err.span_label(fixed_name_sp, "dash-separated idents are not valid");
7526 err.multipart_suggestion(
7527 suggestion_msg,
7528 replacement,
7529 Applicability::MachineApplicable,
7530 );
7531 err.emit();
7532 }
7533 Ok(ident)
7534 }
7535
7536 /// Parses `extern crate` links.
7537 ///
7538 /// # Examples
7539 ///
7540 /// ```
7541 /// extern crate foo;
7542 /// extern crate bar as foo;
7543 /// ```
7544 fn parse_item_extern_crate(&mut self,
7545 lo: Span,
7546 visibility: Visibility,
7547 attrs: Vec<Attribute>)
7548 -> PResult<'a, P<Item>> {
7549 // Accept `extern crate name-like-this` for better diagnostics
7550 let orig_name = self.parse_crate_name_with_dashes()?;
7551 let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
7552 (rename, Some(orig_name.name))
7553 } else {
7554 (orig_name, None)
7555 };
7556 self.expect(&token::Semi)?;
7557
7558 let span = lo.to(self.prev_span);
7559 Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs))
7560 }
7561
7562 /// Parses `extern` for foreign ABIs modules.
7563 ///
7564 /// `extern` is expected to have been
7565 /// consumed before calling this method.
7566 ///
7567 /// # Examples
7568 ///
7569 /// ```ignore (only-for-syntax-highlight)
7570 /// extern "C" {}
7571 /// extern {}
7572 /// ```
7573 fn parse_item_foreign_mod(&mut self,
7574 lo: Span,
7575 opt_abi: Option<Abi>,
7576 visibility: Visibility,
7577 mut attrs: Vec<Attribute>)
7578 -> PResult<'a, P<Item>> {
7579 self.expect(&token::OpenDelim(token::Brace))?;
7580
7581 let abi = opt_abi.unwrap_or(Abi::C);
7582
7583 attrs.extend(self.parse_inner_attributes()?);
7584
7585 let mut foreign_items = vec![];
7586 while !self.eat(&token::CloseDelim(token::Brace)) {
7587 foreign_items.push(self.parse_foreign_item()?);
7588 }
7589
7590 let prev_span = self.prev_span;
7591 let m = ast::ForeignMod {
7592 abi,
7593 items: foreign_items
7594 };
7595 let invalid = keywords::Invalid.ident();
7596 Ok(self.mk_item(lo.to(prev_span), invalid, ItemKind::ForeignMod(m), visibility, attrs))
7597 }
7598
7599 /// Parses `type Foo = Bar;`
7600 /// or
7601 /// `existential type Foo: Bar;`
7602 /// or
7603 /// `return `None``
7604 /// without modifying the parser state.
7605 fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, ast::Generics)>> {
7606 // This parses the grammar:
7607 // Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
7608 if self.check_keyword(keywords::Type) ||
7609 self.check_keyword(keywords::Existential) &&
7610 self.look_ahead(1, |t| t.is_keyword(keywords::Type)) {
7611 let existential = self.eat_keyword(keywords::Existential);
7612 assert!(self.eat_keyword(keywords::Type));
7613 Some(self.parse_existential_or_alias(existential))
7614 } else {
7615 None
7616 }
7617 }
7618
7619 /// Parses a type alias or existential type.
7620 fn parse_existential_or_alias(
7621 &mut self,
7622 existential: bool,
7623 ) -> PResult<'a, (Ident, AliasKind, ast::Generics)> {
7624 let ident = self.parse_ident()?;
7625 let mut tps = self.parse_generics()?;
7626 tps.where_clause = self.parse_where_clause()?;
7627 let alias = if existential {
7628 self.expect(&token::Colon)?;
7629 let bounds = self.parse_generic_bounds(None)?;
7630 AliasKind::Existential(bounds)
7631 } else {
7632 self.expect(&token::Eq)?;
7633 let ty = self.parse_ty()?;
7634 AliasKind::Weak(ty)
7635 };
7636 self.expect(&token::Semi)?;
7637 Ok((ident, alias, tps))
7638 }
7639
7640 /// Parses the part of an enum declaration following the `{`.
7641 fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> {
7642 let mut variants = Vec::new();
7643 let mut all_nullary = true;
7644 let mut any_disr = vec![];
7645 while self.token != token::CloseDelim(token::Brace) {
7646 let variant_attrs = self.parse_outer_attributes()?;
7647 let vlo = self.span;
7648
7649 let struct_def;
7650 let mut disr_expr = None;
7651 let ident = self.parse_ident()?;
7652 if self.check(&token::OpenDelim(token::Brace)) {
7653 // Parse a struct variant.
7654 all_nullary = false;
7655 struct_def = VariantData::Struct(self.parse_record_struct_body()?,
7656 ast::DUMMY_NODE_ID);
7657 } else if self.check(&token::OpenDelim(token::Paren)) {
7658 all_nullary = false;
7659 struct_def = VariantData::Tuple(self.parse_tuple_struct_body()?,
7660 ast::DUMMY_NODE_ID);
7661 } else if self.eat(&token::Eq) {
7662 disr_expr = Some(AnonConst {
7663 id: ast::DUMMY_NODE_ID,
7664 value: self.parse_expr()?,
7665 });
7666 if let Some(sp) = disr_expr.as_ref().map(|c| c.value.span) {
7667 any_disr.push(sp);
7668 }
7669 struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
7670 } else {
7671 struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
7672 }
7673
7674 let vr = ast::Variant_ {
7675 ident,
7676 attrs: variant_attrs,
7677 data: struct_def,
7678 disr_expr,
7679 };
7680 variants.push(respan(vlo.to(self.prev_span), vr));
7681
7682 if !self.eat(&token::Comma) { break; }
7683 }
7684 self.expect(&token::CloseDelim(token::Brace))?;
7685 if !any_disr.is_empty() && !all_nullary {
7686 let mut err =self.struct_span_err(
7687 any_disr.clone(),
7688 "discriminator values can only be used with a field-less enum",
7689 );
7690 for sp in any_disr {
7691 err.span_label(sp, "only valid in field-less enums");
7692 }
7693 err.emit();
7694 }
7695
7696 Ok(ast::EnumDef { variants })
7697 }
7698
7699 /// Parses an enum declaration.
7700 fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
7701 let id = self.parse_ident()?;
7702 let mut generics = self.parse_generics()?;
7703 generics.where_clause = self.parse_where_clause()?;
7704 self.expect(&token::OpenDelim(token::Brace))?;
7705
7706 let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
7707 self.recover_stmt();
7708 self.eat(&token::CloseDelim(token::Brace));
7709 e
7710 })?;
7711 Ok((id, ItemKind::Enum(enum_definition, generics), None))
7712 }
7713
7714 /// Parses a string as an ABI spec on an extern type or module. Consumes
7715 /// the `extern` keyword, if one is found.
7716 fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
7717 match self.token {
7718 token::Literal(token::Str_(s), suf) | token::Literal(token::StrRaw(s, _), suf) => {
7719 let sp = self.span;
7720 self.expect_no_suffix(sp, "ABI spec", suf);
7721 self.bump();
7722 match abi::lookup(&s.as_str()) {
7723 Some(abi) => Ok(Some(abi)),
7724 None => {
7725 let prev_span = self.prev_span;
7726 let mut err = struct_span_err!(
7727 self.sess.span_diagnostic,
7728 prev_span,
7729 E0703,
7730 "invalid ABI: found `{}`",
7731 s);
7732 err.span_label(prev_span, "invalid ABI");
7733 err.help(&format!("valid ABIs: {}", abi::all_names().join(", ")));
7734 err.emit();
7735 Ok(None)
7736 }
7737 }
7738 }
7739
7740 _ => Ok(None),
7741 }
7742 }
7743
7744 fn is_static_global(&mut self) -> bool {
7745 if self.check_keyword(keywords::Static) {
7746 // Check if this could be a closure
7747 !self.look_ahead(1, |token| {
7748 if token.is_keyword(keywords::Move) {
7749 return true;
7750 }
7751 match *token {
7752 token::BinOp(token::Or) | token::OrOr => true,
7753 _ => false,
7754 }
7755 })
7756 } else {
7757 false
7758 }
7759 }
7760
7761 fn parse_item_(
7762 &mut self,
7763 attrs: Vec<Attribute>,
7764 macros_allowed: bool,
7765 attributes_allowed: bool,
7766 ) -> PResult<'a, Option<P<Item>>> {
7767 let (ret, tokens) = self.collect_tokens(|this| {
7768 this.parse_item_implementation(attrs, macros_allowed, attributes_allowed)
7769 })?;
7770
7771 // Once we've parsed an item and recorded the tokens we got while
7772 // parsing we may want to store `tokens` into the item we're about to
7773 // return. Note, though, that we specifically didn't capture tokens
7774 // related to outer attributes. The `tokens` field here may later be
7775 // used with procedural macros to convert this item back into a token
7776 // stream, but during expansion we may be removing attributes as we go
7777 // along.
7778 //
7779 // If we've got inner attributes then the `tokens` we've got above holds
7780 // these inner attributes. If an inner attribute is expanded we won't
7781 // actually remove it from the token stream, so we'll just keep yielding
7782 // it (bad!). To work around this case for now we just avoid recording
7783 // `tokens` if we detect any inner attributes. This should help keep
7784 // expansion correct, but we should fix this bug one day!
7785 Ok(ret.map(|item| {
7786 item.map(|mut i| {
7787 if !i.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
7788 i.tokens = Some(tokens);
7789 }
7790 i
7791 })
7792 }))
7793 }
7794
7795 /// Parses one of the items allowed by the flags.
7796 fn parse_item_implementation(
7797 &mut self,
7798 attrs: Vec<Attribute>,
7799 macros_allowed: bool,
7800 attributes_allowed: bool,
7801 ) -> PResult<'a, Option<P<Item>>> {
7802 maybe_whole!(self, NtItem, |item| {
7803 let mut item = item.into_inner();
7804 let mut attrs = attrs;
7805 mem::swap(&mut item.attrs, &mut attrs);
7806 item.attrs.extend(attrs);
7807 Some(P(item))
7808 });
7809
7810 let lo = self.span;
7811
7812 let visibility = self.parse_visibility(false)?;
7813
7814 if self.eat_keyword(keywords::Use) {
7815 // USE ITEM
7816 let item_ = ItemKind::Use(P(self.parse_use_tree()?));
7817 self.expect(&token::Semi)?;
7818
7819 let span = lo.to(self.prev_span);
7820 let item = self.mk_item(span, keywords::Invalid.ident(), item_, visibility, attrs);
7821 return Ok(Some(item));
7822 }
7823
7824 if self.eat_keyword(keywords::Extern) {
7825 if self.eat_keyword(keywords::Crate) {
7826 return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?));
7827 }
7828
7829 let opt_abi = self.parse_opt_abi()?;
7830
7831 if self.eat_keyword(keywords::Fn) {
7832 // EXTERN FUNCTION ITEM
7833 let fn_span = self.prev_span;
7834 let abi = opt_abi.unwrap_or(Abi::C);
7835 let (ident, item_, extra_attrs) =
7836 self.parse_item_fn(Unsafety::Normal,
7837 IsAsync::NotAsync,
7838 respan(fn_span, Constness::NotConst),
7839 abi)?;
7840 let prev_span = self.prev_span;
7841 let item = self.mk_item(lo.to(prev_span),
7842 ident,
7843 item_,
7844 visibility,
7845 maybe_append(attrs, extra_attrs));
7846 return Ok(Some(item));
7847 } else if self.check(&token::OpenDelim(token::Brace)) {
7848 return Ok(Some(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs)?));
7849 }
7850
7851 self.unexpected()?;
7852 }
7853
7854 if self.is_static_global() {
7855 self.bump();
7856 // STATIC ITEM
7857 let m = if self.eat_keyword(keywords::Mut) {
7858 Mutability::Mutable
7859 } else {
7860 Mutability::Immutable
7861 };
7862 let (ident, item_, extra_attrs) = self.parse_item_const(Some(m))?;
7863 let prev_span = self.prev_span;
7864 let item = self.mk_item(lo.to(prev_span),
7865 ident,
7866 item_,
7867 visibility,
7868 maybe_append(attrs, extra_attrs));
7869 return Ok(Some(item));
7870 }
7871 if self.eat_keyword(keywords::Const) {
7872 let const_span = self.prev_span;
7873 if self.check_keyword(keywords::Fn)
7874 || (self.check_keyword(keywords::Unsafe)
7875 && self.look_ahead(1, |t| t.is_keyword(keywords::Fn))) {
7876 // CONST FUNCTION ITEM
7877 let unsafety = self.parse_unsafety();
7878 self.bump();
7879 let (ident, item_, extra_attrs) =
7880 self.parse_item_fn(unsafety,
7881 IsAsync::NotAsync,
7882 respan(const_span, Constness::Const),
7883 Abi::Rust)?;
7884 let prev_span = self.prev_span;
7885 let item = self.mk_item(lo.to(prev_span),
7886 ident,
7887 item_,
7888 visibility,
7889 maybe_append(attrs, extra_attrs));
7890 return Ok(Some(item));
7891 }
7892
7893 // CONST ITEM
7894 if self.eat_keyword(keywords::Mut) {
7895 let prev_span = self.prev_span;
7896 let mut err = self.diagnostic()
7897 .struct_span_err(prev_span, "const globals cannot be mutable");
7898 err.span_label(prev_span, "cannot be mutable");
7899 err.span_suggestion(
7900 const_span,
7901 "you might want to declare a static instead",
7902 "static".to_owned(),
7903 Applicability::MaybeIncorrect,
7904 );
7905 err.emit();
7906 }
7907 let (ident, item_, extra_attrs) = self.parse_item_const(None)?;
7908 let prev_span = self.prev_span;
7909 let item = self.mk_item(lo.to(prev_span),
7910 ident,
7911 item_,
7912 visibility,
7913 maybe_append(attrs, extra_attrs));
7914 return Ok(Some(item));
7915 }
7916
7917 // `unsafe async fn` or `async fn`
7918 if (
7919 self.check_keyword(keywords::Unsafe) &&
7920 self.look_ahead(1, |t| t.is_keyword(keywords::Async))
7921 ) || (
7922 self.check_keyword(keywords::Async) &&
7923 self.look_ahead(1, |t| t.is_keyword(keywords::Fn))
7924 )
7925 {
7926 // ASYNC FUNCTION ITEM
7927 let unsafety = self.parse_unsafety();
7928 self.expect_keyword(keywords::Async)?;
7929 self.expect_keyword(keywords::Fn)?;
7930 let fn_span = self.prev_span;
7931 let (ident, item_, extra_attrs) =
7932 self.parse_item_fn(unsafety,
7933 IsAsync::Async {
7934 closure_id: ast::DUMMY_NODE_ID,
7935 return_impl_trait_id: ast::DUMMY_NODE_ID,
7936 },
7937 respan(fn_span, Constness::NotConst),
7938 Abi::Rust)?;
7939 let prev_span = self.prev_span;
7940 let item = self.mk_item(lo.to(prev_span),
7941 ident,
7942 item_,
7943 visibility,
7944 maybe_append(attrs, extra_attrs));
7945 return Ok(Some(item));
7946 }
7947 if self.check_keyword(keywords::Unsafe) &&
7948 (self.look_ahead(1, |t| t.is_keyword(keywords::Trait)) ||
7949 self.look_ahead(1, |t| t.is_keyword(keywords::Auto)))
7950 {
7951 // UNSAFE TRAIT ITEM
7952 self.bump(); // `unsafe`
7953 let is_auto = if self.eat_keyword(keywords::Trait) {
7954 IsAuto::No
7955 } else {
7956 self.expect_keyword(keywords::Auto)?;
7957 self.expect_keyword(keywords::Trait)?;
7958 IsAuto::Yes
7959 };
7960 let (ident, item_, extra_attrs) =
7961 self.parse_item_trait(is_auto, Unsafety::Unsafe)?;
7962 let prev_span = self.prev_span;
7963 let item = self.mk_item(lo.to(prev_span),
7964 ident,
7965 item_,
7966 visibility,
7967 maybe_append(attrs, extra_attrs));
7968 return Ok(Some(item));
7969 }
7970 if self.check_keyword(keywords::Impl) ||
7971 self.check_keyword(keywords::Unsafe) &&
7972 self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) ||
7973 self.check_keyword(keywords::Default) &&
7974 self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) ||
7975 self.check_keyword(keywords::Default) &&
7976 self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) {
7977 // IMPL ITEM
7978 let defaultness = self.parse_defaultness();
7979 let unsafety = self.parse_unsafety();
7980 self.expect_keyword(keywords::Impl)?;
7981 let (ident, item, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?;
7982 let span = lo.to(self.prev_span);
7983 return Ok(Some(self.mk_item(span, ident, item, visibility,
7984 maybe_append(attrs, extra_attrs))));
7985 }
7986 if self.check_keyword(keywords::Fn) {
7987 // FUNCTION ITEM
7988 self.bump();
7989 let fn_span = self.prev_span;
7990 let (ident, item_, extra_attrs) =
7991 self.parse_item_fn(Unsafety::Normal,
7992 IsAsync::NotAsync,
7993 respan(fn_span, Constness::NotConst),
7994 Abi::Rust)?;
7995 let prev_span = self.prev_span;
7996 let item = self.mk_item(lo.to(prev_span),
7997 ident,
7998 item_,
7999 visibility,
8000 maybe_append(attrs, extra_attrs));
8001 return Ok(Some(item));
8002 }
8003 if self.check_keyword(keywords::Unsafe)
8004 && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
8005 // UNSAFE FUNCTION ITEM
8006 self.bump(); // `unsafe`
8007 // `{` is also expected after `unsafe`, in case of error, include it in the diagnostic
8008 self.check(&token::OpenDelim(token::Brace));
8009 let abi = if self.eat_keyword(keywords::Extern) {
8010 self.parse_opt_abi()?.unwrap_or(Abi::C)
8011 } else {
8012 Abi::Rust
8013 };
8014 self.expect_keyword(keywords::Fn)?;
8015 let fn_span = self.prev_span;
8016 let (ident, item_, extra_attrs) =
8017 self.parse_item_fn(Unsafety::Unsafe,
8018 IsAsync::NotAsync,
8019 respan(fn_span, Constness::NotConst),
8020 abi)?;
8021 let prev_span = self.prev_span;
8022 let item = self.mk_item(lo.to(prev_span),
8023 ident,
8024 item_,
8025 visibility,
8026 maybe_append(attrs, extra_attrs));
8027 return Ok(Some(item));
8028 }
8029 if self.eat_keyword(keywords::Mod) {
8030 // MODULE ITEM
8031 let (ident, item_, extra_attrs) =
8032 self.parse_item_mod(&attrs[..])?;
8033 let prev_span = self.prev_span;
8034 let item = self.mk_item(lo.to(prev_span),
8035 ident,
8036 item_,
8037 visibility,
8038 maybe_append(attrs, extra_attrs));
8039 return Ok(Some(item));
8040 }
8041 if let Some(type_) = self.eat_type() {
8042 let (ident, alias, generics) = type_?;
8043 // TYPE ITEM
8044 let item_ = match alias {
8045 AliasKind::Weak(ty) => ItemKind::Ty(ty, generics),
8046 AliasKind::Existential(bounds) => ItemKind::Existential(bounds, generics),
8047 };
8048 let prev_span = self.prev_span;
8049 let item = self.mk_item(lo.to(prev_span),
8050 ident,
8051 item_,
8052 visibility,
8053 attrs);
8054 return Ok(Some(item));
8055 }
8056 if self.eat_keyword(keywords::Enum) {
8057 // ENUM ITEM
8058 let (ident, item_, extra_attrs) = self.parse_item_enum()?;
8059 let prev_span = self.prev_span;
8060 let item = self.mk_item(lo.to(prev_span),
8061 ident,
8062 item_,
8063 visibility,
8064 maybe_append(attrs, extra_attrs));
8065 return Ok(Some(item));
8066 }
8067 if self.check_keyword(keywords::Trait)
8068 || (self.check_keyword(keywords::Auto)
8069 && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
8070 {
8071 let is_auto = if self.eat_keyword(keywords::Trait) {
8072 IsAuto::No
8073 } else {
8074 self.expect_keyword(keywords::Auto)?;
8075 self.expect_keyword(keywords::Trait)?;
8076 IsAuto::Yes
8077 };
8078 // TRAIT ITEM
8079 let (ident, item_, extra_attrs) =
8080 self.parse_item_trait(is_auto, Unsafety::Normal)?;
8081 let prev_span = self.prev_span;
8082 let item = self.mk_item(lo.to(prev_span),
8083 ident,
8084 item_,
8085 visibility,
8086 maybe_append(attrs, extra_attrs));
8087 return Ok(Some(item));
8088 }
8089 if self.eat_keyword(keywords::Struct) {
8090 // STRUCT ITEM
8091 let (ident, item_, extra_attrs) = self.parse_item_struct()?;
8092 let prev_span = self.prev_span;
8093 let item = self.mk_item(lo.to(prev_span),
8094 ident,
8095 item_,
8096 visibility,
8097 maybe_append(attrs, extra_attrs));
8098 return Ok(Some(item));
8099 }
8100 if self.is_union_item() {
8101 // UNION ITEM
8102 self.bump();
8103 let (ident, item_, extra_attrs) = self.parse_item_union()?;
8104 let prev_span = self.prev_span;
8105 let item = self.mk_item(lo.to(prev_span),
8106 ident,
8107 item_,
8108 visibility,
8109 maybe_append(attrs, extra_attrs));
8110 return Ok(Some(item));
8111 }
8112 if let Some(macro_def) = self.eat_macro_def(&attrs, &visibility, lo)? {
8113 return Ok(Some(macro_def));
8114 }
8115
8116 // Verify whether we have encountered a struct or method definition where the user forgot to
8117 // add the `struct` or `fn` keyword after writing `pub`: `pub S {}`
8118 if visibility.node.is_pub() &&
8119 self.check_ident() &&
8120 self.look_ahead(1, |t| *t != token::Not)
8121 {
8122 // Space between `pub` keyword and the identifier
8123 //
8124 // pub S {}
8125 // ^^^ `sp` points here
8126 let sp = self.prev_span.between(self.span);
8127 let full_sp = self.prev_span.to(self.span);
8128 let ident_sp = self.span;
8129 if self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) {
8130 // possible public struct definition where `struct` was forgotten
8131 let ident = self.parse_ident().unwrap();
8132 let msg = format!("add `struct` here to parse `{}` as a public struct",
8133 ident);
8134 let mut err = self.diagnostic()
8135 .struct_span_err(sp, "missing `struct` for struct definition");
8136 err.span_suggestion_short(
8137 sp, &msg, " struct ".into(), Applicability::MaybeIncorrect // speculative
8138 );
8139 return Err(err);
8140 } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
8141 let ident = self.parse_ident().unwrap();
8142 self.bump(); // `(`
8143 let kw_name = if let Ok(Some(_)) = self.parse_self_arg() {
8144 "method"
8145 } else {
8146 "function"
8147 };
8148 self.consume_block(token::Paren);
8149 let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
8150 self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
8151 self.bump(); // `{`
8152 ("fn", kw_name, false)
8153 } else if self.check(&token::OpenDelim(token::Brace)) {
8154 self.bump(); // `{`
8155 ("fn", kw_name, false)
8156 } else if self.check(&token::Colon) {
8157 let kw = "struct";
8158 (kw, kw, false)
8159 } else {
8160 ("fn` or `struct", "function or struct", true)
8161 };
8162 self.consume_block(token::Brace);
8163
8164 let msg = format!("missing `{}` for {} definition", kw, kw_name);
8165 let mut err = self.diagnostic().struct_span_err(sp, &msg);
8166 if !ambiguous {
8167 let suggestion = format!("add `{}` here to parse `{}` as a public {}",
8168 kw,
8169 ident,
8170 kw_name);
8171 err.span_suggestion_short(
8172 sp, &suggestion, format!(" {} ", kw), Applicability::MachineApplicable
8173 );
8174 } else {
8175 if let Ok(snippet) = self.sess.source_map().span_to_snippet(ident_sp) {
8176 err.span_suggestion(
8177 full_sp,
8178 "if you meant to call a macro, try",
8179 format!("{}!", snippet),
8180 // this is the `ambiguous` conditional branch
8181 Applicability::MaybeIncorrect
8182 );
8183 } else {
8184 err.help("if you meant to call a macro, remove the `pub` \
8185 and add a trailing `!` after the identifier");
8186 }
8187 }
8188 return Err(err);
8189 } else if self.look_ahead(1, |t| *t == token::Lt) {
8190 let ident = self.parse_ident().unwrap();
8191 self.eat_to_tokens(&[&token::Gt]);
8192 self.bump(); // `>`
8193 let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
8194 if let Ok(Some(_)) = self.parse_self_arg() {
8195 ("fn", "method", false)
8196 } else {
8197 ("fn", "function", false)
8198 }
8199 } else if self.check(&token::OpenDelim(token::Brace)) {
8200 ("struct", "struct", false)
8201 } else {
8202 ("fn` or `struct", "function or struct", true)
8203 };
8204 let msg = format!("missing `{}` for {} definition", kw, kw_name);
8205 let mut err = self.diagnostic().struct_span_err(sp, &msg);
8206 if !ambiguous {
8207 err.span_suggestion_short(
8208 sp,
8209 &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
8210 format!(" {} ", kw),
8211 Applicability::MachineApplicable,
8212 );
8213 }
8214 return Err(err);
8215 }
8216 }
8217 self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
8218 }
8219
8220 /// Parses a foreign item.
8221 crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> {
8222 maybe_whole!(self, NtForeignItem, |ni| ni);
8223
8224 let attrs = self.parse_outer_attributes()?;
8225 let lo = self.span;
8226 let visibility = self.parse_visibility(false)?;
8227
8228 // FOREIGN STATIC ITEM
8229 // Treat `const` as `static` for error recovery, but don't add it to expected tokens.
8230 if self.check_keyword(keywords::Static) || self.token.is_keyword(keywords::Const) {
8231 if self.token.is_keyword(keywords::Const) {
8232 self.diagnostic()
8233 .struct_span_err(self.span, "extern items cannot be `const`")
8234 .span_suggestion(
8235 self.span,
8236 "try using a static value",
8237 "static".to_owned(),
8238 Applicability::MachineApplicable
8239 ).emit();
8240 }
8241 self.bump(); // `static` or `const`
8242 return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?);
8243 }
8244 // FOREIGN FUNCTION ITEM
8245 if self.check_keyword(keywords::Fn) {
8246 return Ok(self.parse_item_foreign_fn(visibility, lo, attrs)?);
8247 }
8248 // FOREIGN TYPE ITEM
8249 if self.check_keyword(keywords::Type) {
8250 return Ok(self.parse_item_foreign_type(visibility, lo, attrs)?);
8251 }
8252
8253 match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? {
8254 Some(mac) => {
8255 Ok(
8256 ForeignItem {
8257 ident: keywords::Invalid.ident(),
8258 span: lo.to(self.prev_span),
8259 id: ast::DUMMY_NODE_ID,
8260 attrs,
8261 vis: visibility,
8262 node: ForeignItemKind::Macro(mac),
8263 }
8264 )
8265 }
8266 None => {
8267 if !attrs.is_empty() {
8268 self.expected_item_err(&attrs)?;
8269 }
8270
8271 self.unexpected()
8272 }
8273 }
8274 }
8275
8276 /// This is the fall-through for parsing items.
8277 fn parse_macro_use_or_failure(
8278 &mut self,
8279 attrs: Vec<Attribute> ,
8280 macros_allowed: bool,
8281 attributes_allowed: bool,
8282 lo: Span,
8283 visibility: Visibility
8284 ) -> PResult<'a, Option<P<Item>>> {
8285 if macros_allowed && self.token.is_path_start() {
8286 // MACRO INVOCATION ITEM
8287
8288 let prev_span = self.prev_span;
8289 self.complain_if_pub_macro(&visibility.node, prev_span);
8290
8291 let mac_lo = self.span;
8292
8293 // item macro.
8294 let pth = self.parse_path(PathStyle::Mod)?;
8295 self.expect(&token::Not)?;
8296
8297 // a 'special' identifier (like what `macro_rules!` uses)
8298 // is optional. We should eventually unify invoc syntax
8299 // and remove this.
8300 let id = if self.token.is_ident() {
8301 self.parse_ident()?
8302 } else {
8303 keywords::Invalid.ident() // no special identifier
8304 };
8305 // eat a matched-delimiter token tree:
8306 let (delim, tts) = self.expect_delimited_token_tree()?;
8307 if delim != MacDelimiter::Brace {
8308 if !self.eat(&token::Semi) {
8309 self.span_err(self.prev_span,
8310 "macros that expand to items must either \
8311 be surrounded with braces or followed by \
8312 a semicolon");
8313 }
8314 }
8315
8316 let hi = self.prev_span;
8317 let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim });
8318 let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs);
8319 return Ok(Some(item));
8320 }
8321
8322 // FAILURE TO PARSE ITEM
8323 match visibility.node {
8324 VisibilityKind::Inherited => {}
8325 _ => {
8326 return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`"));
8327 }
8328 }
8329
8330 if !attributes_allowed && !attrs.is_empty() {
8331 self.expected_item_err(&attrs)?;
8332 }
8333 Ok(None)
8334 }
8335
8336 /// Parses a macro invocation inside a `trait`, `impl` or `extern` block.
8337 fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
8338 at_end: &mut bool) -> PResult<'a, Option<Mac>>
8339 {
8340 if self.token.is_path_start() {
8341 let prev_span = self.prev_span;
8342 let lo = self.span;
8343 let pth = self.parse_path(PathStyle::Mod)?;
8344
8345 if pth.segments.len() == 1 {
8346 if !self.eat(&token::Not) {
8347 return Err(self.missing_assoc_item_kind_err(item_kind, prev_span));
8348 }
8349 } else {
8350 self.expect(&token::Not)?;
8351 }
8352
8353 if let Some(vis) = vis {
8354 self.complain_if_pub_macro(&vis.node, prev_span);
8355 }
8356
8357 *at_end = true;
8358
8359 // eat a matched-delimiter token tree:
8360 let (delim, tts) = self.expect_delimited_token_tree()?;
8361 if delim != MacDelimiter::Brace {
8362 self.expect(&token::Semi)?;
8363 }
8364
8365 Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim })))
8366 } else {
8367 Ok(None)
8368 }
8369 }
8370
8371 fn collect_tokens<F, R>(&mut self, f: F) -> PResult<'a, (R, TokenStream)>
8372 where F: FnOnce(&mut Self) -> PResult<'a, R>
8373 {
8374 // Record all tokens we parse when parsing this item.
8375 let mut tokens = Vec::new();
8376 let prev_collecting = match self.token_cursor.frame.last_token {
8377 LastToken::Collecting(ref mut list) => {
8378 Some(mem::replace(list, Vec::new()))
8379 }
8380 LastToken::Was(ref mut last) => {
8381 tokens.extend(last.take());
8382 None
8383 }
8384 };
8385 self.token_cursor.frame.last_token = LastToken::Collecting(tokens);
8386 let prev = self.token_cursor.stack.len();
8387 let ret = f(self);
8388 let last_token = if self.token_cursor.stack.len() == prev {
8389 &mut self.token_cursor.frame.last_token
8390 } else {
8391 &mut self.token_cursor.stack[prev].last_token
8392 };
8393
8394 // Pull out the tokens that we've collected from the call to `f` above.
8395 let mut collected_tokens = match *last_token {
8396 LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()),
8397 LastToken::Was(_) => panic!("our vector went away?"),
8398 };
8399
8400 // If we're not at EOF our current token wasn't actually consumed by
8401 // `f`, but it'll still be in our list that we pulled out. In that case
8402 // put it back.
8403 let extra_token = if self.token != token::Eof {
8404 collected_tokens.pop()
8405 } else {
8406 None
8407 };
8408
8409 // If we were previously collecting tokens, then this was a recursive
8410 // call. In that case we need to record all the tokens we collected in
8411 // our parent list as well. To do that we push a clone of our stream
8412 // onto the previous list.
8413 match prev_collecting {
8414 Some(mut list) => {
8415 list.extend(collected_tokens.iter().cloned());
8416 list.extend(extra_token);
8417 *last_token = LastToken::Collecting(list);
8418 }
8419 None => {
8420 *last_token = LastToken::Was(extra_token);
8421 }
8422 }
8423
8424 Ok((ret?, TokenStream::new(collected_tokens)))
8425 }
8426
8427 pub fn parse_item(&mut self) -> PResult<'a, Option<P<Item>>> {
8428 let attrs = self.parse_outer_attributes()?;
8429 self.parse_item_(attrs, true, false)
8430 }
8431
8432 /// `::{` or `::*`
8433 fn is_import_coupler(&mut self) -> bool {
8434 self.check(&token::ModSep) &&
8435 self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) ||
8436 *t == token::BinOp(token::Star))
8437 }
8438
8439 /// Parses a `UseTree`.
8440 ///
8441 /// ```
8442 /// USE_TREE = [`::`] `*` |
8443 /// [`::`] `{` USE_TREE_LIST `}` |
8444 /// PATH `::` `*` |
8445 /// PATH `::` `{` USE_TREE_LIST `}` |
8446 /// PATH [`as` IDENT]
8447 /// ```
8448 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
8449 let lo = self.span;
8450
8451 let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
8452 let kind = if self.check(&token::OpenDelim(token::Brace)) ||
8453 self.check(&token::BinOp(token::Star)) ||
8454 self.is_import_coupler() {
8455 // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
8456 let mod_sep_ctxt = self.span.ctxt();
8457 if self.eat(&token::ModSep) {
8458 prefix.segments.push(
8459 PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))
8460 );
8461 }
8462
8463 if self.eat(&token::BinOp(token::Star)) {
8464 UseTreeKind::Glob
8465 } else {
8466 UseTreeKind::Nested(self.parse_use_tree_list()?)
8467 }
8468 } else {
8469 // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
8470 prefix = self.parse_path(PathStyle::Mod)?;
8471
8472 if self.eat(&token::ModSep) {
8473 if self.eat(&token::BinOp(token::Star)) {
8474 UseTreeKind::Glob
8475 } else {
8476 UseTreeKind::Nested(self.parse_use_tree_list()?)
8477 }
8478 } else {
8479 UseTreeKind::Simple(self.parse_rename()?, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID)
8480 }
8481 };
8482
8483 Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) })
8484 }
8485
8486 /// Parses a `UseTreeKind::Nested(list)`.
8487 ///
8488 /// ```
8489 /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
8490 /// ```
8491 fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
8492 self.parse_unspanned_seq(&token::OpenDelim(token::Brace),
8493 &token::CloseDelim(token::Brace),
8494 SeqSep::trailing_allowed(token::Comma), |this| {
8495 Ok((this.parse_use_tree()?, ast::DUMMY_NODE_ID))
8496 })
8497 }
8498
8499 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
8500 if self.eat_keyword(keywords::As) {
8501 self.parse_ident_or_underscore().map(Some)
8502 } else {
8503 Ok(None)
8504 }
8505 }
8506
8507 /// Parses a source module as a crate. This is the main entry point for the parser.
8508 pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
8509 let lo = self.span;
8510 let krate = Ok(ast::Crate {
8511 attrs: self.parse_inner_attributes()?,
8512 module: self.parse_mod_items(&token::Eof, lo)?,
8513 span: lo.to(self.span),
8514 });
8515 emit_unclosed_delims(&self.unclosed_delims, self.diagnostic());
8516 self.unclosed_delims.clear();
8517 krate
8518 }
8519
8520 pub fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
8521 let ret = match self.token {
8522 token::Literal(token::Str_(s), suf) => (s, ast::StrStyle::Cooked, suf),
8523 token::Literal(token::StrRaw(s, n), suf) => (s, ast::StrStyle::Raw(n), suf),
8524 _ => return None
8525 };
8526 self.bump();
8527 Some(ret)
8528 }
8529
8530 pub fn parse_str(&mut self) -> PResult<'a, (Symbol, StrStyle)> {
8531 match self.parse_optional_str() {
8532 Some((s, style, suf)) => {
8533 let sp = self.prev_span;
8534 self.expect_no_suffix(sp, "string literal", suf);
8535 Ok((s, style))
8536 }
8537 _ => {
8538 let msg = "expected string literal";
8539 let mut err = self.fatal(msg);
8540 err.span_label(self.span, msg);
8541 Err(err)
8542 }
8543 }
8544 }
8545}
8546
8547pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors::Handler) {
8548 for unmatched in unclosed_delims {
8549 let mut err = handler.struct_span_err(unmatched.found_span, &format!(
8550 "incorrect close delimiter: `{}`",
8551 pprust::token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),
8552 ));
8553 err.span_label(unmatched.found_span, "incorrect close delimiter");
8554 if let Some(sp) = unmatched.candidate_span {
8555 err.span_label(sp, "close delimiter possibly meant for this");
8556 }
8557 if let Some(sp) = unmatched.unclosed_span {
8558 err.span_label(sp, "un-closed delimiter");
8559 }
8560 err.emit();
8561 }
8562}
diff --git a/bench_data/numerous_macro_rules b/bench_data/numerous_macro_rules
new file mode 100644
index 000000000..bf89ed594
--- /dev/null
+++ b/bench_data/numerous_macro_rules
@@ -0,0 +1,560 @@
1macro_rules! __ra_macro_fixture0 {($T : ident )=>( int_module ! ($T , # [ stable ( feature = "rust1" , since = "1.0.0" )]);); ($T : ident , # [$attr : meta ])=>( doc_comment ! { concat ! ( "The smallest value that can be represented by this integer type.\nUse [`" , stringify ! ($T ), "::MIN" , "`](../../std/primitive." , stringify ! ($T ), ".html#associatedconstant.MIN) instead.\n\n# Examples\n\n```rust\n// deprecated way\nlet min = std::" , stringify ! ($T ), "::MIN;\n\n// intended way\nlet min = " , stringify ! ($T ), "::MIN;\n```\n" ), # [$attr ] pub const MIN : $T = $T :: MIN ; } doc_comment ! { concat ! ( "The largest value that can be represented by this integer type.\nUse [`" , stringify ! ($T ), "::MAX" , "`](../../std/primitive." , stringify ! ($T ), ".html#associatedconstant.MAX) instead.\n\n# Examples\n\n```rust\n// deprecated way\nlet max = std::" , stringify ! ($T ), "::MAX;\n\n// intended way\nlet max = " , stringify ! ($T ), "::MAX;\n```\n" ), # [$attr ] pub const MAX : $T = $T :: MAX ; })}
2macro_rules! __ra_macro_fixture1 {($($ty : ty : add ($addfn : path ), mul / div ($bigty : ident );)*)=>($(impl FullOps for $ty { fn full_add ( self , other : $ty , carry : bool )-> ( bool , $ty ){ let ( v , carry1 )= intrinsics :: add_with_overflow ( self , other ); let ( v , carry2 )= intrinsics :: add_with_overflow ( v , if carry { 1 } else { 0 }); ( carry1 || carry2 , v )} fn full_mul ( self , other : $ty , carry : $ty )-> ($ty , $ty ){ let v = ( self as $bigty )* ( other as $bigty )+ ( carry as $bigty ); (( v >> <$ty >:: BITS ) as $ty , v as $ty )} fn full_mul_add ( self , other : $ty , other2 : $ty , carry : $ty )-> ($ty , $ty ){ let v = ( self as $bigty )* ( other as $bigty )+ ( other2 as $bigty )+ ( carry as $bigty ); (( v >> <$ty >:: BITS ) as $ty , v as $ty )} fn full_div_rem ( self , other : $ty , borrow : $ty )-> ($ty , $ty ){ debug_assert ! ( borrow < other ); let lhs = (( borrow as $bigty )<< <$ty >:: BITS )| ( self as $bigty ); let rhs = other as $bigty ; (( lhs / rhs ) as $ty , ( lhs % rhs ) as $ty )}})* )}
3macro_rules! __ra_macro_fixture2 {($name : ident : type =$ty : ty , n =$n : expr )=>{# [ doc = " Stack-allocated arbitrary-precision (up to certain limit) integer." ]# [ doc = "" ]# [ doc = " This is backed by a fixed-size array of given type (\\\"digit\\\")." ]# [ doc = " While the array is not very large (normally some hundred bytes)," ]# [ doc = " copying it recklessly may result in the performance hit." ]# [ doc = " Thus this is intentionally not `Copy`." ]# [ doc = "" ]# [ doc = " All operations available to bignums panic in the case of overflows." ]# [ doc = " The caller is responsible to use large enough bignum types." ] pub struct $name {# [ doc = " One plus the offset to the maximum \\\"digit\\\" in use." ]# [ doc = " This does not decrease, so be aware of the computation order." ]# [ doc = " `base[size..]` should be zero." ] size : usize , # [ doc = " Digits. `[a, b, c, ...]` represents `a + b*2^W + c*2^(2W) + ...`" ]# [ doc = " where `W` is the number of bits in the digit type." ] base : [$ty ; $n ], } impl $name {# [ doc = " Makes a bignum from one digit." ] pub fn from_small ( v : $ty )-> $name { let mut base = [ 0 ; $n ]; base [ 0 ]= v ; $name { size : 1 , base : base }}# [ doc = " Makes a bignum from `u64` value." ] pub fn from_u64 ( mut v : u64 )-> $name { let mut base = [ 0 ; $n ]; let mut sz = 0 ; while v > 0 { base [ sz ]= v as $ty ; v >>= <$ty >:: BITS ; sz += 1 ; }$name { size : sz , base : base }}# [ doc = " Returns the internal digits as a slice `[a, b, c, ...]` such that the numeric" ]# [ doc = " value is `a + b * 2^W + c * 2^(2W) + ...` where `W` is the number of bits in" ]# [ doc = " the digit type." ] pub fn digits (& self )-> & [$ty ]{& self . base [.. self . size ]}# [ doc = " Returns the `i`-th bit where bit 0 is the least significant one." ]# [ doc = " In other words, the bit with weight `2^i`." ] pub fn get_bit (& self , i : usize )-> u8 { let digitbits = <$ty >:: BITS as usize ; let d = i / digitbits ; let b = i % digitbits ; (( self . base [ d ]>> b )& 1 ) as u8 }# [ doc = " Returns `true` if the bignum is zero." ] pub fn is_zero (& self )-> bool { self . digits (). iter (). all (|& v | v == 0 )}# [ doc = " Returns the number of bits necessary to represent this value. Note that zero" ]# [ doc = " is considered to need 0 bits." ] pub fn bit_length (& self )-> usize { let digits = self . digits (); let zeros = digits . iter (). rev (). take_while (|&& x | x == 0 ). count (); let end = digits . len ()- zeros ; let nonzero = & digits [.. end ]; if nonzero . is_empty (){ return 0 ; } let digitbits = <$ty >:: BITS as usize ; let mut i = nonzero . len ()* digitbits - 1 ; while self . get_bit ( i )== 0 { i -= 1 ; } i + 1 }# [ doc = " Adds `other` to itself and returns its own mutable reference." ] pub fn add < 'a > (& 'a mut self , other : &$name )-> & 'a mut $name { use crate :: cmp ; use crate :: num :: bignum :: FullOps ; let mut sz = cmp :: max ( self . size , other . size ); let mut carry = false ; for ( a , b ) in self . base [.. sz ]. iter_mut (). zip (& other . base [.. sz ]){ let ( c , v )= (* a ). full_add (* b , carry ); * a = v ; carry = c ; } if carry { self . base [ sz ]= 1 ; sz += 1 ; } self . size = sz ; self } pub fn add_small (& mut self , other : $ty )-> & mut $name { use crate :: num :: bignum :: FullOps ; let ( mut carry , v )= self . base [ 0 ]. full_add ( other , false ); self . base [ 0 ]= v ; let mut i = 1 ; while carry { let ( c , v )= self . base [ i ]. full_add ( 0 , carry ); self . base [ i ]= v ; carry = c ; i += 1 ; } if i > self . size { self . size = i ; } self }# [ doc = " Subtracts `other` from itself and returns its own mutable reference." ] pub fn sub < 'a > (& 'a mut self , other : &$name )-> & 'a mut $name { use crate :: cmp ; use crate :: num :: bignum :: FullOps ; let sz = cmp :: max ( self . size , other . size ); let mut noborrow = true ; for ( a , b ) in self . base [.. sz ]. iter_mut (). zip (& other . base [.. sz ]){ let ( c , v )= (* a ). full_add (!* b , noborrow ); * a = v ; noborrow = c ; } assert ! ( noborrow ); self . size = sz ; self }# [ doc = " Multiplies itself by a digit-sized `other` and returns its own" ]# [ doc = " mutable reference." ] pub fn mul_small (& mut self , other : $ty )-> & mut $name { use crate :: num :: bignum :: FullOps ; let mut sz = self . size ; let mut carry = 0 ; for a in & mut self . base [.. sz ]{ let ( c , v )= (* a ). full_mul ( other , carry ); * a = v ; carry = c ; } if carry > 0 { self . base [ sz ]= carry ; sz += 1 ; } self . size = sz ; self }# [ doc = " Multiplies itself by `2^bits` and returns its own mutable reference." ] pub fn mul_pow2 (& mut self , bits : usize )-> & mut $name { let digitbits = <$ty >:: BITS as usize ; let digits = bits / digitbits ; let bits = bits % digitbits ; assert ! ( digits < $n ); debug_assert ! ( self . base [$n - digits ..]. iter (). all (|& v | v == 0 )); debug_assert ! ( bits == 0 || ( self . base [$n - digits - 1 ]>> ( digitbits - bits ))== 0 ); for i in ( 0 .. self . size ). rev (){ self . base [ i + digits ]= self . base [ i ]; } for i in 0 .. digits { self . base [ i ]= 0 ; } let mut sz = self . size + digits ; if bits > 0 { let last = sz ; let overflow = self . base [ last - 1 ]>> ( digitbits - bits ); if overflow > 0 { self . base [ last ]= overflow ; sz += 1 ; } for i in ( digits + 1 .. last ). rev (){ self . base [ i ]= ( self . base [ i ]<< bits )| ( self . base [ i - 1 ]>> ( digitbits - bits )); } self . base [ digits ]<<= bits ; } self . size = sz ; self }# [ doc = " Multiplies itself by `5^e` and returns its own mutable reference." ] pub fn mul_pow5 (& mut self , mut e : usize )-> & mut $name { use crate :: mem ; use crate :: num :: bignum :: SMALL_POW5 ; let table_index = mem :: size_of ::<$ty > (). trailing_zeros () as usize ; let ( small_power , small_e )= SMALL_POW5 [ table_index ]; let small_power = small_power as $ty ; while e >= small_e { self . mul_small ( small_power ); e -= small_e ; } let mut rest_power = 1 ; for _ in 0 .. e { rest_power *= 5 ; } self . mul_small ( rest_power ); self }# [ doc = " Multiplies itself by a number described by `other[0] + other[1] * 2^W +" ]# [ doc = " other[2] * 2^(2W) + ...` (where `W` is the number of bits in the digit type)" ]# [ doc = " and returns its own mutable reference." ] pub fn mul_digits < 'a > (& 'a mut self , other : & [$ty ])-> & 'a mut $name { fn mul_inner ( ret : & mut [$ty ; $n ], aa : & [$ty ], bb : & [$ty ])-> usize { use crate :: num :: bignum :: FullOps ; let mut retsz = 0 ; for ( i , & a ) in aa . iter (). enumerate (){ if a == 0 { continue ; } let mut sz = bb . len (); let mut carry = 0 ; for ( j , & b ) in bb . iter (). enumerate (){ let ( c , v )= a . full_mul_add ( b , ret [ i + j ], carry ); ret [ i + j ]= v ; carry = c ; } if carry > 0 { ret [ i + sz ]= carry ; sz += 1 ; } if retsz < i + sz { retsz = i + sz ; }} retsz } let mut ret = [ 0 ; $n ]; let retsz = if self . size < other . len (){ mul_inner (& mut ret , & self . digits (), other )} else { mul_inner (& mut ret , other , & self . digits ())}; self . base = ret ; self . size = retsz ; self }# [ doc = " Divides itself by a digit-sized `other` and returns its own" ]# [ doc = " mutable reference *and* the remainder." ] pub fn div_rem_small (& mut self , other : $ty )-> (& mut $name , $ty ){ use crate :: num :: bignum :: FullOps ; assert ! ( other > 0 ); let sz = self . size ; let mut borrow = 0 ; for a in self . base [.. sz ]. iter_mut (). rev (){ let ( q , r )= (* a ). full_div_rem ( other , borrow ); * a = q ; borrow = r ; }( self , borrow )}# [ doc = " Divide self by another bignum, overwriting `q` with the quotient and `r` with the" ]# [ doc = " remainder." ] pub fn div_rem (& self , d : &$name , q : & mut $name , r : & mut $name ){ assert ! (! d . is_zero ()); let digitbits = <$ty >:: BITS as usize ; for digit in & mut q . base [..]{* digit = 0 ; } for digit in & mut r . base [..]{* digit = 0 ; } r . size = d . size ; q . size = 1 ; let mut q_is_zero = true ; let end = self . bit_length (); for i in ( 0 .. end ). rev (){ r . mul_pow2 ( 1 ); r . base [ 0 ]|= self . get_bit ( i ) as $ty ; if &* r >= d { r . sub ( d ); let digit_idx = i / digitbits ; let bit_idx = i % digitbits ; if q_is_zero { q . size = digit_idx + 1 ; q_is_zero = false ; } q . base [ digit_idx ]|= 1 << bit_idx ; }} debug_assert ! ( q . base [ q . size ..]. iter (). all (|& d | d == 0 )); debug_assert ! ( r . base [ r . size ..]. iter (). all (|& d | d == 0 )); }} impl crate :: cmp :: PartialEq for $name { fn eq (& self , other : &$name )-> bool { self . base [..]== other . base [..]}} impl crate :: cmp :: Eq for $name {} impl crate :: cmp :: PartialOrd for $name { fn partial_cmp (& self , other : &$name )-> crate :: option :: Option < crate :: cmp :: Ordering > { crate :: option :: Option :: Some ( self . cmp ( other ))}} impl crate :: cmp :: Ord for $name { fn cmp (& self , other : &$name )-> crate :: cmp :: Ordering { use crate :: cmp :: max ; let sz = max ( self . size , other . size ); let lhs = self . base [.. sz ]. iter (). cloned (). rev (); let rhs = other . base [.. sz ]. iter (). cloned (). rev (); lhs . cmp ( rhs )}} impl crate :: clone :: Clone for $name { fn clone (& self )-> Self { Self { size : self . size , base : self . base }}} impl crate :: fmt :: Debug for $name { fn fmt (& self , f : & mut crate :: fmt :: Formatter < '_ >)-> crate :: fmt :: Result { let sz = if self . size < 1 { 1 } else { self . size }; let digitlen = <$ty >:: BITS as usize / 4 ; write ! ( f , "{:#x}" , self . base [ sz - 1 ])?; for & v in self . base [.. sz - 1 ]. iter (). rev (){ write ! ( f , "_{:01$x}" , v , digitlen )?; } crate :: result :: Result :: Ok (())}}}; }
4macro_rules! __ra_macro_fixture3 {($t : ty )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl FromStr for $t { type Err = ParseFloatError ; # [ doc = " Converts a string in base 10 to a float." ]# [ doc = " Accepts an optional decimal exponent." ]# [ doc = "" ]# [ doc = " This function accepts strings such as" ]# [ doc = "" ]# [ doc = " * \\\'3.14\\\'" ]# [ doc = " * \\\'-3.14\\\'" ]# [ doc = " * \\\'2.5E10\\\', or equivalently, \\\'2.5e10\\\'" ]# [ doc = " * \\\'2.5E-10\\\'" ]# [ doc = " * \\\'5.\\\'" ]# [ doc = " * \\\'.5\\\', or, equivalently, \\\'0.5\\\'" ]# [ doc = " * \\\'inf\\\', \\\'-inf\\\', \\\'NaN\\\'" ]# [ doc = "" ]# [ doc = " Leading and trailing whitespace represent an error." ]# [ doc = "" ]# [ doc = " # Grammar" ]# [ doc = "" ]# [ doc = " All strings that adhere to the following [EBNF] grammar" ]# [ doc = " will result in an [`Ok`] being returned:" ]# [ doc = "" ]# [ doc = " ```txt" ]# [ doc = " Float ::= Sign? ( \\\'inf\\\' | \\\'NaN\\\' | Number )" ]# [ doc = " Number ::= ( Digit+ |" ]# [ doc = " Digit+ \\\'.\\\' Digit* |" ]# [ doc = " Digit* \\\'.\\\' Digit+ ) Exp?" ]# [ doc = " Exp ::= [eE] Sign? Digit+" ]# [ doc = " Sign ::= [+-]" ]# [ doc = " Digit ::= [0-9]" ]# [ doc = " ```" ]# [ doc = "" ]# [ doc = " [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation" ]# [ doc = "" ]# [ doc = " # Known bugs" ]# [ doc = "" ]# [ doc = " In some situations, some strings that should create a valid float" ]# [ doc = " instead return an error. See [issue #31407] for details." ]# [ doc = "" ]# [ doc = " [issue #31407]: https://github.com/rust-lang/rust/issues/31407" ]# [ doc = "" ]# [ doc = " # Arguments" ]# [ doc = "" ]# [ doc = " * src - A string" ]# [ doc = "" ]# [ doc = " # Return value" ]# [ doc = "" ]# [ doc = " `Err(ParseFloatError)` if the string did not represent a valid" ]# [ doc = " number. Otherwise, `Ok(n)` where `n` is the floating-point" ]# [ doc = " number represented by `src`." ]# [ inline ] fn from_str ( src : & str )-> Result < Self , ParseFloatError > { dec2flt ( src )}}}; }
5macro_rules! __ra_macro_fixture4 {($(# [$stability : meta ]$Ty : ident ($Int : ty ); )+ )=>{$(doc_comment ! { concat ! ( "An integer that is known not to equal zero.\n\nThis enables some memory layout optimization.\nFor example, `Option<" , stringify ! ($Ty ), ">` is the same size as `" , stringify ! ($Int ), "`:\n\n```rust\nuse std::mem::size_of;\nassert_eq!(size_of::<Option<core::num::" , stringify ! ($Ty ), ">>(), size_of::<" , stringify ! ($Int ), ">());\n```" ), # [$stability ]# [ derive ( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash )]# [ repr ( transparent )]# [ rustc_layout_scalar_valid_range_start ( 1 )]# [ rustc_nonnull_optimization_guaranteed ] pub struct $Ty ($Int ); } impl $Ty {# [ doc = " Creates a non-zero without checking the value." ]# [ doc = "" ]# [ doc = " # Safety" ]# [ doc = "" ]# [ doc = " The value must not be zero." ]# [$stability ]# [ rustc_const_stable ( feature = "nonzero" , since = "1.34.0" )]# [ inline ] pub const unsafe fn new_unchecked ( n : $Int )-> Self { unsafe { Self ( n )}}# [ doc = " Creates a non-zero if the given value is not zero." ]# [$stability ]# [ rustc_const_stable ( feature = "const_nonzero_int_methods" , since = "1.47.0" )]# [ inline ] pub const fn new ( n : $Int )-> Option < Self > { if n != 0 { Some ( unsafe { Self ( n )})} else { None }}# [ doc = " Returns the value as a primitive type." ]# [$stability ]# [ inline ]# [ rustc_const_stable ( feature = "nonzero" , since = "1.34.0" )] pub const fn get ( self )-> $Int { self . 0 }}# [ stable ( feature = "from_nonzero" , since = "1.31.0" )] impl From <$Ty > for $Int { doc_comment ! { concat ! ( "Converts a `" , stringify ! ($Ty ), "` into an `" , stringify ! ($Int ), "`" ), # [ inline ] fn from ( nonzero : $Ty )-> Self { nonzero . 0 }}}# [ stable ( feature = "nonzero_bitor" , since = "1.45.0" )] impl BitOr for $Ty { type Output = Self ; # [ inline ] fn bitor ( self , rhs : Self )-> Self :: Output { unsafe {$Ty :: new_unchecked ( self . get ()| rhs . get ())}}}# [ stable ( feature = "nonzero_bitor" , since = "1.45.0" )] impl BitOr <$Int > for $Ty { type Output = Self ; # [ inline ] fn bitor ( self , rhs : $Int )-> Self :: Output { unsafe {$Ty :: new_unchecked ( self . get ()| rhs )}}}# [ stable ( feature = "nonzero_bitor" , since = "1.45.0" )] impl BitOr <$Ty > for $Int { type Output = $Ty ; # [ inline ] fn bitor ( self , rhs : $Ty )-> Self :: Output { unsafe {$Ty :: new_unchecked ( self | rhs . get ())}}}# [ stable ( feature = "nonzero_bitor" , since = "1.45.0" )] impl BitOrAssign for $Ty {# [ inline ] fn bitor_assign (& mut self , rhs : Self ){* self = * self | rhs ; }}# [ stable ( feature = "nonzero_bitor" , since = "1.45.0" )] impl BitOrAssign <$Int > for $Ty {# [ inline ] fn bitor_assign (& mut self , rhs : $Int ){* self = * self | rhs ; }} impl_nonzero_fmt ! {# [$stability ]( Debug , Display , Binary , Octal , LowerHex , UpperHex ) for $Ty })+ }}
6macro_rules! __ra_macro_fixture5 {($($t : ty )*)=>{$(# [ stable ( feature = "nonzero_parse" , since = "1.35.0" )] impl FromStr for $t { type Err = ParseIntError ; fn from_str ( src : & str )-> Result < Self , Self :: Err > { Self :: new ( from_str_radix ( src , 10 )?). ok_or ( ParseIntError { kind : IntErrorKind :: Zero })}})*}}
7macro_rules! __ra_macro_fixture6 {($($t : ident )*)=>($(sh_impl_unsigned ! {$t , usize })*)}
8macro_rules! __ra_macro_fixture7 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Add for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn add ( self , other : Wrapping <$t >)-> Wrapping <$t > { Wrapping ( self . 0 . wrapping_add ( other . 0 ))}} forward_ref_binop ! { impl Add , add for Wrapping <$t >, Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl AddAssign for Wrapping <$t > {# [ inline ] fn add_assign (& mut self , other : Wrapping <$t >){* self = * self + other ; }} forward_ref_op_assign ! { impl AddAssign , add_assign for Wrapping <$t >, Wrapping <$t > }# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Sub for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn sub ( self , other : Wrapping <$t >)-> Wrapping <$t > { Wrapping ( self . 0 . wrapping_sub ( other . 0 ))}} forward_ref_binop ! { impl Sub , sub for Wrapping <$t >, Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl SubAssign for Wrapping <$t > {# [ inline ] fn sub_assign (& mut self , other : Wrapping <$t >){* self = * self - other ; }} forward_ref_op_assign ! { impl SubAssign , sub_assign for Wrapping <$t >, Wrapping <$t > }# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Mul for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn mul ( self , other : Wrapping <$t >)-> Wrapping <$t > { Wrapping ( self . 0 . wrapping_mul ( other . 0 ))}} forward_ref_binop ! { impl Mul , mul for Wrapping <$t >, Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl MulAssign for Wrapping <$t > {# [ inline ] fn mul_assign (& mut self , other : Wrapping <$t >){* self = * self * other ; }} forward_ref_op_assign ! { impl MulAssign , mul_assign for Wrapping <$t >, Wrapping <$t > }# [ stable ( feature = "wrapping_div" , since = "1.3.0" )] impl Div for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn div ( self , other : Wrapping <$t >)-> Wrapping <$t > { Wrapping ( self . 0 . wrapping_div ( other . 0 ))}} forward_ref_binop ! { impl Div , div for Wrapping <$t >, Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl DivAssign for Wrapping <$t > {# [ inline ] fn div_assign (& mut self , other : Wrapping <$t >){* self = * self / other ; }} forward_ref_op_assign ! { impl DivAssign , div_assign for Wrapping <$t >, Wrapping <$t > }# [ stable ( feature = "wrapping_impls" , since = "1.7.0" )] impl Rem for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn rem ( self , other : Wrapping <$t >)-> Wrapping <$t > { Wrapping ( self . 0 . wrapping_rem ( other . 0 ))}} forward_ref_binop ! { impl Rem , rem for Wrapping <$t >, Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl RemAssign for Wrapping <$t > {# [ inline ] fn rem_assign (& mut self , other : Wrapping <$t >){* self = * self % other ; }} forward_ref_op_assign ! { impl RemAssign , rem_assign for Wrapping <$t >, Wrapping <$t > }# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Not for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn not ( self )-> Wrapping <$t > { Wrapping (! self . 0 )}} forward_ref_unop ! { impl Not , not for Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl BitXor for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn bitxor ( self , other : Wrapping <$t >)-> Wrapping <$t > { Wrapping ( self . 0 ^ other . 0 )}} forward_ref_binop ! { impl BitXor , bitxor for Wrapping <$t >, Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl BitXorAssign for Wrapping <$t > {# [ inline ] fn bitxor_assign (& mut self , other : Wrapping <$t >){* self = * self ^ other ; }} forward_ref_op_assign ! { impl BitXorAssign , bitxor_assign for Wrapping <$t >, Wrapping <$t > }# [ stable ( feature = "rust1" , since = "1.0.0" )] impl BitOr for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn bitor ( self , other : Wrapping <$t >)-> Wrapping <$t > { Wrapping ( self . 0 | other . 0 )}} forward_ref_binop ! { impl BitOr , bitor for Wrapping <$t >, Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl BitOrAssign for Wrapping <$t > {# [ inline ] fn bitor_assign (& mut self , other : Wrapping <$t >){* self = * self | other ; }} forward_ref_op_assign ! { impl BitOrAssign , bitor_assign for Wrapping <$t >, Wrapping <$t > }# [ stable ( feature = "rust1" , since = "1.0.0" )] impl BitAnd for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn bitand ( self , other : Wrapping <$t >)-> Wrapping <$t > { Wrapping ( self . 0 & other . 0 )}} forward_ref_binop ! { impl BitAnd , bitand for Wrapping <$t >, Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl BitAndAssign for Wrapping <$t > {# [ inline ] fn bitand_assign (& mut self , other : Wrapping <$t >){* self = * self & other ; }} forward_ref_op_assign ! { impl BitAndAssign , bitand_assign for Wrapping <$t >, Wrapping <$t > }# [ stable ( feature = "wrapping_neg" , since = "1.10.0" )] impl Neg for Wrapping <$t > { type Output = Self ; # [ inline ] fn neg ( self )-> Self { Wrapping ( 0 )- self }} forward_ref_unop ! { impl Neg , neg for Wrapping <$t >, # [ stable ( feature = "wrapping_ref" , since = "1.14.0" )]})*)}
9macro_rules! __ra_macro_fixture8 {($($t : ty )*)=>($(impl Wrapping <$t > { doc_comment ! { concat ! ( "Returns the smallest value that can be represented by this integer type.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert_eq!(<Wrapping<" , stringify ! ($t ), ">>::MIN, Wrapping(" , stringify ! ($t ), "::MIN));\n```" ), # [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const MIN : Self = Self (<$t >:: MIN ); } doc_comment ! { concat ! ( "Returns the largest value that can be represented by this integer type.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert_eq!(<Wrapping<" , stringify ! ($t ), ">>::MAX, Wrapping(" , stringify ! ($t ), "::MAX));\n```" ), # [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const MAX : Self = Self (<$t >:: MAX ); } doc_comment ! { concat ! ( "Returns the number of ones in the binary representation of `self`.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nlet n = Wrapping(0b01001100" , stringify ! ($t ), ");\n\nassert_eq!(n.count_ones(), 3);\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn count_ones ( self )-> u32 { self . 0 . count_ones ()}} doc_comment ! { concat ! ( "Returns the number of zeros in the binary representation of `self`.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert_eq!(Wrapping(!0" , stringify ! ($t ), ").count_zeros(), 0);\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn count_zeros ( self )-> u32 { self . 0 . count_zeros ()}} doc_comment ! { concat ! ( "Returns the number of trailing zeros in the binary representation\nof `self`.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nlet n = Wrapping(0b0101000" , stringify ! ($t ), ");\n\nassert_eq!(n.trailing_zeros(), 3);\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn trailing_zeros ( self )-> u32 { self . 0 . trailing_zeros ()}}# [ doc = " Shifts the bits to the left by a specified amount, `n`," ]# [ doc = " wrapping the truncated bits to the end of the resulting" ]# [ doc = " integer." ]# [ doc = "" ]# [ doc = " Please note this isn\\\'t the same operation as the `<<` shifting" ]# [ doc = " operator!" ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " Basic usage:" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " #![feature(wrapping_int_impl)]" ]# [ doc = " use std::num::Wrapping;" ]# [ doc = "" ]# [ doc = " let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF);" ]# [ doc = " let m: Wrapping<i64> = Wrapping(-0x76543210FEDCBA99);" ]# [ doc = "" ]# [ doc = " assert_eq!(n.rotate_left(32), m);" ]# [ doc = " ```" ]# [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn rotate_left ( self , n : u32 )-> Self { Wrapping ( self . 0 . rotate_left ( n ))}# [ doc = " Shifts the bits to the right by a specified amount, `n`," ]# [ doc = " wrapping the truncated bits to the beginning of the resulting" ]# [ doc = " integer." ]# [ doc = "" ]# [ doc = " Please note this isn\\\'t the same operation as the `>>` shifting" ]# [ doc = " operator!" ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " Basic usage:" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " #![feature(wrapping_int_impl)]" ]# [ doc = " use std::num::Wrapping;" ]# [ doc = "" ]# [ doc = " let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF);" ]# [ doc = " let m: Wrapping<i64> = Wrapping(-0xFEDCBA987654322);" ]# [ doc = "" ]# [ doc = " assert_eq!(n.rotate_right(4), m);" ]# [ doc = " ```" ]# [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn rotate_right ( self , n : u32 )-> Self { Wrapping ( self . 0 . rotate_right ( n ))}# [ doc = " Reverses the byte order of the integer." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " Basic usage:" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " #![feature(wrapping_int_impl)]" ]# [ doc = " use std::num::Wrapping;" ]# [ doc = "" ]# [ doc = " let n: Wrapping<i16> = Wrapping(0b0000000_01010101);" ]# [ doc = " assert_eq!(n, Wrapping(85));" ]# [ doc = "" ]# [ doc = " let m = n.swap_bytes();" ]# [ doc = "" ]# [ doc = " assert_eq!(m, Wrapping(0b01010101_00000000));" ]# [ doc = " assert_eq!(m, Wrapping(21760));" ]# [ doc = " ```" ]# [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn swap_bytes ( self )-> Self { Wrapping ( self . 0 . swap_bytes ())}# [ doc = " Reverses the bit pattern of the integer." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " Please note that this example is shared between integer types." ]# [ doc = " Which explains why `i16` is used here." ]# [ doc = "" ]# [ doc = " Basic usage:" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use std::num::Wrapping;" ]# [ doc = "" ]# [ doc = " let n = Wrapping(0b0000000_01010101i16);" ]# [ doc = " assert_eq!(n, Wrapping(85));" ]# [ doc = "" ]# [ doc = " let m = n.reverse_bits();" ]# [ doc = "" ]# [ doc = " assert_eq!(m.0 as u16, 0b10101010_00000000);" ]# [ doc = " assert_eq!(m, Wrapping(-22016));" ]# [ doc = " ```" ]# [ stable ( feature = "reverse_bits" , since = "1.37.0" )]# [ rustc_const_stable ( feature = "const_reverse_bits" , since = "1.37.0" )]# [ inline ]# [ must_use ] pub const fn reverse_bits ( self )-> Self { Wrapping ( self . 0 . reverse_bits ())} doc_comment ! { concat ! ( "Converts an integer from big endian to the target's endianness.\n\nOn big endian this is a no-op. On little endian the bytes are\nswapped.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nlet n = Wrapping(0x1A" , stringify ! ($t ), ");\n\nif cfg!(target_endian = \"big\") {\n assert_eq!(<Wrapping<" , stringify ! ($t ), ">>::from_be(n), n)\n} else {\n assert_eq!(<Wrapping<" , stringify ! ($t ), ">>::from_be(n), n.swap_bytes())\n}\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn from_be ( x : Self )-> Self { Wrapping (<$t >:: from_be ( x . 0 ))}} doc_comment ! { concat ! ( "Converts an integer from little endian to the target's endianness.\n\nOn little endian this is a no-op. On big endian the bytes are\nswapped.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nlet n = Wrapping(0x1A" , stringify ! ($t ), ");\n\nif cfg!(target_endian = \"little\") {\n assert_eq!(<Wrapping<" , stringify ! ($t ), ">>::from_le(n), n)\n} else {\n assert_eq!(<Wrapping<" , stringify ! ($t ), ">>::from_le(n), n.swap_bytes())\n}\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn from_le ( x : Self )-> Self { Wrapping (<$t >:: from_le ( x . 0 ))}} doc_comment ! { concat ! ( "Converts `self` to big endian from the target's endianness.\n\nOn big endian this is a no-op. On little endian the bytes are\nswapped.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nlet n = Wrapping(0x1A" , stringify ! ($t ), ");\n\nif cfg!(target_endian = \"big\") {\n assert_eq!(n.to_be(), n)\n} else {\n assert_eq!(n.to_be(), n.swap_bytes())\n}\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn to_be ( self )-> Self { Wrapping ( self . 0 . to_be ())}} doc_comment ! { concat ! ( "Converts `self` to little endian from the target's endianness.\n\nOn little endian this is a no-op. On big endian the bytes are\nswapped.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nlet n = Wrapping(0x1A" , stringify ! ($t ), ");\n\nif cfg!(target_endian = \"little\") {\n assert_eq!(n.to_le(), n)\n} else {\n assert_eq!(n.to_le(), n.swap_bytes())\n}\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn to_le ( self )-> Self { Wrapping ( self . 0 . to_le ())}} doc_comment ! { concat ! ( "Raises self to the power of `exp`, using exponentiation by squaring.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert_eq!(Wrapping(3" , stringify ! ($t ), ").pow(4), Wrapping(81));\n```\n\nResults that are too large are wrapped:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert_eq!(Wrapping(3i8).pow(5), Wrapping(-13));\nassert_eq!(Wrapping(3i8).pow(6), Wrapping(-39));\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub fn pow ( self , exp : u32 )-> Self { Wrapping ( self . 0 . wrapping_pow ( exp ))}}})*)}
10macro_rules! __ra_macro_fixture9 {($($t : ty )*)=>($(impl Wrapping <$t > { doc_comment ! { concat ! ( "Returns the number of leading zeros in the binary representation of `self`.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nlet n = Wrapping(" , stringify ! ($t ), "::MAX) >> 2;\n\nassert_eq!(n.leading_zeros(), 3);\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn leading_zeros ( self )-> u32 { self . 0 . leading_zeros ()}} doc_comment ! { concat ! ( "Computes the absolute value of `self`, wrapping around at\nthe boundary of the type.\n\nThe only case where such wrapping can occur is when one takes the absolute value of the negative\nminimal value for the type this is a positive value that is too large to represent in the type. In\nsuch a case, this function returns `MIN` itself.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert_eq!(Wrapping(100" , stringify ! ($t ), ").abs(), Wrapping(100));\nassert_eq!(Wrapping(-100" , stringify ! ($t ), ").abs(), Wrapping(100));\nassert_eq!(Wrapping(" , stringify ! ($t ), "::MIN).abs(), Wrapping(" , stringify ! ($t ), "::MIN));\nassert_eq!(Wrapping(-128i8).abs().0 as u8, 128u8);\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub fn abs ( self )-> Wrapping <$t > { Wrapping ( self . 0 . wrapping_abs ())}} doc_comment ! { concat ! ( "Returns a number representing sign of `self`.\n\n - `0` if the number is zero\n - `1` if the number is positive\n - `-1` if the number is negative\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert_eq!(Wrapping(10" , stringify ! ($t ), ").signum(), Wrapping(1));\nassert_eq!(Wrapping(0" , stringify ! ($t ), ").signum(), Wrapping(0));\nassert_eq!(Wrapping(-10" , stringify ! ($t ), ").signum(), Wrapping(-1));\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub fn signum ( self )-> Wrapping <$t > { Wrapping ( self . 0 . signum ())}} doc_comment ! { concat ! ( "Returns `true` if `self` is positive and `false` if the number is zero or\nnegative.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert!(Wrapping(10" , stringify ! ($t ), ").is_positive());\nassert!(!Wrapping(-10" , stringify ! ($t ), ").is_positive());\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn is_positive ( self )-> bool { self . 0 . is_positive ()}} doc_comment ! { concat ! ( "Returns `true` if `self` is negative and `false` if the number is zero or\npositive.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert!(Wrapping(-10" , stringify ! ($t ), ").is_negative());\nassert!(!Wrapping(10" , stringify ! ($t ), ").is_negative());\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn is_negative ( self )-> bool { self . 0 . is_negative ()}}})*)}
11macro_rules! __ra_macro_fixture10 {($($t : ty )*)=>($(impl Wrapping <$t > { doc_comment ! { concat ! ( "Returns the number of leading zeros in the binary representation of `self`.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nlet n = Wrapping(" , stringify ! ($t ), "::MAX) >> 2;\n\nassert_eq!(n.leading_zeros(), 2);\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub const fn leading_zeros ( self )-> u32 { self . 0 . leading_zeros ()}} doc_comment ! { concat ! ( "Returns `true` if and only if `self == 2^k` for some `k`.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_int_impl)]\nuse std::num::Wrapping;\n\nassert!(Wrapping(16" , stringify ! ($t ), ").is_power_of_two());\nassert!(!Wrapping(10" , stringify ! ($t ), ").is_power_of_two());\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_int_impl" , issue = "32463" )] pub fn is_power_of_two ( self )-> bool { self . 0 . is_power_of_two ()}} doc_comment ! { concat ! ( "Returns the smallest power of two greater than or equal to `self`.\n\nWhen return value overflows (i.e., `self > (1 << (N-1))` for type\n`uN`), overflows to `2^N = 0`.\n\n# Examples\n\nBasic usage:\n\n```\n#![feature(wrapping_next_power_of_two)]\nuse std::num::Wrapping;\n\nassert_eq!(Wrapping(2" , stringify ! ($t ), ").next_power_of_two(), Wrapping(2));\nassert_eq!(Wrapping(3" , stringify ! ($t ), ").next_power_of_two(), Wrapping(4));\nassert_eq!(Wrapping(200_u8).next_power_of_two(), Wrapping(0));\n```" ), # [ inline ]# [ unstable ( feature = "wrapping_next_power_of_two" , issue = "32463" , reason = "needs decision on wrapping behaviour" )] pub fn next_power_of_two ( self )-> Self { Wrapping ( self . 0 . wrapping_next_power_of_two ())}}})*)}
12macro_rules! __ra_macro_fixture11 {($($t : ty )*)=>{$(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl FromStr for $t { type Err = ParseIntError ; fn from_str ( src : & str )-> Result < Self , ParseIntError > { from_str_radix ( src , 10 )}})*}}
13macro_rules! __ra_macro_fixture12 {($($t : ty )*)=>($(impl FromStrRadixHelper for $t {# [ inline ] fn min_value ()-> Self { Self :: MIN }# [ inline ] fn max_value ()-> Self { Self :: MAX }# [ inline ] fn from_u32 ( u : u32 )-> Self { u as Self }# [ inline ] fn checked_mul (& self , other : u32 )-> Option < Self > { Self :: checked_mul (* self , other as Self )}# [ inline ] fn checked_sub (& self , other : u32 )-> Option < Self > { Self :: checked_sub (* self , other as Self )}# [ inline ] fn checked_add (& self , other : u32 )-> Option < Self > { Self :: checked_add (* self , other as Self )}})*)}
14macro_rules! __ra_macro_fixture13 {($($Arg : ident ),+)=>{ fnptr_impls_safety_abi ! { extern "Rust" fn ($($Arg ),+)-> Ret , $($Arg ),+ } fnptr_impls_safety_abi ! { extern "C" fn ($($Arg ),+)-> Ret , $($Arg ),+ } fnptr_impls_safety_abi ! { extern "C" fn ($($Arg ),+ , ...)-> Ret , $($Arg ),+ } fnptr_impls_safety_abi ! { unsafe extern "Rust" fn ($($Arg ),+)-> Ret , $($Arg ),+ } fnptr_impls_safety_abi ! { unsafe extern "C" fn ($($Arg ),+)-> Ret , $($Arg ),+ } fnptr_impls_safety_abi ! { unsafe extern "C" fn ($($Arg ),+ , ...)-> Ret , $($Arg ),+ }}; ()=>{ fnptr_impls_safety_abi ! { extern "Rust" fn ()-> Ret , } fnptr_impls_safety_abi ! { extern "C" fn ()-> Ret , } fnptr_impls_safety_abi ! { unsafe extern "Rust" fn ()-> Ret , } fnptr_impls_safety_abi ! { unsafe extern "C" fn ()-> Ret , }}; }
15macro_rules! __ra_macro_fixture14 {($($t : ty )*)=>{$(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Clone for $t {# [ inline ] fn clone (& self )-> Self {* self }})* }}
16macro_rules! __ra_macro_fixture15 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl PartialEq for $t {# [ inline ] fn eq (& self , other : &$t )-> bool {(* self )== (* other )}# [ inline ] fn ne (& self , other : &$t )-> bool {(* self )!= (* other )}})*)}
17macro_rules! __ra_macro_fixture16 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Eq for $t {})*)}
18macro_rules! __ra_macro_fixture17 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl PartialOrd for $t {# [ inline ] fn partial_cmp (& self , other : &$t )-> Option < Ordering > { match ( self <= other , self >= other ){( false , false )=> None , ( false , true )=> Some ( Greater ), ( true , false )=> Some ( Less ), ( true , true )=> Some ( Equal ), }}# [ inline ] fn lt (& self , other : &$t )-> bool {(* self )< (* other )}# [ inline ] fn le (& self , other : &$t )-> bool {(* self )<= (* other )}# [ inline ] fn ge (& self , other : &$t )-> bool {(* self )>= (* other )}# [ inline ] fn gt (& self , other : &$t )-> bool {(* self )> (* other )}})*)}
19macro_rules! __ra_macro_fixture18 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl PartialOrd for $t {# [ inline ] fn partial_cmp (& self , other : &$t )-> Option < Ordering > { Some ( self . cmp ( other ))}# [ inline ] fn lt (& self , other : &$t )-> bool {(* self )< (* other )}# [ inline ] fn le (& self , other : &$t )-> bool {(* self )<= (* other )}# [ inline ] fn ge (& self , other : &$t )-> bool {(* self )>= (* other )}# [ inline ] fn gt (& self , other : &$t )-> bool {(* self )> (* other )}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Ord for $t {# [ inline ] fn cmp (& self , other : &$t )-> Ordering { if * self < * other { Less } else if * self == * other { Equal } else { Greater }}})*)}
20macro_rules! __ra_macro_fixture19 {($Float : ident =>$($Int : ident )+ )=>{# [ unstable ( feature = "convert_float_to_int" , issue = "67057" )] impl private :: Sealed for $Float {}$(# [ unstable ( feature = "convert_float_to_int" , issue = "67057" )] impl FloatToInt <$Int > for $Float {# [ doc ( hidden )]# [ inline ] unsafe fn to_int_unchecked ( self )-> $Int { unsafe { crate :: intrinsics :: float_to_int_unchecked ( self )}}})+ }}
21macro_rules! __ra_macro_fixture20 {($target : ty , # [$attr : meta ])=>{ impl_from ! ( bool , $target , # [$attr ], concat ! ( "Converts a `bool` to a `" , stringify ! ($target ), "`. The resulting value is `0` for `false` and `1` for `true`\nvalues.\n\n# Examples\n\n```\nassert_eq!(" , stringify ! ($target ), "::from(true), 1);\nassert_eq!(" , stringify ! ($target ), "::from(false), 0);\n```" )); }; }
22macro_rules! __ra_macro_fixture21 {($Small : ty , $Large : ty , # [$attr : meta ], $doc : expr )=>{# [$attr ]# [ doc = $doc ] impl From <$Small > for $Large {# [ inline ] fn from ( small : $Small )-> Self { small as Self }}}; ($Small : ty , $Large : ty , # [$attr : meta ])=>{ impl_from ! ($Small , $Large , # [$attr ], concat ! ( "Converts `" , stringify ! ($Small ), "` to `" , stringify ! ($Large ), "` losslessly." )); }}
23macro_rules! __ra_macro_fixture22 {($source : ty , $($target : ty ),*)=>{$(# [ stable ( feature = "try_from" , since = "1.34.0" )] impl TryFrom <$source > for $target { type Error = TryFromIntError ; # [ doc = " Try to create the target number type from a source" ]# [ doc = " number type. This returns an error if the source value" ]# [ doc = " is outside of the range of the target type." ]# [ inline ] fn try_from ( u : $source )-> Result < Self , Self :: Error > { if u > ( Self :: MAX as $source ){ Err ( TryFromIntError (()))} else { Ok ( u as Self )}}})*}}
24macro_rules! __ra_macro_fixture23 {($source : ty , $($target : ty ),*)=>{$(# [ stable ( feature = "try_from" , since = "1.34.0" )] impl TryFrom <$source > for $target { type Error = TryFromIntError ; # [ doc = " Try to create the target number type from a source" ]# [ doc = " number type. This returns an error if the source value" ]# [ doc = " is outside of the range of the target type." ]# [ inline ] fn try_from ( u : $source )-> Result < Self , Self :: Error > { let min = Self :: MIN as $source ; let max = Self :: MAX as $source ; if u < min || u > max { Err ( TryFromIntError (()))} else { Ok ( u as Self )}}})*}}
25macro_rules! __ra_macro_fixture24 {($source : ty , $($target : ty ),*)=>{$(# [ stable ( feature = "try_from" , since = "1.34.0" )] impl TryFrom <$source > for $target { type Error = TryFromIntError ; # [ doc = " Try to create the target number type from a source" ]# [ doc = " number type. This returns an error if the source value" ]# [ doc = " is outside of the range of the target type." ]# [ inline ] fn try_from ( u : $source )-> Result < Self , Self :: Error > { if u >= 0 { Ok ( u as Self )} else { Err ( TryFromIntError (()))}}})*}}
26macro_rules! __ra_macro_fixture25 {($source : ty , $($target : ty ),*)=>{$(# [ stable ( feature = "try_from" , since = "1.34.0" )] impl TryFrom <$source > for $target { type Error = TryFromIntError ; # [ doc = " Try to create the target number type from a source" ]# [ doc = " number type. This returns an error if the source value" ]# [ doc = " is outside of the range of the target type." ]# [ inline ] fn try_from ( value : $source )-> Result < Self , Self :: Error > { Ok ( value as Self )}})*}}
27macro_rules! __ra_macro_fixture26 {($mac : ident , $source : ty , $($target : ty ),*)=>{$($mac ! ($target , $source ); )*}}
28macro_rules! __ra_macro_fixture27 {($Small : ty , $Large : ty , # [$attr : meta ], $doc : expr )=>{# [$attr ]# [ doc = $doc ] impl From <$Small > for $Large {# [ inline ] fn from ( small : $Small )-> Self { unsafe { Self :: new_unchecked ( small . get (). into ())}}}}; ($Small : ty , $Large : ty , # [$attr : meta ])=>{ nzint_impl_from ! ($Small , $Large , # [$attr ], concat ! ( "Converts `" , stringify ! ($Small ), "` to `" , stringify ! ($Large ), "` losslessly." )); }}
29macro_rules! __ra_macro_fixture28 {($Int : ty , $NonZeroInt : ty , # [$attr : meta ], $doc : expr )=>{# [$attr ]# [ doc = $doc ] impl TryFrom <$Int > for $NonZeroInt { type Error = TryFromIntError ; # [ inline ] fn try_from ( value : $Int )-> Result < Self , Self :: Error > { Self :: new ( value ). ok_or ( TryFromIntError (()))}}}; ($Int : ty , $NonZeroInt : ty , # [$attr : meta ])=>{ nzint_impl_try_from_int ! ($Int , $NonZeroInt , # [$attr ], concat ! ( "Attempts to convert `" , stringify ! ($Int ), "` to `" , stringify ! ($NonZeroInt ), "`." )); }}
30macro_rules! __ra_macro_fixture29 {($From : ty =>$To : ty , $doc : expr )=>{# [ stable ( feature = "nzint_try_from_nzint_conv" , since = "1.49.0" )]# [ doc = $doc ] impl TryFrom <$From > for $To { type Error = TryFromIntError ; # [ inline ] fn try_from ( value : $From )-> Result < Self , Self :: Error > { TryFrom :: try_from ( value . get ()). map (| v | { unsafe { Self :: new_unchecked ( v )}})}}}; ($To : ty : $($From : ty ),*)=>{$(nzint_impl_try_from_nzint ! ($From =>$To , concat ! ( "Attempts to convert `" , stringify ! ($From ), "` to `" , stringify ! ($To ), "`." , )); )*}; }
31macro_rules! __ra_macro_fixture30 {($t : ty , $v : expr , $doc : tt )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Default for $t {# [ inline ]# [ doc = $doc ] fn default ()-> $t {$v }}}}
32macro_rules! __ra_macro_fixture31 {($t : ident )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized > Hash for $t < T > {# [ inline ] fn hash < H : Hasher > (& self , _: & mut H ){}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized > cmp :: PartialEq for $t < T > { fn eq (& self , _other : &$t < T >)-> bool { true }}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized > cmp :: Eq for $t < T > {}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized > cmp :: PartialOrd for $t < T > { fn partial_cmp (& self , _other : &$t < T >)-> Option < cmp :: Ordering > { Option :: Some ( cmp :: Ordering :: Equal )}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized > cmp :: Ord for $t < T > { fn cmp (& self , _other : &$t < T >)-> cmp :: Ordering { cmp :: Ordering :: Equal }}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized > Copy for $t < T > {}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized > Clone for $t < T > { fn clone (& self )-> Self { Self }}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized > Default for $t < T > { fn default ()-> Self { Self }}# [ unstable ( feature = "structural_match" , issue = "31434" )] impl < T : ? Sized > StructuralPartialEq for $t < T > {}# [ unstable ( feature = "structural_match" , issue = "31434" )] impl < T : ? Sized > StructuralEq for $t < T > {}}; }
33macro_rules! __ra_macro_fixture32 {($($t : ty )*)=>{$(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Copy for $t {})* }}
34macro_rules! __ra_macro_fixture33 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Add for $t { type Output = $t ; # [ inline ]# [ rustc_inherit_overflow_checks ] fn add ( self , other : $t )-> $t { self + other }} forward_ref_binop ! { impl Add , add for $t , $t })*)}
35macro_rules! __ra_macro_fixture34 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Sub for $t { type Output = $t ; # [ inline ]# [ rustc_inherit_overflow_checks ] fn sub ( self , other : $t )-> $t { self - other }} forward_ref_binop ! { impl Sub , sub for $t , $t })*)}
36macro_rules! __ra_macro_fixture35 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Mul for $t { type Output = $t ; # [ inline ]# [ rustc_inherit_overflow_checks ] fn mul ( self , other : $t )-> $t { self * other }} forward_ref_binop ! { impl Mul , mul for $t , $t })*)}
37macro_rules! __ra_macro_fixture36 {($($t : ty )*)=>($(# [ doc = " This operation rounds towards zero, truncating any" ]# [ doc = " fractional part of the exact result." ]# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Div for $t { type Output = $t ; # [ inline ] fn div ( self , other : $t )-> $t { self / other }} forward_ref_binop ! { impl Div , div for $t , $t })*)}
38macro_rules! __ra_macro_fixture37 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Div for $t { type Output = $t ; # [ inline ] fn div ( self , other : $t )-> $t { self / other }} forward_ref_binop ! { impl Div , div for $t , $t })*)}
39macro_rules! __ra_macro_fixture38 {($($t : ty )*)=>($(# [ doc = " This operation satisfies `n % d == n - (n / d) * d`. The" ]# [ doc = " result has the same sign as the left operand." ]# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Rem for $t { type Output = $t ; # [ inline ] fn rem ( self , other : $t )-> $t { self % other }} forward_ref_binop ! { impl Rem , rem for $t , $t })*)}
40macro_rules! __ra_macro_fixture39 {($($t : ty )*)=>($(# [ doc = " The remainder from the division of two floats." ]# [ doc = "" ]# [ doc = " The remainder has the same sign as the dividend and is computed as:" ]# [ doc = " `x - (x / y).trunc() * y`." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = " ```" ]# [ doc = " let x: f32 = 50.50;" ]# [ doc = " let y: f32 = 8.125;" ]# [ doc = " let remainder = x - (x / y).trunc() * y;" ]# [ doc = "" ]# [ doc = " // The answer to both operations is 1.75" ]# [ doc = " assert_eq!(x % y, remainder);" ]# [ doc = " ```" ]# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Rem for $t { type Output = $t ; # [ inline ] fn rem ( self , other : $t )-> $t { self % other }} forward_ref_binop ! { impl Rem , rem for $t , $t })*)}
41macro_rules! __ra_macro_fixture40 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Neg for $t { type Output = $t ; # [ inline ]# [ rustc_inherit_overflow_checks ] fn neg ( self )-> $t {- self }} forward_ref_unop ! { impl Neg , neg for $t })*)}
42macro_rules! __ra_macro_fixture41 {($($t : ty )+)=>($(# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl AddAssign for $t {# [ inline ]# [ rustc_inherit_overflow_checks ] fn add_assign (& mut self , other : $t ){* self += other }} forward_ref_op_assign ! { impl AddAssign , add_assign for $t , $t })+)}
43macro_rules! __ra_macro_fixture42 {($($t : ty )+)=>($(# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl SubAssign for $t {# [ inline ]# [ rustc_inherit_overflow_checks ] fn sub_assign (& mut self , other : $t ){* self -= other }} forward_ref_op_assign ! { impl SubAssign , sub_assign for $t , $t })+)}
44macro_rules! __ra_macro_fixture43 {($($t : ty )+)=>($(# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl MulAssign for $t {# [ inline ]# [ rustc_inherit_overflow_checks ] fn mul_assign (& mut self , other : $t ){* self *= other }} forward_ref_op_assign ! { impl MulAssign , mul_assign for $t , $t })+)}
45macro_rules! __ra_macro_fixture44 {($($t : ty )+)=>($(# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl DivAssign for $t {# [ inline ] fn div_assign (& mut self , other : $t ){* self /= other }} forward_ref_op_assign ! { impl DivAssign , div_assign for $t , $t })+)}
46macro_rules! __ra_macro_fixture45 {($($t : ty )+)=>($(# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl RemAssign for $t {# [ inline ] fn rem_assign (& mut self , other : $t ){* self %= other }} forward_ref_op_assign ! { impl RemAssign , rem_assign for $t , $t })+)}
47macro_rules! __ra_macro_fixture46 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Not for $t { type Output = $t ; # [ inline ] fn not ( self )-> $t {! self }} forward_ref_unop ! { impl Not , not for $t })*)}
48macro_rules! __ra_macro_fixture47 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl BitAnd for $t { type Output = $t ; # [ inline ] fn bitand ( self , rhs : $t )-> $t { self & rhs }} forward_ref_binop ! { impl BitAnd , bitand for $t , $t })*)}
49macro_rules! __ra_macro_fixture48 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl BitOr for $t { type Output = $t ; # [ inline ] fn bitor ( self , rhs : $t )-> $t { self | rhs }} forward_ref_binop ! { impl BitOr , bitor for $t , $t })*)}
50macro_rules! __ra_macro_fixture49 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl BitXor for $t { type Output = $t ; # [ inline ] fn bitxor ( self , other : $t )-> $t { self ^ other }} forward_ref_binop ! { impl BitXor , bitxor for $t , $t })*)}
51macro_rules! __ra_macro_fixture50 {($($t : ty )*)=>($(shl_impl ! {$t , u8 } shl_impl ! {$t , u16 } shl_impl ! {$t , u32 } shl_impl ! {$t , u64 } shl_impl ! {$t , u128 } shl_impl ! {$t , usize } shl_impl ! {$t , i8 } shl_impl ! {$t , i16 } shl_impl ! {$t , i32 } shl_impl ! {$t , i64 } shl_impl ! {$t , i128 } shl_impl ! {$t , isize })*)}
52macro_rules! __ra_macro_fixture51 {($($t : ty )*)=>($(shr_impl ! {$t , u8 } shr_impl ! {$t , u16 } shr_impl ! {$t , u32 } shr_impl ! {$t , u64 } shr_impl ! {$t , u128 } shr_impl ! {$t , usize } shr_impl ! {$t , i8 } shr_impl ! {$t , i16 } shr_impl ! {$t , i32 } shr_impl ! {$t , i64 } shr_impl ! {$t , i128 } shr_impl ! {$t , isize })*)}
53macro_rules! __ra_macro_fixture52 {($($t : ty )+)=>($(# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl BitAndAssign for $t {# [ inline ] fn bitand_assign (& mut self , other : $t ){* self &= other }} forward_ref_op_assign ! { impl BitAndAssign , bitand_assign for $t , $t })+)}
54macro_rules! __ra_macro_fixture53 {($($t : ty )+)=>($(# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl BitOrAssign for $t {# [ inline ] fn bitor_assign (& mut self , other : $t ){* self |= other }} forward_ref_op_assign ! { impl BitOrAssign , bitor_assign for $t , $t })+)}
55macro_rules! __ra_macro_fixture54 {($($t : ty )+)=>($(# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl BitXorAssign for $t {# [ inline ] fn bitxor_assign (& mut self , other : $t ){* self ^= other }} forward_ref_op_assign ! { impl BitXorAssign , bitxor_assign for $t , $t })+)}
56macro_rules! __ra_macro_fixture55 {($($t : ty )*)=>($(shl_assign_impl ! {$t , u8 } shl_assign_impl ! {$t , u16 } shl_assign_impl ! {$t , u32 } shl_assign_impl ! {$t , u64 } shl_assign_impl ! {$t , u128 } shl_assign_impl ! {$t , usize } shl_assign_impl ! {$t , i8 } shl_assign_impl ! {$t , i16 } shl_assign_impl ! {$t , i32 } shl_assign_impl ! {$t , i64 } shl_assign_impl ! {$t , i128 } shl_assign_impl ! {$t , isize })*)}
57macro_rules! __ra_macro_fixture56 {($($t : ty )*)=>($(shr_assign_impl ! {$t , u8 } shr_assign_impl ! {$t , u16 } shr_assign_impl ! {$t , u32 } shr_assign_impl ! {$t , u64 } shr_assign_impl ! {$t , u128 } shr_assign_impl ! {$t , usize } shr_assign_impl ! {$t , i8 } shr_assign_impl ! {$t , i16 } shr_assign_impl ! {$t , i32 } shr_assign_impl ! {$t , i64 } shr_assign_impl ! {$t , i128 } shr_assign_impl ! {$t , isize })*)}
58macro_rules! __ra_macro_fixture57 {{$n : expr , $t : ident $($ts : ident )*}=>{# [ stable ( since = "1.4.0" , feature = "array_default" )] impl < T > Default for [ T ; $n ] where T : Default { fn default ()-> [ T ; $n ]{[$t :: default (), $($ts :: default ()),*]}} array_impl_default ! {($n - 1 ), $($ts )*}}; {$n : expr ,}=>{# [ stable ( since = "1.4.0" , feature = "array_default" )] impl < T > Default for [ T ; $n ]{ fn default ()-> [ T ; $n ]{[]}}}; }
59macro_rules! __ra_macro_fixture58 {($($t : ty ),+)=>{$(# [ unstable ( feature = "c_variadic" , reason = "the `c_variadic` feature has not been properly tested on \\n all supported platforms" , issue = "44930" )] impl sealed_trait :: VaArgSafe for $t {})+ }}
60macro_rules! __ra_macro_fixture59 {{ narrower than or same width as usize : $([$u_narrower : ident $i_narrower : ident ]),+; wider than usize : $([$u_wider : ident $i_wider : ident ]),+; }=>{$(# [ allow ( unreachable_patterns )]# [ unstable ( feature = "step_trait" , reason = "recently redesigned" , issue = "42168" )] unsafe impl Step for $u_narrower { step_identical_methods ! (); # [ inline ] fn steps_between ( start : & Self , end : & Self )-> Option < usize > { if * start <= * end { Some ((* end - * start ) as usize )} else { None }}# [ inline ] fn forward_checked ( start : Self , n : usize )-> Option < Self > { match Self :: try_from ( n ){ Ok ( n )=> start . checked_add ( n ), Err (_)=> None , }}# [ inline ] fn backward_checked ( start : Self , n : usize )-> Option < Self > { match Self :: try_from ( n ){ Ok ( n )=> start . checked_sub ( n ), Err (_)=> None , }}}# [ allow ( unreachable_patterns )]# [ unstable ( feature = "step_trait" , reason = "recently redesigned" , issue = "42168" )] unsafe impl Step for $i_narrower { step_identical_methods ! (); # [ inline ] fn steps_between ( start : & Self , end : & Self )-> Option < usize > { if * start <= * end { Some ((* end as isize ). wrapping_sub (* start as isize ) as usize )} else { None }}# [ inline ] fn forward_checked ( start : Self , n : usize )-> Option < Self > { match $u_narrower :: try_from ( n ){ Ok ( n )=>{ let wrapped = start . wrapping_add ( n as Self ); if wrapped >= start { Some ( wrapped )} else { None }} Err (_)=> None , }}# [ inline ] fn backward_checked ( start : Self , n : usize )-> Option < Self > { match $u_narrower :: try_from ( n ){ Ok ( n )=>{ let wrapped = start . wrapping_sub ( n as Self ); if wrapped <= start { Some ( wrapped )} else { None }} Err (_)=> None , }}})+ $(# [ allow ( unreachable_patterns )]# [ unstable ( feature = "step_trait" , reason = "recently redesigned" , issue = "42168" )] unsafe impl Step for $u_wider { step_identical_methods ! (); # [ inline ] fn steps_between ( start : & Self , end : & Self )-> Option < usize > { if * start <= * end { usize :: try_from (* end - * start ). ok ()} else { None }}# [ inline ] fn forward_checked ( start : Self , n : usize )-> Option < Self > { start . checked_add ( n as Self )}# [ inline ] fn backward_checked ( start : Self , n : usize )-> Option < Self > { start . checked_sub ( n as Self )}}# [ allow ( unreachable_patterns )]# [ unstable ( feature = "step_trait" , reason = "recently redesigned" , issue = "42168" )] unsafe impl Step for $i_wider { step_identical_methods ! (); # [ inline ] fn steps_between ( start : & Self , end : & Self )-> Option < usize > { if * start <= * end { match end . checked_sub (* start ){ Some ( result )=> usize :: try_from ( result ). ok (), None => None , }} else { None }}# [ inline ] fn forward_checked ( start : Self , n : usize )-> Option < Self > { start . checked_add ( n as Self )}# [ inline ] fn backward_checked ( start : Self , n : usize )-> Option < Self > { start . checked_sub ( n as Self )}})+ }; }
61macro_rules! __ra_macro_fixture60 {($($t : ty )*)=>($(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl ExactSizeIterator for ops :: Range <$t > {})*)}
62macro_rules! __ra_macro_fixture61 {($($t : ty )*)=>($(# [ stable ( feature = "inclusive_range" , since = "1.26.0" )] impl ExactSizeIterator for ops :: RangeInclusive <$t > {})*)}
63macro_rules! __ra_macro_fixture62 {(@ impls $zero : expr , $one : expr , # [$attr : meta ], $($a : ty )*)=>($(# [$attr ] impl Sum for $a { fn sum < I : Iterator < Item = Self >> ( iter : I )-> Self { iter . fold ($zero , Add :: add )}}# [$attr ] impl Product for $a { fn product < I : Iterator < Item = Self >> ( iter : I )-> Self { iter . fold ($one , Mul :: mul )}}# [$attr ] impl < 'a > Sum <& 'a $a > for $a { fn sum < I : Iterator < Item =& 'a Self >> ( iter : I )-> Self { iter . fold ($zero , Add :: add )}}# [$attr ] impl < 'a > Product <& 'a $a > for $a { fn product < I : Iterator < Item =& 'a Self >> ( iter : I )-> Self { iter . fold ($one , Mul :: mul )}})*); ($($a : ty )*)=>( integer_sum_product ! (@ impls 0 , 1 , # [ stable ( feature = "iter_arith_traits" , since = "1.12.0" )], $($a )*); integer_sum_product ! (@ impls Wrapping ( 0 ), Wrapping ( 1 ), # [ stable ( feature = "wrapping_iter_arith" , since = "1.14.0" )], $(Wrapping <$a >)*); ); }
64macro_rules! __ra_macro_fixture63 {($($a : ident )*)=>($(# [ stable ( feature = "iter_arith_traits" , since = "1.12.0" )] impl Sum for $a { fn sum < I : Iterator < Item = Self >> ( iter : I )-> Self { iter . fold ( 0.0 , Add :: add )}}# [ stable ( feature = "iter_arith_traits" , since = "1.12.0" )] impl Product for $a { fn product < I : Iterator < Item = Self >> ( iter : I )-> Self { iter . fold ( 1.0 , Mul :: mul )}}# [ stable ( feature = "iter_arith_traits" , since = "1.12.0" )] impl < 'a > Sum <& 'a $a > for $a { fn sum < I : Iterator < Item =& 'a Self >> ( iter : I )-> Self { iter . fold ( 0.0 , Add :: add )}}# [ stable ( feature = "iter_arith_traits" , since = "1.12.0" )] impl < 'a > Product <& 'a $a > for $a { fn product < I : Iterator < Item =& 'a Self >> ( iter : I )-> Self { iter . fold ( 1.0 , Mul :: mul )}})*)}
65macro_rules! __ra_macro_fixture64 {($cfg_cas : meta , $cfg_align : meta , $stable : meta , $stable_cxchg : meta , $stable_debug : meta , $stable_access : meta , $stable_from : meta , $stable_nand : meta , $const_stable : meta , $stable_init_const : meta , $s_int_type : literal , $int_ref : expr , $extra_feature : expr , $min_fn : ident , $max_fn : ident , $align : expr , $atomic_new : expr , $int_type : ident $atomic_type : ident $atomic_init : ident )=>{# [ doc = " An integer type which can be safely shared between threads." ]# [ doc = "" ]# [ doc = " This type has the same in-memory representation as the underlying" ]# [ doc = " integer type, [`" ]# [ doc = $s_int_type ]# [ doc = " `](" ]# [ doc = $int_ref ]# [ doc = " ). For more about the differences between atomic types and" ]# [ doc = " non-atomic types as well as information about the portability of" ]# [ doc = " this type, please see the [module-level documentation]." ]# [ doc = "" ]# [ doc = " **Note:** This type is only available on platforms that support" ]# [ doc = " atomic loads and stores of [`" ]# [ doc = $s_int_type ]# [ doc = " `](" ]# [ doc = $int_ref ]# [ doc = " )." ]# [ doc = "" ]# [ doc = " [module-level documentation]: crate::sync::atomic" ]# [$stable ]# [ repr ( C , align ($align ))] pub struct $atomic_type { v : UnsafeCell <$int_type >, }# [ doc = " An atomic integer initialized to `0`." ]# [$stable_init_const ]# [ rustc_deprecated ( since = "1.34.0" , reason = "the `new` function is now preferred" , suggestion = $atomic_new , )] pub const $atomic_init : $atomic_type = $atomic_type :: new ( 0 ); # [$stable ] impl Default for $atomic_type {# [ inline ] fn default ()-> Self { Self :: new ( Default :: default ())}}# [$stable_from ] impl From <$int_type > for $atomic_type { doc_comment ! { concat ! ( "Converts an `" , stringify ! ($int_type ), "` into an `" , stringify ! ($atomic_type ), "`." ), # [ inline ] fn from ( v : $int_type )-> Self { Self :: new ( v )}}}# [$stable_debug ] impl fmt :: Debug for $atomic_type { fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { fmt :: Debug :: fmt (& self . load ( Ordering :: SeqCst ), f )}}# [$stable ] unsafe impl Sync for $atomic_type {} impl $atomic_type { doc_comment ! { concat ! ( "Creates a new atomic integer.\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::" , stringify ! ($atomic_type ), ";\n\nlet atomic_forty_two = " , stringify ! ($atomic_type ), "::new(42);\n```" ), # [ inline ]# [$stable ]# [$const_stable ] pub const fn new ( v : $int_type )-> Self { Self { v : UnsafeCell :: new ( v )}}} doc_comment ! { concat ! ( "Returns a mutable reference to the underlying integer.\n\nThis is safe because the mutable reference guarantees that no other threads are\nconcurrently accessing the atomic data.\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet mut some_var = " , stringify ! ($atomic_type ), "::new(10);\nassert_eq!(*some_var.get_mut(), 10);\n*some_var.get_mut() = 5;\nassert_eq!(some_var.load(Ordering::SeqCst), 5);\n```" ), # [ inline ]# [$stable_access ] pub fn get_mut (& mut self )-> & mut $int_type { self . v . get_mut ()}} doc_comment ! { concat ! ( "Get atomic access to a `&mut " , stringify ! ($int_type ), "`.\n\n" , if_not_8_bit ! {$int_type , concat ! ( "**Note:** This function is only available on targets where `" , stringify ! ($int_type ), "` has an alignment of " , $align , " bytes." )}, "\n\n# Examples\n\n```\n#![feature(atomic_from_mut)]\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet mut some_int = 123;\nlet a = " , stringify ! ($atomic_type ), "::from_mut(&mut some_int);\na.store(100, Ordering::Relaxed);\nassert_eq!(some_int, 100);\n```\n " ), # [ inline ]# [$cfg_align ]# [ unstable ( feature = "atomic_from_mut" , issue = "76314" )] pub fn from_mut ( v : & mut $int_type )-> & Self { use crate :: mem :: align_of ; let []= [(); align_of ::< Self > ()- align_of ::<$int_type > ()]; unsafe {&* ( v as * mut $int_type as * mut Self )}}} doc_comment ! { concat ! ( "Consumes the atomic and returns the contained value.\n\nThis is safe because passing `self` by value guarantees that no other threads are\nconcurrently accessing the atomic data.\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::" , stringify ! ($atomic_type ), ";\n\nlet some_var = " , stringify ! ($atomic_type ), "::new(5);\nassert_eq!(some_var.into_inner(), 5);\n```" ), # [ inline ]# [$stable_access ]# [ rustc_const_unstable ( feature = "const_cell_into_inner" , issue = "78729" )] pub const fn into_inner ( self )-> $int_type { self . v . into_inner ()}} doc_comment ! { concat ! ( "Loads a value from the atomic integer.\n\n`load` takes an [`Ordering`] argument which describes the memory ordering of this operation.\nPossible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].\n\n# Panics\n\nPanics if `order` is [`Release`] or [`AcqRel`].\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet some_var = " , stringify ! ($atomic_type ), "::new(5);\n\nassert_eq!(some_var.load(Ordering::Relaxed), 5);\n```" ), # [ inline ]# [$stable ] pub fn load (& self , order : Ordering )-> $int_type { unsafe { atomic_load ( self . v . get (), order )}}} doc_comment ! { concat ! ( "Stores a value into the atomic integer.\n\n`store` takes an [`Ordering`] argument which describes the memory ordering of this operation.\n Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].\n\n# Panics\n\nPanics if `order` is [`Acquire`] or [`AcqRel`].\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet some_var = " , stringify ! ($atomic_type ), "::new(5);\n\nsome_var.store(10, Ordering::Relaxed);\nassert_eq!(some_var.load(Ordering::Relaxed), 10);\n```" ), # [ inline ]# [$stable ] pub fn store (& self , val : $int_type , order : Ordering ){ unsafe { atomic_store ( self . v . get (), val , order ); }}} doc_comment ! { concat ! ( "Stores a value into the atomic integer, returning the previous value.\n\n`swap` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet some_var = " , stringify ! ($atomic_type ), "::new(5);\n\nassert_eq!(some_var.swap(10, Ordering::Relaxed), 5);\n```" ), # [ inline ]# [$stable ]# [$cfg_cas ] pub fn swap (& self , val : $int_type , order : Ordering )-> $int_type { unsafe { atomic_swap ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Stores a value into the atomic integer if the current value is the same as\nthe `current` value.\n\nThe return value is always the previous value. If it is equal to `current`, then the\nvalue was updated.\n\n`compare_and_swap` also takes an [`Ordering`] argument which describes the memory\nordering of this operation. Notice that even when using [`AcqRel`], the operation\nmight fail and hence just perform an `Acquire` load, but not have `Release` semantics.\nUsing [`Acquire`] makes the store part of this operation [`Relaxed`] if it\nhappens, and using [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet some_var = " , stringify ! ($atomic_type ), "::new(5);\n\nassert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);\nassert_eq!(some_var.load(Ordering::Relaxed), 10);\n\nassert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);\nassert_eq!(some_var.load(Ordering::Relaxed), 10);\n```" ), # [ inline ]# [$stable ]# [$cfg_cas ] pub fn compare_and_swap (& self , current : $int_type , new : $int_type , order : Ordering )-> $int_type { match self . compare_exchange ( current , new , order , strongest_failure_ordering ( order )){ Ok ( x )=> x , Err ( x )=> x , }}} doc_comment ! { concat ! ( "Stores a value into the atomic integer if the current value is the same as\nthe `current` value.\n\nThe return value is a result indicating whether the new value was written and\ncontaining the previous value. On success this value is guaranteed to be equal to\n`current`.\n\n`compare_exchange` takes two [`Ordering`] arguments to describe the memory\nordering of this operation. The first describes the required ordering if the\noperation succeeds while the second describes the required ordering when the\noperation fails. Using [`Acquire`] as success ordering makes the store part\nof this operation [`Relaxed`], and using [`Release`] makes the successful load\n[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]\nand must be equivalent to or weaker than the success ordering.\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet some_var = " , stringify ! ($atomic_type ), "::new(5);\n\nassert_eq!(some_var.compare_exchange(5, 10,\n Ordering::Acquire,\n Ordering::Relaxed),\n Ok(5));\nassert_eq!(some_var.load(Ordering::Relaxed), 10);\n\nassert_eq!(some_var.compare_exchange(6, 12,\n Ordering::SeqCst,\n Ordering::Acquire),\n Err(10));\nassert_eq!(some_var.load(Ordering::Relaxed), 10);\n```" ), # [ inline ]# [$stable_cxchg ]# [$cfg_cas ] pub fn compare_exchange (& self , current : $int_type , new : $int_type , success : Ordering , failure : Ordering )-> Result <$int_type , $int_type > { unsafe { atomic_compare_exchange ( self . v . get (), current , new , success , failure )}}} doc_comment ! { concat ! ( "Stores a value into the atomic integer if the current value is the same as\nthe `current` value.\n\nUnlike [`" , stringify ! ($atomic_type ), "::compare_exchange`], this function is allowed to spuriously fail even\nwhen the comparison succeeds, which can result in more efficient code on some\nplatforms. The return value is a result indicating whether the new value was\nwritten and containing the previous value.\n\n`compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory\nordering of this operation. The first describes the required ordering if the\noperation succeeds while the second describes the required ordering when the\noperation fails. Using [`Acquire`] as success ordering makes the store part\nof this operation [`Relaxed`], and using [`Release`] makes the successful load\n[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]\nand must be equivalent to or weaker than the success ordering.\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet val = " , stringify ! ($atomic_type ), "::new(4);\n\nlet mut old = val.load(Ordering::Relaxed);\nloop {\n let new = old * 2;\n match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {\n Ok(_) => break,\n Err(x) => old = x,\n }\n}\n```" ), # [ inline ]# [$stable_cxchg ]# [$cfg_cas ] pub fn compare_exchange_weak (& self , current : $int_type , new : $int_type , success : Ordering , failure : Ordering )-> Result <$int_type , $int_type > { unsafe { atomic_compare_exchange_weak ( self . v . get (), current , new , success , failure )}}} doc_comment ! { concat ! ( "Adds to the current value, returning the previous value.\n\nThis operation wraps around on overflow.\n\n`fetch_add` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(0);\nassert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);\nassert_eq!(foo.load(Ordering::SeqCst), 10);\n```" ), # [ inline ]# [$stable ]# [$cfg_cas ] pub fn fetch_add (& self , val : $int_type , order : Ordering )-> $int_type { unsafe { atomic_add ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Subtracts from the current value, returning the previous value.\n\nThis operation wraps around on overflow.\n\n`fetch_sub` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(20);\nassert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);\nassert_eq!(foo.load(Ordering::SeqCst), 10);\n```" ), # [ inline ]# [$stable ]# [$cfg_cas ] pub fn fetch_sub (& self , val : $int_type , order : Ordering )-> $int_type { unsafe { atomic_sub ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Bitwise \"and\" with the current value.\n\nPerforms a bitwise \"and\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_and` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(0b101101);\nassert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);\nassert_eq!(foo.load(Ordering::SeqCst), 0b100001);\n```" ), # [ inline ]# [$stable ]# [$cfg_cas ] pub fn fetch_and (& self , val : $int_type , order : Ordering )-> $int_type { unsafe { atomic_and ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Bitwise \"nand\" with the current value.\n\nPerforms a bitwise \"nand\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_nand` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "\nuse std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(0x13);\nassert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);\nassert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));\n```" ), # [ inline ]# [$stable_nand ]# [$cfg_cas ] pub fn fetch_nand (& self , val : $int_type , order : Ordering )-> $int_type { unsafe { atomic_nand ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Bitwise \"or\" with the current value.\n\nPerforms a bitwise \"or\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_or` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(0b101101);\nassert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);\nassert_eq!(foo.load(Ordering::SeqCst), 0b111111);\n```" ), # [ inline ]# [$stable ]# [$cfg_cas ] pub fn fetch_or (& self , val : $int_type , order : Ordering )-> $int_type { unsafe { atomic_or ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Bitwise \"xor\" with the current value.\n\nPerforms a bitwise \"xor\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_xor` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(0b101101);\nassert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);\nassert_eq!(foo.load(Ordering::SeqCst), 0b011110);\n```" ), # [ inline ]# [$stable ]# [$cfg_cas ] pub fn fetch_xor (& self , val : $int_type , order : Ordering )-> $int_type { unsafe { atomic_xor ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Fetches the value, and applies a function to it that returns an optional\nnew value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else\n`Err(previous_value)`.\n\nNote: This may call the function multiple times if the value has been changed from other threads in\nthe meantime, as long as the function returns `Some(_)`, but the function will have been applied\nonly once to the stored value.\n\n`fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.\nThe first describes the required ordering for when the operation finally succeeds while the second\ndescribes the required ordering for loads. These correspond to the success and failure orderings of\n[`" , stringify ! ($atomic_type ), "::compare_exchange`] respectively.\n\nUsing [`Acquire`] as success ordering makes the store part\nof this operation [`Relaxed`], and using [`Release`] makes the final successful load\n[`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]\nand must be equivalent to or weaker than the success ordering.\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```rust\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet x = " , stringify ! ($atomic_type ), "::new(7);\nassert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));\nassert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));\nassert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));\nassert_eq!(x.load(Ordering::SeqCst), 9);\n```" ), # [ inline ]# [ stable ( feature = "no_more_cas" , since = "1.45.0" )]# [$cfg_cas ] pub fn fetch_update < F > (& self , set_order : Ordering , fetch_order : Ordering , mut f : F )-> Result <$int_type , $int_type > where F : FnMut ($int_type )-> Option <$int_type > { let mut prev = self . load ( fetch_order ); while let Some ( next )= f ( prev ){ match self . compare_exchange_weak ( prev , next , set_order , fetch_order ){ x @ Ok (_)=> return x , Err ( next_prev )=> prev = next_prev }} Err ( prev )}} doc_comment ! { concat ! ( "Maximum with the current value.\n\nFinds the maximum of the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_max` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(23);\nassert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);\nassert_eq!(foo.load(Ordering::SeqCst), 42);\n```\n\nIf you want to obtain the maximum value in one step, you can use the following:\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(23);\nlet bar = 42;\nlet max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);\nassert!(max_foo == 42);\n```" ), # [ inline ]# [ stable ( feature = "atomic_min_max" , since = "1.45.0" )]# [$cfg_cas ] pub fn fetch_max (& self , val : $int_type , order : Ordering )-> $int_type { unsafe {$max_fn ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Minimum with the current value.\n\nFinds the minimum of the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_min` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n**Note**: This method is only available on platforms that support atomic\noperations on [`" , $s_int_type , "`](" , $int_ref , ").\n\n# Examples\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(23);\nassert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);\nassert_eq!(foo.load(Ordering::Relaxed), 23);\nassert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);\nassert_eq!(foo.load(Ordering::Relaxed), 22);\n```\n\nIf you want to obtain the minimum value in one step, you can use the following:\n\n```\n" , $extra_feature , "use std::sync::atomic::{" , stringify ! ($atomic_type ), ", Ordering};\n\nlet foo = " , stringify ! ($atomic_type ), "::new(23);\nlet bar = 12;\nlet min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);\nassert_eq!(min_foo, 12);\n```" ), # [ inline ]# [ stable ( feature = "atomic_min_max" , since = "1.45.0" )]# [$cfg_cas ] pub fn fetch_min (& self , val : $int_type , order : Ordering )-> $int_type { unsafe {$min_fn ( self . v . get (), val , order )}}} doc_comment ! { concat ! ( "Returns a mutable pointer to the underlying integer.\n\nDoing non-atomic reads and writes on the resulting integer can be a data race.\nThis method is mostly useful for FFI, where the function signature may use\n`*mut " , stringify ! ($int_type ), "` instead of `&" , stringify ! ($atomic_type ), "`.\n\nReturning an `*mut` pointer from a shared reference to this atomic is safe because the\natomic types work with interior mutability. All modifications of an atomic change the value\nthrough a shared reference, and can do so safely as long as they use atomic operations. Any\nuse of the returned raw pointer requires an `unsafe` block and still has to uphold the same\nrestriction: operations on it must be atomic.\n\n# Examples\n\n```ignore (extern-declaration)\n# fn main() {\n" , $extra_feature , "use std::sync::atomic::" , stringify ! ($atomic_type ), ";\n\nextern {\n fn my_atomic_op(arg: *mut " , stringify ! ($int_type ), ");\n}\n\nlet mut atomic = " , stringify ! ($atomic_type ), "::new(1);\n" , "unsafe {\n my_atomic_op(atomic.as_mut_ptr());\n}\n# }\n```" ), # [ inline ]# [ unstable ( feature = "atomic_mut_ptr" , reason = "recently added" , issue = "66893" )] pub fn as_mut_ptr (& self )-> * mut $int_type { self . v . get ()}}}}}
66macro_rules! __ra_macro_fixture65 {($($target_pointer_width : literal $align : literal )* )=>{$(# [ cfg ( target_has_atomic_load_store = "ptr" )]# [ cfg ( target_pointer_width = $target_pointer_width )] atomic_int ! { cfg ( target_has_atomic = "ptr" ), cfg ( target_has_atomic_equal_alignment = "ptr" ), stable ( feature = "rust1" , since = "1.0.0" ), stable ( feature = "extended_compare_and_swap" , since = "1.10.0" ), stable ( feature = "atomic_debug" , since = "1.3.0" ), stable ( feature = "atomic_access" , since = "1.15.0" ), stable ( feature = "atomic_from" , since = "1.23.0" ), stable ( feature = "atomic_nand" , since = "1.27.0" ), rustc_const_stable ( feature = "const_integer_atomics" , since = "1.34.0" ), stable ( feature = "rust1" , since = "1.0.0" ), "isize" , "../../../std/primitive.isize.html" , "" , atomic_min , atomic_max , $align , "AtomicIsize::new(0)" , isize AtomicIsize ATOMIC_ISIZE_INIT }# [ cfg ( target_has_atomic_load_store = "ptr" )]# [ cfg ( target_pointer_width = $target_pointer_width )] atomic_int ! { cfg ( target_has_atomic = "ptr" ), cfg ( target_has_atomic_equal_alignment = "ptr" ), stable ( feature = "rust1" , since = "1.0.0" ), stable ( feature = "extended_compare_and_swap" , since = "1.10.0" ), stable ( feature = "atomic_debug" , since = "1.3.0" ), stable ( feature = "atomic_access" , since = "1.15.0" ), stable ( feature = "atomic_from" , since = "1.23.0" ), stable ( feature = "atomic_nand" , since = "1.27.0" ), rustc_const_stable ( feature = "const_integer_atomics" , since = "1.34.0" ), stable ( feature = "rust1" , since = "1.0.0" ), "usize" , "../../../std/primitive.usize.html" , "" , atomic_umin , atomic_umax , $align , "AtomicUsize::new(0)" , usize AtomicUsize ATOMIC_USIZE_INIT })* }; }
67macro_rules! __ra_macro_fixture66 {($ty : ident )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Debug for $ty { fn fmt (& self , fmt : & mut Formatter < '_ >)-> Result { float_to_decimal_common ( fmt , self , true , 1 )}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Display for $ty { fn fmt (& self , fmt : & mut Formatter < '_ >)-> Result { float_to_decimal_common ( fmt , self , false , 0 )}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl LowerExp for $ty { fn fmt (& self , fmt : & mut Formatter < '_ >)-> Result { float_to_exponential_common ( fmt , self , false )}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl UpperExp for $ty { fn fmt (& self , fmt : & mut Formatter < '_ >)-> Result { float_to_exponential_common ( fmt , self , true )}}}; }
68macro_rules! __ra_macro_fixture67 {($($t : ident )*)=>($(impl DisplayInt for $t { fn zero ()-> Self { 0 } fn from_u8 ( u : u8 )-> Self { u as Self } fn to_u8 (& self )-> u8 {* self as u8 } fn to_u16 (& self )-> u16 {* self as u16 } fn to_u32 (& self )-> u32 {* self as u32 } fn to_u64 (& self )-> u64 {* self as u64 } fn to_u128 (& self )-> u128 {* self as u128 }})* )}
69macro_rules! __ra_macro_fixture68 {($($t : ident )*)=>($(impl DisplayInt for $t { fn zero ()-> Self { 0 } fn from_u8 ( u : u8 )-> Self { u as Self } fn to_u8 (& self )-> u8 {* self as u8 } fn to_u16 (& self )-> u16 {* self as u16 } fn to_u32 (& self )-> u32 {* self as u32 } fn to_u64 (& self )-> u64 {* self as u64 } fn to_u128 (& self )-> u128 {* self as u128 }})* )}
70macro_rules! __ra_macro_fixture69 {($T : ident , $base : expr , $prefix : expr , $($x : pat =>$conv : expr ),+)=>{ impl GenericRadix for $T { const BASE : u8 = $base ; const PREFIX : & 'static str = $prefix ; fn digit ( x : u8 )-> u8 { match x {$($x =>$conv ,)+ x => panic ! ( "number not in the range 0..={}: {}" , Self :: BASE - 1 , x ), }}}}}
71macro_rules! __ra_macro_fixture70 {($Int : ident , $Uint : ident )=>{ int_base ! { fmt :: Binary for $Int as $Uint -> Binary } int_base ! { fmt :: Octal for $Int as $Uint -> Octal } int_base ! { fmt :: LowerHex for $Int as $Uint -> LowerHex } int_base ! { fmt :: UpperHex for $Int as $Uint -> UpperHex } int_base ! { fmt :: Binary for $Uint as $Uint -> Binary } int_base ! { fmt :: Octal for $Uint as $Uint -> Octal } int_base ! { fmt :: LowerHex for $Uint as $Uint -> LowerHex } int_base ! { fmt :: UpperHex for $Uint as $Uint -> UpperHex }}; }
72macro_rules! __ra_macro_fixture71 {($($T : ident )*)=>{$(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl fmt :: Debug for $T {# [ inline ] fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { if f . debug_lower_hex (){ fmt :: LowerHex :: fmt ( self , f )} else if f . debug_upper_hex (){ fmt :: UpperHex :: fmt ( self , f )} else { fmt :: Display :: fmt ( self , f )}}})*}; }
73macro_rules! __ra_macro_fixture72 {($($t : ident ),* as $u : ident via $conv_fn : ident named $name : ident )=>{ fn $name ( mut n : $u , is_nonnegative : bool , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { let mut buf = [ MaybeUninit ::< u8 >:: uninit (); 39 ]; let mut curr = buf . len () as isize ; let buf_ptr = MaybeUninit :: slice_as_mut_ptr (& mut buf ); let lut_ptr = DEC_DIGITS_LUT . as_ptr (); unsafe { assert ! ( crate :: mem :: size_of ::<$u > ()>= 2 ); while n >= 10000 { let rem = ( n % 10000 ) as isize ; n /= 10000 ; let d1 = ( rem / 100 )<< 1 ; let d2 = ( rem % 100 )<< 1 ; curr -= 4 ; ptr :: copy_nonoverlapping ( lut_ptr . offset ( d1 ), buf_ptr . offset ( curr ), 2 ); ptr :: copy_nonoverlapping ( lut_ptr . offset ( d2 ), buf_ptr . offset ( curr + 2 ), 2 ); } let mut n = n as isize ; if n >= 100 { let d1 = ( n % 100 )<< 1 ; n /= 100 ; curr -= 2 ; ptr :: copy_nonoverlapping ( lut_ptr . offset ( d1 ), buf_ptr . offset ( curr ), 2 ); } if n < 10 { curr -= 1 ; * buf_ptr . offset ( curr )= ( n as u8 )+ b'0' ; } else { let d1 = n << 1 ; curr -= 2 ; ptr :: copy_nonoverlapping ( lut_ptr . offset ( d1 ), buf_ptr . offset ( curr ), 2 ); }} let buf_slice = unsafe { str :: from_utf8_unchecked ( slice :: from_raw_parts ( buf_ptr . offset ( curr ), buf . len ()- curr as usize ))}; f . pad_integral ( is_nonnegative , "" , buf_slice )}$(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl fmt :: Display for $t {# [ allow ( unused_comparisons )] fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { let is_nonnegative = * self >= 0 ; let n = if is_nonnegative { self .$conv_fn ()} else {(! self .$conv_fn ()). wrapping_add ( 1 )}; $name ( n , is_nonnegative , f )}})* }; }
74macro_rules! __ra_macro_fixture73 {($($t : ident ),* as $u : ident via $conv_fn : ident named $name : ident )=>{ fn $name ( mut n : $u , is_nonnegative : bool , upper : bool , f : & mut fmt :: Formatter < '_ > )-> fmt :: Result { let ( mut n , mut exponent , trailing_zeros , added_precision )= { let mut exponent = 0 ; while n % 10 == 0 && n >= 10 { n /= 10 ; exponent += 1 ; } let trailing_zeros = exponent ; let ( added_precision , subtracted_precision )= match f . precision (){ Some ( fmt_prec )=>{ let mut tmp = n ; let mut prec = 0 ; while tmp >= 10 { tmp /= 10 ; prec += 1 ; }( fmt_prec . saturating_sub ( prec ), prec . saturating_sub ( fmt_prec ))} None =>( 0 , 0 )}; for _ in 1 .. subtracted_precision { n /= 10 ; exponent += 1 ; } if subtracted_precision != 0 { let rem = n % 10 ; n /= 10 ; exponent += 1 ; if rem >= 5 { n += 1 ; }}( n , exponent , trailing_zeros , added_precision )}; let mut buf = [ MaybeUninit ::< u8 >:: uninit (); 40 ]; let mut curr = buf . len () as isize ; let buf_ptr = MaybeUninit :: slice_as_mut_ptr (& mut buf ); let lut_ptr = DEC_DIGITS_LUT . as_ptr (); while n >= 100 { let d1 = (( n % 100 ) as isize )<< 1 ; curr -= 2 ; unsafe { ptr :: copy_nonoverlapping ( lut_ptr . offset ( d1 ), buf_ptr . offset ( curr ), 2 ); } n /= 100 ; exponent += 2 ; } let mut n = n as isize ; if n >= 10 { curr -= 1 ; unsafe {* buf_ptr . offset ( curr )= ( n as u8 % 10_u8 )+ b'0' ; } n /= 10 ; exponent += 1 ; } if exponent != trailing_zeros || added_precision != 0 { curr -= 1 ; unsafe {* buf_ptr . offset ( curr )= b'.' ; }} let buf_slice = unsafe { curr -= 1 ; * buf_ptr . offset ( curr )= ( n as u8 )+ b'0' ; let len = buf . len ()- curr as usize ; slice :: from_raw_parts ( buf_ptr . offset ( curr ), len )}; let mut exp_buf = [ MaybeUninit ::< u8 >:: uninit (); 3 ]; let exp_ptr = MaybeUninit :: slice_as_mut_ptr (& mut exp_buf ); let exp_slice = unsafe {* exp_ptr . offset ( 0 )= if upper { b'E' } else { b'e' }; let len = if exponent < 10 {* exp_ptr . offset ( 1 )= ( exponent as u8 )+ b'0' ; 2 } else { let off = exponent << 1 ; ptr :: copy_nonoverlapping ( lut_ptr . offset ( off ), exp_ptr . offset ( 1 ), 2 ); 3 }; slice :: from_raw_parts ( exp_ptr , len )}; let parts = & [ flt2dec :: Part :: Copy ( buf_slice ), flt2dec :: Part :: Zero ( added_precision ), flt2dec :: Part :: Copy ( exp_slice )]; let sign = if ! is_nonnegative { "-" } else if f . sign_plus (){ "+" } else { "" }; let formatted = flt2dec :: Formatted { sign , parts }; f . pad_formatted_parts (& formatted )}$(# [ stable ( feature = "integer_exp_format" , since = "1.42.0" )] impl fmt :: LowerExp for $t {# [ allow ( unused_comparisons )] fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { let is_nonnegative = * self >= 0 ; let n = if is_nonnegative { self .$conv_fn ()} else {(! self .$conv_fn ()). wrapping_add ( 1 )}; $name ( n , is_nonnegative , false , f )}})* $(# [ stable ( feature = "integer_exp_format" , since = "1.42.0" )] impl fmt :: UpperExp for $t {# [ allow ( unused_comparisons )] fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { let is_nonnegative = * self >= 0 ; let n = if is_nonnegative { self .$conv_fn ()} else {(! self .$conv_fn ()). wrapping_add ( 1 )}; $name ( n , is_nonnegative , true , f )}})* }; }
75macro_rules! __ra_macro_fixture74 {($($tr : ident ),*)=>{$(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized + $tr > $tr for & T { fn fmt (& self , f : & mut Formatter < '_ >)-> Result {$tr :: fmt (&** self , f )}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T : ? Sized + $tr > $tr for & mut T { fn fmt (& self , f : & mut Formatter < '_ >)-> Result {$tr :: fmt (&** self , f )}})* }}
76macro_rules! __ra_macro_fixture75 {()=>(); ($($name : ident ,)+ )=>(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl <$($name : Debug ),+> Debug for ($($name ,)+) where last_type ! ($($name ,)+): ? Sized {# [ allow ( non_snake_case , unused_assignments )] fn fmt (& self , f : & mut Formatter < '_ >)-> Result { let mut builder = f . debug_tuple ( "" ); let ($(ref $name ,)+)= * self ; $(builder . field (&$name ); )+ builder . finish ()}} peel ! {$($name ,)+ })}
77macro_rules! __ra_macro_fixture76 {($(($ty : ident , $meth : ident ),)*)=>{$(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Hash for $ty { fn hash < H : Hasher > (& self , state : & mut H ){ state .$meth (* self )} fn hash_slice < H : Hasher > ( data : & [$ty ], state : & mut H ){ let newlen = data . len ()* mem :: size_of ::<$ty > (); let ptr = data . as_ptr () as * const u8 ; state . write ( unsafe { slice :: from_raw_parts ( ptr , newlen )})}})*}}
78macro_rules! __ra_macro_fixture77 {()=>(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Hash for (){ fn hash < H : Hasher > (& self , _state : & mut H ){}}); ($($name : ident )+)=>(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl <$($name : Hash ),+> Hash for ($($name ,)+) where last_type ! ($($name ,)+): ? Sized {# [ allow ( non_snake_case )] fn hash < S : Hasher > (& self , state : & mut S ){ let ($(ref $name ,)+)= * self ; $($name . hash ( state );)+ }}); }
79macro_rules! __ra_macro_fixture78 {($([$($p : tt )*]$t : ty ,)*)=>{$(impl <$($p )*> AlwaysApplicableOrd for $t {})* }}
80macro_rules! __ra_macro_fixture79 {($traitname : ident , $($ty : ty )*)=>{$(impl $traitname <$ty > for $ty {})* }}
81macro_rules! __ra_macro_fixture80 {( struct $name : ident -> $ptr : ty , $elem : ty , $raw_mut : tt , {$($mut_ : tt )?}, {$($extra : tt )*})=>{ macro_rules ! next_unchecked {($self : ident )=>{& $($mut_ )? *$self . post_inc_start ( 1 )}} macro_rules ! next_back_unchecked {($self : ident )=>{& $($mut_ )? *$self . pre_dec_end ( 1 )}} macro_rules ! zst_shrink {($self : ident , $n : ident )=>{$self . end = ($self . end as * $raw_mut u8 ). wrapping_offset (-$n ) as * $raw_mut T ; }} impl < 'a , T > $name < 'a , T > {# [ inline ( always )] fn make_slice (& self )-> & 'a [ T ]{ unsafe { from_raw_parts ( self . ptr . as_ptr (), len ! ( self ))}}# [ inline ( always )] unsafe fn post_inc_start (& mut self , offset : isize )-> * $raw_mut T { if mem :: size_of ::< T > ()== 0 { zst_shrink ! ( self , offset ); self . ptr . as_ptr ()} else { let old = self . ptr . as_ptr (); self . ptr = unsafe { NonNull :: new_unchecked ( self . ptr . as_ptr (). offset ( offset ))}; old }}# [ inline ( always )] unsafe fn pre_dec_end (& mut self , offset : isize )-> * $raw_mut T { if mem :: size_of ::< T > ()== 0 { zst_shrink ! ( self , offset ); self . ptr . as_ptr ()} else { self . end = unsafe { self . end . offset (- offset )}; self . end }}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < T > ExactSizeIterator for $name < '_ , T > {# [ inline ( always )] fn len (& self )-> usize { len ! ( self )}# [ inline ( always )] fn is_empty (& self )-> bool { is_empty ! ( self )}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < 'a , T > Iterator for $name < 'a , T > { type Item = $elem ; # [ inline ] fn next (& mut self )-> Option <$elem > { unsafe { assume (! self . ptr . as_ptr (). is_null ()); if mem :: size_of ::< T > ()!= 0 { assume (! self . end . is_null ()); } if is_empty ! ( self ){ None } else { Some ( next_unchecked ! ( self ))}}}# [ inline ] fn size_hint (& self )-> ( usize , Option < usize >){ let exact = len ! ( self ); ( exact , Some ( exact ))}# [ inline ] fn count ( self )-> usize { len ! ( self )}# [ inline ] fn nth (& mut self , n : usize )-> Option <$elem > { if n >= len ! ( self ){ if mem :: size_of ::< T > ()== 0 { self . end = self . ptr . as_ptr (); } else { unsafe { self . ptr = NonNull :: new_unchecked ( self . end as * mut T ); }} return None ; } unsafe { self . post_inc_start ( n as isize ); Some ( next_unchecked ! ( self ))}}# [ inline ] fn last ( mut self )-> Option <$elem > { self . next_back ()}# [ inline ] fn for_each < F > ( mut self , mut f : F ) where Self : Sized , F : FnMut ( Self :: Item ), { while let Some ( x )= self . next (){ f ( x ); }}# [ inline ] fn all < F > (& mut self , mut f : F )-> bool where Self : Sized , F : FnMut ( Self :: Item )-> bool , { while let Some ( x )= self . next (){ if ! f ( x ){ return false ; }} true }# [ inline ] fn any < F > (& mut self , mut f : F )-> bool where Self : Sized , F : FnMut ( Self :: Item )-> bool , { while let Some ( x )= self . next (){ if f ( x ){ return true ; }} false }# [ inline ] fn find < P > (& mut self , mut predicate : P )-> Option < Self :: Item > where Self : Sized , P : FnMut (& Self :: Item )-> bool , { while let Some ( x )= self . next (){ if predicate (& x ){ return Some ( x ); }} None }# [ inline ] fn find_map < B , F > (& mut self , mut f : F )-> Option < B > where Self : Sized , F : FnMut ( Self :: Item )-> Option < B >, { while let Some ( x )= self . next (){ if let Some ( y )= f ( x ){ return Some ( y ); }} None }# [ inline ]# [ rustc_inherit_overflow_checks ] fn position < P > (& mut self , mut predicate : P )-> Option < usize > where Self : Sized , P : FnMut ( Self :: Item )-> bool , { let n = len ! ( self ); let mut i = 0 ; while let Some ( x )= self . next (){ if predicate ( x ){ unsafe { assume ( i < n )}; return Some ( i ); } i += 1 ; } None }# [ inline ] fn rposition < P > (& mut self , mut predicate : P )-> Option < usize > where P : FnMut ( Self :: Item )-> bool , Self : Sized + ExactSizeIterator + DoubleEndedIterator { let n = len ! ( self ); let mut i = n ; while let Some ( x )= self . next_back (){ i -= 1 ; if predicate ( x ){ unsafe { assume ( i < n )}; return Some ( i ); }} None }# [ doc ( hidden )] unsafe fn __iterator_get_unchecked (& mut self , idx : usize )-> Self :: Item { unsafe {& $($mut_ )? * self . ptr . as_ptr (). add ( idx )}}$($extra )* }# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < 'a , T > DoubleEndedIterator for $name < 'a , T > {# [ inline ] fn next_back (& mut self )-> Option <$elem > { unsafe { assume (! self . ptr . as_ptr (). is_null ()); if mem :: size_of ::< T > ()!= 0 { assume (! self . end . is_null ()); } if is_empty ! ( self ){ None } else { Some ( next_back_unchecked ! ( self ))}}}# [ inline ] fn nth_back (& mut self , n : usize )-> Option <$elem > { if n >= len ! ( self ){ self . end = self . ptr . as_ptr (); return None ; } unsafe { self . pre_dec_end ( n as isize ); Some ( next_back_unchecked ! ( self ))}}}# [ stable ( feature = "fused" , since = "1.26.0" )] impl < T > FusedIterator for $name < '_ , T > {}# [ unstable ( feature = "trusted_len" , issue = "37572" )] unsafe impl < T > TrustedLen for $name < '_ , T > {}}}
82macro_rules! __ra_macro_fixture81 {($name : ident : $elem : ident , $iter_of : ty )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl < 'a , $elem , P > Iterator for $name < 'a , $elem , P > where P : FnMut (& T )-> bool , { type Item = $iter_of ; # [ inline ] fn next (& mut self )-> Option <$iter_of > { self . inner . next ()}# [ inline ] fn size_hint (& self )-> ( usize , Option < usize >){ self . inner . size_hint ()}}# [ stable ( feature = "fused" , since = "1.26.0" )] impl < 'a , $elem , P > FusedIterator for $name < 'a , $elem , P > where P : FnMut (& T )-> bool {}}; }
83macro_rules! __ra_macro_fixture82 {( clone $t : ident with |$s : ident | $e : expr )=>{ impl < 'a , P > Clone for $t < 'a , P > where P : Pattern < 'a , Searcher : Clone >, { fn clone (& self )-> Self { let $s = self ; $e }}}; }
84macro_rules! __ra_macro_fixture83 {{ forward : $(# [$forward_iterator_attribute : meta ])* struct $forward_iterator : ident ; reverse : $(# [$reverse_iterator_attribute : meta ])* struct $reverse_iterator : ident ; stability : $(# [$common_stability_attribute : meta ])* internal : $internal_iterator : ident yielding ($iterty : ty ); delegate $($t : tt )* }=>{$(# [$forward_iterator_attribute ])* $(# [$common_stability_attribute ])* pub struct $forward_iterator < 'a , P : Pattern < 'a >> ( pub ( super )$internal_iterator < 'a , P >); $(# [$common_stability_attribute ])* impl < 'a , P > fmt :: Debug for $forward_iterator < 'a , P > where P : Pattern < 'a , Searcher : fmt :: Debug >, { fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { f . debug_tuple ( stringify ! ($forward_iterator )). field (& self . 0 ). finish ()}}$(# [$common_stability_attribute ])* impl < 'a , P : Pattern < 'a >> Iterator for $forward_iterator < 'a , P > { type Item = $iterty ; # [ inline ] fn next (& mut self )-> Option <$iterty > { self . 0 . next ()}}$(# [$common_stability_attribute ])* impl < 'a , P > Clone for $forward_iterator < 'a , P > where P : Pattern < 'a , Searcher : Clone >, { fn clone (& self )-> Self {$forward_iterator ( self . 0 . clone ())}}$(# [$reverse_iterator_attribute ])* $(# [$common_stability_attribute ])* pub struct $reverse_iterator < 'a , P : Pattern < 'a >> ( pub ( super )$internal_iterator < 'a , P >); $(# [$common_stability_attribute ])* impl < 'a , P > fmt :: Debug for $reverse_iterator < 'a , P > where P : Pattern < 'a , Searcher : fmt :: Debug >, { fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { f . debug_tuple ( stringify ! ($reverse_iterator )). field (& self . 0 ). finish ()}}$(# [$common_stability_attribute ])* impl < 'a , P > Iterator for $reverse_iterator < 'a , P > where P : Pattern < 'a , Searcher : ReverseSearcher < 'a >>, { type Item = $iterty ; # [ inline ] fn next (& mut self )-> Option <$iterty > { self . 0 . next_back ()}}$(# [$common_stability_attribute ])* impl < 'a , P > Clone for $reverse_iterator < 'a , P > where P : Pattern < 'a , Searcher : Clone >, { fn clone (& self )-> Self {$reverse_iterator ( self . 0 . clone ())}}# [ stable ( feature = "fused" , since = "1.26.0" )] impl < 'a , P : Pattern < 'a >> FusedIterator for $forward_iterator < 'a , P > {}# [ stable ( feature = "fused" , since = "1.26.0" )] impl < 'a , P > FusedIterator for $reverse_iterator < 'a , P > where P : Pattern < 'a , Searcher : ReverseSearcher < 'a >>, {} generate_pattern_iterators ! ($($t )* with $(# [$common_stability_attribute ])*, $forward_iterator , $reverse_iterator , $iterty ); }; { double ended ; with $(# [$common_stability_attribute : meta ])*, $forward_iterator : ident , $reverse_iterator : ident , $iterty : ty }=>{$(# [$common_stability_attribute ])* impl < 'a , P > DoubleEndedIterator for $forward_iterator < 'a , P > where P : Pattern < 'a , Searcher : DoubleEndedSearcher < 'a >>, {# [ inline ] fn next_back (& mut self )-> Option <$iterty > { self . 0 . next_back ()}}$(# [$common_stability_attribute ])* impl < 'a , P > DoubleEndedIterator for $reverse_iterator < 'a , P > where P : Pattern < 'a , Searcher : DoubleEndedSearcher < 'a >>, {# [ inline ] fn next_back (& mut self )-> Option <$iterty > { self . 0 . next ()}}}; { single ended ; with $(# [$common_stability_attribute : meta ])*, $forward_iterator : ident , $reverse_iterator : ident , $iterty : ty }=>{}}
85macro_rules! __ra_macro_fixture84 {($($Name : ident ),+)=>{$(# [ stable ( feature = "str_escape" , since = "1.34.0" )] impl < 'a > fmt :: Display for $Name < 'a > { fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { self . clone (). try_for_each (| c | f . write_char ( c ))}}# [ stable ( feature = "str_escape" , since = "1.34.0" )] impl < 'a > Iterator for $Name < 'a > { type Item = char ; # [ inline ] fn next (& mut self )-> Option < char > { self . inner . next ()}# [ inline ] fn size_hint (& self )-> ( usize , Option < usize >){ self . inner . size_hint ()}# [ inline ] fn try_fold < Acc , Fold , R > (& mut self , init : Acc , fold : Fold )-> R where Self : Sized , Fold : FnMut ( Acc , Self :: Item )-> R , R : Try < Ok = Acc >{ self . inner . try_fold ( init , fold )}# [ inline ] fn fold < Acc , Fold > ( self , init : Acc , fold : Fold )-> Acc where Fold : FnMut ( Acc , Self :: Item )-> Acc , { self . inner . fold ( init , fold )}}# [ stable ( feature = "str_escape" , since = "1.34.0" )] impl < 'a > FusedIterator for $Name < 'a > {})+}}
86macro_rules! __ra_macro_fixture85 {($($(# [$attr : meta ])* struct $Name : ident impl $(<$($lifetime : lifetime ),+> )? Fn = |$($arg : ident : $ArgTy : ty ),*| -> $ReturnTy : ty $body : block ; )+)=>{$($(# [$attr ])* struct $Name ; impl $(<$($lifetime ),+> )? Fn < ($($ArgTy , )*)> for $Name {# [ inline ] extern "rust-call" fn call (& self , ($($arg , )*): ($($ArgTy , )*))-> $ReturnTy {$body }} impl $(<$($lifetime ),+> )? FnMut < ($($ArgTy , )*)> for $Name {# [ inline ] extern "rust-call" fn call_mut (& mut self , ($($arg , )*): ($($ArgTy , )*))-> $ReturnTy { Fn :: call (&* self , ($($arg , )*))}} impl $(<$($lifetime ),+> )? FnOnce < ($($ArgTy , )*)> for $Name { type Output = $ReturnTy ; # [ inline ] extern "rust-call" fn call_once ( self , ($($arg , )*): ($($ArgTy , )*))-> $ReturnTy { Fn :: call (& self , ($($arg , )*))}})+ }}
87macro_rules! __ra_macro_fixture86 {($($Tuple : ident {$(($idx : tt )-> $T : ident )+ })+)=>{$(# [ stable ( feature = "rust1" , since = "1.0.0" )] impl <$($T : PartialEq ),+> PartialEq for ($($T ,)+) where last_type ! ($($T ,)+): ? Sized {# [ inline ] fn eq (& self , other : & ($($T ,)+))-> bool {$(self .$idx == other .$idx )&&+ }# [ inline ] fn ne (& self , other : & ($($T ,)+))-> bool {$(self .$idx != other .$idx )||+ }}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl <$($T : Eq ),+> Eq for ($($T ,)+) where last_type ! ($($T ,)+): ? Sized {}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl <$($T : PartialOrd + PartialEq ),+> PartialOrd for ($($T ,)+) where last_type ! ($($T ,)+): ? Sized {# [ inline ] fn partial_cmp (& self , other : & ($($T ,)+))-> Option < Ordering > { lexical_partial_cmp ! ($(self .$idx , other .$idx ),+)}# [ inline ] fn lt (& self , other : & ($($T ,)+))-> bool { lexical_ord ! ( lt , $(self .$idx , other .$idx ),+)}# [ inline ] fn le (& self , other : & ($($T ,)+))-> bool { lexical_ord ! ( le , $(self .$idx , other .$idx ),+)}# [ inline ] fn ge (& self , other : & ($($T ,)+))-> bool { lexical_ord ! ( ge , $(self .$idx , other .$idx ),+)}# [ inline ] fn gt (& self , other : & ($($T ,)+))-> bool { lexical_ord ! ( gt , $(self .$idx , other .$idx ),+)}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl <$($T : Ord ),+> Ord for ($($T ,)+) where last_type ! ($($T ,)+): ? Sized {# [ inline ] fn cmp (& self , other : & ($($T ,)+))-> Ordering { lexical_cmp ! ($(self .$idx , other .$idx ),+)}}# [ stable ( feature = "rust1" , since = "1.0.0" )] impl <$($T : Default ),+> Default for ($($T ,)+){# [ inline ] fn default ()-> ($($T ,)+){($({let x : $T = Default :: default (); x },)+)}})+ }}
88macro_rules! __ra_macro_fixture87 {($x : expr , $($tt : tt )*)=>{# [ doc = $x ]$($tt )* }; }
89macro_rules! __ra_macro_fixture88 {($x : expr , $($tt : tt )*)=>{# [ doc = $x ]$($tt )* }; }
90macro_rules! __ra_macro_fixture89 {(# [$stability : meta ]($($Trait : ident ),+ ) for $Ty : ident )=>{$(# [$stability ] impl fmt ::$Trait for $Ty {# [ inline ] fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { self . get (). fmt ( f )}})+ }}
91macro_rules! __ra_macro_fixture90 {($t : ident , $f : ident )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Shl <$f > for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn shl ( self , other : $f )-> Wrapping <$t > { Wrapping ( self . 0 . wrapping_shl (( other & self :: shift_max ::$t as $f ) as u32 ))}} forward_ref_binop ! { impl Shl , shl for Wrapping <$t >, $f , # [ stable ( feature = "wrapping_ref_ops" , since = "1.39.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl ShlAssign <$f > for Wrapping <$t > {# [ inline ] fn shl_assign (& mut self , other : $f ){* self = * self << other ; }} forward_ref_op_assign ! { impl ShlAssign , shl_assign for Wrapping <$t >, $f }# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Shr <$f > for Wrapping <$t > { type Output = Wrapping <$t >; # [ inline ] fn shr ( self , other : $f )-> Wrapping <$t > { Wrapping ( self . 0 . wrapping_shr (( other & self :: shift_max ::$t as $f ) as u32 ))}} forward_ref_binop ! { impl Shr , shr for Wrapping <$t >, $f , # [ stable ( feature = "wrapping_ref_ops" , since = "1.39.0" )]}# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl ShrAssign <$f > for Wrapping <$t > {# [ inline ] fn shr_assign (& mut self , other : $f ){* self = * self >> other ; }} forward_ref_op_assign ! { impl ShrAssign , shr_assign for Wrapping <$t >, $f }}; }
92macro_rules! __ra_macro_fixture91 {( impl $imp : ident , $method : ident for $t : ty , $u : ty )=>{ forward_ref_binop ! ( impl $imp , $method for $t , $u , # [ stable ( feature = "rust1" , since = "1.0.0" )]); }; ( impl $imp : ident , $method : ident for $t : ty , $u : ty , # [$attr : meta ])=>{# [$attr ] impl < 'a > $imp <$u > for & 'a $t { type Output = <$t as $imp <$u >>:: Output ; # [ inline ] fn $method ( self , other : $u )-> <$t as $imp <$u >>:: Output {$imp ::$method (* self , other )}}# [$attr ] impl $imp <&$u > for $t { type Output = <$t as $imp <$u >>:: Output ; # [ inline ] fn $method ( self , other : &$u )-> <$t as $imp <$u >>:: Output {$imp ::$method ( self , * other )}}# [$attr ] impl $imp <&$u > for &$t { type Output = <$t as $imp <$u >>:: Output ; # [ inline ] fn $method ( self , other : &$u )-> <$t as $imp <$u >>:: Output {$imp ::$method (* self , * other )}}}}
93macro_rules! __ra_macro_fixture92 {( impl $imp : ident , $method : ident for $t : ty , $u : ty )=>{ forward_ref_op_assign ! ( impl $imp , $method for $t , $u , # [ stable ( feature = "op_assign_builtins_by_ref" , since = "1.22.0" )]); }; ( impl $imp : ident , $method : ident for $t : ty , $u : ty , # [$attr : meta ])=>{# [$attr ] impl $imp <&$u > for $t {# [ inline ] fn $method (& mut self , other : &$u ){$imp ::$method ( self , * other ); }}}}
94macro_rules! __ra_macro_fixture93 {( impl $imp : ident , $method : ident for $t : ty )=>{ forward_ref_unop ! ( impl $imp , $method for $t , # [ stable ( feature = "rust1" , since = "1.0.0" )]); }; ( impl $imp : ident , $method : ident for $t : ty , # [$attr : meta ])=>{# [$attr ] impl $imp for &$t { type Output = <$t as $imp >:: Output ; # [ inline ] fn $method ( self )-> <$t as $imp >:: Output {$imp ::$method (* self )}}}}
95macro_rules! __ra_macro_fixture94 {($FnTy : ty , $($Arg : ident ),*)=>{# [ stable ( feature = "fnptr_impls" , since = "1.4.0" )] impl < Ret , $($Arg ),*> PartialEq for $FnTy {# [ inline ] fn eq (& self , other : & Self )-> bool {* self as usize == * other as usize }}# [ stable ( feature = "fnptr_impls" , since = "1.4.0" )] impl < Ret , $($Arg ),*> Eq for $FnTy {}# [ stable ( feature = "fnptr_impls" , since = "1.4.0" )] impl < Ret , $($Arg ),*> PartialOrd for $FnTy {# [ inline ] fn partial_cmp (& self , other : & Self )-> Option < Ordering > {(* self as usize ). partial_cmp (& (* other as usize ))}}# [ stable ( feature = "fnptr_impls" , since = "1.4.0" )] impl < Ret , $($Arg ),*> Ord for $FnTy {# [ inline ] fn cmp (& self , other : & Self )-> Ordering {(* self as usize ). cmp (& (* other as usize ))}}# [ stable ( feature = "fnptr_impls" , since = "1.4.0" )] impl < Ret , $($Arg ),*> hash :: Hash for $FnTy { fn hash < HH : hash :: Hasher > (& self , state : & mut HH ){ state . write_usize (* self as usize )}}# [ stable ( feature = "fnptr_impls" , since = "1.4.0" )] impl < Ret , $($Arg ),*> fmt :: Pointer for $FnTy { fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { fmt :: Pointer :: fmt (& (* self as usize as * const ()), f )}}# [ stable ( feature = "fnptr_impls" , since = "1.4.0" )] impl < Ret , $($Arg ),*> fmt :: Debug for $FnTy { fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result { fmt :: Pointer :: fmt (& (* self as usize as * const ()), f )}}}}
96macro_rules! __ra_macro_fixture95 {($t : ty , $f : ty )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Shl <$f > for $t { type Output = $t ; # [ inline ]# [ rustc_inherit_overflow_checks ] fn shl ( self , other : $f )-> $t { self << other }} forward_ref_binop ! { impl Shl , shl for $t , $f }}; }
97macro_rules! __ra_macro_fixture96 {($t : ty , $f : ty )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl Shr <$f > for $t { type Output = $t ; # [ inline ]# [ rustc_inherit_overflow_checks ] fn shr ( self , other : $f )-> $t { self >> other }} forward_ref_binop ! { impl Shr , shr for $t , $f }}; }
98macro_rules! __ra_macro_fixture97 {($t : ty , $f : ty )=>{# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl ShlAssign <$f > for $t {# [ inline ]# [ rustc_inherit_overflow_checks ] fn shl_assign (& mut self , other : $f ){* self <<= other }} forward_ref_op_assign ! { impl ShlAssign , shl_assign for $t , $f }}; }
99macro_rules! __ra_macro_fixture98 {($t : ty , $f : ty )=>{# [ stable ( feature = "op_assign_traits" , since = "1.8.0" )] impl ShrAssign <$f > for $t {# [ inline ]# [ rustc_inherit_overflow_checks ] fn shr_assign (& mut self , other : $f ){* self >>= other }} forward_ref_op_assign ! { impl ShrAssign , shr_assign for $t , $f }}; }
100macro_rules! __ra_macro_fixture99 {( fmt ::$Trait : ident for $T : ident as $U : ident -> $Radix : ident )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )] impl fmt ::$Trait for $T { fn fmt (& self , f : & mut fmt :: Formatter < '_ >)-> fmt :: Result {$Radix . fmt_int (* self as $U , f )}}}; }
101macro_rules! __ra_macro_fixture100 {($name : ident , $($other : ident ,)*)=>( tuple ! {$($other ,)* })}
102macro_rules! __ra_macro_fixture101 {{ unsafe fn $name : ident : $adjacent_kv : ident }=>{# [ doc = " Given a leaf edge handle into an owned tree, returns a handle to the next KV," ]# [ doc = " while deallocating any node left behind yet leaving the corresponding edge" ]# [ doc = " in its parent node dangling." ]# [ doc = "" ]# [ doc = " # Safety" ]# [ doc = " - The leaf edge must not be the last one in the direction travelled." ]# [ doc = " - The node carrying the next KV returned must not have been deallocated by a" ]# [ doc = " previous call on any handle obtained for this tree." ] unsafe fn $name < K , V > ( leaf_edge : Handle < NodeRef < marker :: Owned , K , V , marker :: Leaf >, marker :: Edge >, )-> Handle < NodeRef < marker :: Owned , K , V , marker :: LeafOrInternal >, marker :: KV > { let mut edge = leaf_edge . forget_node_type (); loop { edge = match edge .$adjacent_kv (){ Ok ( internal_kv )=> return internal_kv , Err ( last_edge )=>{ unsafe { let parent_edge = last_edge . into_node (). deallocate_and_ascend (); unwrap_unchecked ( parent_edge ). forget_node_type ()}}}}}}; }
103macro_rules! __ra_macro_fixture102 {([$($vars : tt )*]$lhs : ty , $rhs : ty , $($constraints : tt )*)=>{# [ stable ( feature = "vec_deque_partial_eq_slice" , since = "1.17.0" )] impl < A , B , $($vars )*> PartialEq <$rhs > for $lhs where A : PartialEq < B >, $($constraints )* { fn eq (& self , other : &$rhs )-> bool { if self . len ()!= other . len (){ return false ; } let ( sa , sb )= self . as_slices (); let ( oa , ob )= other [..]. split_at ( sa . len ()); sa == oa && sb == ob }}}}
104macro_rules! __ra_macro_fixture103 {($lhs : ty , $rhs : ty )=>{# [ stable ( feature = "rust1" , since = "1.0.0" )]# [ allow ( unused_lifetimes )] impl < 'a , 'b > PartialEq <$rhs > for $lhs {# [ inline ] fn eq (& self , other : &$rhs )-> bool { PartialEq :: eq (& self [..], & other [..])}# [ inline ] fn ne (& self , other : &$rhs )-> bool { PartialEq :: ne (& self [..], & other [..])}}# [ stable ( feature = "rust1" , since = "1.0.0" )]# [ allow ( unused_lifetimes )] impl < 'a , 'b > PartialEq <$lhs > for $rhs {# [ inline ] fn eq (& self , other : &$lhs )-> bool { PartialEq :: eq (& self [..], & other [..])}# [ inline ] fn ne (& self , other : &$lhs )-> bool { PartialEq :: ne (& self [..], & other [..])}}}; }
105macro_rules! __ra_macro_fixture104 {($t : ty , $is_zero : expr )=>{ unsafe impl IsZero for $t {# [ inline ] fn is_zero (& self )-> bool {$is_zero (* self )}}}; }
106macro_rules! __ra_macro_fixture105 {([$($vars : tt )*]$lhs : ty , $rhs : ty $(where $ty : ty : $bound : ident )?, # [$stability : meta ])=>{# [$stability ] impl < A , B , $($vars )*> PartialEq <$rhs > for $lhs where A : PartialEq < B >, $($ty : $bound )? {# [ inline ] fn eq (& self , other : &$rhs )-> bool { self [..]== other [..]}# [ inline ] fn ne (& self , other : &$rhs )-> bool { self [..]!= other [..]}}}}
107macro_rules! __ra_macro_fixture106 {('owned : $($oty : ident ,)* 'interned : $($ity : ident ,)* )=>{# [ repr ( C )]# [ allow ( non_snake_case )] pub struct HandleCounters {$($oty : AtomicUsize ,)* $($ity : AtomicUsize ,)* } impl HandleCounters { extern "C" fn get ()-> & 'static Self { static COUNTERS : HandleCounters = HandleCounters {$($oty : AtomicUsize :: new ( 1 ),)* $($ity : AtomicUsize :: new ( 1 ),)* }; & COUNTERS }}# [ repr ( C )]# [ allow ( non_snake_case )] pub ( super ) struct HandleStore < S : server :: Types > {$($oty : handle :: OwnedStore < S ::$oty >,)* $($ity : handle :: InternedStore < S ::$ity >,)* } impl < S : server :: Types > HandleStore < S > { pub ( super ) fn new ( handle_counters : & 'static HandleCounters )-> Self { HandleStore {$($oty : handle :: OwnedStore :: new (& handle_counters .$oty ),)* $($ity : handle :: InternedStore :: new (& handle_counters .$ity ),)* }}}$(# [ repr ( C )] pub ( crate ) struct $oty ( handle :: Handle ); impl ! Send for $oty {} impl ! Sync for $oty {} impl Drop for $oty { fn drop (& mut self ){$oty ( self . 0 ). drop (); }} impl < S > Encode < S > for $oty { fn encode ( self , w : & mut Writer , s : & mut S ){ let handle = self . 0 ; mem :: forget ( self ); handle . encode ( w , s ); }} impl < S : server :: Types > DecodeMut < '_ , '_ , HandleStore < server :: MarkedTypes < S >>> for Marked < S ::$oty , $oty > { fn decode ( r : & mut Reader < '_ >, s : & mut HandleStore < server :: MarkedTypes < S >>)-> Self { s .$oty . take ( handle :: Handle :: decode ( r , & mut ()))}} impl < S > Encode < S > for &$oty { fn encode ( self , w : & mut Writer , s : & mut S ){ self . 0 . encode ( w , s ); }} impl < S : server :: Types > Decode < '_ , 's , HandleStore < server :: MarkedTypes < S >>> for & 's Marked < S ::$oty , $oty > { fn decode ( r : & mut Reader < '_ >, s : & 's HandleStore < server :: MarkedTypes < S >>)-> Self {& s .$oty [ handle :: Handle :: decode ( r , & mut ())]}} impl < S > Encode < S > for & mut $oty { fn encode ( self , w : & mut Writer , s : & mut S ){ self . 0 . encode ( w , s ); }} impl < S : server :: Types > DecodeMut < '_ , 's , HandleStore < server :: MarkedTypes < S >>> for & 's mut Marked < S ::$oty , $oty > { fn decode ( r : & mut Reader < '_ >, s : & 's mut HandleStore < server :: MarkedTypes < S >> )-> Self {& mut s .$oty [ handle :: Handle :: decode ( r , & mut ())]}} impl < S : server :: Types > Encode < HandleStore < server :: MarkedTypes < S >>> for Marked < S ::$oty , $oty > { fn encode ( self , w : & mut Writer , s : & mut HandleStore < server :: MarkedTypes < S >>){ s .$oty . alloc ( self ). encode ( w , s ); }} impl < S > DecodeMut < '_ , '_ , S > for $oty { fn decode ( r : & mut Reader < '_ >, s : & mut S )-> Self {$oty ( handle :: Handle :: decode ( r , s ))}})* $(# [ repr ( C )]# [ derive ( Copy , Clone , PartialEq , Eq , Hash )] pub ( crate ) struct $ity ( handle :: Handle ); impl ! Send for $ity {} impl ! Sync for $ity {} impl < S > Encode < S > for $ity { fn encode ( self , w : & mut Writer , s : & mut S ){ self . 0 . encode ( w , s ); }} impl < S : server :: Types > DecodeMut < '_ , '_ , HandleStore < server :: MarkedTypes < S >>> for Marked < S ::$ity , $ity > { fn decode ( r : & mut Reader < '_ >, s : & mut HandleStore < server :: MarkedTypes < S >>)-> Self { s .$ity . copy ( handle :: Handle :: decode ( r , & mut ()))}} impl < S : server :: Types > Encode < HandleStore < server :: MarkedTypes < S >>> for Marked < S ::$ity , $ity > { fn encode ( self , w : & mut Writer , s : & mut HandleStore < server :: MarkedTypes < S >>){ s .$ity . alloc ( self ). encode ( w , s ); }} impl < S > DecodeMut < '_ , '_ , S > for $ity { fn decode ( r : & mut Reader < '_ >, s : & mut S )-> Self {$ity ( handle :: Handle :: decode ( r , s ))}})* }}
108macro_rules! __ra_macro_fixture107 {($S : ident , $self : ident , $m : ident )=>{$m ! { FreeFunctions { fn drop ($self : $S :: FreeFunctions ); fn track_env_var ( var : & str , value : Option <& str >); }, TokenStream { fn drop ($self : $S :: TokenStream ); fn clone ($self : &$S :: TokenStream )-> $S :: TokenStream ; fn new ()-> $S :: TokenStream ; fn is_empty ($self : &$S :: TokenStream )-> bool ; fn from_str ( src : & str )-> $S :: TokenStream ; fn to_string ($self : &$S :: TokenStream )-> String ; fn from_token_tree ( tree : TokenTree <$S :: Group , $S :: Punct , $S :: Ident , $S :: Literal >, )-> $S :: TokenStream ; fn into_iter ($self : $S :: TokenStream )-> $S :: TokenStreamIter ; }, TokenStreamBuilder { fn drop ($self : $S :: TokenStreamBuilder ); fn new ()-> $S :: TokenStreamBuilder ; fn push ($self : & mut $S :: TokenStreamBuilder , stream : $S :: TokenStream ); fn build ($self : $S :: TokenStreamBuilder )-> $S :: TokenStream ; }, TokenStreamIter { fn drop ($self : $S :: TokenStreamIter ); fn clone ($self : &$S :: TokenStreamIter )-> $S :: TokenStreamIter ; fn next ($self : & mut $S :: TokenStreamIter , )-> Option < TokenTree <$S :: Group , $S :: Punct , $S :: Ident , $S :: Literal >>; }, Group { fn drop ($self : $S :: Group ); fn clone ($self : &$S :: Group )-> $S :: Group ; fn new ( delimiter : Delimiter , stream : $S :: TokenStream )-> $S :: Group ; fn delimiter ($self : &$S :: Group )-> Delimiter ; fn stream ($self : &$S :: Group )-> $S :: TokenStream ; fn span ($self : &$S :: Group )-> $S :: Span ; fn span_open ($self : &$S :: Group )-> $S :: Span ; fn span_close ($self : &$S :: Group )-> $S :: Span ; fn set_span ($self : & mut $S :: Group , span : $S :: Span ); }, Punct { fn new ( ch : char , spacing : Spacing )-> $S :: Punct ; fn as_char ($self : $S :: Punct )-> char ; fn spacing ($self : $S :: Punct )-> Spacing ; fn span ($self : $S :: Punct )-> $S :: Span ; fn with_span ($self : $S :: Punct , span : $S :: Span )-> $S :: Punct ; }, Ident { fn new ( string : & str , span : $S :: Span , is_raw : bool )-> $S :: Ident ; fn span ($self : $S :: Ident )-> $S :: Span ; fn with_span ($self : $S :: Ident , span : $S :: Span )-> $S :: Ident ; }, Literal { fn drop ($self : $S :: Literal ); fn clone ($self : &$S :: Literal )-> $S :: Literal ; fn debug_kind ($self : &$S :: Literal )-> String ; fn symbol ($self : &$S :: Literal )-> String ; fn suffix ($self : &$S :: Literal )-> Option < String >; fn integer ( n : & str )-> $S :: Literal ; fn typed_integer ( n : & str , kind : & str )-> $S :: Literal ; fn float ( n : & str )-> $S :: Literal ; fn f32 ( n : & str )-> $S :: Literal ; fn f64 ( n : & str )-> $S :: Literal ; fn string ( string : & str )-> $S :: Literal ; fn character ( ch : char )-> $S :: Literal ; fn byte_string ( bytes : & [ u8 ])-> $S :: Literal ; fn span ($self : &$S :: Literal )-> $S :: Span ; fn set_span ($self : & mut $S :: Literal , span : $S :: Span ); fn subspan ($self : &$S :: Literal , start : Bound < usize >, end : Bound < usize >, )-> Option <$S :: Span >; }, SourceFile { fn drop ($self : $S :: SourceFile ); fn clone ($self : &$S :: SourceFile )-> $S :: SourceFile ; fn eq ($self : &$S :: SourceFile , other : &$S :: SourceFile )-> bool ; fn path ($self : &$S :: SourceFile )-> String ; fn is_real ($self : &$S :: SourceFile )-> bool ; }, MultiSpan { fn drop ($self : $S :: MultiSpan ); fn new ()-> $S :: MultiSpan ; fn push ($self : & mut $S :: MultiSpan , span : $S :: Span ); }, Diagnostic { fn drop ($self : $S :: Diagnostic ); fn new ( level : Level , msg : & str , span : $S :: MultiSpan )-> $S :: Diagnostic ; fn sub ($self : & mut $S :: Diagnostic , level : Level , msg : & str , span : $S :: MultiSpan , ); fn emit ($self : $S :: Diagnostic ); }, Span { fn debug ($self : $S :: Span )-> String ; fn def_site ()-> $S :: Span ; fn call_site ()-> $S :: Span ; fn mixed_site ()-> $S :: Span ; fn source_file ($self : $S :: Span )-> $S :: SourceFile ; fn parent ($self : $S :: Span )-> Option <$S :: Span >; fn source ($self : $S :: Span )-> $S :: Span ; fn start ($self : $S :: Span )-> LineColumn ; fn end ($self : $S :: Span )-> LineColumn ; fn join ($self : $S :: Span , other : $S :: Span )-> Option <$S :: Span >; fn resolved_at ($self : $S :: Span , at : $S :: Span )-> $S :: Span ; fn source_text ($self : $S :: Span )-> Option < String >; }, }}; }
109macro_rules! __ra_macro_fixture108 {( le $ty : ty )=>{ impl < S > Encode < S > for $ty { fn encode ( self , w : & mut Writer , _: & mut S ){ w . write_all (& self . to_le_bytes ()). unwrap (); }} impl < S > DecodeMut < '_ , '_ , S > for $ty { fn decode ( r : & mut Reader < '_ >, _: & mut S )-> Self { const N : usize = :: std :: mem :: size_of ::<$ty > (); let mut bytes = [ 0 ; N ]; bytes . copy_from_slice (& r [.. N ]); * r = & r [ N ..]; Self :: from_le_bytes ( bytes )}}}; ( struct $name : ident {$($field : ident ),* $(,)? })=>{ impl < S > Encode < S > for $name { fn encode ( self , w : & mut Writer , s : & mut S ){$(self .$field . encode ( w , s );)* }} impl < S > DecodeMut < '_ , '_ , S > for $name { fn decode ( r : & mut Reader < '_ >, s : & mut S )-> Self {$name {$($field : DecodeMut :: decode ( r , s )),* }}}}; ( enum $name : ident $(<$($T : ident ),+>)? {$($variant : ident $(($field : ident ))*),* $(,)? })=>{ impl < S , $($($T : Encode < S >),+)?> Encode < S > for $name $(<$($T ),+>)? { fn encode ( self , w : & mut Writer , s : & mut S ){# [ allow ( non_upper_case_globals )] mod tag {# [ repr ( u8 )] enum Tag {$($variant ),* }$(pub const $variant : u8 = Tag ::$variant as u8 ;)* } match self {$($name ::$variant $(($field ))* =>{ tag ::$variant . encode ( w , s ); $($field . encode ( w , s );)* })* }}} impl < S , $($($T : for < 's > DecodeMut < 'a , 's , S >),+)?> DecodeMut < 'a , '_ , S > for $name $(<$($T ),+>)? { fn decode ( r : & mut Reader < 'a >, s : & mut S )-> Self {# [ allow ( non_upper_case_globals )] mod tag {# [ repr ( u8 )] enum Tag {$($variant ),* }$(pub const $variant : u8 = Tag ::$variant as u8 ;)* } match u8 :: decode ( r , s ){$(tag ::$variant =>{$(let $field = DecodeMut :: decode ( r , s );)* $name ::$variant $(($field ))* })* _ => unreachable ! (), }}}}}
110macro_rules! __ra_macro_fixture109 {($($ty : ty ),* $(,)?)=>{$(impl Mark for $ty { type Unmarked = Self ; fn mark ( unmarked : Self :: Unmarked )-> Self { unmarked }} impl Unmark for $ty { type Unmarked = Self ; fn unmark ( self )-> Self :: Unmarked { self }})* }}
111macro_rules! __ra_macro_fixture110 {($($name : ident {$(fn $method : ident ($($arg : ident : $arg_ty : ty ),* $(,)?)$(-> $ret_ty : ty )*;)* }),* $(,)?)=>{$(impl $name {$(pub ( crate ) fn $method ($($arg : $arg_ty ),*)$(-> $ret_ty )* { Bridge :: with (| bridge | { let mut b = bridge . cached_buffer . take (); b . clear (); api_tags :: Method ::$name ( api_tags ::$name ::$method ). encode (& mut b , & mut ()); reverse_encode ! ( b ; $($arg ),*); b = bridge . dispatch . call ( b ); let r = Result ::<_, PanicMessage >:: decode (& mut & b [..], & mut ()); bridge . cached_buffer = b ; r . unwrap_or_else (| e | panic :: resume_unwind ( e . into ()))})})* })* }}
112macro_rules! __ra_macro_fixture111 {($($name : ident {$(fn $method : ident ($($arg : ident : $arg_ty : ty ),* $(,)?)$(-> $ret_ty : ty )?;)* }),* $(,)?)=>{ pub trait Types {$(associated_item ! ( type $name );)* }$(pub trait $name : Types {$(associated_item ! ( fn $method (& mut self , $($arg : $arg_ty ),*)$(-> $ret_ty )?);)* })* pub trait Server : Types $(+ $name )* {} impl < S : Types $(+ $name )*> Server for S {}}}
113macro_rules! __ra_macro_fixture112 {($($name : ident {$(fn $method : ident ($($arg : ident : $arg_ty : ty ),* $(,)?)$(-> $ret_ty : ty )?;)* }),* $(,)?)=>{ impl < S : Types > Types for MarkedTypes < S > {$(type $name = Marked < S ::$name , client ::$name >;)* }$(impl < S : $name > $name for MarkedTypes < S > {$(fn $method (& mut self , $($arg : $arg_ty ),*)$(-> $ret_ty )? {<_>:: mark ($name ::$method (& mut self . 0 , $($arg . unmark ()),*))})* })* }}
114macro_rules! __ra_macro_fixture113 {($($name : ident {$(fn $method : ident ($($arg : ident : $arg_ty : ty ),* $(,)?)$(-> $ret_ty : ty )?;)* }),* $(,)?)=>{ pub trait DispatcherTrait {$(type $name ;)* fn dispatch (& mut self , b : Buffer < u8 >)-> Buffer < u8 >; } impl < S : Server > DispatcherTrait for Dispatcher < MarkedTypes < S >> {$(type $name = < MarkedTypes < S > as Types >::$name ;)* fn dispatch (& mut self , mut b : Buffer < u8 >)-> Buffer < u8 > { let Dispatcher { handle_store , server }= self ; let mut reader = & b [..]; match api_tags :: Method :: decode (& mut reader , & mut ()){$(api_tags :: Method ::$name ( m )=> match m {$(api_tags ::$name ::$method =>{ let mut call_method = || { reverse_decode ! ( reader , handle_store ; $($arg : $arg_ty ),*); $name ::$method ( server , $($arg ),*)}; let r = if thread :: panicking (){ Ok ( call_method ())} else { panic :: catch_unwind ( panic :: AssertUnwindSafe ( call_method )). map_err ( PanicMessage :: from )}; b . clear (); r . encode (& mut b , handle_store ); })* }),* } b }}}}
115macro_rules! __ra_macro_fixture114 {($($name : ident {$(fn $method : ident ($($arg : ident : $arg_ty : ty ),* $(,)?)$(-> $ret_ty : ty )*;)* }),* $(,)?)=>{$(pub ( super ) enum $name {$($method ),* } rpc_encode_decode ! ( enum $name {$($method ),* }); )* pub ( super ) enum Method {$($name ($name )),* } rpc_encode_decode ! ( enum Method {$($name ( m )),* }); }}
116macro_rules! __ra_macro_fixture115 {($(if # [ cfg ($meta : meta )]{$($tokens : tt )* }) else * else {$($tokens2 : tt )* })=>{$crate :: cfg_if ! {@ __items (); $((($meta )($($tokens )*)), )* (()($($tokens2 )*)), }}; ( if # [ cfg ($i_met : meta )]{$($i_tokens : tt )* }$(else if # [ cfg ($e_met : meta )]{$($e_tokens : tt )* })* )=>{$crate :: cfg_if ! {@ __items (); (($i_met )($($i_tokens )*)), $((($e_met )($($e_tokens )*)), )* (()()), }}; (@ __items ($($not : meta ,)*); )=>{}; (@ __items ($($not : meta ,)*); (($($m : meta ),*)($($tokens : tt )*)), $($rest : tt )*)=>{# [ cfg ( all ($($m ,)* not ( any ($($not ),*))))]$crate :: cfg_if ! {@ __identity $($tokens )* }$crate :: cfg_if ! {@ __items ($($not ,)* $($m ,)*); $($rest )* }}; (@ __identity $($tokens : tt )*)=>{$($tokens )* }; }
117macro_rules! __ra_macro_fixture116 {($lhs : ty , $rhs : ty )=>{# [ stable ( feature = "cmp_os_str" , since = "1.8.0" )] impl < 'a , 'b > PartialEq <$rhs > for $lhs {# [ inline ] fn eq (& self , other : &$rhs )-> bool {< OsStr as PartialEq >:: eq ( self , other )}}# [ stable ( feature = "cmp_os_str" , since = "1.8.0" )] impl < 'a , 'b > PartialEq <$lhs > for $rhs {# [ inline ] fn eq (& self , other : &$lhs )-> bool {< OsStr as PartialEq >:: eq ( self , other )}}# [ stable ( feature = "cmp_os_str" , since = "1.8.0" )] impl < 'a , 'b > PartialOrd <$rhs > for $lhs {# [ inline ] fn partial_cmp (& self , other : &$rhs )-> Option < cmp :: Ordering > {< OsStr as PartialOrd >:: partial_cmp ( self , other )}}# [ stable ( feature = "cmp_os_str" , since = "1.8.0" )] impl < 'a , 'b > PartialOrd <$lhs > for $rhs {# [ inline ] fn partial_cmp (& self , other : &$lhs )-> Option < cmp :: Ordering > {< OsStr as PartialOrd >:: partial_cmp ( self , other )}}}; }
118macro_rules! __ra_macro_fixture117 {()=>{}; ($(# [$attr : meta ])* $vis : vis static $name : ident : $t : ty = $init : expr ; $($rest : tt )*)=>($crate :: __thread_local_inner ! ($(# [$attr ])* $vis $name , $t , $init ); $crate :: thread_local ! ($($rest )*); ); ($(# [$attr : meta ])* $vis : vis static $name : ident : $t : ty = $init : expr )=>($crate :: __thread_local_inner ! ($(# [$attr ])* $vis $name , $t , $init ); ); }
119macro_rules! __ra_macro_fixture118 {($($t : ty )*)=>($(impl ReadNumberHelper for $t { const ZERO : Self = 0 ; # [ inline ] fn checked_mul (& self , other : u32 )-> Option < Self > { Self :: checked_mul (* self , other . try_into (). ok ()?)}# [ inline ] fn checked_add (& self , other : u32 )-> Option < Self > { Self :: checked_add (* self , other . try_into (). ok ()?)}})*)}
120macro_rules! __ra_macro_fixture119 {($lhs : ty , $rhs : ty )=>{# [ stable ( feature = "partialeq_path" , since = "1.6.0" )] impl < 'a , 'b > PartialEq <$rhs > for $lhs {# [ inline ] fn eq (& self , other : &$rhs )-> bool {< Path as PartialEq >:: eq ( self , other )}}# [ stable ( feature = "partialeq_path" , since = "1.6.0" )] impl < 'a , 'b > PartialEq <$lhs > for $rhs {# [ inline ] fn eq (& self , other : &$lhs )-> bool {< Path as PartialEq >:: eq ( self , other )}}# [ stable ( feature = "cmp_path" , since = "1.8.0" )] impl < 'a , 'b > PartialOrd <$rhs > for $lhs {# [ inline ] fn partial_cmp (& self , other : &$rhs )-> Option < cmp :: Ordering > {< Path as PartialOrd >:: partial_cmp ( self , other )}}# [ stable ( feature = "cmp_path" , since = "1.8.0" )] impl < 'a , 'b > PartialOrd <$lhs > for $rhs {# [ inline ] fn partial_cmp (& self , other : &$lhs )-> Option < cmp :: Ordering > {< Path as PartialOrd >:: partial_cmp ( self , other )}}}; }
121macro_rules! __ra_macro_fixture120 {($lhs : ty , $rhs : ty )=>{# [ stable ( feature = "cmp_path" , since = "1.8.0" )] impl < 'a , 'b > PartialEq <$rhs > for $lhs {# [ inline ] fn eq (& self , other : &$rhs )-> bool {< Path as PartialEq >:: eq ( self , other . as_ref ())}}# [ stable ( feature = "cmp_path" , since = "1.8.0" )] impl < 'a , 'b > PartialEq <$lhs > for $rhs {# [ inline ] fn eq (& self , other : &$lhs )-> bool {< Path as PartialEq >:: eq ( self . as_ref (), other )}}# [ stable ( feature = "cmp_path" , since = "1.8.0" )] impl < 'a , 'b > PartialOrd <$rhs > for $lhs {# [ inline ] fn partial_cmp (& self , other : &$rhs )-> Option < cmp :: Ordering > {< Path as PartialOrd >:: partial_cmp ( self , other . as_ref ())}}# [ stable ( feature = "cmp_path" , since = "1.8.0" )] impl < 'a , 'b > PartialOrd <$lhs > for $rhs {# [ inline ] fn partial_cmp (& self , other : &$lhs )-> Option < cmp :: Ordering > {< Path as PartialOrd >:: partial_cmp ( self . as_ref (), other )}}}; }
122macro_rules! __ra_macro_fixture121 {(@ key $t : ty , $init : expr )=>{{# [ inline ] fn __init ()-> $t {$init } unsafe fn __getit ()-> $crate :: option :: Option <& 'static $t > {# [ cfg ( all ( target_arch = "wasm32" , not ( target_feature = "atomics" )))] static __KEY : $crate :: thread :: __StaticLocalKeyInner <$t > = $crate :: thread :: __StaticLocalKeyInner :: new (); # [ thread_local ]# [ cfg ( all ( target_thread_local , not ( all ( target_arch = "wasm32" , not ( target_feature = "atomics" ))), ))] static __KEY : $crate :: thread :: __FastLocalKeyInner <$t > = $crate :: thread :: __FastLocalKeyInner :: new (); # [ cfg ( all ( not ( target_thread_local ), not ( all ( target_arch = "wasm32" , not ( target_feature = "atomics" ))), ))] static __KEY : $crate :: thread :: __OsLocalKeyInner <$t > = $crate :: thread :: __OsLocalKeyInner :: new (); # [ allow ( unused_unsafe )] unsafe { __KEY . get ( __init )}} unsafe {$crate :: thread :: LocalKey :: new ( __getit )}}}; ($(# [$attr : meta ])* $vis : vis $name : ident , $t : ty , $init : expr )=>{$(# [$attr ])* $vis const $name : $crate :: thread :: LocalKey <$t > = $crate :: __thread_local_inner ! (@ key $t , $init ); }}
123macro_rules! __ra_macro_fixture122 {({$($then_tt : tt )* } else {$($else_tt : tt )* })=>{ cfg_if :: cfg_if ! { if # [ cfg ( all ( target_os = "linux" , target_env = "gnu" ))]{$($then_tt )* } else {$($else_tt )* }}}; ($($block_inner : tt )*)=>{# [ cfg ( all ( target_os = "linux" , target_env = "gnu" ))]{$($block_inner )* }}; }
124macro_rules! __ra_macro_fixture123 {($($t : ident )*)=>($(impl IsMinusOne for $t { fn is_minus_one (& self )-> bool {* self == - 1 }})*)}
125macro_rules! __ra_macro_fixture124 {($(if # [ cfg ($($meta : meta ),*)]{$($it : item )* }) else * else {$($it2 : item )* })=>{ cfg_if ! {@ __items (); $((($($meta ),*)($($it )*)), )* (()($($it2 )*)), }}; ( if # [ cfg ($($i_met : meta ),*)]{$($i_it : item )* }$(else if # [ cfg ($($e_met : meta ),*)]{$($e_it : item )* })* )=>{ cfg_if ! {@ __items (); (($($i_met ),*)($($i_it )*)), $((($($e_met ),*)($($e_it )*)), )* (()()), }}; (@ __items ($($not : meta ,)*); )=>{}; (@ __items ($($not : meta ,)*); (($($m : meta ),*)($($it : item )*)), $($rest : tt )*)=>{ cfg_if ! {@ __apply cfg ( all ($($m ,)* not ( any ($($not ),*)))), $($it )* } cfg_if ! {@ __items ($($not ,)* $($m ,)*); $($rest )* }}; (@ __apply $m : meta , $($it : item )*)=>{$(# [$m ]$it )* }; }
126macro_rules! __ra_macro_fixture125 {($bench_macro : ident , $bench_ahash_serial : ident , $bench_std_serial : ident , $bench_ahash_highbits : ident , $bench_std_highbits : ident , $bench_ahash_random : ident , $bench_std_random : ident )=>{$bench_macro ! ($bench_ahash_serial , AHashMap , 0 ..); $bench_macro ! ($bench_std_serial , StdHashMap , 0 ..); $bench_macro ! ($bench_ahash_highbits , AHashMap , ( 0 ..). map ( usize :: swap_bytes )); $bench_macro ! ($bench_std_highbits , StdHashMap , ( 0 ..). map ( usize :: swap_bytes )); $bench_macro ! ($bench_ahash_random , AHashMap , RandomKeys :: new ()); $bench_macro ! ($bench_std_random , StdHashMap , RandomKeys :: new ()); }; }
127macro_rules! __ra_macro_fixture126 {($name : ident , $maptype : ident , $keydist : expr )=>{# [ bench ] fn $name ( b : & mut Bencher ){ let mut m = $maptype :: with_capacity_and_hasher ( SIZE , Default :: default ()); b . iter (|| { m . clear (); for i in ($keydist ). take ( SIZE ){ m . insert ( i , i ); } black_box (& mut m ); })}}; }
128macro_rules! __ra_macro_fixture127 {($name : ident , $maptype : ident , $keydist : expr )=>{# [ bench ] fn $name ( b : & mut Bencher ){ let mut base = $maptype :: default (); for i in ($keydist ). take ( SIZE ){ base . insert ( i , i ); } let skip = $keydist . skip ( SIZE ); b . iter (|| { let mut m = base . clone (); let mut add_iter = skip . clone (); let mut remove_iter = $keydist ; for ( add , remove ) in (& mut add_iter ). zip (& mut remove_iter ). take ( SIZE ){ m . insert ( add , add ); black_box ( m . remove (& remove )); } black_box ( m ); })}}; }
129macro_rules! __ra_macro_fixture128 {($name : ident , $maptype : ident , $keydist : expr )=>{# [ bench ] fn $name ( b : & mut Bencher ){ let mut m = $maptype :: default (); for i in $keydist . take ( SIZE ){ m . insert ( i , i ); } b . iter (|| { for i in $keydist . take ( SIZE ){ black_box ( m . get (& i )); }})}}; }
130macro_rules! __ra_macro_fixture129 {($name : ident , $maptype : ident , $keydist : expr )=>{# [ bench ] fn $name ( b : & mut Bencher ){ let mut m = $maptype :: default (); let mut iter = $keydist ; for i in (& mut iter ). take ( SIZE ){ m . insert ( i , i ); } b . iter (|| { for i in (& mut iter ). take ( SIZE ){ black_box ( m . get (& i )); }})}}; }
131macro_rules! __ra_macro_fixture130 {($name : ident , $maptype : ident , $keydist : expr )=>{# [ bench ] fn $name ( b : & mut Bencher ){ let mut m = $maptype :: default (); for i in ($keydist ). take ( SIZE ){ m . insert ( i , i ); } b . iter (|| { for i in & m { black_box ( i ); }})}}; }
132macro_rules! __ra_macro_fixture131 {($(if # [ cfg ($($meta : meta ),*)]{$($it : item )* }) else * else {$($it2 : item )* })=>{ cfg_if ! {@ __items (); $((($($meta ),*)($($it )*)), )* (()($($it2 )*)), }}; ( if # [ cfg ($($i_met : meta ),*)]{$($i_it : item )* }$(else if # [ cfg ($($e_met : meta ),*)]{$($e_it : item )* })* )=>{ cfg_if ! {@ __items (); (($($i_met ),*)($($i_it )*)), $((($($e_met ),*)($($e_it )*)), )* (()()), }}; (@ __items ($($not : meta ,)*); )=>{}; (@ __items ($($not : meta ,)*); (($($m : meta ),*)($($it : item )*)), $($rest : tt )*)=>{ cfg_if ! {@ __apply cfg ( all ($($m ,)* not ( any ($($not ),*)))), $($it )* } cfg_if ! {@ __items ($($not ,)* $($m ,)*); $($rest )* }}; (@ __apply $m : meta , $($it : item )*)=>{$(# [$m ]$it )* }; }
133macro_rules! __ra_macro_fixture132 {($($(# [$attr : meta ])* pub $t : ident $i : ident {$($field : tt )* })*)=>($(s ! ( it : $(# [$attr ])* pub $t $i {$($field )* }); )*); ( it : $(# [$attr : meta ])* pub union $i : ident {$($field : tt )* })=>( compile_error ! ( "unions cannot derive extra traits, use s_no_extra_traits instead" ); ); ( it : $(# [$attr : meta ])* pub struct $i : ident {$($field : tt )* })=>( __item ! {# [ repr ( C )]# [ cfg_attr ( feature = "extra_traits" , derive ( Debug , Eq , Hash , PartialEq ))]# [ allow ( deprecated )]$(# [$attr ])* pub struct $i {$($field )* }}# [ allow ( deprecated )] impl :: Copy for $i {}# [ allow ( deprecated )] impl :: Clone for $i { fn clone (& self )-> $i {* self }}); }
134macro_rules! __ra_macro_fixture133 {($i : item )=>{$i }; }
135macro_rules! __ra_macro_fixture134 {($($(# [$attr : meta ])* pub $t : ident $i : ident {$($field : tt )* })*)=>($(s_no_extra_traits ! ( it : $(# [$attr ])* pub $t $i {$($field )* }); )*); ( it : $(# [$attr : meta ])* pub union $i : ident {$($field : tt )* })=>( cfg_if ! { if # [ cfg ( libc_union )]{ __item ! {# [ repr ( C )]$(# [$attr ])* pub union $i {$($field )* }} impl :: Copy for $i {} impl :: Clone for $i { fn clone (& self )-> $i {* self }}}}); ( it : $(# [$attr : meta ])* pub struct $i : ident {$($field : tt )* })=>( __item ! {# [ repr ( C )]$(# [$attr ])* pub struct $i {$($field )* }}# [ allow ( deprecated )] impl :: Copy for $i {}# [ allow ( deprecated )] impl :: Clone for $i { fn clone (& self )-> $i {* self }}); }
136macro_rules! __ra_macro_fixture135 {($($(# [$attr : meta ])* pub const $name : ident : $t1 : ty = $t2 : ident {$($field : tt )* };)*)=>($(# [ cfg ( libc_align )]$(# [$attr ])* pub const $name : $t1 = $t2 {$($field )* }; # [ cfg ( not ( libc_align ))]$(# [$attr ])* pub const $name : $t1 = $t2 {$($field )* __align : [], }; )*)}
137macro_rules! __ra_macro_fixture136 {($($args : tt )* )=>{$(define_ioctl ! ($args ); )* }}
138macro_rules! __ra_macro_fixture137 {({$name : ident , $ioctl : ident , $arg_type : ty })=>{ pub unsafe fn $name ( fd : c_int , arg : $arg_type )-> c_int { untyped_ioctl ( fd , bindings ::$ioctl , arg )}}; }
139macro_rules! __ra_macro_fixture138 {($($T : ty ),*)=>{$(impl IdentFragment for $T { fn fmt (& self , f : & mut fmt :: Formatter )-> fmt :: Result { fmt :: Display :: fmt ( self , f )}})* }}
140macro_rules! __ra_macro_fixture139 {($($t : ident =>$name : ident )*)=>($(impl ToTokens for $t { fn to_tokens (& self , tokens : & mut TokenStream ){ tokens . append ( Literal ::$name (* self )); }})*)}
141macro_rules! __ra_macro_fixture140 {($($l : tt )*)=>{$(impl < 'q , T : 'q > RepAsIteratorExt < 'q > for [ T ; $l ]{ type Iter = slice :: Iter < 'q , T >; fn quote_into_iter (& 'q self )-> ( Self :: Iter , HasIter ){( self . iter (), HasIter )}})* }}
142macro_rules! __ra_macro_fixture141 {($name : ident $spanned : ident $char1 : tt )=>{ pub fn $name ( tokens : & mut TokenStream ){ tokens . append ( Punct :: new ($char1 , Spacing :: Alone )); } pub fn $spanned ( tokens : & mut TokenStream , span : Span ){ let mut punct = Punct :: new ($char1 , Spacing :: Alone ); punct . set_span ( span ); tokens . append ( punct ); }}; ($name : ident $spanned : ident $char1 : tt $char2 : tt )=>{ pub fn $name ( tokens : & mut TokenStream ){ tokens . append ( Punct :: new ($char1 , Spacing :: Joint )); tokens . append ( Punct :: new ($char2 , Spacing :: Alone )); } pub fn $spanned ( tokens : & mut TokenStream , span : Span ){ let mut punct = Punct :: new ($char1 , Spacing :: Joint ); punct . set_span ( span ); tokens . append ( punct ); let mut punct = Punct :: new ($char2 , Spacing :: Alone ); punct . set_span ( span ); tokens . append ( punct ); }}; ($name : ident $spanned : ident $char1 : tt $char2 : tt $char3 : tt )=>{ pub fn $name ( tokens : & mut TokenStream ){ tokens . append ( Punct :: new ($char1 , Spacing :: Joint )); tokens . append ( Punct :: new ($char2 , Spacing :: Joint )); tokens . append ( Punct :: new ($char3 , Spacing :: Alone )); } pub fn $spanned ( tokens : & mut TokenStream , span : Span ){ let mut punct = Punct :: new ($char1 , Spacing :: Joint ); punct . set_span ( span ); tokens . append ( punct ); let mut punct = Punct :: new ($char2 , Spacing :: Joint ); punct . set_span ( span ); tokens . append ( punct ); let mut punct = Punct :: new ($char3 , Spacing :: Alone ); punct . set_span ( span ); tokens . append ( punct ); }}; }
143macro_rules! __ra_macro_fixture142 {($display : tt $name : ty )=>{# [ cfg ( feature = "parsing" )] impl Token for $name { fn peek ( cursor : Cursor )-> bool { fn peek ( input : ParseStream )-> bool {<$name as Parse >:: parse ( input ). is_ok ()} peek_impl ( cursor , peek )} fn display ()-> & 'static str {$display }}# [ cfg ( feature = "parsing" )] impl private :: Sealed for $name {}}; }
144macro_rules! __ra_macro_fixture143 {($display : tt $ty : ident $get : ident )=>{# [ cfg ( feature = "parsing" )] impl Token for $ty { fn peek ( cursor : Cursor )-> bool { cursor .$get (). is_some ()} fn display ()-> & 'static str {$display }}# [ cfg ( feature = "parsing" )] impl private :: Sealed for $ty {}}; }
145macro_rules! __ra_macro_fixture144 {($($token : tt pub struct $name : ident /$len : tt # [$doc : meta ])*)=>{$(# [ repr ( C )]# [$doc ]# [ doc = "" ]# [ doc = " Don\\\'t try to remember the name of this type &mdash; use the" ]# [ doc = " [`Token!`] macro instead." ]# [ doc = "" ]# [ doc = " [`Token!`]: crate::token" ] pub struct $name { pub spans : [ Span ; $len ], }# [ doc ( hidden )]# [ allow ( non_snake_case )] pub fn $name < S : IntoSpans < [ Span ; $len ]>> ( spans : S )-> $name {$name { spans : spans . into_spans (), }} impl std :: default :: Default for $name { fn default ()-> Self {$name { spans : [ Span :: call_site (); $len ], }}}# [ cfg ( feature = "clone-impls" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "clone-impls" )))] impl Copy for $name {}# [ cfg ( feature = "clone-impls" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "clone-impls" )))] impl Clone for $name { fn clone (& self )-> Self {* self }}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl Debug for $name { fn fmt (& self , f : & mut fmt :: Formatter )-> fmt :: Result { f . write_str ( stringify ! ($name ))}}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl cmp :: Eq for $name {}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl PartialEq for $name { fn eq (& self , _other : &$name )-> bool { true }}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl Hash for $name { fn hash < H : Hasher > (& self , _state : & mut H ){}} impl_deref_if_len_is_1 ! ($name /$len ); )* }; }
146macro_rules! __ra_macro_fixture145 {($($token : tt pub struct $name : ident # [$doc : meta ])*)=>{$(# [$doc ]# [ doc = "" ]# [ doc = " Don\\\'t try to remember the name of this type &mdash; use the" ]# [ doc = " [`Token!`] macro instead." ]# [ doc = "" ]# [ doc = " [`Token!`]: crate::token" ] pub struct $name { pub span : Span , }# [ doc ( hidden )]# [ allow ( non_snake_case )] pub fn $name < S : IntoSpans < [ Span ; 1 ]>> ( span : S )-> $name {$name { span : span . into_spans ()[ 0 ], }} impl std :: default :: Default for $name { fn default ()-> Self {$name { span : Span :: call_site (), }}}# [ cfg ( feature = "clone-impls" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "clone-impls" )))] impl Copy for $name {}# [ cfg ( feature = "clone-impls" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "clone-impls" )))] impl Clone for $name { fn clone (& self )-> Self {* self }}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl Debug for $name { fn fmt (& self , f : & mut fmt :: Formatter )-> fmt :: Result { f . write_str ( stringify ! ($name ))}}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl cmp :: Eq for $name {}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl PartialEq for $name { fn eq (& self , _other : &$name )-> bool { true }}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl Hash for $name { fn hash < H : Hasher > (& self , _state : & mut H ){}}# [ cfg ( feature = "printing" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "printing" )))] impl ToTokens for $name { fn to_tokens (& self , tokens : & mut TokenStream ){ printing :: keyword ($token , self . span , tokens ); }}# [ cfg ( feature = "parsing" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "parsing" )))] impl Parse for $name { fn parse ( input : ParseStream )-> Result < Self > { Ok ($name { span : parsing :: keyword ( input , $token )?, })}}# [ cfg ( feature = "parsing" )] impl Token for $name { fn peek ( cursor : Cursor )-> bool { parsing :: peek_keyword ( cursor , $token )} fn display ()-> & 'static str { concat ! ( "`" , $token , "`" )}}# [ cfg ( feature = "parsing" )] impl private :: Sealed for $name {})* }; }
147macro_rules! __ra_macro_fixture146 {($($token : tt pub struct $name : ident /$len : tt # [$doc : meta ])*)=>{$(define_punctuation_structs ! {$token pub struct $name /$len # [$doc ]}# [ cfg ( feature = "printing" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "printing" )))] impl ToTokens for $name { fn to_tokens (& self , tokens : & mut TokenStream ){ printing :: punct ($token , & self . spans , tokens ); }}# [ cfg ( feature = "parsing" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "parsing" )))] impl Parse for $name { fn parse ( input : ParseStream )-> Result < Self > { Ok ($name { spans : parsing :: punct ( input , $token )?, })}}# [ cfg ( feature = "parsing" )] impl Token for $name { fn peek ( cursor : Cursor )-> bool { parsing :: peek_punct ( cursor , $token )} fn display ()-> & 'static str { concat ! ( "`" , $token , "`" )}}# [ cfg ( feature = "parsing" )] impl private :: Sealed for $name {})* }; }
148macro_rules! __ra_macro_fixture147 {($($token : tt pub struct $name : ident # [$doc : meta ])*)=>{$(# [$doc ] pub struct $name { pub span : Span , }# [ doc ( hidden )]# [ allow ( non_snake_case )] pub fn $name < S : IntoSpans < [ Span ; 1 ]>> ( span : S )-> $name {$name { span : span . into_spans ()[ 0 ], }} impl std :: default :: Default for $name { fn default ()-> Self {$name { span : Span :: call_site (), }}}# [ cfg ( feature = "clone-impls" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "clone-impls" )))] impl Copy for $name {}# [ cfg ( feature = "clone-impls" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "clone-impls" )))] impl Clone for $name { fn clone (& self )-> Self {* self }}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl Debug for $name { fn fmt (& self , f : & mut fmt :: Formatter )-> fmt :: Result { f . write_str ( stringify ! ($name ))}}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl cmp :: Eq for $name {}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl PartialEq for $name { fn eq (& self , _other : &$name )-> bool { true }}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl Hash for $name { fn hash < H : Hasher > (& self , _state : & mut H ){}} impl $name {# [ cfg ( feature = "printing" )] pub fn surround < F > (& self , tokens : & mut TokenStream , f : F ) where F : FnOnce (& mut TokenStream ), { printing :: delim ($token , self . span , tokens , f ); }}# [ cfg ( feature = "parsing" )] impl private :: Sealed for $name {})* }; }
149macro_rules! __ra_macro_fixture148 {($token : ident )=>{ impl From < Token ! [$token ]> for Ident { fn from ( token : Token ! [$token ])-> Ident { Ident :: new ( stringify ! ($token ), token . span )}}}; }
150macro_rules! __ra_macro_fixture149 {([$($attrs_pub : tt )*] struct $name : ident # full $($rest : tt )* )=>{# [ cfg ( feature = "full" )]$($attrs_pub )* struct $name $($rest )* # [ cfg ( not ( feature = "full" ))]$($attrs_pub )* struct $name { _noconstruct : :: std :: marker :: PhantomData <:: proc_macro2 :: Span >, }# [ cfg ( all ( not ( feature = "full" ), feature = "printing" ))] impl :: quote :: ToTokens for $name { fn to_tokens (& self , _: & mut :: proc_macro2 :: TokenStream ){ unreachable ! ()}}}; ([$($attrs_pub : tt )*] struct $name : ident $($rest : tt )* )=>{$($attrs_pub )* struct $name $($rest )* }; ($($t : tt )*)=>{ strip_attrs_pub ! ( ast_struct ! ($($t )*)); }; }
151macro_rules! __ra_macro_fixture150 {([$($attrs_pub : tt )*] enum $name : ident # no_visit $($rest : tt )* )=>( ast_enum ! ([$($attrs_pub )*] enum $name $($rest )*); ); ([$($attrs_pub : tt )*] enum $name : ident $($rest : tt )* )=>($($attrs_pub )* enum $name $($rest )* ); ($($t : tt )*)=>{ strip_attrs_pub ! ( ast_enum ! ($($t )*)); }; }
152macro_rules! __ra_macro_fixture151 {($(# [$enum_attr : meta ])* $pub : ident $enum : ident $name : ident #$tag : ident $body : tt $($remaining : tt )* )=>{ ast_enum ! ($(# [$enum_attr ])* $pub $enum $name #$tag $body ); ast_enum_of_structs_impl ! ($pub $enum $name $body $($remaining )*); }; ($(# [$enum_attr : meta ])* $pub : ident $enum : ident $name : ident $body : tt $($remaining : tt )* )=>{ ast_enum ! ($(# [$enum_attr ])* $pub $enum $name $body ); ast_enum_of_structs_impl ! ($pub $enum $name $body $($remaining )*); }; }
153macro_rules! __ra_macro_fixture152 {($ident : ident )=>{# [ allow ( non_camel_case_types )] pub struct $ident { pub span : $crate :: __private :: Span , }# [ doc ( hidden )]# [ allow ( dead_code , non_snake_case )] pub fn $ident < __S : $crate :: __private :: IntoSpans < [$crate :: __private :: Span ; 1 ]>> ( span : __S , )-> $ident {$ident { span : $crate :: __private :: IntoSpans :: into_spans ( span )[ 0 ], }} impl $crate :: __private :: Default for $ident { fn default ()-> Self {$ident { span : $crate :: __private :: Span :: call_site (), }}}$crate :: impl_parse_for_custom_keyword ! ($ident ); $crate :: impl_to_tokens_for_custom_keyword ! ($ident ); $crate :: impl_clone_for_custom_keyword ! ($ident ); $crate :: impl_extra_traits_for_custom_keyword ! ($ident ); }; }
154macro_rules! __ra_macro_fixture153 {($($expr_type : ty , $variant : ident , $msg : expr , )* )=>{$(# [ cfg ( all ( feature = "full" , feature = "printing" ))]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "parsing" )))] impl Parse for $expr_type { fn parse ( input : ParseStream )-> Result < Self > { let mut expr : Expr = input . parse ()?; loop { match expr { Expr ::$variant ( inner )=> return Ok ( inner ), Expr :: Group ( next )=> expr = * next . expr , _ => return Err ( Error :: new_spanned ( expr , $msg )), }}}})* }; }
155macro_rules! __ra_macro_fixture154 {($ty : ident )=>{# [ cfg ( feature = "clone-impls" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "clone-impls" )))] impl < 'a > Clone for $ty < 'a > { fn clone (& self )-> Self {$ty ( self . 0 )}}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl < 'a > Debug for $ty < 'a > { fn fmt (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . debug_tuple ( stringify ! ($ty )). field ( self . 0 ). finish ()}}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl < 'a > Eq for $ty < 'a > {}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl < 'a > PartialEq for $ty < 'a > { fn eq (& self , other : & Self )-> bool { self . 0 == other . 0 }}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl < 'a > Hash for $ty < 'a > { fn hash < H : Hasher > (& self , state : & mut H ){ self . 0 . hash ( state ); }}}; }
156macro_rules! __ra_macro_fixture155 {($ty : ident )=>{# [ cfg ( feature = "clone-impls" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "clone-impls" )))] impl Clone for $ty { fn clone (& self )-> Self {$ty { repr : self . repr . clone (), }}}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl PartialEq for $ty { fn eq (& self , other : & Self )-> bool { self . repr . token . to_string ()== other . repr . token . to_string ()}}# [ cfg ( feature = "extra-traits" )]# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "extra-traits" )))] impl Hash for $ty { fn hash < H > (& self , state : & mut H ) where H : Hasher , { self . repr . token . to_string (). hash ( state ); }}# [ cfg ( feature = "parsing" )]# [ doc ( hidden )]# [ allow ( non_snake_case )] pub fn $ty ( marker : lookahead :: TokenMarker )-> $ty { match marker {}}}; }
157macro_rules! __ra_macro_fixture156 {($name : ident / 1 )=>{ impl Deref for $name { type Target = WithSpan ; fn deref (& self )-> & Self :: Target { unsafe {&* ( self as * const Self as * const WithSpan )}}} impl DerefMut for $name { fn deref_mut (& mut self )-> & mut Self :: Target { unsafe {& mut * ( self as * mut Self as * mut WithSpan )}}}}; ($name : ident /$len : tt )=>{}; }
158macro_rules! __ra_macro_fixture157 {($($await_rule : tt )*)=>{# [ doc = " A type-macro that expands to the name of the Rust type representation of a" ]# [ doc = " given token." ]# [ doc = "" ]# [ doc = " See the [token module] documentation for details and examples." ]# [ doc = "" ]# [ doc = " [token module]: crate::token" ]# [ macro_export ] macro_rules ! Token {[ abstract ]=>{$crate :: token :: Abstract }; [ as ]=>{$crate :: token :: As }; [ async ]=>{$crate :: token :: Async }; [ auto ]=>{$crate :: token :: Auto }; $($await_rule =>{$crate :: token :: Await };)* [ become ]=>{$crate :: token :: Become }; [ box ]=>{$crate :: token :: Box }; [ break ]=>{$crate :: token :: Break }; [ const ]=>{$crate :: token :: Const }; [ continue ]=>{$crate :: token :: Continue }; [ crate ]=>{$crate :: token :: Crate }; [ default ]=>{$crate :: token :: Default }; [ do ]=>{$crate :: token :: Do }; [ dyn ]=>{$crate :: token :: Dyn }; [ else ]=>{$crate :: token :: Else }; [ enum ]=>{$crate :: token :: Enum }; [ extern ]=>{$crate :: token :: Extern }; [ final ]=>{$crate :: token :: Final }; [ fn ]=>{$crate :: token :: Fn }; [ for ]=>{$crate :: token :: For }; [ if ]=>{$crate :: token :: If }; [ impl ]=>{$crate :: token :: Impl }; [ in ]=>{$crate :: token :: In }; [ let ]=>{$crate :: token :: Let }; [ loop ]=>{$crate :: token :: Loop }; [ macro ]=>{$crate :: token :: Macro }; [ match ]=>{$crate :: token :: Match }; [ mod ]=>{$crate :: token :: Mod }; [ move ]=>{$crate :: token :: Move }; [ mut ]=>{$crate :: token :: Mut }; [ override ]=>{$crate :: token :: Override }; [ priv ]=>{$crate :: token :: Priv }; [ pub ]=>{$crate :: token :: Pub }; [ ref ]=>{$crate :: token :: Ref }; [ return ]=>{$crate :: token :: Return }; [ Self ]=>{$crate :: token :: SelfType }; [ self ]=>{$crate :: token :: SelfValue }; [ static ]=>{$crate :: token :: Static }; [ struct ]=>{$crate :: token :: Struct }; [ super ]=>{$crate :: token :: Super }; [ trait ]=>{$crate :: token :: Trait }; [ try ]=>{$crate :: token :: Try }; [ type ]=>{$crate :: token :: Type }; [ typeof ]=>{$crate :: token :: Typeof }; [ union ]=>{$crate :: token :: Union }; [ unsafe ]=>{$crate :: token :: Unsafe }; [ unsized ]=>{$crate :: token :: Unsized }; [ use ]=>{$crate :: token :: Use }; [ virtual ]=>{$crate :: token :: Virtual }; [ where ]=>{$crate :: token :: Where }; [ while ]=>{$crate :: token :: While }; [ yield ]=>{$crate :: token :: Yield }; [+]=>{$crate :: token :: Add }; [+=]=>{$crate :: token :: AddEq }; [&]=>{$crate :: token :: And }; [&&]=>{$crate :: token :: AndAnd }; [&=]=>{$crate :: token :: AndEq }; [@]=>{$crate :: token :: At }; [!]=>{$crate :: token :: Bang }; [^]=>{$crate :: token :: Caret }; [^=]=>{$crate :: token :: CaretEq }; [:]=>{$crate :: token :: Colon }; [::]=>{$crate :: token :: Colon2 }; [,]=>{$crate :: token :: Comma }; [/]=>{$crate :: token :: Div }; [/=]=>{$crate :: token :: DivEq }; [$]=>{$crate :: token :: Dollar }; [.]=>{$crate :: token :: Dot }; [..]=>{$crate :: token :: Dot2 }; [...]=>{$crate :: token :: Dot3 }; [..=]=>{$crate :: token :: DotDotEq }; [=]=>{$crate :: token :: Eq }; [==]=>{$crate :: token :: EqEq }; [>=]=>{$crate :: token :: Ge }; [>]=>{$crate :: token :: Gt }; [<=]=>{$crate :: token :: Le }; [<]=>{$crate :: token :: Lt }; [*=]=>{$crate :: token :: MulEq }; [!=]=>{$crate :: token :: Ne }; [|]=>{$crate :: token :: Or }; [|=]=>{$crate :: token :: OrEq }; [||]=>{$crate :: token :: OrOr }; [#]=>{$crate :: token :: Pound }; [?]=>{$crate :: token :: Question }; [->]=>{$crate :: token :: RArrow }; [<-]=>{$crate :: token :: LArrow }; [%]=>{$crate :: token :: Rem }; [%=]=>{$crate :: token :: RemEq }; [=>]=>{$crate :: token :: FatArrow }; [;]=>{$crate :: token :: Semi }; [<<]=>{$crate :: token :: Shl }; [<<=]=>{$crate :: token :: ShlEq }; [>>]=>{$crate :: token :: Shr }; [>>=]=>{$crate :: token :: ShrEq }; [*]=>{$crate :: token :: Star }; [-]=>{$crate :: token :: Sub }; [-=]=>{$crate :: token :: SubEq }; [~]=>{$crate :: token :: Tilde }; [_]=>{$crate :: token :: Underscore }; }}; }
159macro_rules! __ra_macro_fixture158 {($mac : ident ! ($(# [$m : meta ])* $pub : ident $($t : tt )*))=>{ check_keyword_matches ! ( pub $pub ); $mac ! ([$(# [$m ])* $pub ]$($t )*); }; }
160macro_rules! __ra_macro_fixture159 {($pub : ident $enum : ident $name : ident {$($(# [$variant_attr : meta ])* $variant : ident $(($($member : ident )::+))*, )* }$($remaining : tt )* )=>{ check_keyword_matches ! ( pub $pub ); check_keyword_matches ! ( enum $enum ); $($(ast_enum_from_struct ! ($name ::$variant , $($member )::+); )*)* # [ cfg ( feature = "printing" )] generate_to_tokens ! {$($remaining )* () tokens $name {$($variant $($($member )::+)*,)* }}}; }
161macro_rules! __ra_macro_fixture160 {($ident : ident )=>{ impl $crate :: token :: CustomToken for $ident { fn peek ( cursor : $crate :: buffer :: Cursor )-> $crate :: __private :: bool { if let Some (( ident , _rest ))= cursor . ident (){ ident == stringify ! ($ident )} else { false }} fn display ()-> & 'static $crate :: __private :: str { concat ! ( "`" , stringify ! ($ident ), "`" )}} impl $crate :: parse :: Parse for $ident { fn parse ( input : $crate :: parse :: ParseStream )-> $crate :: parse :: Result <$ident > { input . step (| cursor | { if let $crate :: __private :: Some (( ident , rest ))= cursor . ident (){ if ident == stringify ! ($ident ){ return $crate :: __private :: Ok (($ident { span : ident . span ()}, rest )); }}$crate :: __private :: Err ( cursor . error ( concat ! ( "expected `" , stringify ! ($ident ), "`" )))})}}}; }
162macro_rules! __ra_macro_fixture161 {($ident : ident )=>{ impl $crate :: __private :: ToTokens for $ident { fn to_tokens (& self , tokens : & mut $crate :: __private :: TokenStream2 ){ let ident = $crate :: Ident :: new ( stringify ! ($ident ), self . span ); $crate :: __private :: TokenStreamExt :: append ( tokens , ident ); }}}; }
163macro_rules! __ra_macro_fixture162 {($ident : ident )=>{ impl $crate :: __private :: Copy for $ident {} impl $crate :: __private :: Clone for $ident { fn clone (& self )-> Self {* self }}}; }
164macro_rules! __ra_macro_fixture163 {($ident : ident )=>{ impl $crate :: __private :: Debug for $ident { fn fmt (& self , f : & mut $crate :: __private :: Formatter )-> $crate :: __private :: fmt :: Result {$crate :: __private :: Formatter :: write_str ( f , concat ! ( "Keyword [" , stringify ! ($ident ), "]" ), )}} impl $crate :: __private :: Eq for $ident {} impl $crate :: __private :: PartialEq for $ident { fn eq (& self , _other : & Self )-> $crate :: __private :: bool { true }} impl $crate :: __private :: Hash for $ident { fn hash < __H : $crate :: __private :: Hasher > (& self , _state : & mut __H ){}}}; }
165macro_rules! __ra_macro_fixture164 {( struct struct )=>{}; ( enum enum )=>{}; ( pub pub )=>{}; }
166macro_rules! __ra_macro_fixture165 {($name : ident :: Verbatim , $member : ident )=>{}; ($name : ident ::$variant : ident , crate :: private )=>{}; ($name : ident ::$variant : ident , $member : ident )=>{ impl From <$member > for $name { fn from ( e : $member )-> $name {$name ::$variant ( e )}}}; }
167macro_rules! __ra_macro_fixture166 {( do_not_generate_to_tokens $($foo : tt )*)=>(); (($($arms : tt )*)$tokens : ident $name : ident {$variant : ident , $($next : tt )*})=>{ generate_to_tokens ! (($($arms )* $name ::$variant =>{})$tokens $name {$($next )* }); }; (($($arms : tt )*)$tokens : ident $name : ident {$variant : ident $member : ident , $($next : tt )*})=>{ generate_to_tokens ! (($($arms )* $name ::$variant ( _e )=> _e . to_tokens ($tokens ),)$tokens $name {$($next )* }); }; (($($arms : tt )*)$tokens : ident $name : ident {$variant : ident crate :: private , $($next : tt )*})=>{ generate_to_tokens ! (($($arms )* $name ::$variant (_)=> unreachable ! (),)$tokens $name {$($next )* }); }; (($($arms : tt )*)$tokens : ident $name : ident {})=>{# [ cfg_attr ( doc_cfg , doc ( cfg ( feature = "printing" )))] impl :: quote :: ToTokens for $name { fn to_tokens (& self , $tokens : & mut :: proc_macro2 :: TokenStream ){ match self {$($arms )* }}}}; }
168macro_rules! __ra_macro_fixture167 {($(# [$attr : meta ])* static ref $N : ident : $T : ty = $e : expr ; $($t : tt )*)=>{ __lazy_static_internal ! ($(# [$attr ])* () static ref $N : $T = $e ; $($t )*); }; ($(# [$attr : meta ])* pub static ref $N : ident : $T : ty = $e : expr ; $($t : tt )*)=>{ __lazy_static_internal ! ($(# [$attr ])* ( pub ) static ref $N : $T = $e ; $($t )*); }; ($(# [$attr : meta ])* pub ($($vis : tt )+) static ref $N : ident : $T : ty = $e : expr ; $($t : tt )*)=>{ __lazy_static_internal ! ($(# [$attr ])* ( pub ($($vis )+)) static ref $N : $T = $e ; $($t )*); }; ()=>()}
169macro_rules! __ra_macro_fixture168 {($($record : ident ($($whatever : tt )+ )),+ )=>{$(impl_value ! {$record ($($whatever )+ )})+ }}
170macro_rules! __ra_macro_fixture169 {($($len : tt ),+ )=>{$(impl < 'a > private :: ValidLen < 'a > for [(& 'a Field , Option <& 'a ( dyn Value + 'a )>); $len ]{})+ }}
171macro_rules! __ra_macro_fixture170 {($(# [$attr : meta ])* ($($vis : tt )*) static ref $N : ident : $T : ty = $e : expr ; $($t : tt )*)=>{ __lazy_static_internal ! (@ MAKE TY , $(# [$attr ])*, ($($vis )*), $N ); __lazy_static_internal ! (@ TAIL , $N : $T = $e ); lazy_static ! ($($t )*); }; (@ TAIL , $N : ident : $T : ty = $e : expr )=>{ impl $crate :: __Deref for $N { type Target = $T ; fn deref (& self )-> &$T {# [ inline ( always )] fn __static_ref_initialize ()-> $T {$e }# [ inline ( always )] fn __stability ()-> & 'static $T { __lazy_static_create ! ( LAZY , $T ); LAZY . get ( __static_ref_initialize )} __stability ()}} impl $crate :: LazyStatic for $N { fn initialize ( lazy : & Self ){ let _ = &** lazy ; }}}; (@ MAKE TY , $(# [$attr : meta ])*, ($($vis : tt )*), $N : ident )=>{# [ allow ( missing_copy_implementations )]# [ allow ( non_camel_case_types )]# [ allow ( dead_code )]$(# [$attr ])* $($vis )* struct $N { __private_field : ()}# [ doc ( hidden )]$($vis )* static $N : $N = $N { __private_field : ()}; }; ()=>()}
172macro_rules! __ra_macro_fixture171 {($record : ident ($($value_ty : tt ),+ ))=>{$(impl_one_value ! ($value_ty , | this : $value_ty | this , $record ); )+ }; ($record : ident ($($value_ty : tt ),+ as $as_ty : ty ))=>{$(impl_one_value ! ($value_ty , | this : $value_ty | this as $as_ty , $record ); )+ }; }
173macro_rules! __ra_macro_fixture172 {( bool , $op : expr , $record : ident )=>{ impl_one_value ! ( normal , bool , $op , $record ); }; ($value_ty : tt , $op : expr , $record : ident )=>{ impl_one_value ! ( normal , $value_ty , $op , $record ); impl_one_value ! ( nonzero , $value_ty , $op , $record ); }; ( normal , $value_ty : tt , $op : expr , $record : ident )=>{ impl $crate :: sealed :: Sealed for $value_ty {} impl $crate :: field :: Value for $value_ty { fn record (& self , key : &$crate :: field :: Field , visitor : & mut dyn $crate :: field :: Visit ){ visitor .$record ( key , $op (* self ))}}}; ( nonzero , $value_ty : tt , $op : expr , $record : ident )=>{# [ allow ( clippy :: useless_attribute , unused )] use num ::*; impl $crate :: sealed :: Sealed for ty_to_nonzero ! ($value_ty ){} impl $crate :: field :: Value for ty_to_nonzero ! ($value_ty ){ fn record (& self , key : &$crate :: field :: Field , visitor : & mut dyn $crate :: field :: Visit ){ visitor .$record ( key , $op ( self . get ()))}}}; }
174macro_rules! __ra_macro_fixture173 {($(# [ doc $($doc : tt )*])* # [ project = $proj_mut_ident : ident ]# [ project_ref = $proj_ref_ident : ident ]# [ project_replace = $proj_replace_ident : ident ]$($tt : tt )* )=>{$crate :: __pin_project_internal ! {[$proj_mut_ident ][$proj_ref_ident ][$proj_replace_ident ]$(# [ doc $($doc )*])* $($tt )* }}; ($(# [ doc $($doc : tt )*])* # [ project = $proj_mut_ident : ident ]# [ project_ref = $proj_ref_ident : ident ]$($tt : tt )* )=>{$crate :: __pin_project_internal ! {[$proj_mut_ident ][$proj_ref_ident ][]$(# [ doc $($doc )*])* $($tt )* }}; ($(# [ doc $($doc : tt )*])* # [ project = $proj_mut_ident : ident ]# [ project_replace = $proj_replace_ident : ident ]$($tt : tt )* )=>{$crate :: __pin_project_internal ! {[$proj_mut_ident ][][$proj_replace_ident ]$(# [ doc $($doc )*])* $($tt )* }}; ($(# [ doc $($doc : tt )*])* # [ project_ref = $proj_ref_ident : ident ]# [ project_replace = $proj_replace_ident : ident ]$($tt : tt )* )=>{$crate :: __pin_project_internal ! {[][$proj_ref_ident ][$proj_replace_ident ]$(# [ doc $($doc )*])* $($tt )* }}; ($(# [ doc $($doc : tt )*])* # [ project = $proj_mut_ident : ident ]$($tt : tt )* )=>{$crate :: __pin_project_internal ! {[$proj_mut_ident ][][]$(# [ doc $($doc )*])* $($tt )* }}; ($(# [ doc $($doc : tt )*])* # [ project_ref = $proj_ref_ident : ident ]$($tt : tt )* )=>{$crate :: __pin_project_internal ! {[][$proj_ref_ident ][]$(# [ doc $($doc )*])* $($tt )* }}; ($(# [ doc $($doc : tt )*])* # [ project_replace = $proj_replace_ident : ident ]$($tt : tt )* )=>{$crate :: __pin_project_internal ! {[][][$proj_replace_ident ]$(# [ doc $($doc )*])* $($tt )* }}; ($($tt : tt )* )=>{$crate :: __pin_project_internal ! {[][][]$($tt )* }}; }
175macro_rules! __ra_macro_fixture174 {(@ struct => internal ; [$($proj_mut_ident : ident )?][$($proj_ref_ident : ident )?][$($proj_replace_ident : ident )?][$proj_vis : vis ][$(# [$attrs : meta ])* $vis : vis struct $ident : ident ][$($def_generics : tt )*][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )*)?]{$($(# [$pin : ident ])? $field_vis : vis $field : ident : $field_ty : ty ),+ })=>{$(# [$attrs ])* $vis struct $ident $($def_generics )* $(where $($where_clause )*)? {$($field_vis $field : $field_ty ),+ }$crate :: __pin_project_internal ! {@ struct => make_proj_ty => named ; [$proj_vis ][$($proj_mut_ident )?][ make_proj_field_mut ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($(# [$pin ])? $field_vis $field : $field_ty ),+ }}$crate :: __pin_project_internal ! {@ struct => make_proj_ty => named ; [$proj_vis ][$($proj_ref_ident )?][ make_proj_field_ref ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($(# [$pin ])? $field_vis $field : $field_ty ),+ }}$crate :: __pin_project_internal ! {@ struct => make_proj_replace_ty => named ; [$proj_vis ][$($proj_replace_ident )?][ make_proj_field_replace ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($(# [$pin ])? $field_vis $field : $field_ty ),+ }}# [ allow ( explicit_outlives_requirements )]# [ allow ( single_use_lifetimes )]# [ allow ( clippy :: unknown_clippy_lints )]# [ allow ( clippy :: redundant_pub_crate )]# [ allow ( clippy :: used_underscore_binding )] const _: ()= {$crate :: __pin_project_internal ! {@ struct => make_proj_ty => unnamed ; [$proj_vis ][$($proj_mut_ident )?][ Projection ][ make_proj_field_mut ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($(# [$pin ])? $field_vis $field : $field_ty ),+ }}$crate :: __pin_project_internal ! {@ struct => make_proj_ty => unnamed ; [$proj_vis ][$($proj_ref_ident )?][ ProjectionRef ][ make_proj_field_ref ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($(# [$pin ])? $field_vis $field : $field_ty ),+ }}$crate :: __pin_project_internal ! {@ struct => make_proj_replace_ty => unnamed ; [$proj_vis ][$($proj_replace_ident )?][ ProjectionReplace ][ make_proj_field_replace ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($(# [$pin ])? $field_vis $field : $field_ty ),+ }} impl <$($impl_generics )*> $ident <$($ty_generics )*> $(where $($where_clause )*)? {$crate :: __pin_project_internal ! {@ struct => make_proj_method ; [$proj_vis ][$($proj_mut_ident )?][ Projection ][ project get_unchecked_mut mut ][$($ty_generics )*]{$($(# [$pin ])? $field_vis $field ),+ }}$crate :: __pin_project_internal ! {@ struct => make_proj_method ; [$proj_vis ][$($proj_ref_ident )?][ ProjectionRef ][ project_ref get_ref ][$($ty_generics )*]{$($(# [$pin ])? $field_vis $field ),+ }}$crate :: __pin_project_internal ! {@ struct => make_proj_replace_method ; [$proj_vis ][$($proj_replace_ident )?][ ProjectionReplace ][$($ty_generics )*]{$($(# [$pin ])? $field_vis $field ),+ }}}$crate :: __pin_project_internal ! {@ make_unpin_impl ; [$vis $ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]$($field : $crate :: __pin_project_internal ! (@ make_unpin_bound ; $(# [$pin ])? $field_ty )),+ }$crate :: __pin_project_internal ! {@ make_drop_impl ; [$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]}# [ forbid ( safe_packed_borrows )] fn __assert_not_repr_packed <$($impl_generics )*> ( this : &$ident <$($ty_generics )*>)$(where $($where_clause )*)? {$(let _ = & this .$field ; )+ }}; }; (@ enum => internal ; [$($proj_mut_ident : ident )?][$($proj_ref_ident : ident )?][$($proj_replace_ident : ident )?][$proj_vis : vis ][$(# [$attrs : meta ])* $vis : vis enum $ident : ident ][$($def_generics : tt )*][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )*)?]{$($(# [$variant_attrs : meta ])* $variant : ident $({$($(# [$pin : ident ])? $field : ident : $field_ty : ty ),+ })? ),+ })=>{$(# [$attrs ])* $vis enum $ident $($def_generics )* $(where $($where_clause )*)? {$($(# [$variant_attrs ])* $variant $({$($field : $field_ty ),+ })? ),+ }$crate :: __pin_project_internal ! {@ enum => make_proj_ty ; [$proj_vis ][$($proj_mut_ident )?][ make_proj_field_mut ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($variant $({$($(# [$pin ])? $field : $field_ty ),+ })? ),+ }}$crate :: __pin_project_internal ! {@ enum => make_proj_ty ; [$proj_vis ][$($proj_ref_ident )?][ make_proj_field_ref ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($variant $({$($(# [$pin ])? $field : $field_ty ),+ })? ),+ }}$crate :: __pin_project_internal ! {@ enum => make_proj_replace_ty ; [$proj_vis ][$($proj_replace_ident )?][ make_proj_field_replace ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]{$($variant $({$($(# [$pin ])? $field : $field_ty ),+ })? ),+ }}# [ allow ( single_use_lifetimes )]# [ allow ( clippy :: unknown_clippy_lints )]# [ allow ( clippy :: used_underscore_binding )] const _: ()= { impl <$($impl_generics )*> $ident <$($ty_generics )*> $(where $($where_clause )*)? {$crate :: __pin_project_internal ! {@ enum => make_proj_method ; [$proj_vis ][$($proj_mut_ident )?][ project get_unchecked_mut mut ][$($ty_generics )*]{$($variant $({$($(# [$pin ])? $field ),+ })? ),+ }}$crate :: __pin_project_internal ! {@ enum => make_proj_method ; [$proj_vis ][$($proj_ref_ident )?][ project_ref get_ref ][$($ty_generics )*]{$($variant $({$($(# [$pin ])? $field ),+ })? ),+ }}$crate :: __pin_project_internal ! {@ enum => make_proj_replace_method ; [$proj_vis ][$($proj_replace_ident )?][$($ty_generics )*]{$($variant $({$($(# [$pin ])? $field ),+ })? ),+ }}}$crate :: __pin_project_internal ! {@ make_unpin_impl ; [$vis $ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]$($variant : ($($($crate :: __pin_project_internal ! (@ make_unpin_bound ; $(# [$pin ])? $field_ty )),+ )?)),+ }$crate :: __pin_project_internal ! {@ make_drop_impl ; [$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]}}; }; (@ struct => make_proj_ty => unnamed ; [$proj_vis : vis ][$_proj_ty_ident : ident ][$proj_ty_ident : ident ][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($field : tt )* )=>{}; (@ struct => make_proj_ty => unnamed ; [$proj_vis : vis ][][$proj_ty_ident : ident ][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($field : tt )* )=>{$crate :: __pin_project_internal ! {@ struct => make_proj_ty => named ; [$proj_vis ][$proj_ty_ident ][$make_proj_field ][$ident ][$($impl_generics )*][$($ty_generics )*][$(where $($where_clause )*)?]$($field )* }}; (@ struct => make_proj_ty => named ; [$proj_vis : vis ][$proj_ty_ident : ident ][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]{$($(# [$pin : ident ])? $field_vis : vis $field : ident : $field_ty : ty ),+ })=>{# [ allow ( dead_code )]# [ allow ( single_use_lifetimes )]# [ allow ( clippy :: unknown_clippy_lints )]# [ allow ( clippy :: mut_mut )]# [ allow ( clippy :: redundant_pub_crate )]# [ allow ( clippy :: ref_option_ref )]# [ allow ( clippy :: type_repetition_in_bounds )]$proj_vis struct $proj_ty_ident < '__pin , $($impl_generics )*> where $ident <$($ty_generics )*>: '__pin $(, $($where_clause )*)? {$($field_vis $field : $crate :: __pin_project_internal ! (@$make_proj_field ; $(# [$pin ])? $field_ty )),+ }}; (@ struct => make_proj_ty => named ; [$proj_vis : vis ][][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($field : tt )* )=>{}; (@ struct => make_proj_replace_ty => unnamed ; [$proj_vis : vis ][$_proj_ty_ident : ident ][$proj_ty_ident : ident ][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($field : tt )* )=>{}; (@ struct => make_proj_replace_ty => unnamed ; [$proj_vis : vis ][][$proj_ty_ident : ident ][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($field : tt )* )=>{}; (@ struct => make_proj_replace_ty => named ; [$proj_vis : vis ][$proj_ty_ident : ident ][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]{$($(# [$pin : ident ])? $field_vis : vis $field : ident : $field_ty : ty ),+ })=>{# [ allow ( dead_code )]# [ allow ( single_use_lifetimes )]# [ allow ( clippy :: mut_mut )]# [ allow ( clippy :: redundant_pub_crate )]# [ allow ( clippy :: type_repetition_in_bounds )]$proj_vis struct $proj_ty_ident <$($impl_generics )*> where $($($where_clause )*)? {$($field_vis $field : $crate :: __pin_project_internal ! (@$make_proj_field ; $(# [$pin ])? $field_ty )),+ }}; (@ struct => make_proj_replace_ty => named ; [$proj_vis : vis ][][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($field : tt )* )=>{}; (@ enum => make_proj_ty ; [$proj_vis : vis ][$proj_ty_ident : ident ][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]{$($variant : ident $({$($(# [$pin : ident ])? $field : ident : $field_ty : ty ),+ })? ),+ })=>{# [ allow ( dead_code )]# [ allow ( single_use_lifetimes )]# [ allow ( clippy :: unknown_clippy_lints )]# [ allow ( clippy :: mut_mut )]# [ allow ( clippy :: redundant_pub_crate )]# [ allow ( clippy :: ref_option_ref )]# [ allow ( clippy :: type_repetition_in_bounds )]$proj_vis enum $proj_ty_ident < '__pin , $($impl_generics )*> where $ident <$($ty_generics )*>: '__pin $(, $($where_clause )*)? {$($variant $({$($field : $crate :: __pin_project_internal ! (@$make_proj_field ; $(# [$pin ])? $field_ty )),+ })? ),+ }}; (@ enum => make_proj_ty ; [$proj_vis : vis ][][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($variant : tt )* )=>{}; (@ enum => make_proj_replace_ty ; [$proj_vis : vis ][$proj_ty_ident : ident ][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]{$($variant : ident $({$($(# [$pin : ident ])? $field : ident : $field_ty : ty ),+ })? ),+ })=>{# [ allow ( dead_code )]# [ allow ( single_use_lifetimes )]# [ allow ( clippy :: mut_mut )]# [ allow ( clippy :: redundant_pub_crate )]# [ allow ( clippy :: type_repetition_in_bounds )]$proj_vis enum $proj_ty_ident <$($impl_generics )*> where $($($where_clause )*)? {$($variant $({$($field : $crate :: __pin_project_internal ! (@$make_proj_field ; $(# [$pin ])? $field_ty )),+ })? ),+ }}; (@ enum => make_proj_replace_ty ; [$proj_vis : vis ][][$make_proj_field : ident ][$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($variant : tt )* )=>{}; (@ make_proj_replace_block ; [$($proj_path : tt )+]{$($(# [$pin : ident ])? $field_vis : vis $field : ident ),+ })=>{ let result = $($proj_path )* {$($field : $crate :: __pin_project_internal ! (@ make_replace_field_proj ; $(# [$pin ])? $field )),+ }; {($($crate :: __pin_project_internal ! (@ make_unsafe_drop_in_place_guard ; $(# [$pin ])? $field ), )* ); } result }; (@ make_proj_replace_block ; [$($proj_path : tt )+])=>{$($proj_path )* }; (@ struct => make_proj_method ; [$proj_vis : vis ][$proj_ty_ident : ident ][$_proj_ty_ident : ident ][$method_ident : ident $get_method : ident $($mut : ident )?][$($ty_generics : tt )*]{$($(# [$pin : ident ])? $field_vis : vis $field : ident ),+ })=>{$proj_vis fn $method_ident < '__pin > ( self : $crate :: __private :: Pin <& '__pin $($mut )? Self >, )-> $proj_ty_ident < '__pin , $($ty_generics )*> { unsafe { let Self {$($field ),* }= self .$get_method (); $proj_ty_ident {$($field : $crate :: __pin_project_internal ! (@ make_unsafe_field_proj ; $(# [$pin ])? $field )),+ }}}}; (@ struct => make_proj_method ; [$proj_vis : vis ][][$proj_ty_ident : ident ][$method_ident : ident $get_method : ident $($mut : ident )?][$($ty_generics : tt )*]$($variant : tt )* )=>{$crate :: __pin_project_internal ! {@ struct => make_proj_method ; [$proj_vis ][$proj_ty_ident ][$proj_ty_ident ][$method_ident $get_method $($mut )?][$($ty_generics )*]$($variant )* }}; (@ struct => make_proj_replace_method ; [$proj_vis : vis ][$proj_ty_ident : ident ][$_proj_ty_ident : ident ][$($ty_generics : tt )*]{$($(# [$pin : ident ])? $field_vis : vis $field : ident ),+ })=>{$proj_vis fn project_replace ( self : $crate :: __private :: Pin <& mut Self >, replacement : Self , )-> $proj_ty_ident <$($ty_generics )*> { unsafe { let __self_ptr : * mut Self = self . get_unchecked_mut (); let __guard = $crate :: __private :: UnsafeOverwriteGuard { target : __self_ptr , value : $crate :: __private :: ManuallyDrop :: new ( replacement ), }; let Self {$($field ),* }= & mut * __self_ptr ; $crate :: __pin_project_internal ! {@ make_proj_replace_block ; [$proj_ty_ident ]{$($(# [$pin ])? $field ),+ }}}}}; (@ struct => make_proj_replace_method ; [$proj_vis : vis ][][$proj_ty_ident : ident ][$($ty_generics : tt )*]$($variant : tt )* )=>{}; (@ enum => make_proj_method ; [$proj_vis : vis ][$proj_ty_ident : ident ][$method_ident : ident $get_method : ident $($mut : ident )?][$($ty_generics : tt )*]{$($variant : ident $({$($(# [$pin : ident ])? $field : ident ),+ })? ),+ })=>{$proj_vis fn $method_ident < '__pin > ( self : $crate :: __private :: Pin <& '__pin $($mut )? Self >, )-> $proj_ty_ident < '__pin , $($ty_generics )*> { unsafe { match self .$get_method (){$(Self ::$variant $({$($field ),+ })? =>{$proj_ty_ident ::$variant $({$($field : $crate :: __pin_project_internal ! (@ make_unsafe_field_proj ; $(# [$pin ])? $field )),+ })? }),+ }}}}; (@ enum => make_proj_method ; [$proj_vis : vis ][][$method_ident : ident $get_method : ident $($mut : ident )?][$($ty_generics : tt )*]$($variant : tt )* )=>{}; (@ enum => make_proj_replace_method ; [$proj_vis : vis ][$proj_ty_ident : ident ][$($ty_generics : tt )*]{$($variant : ident $({$($(# [$pin : ident ])? $field : ident ),+ })? ),+ })=>{$proj_vis fn project_replace ( self : $crate :: __private :: Pin <& mut Self >, replacement : Self , )-> $proj_ty_ident <$($ty_generics )*> { unsafe { let __self_ptr : * mut Self = self . get_unchecked_mut (); let __guard = $crate :: __private :: UnsafeOverwriteGuard { target : __self_ptr , value : $crate :: __private :: ManuallyDrop :: new ( replacement ), }; match & mut * __self_ptr {$(Self ::$variant $({$($field ),+ })? =>{$crate :: __pin_project_internal ! {@ make_proj_replace_block ; [$proj_ty_ident :: $variant ]$({$($(# [$pin ])? $field ),+ })? }}),+ }}}}; (@ enum => make_proj_replace_method ; [$proj_vis : vis ][][$($ty_generics : tt )*]$($variant : tt )* )=>{}; (@ make_unpin_impl ; [$vis : vis $ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?]$($field : tt )* )=>{# [ allow ( non_snake_case )]$vis struct __Origin < '__pin , $($impl_generics )*> $(where $($where_clause )*)? { __dummy_lifetime : $crate :: __private :: PhantomData <& '__pin ()>, $($field )* } impl < '__pin , $($impl_generics )*> $crate :: __private :: Unpin for $ident <$($ty_generics )*> where __Origin < '__pin , $($ty_generics )*>: $crate :: __private :: Unpin $(, $($where_clause )*)? {}}; (@ make_drop_impl ; [$ident : ident ][$($impl_generics : tt )*][$($ty_generics : tt )*][$(where $($where_clause : tt )* )?])=>{ trait MustNotImplDrop {}# [ allow ( clippy :: drop_bounds , drop_bounds )] impl < T : $crate :: __private :: Drop > MustNotImplDrop for T {} impl <$($impl_generics )*> MustNotImplDrop for $ident <$($ty_generics )*> $(where $($where_clause )*)? {}}; (@ make_unpin_bound ; # [ pin ]$field_ty : ty )=>{$field_ty }; (@ make_unpin_bound ; $field_ty : ty )=>{$crate :: __private :: AlwaysUnpin <$field_ty > }; (@ make_unsafe_field_proj ; # [ pin ]$field : ident )=>{$crate :: __private :: Pin :: new_unchecked ($field )}; (@ make_unsafe_field_proj ; $field : ident )=>{$field }; (@ make_replace_field_proj ; # [ pin ]$field : ident )=>{$crate :: __private :: PhantomData }; (@ make_replace_field_proj ; $field : ident )=>{$crate :: __private :: ptr :: read ($field )}; (@ make_unsafe_drop_in_place_guard ; # [ pin ]$field : ident )=>{$crate :: __private :: UnsafeDropInPlaceGuard ($field )}; (@ make_unsafe_drop_in_place_guard ; $field : ident )=>{()}; (@ make_proj_field_mut ; # [ pin ]$field_ty : ty )=>{$crate :: __private :: Pin <& '__pin mut ($field_ty )> }; (@ make_proj_field_mut ; $field_ty : ty )=>{& '__pin mut ($field_ty )}; (@ make_proj_field_ref ; # [ pin ]$field_ty : ty )=>{$crate :: __private :: Pin <& '__pin ($field_ty )> }; (@ make_proj_field_ref ; $field_ty : ty )=>{& '__pin ($field_ty )}; (@ make_proj_field_replace ; # [ pin ]$field_ty : ty )=>{$crate :: __private :: PhantomData <$field_ty > }; (@ make_proj_field_replace ; $field_ty : ty )=>{$field_ty }; ([$($proj_mut_ident : ident )?][$($proj_ref_ident : ident )?][$($proj_replace_ident : ident )?]$(# [$attrs : meta ])* pub struct $ident : ident $(< $($lifetime : lifetime $(: $lifetime_bound : lifetime )? ),* $(,)? $($generics : ident $(: $generics_bound : path )? $(: ?$generics_unsized_bound : path )? $(: $generics_lifetime_bound : lifetime )? $(= $generics_default : ty )? ),* $(,)? >)? $(where $($where_clause_ty : ty $(: $where_clause_bound : path )? $(: ?$where_clause_unsized_bound : path )? $(: $where_clause_lifetime_bound : lifetime )? ),* $(,)? )? {$($(# [$pin : ident ])? $field_vis : vis $field : ident : $field_ty : ty ),+ $(,)? })=>{$crate :: __pin_project_internal ! {@ struct => internal ; [$($proj_mut_ident )?][$($proj_ref_ident )?][$($proj_replace_ident )?][ pub ( crate )][$(# [$attrs ])* pub struct $ident ][$(< $($lifetime $(: $lifetime_bound )? ,)* $($generics $(: $generics_bound )? $(: ?$generics_unsized_bound )? $(: $generics_lifetime_bound )? $(= $generics_default )? ),* >)?][$($($lifetime $(: $lifetime_bound )? ,)* $($generics $(: $generics_bound )? $(: ?$generics_unsized_bound )? $(: $generics_lifetime_bound )? ),* )?][$($($lifetime ,)* $($generics ),* )?][$(where $($where_clause_ty $(: $where_clause_bound )? $(: ?$where_clause_unsized_bound )? $(: $where_clause_lifetime_bound )? ),* )?]{$($(# [$pin ])? $field_vis $field : $field_ty ),+ }}}; ([$($proj_mut_ident : ident )?][$($proj_ref_ident : ident )?][$($proj_replace_ident : ident )?]$(# [$attrs : meta ])* $vis : vis struct $ident : ident $(< $($lifetime : lifetime $(: $lifetime_bound : lifetime )? ),* $(,)? $($generics : ident $(: $generics_bound : path )? $(: ?$generics_unsized_bound : path )? $(: $generics_lifetime_bound : lifetime )? $(= $generics_default : ty )? ),* $(,)? >)? $(where $($where_clause_ty : ty $(: $where_clause_bound : path )? $(: ?$where_clause_unsized_bound : path )? $(: $where_clause_lifetime_bound : lifetime )? ),* $(,)? )? {$($(# [$pin : ident ])? $field_vis : vis $field : ident : $field_ty : ty ),+ $(,)? })=>{$crate :: __pin_project_internal ! {@ struct => internal ; [$($proj_mut_ident )?][$($proj_ref_ident )?][$($proj_replace_ident )?][$vis ][$(# [$attrs ])* $vis struct $ident ][$(< $($lifetime $(: $lifetime_bound )? ,)* $($generics $(: $generics_bound )? $(: ?$generics_unsized_bound )? $(: $generics_lifetime_bound )? $(= $generics_default )? ),* >)?][$($($lifetime $(: $lifetime_bound )? ,)* $($generics $(: $generics_bound )? $(: ?$generics_unsized_bound )? $(: $generics_lifetime_bound )? ),* )?][$($($lifetime ,)* $($generics ),* )?][$(where $($where_clause_ty $(: $where_clause_bound )? $(: ?$where_clause_unsized_bound )? $(: $where_clause_lifetime_bound )? ),* )?]{$($(# [$pin ])? $field_vis $field : $field_ty ),+ }}}; ([$($proj_mut_ident : ident )?][$($proj_ref_ident : ident )?][$($proj_replace_ident : ident )?]$(# [$attrs : meta ])* pub enum $ident : ident $(< $($lifetime : lifetime $(: $lifetime_bound : lifetime )? ),* $(,)? $($generics : ident $(: $generics_bound : path )? $(: ?$generics_unsized_bound : path )? $(: $generics_lifetime_bound : lifetime )? $(= $generics_default : ty )? ),* $(,)? >)? $(where $($where_clause_ty : ty $(: $where_clause_bound : path )? $(: ?$where_clause_unsized_bound : path )? $(: $where_clause_lifetime_bound : lifetime )? ),* $(,)? )? {$($(# [$variant_attrs : meta ])* $variant : ident $({$($(# [$pin : ident ])? $field : ident : $field_ty : ty ),+ $(,)? })? ),+ $(,)? })=>{$crate :: __pin_project_internal ! {@ enum => internal ; [$($proj_mut_ident )?][$($proj_ref_ident )?][$($proj_replace_ident )?][ pub ( crate )][$(# [$attrs ])* pub enum $ident ][$(< $($lifetime $(: $lifetime_bound )? ,)* $($generics $(: $generics_bound )? $(: ?$generics_unsized_bound )? $(: $generics_lifetime_bound )? $(= $generics_default )? ),* >)?][$($($lifetime $(: $lifetime_bound )? ,)* $($generics $(: $generics_bound )? $(: ?$generics_unsized_bound )? $(: $generics_lifetime_bound )? ),* )?][$($($lifetime ,)* $($generics ),* )?][$(where $($where_clause_ty $(: $where_clause_bound )? $(: ?$where_clause_unsized_bound )? $(: $where_clause_lifetime_bound )? ),* )?]{$($(# [$variant_attrs ])* $variant $({$($(# [$pin ])? $field : $field_ty ),+ })? ),+ }}}; ([$($proj_mut_ident : ident )?][$($proj_ref_ident : ident )?][$($proj_replace_ident : ident )?]$(# [$attrs : meta ])* $vis : vis enum $ident : ident $(< $($lifetime : lifetime $(: $lifetime_bound : lifetime )? ),* $(,)? $($generics : ident $(: $generics_bound : path )? $(: ?$generics_unsized_bound : path )? $(: $generics_lifetime_bound : lifetime )? $(= $generics_default : ty )? ),* $(,)? >)? $(where $($where_clause_ty : ty $(: $where_clause_bound : path )? $(: ?$where_clause_unsized_bound : path )? $(: $where_clause_lifetime_bound : lifetime )? ),* $(,)? )? {$($(# [$variant_attrs : meta ])* $variant : ident $({$($(# [$pin : ident ])? $field : ident : $field_ty : ty ),+ $(,)? })? ),+ $(,)? })=>{$crate :: __pin_project_internal ! {@ enum => internal ; [$($proj_mut_ident )?][$($proj_ref_ident )?][$($proj_replace_ident )?][$vis ][$(# [$attrs ])* $vis enum $ident ][$(< $($lifetime $(: $lifetime_bound )? ,)* $($generics $(: $generics_bound )? $(: ?$generics_unsized_bound )? $(: $generics_lifetime_bound )? $(= $generics_default )? ),* >)?][$($($lifetime $(: $lifetime_bound )? ,)* $($generics $(: $generics_bound )? $(: ?$generics_unsized_bound )? $(: $generics_lifetime_bound )? ),* )?][$($($lifetime ,)* $($generics ),* )?][$(where $($where_clause_ty $(: $where_clause_bound )? $(: ?$where_clause_unsized_bound )? $(: $where_clause_lifetime_bound )? ),* )?]{$($(# [$variant_attrs ])* $variant $({$($(# [$pin ])? $field : $field_ty ),+ })? ),+ }}}; }
176macro_rules! __ra_macro_fixture175 {($t : ty , $example : tt )=>{ impl AtomicCell <$t > {# [ doc = " Increments the current value by `val` and returns the previous value." ]# [ doc = "" ]# [ doc = " The addition wraps on overflow." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_add(3), 7);" ]# [ doc = " assert_eq!(a.load(), 10);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_add (& self , val : $t )-> $t { if can_transmute ::<$t , atomic :: AtomicUsize > (){ let a = unsafe {&* ( self . value . get () as * const atomic :: AtomicUsize )}; a . fetch_add ( val as usize , Ordering :: AcqRel ) as $t } else { let _guard = lock ( self . value . get () as usize ). write (); let value = unsafe {& mut * ( self . value . get ())}; let old = * value ; * value = value . wrapping_add ( val ); old }}# [ doc = " Decrements the current value by `val` and returns the previous value." ]# [ doc = "" ]# [ doc = " The subtraction wraps on overflow." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_sub(3), 7);" ]# [ doc = " assert_eq!(a.load(), 4);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_sub (& self , val : $t )-> $t { if can_transmute ::<$t , atomic :: AtomicUsize > (){ let a = unsafe {&* ( self . value . get () as * const atomic :: AtomicUsize )}; a . fetch_sub ( val as usize , Ordering :: AcqRel ) as $t } else { let _guard = lock ( self . value . get () as usize ). write (); let value = unsafe {& mut * ( self . value . get ())}; let old = * value ; * value = value . wrapping_sub ( val ); old }}# [ doc = " Applies bitwise \\\"and\\\" to the current value and returns the previous value." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_and(3), 7);" ]# [ doc = " assert_eq!(a.load(), 3);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_and (& self , val : $t )-> $t { if can_transmute ::<$t , atomic :: AtomicUsize > (){ let a = unsafe {&* ( self . value . get () as * const atomic :: AtomicUsize )}; a . fetch_and ( val as usize , Ordering :: AcqRel ) as $t } else { let _guard = lock ( self . value . get () as usize ). write (); let value = unsafe {& mut * ( self . value . get ())}; let old = * value ; * value &= val ; old }}# [ doc = " Applies bitwise \\\"or\\\" to the current value and returns the previous value." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_or(16), 7);" ]# [ doc = " assert_eq!(a.load(), 23);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_or (& self , val : $t )-> $t { if can_transmute ::<$t , atomic :: AtomicUsize > (){ let a = unsafe {&* ( self . value . get () as * const atomic :: AtomicUsize )}; a . fetch_or ( val as usize , Ordering :: AcqRel ) as $t } else { let _guard = lock ( self . value . get () as usize ). write (); let value = unsafe {& mut * ( self . value . get ())}; let old = * value ; * value |= val ; old }}# [ doc = " Applies bitwise \\\"xor\\\" to the current value and returns the previous value." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_xor(2), 7);" ]# [ doc = " assert_eq!(a.load(), 5);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_xor (& self , val : $t )-> $t { if can_transmute ::<$t , atomic :: AtomicUsize > (){ let a = unsafe {&* ( self . value . get () as * const atomic :: AtomicUsize )}; a . fetch_xor ( val as usize , Ordering :: AcqRel ) as $t } else { let _guard = lock ( self . value . get () as usize ). write (); let value = unsafe {& mut * ( self . value . get ())}; let old = * value ; * value ^= val ; old }}}}; ($t : ty , $atomic : ty , $example : tt )=>{ impl AtomicCell <$t > {# [ doc = " Increments the current value by `val` and returns the previous value." ]# [ doc = "" ]# [ doc = " The addition wraps on overflow." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_add(3), 7);" ]# [ doc = " assert_eq!(a.load(), 10);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_add (& self , val : $t )-> $t { let a = unsafe {&* ( self . value . get () as * const $atomic )}; a . fetch_add ( val , Ordering :: AcqRel )}# [ doc = " Decrements the current value by `val` and returns the previous value." ]# [ doc = "" ]# [ doc = " The subtraction wraps on overflow." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_sub(3), 7);" ]# [ doc = " assert_eq!(a.load(), 4);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_sub (& self , val : $t )-> $t { let a = unsafe {&* ( self . value . get () as * const $atomic )}; a . fetch_sub ( val , Ordering :: AcqRel )}# [ doc = " Applies bitwise \\\"and\\\" to the current value and returns the previous value." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_and(3), 7);" ]# [ doc = " assert_eq!(a.load(), 3);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_and (& self , val : $t )-> $t { let a = unsafe {&* ( self . value . get () as * const $atomic )}; a . fetch_and ( val , Ordering :: AcqRel )}# [ doc = " Applies bitwise \\\"or\\\" to the current value and returns the previous value." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_or(16), 7);" ]# [ doc = " assert_eq!(a.load(), 23);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_or (& self , val : $t )-> $t { let a = unsafe {&* ( self . value . get () as * const $atomic )}; a . fetch_or ( val , Ordering :: AcqRel )}# [ doc = " Applies bitwise \\\"xor\\\" to the current value and returns the previous value." ]# [ doc = "" ]# [ doc = " # Examples" ]# [ doc = "" ]# [ doc = " ```" ]# [ doc = " use crossbeam_utils::atomic::AtomicCell;" ]# [ doc = "" ]# [ doc = $example ]# [ doc = "" ]# [ doc = " assert_eq!(a.fetch_xor(2), 7);" ]# [ doc = " assert_eq!(a.load(), 5);" ]# [ doc = " ```" ]# [ inline ] pub fn fetch_xor (& self , val : $t )-> $t { let a = unsafe {&* ( self . value . get () as * const $atomic )}; a . fetch_xor ( val , Ordering :: AcqRel )}}}; }
177macro_rules! __ra_macro_fixture176 {($atomic : ident , $val : ty )=>{ impl AtomicConsume for :: core :: sync :: atomic ::$atomic { type Val = $val ; impl_consume ! (); }}; }
178macro_rules! __ra_macro_fixture177 {($t : ty , $min : expr , $max : expr )=>{ impl Bounded for $t {# [ inline ] fn min_value ()-> $t {$min }# [ inline ] fn max_value ()-> $t {$max }}}; }
179macro_rules! __ra_macro_fixture178 {($m : ident )=>{ for_each_tuple_ ! {$m !! A , B , C , D , E , F , G , H , I , J , K , L , M , N , O , P , Q , R , S , T , }}; }
180macro_rules! __ra_macro_fixture179 {($T : ident )=>{ impl ToPrimitive for $T { impl_to_primitive_int_to_int ! {$T : fn to_isize -> isize ; fn to_i8 -> i8 ; fn to_i16 -> i16 ; fn to_i32 -> i32 ; fn to_i64 -> i64 ; # [ cfg ( has_i128 )] fn to_i128 -> i128 ; } impl_to_primitive_int_to_uint ! {$T : fn to_usize -> usize ; fn to_u8 -> u8 ; fn to_u16 -> u16 ; fn to_u32 -> u32 ; fn to_u64 -> u64 ; # [ cfg ( has_i128 )] fn to_u128 -> u128 ; }# [ inline ] fn to_f32 (& self )-> Option < f32 > { Some (* self as f32 )}# [ inline ] fn to_f64 (& self )-> Option < f64 > { Some (* self as f64 )}}}; }
181macro_rules! __ra_macro_fixture180 {($T : ident )=>{ impl ToPrimitive for $T { impl_to_primitive_uint_to_int ! {$T : fn to_isize -> isize ; fn to_i8 -> i8 ; fn to_i16 -> i16 ; fn to_i32 -> i32 ; fn to_i64 -> i64 ; # [ cfg ( has_i128 )] fn to_i128 -> i128 ; } impl_to_primitive_uint_to_uint ! {$T : fn to_usize -> usize ; fn to_u8 -> u8 ; fn to_u16 -> u16 ; fn to_u32 -> u32 ; fn to_u64 -> u64 ; # [ cfg ( has_i128 )] fn to_u128 -> u128 ; }# [ inline ] fn to_f32 (& self )-> Option < f32 > { Some (* self as f32 )}# [ inline ] fn to_f64 (& self )-> Option < f64 > { Some (* self as f64 )}}}; }
182macro_rules! __ra_macro_fixture181 {($T : ident )=>{ impl ToPrimitive for $T { impl_to_primitive_float_to_signed_int ! {$T : fn to_isize -> isize ; fn to_i8 -> i8 ; fn to_i16 -> i16 ; fn to_i32 -> i32 ; fn to_i64 -> i64 ; # [ cfg ( has_i128 )] fn to_i128 -> i128 ; } impl_to_primitive_float_to_unsigned_int ! {$T : fn to_usize -> usize ; fn to_u8 -> u8 ; fn to_u16 -> u16 ; fn to_u32 -> u32 ; fn to_u64 -> u64 ; # [ cfg ( has_i128 )] fn to_u128 -> u128 ; } impl_to_primitive_float_to_float ! {$T : fn to_f32 -> f32 ; fn to_f64 -> f64 ; }}}; }
183macro_rules! __ra_macro_fixture182 {($T : ty , $to_ty : ident )=>{# [ allow ( deprecated )] impl FromPrimitive for $T {# [ inline ] fn from_isize ( n : isize )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_i8 ( n : i8 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_i16 ( n : i16 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_i32 ( n : i32 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_i64 ( n : i64 )-> Option <$T > { n .$to_ty ()}# [ cfg ( has_i128 )]# [ inline ] fn from_i128 ( n : i128 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_usize ( n : usize )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_u8 ( n : u8 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_u16 ( n : u16 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_u32 ( n : u32 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_u64 ( n : u64 )-> Option <$T > { n .$to_ty ()}# [ cfg ( has_i128 )]# [ inline ] fn from_u128 ( n : u128 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_f32 ( n : f32 )-> Option <$T > { n .$to_ty ()}# [ inline ] fn from_f64 ( n : f64 )-> Option <$T > { n .$to_ty ()}}}; }
184macro_rules! __ra_macro_fixture183 {($T : ty , $conv : ident )=>{ impl NumCast for $T {# [ inline ]# [ allow ( deprecated )] fn from < N : ToPrimitive > ( n : N )-> Option <$T > { n .$conv ()}}}; }
185macro_rules! __ra_macro_fixture184 {(@ $T : ty =>$(# [$cfg : meta ])* impl $U : ty )=>{$(# [$cfg ])* impl AsPrimitive <$U > for $T {# [ inline ] fn as_ ( self )-> $U { self as $U }}}; (@ $T : ty =>{$($U : ty ),* })=>{$(impl_as_primitive ! (@ $T => impl $U ); )*}; ($T : ty =>{$($U : ty ),* })=>{ impl_as_primitive ! (@ $T =>{$($U ),* }); impl_as_primitive ! (@ $T =>{ u8 , u16 , u32 , u64 , usize }); impl_as_primitive ! (@ $T =># [ cfg ( has_i128 )] impl u128 ); impl_as_primitive ! (@ $T =>{ i8 , i16 , i32 , i64 , isize }); impl_as_primitive ! (@ $T =># [ cfg ( has_i128 )] impl i128 ); }; }
186macro_rules! __ra_macro_fixture185 {($(# [$doc : meta ]$constant : ident ,)+)=>(# [ allow ( non_snake_case )] pub trait FloatConst {$(# [$doc ] fn $constant ()-> Self ;)+ # [ doc = "Return the full circle constant `Ï„`." ]# [ inline ] fn TAU ()-> Self where Self : Sized + Add < Self , Output = Self >{ Self :: PI ()+ Self :: PI ()}# [ doc = "Return `log10(2.0)`." ]# [ inline ] fn LOG10_2 ()-> Self where Self : Sized + Div < Self , Output = Self >{ Self :: LN_2 ()/ Self :: LN_10 ()}# [ doc = "Return `log2(10.0)`." ]# [ inline ] fn LOG2_10 ()-> Self where Self : Sized + Div < Self , Output = Self >{ Self :: LN_10 ()/ Self :: LN_2 ()}} float_const_impl ! {@ float f32 , $($constant ,)+ } float_const_impl ! {@ float f64 , $($constant ,)+ }); (@ float $T : ident , $($constant : ident ,)+)=>( impl FloatConst for $T { constant ! {$($constant ()-> $T :: consts ::$constant ; )+ TAU ()-> 6.28318530717958647692528676655900577 ; LOG10_2 ()-> 0.301029995663981195213738894724493027 ; LOG2_10 ()-> 3.32192809488736234787031942948939018 ; }}); }
187macro_rules! __ra_macro_fixture186 {($t : ty , $v : expr )=>{ impl Zero for $t {# [ inline ] fn zero ()-> $t {$v }# [ inline ] fn is_zero (& self )-> bool {* self == $v }}}; }
188macro_rules! __ra_macro_fixture187 {($t : ty , $v : expr )=>{ impl One for $t {# [ inline ] fn one ()-> $t {$v }# [ inline ] fn is_one (& self )-> bool {* self == $v }}}; }
189macro_rules! __ra_macro_fixture188 {($T : ty , $S : ty , $U : ty )=>{ impl PrimInt for $T {# [ inline ] fn count_ones ( self )-> u32 {<$T >:: count_ones ( self )}# [ inline ] fn count_zeros ( self )-> u32 {<$T >:: count_zeros ( self )}# [ inline ] fn leading_zeros ( self )-> u32 {<$T >:: leading_zeros ( self )}# [ inline ] fn trailing_zeros ( self )-> u32 {<$T >:: trailing_zeros ( self )}# [ inline ] fn rotate_left ( self , n : u32 )-> Self {<$T >:: rotate_left ( self , n )}# [ inline ] fn rotate_right ( self , n : u32 )-> Self {<$T >:: rotate_right ( self , n )}# [ inline ] fn signed_shl ( self , n : u32 )-> Self {(( self as $S )<< n ) as $T }# [ inline ] fn signed_shr ( self , n : u32 )-> Self {(( self as $S )>> n ) as $T }# [ inline ] fn unsigned_shl ( self , n : u32 )-> Self {(( self as $U )<< n ) as $T }# [ inline ] fn unsigned_shr ( self , n : u32 )-> Self {(( self as $U )>> n ) as $T }# [ inline ] fn swap_bytes ( self )-> Self {<$T >:: swap_bytes ( self )}# [ inline ] fn from_be ( x : Self )-> Self {<$T >:: from_be ( x )}# [ inline ] fn from_le ( x : Self )-> Self {<$T >:: from_le ( x )}# [ inline ] fn to_be ( self )-> Self {<$T >:: to_be ( self )}# [ inline ] fn to_le ( self )-> Self {<$T >:: to_le ( self )}# [ inline ] fn pow ( self , exp : u32 )-> Self {<$T >:: pow ( self , exp )}}}; }
190macro_rules! __ra_macro_fixture189 {($trait_name : ident , $method : ident , $t : ty )=>{ impl $trait_name for $t {# [ inline ] fn $method (& self , v : &$t )-> Option <$t > {<$t >::$method (* self , * v )}}}; }
191macro_rules! __ra_macro_fixture190 {($trait_name : ident , $method : ident , $t : ty )=>{ impl $trait_name for $t {# [ inline ] fn $method (& self )-> Option <$t > {<$t >::$method (* self )}}}; }
192macro_rules! __ra_macro_fixture191 {($trait_name : ident , $method : ident , $t : ty )=>{ impl $trait_name for $t {# [ inline ] fn $method (& self , rhs : u32 )-> Option <$t > {<$t >::$method (* self , rhs )}}}; }
193macro_rules! __ra_macro_fixture192 {($trait_name : ident for $($t : ty )*)=>{$(impl $trait_name for $t { type Output = Self ; # [ inline ] fn mul_add ( self , a : Self , b : Self )-> Self :: Output {( self * a )+ b }})*}}
194macro_rules! __ra_macro_fixture193 {($trait_name : ident for $($t : ty )*)=>{$(impl $trait_name for $t {# [ inline ] fn mul_add_assign (& mut self , a : Self , b : Self ){* self = (* self * a )+ b }})*}}
195macro_rules! __ra_macro_fixture194 {($trait_name : ident , $method : ident , $t : ty )=>{ impl $trait_name for $t {# [ inline ] fn $method (& self , v : & Self )-> ( Self , bool ){<$t >::$method (* self , * v )}}}; }
196macro_rules! __ra_macro_fixture195 {($trait_name : ident for $($t : ty )*)=>{$(impl $trait_name for $t {# [ inline ] fn saturating_add ( self , v : Self )-> Self { Self :: saturating_add ( self , v )}# [ inline ] fn saturating_sub ( self , v : Self )-> Self { Self :: saturating_sub ( self , v )}})*}}
197macro_rules! __ra_macro_fixture196 {($trait_name : ident , $method : ident , $t : ty )=>{ impl $trait_name for $t {# [ inline ] fn $method (& self , v : & Self )-> Self {<$t >::$method (* self , * v )}}}; }
198macro_rules! __ra_macro_fixture197 {($trait_name : ident , $method : ident , $t : ty )=>{ impl $trait_name for $t {# [ inline ] fn $method (& self , v : & Self )-> Self {<$t >::$method (* self , * v )}}}; ($trait_name : ident , $method : ident , $t : ty , $rhs : ty )=>{ impl $trait_name <$rhs > for $t {# [ inline ] fn $method (& self , v : &$rhs )-> Self {<$t >::$method (* self , * v )}}}; }
199macro_rules! __ra_macro_fixture198 {($trait_name : ident , $method : ident , $t : ty )=>{ impl $trait_name for $t {# [ inline ] fn $method (& self )-> $t {<$t >::$method (* self )}}}; }
200macro_rules! __ra_macro_fixture199 {($trait_name : ident , $method : ident , $t : ty )=>{ impl $trait_name for $t {# [ inline ] fn $method (& self , rhs : u32 )-> $t {<$t >::$method (* self , rhs )}}}; }
201macro_rules! __ra_macro_fixture200 {($t : ty )=>{ pow_impl ! ($t , u8 ); pow_impl ! ($t , usize ); }; ($t : ty , $rhs : ty )=>{ pow_impl ! ($t , $rhs , usize , pow ); }; ($t : ty , $rhs : ty , $desired_rhs : ty , $method : expr )=>{ impl Pow <$rhs > for $t { type Output = $t ; # [ inline ] fn pow ( self , rhs : $rhs )-> $t {($method )( self , <$desired_rhs >:: from ( rhs ))}} impl < 'a > Pow <& 'a $rhs > for $t { type Output = $t ; # [ inline ] fn pow ( self , rhs : & 'a $rhs )-> $t {($method )( self , <$desired_rhs >:: from (* rhs ))}} impl < 'a > Pow <$rhs > for & 'a $t { type Output = $t ; # [ inline ] fn pow ( self , rhs : $rhs )-> $t {($method )(* self , <$desired_rhs >:: from ( rhs ))}} impl < 'a , 'b > Pow <& 'a $rhs > for & 'b $t { type Output = $t ; # [ inline ] fn pow ( self , rhs : & 'a $rhs )-> $t {($method )(* self , <$desired_rhs >:: from (* rhs ))}}}; }
202macro_rules! __ra_macro_fixture201 {($($t : ty )*)=>($(impl Signed for $t {# [ inline ] fn abs (& self )-> $t { if self . is_negative (){-* self } else {* self }}# [ inline ] fn abs_sub (& self , other : &$t )-> $t { if * self <= * other { 0 } else {* self - * other }}# [ inline ] fn signum (& self )-> $t { match * self { n if n > 0 => 1 , 0 => 0 , _ =>- 1 , }}# [ inline ] fn is_positive (& self )-> bool {* self > 0 }# [ inline ] fn is_negative (& self )-> bool {* self < 0 }})*)}
203macro_rules! __ra_macro_fixture202 {($t : ty )=>{ impl Signed for $t {# [ doc = " Computes the absolute value. Returns `NAN` if the number is `NAN`." ]# [ inline ] fn abs (& self )-> $t { FloatCore :: abs (* self )}# [ doc = " The positive difference of two numbers. Returns `0.0` if the number is" ]# [ doc = " less than or equal to `other`, otherwise the difference between`self`" ]# [ doc = " and `other` is returned." ]# [ inline ] fn abs_sub (& self , other : &$t )-> $t { if * self <= * other { 0. } else {* self - * other }}# [ doc = " # Returns" ]# [ doc = "" ]# [ doc = " - `1.0` if the number is positive, `+0.0` or `INFINITY`" ]# [ doc = " - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`" ]# [ doc = " - `NAN` if the number is NaN" ]# [ inline ] fn signum (& self )-> $t { FloatCore :: signum (* self )}# [ doc = " Returns `true` if the number is positive, including `+0.0` and `INFINITY`" ]# [ inline ] fn is_positive (& self )-> bool { FloatCore :: is_sign_positive (* self )}# [ doc = " Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`" ]# [ inline ] fn is_negative (& self )-> bool { FloatCore :: is_sign_negative (* self )}}}; }
204macro_rules! __ra_macro_fixture203 {($name : ident for $($t : ty )*)=>($(impl $name for $t {})*)}
205macro_rules! __ra_macro_fixture204 {($name : ident for $($t : ty )*)=>($(impl $name for $t { type FromStrRadixErr = :: core :: num :: ParseIntError ; # [ inline ] fn from_str_radix ( s : & str , radix : u32 )-> Result < Self , :: core :: num :: ParseIntError > {<$t >:: from_str_radix ( s , radix )}})*)}
206macro_rules! __ra_macro_fixture205 {($name : ident for $($t : ident )*)=>($(impl $name for $t { type FromStrRadixErr = ParseFloatError ; fn from_str_radix ( src : & str , radix : u32 )-> Result < Self , Self :: FromStrRadixErr > { use self :: FloatErrorKind ::*; use self :: ParseFloatError as PFE ; match src { "inf" => return Ok ( core ::$t :: INFINITY ), "-inf" => return Ok ( core ::$t :: NEG_INFINITY ), "NaN" => return Ok ( core ::$t :: NAN ), _ =>{}, } fn slice_shift_char ( src : & str )-> Option < ( char , & str )> { let mut chars = src . chars (); if let Some ( ch )= chars . next (){ Some (( ch , chars . as_str ()))} else { None }} let ( is_positive , src )= match slice_shift_char ( src ){ None => return Err ( PFE { kind : Empty }), Some (( '-' , "" ))=> return Err ( PFE { kind : Empty }), Some (( '-' , src ))=>( false , src ), Some ((_, _))=>( true , src ), }; let mut sig = if is_positive { 0.0 } else {- 0.0 }; let mut prev_sig = sig ; let mut cs = src . chars (). enumerate (); let mut exp_info = None ::< ( char , usize )>; for ( i , c ) in cs . by_ref (){ match c . to_digit ( radix ){ Some ( digit )=>{ sig = sig * ( radix as $t ); if is_positive { sig = sig + (( digit as isize ) as $t ); } else { sig = sig - (( digit as isize ) as $t ); } if prev_sig != 0.0 { if is_positive && sig <= prev_sig { return Ok ( core ::$t :: INFINITY ); } if ! is_positive && sig >= prev_sig { return Ok ( core ::$t :: NEG_INFINITY ); } if is_positive && ( prev_sig != ( sig - digit as $t )/ radix as $t ){ return Ok ( core ::$t :: INFINITY ); } if ! is_positive && ( prev_sig != ( sig + digit as $t )/ radix as $t ){ return Ok ( core ::$t :: NEG_INFINITY ); }} prev_sig = sig ; }, None => match c { 'e' | 'E' | 'p' | 'P' =>{ exp_info = Some (( c , i + 1 )); break ; }, '.' =>{ break ; }, _ =>{ return Err ( PFE { kind : Invalid }); }, }, }} if exp_info . is_none (){ let mut power = 1.0 ; for ( i , c ) in cs . by_ref (){ match c . to_digit ( radix ){ Some ( digit )=>{ power = power / ( radix as $t ); sig = if is_positive { sig + ( digit as $t )* power } else { sig - ( digit as $t )* power }; if is_positive && sig < prev_sig { return Ok ( core ::$t :: INFINITY ); } if ! is_positive && sig > prev_sig { return Ok ( core ::$t :: NEG_INFINITY ); } prev_sig = sig ; }, None => match c { 'e' | 'E' | 'p' | 'P' =>{ exp_info = Some (( c , i + 1 )); break ; }, _ =>{ return Err ( PFE { kind : Invalid }); }, }, }}} let exp = match exp_info { Some (( c , offset ))=>{ let base = match c { 'E' | 'e' if radix == 10 => 10.0 , 'P' | 'p' if radix == 16 => 2.0 , _ => return Err ( PFE { kind : Invalid }), }; let src = & src [ offset ..]; let ( is_positive , exp )= match slice_shift_char ( src ){ Some (( '-' , src ))=>( false , src . parse ::< usize > ()), Some (( '+' , src ))=>( true , src . parse ::< usize > ()), Some ((_, _))=>( true , src . parse ::< usize > ()), None => return Err ( PFE { kind : Invalid }), }; # [ cfg ( feature = "std" )] fn pow ( base : $t , exp : usize )-> $t { Float :: powi ( base , exp as i32 )} match ( is_positive , exp ){( true , Ok ( exp ))=> pow ( base , exp ), ( false , Ok ( exp ))=> 1.0 / pow ( base , exp ), (_, Err (_))=> return Err ( PFE { kind : Invalid }), }}, None => 1.0 , }; Ok ( sig * exp )}})*)}
207macro_rules! __ra_macro_fixture206 {($m : ident !! )=>($m ! {}); ($m : ident !! $h : ident , $($t : ident ,)* )=>($m ! {$h $($t )* } for_each_tuple_ ! {$m !! $($t ,)* }); }
208macro_rules! __ra_macro_fixture207 {($($name : ident )* )=>( impl <$($name : Bounded ,)*> Bounded for ($($name ,)*){# [ inline ] fn min_value ()-> Self {($($name :: min_value (),)*)}# [ inline ] fn max_value ()-> Self {($($name :: max_value (),)*)}}); }
209macro_rules! __ra_macro_fixture208 {($T : ty , $U : ty )=>{ impl Roots for $T {# [ inline ] fn nth_root (& self , n : u32 )-> Self { if * self >= 0 {(* self as $U ). nth_root ( n ) as Self } else { assert ! ( n . is_odd (), "even roots of a negative are imaginary" ); - (( self . wrapping_neg () as $U ). nth_root ( n ) as Self )}}# [ inline ] fn sqrt (& self )-> Self { assert ! (* self >= 0 , "the square root of a negative is imaginary" ); (* self as $U ). sqrt () as Self }# [ inline ] fn cbrt (& self )-> Self { if * self >= 0 {(* self as $U ). cbrt () as Self } else {- (( self . wrapping_neg () as $U ). cbrt () as Self )}}}}; }
210macro_rules! __ra_macro_fixture209 {($T : ident )=>{ impl Roots for $T {# [ inline ] fn nth_root (& self , n : u32 )-> Self { fn go ( a : $T , n : u32 )-> $T { match n { 0 => panic ! ( "can't find a root of degree 0!" ), 1 => return a , 2 => return a . sqrt (), 3 => return a . cbrt (), _ =>(), } if bits ::<$T > ()<= n || a < ( 1 << n ){ return ( a > 0 ) as $T ; } if bits ::<$T > ()> 64 { return if a <= core :: u64 :: MAX as $T {( a as u64 ). nth_root ( n ) as $T } else { let lo = ( a >> n ). nth_root ( n )<< 1 ; let hi = lo + 1 ; if hi . next_power_of_two (). trailing_zeros ()* n >= bits ::<$T > (){ match checked_pow ( hi , n as usize ){ Some ( x ) if x <= a => hi , _ => lo , }} else { if hi . pow ( n )<= a { hi } else { lo }}}; }# [ cfg ( feature = "std" )]# [ inline ] fn guess ( x : $T , n : u32 )-> $T { if bits ::<$T > ()<= 32 || x <= core :: u32 :: MAX as $T { 1 << (( log2 ( x )+ n - 1 )/ n )} else {(( x as f64 ). ln ()/ f64 :: from ( n )). exp () as $T }}# [ cfg ( not ( feature = "std" ))]# [ inline ] fn guess ( x : $T , n : u32 )-> $T { 1 << (( log2 ( x )+ n - 1 )/ n )} let n1 = n - 1 ; let next = | x : $T | { let y = match checked_pow ( x , n1 as usize ){ Some ( ax )=> a / ax , None => 0 , }; ( y + x * n1 as $T )/ n as $T }; fixpoint ( guess ( a , n ), next )} go (* self , n )}# [ inline ] fn sqrt (& self )-> Self { fn go ( a : $T )-> $T { if bits ::<$T > ()> 64 { return if a <= core :: u64 :: MAX as $T {( a as u64 ). sqrt () as $T } else { let lo = ( a >> 2u32 ). sqrt ()<< 1 ; let hi = lo + 1 ; if hi * hi <= a { hi } else { lo }}; } if a < 4 { return ( a > 0 ) as $T ; }# [ cfg ( feature = "std" )]# [ inline ] fn guess ( x : $T )-> $T {( x as f64 ). sqrt () as $T }# [ cfg ( not ( feature = "std" ))]# [ inline ] fn guess ( x : $T )-> $T { 1 << (( log2 ( x )+ 1 )/ 2 )} let next = | x : $T | ( a / x + x )>> 1 ; fixpoint ( guess ( a ), next )} go (* self )}# [ inline ] fn cbrt (& self )-> Self { fn go ( a : $T )-> $T { if bits ::<$T > ()> 64 { return if a <= core :: u64 :: MAX as $T {( a as u64 ). cbrt () as $T } else { let lo = ( a >> 3u32 ). cbrt ()<< 1 ; let hi = lo + 1 ; if hi * hi * hi <= a { hi } else { lo }}; } if bits ::<$T > ()<= 32 { let mut x = a ; let mut y2 = 0 ; let mut y = 0 ; let smax = bits ::<$T > ()/ 3 ; for s in ( 0 .. smax + 1 ). rev (){ let s = s * 3 ; y2 *= 4 ; y *= 2 ; let b = 3 * ( y2 + y )+ 1 ; if x >> s >= b { x -= b << s ; y2 += 2 * y + 1 ; y += 1 ; }} return y ; } if a < 8 { return ( a > 0 ) as $T ; } if a <= core :: u32 :: MAX as $T { return ( a as u32 ). cbrt () as $T ; }# [ cfg ( feature = "std" )]# [ inline ] fn guess ( x : $T )-> $T {( x as f64 ). cbrt () as $T }# [ cfg ( not ( feature = "std" ))]# [ inline ] fn guess ( x : $T )-> $T { 1 << (( log2 ( x )+ 2 )/ 3 )} let next = | x : $T | ( a / ( x * x )+ x * 2 )/ 3 ; fixpoint ( guess ( a ), next )} go (* self )}}}; }
211macro_rules! __ra_macro_fixture210 {($T : ty , $test_mod : ident )=>{ impl Integer for $T {# [ doc = " Floored integer division" ]# [ inline ] fn div_floor (& self , other : & Self )-> Self { let ( d , r )= self . div_rem ( other ); if ( r > 0 && * other < 0 )|| ( r < 0 && * other > 0 ){ d - 1 } else { d }}# [ doc = " Floored integer modulo" ]# [ inline ] fn mod_floor (& self , other : & Self )-> Self { let r = * self % * other ; if ( r > 0 && * other < 0 )|| ( r < 0 && * other > 0 ){ r + * other } else { r }}# [ doc = " Calculates `div_floor` and `mod_floor` simultaneously" ]# [ inline ] fn div_mod_floor (& self , other : & Self )-> ( Self , Self ){ let ( d , r )= self . div_rem ( other ); if ( r > 0 && * other < 0 )|| ( r < 0 && * other > 0 ){( d - 1 , r + * other )} else {( d , r )}}# [ inline ] fn div_ceil (& self , other : & Self )-> Self { let ( d , r )= self . div_rem ( other ); if ( r > 0 && * other > 0 )|| ( r < 0 && * other < 0 ){ d + 1 } else { d }}# [ doc = " Calculates the Greatest Common Divisor (GCD) of the number and" ]# [ doc = " `other`. The result is always positive." ]# [ inline ] fn gcd (& self , other : & Self )-> Self { let mut m = * self ; let mut n = * other ; if m == 0 || n == 0 { return ( m | n ). abs (); } let shift = ( m | n ). trailing_zeros (); if m == Self :: min_value ()|| n == Self :: min_value (){ return ( 1 << shift ). abs (); } m = m . abs (); n = n . abs (); m >>= m . trailing_zeros (); n >>= n . trailing_zeros (); while m != n { if m > n { m -= n ; m >>= m . trailing_zeros (); } else { n -= m ; n >>= n . trailing_zeros (); }} m << shift }# [ inline ] fn extended_gcd_lcm (& self , other : & Self )-> ( ExtendedGcd < Self >, Self ){ let egcd = self . extended_gcd ( other ); let lcm = if egcd . gcd . is_zero (){ Self :: zero ()} else {(* self * (* other / egcd . gcd )). abs ()}; ( egcd , lcm )}# [ doc = " Calculates the Lowest Common Multiple (LCM) of the number and" ]# [ doc = " `other`." ]# [ inline ] fn lcm (& self , other : & Self )-> Self { self . gcd_lcm ( other ). 1 }# [ doc = " Calculates the Greatest Common Divisor (GCD) and" ]# [ doc = " Lowest Common Multiple (LCM) of the number and `other`." ]# [ inline ] fn gcd_lcm (& self , other : & Self )-> ( Self , Self ){ if self . is_zero ()&& other . is_zero (){ return ( Self :: zero (), Self :: zero ()); } let gcd = self . gcd ( other ); let lcm = (* self * (* other / gcd )). abs (); ( gcd , lcm )}# [ doc = " Deprecated, use `is_multiple_of` instead." ]# [ inline ] fn divides (& self , other : & Self )-> bool { self . is_multiple_of ( other )}# [ doc = " Returns `true` if the number is a multiple of `other`." ]# [ inline ] fn is_multiple_of (& self , other : & Self )-> bool {* self % * other == 0 }# [ doc = " Returns `true` if the number is divisible by `2`" ]# [ inline ] fn is_even (& self )-> bool {(* self )& 1 == 0 }# [ doc = " Returns `true` if the number is not divisible by `2`" ]# [ inline ] fn is_odd (& self )-> bool {! self . is_even ()}# [ doc = " Simultaneous truncated integer division and modulus." ]# [ inline ] fn div_rem (& self , other : & Self )-> ( Self , Self ){(* self / * other , * self % * other )}}# [ cfg ( test )] mod $test_mod { use core :: mem ; use Integer ; # [ doc = " Checks that the division rule holds for:" ]# [ doc = "" ]# [ doc = " - `n`: numerator (dividend)" ]# [ doc = " - `d`: denominator (divisor)" ]# [ doc = " - `qr`: quotient and remainder" ]# [ cfg ( test )] fn test_division_rule (( n , d ): ($T , $T ), ( q , r ): ($T , $T )){ assert_eq ! ( d * q + r , n ); }# [ test ] fn test_div_rem (){ fn test_nd_dr ( nd : ($T , $T ), qr : ($T , $T )){ let ( n , d )= nd ; let separate_div_rem = ( n / d , n % d ); let combined_div_rem = n . div_rem (& d ); assert_eq ! ( separate_div_rem , qr ); assert_eq ! ( combined_div_rem , qr ); test_division_rule ( nd , separate_div_rem ); test_division_rule ( nd , combined_div_rem ); } test_nd_dr (( 8 , 3 ), ( 2 , 2 )); test_nd_dr (( 8 , - 3 ), (- 2 , 2 )); test_nd_dr ((- 8 , 3 ), (- 2 , - 2 )); test_nd_dr ((- 8 , - 3 ), ( 2 , - 2 )); test_nd_dr (( 1 , 2 ), ( 0 , 1 )); test_nd_dr (( 1 , - 2 ), ( 0 , 1 )); test_nd_dr ((- 1 , 2 ), ( 0 , - 1 )); test_nd_dr ((- 1 , - 2 ), ( 0 , - 1 )); }# [ test ] fn test_div_mod_floor (){ fn test_nd_dm ( nd : ($T , $T ), dm : ($T , $T )){ let ( n , d )= nd ; let separate_div_mod_floor = ( n . div_floor (& d ), n . mod_floor (& d )); let combined_div_mod_floor = n . div_mod_floor (& d ); assert_eq ! ( separate_div_mod_floor , dm ); assert_eq ! ( combined_div_mod_floor , dm ); test_division_rule ( nd , separate_div_mod_floor ); test_division_rule ( nd , combined_div_mod_floor ); } test_nd_dm (( 8 , 3 ), ( 2 , 2 )); test_nd_dm (( 8 , - 3 ), (- 3 , - 1 )); test_nd_dm ((- 8 , 3 ), (- 3 , 1 )); test_nd_dm ((- 8 , - 3 ), ( 2 , - 2 )); test_nd_dm (( 1 , 2 ), ( 0 , 1 )); test_nd_dm (( 1 , - 2 ), (- 1 , - 1 )); test_nd_dm ((- 1 , 2 ), (- 1 , 1 )); test_nd_dm ((- 1 , - 2 ), ( 0 , - 1 )); }# [ test ] fn test_gcd (){ assert_eq ! (( 10 as $T ). gcd (& 2 ), 2 as $T ); assert_eq ! (( 10 as $T ). gcd (& 3 ), 1 as $T ); assert_eq ! (( 0 as $T ). gcd (& 3 ), 3 as $T ); assert_eq ! (( 3 as $T ). gcd (& 3 ), 3 as $T ); assert_eq ! (( 56 as $T ). gcd (& 42 ), 14 as $T ); assert_eq ! (( 3 as $T ). gcd (&- 3 ), 3 as $T ); assert_eq ! ((- 6 as $T ). gcd (& 3 ), 3 as $T ); assert_eq ! ((- 4 as $T ). gcd (&- 2 ), 2 as $T ); }# [ test ] fn test_gcd_cmp_with_euclidean (){ fn euclidean_gcd ( mut m : $T , mut n : $T )-> $T { while m != 0 { mem :: swap (& mut m , & mut n ); m %= n ; } n . abs ()} for i in - 127 .. 127 { for j in - 127 .. 127 { assert_eq ! ( euclidean_gcd ( i , j ), i . gcd (& j )); }} let i = 127 ; for j in - 127 .. 127 { assert_eq ! ( euclidean_gcd ( i , j ), i . gcd (& j )); } assert_eq ! ( 127 . gcd (& 127 ), 127 ); }# [ test ] fn test_gcd_min_val (){ let min = <$T >:: min_value (); let max = <$T >:: max_value (); let max_pow2 = max / 2 + 1 ; assert_eq ! ( min . gcd (& max ), 1 as $T ); assert_eq ! ( max . gcd (& min ), 1 as $T ); assert_eq ! ( min . gcd (& max_pow2 ), max_pow2 ); assert_eq ! ( max_pow2 . gcd (& min ), max_pow2 ); assert_eq ! ( min . gcd (& 42 ), 2 as $T ); assert_eq ! (( 42 as $T ). gcd (& min ), 2 as $T ); }# [ test ]# [ should_panic ] fn test_gcd_min_val_min_val (){ let min = <$T >:: min_value (); assert ! ( min . gcd (& min )>= 0 ); }# [ test ]# [ should_panic ] fn test_gcd_min_val_0 (){ let min = <$T >:: min_value (); assert ! ( min . gcd (& 0 )>= 0 ); }# [ test ]# [ should_panic ] fn test_gcd_0_min_val (){ let min = <$T >:: min_value (); assert ! (( 0 as $T ). gcd (& min )>= 0 ); }# [ test ] fn test_lcm (){ assert_eq ! (( 1 as $T ). lcm (& 0 ), 0 as $T ); assert_eq ! (( 0 as $T ). lcm (& 1 ), 0 as $T ); assert_eq ! (( 1 as $T ). lcm (& 1 ), 1 as $T ); assert_eq ! ((- 1 as $T ). lcm (& 1 ), 1 as $T ); assert_eq ! (( 1 as $T ). lcm (&- 1 ), 1 as $T ); assert_eq ! ((- 1 as $T ). lcm (&- 1 ), 1 as $T ); assert_eq ! (( 8 as $T ). lcm (& 9 ), 72 as $T ); assert_eq ! (( 11 as $T ). lcm (& 5 ), 55 as $T ); }# [ test ] fn test_gcd_lcm (){ use core :: iter :: once ; for i in once ( 0 ). chain (( 1 ..). take ( 127 ). flat_map (| a | once ( a ). chain ( once (- a )))). chain ( once (- 128 )){ for j in once ( 0 ). chain (( 1 ..). take ( 127 ). flat_map (| a | once ( a ). chain ( once (- a )))). chain ( once (- 128 )){ assert_eq ! ( i . gcd_lcm (& j ), ( i . gcd (& j ), i . lcm (& j ))); }}}# [ test ] fn test_extended_gcd_lcm (){ use core :: fmt :: Debug ; use traits :: NumAssign ; use ExtendedGcd ; fn check < A : Copy + Debug + Integer + NumAssign > ( a : A , b : A ){ let ExtendedGcd { gcd , x , y , .. }= a . extended_gcd (& b ); assert_eq ! ( gcd , x * a + y * b ); } use core :: iter :: once ; for i in once ( 0 ). chain (( 1 ..). take ( 127 ). flat_map (| a | once ( a ). chain ( once (- a )))). chain ( once (- 128 )){ for j in once ( 0 ). chain (( 1 ..). take ( 127 ). flat_map (| a | once ( a ). chain ( once (- a )))). chain ( once (- 128 )){ check ( i , j ); let ( ExtendedGcd { gcd , .. }, lcm )= i . extended_gcd_lcm (& j ); assert_eq ! (( gcd , lcm ), ( i . gcd (& j ), i . lcm (& j ))); }}}# [ test ] fn test_even (){ assert_eq ! ((- 4 as $T ). is_even (), true ); assert_eq ! ((- 3 as $T ). is_even (), false ); assert_eq ! ((- 2 as $T ). is_even (), true ); assert_eq ! ((- 1 as $T ). is_even (), false ); assert_eq ! (( 0 as $T ). is_even (), true ); assert_eq ! (( 1 as $T ). is_even (), false ); assert_eq ! (( 2 as $T ). is_even (), true ); assert_eq ! (( 3 as $T ). is_even (), false ); assert_eq ! (( 4 as $T ). is_even (), true ); }# [ test ] fn test_odd (){ assert_eq ! ((- 4 as $T ). is_odd (), false ); assert_eq ! ((- 3 as $T ). is_odd (), true ); assert_eq ! ((- 2 as $T ). is_odd (), false ); assert_eq ! ((- 1 as $T ). is_odd (), true ); assert_eq ! (( 0 as $T ). is_odd (), false ); assert_eq ! (( 1 as $T ). is_odd (), true ); assert_eq ! (( 2 as $T ). is_odd (), false ); assert_eq ! (( 3 as $T ). is_odd (), true ); assert_eq ! (( 4 as $T ). is_odd (), false ); }}}; }
212macro_rules! __ra_macro_fixture211 {($T : ty , $test_mod : ident )=>{ impl Integer for $T {# [ doc = " Unsigned integer division. Returns the same result as `div` (`/`)." ]# [ inline ] fn div_floor (& self , other : & Self )-> Self {* self / * other }# [ doc = " Unsigned integer modulo operation. Returns the same result as `rem` (`%`)." ]# [ inline ] fn mod_floor (& self , other : & Self )-> Self {* self % * other }# [ inline ] fn div_ceil (& self , other : & Self )-> Self {* self / * other + ( 0 != * self % * other ) as Self }# [ doc = " Calculates the Greatest Common Divisor (GCD) of the number and `other`" ]# [ inline ] fn gcd (& self , other : & Self )-> Self { let mut m = * self ; let mut n = * other ; if m == 0 || n == 0 { return m | n ; } let shift = ( m | n ). trailing_zeros (); m >>= m . trailing_zeros (); n >>= n . trailing_zeros (); while m != n { if m > n { m -= n ; m >>= m . trailing_zeros (); } else { n -= m ; n >>= n . trailing_zeros (); }} m << shift }# [ inline ] fn extended_gcd_lcm (& self , other : & Self )-> ( ExtendedGcd < Self >, Self ){ let egcd = self . extended_gcd ( other ); let lcm = if egcd . gcd . is_zero (){ Self :: zero ()} else {* self * (* other / egcd . gcd )}; ( egcd , lcm )}# [ doc = " Calculates the Lowest Common Multiple (LCM) of the number and `other`." ]# [ inline ] fn lcm (& self , other : & Self )-> Self { self . gcd_lcm ( other ). 1 }# [ doc = " Calculates the Greatest Common Divisor (GCD) and" ]# [ doc = " Lowest Common Multiple (LCM) of the number and `other`." ]# [ inline ] fn gcd_lcm (& self , other : & Self )-> ( Self , Self ){ if self . is_zero ()&& other . is_zero (){ return ( Self :: zero (), Self :: zero ()); } let gcd = self . gcd ( other ); let lcm = * self * (* other / gcd ); ( gcd , lcm )}# [ doc = " Deprecated, use `is_multiple_of` instead." ]# [ inline ] fn divides (& self , other : & Self )-> bool { self . is_multiple_of ( other )}# [ doc = " Returns `true` if the number is a multiple of `other`." ]# [ inline ] fn is_multiple_of (& self , other : & Self )-> bool {* self % * other == 0 }# [ doc = " Returns `true` if the number is divisible by `2`." ]# [ inline ] fn is_even (& self )-> bool {* self % 2 == 0 }# [ doc = " Returns `true` if the number is not divisible by `2`." ]# [ inline ] fn is_odd (& self )-> bool {! self . is_even ()}# [ doc = " Simultaneous truncated integer division and modulus." ]# [ inline ] fn div_rem (& self , other : & Self )-> ( Self , Self ){(* self / * other , * self % * other )}}# [ cfg ( test )] mod $test_mod { use core :: mem ; use Integer ; # [ test ] fn test_div_mod_floor (){ assert_eq ! (( 10 as $T ). div_floor (& ( 3 as $T )), 3 as $T ); assert_eq ! (( 10 as $T ). mod_floor (& ( 3 as $T )), 1 as $T ); assert_eq ! (( 10 as $T ). div_mod_floor (& ( 3 as $T )), ( 3 as $T , 1 as $T )); assert_eq ! (( 5 as $T ). div_floor (& ( 5 as $T )), 1 as $T ); assert_eq ! (( 5 as $T ). mod_floor (& ( 5 as $T )), 0 as $T ); assert_eq ! (( 5 as $T ). div_mod_floor (& ( 5 as $T )), ( 1 as $T , 0 as $T )); assert_eq ! (( 3 as $T ). div_floor (& ( 7 as $T )), 0 as $T ); assert_eq ! (( 3 as $T ). mod_floor (& ( 7 as $T )), 3 as $T ); assert_eq ! (( 3 as $T ). div_mod_floor (& ( 7 as $T )), ( 0 as $T , 3 as $T )); }# [ test ] fn test_gcd (){ assert_eq ! (( 10 as $T ). gcd (& 2 ), 2 as $T ); assert_eq ! (( 10 as $T ). gcd (& 3 ), 1 as $T ); assert_eq ! (( 0 as $T ). gcd (& 3 ), 3 as $T ); assert_eq ! (( 3 as $T ). gcd (& 3 ), 3 as $T ); assert_eq ! (( 56 as $T ). gcd (& 42 ), 14 as $T ); }# [ test ] fn test_gcd_cmp_with_euclidean (){ fn euclidean_gcd ( mut m : $T , mut n : $T )-> $T { while m != 0 { mem :: swap (& mut m , & mut n ); m %= n ; } n } for i in 0 .. 255 { for j in 0 .. 255 { assert_eq ! ( euclidean_gcd ( i , j ), i . gcd (& j )); }} let i = 255 ; for j in 0 .. 255 { assert_eq ! ( euclidean_gcd ( i , j ), i . gcd (& j )); } assert_eq ! ( 255 . gcd (& 255 ), 255 ); }# [ test ] fn test_lcm (){ assert_eq ! (( 1 as $T ). lcm (& 0 ), 0 as $T ); assert_eq ! (( 0 as $T ). lcm (& 1 ), 0 as $T ); assert_eq ! (( 1 as $T ). lcm (& 1 ), 1 as $T ); assert_eq ! (( 8 as $T ). lcm (& 9 ), 72 as $T ); assert_eq ! (( 11 as $T ). lcm (& 5 ), 55 as $T ); assert_eq ! (( 15 as $T ). lcm (& 17 ), 255 as $T ); }# [ test ] fn test_gcd_lcm (){ for i in ( 0 ..). take ( 256 ){ for j in ( 0 ..). take ( 256 ){ assert_eq ! ( i . gcd_lcm (& j ), ( i . gcd (& j ), i . lcm (& j ))); }}}# [ test ] fn test_is_multiple_of (){ assert ! (( 6 as $T ). is_multiple_of (& ( 6 as $T ))); assert ! (( 6 as $T ). is_multiple_of (& ( 3 as $T ))); assert ! (( 6 as $T ). is_multiple_of (& ( 1 as $T ))); }# [ test ] fn test_even (){ assert_eq ! (( 0 as $T ). is_even (), true ); assert_eq ! (( 1 as $T ). is_even (), false ); assert_eq ! (( 2 as $T ). is_even (), true ); assert_eq ! (( 3 as $T ). is_even (), false ); assert_eq ! (( 4 as $T ). is_even (), true ); }# [ test ] fn test_odd (){ assert_eq ! (( 0 as $T ). is_odd (), false ); assert_eq ! (( 1 as $T ). is_odd (), true ); assert_eq ! (( 2 as $T ). is_odd (), false ); assert_eq ! (( 3 as $T ). is_odd (), true ); assert_eq ! (( 4 as $T ). is_odd (), false ); }}}; }
213macro_rules! __ra_macro_fixture212 {($I : ident , $U : ident )=>{ mod $I { use check ; use neg ; use num_integer :: Roots ; use pos ; use std :: mem ; # [ test ]# [ should_panic ] fn zeroth_root (){( 123 as $I ). nth_root ( 0 ); }# [ test ] fn sqrt (){ check (& pos ::<$I > (), 2 ); }# [ test ]# [ should_panic ] fn sqrt_neg (){(- 123 as $I ). sqrt (); }# [ test ] fn cbrt (){ check (& pos ::<$I > (), 3 ); }# [ test ] fn cbrt_neg (){ check (& neg ::<$I > (), 3 ); }# [ test ] fn nth_root (){ let bits = 8 * mem :: size_of ::<$I > () as u32 - 1 ; let pos = pos ::<$I > (); for n in 4 .. bits { check (& pos , n ); }}# [ test ] fn nth_root_neg (){ let bits = 8 * mem :: size_of ::<$I > () as u32 - 1 ; let neg = neg ::<$I > (); for n in 2 .. bits / 2 { check (& neg , 2 * n + 1 ); }}# [ test ] fn bit_size (){ let bits = 8 * mem :: size_of ::<$I > () as u32 - 1 ; assert_eq ! ($I :: max_value (). nth_root ( bits - 1 ), 2 ); assert_eq ! ($I :: max_value (). nth_root ( bits ), 1 ); assert_eq ! ($I :: min_value (). nth_root ( bits ), - 2 ); assert_eq ! (($I :: min_value ()+ 1 ). nth_root ( bits ), - 1 ); }} mod $U { use check ; use num_integer :: Roots ; use pos ; use std :: mem ; # [ test ]# [ should_panic ] fn zeroth_root (){( 123 as $U ). nth_root ( 0 ); }# [ test ] fn sqrt (){ check (& pos ::<$U > (), 2 ); }# [ test ] fn cbrt (){ check (& pos ::<$U > (), 3 ); }# [ test ] fn nth_root (){ let bits = 8 * mem :: size_of ::<$I > () as u32 - 1 ; let pos = pos ::<$I > (); for n in 4 .. bits { check (& pos , n ); }}# [ test ] fn bit_size (){ let bits = 8 * mem :: size_of ::<$U > () as u32 ; assert_eq ! ($U :: max_value (). nth_root ( bits - 1 ), 2 ); assert_eq ! ($U :: max_value (). nth_root ( bits ), 1 ); }}}; }
214macro_rules! __ra_macro_fixture213 {($name : ident , $ranges : ident )=>{# [ test ] fn $name (){ let set = ranges_to_set ( general_category ::$ranges ); let hashset : HashSet < u32 > = set . iter (). cloned (). collect (); let trie = TrieSetOwned :: from_codepoints (& set ). unwrap (); for cp in 0 .. 0x110000 { assert ! ( trie . contains_u32 ( cp )== hashset . contains (& cp )); } assert ! (! trie . contains_u32 ( 0x110000 )); assert ! (! hashset . contains (& 0x110000 )); }}; }
215macro_rules! __ra_macro_fixture214 {{$(mod $module : ident ; [$($prop : ident , )*]; )*}=>{$(# [ allow ( unused )] mod $module ; $(pub fn $prop ( c : char )-> bool { self ::$module ::$prop . contains_char ( c )})* )*}; }
216macro_rules! __ra_macro_fixture215 {($name : ident : $input : expr , $($x : tt )* )=>{# [ test ] fn $name (){ let expected_sets = vec ! [$($x )*]; let range_set : RangeSet = $input . parse (). expect ( "parse failed" ); assert_eq ! ( range_set . ranges . len (), expected_sets . len ()); for it in range_set . ranges . iter (). zip ( expected_sets . iter ()){ let ( ai , bi )= it ; assert_eq ! ( ai . comparator_set . len (), * bi ); }}}; }
217macro_rules! __ra_macro_fixture216 {($name : ident : $input : expr , $($x : tt )* )=>{# [ test ] fn $name (){ let expected_sets = vec ! [$($x )*]; let range_set = RangeSet :: parse ($input , Compat :: Npm ). expect ( "parse failed" ); assert_eq ! ( range_set . ranges . len (), expected_sets . len ()); for it in range_set . ranges . iter (). zip ( expected_sets . iter ()){ let ( ai , bi )= it ; assert_eq ! ( ai . comparator_set . len (), * bi ); }}}; }
218macro_rules! __ra_macro_fixture217 {($($name : ident : $value : expr , )* )=>{$(# [ test ] fn $name (){ assert ! ($value . parse ::< RangeSet > (). is_err ()); })* }; }
219macro_rules! __ra_macro_fixture218 {($($name : ident : $value : expr , )* )=>{$(# [ test ] fn $name (){ let ( input , expected_range )= $value ; let parsed_range = parse_range ( input ); let range = from_pair_iterator ( parsed_range , range_set :: Compat :: Cargo ). expect ( "parsing failed" ); let num_comparators = range . comparator_set . len (); let expected_comparators = expected_range . comparator_set . len (); assert_eq ! ( expected_comparators , num_comparators , "expected number of comparators: {}, got: {}" , expected_comparators , num_comparators ); assert_eq ! ( range , expected_range ); })* }; }
220macro_rules! __ra_macro_fixture219 {($($name : ident : $value : expr , )* )=>{$(# [ test ] fn $name (){ let ( input , expected_range )= $value ; let parsed_range = parse_range ( input ); let range = from_pair_iterator ( parsed_range , range_set :: Compat :: Npm ). expect ( "parsing failed" ); let num_comparators = range . comparator_set . len (); let expected_comparators = expected_range . comparator_set . len (); assert_eq ! ( expected_comparators , num_comparators , "expected number of comparators: {}, got: {}" , expected_comparators , num_comparators ); assert_eq ! ( range , expected_range ); })* }; }
221macro_rules! __ra_macro_fixture220 {($ty : ident $(<$lifetime : tt >)*)=>{ impl <$($lifetime ,)* E > Copy for $ty <$($lifetime ,)* E > {} impl <$($lifetime ,)* E > Clone for $ty <$($lifetime ,)* E > { fn clone (& self )-> Self {* self }}}; }
222macro_rules! __ra_macro_fixture221 {($ty : ty , $doc : tt , $name : ident , $method : ident $($cast : tt )*)=>{# [ doc = "A deserializer holding" ]# [ doc = $doc ] pub struct $name < E > { value : $ty , marker : PhantomData < E > } impl_copy_clone ! ($name ); impl < 'de , E > IntoDeserializer < 'de , E > for $ty where E : de :: Error , { type Deserializer = $name < E >; fn into_deserializer ( self )-> $name < E > {$name { value : self , marker : PhantomData , }}} impl < 'de , E > de :: Deserializer < 'de > for $name < E > where E : de :: Error , { type Error = E ; forward_to_deserialize_any ! { bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any } fn deserialize_any < V > ( self , visitor : V )-> Result < V :: Value , Self :: Error > where V : de :: Visitor < 'de >, { visitor .$method ( self . value $($cast )*)}} impl < E > Debug for $name < E > { fn fmt (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . debug_struct ( stringify ! ($name )). field ( "value" , & self . value ). finish ()}}}}
223macro_rules! __ra_macro_fixture222 {($($tt : tt )*)=>{}; }
224macro_rules! __ra_macro_fixture223 {($ty : ident , $deserialize : ident $($methods : tt )*)=>{ impl < 'de > Deserialize < 'de > for $ty {# [ inline ] fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { struct PrimitiveVisitor ; impl < 'de > Visitor < 'de > for PrimitiveVisitor { type Value = $ty ; fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ( stringify ! ($ty ))}$($methods )* } deserializer .$deserialize ( PrimitiveVisitor )}}}; }
225macro_rules! __ra_macro_fixture224 {($ty : ident < T $(: $tbound1 : ident $(+ $tbound2 : ident )*)* $(, $typaram : ident : $bound1 : ident $(+ $bound2 : ident )*)* >, $access : ident , $clear : expr , $with_capacity : expr , $reserve : expr , $insert : expr )=>{ impl < 'de , T $(, $typaram )*> Deserialize < 'de > for $ty < T $(, $typaram )*> where T : Deserialize < 'de > $(+ $tbound1 $(+ $tbound2 )*)*, $($typaram : $bound1 $(+ $bound2 )*,)* { fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { struct SeqVisitor < T $(, $typaram )*> { marker : PhantomData <$ty < T $(, $typaram )*>>, } impl < 'de , T $(, $typaram )*> Visitor < 'de > for SeqVisitor < T $(, $typaram )*> where T : Deserialize < 'de > $(+ $tbound1 $(+ $tbound2 )*)*, $($typaram : $bound1 $(+ $bound2 )*,)* { type Value = $ty < T $(, $typaram )*>; fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ( "a sequence" )}# [ inline ] fn visit_seq < A > ( self , mut $access : A )-> Result < Self :: Value , A :: Error > where A : SeqAccess < 'de >, { let mut values = $with_capacity ; while let Some ( value )= try ! ($access . next_element ()){$insert (& mut values , value ); } Ok ( values )}} let visitor = SeqVisitor { marker : PhantomData }; deserializer . deserialize_seq ( visitor )} fn deserialize_in_place < D > ( deserializer : D , place : & mut Self )-> Result < (), D :: Error > where D : Deserializer < 'de >, { struct SeqInPlaceVisitor < 'a , T : 'a $(, $typaram : 'a )*> (& 'a mut $ty < T $(, $typaram )*>); impl < 'a , 'de , T $(, $typaram )*> Visitor < 'de > for SeqInPlaceVisitor < 'a , T $(, $typaram )*> where T : Deserialize < 'de > $(+ $tbound1 $(+ $tbound2 )*)*, $($typaram : $bound1 $(+ $bound2 )*,)* { type Value = (); fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ( "a sequence" )}# [ inline ] fn visit_seq < A > ( mut self , mut $access : A )-> Result < Self :: Value , A :: Error > where A : SeqAccess < 'de >, {$clear (& mut self . 0 ); $reserve (& mut self . 0 , size_hint :: cautious ($access . size_hint ())); while let Some ( value )= try ! ($access . next_element ()){$insert (& mut self . 0 , value ); } Ok (())}} deserializer . deserialize_seq ( SeqInPlaceVisitor ( place ))}}}}
226macro_rules! __ra_macro_fixture225 {($($len : expr =>($($n : tt )+))+)=>{$(impl < 'de , T > Visitor < 'de > for ArrayVisitor < [ T ; $len ]> where T : Deserialize < 'de >, { type Value = [ T ; $len ]; fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ( concat ! ( "an array of length " , $len ))}# [ inline ] fn visit_seq < A > ( self , mut seq : A )-> Result < Self :: Value , A :: Error > where A : SeqAccess < 'de >, { Ok ([$(match try ! ( seq . next_element ()){ Some ( val )=> val , None => return Err ( Error :: invalid_length ($n , & self )), }),+])}} impl < 'a , 'de , T > Visitor < 'de > for ArrayInPlaceVisitor < 'a , [ T ; $len ]> where T : Deserialize < 'de >, { type Value = (); fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ( concat ! ( "an array of length " , $len ))}# [ inline ] fn visit_seq < A > ( self , mut seq : A )-> Result < Self :: Value , A :: Error > where A : SeqAccess < 'de >, { let mut fail_idx = None ; for ( idx , dest ) in self . 0 [..]. iter_mut (). enumerate (){ if try ! ( seq . next_element_seed ( InPlaceSeed ( dest ))). is_none (){ fail_idx = Some ( idx ); break ; }} if let Some ( idx )= fail_idx { return Err ( Error :: invalid_length ( idx , & self )); } Ok (())}} impl < 'de , T > Deserialize < 'de > for [ T ; $len ] where T : Deserialize < 'de >, { fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { deserializer . deserialize_tuple ($len , ArrayVisitor ::< [ T ; $len ]>:: new ())} fn deserialize_in_place < D > ( deserializer : D , place : & mut Self )-> Result < (), D :: Error > where D : Deserializer < 'de >, { deserializer . deserialize_tuple ($len , ArrayInPlaceVisitor ( place ))}})+ }}
227macro_rules! __ra_macro_fixture226 {($($len : tt =>($($n : tt $name : ident )+))+)=>{$(impl < 'de , $($name : Deserialize < 'de >),+> Deserialize < 'de > for ($($name ,)+){# [ inline ] fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { struct TupleVisitor <$($name ,)+> { marker : PhantomData < ($($name ,)+)>, } impl < 'de , $($name : Deserialize < 'de >),+> Visitor < 'de > for TupleVisitor <$($name ,)+> { type Value = ($($name ,)+); fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ( concat ! ( "a tuple of size " , $len ))}# [ inline ]# [ allow ( non_snake_case )] fn visit_seq < A > ( self , mut seq : A )-> Result < Self :: Value , A :: Error > where A : SeqAccess < 'de >, {$(let $name = match try ! ( seq . next_element ()){ Some ( value )=> value , None => return Err ( Error :: invalid_length ($n , & self )), }; )+ Ok (($($name ,)+))}} deserializer . deserialize_tuple ($len , TupleVisitor { marker : PhantomData })}# [ inline ] fn deserialize_in_place < D > ( deserializer : D , place : & mut Self )-> Result < (), D :: Error > where D : Deserializer < 'de >, { struct TupleInPlaceVisitor < 'a , $($name : 'a ,)+> (& 'a mut ($($name ,)+)); impl < 'a , 'de , $($name : Deserialize < 'de >),+> Visitor < 'de > for TupleInPlaceVisitor < 'a , $($name ,)+> { type Value = (); fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ( concat ! ( "a tuple of size " , $len ))}# [ inline ]# [ allow ( non_snake_case )] fn visit_seq < A > ( self , mut seq : A )-> Result < Self :: Value , A :: Error > where A : SeqAccess < 'de >, {$(if try ! ( seq . next_element_seed ( InPlaceSeed (& mut ( self . 0 ).$n ))). is_none (){ return Err ( Error :: invalid_length ($n , & self )); })+ Ok (())}} deserializer . deserialize_tuple ($len , TupleInPlaceVisitor ( place ))}})+ }}
228macro_rules! __ra_macro_fixture227 {($ty : ident < K $(: $kbound1 : ident $(+ $kbound2 : ident )*)*, V $(, $typaram : ident : $bound1 : ident $(+ $bound2 : ident )*)* >, $access : ident , $with_capacity : expr )=>{ impl < 'de , K , V $(, $typaram )*> Deserialize < 'de > for $ty < K , V $(, $typaram )*> where K : Deserialize < 'de > $(+ $kbound1 $(+ $kbound2 )*)*, V : Deserialize < 'de >, $($typaram : $bound1 $(+ $bound2 )*),* { fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { struct MapVisitor < K , V $(, $typaram )*> { marker : PhantomData <$ty < K , V $(, $typaram )*>>, } impl < 'de , K , V $(, $typaram )*> Visitor < 'de > for MapVisitor < K , V $(, $typaram )*> where K : Deserialize < 'de > $(+ $kbound1 $(+ $kbound2 )*)*, V : Deserialize < 'de >, $($typaram : $bound1 $(+ $bound2 )*),* { type Value = $ty < K , V $(, $typaram )*>; fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ( "a map" )}# [ inline ] fn visit_map < A > ( self , mut $access : A )-> Result < Self :: Value , A :: Error > where A : MapAccess < 'de >, { let mut values = $with_capacity ; while let Some (( key , value ))= try ! ($access . next_entry ()){ values . insert ( key , value ); } Ok ( values )}} let visitor = MapVisitor { marker : PhantomData }; deserializer . deserialize_map ( visitor )}}}}
229macro_rules! __ra_macro_fixture228 {($expecting : tt $ty : ty ; $size : tt )=>{ impl < 'de > Deserialize < 'de > for $ty { fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { if deserializer . is_human_readable (){ deserializer . deserialize_str ( FromStrVisitor :: new ($expecting ))} else {< [ u8 ; $size ]>:: deserialize ( deserializer ). map (<$ty >:: from )}}}}; }
230macro_rules! __ra_macro_fixture229 {($expecting : tt $ty : ty , $new : expr )=>{ impl < 'de > Deserialize < 'de > for $ty { fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { if deserializer . is_human_readable (){ deserializer . deserialize_str ( FromStrVisitor :: new ($expecting ))} else {< (_, u16 )>:: deserialize ( deserializer ). map (| ( ip , port )| $new ( ip , port ))}}}}; }
231macro_rules! __ra_macro_fixture230 {($name_kind : ident ($($variant : ident ; $bytes : expr ; $index : expr ),* )$expecting_message : expr , $variants_name : ident )=>{ enum $name_kind {$($variant ),* } static $variants_name : & 'static [& 'static str ]= & [$(stringify ! ($variant )),*]; impl < 'de > Deserialize < 'de > for $name_kind { fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { struct KindVisitor ; impl < 'de > Visitor < 'de > for KindVisitor { type Value = $name_kind ; fn expecting (& self , formatter : & mut fmt :: Formatter )-> fmt :: Result { formatter . write_str ($expecting_message )} fn visit_u64 < E > ( self , value : u64 )-> Result < Self :: Value , E > where E : Error , { match value {$($index => Ok ($name_kind :: $variant ), )* _ => Err ( Error :: invalid_value ( Unexpected :: Unsigned ( value ), & self ),), }} fn visit_str < E > ( self , value : & str )-> Result < Self :: Value , E > where E : Error , { match value {$(stringify ! ($variant )=> Ok ($name_kind :: $variant ), )* _ => Err ( Error :: unknown_variant ( value , $variants_name )), }} fn visit_bytes < E > ( self , value : & [ u8 ])-> Result < Self :: Value , E > where E : Error , { match value {$($bytes => Ok ($name_kind :: $variant ), )* _ =>{ match str :: from_utf8 ( value ){ Ok ( value )=> Err ( Error :: unknown_variant ( value , $variants_name )), Err (_)=> Err ( Error :: invalid_value ( Unexpected :: Bytes ( value ), & self )), }}}}} deserializer . deserialize_identifier ( KindVisitor )}}}}
232macro_rules! __ra_macro_fixture231 {($(# [ doc = $doc : tt ])* ($($id : ident ),* ), $ty : ty , $func : expr )=>{$(# [ doc = $doc ])* impl < 'de $(, $id : Deserialize < 'de >,)*> Deserialize < 'de > for $ty { fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { Deserialize :: deserialize ( deserializer ). map ($func )}}}}
233macro_rules! __ra_macro_fixture232 {($($T : ident , )+ )=>{$(# [ cfg ( num_nonzero )] impl < 'de > Deserialize < 'de > for num ::$T { fn deserialize < D > ( deserializer : D )-> Result < Self , D :: Error > where D : Deserializer < 'de >, { let value = try ! ( Deserialize :: deserialize ( deserializer )); match < num ::$T >:: new ( value ){ Some ( nonzero )=> Ok ( nonzero ), None => Err ( Error :: custom ( "expected a non-zero value" )), }}})+ }; }
234macro_rules! __ra_macro_fixture233 {( Error : Sized $(+ $($supertrait : ident )::+)*)=>{# [ doc = " The `Error` trait allows `Deserialize` implementations to create descriptive" ]# [ doc = " error messages belonging to the `Deserializer` against which they are" ]# [ doc = " currently running." ]# [ doc = "" ]# [ doc = " Every `Deserializer` declares an `Error` type that encompasses both" ]# [ doc = " general-purpose deserialization errors as well as errors specific to the" ]# [ doc = " particular deserialization format. For example the `Error` type of" ]# [ doc = " `serde_json` can represent errors like an invalid JSON escape sequence or an" ]# [ doc = " unterminated string literal, in addition to the error cases that are part of" ]# [ doc = " this trait." ]# [ doc = "" ]# [ doc = " Most deserializers should only need to provide the `Error::custom` method" ]# [ doc = " and inherit the default behavior for the other methods." ]# [ doc = "" ]# [ doc = " # Example implementation" ]# [ doc = "" ]# [ doc = " The [example data format] presented on the website shows an error" ]# [ doc = " type appropriate for a basic JSON data format." ]# [ doc = "" ]# [ doc = " [example data format]: https://serde.rs/data-format.html" ] pub trait Error : Sized $(+ $($supertrait )::+)* {# [ doc = " Raised when there is general error when deserializing a type." ]# [ doc = "" ]# [ doc = " The message should not be capitalized and should not end with a period." ]# [ doc = "" ]# [ doc = " ```edition2018" ]# [ doc = " # use std::str::FromStr;" ]# [ doc = " #" ]# [ doc = " # struct IpAddr;" ]# [ doc = " #" ]# [ doc = " # impl FromStr for IpAddr {" ]# [ doc = " # type Err = String;" ]# [ doc = " #" ]# [ doc = " # fn from_str(_: &str) -> Result<Self, String> {" ]# [ doc = " # unimplemented!()" ]# [ doc = " # }" ]# [ doc = " # }" ]# [ doc = " #" ]# [ doc = " use serde::de::{self, Deserialize, Deserializer};" ]# [ doc = "" ]# [ doc = " impl<\\\'de> Deserialize<\\\'de> for IpAddr {" ]# [ doc = " fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>" ]# [ doc = " where" ]# [ doc = " D: Deserializer<\\\'de>," ]# [ doc = " {" ]# [ doc = " let s = String::deserialize(deserializer)?;" ]# [ doc = " s.parse().map_err(de::Error::custom)" ]# [ doc = " }" ]# [ doc = " }" ]# [ doc = " ```" ] fn custom < T > ( msg : T )-> Self where T : Display ; # [ doc = " Raised when a `Deserialize` receives a type different from what it was" ]# [ doc = " expecting." ]# [ doc = "" ]# [ doc = " The `unexp` argument provides information about what type was received." ]# [ doc = " This is the type that was present in the input file or other source data" ]# [ doc = " of the Deserializer." ]# [ doc = "" ]# [ doc = " The `exp` argument provides information about what type was being" ]# [ doc = " expected. This is the type that is written in the program." ]# [ doc = "" ]# [ doc = " For example if we try to deserialize a String out of a JSON file" ]# [ doc = " containing an integer, the unexpected type is the integer and the" ]# [ doc = " expected type is the string." ]# [ cold ] fn invalid_type ( unexp : Unexpected , exp : & Expected )-> Self { Error :: custom ( format_args ! ( "invalid type: {}, expected {}" , unexp , exp ))}# [ doc = " Raised when a `Deserialize` receives a value of the right type but that" ]# [ doc = " is wrong for some other reason." ]# [ doc = "" ]# [ doc = " The `unexp` argument provides information about what value was received." ]# [ doc = " This is the value that was present in the input file or other source" ]# [ doc = " data of the Deserializer." ]# [ doc = "" ]# [ doc = " The `exp` argument provides information about what value was being" ]# [ doc = " expected. This is the type that is written in the program." ]# [ doc = "" ]# [ doc = " For example if we try to deserialize a String out of some binary data" ]# [ doc = " that is not valid UTF-8, the unexpected value is the bytes and the" ]# [ doc = " expected value is a string." ]# [ cold ] fn invalid_value ( unexp : Unexpected , exp : & Expected )-> Self { Error :: custom ( format_args ! ( "invalid value: {}, expected {}" , unexp , exp ))}# [ doc = " Raised when deserializing a sequence or map and the input data contains" ]# [ doc = " too many or too few elements." ]# [ doc = "" ]# [ doc = " The `len` argument is the number of elements encountered. The sequence" ]# [ doc = " or map may have expected more arguments or fewer arguments." ]# [ doc = "" ]# [ doc = " The `exp` argument provides information about what data was being" ]# [ doc = " expected. For example `exp` might say that a tuple of size 6 was" ]# [ doc = " expected." ]# [ cold ] fn invalid_length ( len : usize , exp : & Expected )-> Self { Error :: custom ( format_args ! ( "invalid length {}, expected {}" , len , exp ))}# [ doc = " Raised when a `Deserialize` enum type received a variant with an" ]# [ doc = " unrecognized name." ]# [ cold ] fn unknown_variant ( variant : & str , expected : & 'static [& 'static str ])-> Self { if expected . is_empty (){ Error :: custom ( format_args ! ( "unknown variant `{}`, there are no variants" , variant ))} else { Error :: custom ( format_args ! ( "unknown variant `{}`, expected {}" , variant , OneOf { names : expected }))}}# [ doc = " Raised when a `Deserialize` struct type received a field with an" ]# [ doc = " unrecognized name." ]# [ cold ] fn unknown_field ( field : & str , expected : & 'static [& 'static str ])-> Self { if expected . is_empty (){ Error :: custom ( format_args ! ( "unknown field `{}`, there are no fields" , field ))} else { Error :: custom ( format_args ! ( "unknown field `{}`, expected {}" , field , OneOf { names : expected }))}}# [ doc = " Raised when a `Deserialize` struct type expected to receive a required" ]# [ doc = " field with a particular name but that field was not present in the" ]# [ doc = " input." ]# [ cold ] fn missing_field ( field : & 'static str )-> Self { Error :: custom ( format_args ! ( "missing field `{}`" , field ))}# [ doc