| author | bors <bors@rust-lang.org> 2026-06-25 04:45:47 UTC |
| committer | bors <bors@rust-lang.org> 2026-06-25 04:45:47 UTC |
| log | 73100eefe2afb831c4964f579c95beeb27b86e28 |
| tree | ef221079b923742506992b2931ec16c0d55fc053 |
| parent | 8e25b4121d5ea29bef166b86173fb043782ffbff |
| parent | 81526af38549605c9656264e012af035d7fd60aa |
Rollup of 35 pull requests
Successful merges:
- rust-lang/rust#158315 (`rust-analyzer` subtree update)
- rust-lang/rust#158336 (Stop excluding `stdarch` test crates from `rust-src`)
- rust-lang/rust#155739 (Add temporary scope to assert_eq and assert_ne)
- rust-lang/rust#156885 (Fix misattributed type inference error span for index expressions)
- rust-lang/rust#157271 (simplify some `proc_macro` things)
- rust-lang/rust#157419 (move rustc_type_ir Term things to term_kind.rs)
- rust-lang/rust#157883 (Remove strict invariant node_type on hir_type during ty privacy visit)
- rust-lang/rust#157921 (trait solver: Resolve region vars in max universe)
- rust-lang/rust#157960 (delegation: add support for infers in generics)
- rust-lang/rust#157983 (Lift the same-signature restriction for `extern "tail"`)
- rust-lang/rust#158053 (Optimize network address parser)
- rust-lang/rust#158105 (Extract all instance shim variants into new `ShimKind` enum)
- rust-lang/rust#158207 (Resolver: local/external split of `resolve_ident_in_module_non_globs_unadjusted` )
- rust-lang/rust#158279 (Follow goto and drop when linting unreachable code)
- rust-lang/rust#157527 (Move derive tests into their dedicated folder)
- rust-lang/rust#157807 (don't ice on non-lifetime binders under `-Zassumptions-on-binders`)
- rust-lang/rust#157939 (Reorganize `tests/ui/issues` [8/N])
- rust-lang/rust#157946 (Make `char::is_private_use` and `char::is_assigned` unstably public)
- rust-lang/rust#158003 (Reorganize `tests/ui/issues` [9/N])
- rust-lang/rust#158020 (Update mingw-w64 C toolchain)
- rust-lang/rust#158039 (c-variadic: test that we use equality up to free lifetimes)
- rust-lang/rust#158060 (Reorganize `tests/ui/issues` [10/N])
- rust-lang/rust#158222 (format: ignore println newline in foreign format hints)
- rust-lang/rust#158223 (Move target checking for #[lang] to the attribute parser)
- rust-lang/rust#158252 (Use `cfg_select` in `std::os`)
- rust-lang/rust#158263 (Only load the feature list once in the entire resolver)
- rust-lang/rust#158267 (FromUtf8Error::into_utf8_lossy better example and suggest use)
- rust-lang/rust#158272 (Reorganize `tests/ui/issues` [13/N])
- rust-lang/rust#158274 (triagebot: Stop pinging myself)
- rust-lang/rust#158282 (slice_split_once: bounds check optimization note)
- rust-lang/rust#158300 (Improve unknown crate_type diagnostic suggestions)
- rust-lang/rust#158304 (mailmap: update mu001999)
- rust-lang/rust#158309 (Update `rustc-literal-escaper` version to `0.0.8`)
- rust-lang/rust#158314 (Fix incorrect unsafe debug assertion in unchecked_div_exact)
- rust-lang/rust#158326 (Add `io::ErrorKind::TooManyOpenFiles`)421 files changed, 8860 insertions(+), 4983 deletions(-)
.mailmap+1-1| ... | ... | @@ -491,7 +491,6 @@ Milan Landaverde <milanlandaverde@gmail.com> |
| 491 | 491 | mjptree <michael.prantl@hotmail.de> |
| 492 | 492 | Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com> |
| 493 | 493 | msizanoen1 <qtmlabs@protonmail.com> |
| 494 | mu001999 <mu001999@outlook.com> <rcu@live.com> | |
| 495 | 494 | Mukilan Thiagarajan <mukilanthiagarajan@gmail.com> |
| 496 | 495 | Nadrieril Feneanar <Nadrieril@users.noreply.github.com> |
| 497 | 496 | Nadrieril Feneanar <Nadrieril@users.noreply.github.com> <nadrieril+rust@gmail.com> |
| ... | ... | @@ -603,6 +602,7 @@ Robert Habermeier <rphmeier@gmail.com> |
| 603 | 602 | Robert Millar <robert.millar@cantab.net> |
| 604 | 603 | Roc Yu <rocyu@protonmail.com> |
| 605 | 604 | Rohit Joshi <rohitjoshi@users.noreply.github.com> Rohit Joshi <rohit.joshi@capitalone.com> |
| 605 | Roland Xu <rcu@live.com> <mu001999@outlook.com> | |
| 606 | 606 | Ross Smyth <18294397+RossSmyth@users.noreply.github.com> |
| 607 | 607 | Ross Smyth <18294397+RossSmyth@users.noreply.github.com> <crs2017@gmail.com> |
| 608 | 608 | Ross Smyth <18294397+RossSmyth@users.noreply.github.com> <rsmyth@electrocraft.com> |
Cargo.lock+2-2| ... | ... | @@ -3554,9 +3554,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" |
| 3554 | 3554 | |
| 3555 | 3555 | [[package]] |
| 3556 | 3556 | name = "rustc-literal-escaper" |
| 3557 | version = "0.0.7" | |
| 3557 | version = "0.0.8" | |
| 3558 | 3558 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3559 | checksum = "8be87abb9e40db7466e0681dc8ecd9dcfd40360cb10b4c8fe24a7c4c3669b198" | |
| 3559 | checksum = "bfe6f213fb658c8fb95baabd5420393438cf5a98d707f5dd701d9197c705f71e" | |
| 3560 | 3560 | |
| 3561 | 3561 | [[package]] |
| 3562 | 3562 | name = "rustc-main" |
compiler/rustc_ast/Cargo.toml+1-1| ... | ... | @@ -7,7 +7,7 @@ edition = "2024" |
| 7 | 7 | # tidy-alphabetical-start |
| 8 | 8 | bitflags = "2.4.1" |
| 9 | 9 | memchr = "2.7.6" |
| 10 | rustc-literal-escaper = "0.0.7" | |
| 10 | rustc-literal-escaper = "0.0.8" | |
| 11 | 11 | rustc_ast_ir = { path = "../rustc_ast_ir" } |
| 12 | 12 | rustc_data_structures = { path = "../rustc_data_structures" } |
| 13 | 13 | rustc_index = { path = "../rustc_index" } |
compiler/rustc_ast_lowering/src/delegation.rs+65-32| ... | ... | @@ -194,7 +194,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 194 | 194 | return self.generate_delegation_error(span, delegation); |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method); | |
| 197 | let mut generics = self.uplift_delegation_generics(delegation, sig_id); | |
| 198 | 198 | |
| 199 | 199 | let (body_id, call_expr_id, unused_target_expr) = self.lower_delegation_body( |
| 200 | 200 | delegation, |
| ... | ... | @@ -404,10 +404,10 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 404 | 404 | hir::InferDelegationSig::Output(self.arena.alloc(hir::DelegationInfo { |
| 405 | 405 | call_expr_id, |
| 406 | 406 | call_path_res: self.get_resolution_id(call_path_node_id), |
| 407 | child_args_segment_id: generics.child.args_segment_id, | |
| 408 | parent_args_segment_id: generics.parent.args_segment_id, | |
| 409 | self_ty_id: generics.self_ty_id, | |
| 410 | propagate_self_ty: generics.propagate_self_ty, | |
| 407 | child_seg_id: generics.child.args_segment_id, | |
| 408 | child_seg_id_for_sig: generics.child.segment_id_for_sig(), | |
| 409 | parent_seg_id_for_sig: generics.parent.segment_id_for_sig(), | |
| 410 | self_ty_propagation_kind: generics.self_ty_propagation_kind, | |
| 411 | 411 | group_id: { |
| 412 | 412 | let id = match source { |
| 413 | 413 | DelegationSource::Single => None, |
| ... | ... | @@ -625,20 +625,40 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 625 | 625 | }), |
| 626 | 626 | ); |
| 627 | 627 | |
| 628 | hir::QPath::Resolved(ty, self.arena.alloc(new_path)) | |
| 629 | } | |
| 630 | hir::QPath::TypeRelative(ty, segment) => { | |
| 631 | let segment = self.process_segment(span, segment, &mut generics.child); | |
| 628 | // Explicitly create `Self` self-type in case of infers or static | |
| 629 | // free-to-trait reuses. | |
| 630 | let ty = match generics.self_ty_propagation_kind { | |
| 631 | Some(hir::DelegationSelfTyPropagationKind::SelfParam) => { | |
| 632 | let self_param = generics.parent.generics.find_self_param(); | |
| 633 | let path = self.create_generic_arg_path(self_param); | |
| 634 | let kind = hir::TyKind::Path(path); | |
| 635 | ||
| 636 | let ty = match ty { | |
| 637 | Some(ty) => hir::Ty { kind, ..ty.clone() }, | |
| 638 | None => hir::Ty { kind, hir_id: self.next_id(), span }, | |
| 639 | }; | |
| 640 | ||
| 641 | Some(&*self.arena.alloc(ty)) | |
| 642 | } | |
| 643 | _ => ty, | |
| 644 | }; | |
| 632 | 645 | |
| 633 | hir::QPath::TypeRelative(ty, self.arena.alloc(segment)) | |
| 646 | hir::QPath::Resolved(ty, self.arena.alloc(new_path)) | |
| 634 | 647 | } |
| 648 | hir::QPath::TypeRelative(..) => unreachable!("until inherent methods are supported"), | |
| 635 | 649 | }; |
| 636 | 650 | |
| 637 | generics.self_ty_id = match new_path { | |
| 638 | hir::QPath::Resolved(ty, _) => ty, | |
| 639 | hir::QPath::TypeRelative(ty, _) => Some(ty), | |
| 651 | if let Some(hir::DelegationSelfTyPropagationKind::SelfTy(id)) = | |
| 652 | generics.self_ty_propagation_kind.as_mut() | |
| 653 | { | |
| 654 | *id = match new_path { | |
| 655 | hir::QPath::Resolved(ty, _) => { | |
| 656 | ty.expect("must contain self type as `SelfTy` propagation kind is specified") | |
| 657 | } | |
| 658 | hir::QPath::TypeRelative(ty, _) => ty, | |
| 659 | } | |
| 660 | .hir_id; | |
| 640 | 661 | } |
| 641 | .map(|ty| ty.hir_id); | |
| 642 | 662 | |
| 643 | 663 | let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span)); |
| 644 | 664 | let args = self.arena.alloc_from_iter(args); |
| ... | ... | @@ -662,25 +682,38 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 662 | 682 | segment: &hir::PathSegment<'hir>, |
| 663 | 683 | result: &mut GenericsGenerationResult<'hir>, |
| 664 | 684 | ) -> hir::PathSegment<'hir> { |
| 665 | let details = result.generics.args_propagation_details(); | |
| 666 | ||
| 667 | // Always uplift generic params, because if they are not empty then they | |
| 668 | // should be generated in delegation. | |
| 669 | let generics = result.generics.into_hir_generics(self, span); | |
| 670 | let segment = if details.should_propagate { | |
| 671 | let args = generics.into_generic_args(self, span); | |
| 672 | ||
| 673 | // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). | |
| 674 | let args = if args.is_empty() { None } else { Some(args) }; | |
| 675 | ||
| 676 | hir::PathSegment { args, ..segment.clone() } | |
| 677 | } else { | |
| 678 | segment.clone() | |
| 679 | }; | |
| 685 | let infer_indices = result.generics.infer_indices(); | |
| 686 | result.generics.into_hir_generics(self, span); | |
| 687 | ||
| 688 | let mut segment = segment.clone(); | |
| 689 | let mut args_iter = result.generics.create_args_iterator(); | |
| 690 | ||
| 691 | let new_args = segment | |
| 692 | .args | |
| 693 | .filter(|args| !args.is_empty()) | |
| 694 | .map(|args| { | |
| 695 | self.arena.alloc_from_iter(args.args.iter().enumerate().map(|(idx, arg)| { | |
| 696 | if infer_indices.contains(&idx) { | |
| 697 | args_iter.next(self, |_| arg.hir_id()).expect("arg must exist for infer") | |
| 698 | } else { | |
| 699 | *arg | |
| 700 | } | |
| 701 | })) | |
| 702 | }) | |
| 703 | .unwrap_or_else(|| self.arena.alloc_from_iter(args_iter.consume_all(self))); | |
| 704 | ||
| 705 | // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). | |
| 706 | segment.args = (!new_args.is_empty()).then(|| { | |
| 707 | &*self.arena.alloc(hir::GenericArgs { | |
| 708 | args: new_args, | |
| 709 | constraints: &[], | |
| 710 | parenthesized: hir::GenericArgsParentheses::No, | |
| 711 | span_ext: segment.args.map_or(span, |args| args.span_ext), | |
| 712 | }) | |
| 713 | }); | |
| 680 | 714 | |
| 681 | if details.use_args_in_sig_inheritance { | |
| 682 | result.args_segment_id = Some(segment.hir_id); | |
| 683 | } | |
| 715 | result.args_segment_id = segment.hir_id; | |
| 716 | result.use_for_sig_inheritance = !result.generics.is_trait_impl(); | |
| 684 | 717 | |
| 685 | 718 | segment |
| 686 | 719 | } |
compiler/rustc_ast_lowering/src/delegation/generics.rs+304-194| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | use hir::HirId; |
| 2 | 2 | use hir::def::{DefKind, Res}; |
| 3 | 3 | use rustc_ast::*; |
| 4 | use rustc_data_structures::fx::FxHashSet; | |
| 4 | 5 | use rustc_hir as hir; |
| 5 | 6 | use rustc_hir::def_id::DefId; |
| 6 | 7 | use rustc_middle::ty::GenericParamDefKind; |
| ... | ... | @@ -9,21 +10,7 @@ use rustc_span::symbol::kw; |
| 9 | 10 | use rustc_span::{Ident, Span, sym}; |
| 10 | 11 | |
| 11 | 12 | use crate::LoweringContext; |
| 12 | ||
| 13 | #[derive(Clone, Copy)] | |
| 14 | pub(super) enum DelegationGenericsKind { | |
| 15 | /// User-specified args are present: `reuse foo::<String>;`. | |
| 16 | UserSpecified, | |
| 17 | /// The default case when no user-specified args are present: `reuse Trait::foo;`. | |
| 18 | Default, | |
| 19 | /// In free-to-trait reuse, when user specified args for trait `reuse Trait::<i32>::foo;` | |
| 20 | /// in this case we need to both generate `Self` and process user args. | |
| 21 | SelfAndUserSpecified, | |
| 22 | /// In delegations from trait impl to other entities like free functions or trait functions, | |
| 23 | /// we want to generate a function whose generics matches generics of signature function | |
| 24 | /// in trait. | |
| 25 | TraitImpl(bool /* Has user-specified args */), | |
| 26 | } | |
| 13 | use crate::diagnostics::DelegationInfersMismatch; | |
| 27 | 14 | |
| 28 | 15 | #[derive(Debug, Clone, Copy)] |
| 29 | 16 | pub(super) enum GenericsPosition { |
| ... | ... | @@ -31,30 +18,30 @@ pub(super) enum GenericsPosition { |
| 31 | 18 | Child, |
| 32 | 19 | } |
| 33 | 20 | |
| 21 | #[derive(Debug)] | |
| 22 | pub(super) enum GenericArgSlot<T> { | |
| 23 | UserSpecified, | |
| 24 | Generate(T, Option<usize> /* Infer arg index from AST */), | |
| 25 | } | |
| 26 | ||
| 34 | 27 | pub(super) struct DelegationGenerics<T> { |
| 35 | generics: T, | |
| 36 | kind: DelegationGenericsKind, | |
| 28 | data: T, | |
| 37 | 29 | pos: GenericsPosition, |
| 30 | trait_impl: bool, | |
| 38 | 31 | } |
| 39 | 32 | |
| 40 | impl<'hir> DelegationGenerics<&'hir [ty::GenericParamDef]> { | |
| 41 | fn default(generics: &'hir [ty::GenericParamDef], pos: GenericsPosition) -> Self { | |
| 42 | DelegationGenerics { generics, pos, kind: DelegationGenericsKind::Default } | |
| 43 | } | |
| 44 | ||
| 45 | fn user_specified(generics: &'hir [ty::GenericParamDef], pos: GenericsPosition) -> Self { | |
| 46 | DelegationGenerics { generics, pos, kind: DelegationGenericsKind::UserSpecified } | |
| 47 | } | |
| 33 | type TyGenerics<'hir> = Vec<GenericArgSlot<&'hir ty::GenericParamDef>>; | |
| 48 | 34 | |
| 49 | fn trait_impl( | |
| 50 | generics: &'hir [ty::GenericParamDef], | |
| 51 | user_specified: bool, | |
| 35 | impl<'hir> DelegationGenerics<TyGenerics<'hir>> { | |
| 36 | fn generate_all( | |
| 37 | params: &'hir [ty::GenericParamDef], | |
| 52 | 38 | pos: GenericsPosition, |
| 39 | trait_impl: bool, | |
| 53 | 40 | ) -> Self { |
| 54 | 41 | DelegationGenerics { |
| 55 | generics, | |
| 42 | data: params.iter().map(|p| GenericArgSlot::Generate(p, None)).collect(), | |
| 56 | 43 | pos, |
| 57 | kind: DelegationGenericsKind::TraitImpl(user_specified), | |
| 44 | trait_impl, | |
| 58 | 45 | } |
| 59 | 46 | } |
| 60 | 47 | } |
| ... | ... | @@ -70,103 +57,176 @@ impl<'hir> DelegationGenerics<&'hir [ty::GenericParamDef]> { |
| 70 | 57 | /// (i.e., method call scenarios), in such a case this approach helps |
| 71 | 58 | /// a lot as if `into_hir_generics` will not be called then uplifting will not happen. |
| 72 | 59 | pub(super) enum HirOrTyGenerics<'hir> { |
| 73 | Ty(DelegationGenerics<&'hir [ty::GenericParamDef]>), | |
| 60 | Ty(DelegationGenerics<TyGenerics<'hir>>), | |
| 74 | 61 | Hir(DelegationGenerics<&'hir hir::Generics<'hir>>), |
| 75 | 62 | } |
| 76 | 63 | |
| 77 | 64 | pub(super) struct GenericsGenerationResult<'hir> { |
| 78 | 65 | pub(super) generics: HirOrTyGenerics<'hir>, |
| 79 | pub(super) args_segment_id: Option<HirId>, | |
| 66 | pub(super) args_segment_id: HirId, | |
| 67 | pub(super) use_for_sig_inheritance: bool, | |
| 68 | } | |
| 69 | ||
| 70 | impl GenericsGenerationResult<'_> { | |
| 71 | pub(super) fn segment_id_for_sig(&self) -> Option<HirId> { | |
| 72 | self.use_for_sig_inheritance.then(|| self.args_segment_id) | |
| 73 | } | |
| 80 | 74 | } |
| 81 | 75 | |
| 82 | 76 | pub(super) struct GenericsGenerationResults<'hir> { |
| 83 | 77 | pub(super) parent: GenericsGenerationResult<'hir>, |
| 84 | 78 | pub(super) child: GenericsGenerationResult<'hir>, |
| 85 | pub(super) self_ty_id: Option<HirId>, | |
| 86 | pub(super) propagate_self_ty: bool, | |
| 79 | pub(super) self_ty_propagation_kind: Option<hir::DelegationSelfTyPropagationKind>, | |
| 87 | 80 | } |
| 88 | 81 | |
| 89 | pub(super) struct GenericArgsPropagationDetails { | |
| 90 | pub(super) should_propagate: bool, | |
| 91 | pub(super) use_args_in_sig_inheritance: bool, | |
| 82 | pub(super) struct DelegationGenericArgsIterator<'hir> { | |
| 83 | index: usize = Default::default(), | |
| 84 | params: &'hir [hir::GenericParam<'hir>], | |
| 92 | 85 | } |
| 93 | 86 | |
| 94 | impl DelegationGenericsKind { | |
| 95 | fn args_propagation_details(self) -> GenericArgsPropagationDetails { | |
| 96 | match self { | |
| 97 | DelegationGenericsKind::UserSpecified | |
| 98 | | DelegationGenericsKind::SelfAndUserSpecified => GenericArgsPropagationDetails { | |
| 99 | should_propagate: false, | |
| 100 | use_args_in_sig_inheritance: true, | |
| 101 | }, | |
| 102 | DelegationGenericsKind::TraitImpl(user_specified) => GenericArgsPropagationDetails { | |
| 103 | should_propagate: !user_specified, | |
| 104 | use_args_in_sig_inheritance: false, | |
| 105 | }, | |
| 106 | DelegationGenericsKind::Default => GenericArgsPropagationDetails { | |
| 107 | should_propagate: true, | |
| 108 | use_args_in_sig_inheritance: false, | |
| 109 | }, | |
| 87 | /// During generic args propagation we need to create generic args | |
| 88 | /// (and their `HirId`s) on demand, as some of generic args can not be used | |
| 89 | /// and in this case an assert of an unseen `HirId` will be triggered. Moreover, | |
| 90 | /// when replacing infers with generated generic params we should reuse existing | |
| 91 | /// `HirId` of replaced infer, thus this iterator abstracts the way `HirId`s are | |
| 92 | /// created for new generic args. | |
| 93 | impl<'hir> DelegationGenericArgsIterator<'hir> { | |
| 94 | pub(super) fn next( | |
| 95 | &mut self, | |
| 96 | ctx: &mut LoweringContext<'_, 'hir>, | |
| 97 | hir_id_factory: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> HirId, | |
| 98 | ) -> Option<hir::GenericArg<'hir>> { | |
| 99 | let p = loop { | |
| 100 | if self.index >= self.params.len() { | |
| 101 | return None; | |
| 102 | } | |
| 103 | ||
| 104 | let p = self.params[self.index]; | |
| 105 | self.index += 1; | |
| 106 | ||
| 107 | // Skip self generic arg, we do not need to propagate it. | |
| 108 | if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() { | |
| 109 | continue; | |
| 110 | } | |
| 111 | ||
| 112 | break p; | |
| 113 | }; | |
| 114 | ||
| 115 | let hir_id = hir_id_factory(ctx); | |
| 116 | ||
| 117 | Some(match p.kind { | |
| 118 | hir::GenericParamKind::Lifetime { .. } => { | |
| 119 | hir::GenericArg::Lifetime(ctx.arena.alloc(hir::Lifetime { | |
| 120 | hir_id, | |
| 121 | ident: p.name.ident(), | |
| 122 | kind: hir::LifetimeKind::Param(p.def_id), | |
| 123 | source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full }, | |
| 124 | syntax: hir::LifetimeSyntax::ExplicitBound, | |
| 125 | })) | |
| 126 | } | |
| 127 | hir::GenericParamKind::Type { .. } => hir::GenericArg::Type(ctx.arena.alloc(hir::Ty { | |
| 128 | hir_id, | |
| 129 | span: p.span, | |
| 130 | kind: hir::TyKind::Path(ctx.create_generic_arg_path(&p)), | |
| 131 | })), | |
| 132 | hir::GenericParamKind::Const { .. } => { | |
| 133 | hir::GenericArg::Const(ctx.arena.alloc(hir::ConstArg { | |
| 134 | hir_id, | |
| 135 | kind: hir::ConstArgKind::Path(ctx.create_generic_arg_path(&p)), | |
| 136 | span: p.span, | |
| 137 | })) | |
| 138 | } | |
| 139 | }) | |
| 140 | } | |
| 141 | ||
| 142 | pub(super) fn consume_all( | |
| 143 | mut self, | |
| 144 | ctx: &mut LoweringContext<'_, 'hir>, | |
| 145 | ) -> Vec<hir::GenericArg<'hir>> { | |
| 146 | let mut args = vec![]; | |
| 147 | while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) { | |
| 148 | args.push(arg); | |
| 110 | 149 | } |
| 150 | ||
| 151 | args | |
| 111 | 152 | } |
| 112 | 153 | } |
| 113 | 154 | |
| 114 | 155 | impl<'hir> HirOrTyGenerics<'hir> { |
| 115 | pub(super) fn into_hir_generics( | |
| 116 | &mut self, | |
| 117 | ctx: &mut LoweringContext<'_, 'hir>, | |
| 118 | span: Span, | |
| 119 | ) -> &mut HirOrTyGenerics<'hir> { | |
| 156 | pub(super) fn into_hir_generics(&mut self, ctx: &mut LoweringContext<'_, 'hir>, span: Span) { | |
| 120 | 157 | if let HirOrTyGenerics::Ty(ty) = self { |
| 121 | 158 | let rename_self = matches!(ty.pos, GenericsPosition::Child); |
| 122 | let params = ctx.uplift_delegation_generic_params(span, ty.generics, rename_self); | |
| 159 | let params = ctx.uplift_delegation_generic_params(span, &ty.data, rename_self); | |
| 123 | 160 | |
| 124 | 161 | *self = HirOrTyGenerics::Hir(DelegationGenerics { |
| 125 | generics: params, | |
| 126 | kind: ty.kind, | |
| 162 | data: params, | |
| 127 | 163 | pos: ty.pos, |
| 164 | trait_impl: ty.trait_impl, | |
| 128 | 165 | }); |
| 129 | 166 | } |
| 130 | ||
| 131 | self | |
| 132 | 167 | } |
| 133 | 168 | |
| 134 | 169 | fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> { |
| 135 | 170 | match self { |
| 136 | 171 | HirOrTyGenerics::Ty(_) => hir::Generics::empty(), |
| 137 | HirOrTyGenerics::Hir(hir) => hir.generics, | |
| 172 | HirOrTyGenerics::Hir(hir) => hir.data, | |
| 138 | 173 | } |
| 139 | 174 | } |
| 140 | 175 | |
| 141 | pub(super) fn into_generic_args( | |
| 142 | &self, | |
| 143 | ctx: &mut LoweringContext<'_, 'hir>, | |
| 144 | span: Span, | |
| 145 | ) -> &'hir hir::GenericArgs<'hir> { | |
| 176 | pub(super) fn create_args_iterator(&self) -> DelegationGenericArgsIterator<'hir> { | |
| 146 | 177 | match self { |
| 147 | 178 | HirOrTyGenerics::Ty(_) => { |
| 148 | bug!("Attempting to get generic args before uplifting to HIR") | |
| 179 | bug!("attempting to get generic args before uplifting to HIR") | |
| 149 | 180 | } |
| 150 | 181 | HirOrTyGenerics::Hir(hir) => { |
| 151 | let add_lifetimes = matches!(hir.pos, GenericsPosition::Parent); | |
| 152 | ctx.create_generics_args_from_params(hir.generics.params, add_lifetimes, span) | |
| 182 | DelegationGenericArgsIterator { params: hir.data.params, .. } | |
| 153 | 183 | } |
| 154 | 184 | } |
| 155 | 185 | } |
| 156 | 186 | |
| 157 | pub(super) fn args_propagation_details(&self) -> GenericArgsPropagationDetails { | |
| 187 | pub(super) fn infer_indices(&self) -> FxHashSet<usize> { | |
| 158 | 188 | match self { |
| 159 | HirOrTyGenerics::Ty(ty) => ty.kind.args_propagation_details(), | |
| 160 | HirOrTyGenerics::Hir(hir) => hir.kind.args_propagation_details(), | |
| 189 | HirOrTyGenerics::Ty(ty) => ty | |
| 190 | .data | |
| 191 | .iter() | |
| 192 | .flat_map(|slot| match slot { | |
| 193 | GenericArgSlot::Generate(_, Some(idx)) => Some(*idx), | |
| 194 | _ => None, | |
| 195 | }) | |
| 196 | .collect(), | |
| 197 | HirOrTyGenerics::Hir(_) => bug!("accessed infer indices on uplifted generics"), | |
| 198 | } | |
| 199 | } | |
| 200 | ||
| 201 | pub(super) fn is_trait_impl(&self) -> bool { | |
| 202 | match self { | |
| 203 | HirOrTyGenerics::Ty(ty) => ty.trait_impl, | |
| 204 | HirOrTyGenerics::Hir(hir) => hir.trait_impl, | |
| 205 | } | |
| 206 | } | |
| 207 | ||
| 208 | pub(super) fn find_self_param(&self) -> &'hir hir::GenericParam<'hir> { | |
| 209 | match self { | |
| 210 | HirOrTyGenerics::Ty(_) => { | |
| 211 | bug!("accessed ty-level generics while searching for uplifted `Self` param") | |
| 212 | } | |
| 213 | HirOrTyGenerics::Hir(hir) => hir | |
| 214 | .data | |
| 215 | .params | |
| 216 | .iter() | |
| 217 | .find(|p| p.name.ident().name == kw::SelfUpper) | |
| 218 | .expect("`Self` generic param is not found while expected"), | |
| 161 | 219 | } |
| 162 | 220 | } |
| 163 | 221 | } |
| 164 | 222 | |
| 165 | 223 | impl<'hir> GenericsGenerationResult<'hir> { |
| 166 | fn new( | |
| 167 | generics: DelegationGenerics<&'hir [ty::GenericParamDef]>, | |
| 168 | ) -> GenericsGenerationResult<'hir> { | |
| 169 | GenericsGenerationResult { generics: HirOrTyGenerics::Ty(generics), args_segment_id: None } | |
| 224 | fn new(generics: DelegationGenerics<TyGenerics<'hir>>) -> GenericsGenerationResult<'hir> { | |
| 225 | GenericsGenerationResult { | |
| 226 | generics: HirOrTyGenerics::Ty(generics), | |
| 227 | args_segment_id: HirId::INVALID, | |
| 228 | use_for_sig_inheritance: false, | |
| 229 | } | |
| 170 | 230 | } |
| 171 | 231 | } |
| 172 | 232 | |
| ... | ... | @@ -208,13 +268,30 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 208 | 268 | &mut self, |
| 209 | 269 | delegation: &Delegation, |
| 210 | 270 | sig_id: DefId, |
| 211 | is_method: bool, | |
| 212 | 271 | ) -> GenericsGenerationResults<'hir> { |
| 213 | 272 | let delegation_parent_kind = self.tcx.def_kind(self.tcx.local_parent(self.owner.def_id)); |
| 214 | 273 | |
| 215 | 274 | let segments = &delegation.path.segments; |
| 216 | 275 | let len = segments.len(); |
| 217 | let child_user_specified = segments[len - 1].args.is_some(); | |
| 276 | ||
| 277 | let get_user_args = |idx: usize| -> Option<&AngleBracketedArgs> { | |
| 278 | let segment = &segments[idx]; | |
| 279 | ||
| 280 | let Some(args) = segment.args.as_ref() else { return None }; | |
| 281 | let GenericArgs::AngleBracketed(args) = args else { | |
| 282 | self.tcx.dcx().span_delayed_bug( | |
| 283 | segment.span(), | |
| 284 | "expected angle-bracketed generic args in delegation segment", | |
| 285 | ); | |
| 286 | ||
| 287 | return None; | |
| 288 | }; | |
| 289 | ||
| 290 | // Treat empty args `reuse foo::<> as bar` as `reuse foo as bar`, | |
| 291 | // the same logic applied when we call function `fn f<T>(t: T)` | |
| 292 | // like that `f::<>(())`, in HIR no `<>` will be generated. | |
| 293 | (!args.args.is_empty()).then(|| args) | |
| 294 | }; | |
| 218 | 295 | |
| 219 | 296 | let sig_params = &self.tcx.generics_of(sig_id).own_params[..]; |
| 220 | 297 | |
| ... | ... | @@ -223,23 +300,15 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 223 | 300 | if matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }) { |
| 224 | 301 | // Considering parent generics, during signature inheritance |
| 225 | 302 | // we will take those args that are in trait impl header trait ref. |
| 226 | let parent = DelegationGenerics::trait_impl(&[], true, GenericsPosition::Parent); | |
| 227 | let parent = GenericsGenerationResult::new(parent); | |
| 303 | let parent = | |
| 304 | DelegationGenerics { data: vec![], pos: GenericsPosition::Child, trait_impl: true }; | |
| 228 | 305 | |
| 229 | let child = DelegationGenerics::trait_impl( | |
| 230 | sig_params, | |
| 231 | child_user_specified, | |
| 232 | GenericsPosition::Child, | |
| 233 | ); | |
| 306 | let parent = GenericsGenerationResult::new(parent); | |
| 234 | 307 | |
| 308 | let child = DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, true); | |
| 235 | 309 | let child = GenericsGenerationResult::new(child); |
| 236 | 310 | |
| 237 | return GenericsGenerationResults { | |
| 238 | parent, | |
| 239 | child, | |
| 240 | self_ty_id: None, | |
| 241 | propagate_self_ty: false, | |
| 242 | }; | |
| 311 | return GenericsGenerationResults { parent, child, self_ty_propagation_kind: None }; | |
| 243 | 312 | } |
| 244 | 313 | |
| 245 | 314 | let delegation_in_free_ctx = |
| ... | ... | @@ -248,7 +317,13 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 248 | 317 | let sig_parent = self.tcx.parent(sig_id); |
| 249 | 318 | let sig_in_trait = matches!(self.tcx.def_kind(sig_parent), DefKind::Trait); |
| 250 | 319 | let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait; |
| 251 | let generate_self = free_to_trait_delegation && is_method && delegation.qself.is_none(); | |
| 320 | ||
| 321 | let qself_is_infer = | |
| 322 | delegation.qself.as_ref().is_some_and(|qself| qself.ty.is_maybe_parenthesised_infer()); | |
| 323 | ||
| 324 | let qself_is_none = delegation.qself.is_none(); | |
| 325 | ||
| 326 | let generate_self = free_to_trait_delegation && (qself_is_none || qself_is_infer); | |
| 252 | 327 | |
| 253 | 328 | let can_add_generics_to_parent = len >= 2 |
| 254 | 329 | && self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| { |
| ... | ... | @@ -256,57 +331,137 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 256 | 331 | }); |
| 257 | 332 | |
| 258 | 333 | let parent_generics = if can_add_generics_to_parent { |
| 259 | let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params[..]; | |
| 260 | ||
| 261 | if segments[len - 2].args.is_some() { | |
| 262 | if generate_self { | |
| 263 | // Take only first Self parameter, it is trait so Self must be present. | |
| 264 | DelegationGenerics { | |
| 265 | kind: DelegationGenericsKind::SelfAndUserSpecified, | |
| 266 | generics: &sig_parent_params[..1], | |
| 267 | pos: GenericsPosition::Parent, | |
| 268 | } | |
| 269 | } else { | |
| 270 | DelegationGenerics::user_specified(&[], GenericsPosition::Parent) | |
| 334 | let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params; | |
| 335 | ||
| 336 | if let Some(args) = get_user_args(len - 2) { | |
| 337 | DelegationGenerics { | |
| 338 | data: self.create_slots_from_args( | |
| 339 | args, | |
| 340 | &sig_parent_params[usize::from(!generate_self)..], | |
| 341 | generate_self, | |
| 342 | ), | |
| 343 | pos: GenericsPosition::Parent, | |
| 344 | trait_impl: false, | |
| 271 | 345 | } |
| 272 | 346 | } else { |
| 273 | let skip_self = usize::from(!generate_self); | |
| 274 | DelegationGenerics::default( | |
| 275 | &sig_parent_params[skip_self..], | |
| 347 | DelegationGenerics::generate_all( | |
| 348 | &sig_parent_params[usize::from(!generate_self)..], | |
| 276 | 349 | GenericsPosition::Parent, |
| 350 | false, | |
| 277 | 351 | ) |
| 278 | 352 | } |
| 279 | 353 | } else { |
| 280 | DelegationGenerics::default(&[], GenericsPosition::Parent) | |
| 354 | DelegationGenerics { data: vec![], pos: GenericsPosition::Parent, trait_impl: false } | |
| 281 | 355 | }; |
| 282 | 356 | |
| 283 | let child_generics = if child_user_specified { | |
| 357 | let child_generics = if let Some(args) = get_user_args(len - 1) { | |
| 284 | 358 | let synth_params_index = |
| 285 | 359 | sig_params.iter().position(|p| p.kind.is_synthetic()).unwrap_or(sig_params.len()); |
| 286 | 360 | |
| 287 | DelegationGenerics::user_specified( | |
| 288 | &sig_params[synth_params_index..], | |
| 289 | GenericsPosition::Child, | |
| 290 | ) | |
| 361 | let mut slots = | |
| 362 | self.create_slots_from_args(args, &sig_params[..synth_params_index], false); | |
| 363 | ||
| 364 | for synth_param in &sig_params[synth_params_index..] { | |
| 365 | slots.push(GenericArgSlot::Generate(synth_param, None)); | |
| 366 | } | |
| 367 | ||
| 368 | DelegationGenerics { data: slots, pos: GenericsPosition::Child, trait_impl: false } | |
| 291 | 369 | } else { |
| 292 | DelegationGenerics::default(sig_params, GenericsPosition::Child) | |
| 370 | DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, false) | |
| 293 | 371 | }; |
| 294 | 372 | |
| 295 | 373 | GenericsGenerationResults { |
| 296 | 374 | parent: GenericsGenerationResult::new(parent_generics), |
| 297 | 375 | child: GenericsGenerationResult::new(child_generics), |
| 298 | self_ty_id: None, | |
| 299 | propagate_self_ty: free_to_trait_delegation && !generate_self, | |
| 376 | self_ty_propagation_kind: match free_to_trait_delegation { | |
| 377 | true => Some(match qself_is_none { | |
| 378 | true => hir::DelegationSelfTyPropagationKind::SelfParam, | |
| 379 | false => match qself_is_infer { | |
| 380 | true => hir::DelegationSelfTyPropagationKind::SelfParam, | |
| 381 | // HirId is filled during generic args propagation. | |
| 382 | false => hir::DelegationSelfTyPropagationKind::SelfTy(HirId::INVALID), | |
| 383 | }, | |
| 384 | }), | |
| 385 | false => None, | |
| 386 | }, | |
| 387 | } | |
| 388 | } | |
| 389 | ||
| 390 | /// Generates generic argument slots for user-specified `args` and | |
| 391 | /// generic `params` of the signature function. This function checks whether | |
| 392 | /// there are infers (`kw::UnderscoreLifetime` or `kw::Underscore`) in | |
| 393 | /// user-specified args, and if so we add `Generate` slot meaning we have to | |
| 394 | /// generate generic param for delegation and propagate it instead of this infer. | |
| 395 | /// We zip over user-specified args and signature generic params, so if there are more | |
| 396 | /// infers than generic params then we will not process all infers thus not generating | |
| 397 | /// more generic params then needed (anyway it is an error). | |
| 398 | fn create_slots_from_args( | |
| 399 | &self, | |
| 400 | args: &AngleBracketedArgs, | |
| 401 | params: &'hir [ty::GenericParamDef], | |
| 402 | add_first_self: bool, | |
| 403 | ) -> TyGenerics<'hir> { | |
| 404 | let mut slots = vec![]; | |
| 405 | if add_first_self { | |
| 406 | slots.push(GenericArgSlot::Generate(&params[0], None)); | |
| 407 | } | |
| 408 | ||
| 409 | let params = &params[usize::from(add_first_self)..]; | |
| 410 | for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() { | |
| 411 | let AngleBracketedArg::Arg(arg) = arg else { continue }; | |
| 412 | ||
| 413 | let is_infer = match arg { | |
| 414 | GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime, | |
| 415 | GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(), | |
| 416 | GenericArg::Const(_) => false, | |
| 417 | }; | |
| 418 | ||
| 419 | // If `'_` is used instead of `_` (or vice versa) we emit a meaningful | |
| 420 | // error instead of processing this infer or leaving it as is for signature | |
| 421 | // inheritance. | |
| 422 | if is_infer | |
| 423 | && matches!( | |
| 424 | (arg, &param.kind), | |
| 425 | ( | |
| 426 | GenericArg::Lifetime(_), | |
| 427 | GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } | |
| 428 | ) | ( | |
| 429 | GenericArg::Type(_) | GenericArg::Const(_), | |
| 430 | GenericParamDefKind::Lifetime { .. } | |
| 431 | ) | |
| 432 | ) | |
| 433 | { | |
| 434 | let (actual, expected) = if matches!(arg, GenericArg::Lifetime(..)) { | |
| 435 | (kw::UnderscoreLifetime, kw::Underscore) | |
| 436 | } else { | |
| 437 | (kw::Underscore, kw::UnderscoreLifetime) | |
| 438 | }; | |
| 439 | ||
| 440 | self.tcx.dcx().emit_err(DelegationInfersMismatch { | |
| 441 | span: arg.span(), | |
| 442 | actual, | |
| 443 | expected, | |
| 444 | }); | |
| 445 | } | |
| 446 | ||
| 447 | slots.push(match is_infer { | |
| 448 | true => GenericArgSlot::Generate(param, Some(idx)), | |
| 449 | false => GenericArgSlot::UserSpecified, | |
| 450 | }); | |
| 300 | 451 | } |
| 452 | ||
| 453 | slots | |
| 301 | 454 | } |
| 302 | 455 | |
| 303 | 456 | fn uplift_delegation_generic_params( |
| 304 | 457 | &mut self, |
| 305 | 458 | span: Span, |
| 306 | params: &'hir [ty::GenericParamDef], | |
| 459 | params: &[GenericArgSlot<&ty::GenericParamDef>], | |
| 307 | 460 | rename_self: bool, |
| 308 | 461 | ) -> &'hir hir::Generics<'hir> { |
| 309 | let params = self.arena.alloc_from_iter(params.iter().map(|p| { | |
| 462 | let params = self.arena.alloc_from_iter(params.iter().flat_map(|p| { | |
| 463 | let GenericArgSlot::Generate(p, _) = p else { return None }; | |
| 464 | ||
| 310 | 465 | let def_kind = match p.kind { |
| 311 | 466 | GenericParamDefKind::Lifetime => DefKind::LifetimeParam, |
| 312 | 467 | GenericParamDefKind::Type { .. } => DefKind::TyParam, |
| ... | ... | @@ -354,7 +509,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 354 | 509 | // `lower_node_id` routine so param's id is added to `self.children`. |
| 355 | 510 | let hir_id = self.lower_node_id(node_id); |
| 356 | 511 | |
| 357 | hir::GenericParam { | |
| 512 | Some(hir::GenericParam { | |
| 358 | 513 | hir_id, |
| 359 | 514 | colon_span: Some(span), |
| 360 | 515 | def_id, |
| ... | ... | @@ -363,7 +518,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 363 | 518 | pure_wrt_drop: p.pure_wrt_drop, |
| 364 | 519 | source: hir::GenericParamSource::Generics, |
| 365 | 520 | span, |
| 366 | } | |
| 521 | }) | |
| 367 | 522 | })); |
| 368 | 523 | |
| 369 | 524 | // HACK: for now we generate predicates such that all lifetimes are early bound, |
| ... | ... | @@ -413,77 +568,32 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 413 | 568 | } |
| 414 | 569 | } |
| 415 | 570 | |
| 416 | fn create_generics_args_from_params( | |
| 571 | pub(super) fn create_generic_arg_path( | |
| 417 | 572 | &mut self, |
| 418 | params: &[hir::GenericParam<'hir>], | |
| 419 | add_lifetimes: bool, | |
| 420 | span: Span, | |
| 421 | ) -> &'hir hir::GenericArgs<'hir> { | |
| 422 | self.arena.alloc(hir::GenericArgs { | |
| 423 | args: self.arena.alloc_from_iter(params.iter().filter_map(|p| { | |
| 424 | // Skip self generic arg, we do not need to propagate it. | |
| 425 | if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() { | |
| 426 | return None; | |
| 427 | } | |
| 428 | ||
| 429 | let create_path = |this: &mut Self| { | |
| 430 | let res = Res::Def( | |
| 431 | match p.kind { | |
| 432 | hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, | |
| 433 | hir::GenericParamKind::Type { .. } => DefKind::TyParam, | |
| 434 | hir::GenericParamKind::Const { .. } => DefKind::ConstParam, | |
| 435 | }, | |
| 436 | p.def_id.to_def_id(), | |
| 437 | ); | |
| 438 | ||
| 439 | hir::QPath::Resolved( | |
| 440 | None, | |
| 441 | self.arena.alloc(hir::Path { | |
| 442 | segments: this.arena.alloc_slice(&[hir::PathSegment { | |
| 443 | args: None, | |
| 444 | hir_id: this.next_id(), | |
| 445 | ident: p.name.ident(), | |
| 446 | infer_args: false, | |
| 447 | res, | |
| 448 | }]), | |
| 449 | res, | |
| 450 | span: p.span, | |
| 451 | }), | |
| 452 | ) | |
| 453 | }; | |
| 454 | ||
| 455 | match p.kind { | |
| 456 | hir::GenericParamKind::Lifetime { .. } => match add_lifetimes { | |
| 457 | true => Some(hir::GenericArg::Lifetime(self.arena.alloc(hir::Lifetime { | |
| 458 | hir_id: self.next_id(), | |
| 459 | ident: p.name.ident(), | |
| 460 | kind: hir::LifetimeKind::Param(p.def_id), | |
| 461 | source: hir::LifetimeSource::Path { | |
| 462 | angle_brackets: hir::AngleBrackets::Full, | |
| 463 | }, | |
| 464 | syntax: hir::LifetimeSyntax::ExplicitBound, | |
| 465 | }))), | |
| 466 | false => None, | |
| 467 | }, | |
| 468 | hir::GenericParamKind::Type { .. } => { | |
| 469 | Some(hir::GenericArg::Type(self.arena.alloc(hir::Ty { | |
| 470 | hir_id: self.next_id(), | |
| 471 | span: p.span, | |
| 472 | kind: hir::TyKind::Path(create_path(self)), | |
| 473 | }))) | |
| 474 | } | |
| 475 | hir::GenericParamKind::Const { .. } => { | |
| 476 | Some(hir::GenericArg::Const(self.arena.alloc(hir::ConstArg { | |
| 477 | hir_id: self.next_id(), | |
| 478 | kind: hir::ConstArgKind::Path(create_path(self)), | |
| 479 | span: p.span, | |
| 480 | }))) | |
| 481 | } | |
| 482 | } | |
| 483 | })), | |
| 484 | constraints: &[], | |
| 485 | parenthesized: hir::GenericArgsParentheses::No, | |
| 486 | span_ext: span, | |
| 487 | }) | |
| 573 | p: &hir::GenericParam<'hir>, | |
| 574 | ) -> hir::QPath<'hir> { | |
| 575 | let res = Res::Def( | |
| 576 | match p.kind { | |
| 577 | hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, | |
| 578 | hir::GenericParamKind::Type { .. } => DefKind::TyParam, | |
| 579 | hir::GenericParamKind::Const { .. } => DefKind::ConstParam, | |
| 580 | }, | |
| 581 | p.def_id.to_def_id(), | |
| 582 | ); | |
| 583 | ||
| 584 | hir::QPath::Resolved( | |
| 585 | None, | |
| 586 | self.arena.alloc(hir::Path { | |
| 587 | segments: self.arena.alloc_slice(&[hir::PathSegment { | |
| 588 | args: None, | |
| 589 | hir_id: self.next_id(), | |
| 590 | ident: p.name.ident(), | |
| 591 | infer_args: false, | |
| 592 | res, | |
| 593 | }]), | |
| 594 | res, | |
| 595 | span: p.span, | |
| 596 | }), | |
| 597 | ) | |
| 488 | 598 | } |
| 489 | 599 | } |
compiler/rustc_ast_lowering/src/diagnostics.rs+9| ... | ... | @@ -560,3 +560,12 @@ pub(crate) struct DelegationAttemptedBlockWithDefsDeletion { |
| 560 | 560 | #[primary_span] |
| 561 | 561 | pub span: Span, |
| 562 | 562 | } |
| 563 | ||
| 564 | #[derive(Diagnostic)] | |
| 565 | #[diag("wrong infer used: expected {$expected}, found: {$actual}")] | |
| 566 | pub(crate) struct DelegationInfersMismatch { | |
| 567 | #[primary_span] | |
| 568 | pub span: Span, | |
| 569 | pub expected: Symbol, | |
| 570 | pub actual: Symbol, | |
| 571 | } |
compiler/rustc_ast_lowering/src/lib.rs+3| ... | ... | @@ -31,6 +31,9 @@ |
| 31 | 31 | //! in the HIR, especially for multiple identifiers. |
| 32 | 32 | |
| 33 | 33 | // tidy-alphabetical-start |
| 34 | #![feature(const_default)] | |
| 35 | #![feature(const_trait_impl)] | |
| 36 | #![feature(default_field_values)] | |
| 34 | 37 | #![feature(deref_patterns)] |
| 35 | 38 | #![recursion_limit = "256"] |
| 36 | 39 | // tidy-alphabetical-end |
compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs+3-3| ... | ... | @@ -11,7 +11,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser { |
| 11 | 11 | type Item = (Symbol, Span); |
| 12 | 12 | const CONVERT: ConvertFn<Self::Item> = |
| 13 | 13 | |items, span| AttributeKind::AllowInternalUnstable(items, span); |
| 14 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 14 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 15 | 15 | Allow(Target::MacroDef), |
| 16 | 16 | Allow(Target::Fn), |
| 17 | 17 | Warn(Target::Field), |
| ... | ... | @@ -36,7 +36,7 @@ impl CombineAttributeParser for UnstableFeatureBoundParser { |
| 36 | 36 | type Item = (Symbol, Span); |
| 37 | 37 | const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::UnstableFeatureBound(items); |
| 38 | 38 | const STABILITY: AttributeStability = unstable!(staged_api); |
| 39 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 39 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 40 | 40 | Allow(Target::Fn), |
| 41 | 41 | Allow(Target::Impl { of_trait: true }), |
| 42 | 42 | Allow(Target::Trait), |
| ... | ... | @@ -59,7 +59,7 @@ impl CombineAttributeParser for RustcAllowConstFnUnstableParser { |
| 59 | 59 | type Item = Symbol; |
| 60 | 60 | const CONVERT: ConvertFn<Self::Item> = |
| 61 | 61 | |items, first_span| AttributeKind::RustcAllowConstFnUnstable(items, first_span); |
| 62 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 62 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 63 | 63 | Allow(Target::Fn), |
| 64 | 64 | Allow(Target::Method(MethodKind::Inherent)), |
| 65 | 65 | Allow(Target::Method(MethodKind::Trait { body: true })), |
compiler/rustc_attr_parsing/src/attributes/autodiff.rs+1-1| ... | ... | @@ -19,7 +19,7 @@ pub(crate) struct RustcAutodiffParser; |
| 19 | 19 | |
| 20 | 20 | impl SingleAttributeParser for RustcAutodiffParser { |
| 21 | 21 | const PATH: &[Symbol] = &[sym::rustc_autodiff]; |
| 22 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 22 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 23 | 23 | Allow(Target::Fn), |
| 24 | 24 | Allow(Target::Method(MethodKind::Inherent)), |
| 25 | 25 | Allow(Target::Method(MethodKind::Trait { body: true })), |
compiler/rustc_attr_parsing/src/attributes/body.rs+2-1| ... | ... | @@ -8,7 +8,8 @@ pub(crate) struct CoroutineParser; |
| 8 | 8 | |
| 9 | 9 | impl NoArgsAttributeParser for CoroutineParser { |
| 10 | 10 | const PATH: &[Symbol] = &[sym::coroutine]; |
| 11 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]); | |
| 11 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 12 | AllowedTargets::AllowList(&[Allow(Target::Closure)]); | |
| 12 | 13 | const STABILITY: AttributeStability = unstable!(coroutines); |
| 13 | 14 | const CREATE: fn(rustc_span::Span) -> AttributeKind = |_| AttributeKind::Coroutine; |
| 14 | 15 | } |
compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ use super::prelude::*; |
| 4 | 4 | pub(crate) struct CfiEncodingParser; |
| 5 | 5 | impl SingleAttributeParser for CfiEncodingParser { |
| 6 | 6 | const PATH: &[Symbol] = &[sym::cfi_encoding]; |
| 7 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 7 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 8 | 8 | Allow(Target::Struct), |
| 9 | 9 | Allow(Target::ForeignTy), |
| 10 | 10 | Allow(Target::Enum), |
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs+18-18| ... | ... | @@ -18,7 +18,7 @@ pub(crate) struct OptimizeParser; |
| 18 | 18 | |
| 19 | 19 | impl SingleAttributeParser for OptimizeParser { |
| 20 | 20 | const PATH: &[Symbol] = &[sym::optimize]; |
| 21 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 21 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 22 | 22 | Allow(Target::Fn), |
| 23 | 23 | Allow(Target::Closure), |
| 24 | 24 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -51,7 +51,7 @@ pub(crate) struct ColdParser; |
| 51 | 51 | impl NoArgsAttributeParser for ColdParser { |
| 52 | 52 | const PATH: &[Symbol] = &[sym::cold]; |
| 53 | 53 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 54 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 54 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 55 | 55 | Allow(Target::Fn), |
| 56 | 56 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| 57 | 57 | Allow(Target::Method(MethodKind::TraitImpl)), |
| ... | ... | @@ -67,7 +67,7 @@ pub(crate) struct CoverageParser; |
| 67 | 67 | |
| 68 | 68 | impl SingleAttributeParser for CoverageParser { |
| 69 | 69 | const PATH: &[Symbol] = &[sym::coverage]; |
| 70 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 70 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 71 | 71 | Allow(Target::Fn), |
| 72 | 72 | Allow(Target::Closure), |
| 73 | 73 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -114,7 +114,7 @@ impl SingleAttributeParser for ExportNameParser { |
| 114 | 114 | note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them", |
| 115 | 115 | unsafe_since: Some(Edition2024), |
| 116 | 116 | }; |
| 117 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 117 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 118 | 118 | Allow(Target::Static), |
| 119 | 119 | Allow(Target::Fn), |
| 120 | 120 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -151,7 +151,7 @@ pub(crate) struct RustcObjcClassParser; |
| 151 | 151 | |
| 152 | 152 | impl SingleAttributeParser for RustcObjcClassParser { |
| 153 | 153 | const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_class]; |
| 154 | const ALLOWED_TARGETS: AllowedTargets = | |
| 154 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 155 | 155 | AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); |
| 156 | 156 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName"); |
| 157 | 157 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| ... | ... | @@ -179,7 +179,7 @@ pub(crate) struct RustcObjcSelectorParser; |
| 179 | 179 | |
| 180 | 180 | impl SingleAttributeParser for RustcObjcSelectorParser { |
| 181 | 181 | const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_selector]; |
| 182 | const ALLOWED_TARGETS: AllowedTargets = | |
| 182 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 183 | 183 | AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); |
| 184 | 184 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName"); |
| 185 | 185 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| ... | ... | @@ -226,7 +226,7 @@ impl AttributeParser for NakedParser { |
| 226 | 226 | note: "the `#[naked]` attribute adds the safety obligation that the function's body must respect the function’s calling convention, uphold its signature, and either return or diverge (i.e., not fall through past the end of the assembly code).", |
| 227 | 227 | unsafe_since: None, |
| 228 | 228 | }; |
| 229 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 229 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 230 | 230 | Allow(Target::Fn), |
| 231 | 231 | Allow(Target::Method(MethodKind::Inherent)), |
| 232 | 232 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -334,7 +334,7 @@ pub(crate) struct TrackCallerParser; |
| 334 | 334 | impl NoArgsAttributeParser for TrackCallerParser { |
| 335 | 335 | const PATH: &[Symbol] = &[sym::track_caller]; |
| 336 | 336 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 337 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 337 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 338 | 338 | Allow(Target::Fn), |
| 339 | 339 | Allow(Target::Method(MethodKind::Inherent)), |
| 340 | 340 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -359,7 +359,7 @@ impl NoArgsAttributeParser for NoMangleParser { |
| 359 | 359 | note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them", |
| 360 | 360 | unsafe_since: Some(Edition2024), |
| 361 | 361 | }; |
| 362 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 362 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 363 | 363 | Allow(Target::Fn), |
| 364 | 364 | Allow(Target::Static), |
| 365 | 365 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -462,7 +462,7 @@ impl AttributeParser for UsedParser { |
| 462 | 462 | } |
| 463 | 463 | }, |
| 464 | 464 | )]; |
| 465 | const ALLOWED_TARGETS: AllowedTargets = | |
| 465 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 466 | 466 | AllowedTargets::AllowList(&[Allow(Target::Static), Warn(Target::MacroCall)]); |
| 467 | 467 | |
| 468 | 468 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
| ... | ... | @@ -533,7 +533,7 @@ impl CombineAttributeParser for TargetFeatureParser { |
| 533 | 533 | parse_tf_attribute(cx, args) |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 536 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 537 | 537 | Allow(Target::Fn), |
| 538 | 538 | Allow(Target::Method(MethodKind::Inherent)), |
| 539 | 539 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -561,7 +561,7 @@ impl CombineAttributeParser for ForceTargetFeatureParser { |
| 561 | 561 | was_forced: true, |
| 562 | 562 | }; |
| 563 | 563 | const TEMPLATE: AttributeTemplate = template!(List: &["enable = \"feat1, feat2\""]); |
| 564 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 564 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 565 | 565 | Allow(Target::Fn), |
| 566 | 566 | Allow(Target::Method(MethodKind::Inherent)), |
| 567 | 567 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -581,7 +581,7 @@ pub(crate) struct InstrumentFnParser; |
| 581 | 581 | |
| 582 | 582 | impl SingleAttributeParser for InstrumentFnParser { |
| 583 | 583 | const PATH: &[Symbol] = &[sym::instrument_fn]; |
| 584 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 584 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 585 | 585 | Allow(Target::Fn), |
| 586 | 586 | Allow(Target::Method(MethodKind::Inherent)), |
| 587 | 587 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -619,7 +619,7 @@ pub(crate) struct SanitizeParser; |
| 619 | 619 | |
| 620 | 620 | impl SingleAttributeParser for SanitizeParser { |
| 621 | 621 | const PATH: &[Symbol] = &[sym::sanitize]; |
| 622 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 622 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 623 | 623 | Allow(Target::Fn), |
| 624 | 624 | Allow(Target::Closure), |
| 625 | 625 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -751,7 +751,7 @@ pub(crate) struct ThreadLocalParser; |
| 751 | 751 | |
| 752 | 752 | impl NoArgsAttributeParser for ThreadLocalParser { |
| 753 | 753 | const PATH: &[Symbol] = &[sym::thread_local]; |
| 754 | const ALLOWED_TARGETS: AllowedTargets = | |
| 754 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 755 | 755 | AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]); |
| 756 | 756 | const STABILITY: AttributeStability = unstable!(thread_local); |
| 757 | 757 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal; |
| ... | ... | @@ -761,7 +761,7 @@ pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser; |
| 761 | 761 | |
| 762 | 762 | impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisParser { |
| 763 | 763 | const PATH: &[Symbol] = &[sym::rustc_pass_indirectly_in_non_rustic_abis]; |
| 764 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 764 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 765 | 765 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 766 | 766 | const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis; |
| 767 | 767 | } |
| ... | ... | @@ -770,7 +770,7 @@ pub(crate) struct RustcEiiForeignItemParser; |
| 770 | 770 | |
| 771 | 771 | impl NoArgsAttributeParser for RustcEiiForeignItemParser { |
| 772 | 772 | const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item]; |
| 773 | const ALLOWED_TARGETS: AllowedTargets = | |
| 773 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 774 | 774 | AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]); |
| 775 | 775 | const STABILITY: AttributeStability = unstable!(eii_internals); |
| 776 | 776 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem; |
| ... | ... | @@ -780,7 +780,7 @@ pub(crate) struct PatchableFunctionEntryParser; |
| 780 | 780 | |
| 781 | 781 | impl SingleAttributeParser for PatchableFunctionEntryParser { |
| 782 | 782 | const PATH: &[Symbol] = &[sym::patchable_function_entry]; |
| 783 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 783 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 784 | 784 | const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]); |
| 785 | 785 | const STABILITY: AttributeStability = unstable!(patchable_function_entry); |
| 786 | 786 |
compiler/rustc_attr_parsing/src/attributes/confusables.rs+1-1| ... | ... | @@ -32,7 +32,7 @@ impl AttributeParser for ConfusablesParser { |
| 32 | 32 | this.first_span.get_or_insert(cx.attr_span); |
| 33 | 33 | }, |
| 34 | 34 | )]; |
| 35 | const ALLOWED_TARGETS: AllowedTargets = | |
| 35 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 36 | 36 | AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]); |
| 37 | 37 | |
| 38 | 38 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
compiler/rustc_attr_parsing/src/attributes/crate_level.rs+23-23| ... | ... | @@ -2,7 +2,7 @@ use rustc_feature::AttributeStability; |
| 2 | 2 | use rustc_hir::attrs::{CrateType, WindowsSubsystemKind}; |
| 3 | 3 | use rustc_session::lint::builtin::UNKNOWN_CRATE_TYPES; |
| 4 | 4 | use rustc_span::Symbol; |
| 5 | use rustc_span::edit_distance::find_best_match_for_name; | |
| 5 | use rustc_span::edit_distance::find_best_match_for_name_with_substrings; | |
| 6 | 6 | |
| 7 | 7 | use super::prelude::*; |
| 8 | 8 | use crate::diagnostics::{UnknownCrateTypes, UnknownCrateTypesSuggestion}; |
| ... | ... | @@ -13,7 +13,7 @@ impl SingleAttributeParser for CrateNameParser { |
| 13 | 13 | const PATH: &[Symbol] = &[sym::crate_name]; |
| 14 | 14 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 15 | 15 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); |
| 16 | const ALLOWED_TARGETS: AllowedTargets = | |
| 16 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 17 | 17 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 18 | 18 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 19 | 19 | |
| ... | ... | @@ -32,7 +32,7 @@ impl CombineAttributeParser for CrateTypeParser { |
| 32 | 32 | const PATH: &[Symbol] = &[sym::crate_type]; |
| 33 | 33 | type Item = CrateType; |
| 34 | 34 | const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::CrateType(items); |
| 35 | const ALLOWED_TARGETS: AllowedTargets = | |
| 35 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 36 | 36 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 37 | 37 | const TEMPLATE: AttributeTemplate = |
| 38 | 38 | template!(NameValueStr: "crate type", "https://doc.rust-lang.org/reference/linkage.html"); |
| ... | ... | @@ -49,10 +49,10 @@ impl CombineAttributeParser for CrateTypeParser { |
| 49 | 49 | let Ok(crate_type) = crate_type.try_into() else { |
| 50 | 50 | // We don't error on invalid `#![crate_type]` when not applied to a crate |
| 51 | 51 | if cx.shared.target == Target::Crate { |
| 52 | let candidate = find_best_match_for_name( | |
| 52 | let candidate = find_best_match_for_name_with_substrings( | |
| 53 | 53 | &CrateType::all_stable().iter().map(|(name, _)| *name).collect::<Vec<_>>(), |
| 54 | 54 | crate_type, |
| 55 | None, | |
| 55 | Some(5), | |
| 56 | 56 | ); |
| 57 | 57 | let span = n.value_span; |
| 58 | 58 | cx.emit_lint( |
| ... | ... | @@ -76,7 +76,7 @@ impl SingleAttributeParser for RecursionLimitParser { |
| 76 | 76 | const PATH: &[Symbol] = &[sym::recursion_limit]; |
| 77 | 77 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 78 | 78 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); |
| 79 | const ALLOWED_TARGETS: AllowedTargets = | |
| 79 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 80 | 80 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 81 | 81 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 82 | 82 | |
| ... | ... | @@ -92,7 +92,7 @@ pub(crate) struct MoveSizeLimitParser; |
| 92 | 92 | impl SingleAttributeParser for MoveSizeLimitParser { |
| 93 | 93 | const PATH: &[Symbol] = &[sym::move_size_limit]; |
| 94 | 94 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); |
| 95 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 95 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 96 | 96 | const STABILITY: AttributeStability = unstable!(large_assignments); |
| 97 | 97 | |
| 98 | 98 | fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> { |
| ... | ... | @@ -108,7 +108,7 @@ impl SingleAttributeParser for TypeLengthLimitParser { |
| 108 | 108 | const PATH: &[Symbol] = &[sym::type_length_limit]; |
| 109 | 109 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 110 | 110 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); |
| 111 | const ALLOWED_TARGETS: AllowedTargets = | |
| 111 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 112 | 112 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 113 | 113 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 114 | 114 | |
| ... | ... | @@ -124,7 +124,7 @@ pub(crate) struct PatternComplexityLimitParser; |
| 124 | 124 | impl SingleAttributeParser for PatternComplexityLimitParser { |
| 125 | 125 | const PATH: &[Symbol] = &[sym::pattern_complexity_limit]; |
| 126 | 126 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); |
| 127 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 127 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 128 | 128 | const STABILITY: AttributeStability = unstable!( |
| 129 | 129 | rustc_attrs, |
| 130 | 130 | "the `#[pattern_complexity_limit]` attribute is used for rustc unit tests" |
| ... | ... | @@ -141,7 +141,7 @@ pub(crate) struct NoCoreParser; |
| 141 | 141 | |
| 142 | 142 | impl NoArgsAttributeParser for NoCoreParser { |
| 143 | 143 | const PATH: &[Symbol] = &[sym::no_core]; |
| 144 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 144 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 145 | 145 | const STABILITY: AttributeStability = unstable!(no_core); |
| 146 | 146 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoCore; |
| 147 | 147 | } |
| ... | ... | @@ -151,7 +151,7 @@ pub(crate) struct NoStdParser; |
| 151 | 151 | impl NoArgsAttributeParser for NoStdParser { |
| 152 | 152 | const PATH: &[Symbol] = &[sym::no_std]; |
| 153 | 153 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 154 | const ALLOWED_TARGETS: AllowedTargets = | |
| 154 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 155 | 155 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 156 | 156 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 157 | 157 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoStd; |
| ... | ... | @@ -162,7 +162,7 @@ pub(crate) struct NoMainParser; |
| 162 | 162 | impl NoArgsAttributeParser for NoMainParser { |
| 163 | 163 | const PATH: &[Symbol] = &[sym::no_main]; |
| 164 | 164 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 165 | const ALLOWED_TARGETS: AllowedTargets = | |
| 165 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 166 | 166 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 167 | 167 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 168 | 168 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain; |
| ... | ... | @@ -172,7 +172,7 @@ pub(crate) struct RustcCoherenceIsCoreParser; |
| 172 | 172 | |
| 173 | 173 | impl NoArgsAttributeParser for RustcCoherenceIsCoreParser { |
| 174 | 174 | const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; |
| 175 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 175 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 176 | 176 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 177 | 177 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoherenceIsCore; |
| 178 | 178 | } |
| ... | ... | @@ -182,7 +182,7 @@ pub(crate) struct WindowsSubsystemParser; |
| 182 | 182 | impl SingleAttributeParser for WindowsSubsystemParser { |
| 183 | 183 | const PATH: &[Symbol] = &[sym::windows_subsystem]; |
| 184 | 184 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 185 | const ALLOWED_TARGETS: AllowedTargets = | |
| 185 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 186 | 186 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 187 | 187 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"); |
| 188 | 188 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| ... | ... | @@ -210,7 +210,7 @@ pub(crate) struct PanicRuntimeParser; |
| 210 | 210 | |
| 211 | 211 | impl NoArgsAttributeParser for PanicRuntimeParser { |
| 212 | 212 | const PATH: &[Symbol] = &[sym::panic_runtime]; |
| 213 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 213 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 214 | 214 | const STABILITY: AttributeStability = unstable!(panic_runtime); |
| 215 | 215 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PanicRuntime; |
| 216 | 216 | } |
| ... | ... | @@ -219,7 +219,7 @@ pub(crate) struct NeedsPanicRuntimeParser; |
| 219 | 219 | |
| 220 | 220 | impl NoArgsAttributeParser for NeedsPanicRuntimeParser { |
| 221 | 221 | const PATH: &[Symbol] = &[sym::needs_panic_runtime]; |
| 222 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 222 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 223 | 223 | const STABILITY: AttributeStability = unstable!(needs_panic_runtime); |
| 224 | 224 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsPanicRuntime; |
| 225 | 225 | } |
| ... | ... | @@ -228,7 +228,7 @@ pub(crate) struct ProfilerRuntimeParser; |
| 228 | 228 | |
| 229 | 229 | impl NoArgsAttributeParser for ProfilerRuntimeParser { |
| 230 | 230 | const PATH: &[Symbol] = &[sym::profiler_runtime]; |
| 231 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 231 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 232 | 232 | const STABILITY: AttributeStability = unstable!(profiler_runtime); |
| 233 | 233 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProfilerRuntime; |
| 234 | 234 | } |
| ... | ... | @@ -238,7 +238,7 @@ pub(crate) struct NoBuiltinsParser; |
| 238 | 238 | impl NoArgsAttributeParser for NoBuiltinsParser { |
| 239 | 239 | const PATH: &[Symbol] = &[sym::no_builtins]; |
| 240 | 240 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 241 | const ALLOWED_TARGETS: AllowedTargets = | |
| 241 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 242 | 242 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 243 | 243 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 244 | 244 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoBuiltins; |
| ... | ... | @@ -248,7 +248,7 @@ pub(crate) struct RustcPreserveUbChecksParser; |
| 248 | 248 | |
| 249 | 249 | impl NoArgsAttributeParser for RustcPreserveUbChecksParser { |
| 250 | 250 | const PATH: &[Symbol] = &[sym::rustc_preserve_ub_checks]; |
| 251 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 251 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 252 | 252 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 253 | 253 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPreserveUbChecks; |
| 254 | 254 | } |
| ... | ... | @@ -257,7 +257,7 @@ pub(crate) struct RustcNoImplicitBoundsParser; |
| 257 | 257 | |
| 258 | 258 | impl NoArgsAttributeParser for RustcNoImplicitBoundsParser { |
| 259 | 259 | const PATH: &[Symbol] = &[sym::rustc_no_implicit_bounds]; |
| 260 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 260 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 261 | 261 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 262 | 262 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitBounds; |
| 263 | 263 | } |
| ... | ... | @@ -266,7 +266,7 @@ pub(crate) struct DefaultLibAllocatorParser; |
| 266 | 266 | |
| 267 | 267 | impl NoArgsAttributeParser for DefaultLibAllocatorParser { |
| 268 | 268 | const PATH: &[Symbol] = &[sym::default_lib_allocator]; |
| 269 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 269 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 270 | 270 | const STABILITY: AttributeStability = unstable!(allocator_internals); |
| 271 | 271 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::DefaultLibAllocator; |
| 272 | 272 | } |
| ... | ... | @@ -277,7 +277,7 @@ impl CombineAttributeParser for FeatureParser { |
| 277 | 277 | const PATH: &[Symbol] = &[sym::feature]; |
| 278 | 278 | type Item = Ident; |
| 279 | 279 | const CONVERT: ConvertFn<Self::Item> = AttributeKind::Feature; |
| 280 | const ALLOWED_TARGETS: AllowedTargets = | |
| 280 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 281 | 281 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]); |
| 282 | 282 | const TEMPLATE: AttributeTemplate = template!(List: &["feature1, feature2, ..."]); |
| 283 | 283 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| ... | ... | @@ -323,7 +323,7 @@ impl CombineAttributeParser for RegisterToolParser { |
| 323 | 323 | const PATH: &[Symbol] = &[sym::register_tool]; |
| 324 | 324 | type Item = Ident; |
| 325 | 325 | const CONVERT: ConvertFn<Self::Item> = |tools, _span| AttributeKind::RegisterTool(tools); |
| 326 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 326 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 327 | 327 | const TEMPLATE: AttributeTemplate = template!(List: &["tool1, tool2, ..."]); |
| 328 | 328 | const STABILITY: AttributeStability = unstable!(register_tool); |
| 329 | 329 |
compiler/rustc_attr_parsing/src/attributes/debugger.rs+1-1| ... | ... | @@ -7,7 +7,7 @@ pub(crate) struct DebuggerVisualizerParser; |
| 7 | 7 | |
| 8 | 8 | impl CombineAttributeParser for DebuggerVisualizerParser { |
| 9 | 9 | const PATH: &[Symbol] = &[sym::debugger_visualizer]; |
| 10 | const ALLOWED_TARGETS: AllowedTargets = | |
| 10 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 11 | 11 | AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]); |
| 12 | 12 | const TEMPLATE: AttributeTemplate = template!( |
| 13 | 13 | List: &[r#"natvis_file = "...", gdb_script_file = "...""#], |
compiler/rustc_attr_parsing/src/attributes/deprecation.rs+1-1| ... | ... | @@ -32,7 +32,7 @@ fn get( |
| 32 | 32 | pub(crate) struct DeprecatedParser; |
| 33 | 33 | impl SingleAttributeParser for DeprecatedParser { |
| 34 | 34 | const PATH: &[Symbol] = &[sym::deprecated]; |
| 35 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 35 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 36 | 36 | Allow(Target::Fn), |
| 37 | 37 | Allow(Target::Mod), |
| 38 | 38 | Allow(Target::Struct), |
compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs+1-1| ... | ... | @@ -16,7 +16,7 @@ impl SingleAttributeParser for DoNotRecommendParser { |
| 16 | 16 | const PATH: &[Symbol] = &[sym::diagnostic, sym::do_not_recommend]; |
| 17 | 17 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 18 | 18 | // "Allowed" on any target, noop on all but trait impls |
| 19 | const ALLOWED_TARGETS: AllowedTargets = | |
| 19 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 20 | 20 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Impl { of_trait: true })]); |
| 21 | 21 | const TEMPLATE: AttributeTemplate = template!(Word /*doesn't matter */); |
| 22 | 22 | const STABILITY: AttributeStability = AttributeStability::Stable; |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs+1-1| ... | ... | @@ -37,7 +37,7 @@ impl AttributeParser for OnConstParser { |
| 37 | 37 | |
| 38 | 38 | // "Allowed" on all targets; noop on anything but non-const trait impls; |
| 39 | 39 | // this linted on in parser. |
| 40 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 40 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 41 | 41 | // FIXME(mejrs) no constness field on `Target`, |
| 42 | 42 | // so non-constness is still checked in check_attr.rs |
| 43 | 43 | Allow(Target::Impl { of_trait: true }), |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs+1-1| ... | ... | @@ -43,7 +43,7 @@ impl AttributeParser for OnMoveParser { |
| 43 | 43 | }, |
| 44 | 44 | )]; |
| 45 | 45 | |
| 46 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 46 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 47 | 47 | Allow(Target::Enum), |
| 48 | 48 | Allow(Target::Struct), |
| 49 | 49 | Allow(Target::Union), |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_type_error.rs+1-1| ... | ... | @@ -42,7 +42,7 @@ impl AttributeParser for OnTypeErrorParser { |
| 42 | 42 | }, |
| 43 | 43 | )]; |
| 44 | 44 | |
| 45 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 45 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 46 | 46 | Allow(Target::Enum), |
| 47 | 47 | Allow(Target::Struct), |
| 48 | 48 | Allow(Target::Union), |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs+1-1| ... | ... | @@ -45,7 +45,7 @@ impl AttributeParser for OnUnimplementedParser { |
| 45 | 45 | }, |
| 46 | 46 | ), |
| 47 | 47 | ]; |
| 48 | const ALLOWED_TARGETS: AllowedTargets = | |
| 48 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 49 | 49 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Trait)]); |
| 50 | 50 | |
| 51 | 51 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs+1-1| ... | ... | @@ -40,7 +40,7 @@ impl AttributeParser for OnUnknownParser { |
| 40 | 40 | }, |
| 41 | 41 | )]; |
| 42 | 42 | // "Allowed" for all targets, but noop for all but use statements. |
| 43 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 43 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 44 | 44 | Allow(Target::Use), |
| 45 | 45 | Allow(Target::Mod), |
| 46 | 46 | Allow(Target::Crate), |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unmatched_args.rs+1-1| ... | ... | @@ -33,7 +33,7 @@ impl AttributeParser for OnUnmatchedArgsParser { |
| 33 | 33 | }, |
| 34 | 34 | )]; |
| 35 | 35 | |
| 36 | const ALLOWED_TARGETS: AllowedTargets = | |
| 36 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 37 | 37 | AllowedTargets::AllowListWarnRest(&[Allow(Target::MacroDef)]); |
| 38 | 38 | |
| 39 | 39 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
compiler/rustc_attr_parsing/src/attributes/doc.rs+2-2| ... | ... | @@ -706,8 +706,8 @@ impl AttributeParser for DocParser { |
| 706 | 706 | }, |
| 707 | 707 | )]; |
| 708 | 708 | // FIXME: Currently emitted from 2 different places, generating duplicated warnings. |
| 709 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); | |
| 710 | // const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 709 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(ALL_TARGETS); | |
| 710 | // const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 711 | 711 | // Allow(Target::ExternCrate), |
| 712 | 712 | // Allow(Target::Use), |
| 713 | 713 | // Allow(Target::Static), |
compiler/rustc_attr_parsing/src/attributes/dummy.rs+1-1| ... | ... | @@ -12,7 +12,7 @@ pub(crate) struct RustcDummyParser; |
| 12 | 12 | impl SingleAttributeParser for RustcDummyParser { |
| 13 | 13 | const PATH: &[Symbol] = &[sym::rustc_dummy]; |
| 14 | 14 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore; |
| 15 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::ManuallyChecked; | |
| 15 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked; | |
| 16 | 16 | const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really |
| 17 | 17 | const STABILITY: AttributeStability = |
| 18 | 18 | unstable!(rustc_attrs, "the `#[rustc_dummy]` attribute is used for rustc unit tests"); |
compiler/rustc_attr_parsing/src/attributes/inline.rs+2-2| ... | ... | @@ -13,7 +13,7 @@ pub(crate) struct InlineParser; |
| 13 | 13 | impl SingleAttributeParser for InlineParser { |
| 14 | 14 | const PATH: &[Symbol] = &[sym::inline]; |
| 15 | 15 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 16 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 16 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 17 | 17 | Allow(Target::Fn), |
| 18 | 18 | Allow(Target::Method(MethodKind::Inherent)), |
| 19 | 19 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -66,7 +66,7 @@ pub(crate) struct RustcForceInlineParser; |
| 66 | 66 | |
| 67 | 67 | impl SingleAttributeParser for RustcForceInlineParser { |
| 68 | 68 | const PATH: &[Symbol] = &[sym::rustc_force_inline]; |
| 69 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 69 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 70 | 70 | Allow(Target::Fn), |
| 71 | 71 | Allow(Target::Method(MethodKind::Inherent)), |
| 72 | 72 | ]); |
compiler/rustc_attr_parsing/src/attributes/instruction_set.rs+1-1| ... | ... | @@ -8,7 +8,7 @@ pub(crate) struct InstructionSetParser; |
| 8 | 8 | |
| 9 | 9 | impl SingleAttributeParser for InstructionSetParser { |
| 10 | 10 | const PATH: &[Symbol] = &[sym::instruction_set]; |
| 11 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 11 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 12 | 12 | Allow(Target::Fn), |
| 13 | 13 | Allow(Target::Closure), |
| 14 | 14 | Allow(Target::Method(MethodKind::Inherent)), |
compiler/rustc_attr_parsing/src/attributes/link_attrs.rs+13-11| ... | ... | @@ -26,7 +26,7 @@ pub(crate) struct LinkNameParser; |
| 26 | 26 | impl SingleAttributeParser for LinkNameParser { |
| 27 | 27 | const PATH: &[Symbol] = &[sym::link_name]; |
| 28 | 28 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 29 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 29 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 30 | 30 | Allow(Target::ForeignFn), |
| 31 | 31 | Allow(Target::ForeignStatic), |
| 32 | 32 | ]); |
| ... | ... | @@ -70,7 +70,7 @@ impl CombineAttributeParser for LinkParser { |
| 70 | 70 | r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#, |
| 71 | 71 | r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#, |
| 72 | 72 | ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute"); |
| 73 | const ALLOWED_TARGETS: AllowedTargets = | |
| 73 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 74 | 74 | AllowedTargets::AllowListWarnRest(&[Allow(Target::ForeignMod)]); |
| 75 | 75 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 76 | 76 | |
| ... | ... | @@ -494,7 +494,7 @@ impl SingleAttributeParser for LinkSectionParser { |
| 494 | 494 | unsafe_since: Some(Edition2024), |
| 495 | 495 | }; |
| 496 | 496 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 497 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 497 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 498 | 498 | Allow(Target::Static), |
| 499 | 499 | Allow(Target::Fn), |
| 500 | 500 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -535,7 +535,7 @@ impl SingleAttributeParser for LinkSectionParser { |
| 535 | 535 | pub(crate) struct ExportStableParser; |
| 536 | 536 | impl NoArgsAttributeParser for ExportStableParser { |
| 537 | 537 | const PATH: &[Symbol] = &[sym::export_stable]; |
| 538 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 538 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 539 | 539 | Allow(Target::Fn), |
| 540 | 540 | Allow(Target::Method(MethodKind::Inherent)), |
| 541 | 541 | Allow(Target::Struct), |
| ... | ... | @@ -558,7 +558,8 @@ impl NoArgsAttributeParser for FfiConstParser { |
| 558 | 558 | note: "`#[ffi_const]` functions shall have no effects except for its return value, which can only depend on the values of the function parameters, and is not affected by changes to the observable state of the program.", |
| 559 | 559 | unsafe_since: None, |
| 560 | 560 | }; |
| 561 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); | |
| 561 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 562 | AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); | |
| 562 | 563 | const STABILITY: AttributeStability = unstable!(ffi_const); |
| 563 | 564 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::FfiConst; |
| 564 | 565 | } |
| ... | ... | @@ -570,7 +571,8 @@ impl NoArgsAttributeParser for FfiPureParser { |
| 570 | 571 | note: "`#[ffi_pure]` functions shall have no effects except for its return value, which shall not change across two consecutive function calls with the same parameters.", |
| 571 | 572 | unsafe_since: None, |
| 572 | 573 | }; |
| 573 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); | |
| 574 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 575 | AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); | |
| 574 | 576 | const STABILITY: AttributeStability = unstable!(ffi_pure); |
| 575 | 577 | const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure; |
| 576 | 578 | } |
| ... | ... | @@ -578,7 +580,7 @@ impl NoArgsAttributeParser for FfiPureParser { |
| 578 | 580 | pub(crate) struct RustcStdInternalSymbolParser; |
| 579 | 581 | impl NoArgsAttributeParser for RustcStdInternalSymbolParser { |
| 580 | 582 | const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol]; |
| 581 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 583 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 582 | 584 | Allow(Target::Fn), |
| 583 | 585 | Allow(Target::ForeignFn), |
| 584 | 586 | Allow(Target::Static), |
| ... | ... | @@ -592,7 +594,7 @@ pub(crate) struct LinkOrdinalParser; |
| 592 | 594 | |
| 593 | 595 | impl SingleAttributeParser for LinkOrdinalParser { |
| 594 | 596 | const PATH: &[Symbol] = &[sym::link_ordinal]; |
| 595 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 597 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 596 | 598 | Allow(Target::ForeignFn), |
| 597 | 599 | Allow(Target::ForeignStatic), |
| 598 | 600 | Warn(Target::MacroCall), |
| ... | ... | @@ -632,7 +634,7 @@ pub(crate) struct LinkageParser; |
| 632 | 634 | |
| 633 | 635 | impl SingleAttributeParser for LinkageParser { |
| 634 | 636 | const PATH: &[Symbol] = &[sym::linkage]; |
| 635 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 637 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 636 | 638 | Allow(Target::Fn), |
| 637 | 639 | Allow(Target::Method(MethodKind::Inherent)), |
| 638 | 640 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -708,7 +710,7 @@ pub(crate) struct NeedsAllocatorParser; |
| 708 | 710 | |
| 709 | 711 | impl NoArgsAttributeParser for NeedsAllocatorParser { |
| 710 | 712 | const PATH: &[Symbol] = &[sym::needs_allocator]; |
| 711 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 713 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 712 | 714 | const STABILITY: AttributeStability = unstable!(allocator_internals); |
| 713 | 715 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsAllocator; |
| 714 | 716 | } |
| ... | ... | @@ -717,7 +719,7 @@ pub(crate) struct CompilerBuiltinsParser; |
| 717 | 719 | |
| 718 | 720 | impl NoArgsAttributeParser for CompilerBuiltinsParser { |
| 719 | 721 | const PATH: &[Symbol] = &[sym::compiler_builtins]; |
| 720 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 722 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 721 | 723 | const STABILITY: AttributeStability = unstable!(compiler_builtins); |
| 722 | 724 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CompilerBuiltins; |
| 723 | 725 | } |
compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs+5-5| ... | ... | @@ -5,7 +5,7 @@ use super::prelude::*; |
| 5 | 5 | pub(crate) struct RustcAsPtrParser; |
| 6 | 6 | impl NoArgsAttributeParser for RustcAsPtrParser { |
| 7 | 7 | const PATH: &[Symbol] = &[sym::rustc_as_ptr]; |
| 8 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 8 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 9 | 9 | Allow(Target::Fn), |
| 10 | 10 | Allow(Target::Method(MethodKind::Inherent)), |
| 11 | 11 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -19,7 +19,7 @@ impl NoArgsAttributeParser for RustcAsPtrParser { |
| 19 | 19 | pub(crate) struct RustcPubTransparentParser; |
| 20 | 20 | impl NoArgsAttributeParser for RustcPubTransparentParser { |
| 21 | 21 | const PATH: &[Symbol] = &[sym::rustc_pub_transparent]; |
| 22 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 22 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 23 | 23 | Allow(Target::Struct), |
| 24 | 24 | Allow(Target::Enum), |
| 25 | 25 | Allow(Target::Union), |
| ... | ... | @@ -31,7 +31,7 @@ impl NoArgsAttributeParser for RustcPubTransparentParser { |
| 31 | 31 | pub(crate) struct RustcPassByValueParser; |
| 32 | 32 | impl NoArgsAttributeParser for RustcPassByValueParser { |
| 33 | 33 | const PATH: &[Symbol] = &[sym::rustc_pass_by_value]; |
| 34 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 34 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 35 | 35 | Allow(Target::Struct), |
| 36 | 36 | Allow(Target::Enum), |
| 37 | 37 | Allow(Target::TyAlias), |
| ... | ... | @@ -43,7 +43,7 @@ impl NoArgsAttributeParser for RustcPassByValueParser { |
| 43 | 43 | pub(crate) struct RustcShouldNotBeCalledOnConstItemsParser; |
| 44 | 44 | impl NoArgsAttributeParser for RustcShouldNotBeCalledOnConstItemsParser { |
| 45 | 45 | const PATH: &[Symbol] = &[sym::rustc_should_not_be_called_on_const_items]; |
| 46 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 46 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 47 | 47 | Allow(Target::Method(MethodKind::Inherent)), |
| 48 | 48 | Allow(Target::Method(MethodKind::TraitImpl)), |
| 49 | 49 | ]); |
| ... | ... | @@ -55,7 +55,7 @@ pub(crate) struct AutomaticallyDerivedParser; |
| 55 | 55 | impl NoArgsAttributeParser for AutomaticallyDerivedParser { |
| 56 | 56 | const PATH: &[Symbol] = &[sym::automatically_derived]; |
| 57 | 57 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 58 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 58 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 59 | 59 | Allow(Target::Impl { of_trait: true }), |
| 60 | 60 | Error(Target::Crate), |
| 61 | 61 | Error(Target::WherePredicate), |
compiler/rustc_attr_parsing/src/attributes/loop_match.rs+2-2| ... | ... | @@ -5,7 +5,7 @@ use super::prelude::*; |
| 5 | 5 | pub(crate) struct LoopMatchParser; |
| 6 | 6 | impl NoArgsAttributeParser for LoopMatchParser { |
| 7 | 7 | const PATH: &[Symbol] = &[sym::loop_match]; |
| 8 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Loop)]); | |
| 8 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Loop)]); | |
| 9 | 9 | const STABILITY: AttributeStability = unstable!(loop_match); |
| 10 | 10 | const CREATE: fn(Span) -> AttributeKind = AttributeKind::LoopMatch; |
| 11 | 11 | } |
| ... | ... | @@ -13,7 +13,7 @@ impl NoArgsAttributeParser for LoopMatchParser { |
| 13 | 13 | pub(crate) struct ConstContinueParser; |
| 14 | 14 | impl NoArgsAttributeParser for ConstContinueParser { |
| 15 | 15 | const PATH: &[Symbol] = &[sym::const_continue]; |
| 16 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Break)]); | |
| 16 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Break)]); | |
| 17 | 17 | const STABILITY: AttributeStability = unstable!(loop_match); |
| 18 | 18 | const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstContinue; |
| 19 | 19 | } |
compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs+8-7| ... | ... | @@ -8,7 +8,7 @@ pub(crate) struct MacroEscapeParser; |
| 8 | 8 | impl NoArgsAttributeParser for MacroEscapeParser { |
| 9 | 9 | const PATH: &[Symbol] = &[sym::macro_escape]; |
| 10 | 10 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 11 | const ALLOWED_TARGETS: AllowedTargets = MACRO_USE_ALLOWED_TARGETS; | |
| 11 | const ALLOWED_TARGETS: AllowedTargets<'_> = MACRO_USE_ALLOWED_TARGETS; | |
| 12 | 12 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 13 | 13 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::MacroEscape; |
| 14 | 14 | } |
| ... | ... | @@ -32,7 +32,7 @@ const MACRO_USE_TEMPLATE: AttributeTemplate = template!( |
| 32 | 32 | Word, List: &["name1, name2, ..."], |
| 33 | 33 | "https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute" |
| 34 | 34 | ); |
| 35 | const MACRO_USE_ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 35 | const MACRO_USE_ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 36 | 36 | Allow(Target::Mod), |
| 37 | 37 | Allow(Target::ExternCrate), |
| 38 | 38 | Error(Target::WherePredicate), |
| ... | ... | @@ -106,7 +106,7 @@ impl AttributeParser for MacroUseParser { |
| 106 | 106 | } |
| 107 | 107 | }, |
| 108 | 108 | )]; |
| 109 | const ALLOWED_TARGETS: AllowedTargets = MACRO_USE_ALLOWED_TARGETS; | |
| 109 | const ALLOWED_TARGETS: AllowedTargets<'_> = MACRO_USE_ALLOWED_TARGETS; | |
| 110 | 110 | |
| 111 | 111 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
| 112 | 112 | Some(AttributeKind::MacroUse { span: self.first_span?, arguments: self.state }) |
| ... | ... | @@ -118,7 +118,7 @@ pub(crate) struct AllowInternalUnsafeParser; |
| 118 | 118 | impl NoArgsAttributeParser for AllowInternalUnsafeParser { |
| 119 | 119 | const PATH: &[Symbol] = &[sym::allow_internal_unsafe]; |
| 120 | 120 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore; |
| 121 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 121 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 122 | 122 | Allow(Target::Fn), |
| 123 | 123 | Allow(Target::MacroDef), |
| 124 | 124 | Warn(Target::Field), |
| ... | ... | @@ -134,7 +134,7 @@ impl SingleAttributeParser for MacroExportParser { |
| 134 | 134 | const PATH: &[Symbol] = &[sym::macro_export]; |
| 135 | 135 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 136 | 136 | const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]); |
| 137 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 137 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 138 | 138 | Allow(Target::MacroDef), |
| 139 | 139 | Error(Target::WherePredicate), |
| 140 | 140 | Error(Target::Crate), |
| ... | ... | @@ -174,7 +174,8 @@ impl SingleAttributeParser for CollapseDebugInfoParser { |
| 174 | 174 | List: &["no", "external", "yes"], |
| 175 | 175 | "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute" |
| 176 | 176 | ); |
| 177 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); | |
| 177 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 178 | AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); | |
| 178 | 179 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 179 | 180 | |
| 180 | 181 | fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> { |
| ... | ... | @@ -204,7 +205,7 @@ pub(crate) struct RustcProcMacroDeclsParser; |
| 204 | 205 | |
| 205 | 206 | impl NoArgsAttributeParser for RustcProcMacroDeclsParser { |
| 206 | 207 | const PATH: &[Symbol] = &[sym::rustc_proc_macro_decls]; |
| 207 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Static)]); | |
| 208 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Static)]); | |
| 208 | 209 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 209 | 210 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcProcMacroDecls; |
| 210 | 211 | } |
compiler/rustc_attr_parsing/src/attributes/mod.rs+7-7| ... | ... | @@ -105,7 +105,7 @@ pub(crate) trait AttributeParser: Default + 'static { |
| 105 | 105 | /// |
| 106 | 106 | /// If an attribute has this symbol, the `accept` function will be called on it. |
| 107 | 107 | const ATTRIBUTES: AcceptMapping<Self>; |
| 108 | const ALLOWED_TARGETS: AllowedTargets; | |
| 108 | const ALLOWED_TARGETS: AllowedTargets<'_>; | |
| 109 | 109 | const SAFETY: AttributeSafety = AttributeSafety::Normal; |
| 110 | 110 | |
| 111 | 111 | /// The parser has gotten a chance to accept the attributes on an item, |
| ... | ... | @@ -140,7 +140,7 @@ pub(crate) trait SingleAttributeParser: 'static { |
| 140 | 140 | const SAFETY: AttributeSafety = AttributeSafety::Normal; |
| 141 | 141 | const STABILITY: AttributeStability; |
| 142 | 142 | |
| 143 | const ALLOWED_TARGETS: AllowedTargets; | |
| 143 | const ALLOWED_TARGETS: AllowedTargets<'_>; | |
| 144 | 144 | |
| 145 | 145 | /// The template this attribute parser should implement. Used for diagnostics. |
| 146 | 146 | const TEMPLATE: AttributeTemplate; |
| ... | ... | @@ -174,7 +174,7 @@ impl<T: SingleAttributeParser> AttributeParser for Single<T> { |
| 174 | 174 | } |
| 175 | 175 | }, |
| 176 | 176 | )]; |
| 177 | const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; | |
| 177 | const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS; | |
| 178 | 178 | const SAFETY: AttributeSafety = T::SAFETY; |
| 179 | 179 | |
| 180 | 180 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
| ... | ... | @@ -252,7 +252,7 @@ pub enum AttributeSafety { |
| 252 | 252 | pub(crate) trait NoArgsAttributeParser: 'static { |
| 253 | 253 | const PATH: &[Symbol]; |
| 254 | 254 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; |
| 255 | const ALLOWED_TARGETS: AllowedTargets; | |
| 255 | const ALLOWED_TARGETS: AllowedTargets<'_>; | |
| 256 | 256 | const SAFETY: AttributeSafety = AttributeSafety::Normal; |
| 257 | 257 | const STABILITY: AttributeStability; |
| 258 | 258 | |
| ... | ... | @@ -273,7 +273,7 @@ impl<T: NoArgsAttributeParser> SingleAttributeParser for WithoutArgs<T> { |
| 273 | 273 | const ON_DUPLICATE: OnDuplicate = T::ON_DUPLICATE; |
| 274 | 274 | const SAFETY: AttributeSafety = T::SAFETY; |
| 275 | 275 | const STABILITY: AttributeStability = T::STABILITY; |
| 276 | const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; | |
| 276 | const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS; | |
| 277 | 277 | const TEMPLATE: AttributeTemplate = template!(Word); |
| 278 | 278 | |
| 279 | 279 | fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> { |
| ... | ... | @@ -303,7 +303,7 @@ pub(crate) trait CombineAttributeParser: 'static { |
| 303 | 303 | const SAFETY: AttributeSafety = AttributeSafety::Normal; |
| 304 | 304 | const STABILITY: AttributeStability; |
| 305 | 305 | |
| 306 | const ALLOWED_TARGETS: AllowedTargets; | |
| 306 | const ALLOWED_TARGETS: AllowedTargets<'_>; | |
| 307 | 307 | |
| 308 | 308 | /// The template this attribute parser should implement. Used for diagnostics. |
| 309 | 309 | const TEMPLATE: AttributeTemplate; |
| ... | ... | @@ -342,7 +342,7 @@ impl<T: CombineAttributeParser> AttributeParser for Combine<T> { |
| 342 | 342 | group.first_span.get_or_insert(cx.attr_span); |
| 343 | 343 | group.items.extend(T::extend(cx, args)) |
| 344 | 344 | })]; |
| 345 | const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; | |
| 345 | const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS; | |
| 346 | 346 | const SAFETY: AttributeSafety = T::SAFETY; |
| 347 | 347 | |
| 348 | 348 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs+1-1| ... | ... | @@ -6,7 +6,7 @@ pub(crate) struct MustNotSuspendParser; |
| 6 | 6 | |
| 7 | 7 | impl SingleAttributeParser for MustNotSuspendParser { |
| 8 | 8 | const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend]; |
| 9 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 9 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 10 | 10 | Allow(Target::Struct), |
| 11 | 11 | Allow(Target::Enum), |
| 12 | 12 | Allow(Target::Union), |
compiler/rustc_attr_parsing/src/attributes/must_use.rs+1-1| ... | ... | @@ -7,7 +7,7 @@ pub(crate) struct MustUseParser; |
| 7 | 7 | impl SingleAttributeParser for MustUseParser { |
| 8 | 8 | const PATH: &[Symbol] = &[sym::must_use]; |
| 9 | 9 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 10 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ | |
| 10 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ | |
| 11 | 11 | Allow(Target::Fn), |
| 12 | 12 | Allow(Target::Enum), |
| 13 | 13 | Allow(Target::Struct), |
compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs+1-1| ... | ... | @@ -7,7 +7,7 @@ pub(crate) struct NoImplicitPreludeParser; |
| 7 | 7 | impl NoArgsAttributeParser for NoImplicitPreludeParser { |
| 8 | 8 | const PATH: &[rustc_span::Symbol] = &[sym::no_implicit_prelude]; |
| 9 | 9 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 10 | const ALLOWED_TARGETS: AllowedTargets = | |
| 10 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 11 | 11 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Mod), Allow(Target::Crate)]); |
| 12 | 12 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 13 | 13 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoImplicitPrelude; |
compiler/rustc_attr_parsing/src/attributes/no_link.rs+1-1| ... | ... | @@ -6,7 +6,7 @@ pub(crate) struct NoLinkParser; |
| 6 | 6 | impl NoArgsAttributeParser for NoLinkParser { |
| 7 | 7 | const PATH: &[Symbol] = &[sym::no_link]; |
| 8 | 8 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 9 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 9 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 10 | 10 | Allow(Target::ExternCrate), |
| 11 | 11 | Warn(Target::Field), |
| 12 | 12 | Warn(Target::Arm), |
compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs+1-1| ... | ... | @@ -12,7 +12,7 @@ pub(crate) struct NonExhaustiveParser; |
| 12 | 12 | impl NoArgsAttributeParser for NonExhaustiveParser { |
| 13 | 13 | const PATH: &[Symbol] = &[sym::non_exhaustive]; |
| 14 | 14 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 15 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 15 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 16 | 16 | Allow(Target::Enum), |
| 17 | 17 | Allow(Target::Struct), |
| 18 | 18 | Allow(Target::Variant), |
compiler/rustc_attr_parsing/src/attributes/path.rs+1-1| ... | ... | @@ -7,7 +7,7 @@ pub(crate) struct PathParser; |
| 7 | 7 | impl SingleAttributeParser for PathParser { |
| 8 | 8 | const PATH: &[Symbol] = &[sym::path]; |
| 9 | 9 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 10 | const ALLOWED_TARGETS: AllowedTargets = | |
| 10 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 11 | 11 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Mod), Error(Target::Crate)]); |
| 12 | 12 | const TEMPLATE: AttributeTemplate = template!( |
| 13 | 13 | NameValueStr: "file", |
compiler/rustc_attr_parsing/src/attributes/pin_v2.rs+1-1| ... | ... | @@ -12,7 +12,7 @@ pub(crate) struct PinV2Parser; |
| 12 | 12 | |
| 13 | 13 | impl NoArgsAttributeParser for PinV2Parser { |
| 14 | 14 | const PATH: &[Symbol] = &[sym::pin_v2]; |
| 15 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 15 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 16 | 16 | Allow(Target::Enum), |
| 17 | 17 | Allow(Target::Struct), |
| 18 | 18 | Allow(Target::Union), |
compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs+6-5| ... | ... | @@ -3,13 +3,13 @@ use rustc_session::lint::builtin::AMBIGUOUS_DERIVE_HELPERS; |
| 3 | 3 | |
| 4 | 4 | use super::prelude::*; |
| 5 | 5 | |
| 6 | const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets = | |
| 6 | const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 7 | 7 | AllowedTargets::AllowList(&[Allow(Target::Fn), Warn(Target::Crate), Warn(Target::MacroCall)]); |
| 8 | 8 | |
| 9 | 9 | pub(crate) struct ProcMacroParser; |
| 10 | 10 | impl NoArgsAttributeParser for ProcMacroParser { |
| 11 | 11 | const PATH: &[Symbol] = &[sym::proc_macro]; |
| 12 | const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; | |
| 12 | const ALLOWED_TARGETS: AllowedTargets<'_> = PROC_MACRO_ALLOWED_TARGETS; | |
| 13 | 13 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 14 | 14 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProcMacro; |
| 15 | 15 | } |
| ... | ... | @@ -17,7 +17,7 @@ impl NoArgsAttributeParser for ProcMacroParser { |
| 17 | 17 | pub(crate) struct ProcMacroAttributeParser; |
| 18 | 18 | impl NoArgsAttributeParser for ProcMacroAttributeParser { |
| 19 | 19 | const PATH: &[Symbol] = &[sym::proc_macro_attribute]; |
| 20 | const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; | |
| 20 | const ALLOWED_TARGETS: AllowedTargets<'_> = PROC_MACRO_ALLOWED_TARGETS; | |
| 21 | 21 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 22 | 22 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProcMacroAttribute; |
| 23 | 23 | } |
| ... | ... | @@ -25,7 +25,7 @@ impl NoArgsAttributeParser for ProcMacroAttributeParser { |
| 25 | 25 | pub(crate) struct ProcMacroDeriveParser; |
| 26 | 26 | impl SingleAttributeParser for ProcMacroDeriveParser { |
| 27 | 27 | const PATH: &[Symbol] = &[sym::proc_macro_derive]; |
| 28 | const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; | |
| 28 | const ALLOWED_TARGETS: AllowedTargets<'_> = PROC_MACRO_ALLOWED_TARGETS; | |
| 29 | 29 | const TEMPLATE: AttributeTemplate = template!( |
| 30 | 30 | List: &["TraitName", "TraitName, attributes(name1, name2, ...)"], |
| 31 | 31 | "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros" |
| ... | ... | @@ -44,7 +44,8 @@ impl SingleAttributeParser for ProcMacroDeriveParser { |
| 44 | 44 | pub(crate) struct RustcBuiltinMacroParser; |
| 45 | 45 | impl SingleAttributeParser for RustcBuiltinMacroParser { |
| 46 | 46 | const PATH: &[Symbol] = &[sym::rustc_builtin_macro]; |
| 47 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); | |
| 47 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 48 | AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); | |
| 48 | 49 | const TEMPLATE: AttributeTemplate = |
| 49 | 50 | template!(List: &["TraitName", "TraitName, attributes(name1, name2, ...)"]); |
| 50 | 51 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
compiler/rustc_attr_parsing/src/attributes/prototype.rs+1-1| ... | ... | @@ -18,7 +18,7 @@ impl SingleAttributeParser for CustomMirParser { |
| 18 | 18 | const PATH: &[rustc_span::Symbol] = &[sym::custom_mir]; |
| 19 | 19 | const STABILITY: AttributeStability = unstable!(custom_mir); |
| 20 | 20 | |
| 21 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 21 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 22 | 22 | |
| 23 | 23 | const TEMPLATE: AttributeTemplate = template!(List: &[r#"dialect = "...", phase = "...""#]); |
| 24 | 24 |
compiler/rustc_attr_parsing/src/attributes/repr.rs+3-3| ... | ... | @@ -63,7 +63,7 @@ impl CombineAttributeParser for ReprParser { |
| 63 | 63 | reprs |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::ManuallyChecked; | |
| 66 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked; | |
| 67 | 67 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 68 | 68 | } |
| 69 | 69 | |
| ... | ... | @@ -306,7 +306,7 @@ impl RustcAlignParser { |
| 306 | 306 | impl AttributeParser for RustcAlignParser { |
| 307 | 307 | const ATTRIBUTES: AcceptMapping<Self> = |
| 308 | 308 | &[(Self::PATH, Self::TEMPLATE, unstable!(fn_align), Self::parse)]; |
| 309 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 309 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 310 | 310 | Allow(Target::Fn), |
| 311 | 311 | Allow(Target::Method(MethodKind::Inherent)), |
| 312 | 312 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -336,7 +336,7 @@ impl RustcAlignStaticParser { |
| 336 | 336 | impl AttributeParser for RustcAlignStaticParser { |
| 337 | 337 | const ATTRIBUTES: AcceptMapping<Self> = |
| 338 | 338 | &[(Self::PATH, Self::TEMPLATE, unstable!(static_align), Self::parse)]; |
| 339 | const ALLOWED_TARGETS: AllowedTargets = | |
| 339 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 340 | 340 | AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]); |
| 341 | 341 | |
| 342 | 342 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs+5-5| ... | ... | @@ -6,7 +6,7 @@ pub(crate) struct RustcAllocatorParser; |
| 6 | 6 | |
| 7 | 7 | impl NoArgsAttributeParser for RustcAllocatorParser { |
| 8 | 8 | const PATH: &[Symbol] = &[sym::rustc_allocator]; |
| 9 | const ALLOWED_TARGETS: AllowedTargets = | |
| 9 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 10 | 10 | AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); |
| 11 | 11 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 12 | 12 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator; |
| ... | ... | @@ -16,7 +16,7 @@ pub(crate) struct RustcAllocatorZeroedParser; |
| 16 | 16 | |
| 17 | 17 | impl NoArgsAttributeParser for RustcAllocatorZeroedParser { |
| 18 | 18 | const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed]; |
| 19 | const ALLOWED_TARGETS: AllowedTargets = | |
| 19 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 20 | 20 | AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); |
| 21 | 21 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 22 | 22 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocatorZeroed; |
| ... | ... | @@ -26,7 +26,7 @@ pub(crate) struct RustcAllocatorZeroedVariantParser; |
| 26 | 26 | |
| 27 | 27 | impl SingleAttributeParser for RustcAllocatorZeroedVariantParser { |
| 28 | 28 | const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed_variant]; |
| 29 | const ALLOWED_TARGETS: AllowedTargets = | |
| 29 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 30 | 30 | AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); |
| 31 | 31 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function"); |
| 32 | 32 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| ... | ... | @@ -42,7 +42,7 @@ pub(crate) struct RustcDeallocatorParser; |
| 42 | 42 | |
| 43 | 43 | impl NoArgsAttributeParser for RustcDeallocatorParser { |
| 44 | 44 | const PATH: &[Symbol] = &[sym::rustc_deallocator]; |
| 45 | const ALLOWED_TARGETS: AllowedTargets = | |
| 45 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 46 | 46 | AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); |
| 47 | 47 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 48 | 48 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDeallocator; |
| ... | ... | @@ -52,7 +52,7 @@ pub(crate) struct RustcReallocatorParser; |
| 52 | 52 | |
| 53 | 53 | impl NoArgsAttributeParser for RustcReallocatorParser { |
| 54 | 54 | const PATH: &[Symbol] = &[sym::rustc_reallocator]; |
| 55 | const ALLOWED_TARGETS: AllowedTargets = | |
| 55 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 56 | 56 | AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); |
| 57 | 57 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 58 | 58 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcReallocator; |
compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs+15-14| ... | ... | @@ -10,7 +10,7 @@ pub(crate) struct RustcDumpUserArgsParser; |
| 10 | 10 | |
| 11 | 11 | impl NoArgsAttributeParser for RustcDumpUserArgsParser { |
| 12 | 12 | const PATH: &[Symbol] = &[sym::rustc_dump_user_args]; |
| 13 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 13 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 14 | 14 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 15 | 15 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs; |
| 16 | 16 | } |
| ... | ... | @@ -19,7 +19,7 @@ pub(crate) struct RustcDumpDefParentsParser; |
| 19 | 19 | |
| 20 | 20 | impl NoArgsAttributeParser for RustcDumpDefParentsParser { |
| 21 | 21 | const PATH: &[Symbol] = &[sym::rustc_dump_def_parents]; |
| 22 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 22 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 23 | 23 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 24 | 24 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents; |
| 25 | 25 | } |
| ... | ... | @@ -28,7 +28,7 @@ pub(crate) struct RustcDumpDefPathParser; |
| 28 | 28 | |
| 29 | 29 | impl SingleAttributeParser for RustcDumpDefPathParser { |
| 30 | 30 | const PATH: &[Symbol] = &[sym::rustc_dump_def_path]; |
| 31 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 31 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 32 | 32 | Allow(Target::Fn), |
| 33 | 33 | Allow(Target::Method(MethodKind::TraitImpl)), |
| 34 | 34 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -49,7 +49,7 @@ pub(crate) struct RustcDumpGenericsParser; |
| 49 | 49 | |
| 50 | 50 | impl NoArgsAttributeParser for RustcDumpGenericsParser { |
| 51 | 51 | const PATH: &[Symbol] = &[sym::rustc_dump_generics]; |
| 52 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 52 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 53 | 53 | Allow(Target::Struct), |
| 54 | 54 | Allow(Target::Enum), |
| 55 | 55 | Allow(Target::Union), |
| ... | ... | @@ -78,7 +78,7 @@ pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser; |
| 78 | 78 | |
| 79 | 79 | impl NoArgsAttributeParser for RustcDumpHiddenTypeOfOpaquesParser { |
| 80 | 80 | const PATH: &[Symbol] = &[sym::rustc_dump_hidden_type_of_opaques]; |
| 81 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 81 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 82 | 82 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 83 | 83 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques; |
| 84 | 84 | } |
| ... | ... | @@ -87,7 +87,7 @@ pub(crate) struct RustcDumpInferredOutlivesParser; |
| 87 | 87 | |
| 88 | 88 | impl NoArgsAttributeParser for RustcDumpInferredOutlivesParser { |
| 89 | 89 | const PATH: &[Symbol] = &[sym::rustc_dump_inferred_outlives]; |
| 90 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 90 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 91 | 91 | Allow(Target::Struct), |
| 92 | 92 | Allow(Target::Enum), |
| 93 | 93 | Allow(Target::Union), |
| ... | ... | @@ -101,7 +101,8 @@ pub(crate) struct RustcDumpItemBoundsParser; |
| 101 | 101 | |
| 102 | 102 | impl NoArgsAttributeParser for RustcDumpItemBoundsParser { |
| 103 | 103 | const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds]; |
| 104 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]); | |
| 104 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 105 | AllowedTargets::AllowList(&[Allow(Target::AssocTy)]); | |
| 105 | 106 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 106 | 107 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds; |
| 107 | 108 | } |
| ... | ... | @@ -115,7 +116,7 @@ impl CombineAttributeParser for RustcDumpLayoutParser { |
| 115 | 116 | |
| 116 | 117 | const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcDumpLayout(items); |
| 117 | 118 | |
| 118 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 119 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 119 | 120 | Allow(Target::Struct), |
| 120 | 121 | Allow(Target::Enum), |
| 121 | 122 | Allow(Target::Union), |
| ... | ... | @@ -174,7 +175,7 @@ pub(crate) struct RustcDumpObjectLifetimeDefaultsParser; |
| 174 | 175 | |
| 175 | 176 | impl NoArgsAttributeParser for RustcDumpObjectLifetimeDefaultsParser { |
| 176 | 177 | const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults]; |
| 177 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 178 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 178 | 179 | Allow(Target::AssocConst), |
| 179 | 180 | Allow(Target::AssocTy), |
| 180 | 181 | Allow(Target::Const), |
| ... | ... | @@ -201,7 +202,7 @@ pub(crate) struct RustcDumpPredicatesParser; |
| 201 | 202 | |
| 202 | 203 | impl NoArgsAttributeParser for RustcDumpPredicatesParser { |
| 203 | 204 | const PATH: &[Symbol] = &[sym::rustc_dump_predicates]; |
| 204 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 205 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 205 | 206 | Allow(Target::AssocConst), |
| 206 | 207 | Allow(Target::AssocTy), |
| 207 | 208 | Allow(Target::Const), |
| ... | ... | @@ -229,7 +230,7 @@ pub(crate) struct RustcDumpSymbolNameParser; |
| 229 | 230 | |
| 230 | 231 | impl SingleAttributeParser for RustcDumpSymbolNameParser { |
| 231 | 232 | const PATH: &[Symbol] = &[sym::rustc_dump_symbol_name]; |
| 232 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 233 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 233 | 234 | Allow(Target::Fn), |
| 234 | 235 | Allow(Target::Method(MethodKind::TraitImpl)), |
| 235 | 236 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -250,7 +251,7 @@ pub(crate) struct RustcDumpVariancesParser; |
| 250 | 251 | |
| 251 | 252 | impl NoArgsAttributeParser for RustcDumpVariancesParser { |
| 252 | 253 | const PATH: &[Symbol] = &[sym::rustc_dump_variances]; |
| 253 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 254 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 254 | 255 | Allow(Target::Enum), |
| 255 | 256 | Allow(Target::Fn), |
| 256 | 257 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -271,7 +272,7 @@ pub(crate) struct RustcDumpVariancesOfOpaquesParser; |
| 271 | 272 | |
| 272 | 273 | impl NoArgsAttributeParser for RustcDumpVariancesOfOpaquesParser { |
| 273 | 274 | const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques]; |
| 274 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 275 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 275 | 276 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 276 | 277 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques; |
| 277 | 278 | } |
| ... | ... | @@ -280,7 +281,7 @@ pub(crate) struct RustcDumpVtableParser; |
| 280 | 281 | |
| 281 | 282 | impl NoArgsAttributeParser for RustcDumpVtableParser { |
| 282 | 283 | const PATH: &[Symbol] = &[sym::rustc_dump_vtable]; |
| 283 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 284 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 284 | 285 | Allow(Target::Impl { of_trait: true }), |
| 285 | 286 | Allow(Target::TyAlias), |
| 286 | 287 | ]); |
compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs+63-43| ... | ... | @@ -12,6 +12,7 @@ use rustc_span::Symbol; |
| 12 | 12 | use super::prelude::*; |
| 13 | 13 | use super::util::parse_single_integer; |
| 14 | 14 | use crate::diagnostics; |
| 15 | use crate::diagnostics::UnknownExternLangItem; | |
| 15 | 16 | use crate::session_diagnostics::{ |
| 16 | 17 | AttributeRequiresOpt, CguFieldsMissing, RustcScalableVectorCountOutOfRange, UnknownLangItem, |
| 17 | 18 | }; |
| ... | ... | @@ -20,7 +21,7 @@ pub(crate) struct RustcMainParser; |
| 20 | 21 | |
| 21 | 22 | impl NoArgsAttributeParser for RustcMainParser { |
| 22 | 23 | const PATH: &[Symbol] = &[sym::rustc_main]; |
| 23 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 24 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 24 | 25 | const STABILITY: AttributeStability = unstable!( |
| 25 | 26 | rustc_attrs, |
| 26 | 27 | "the `#[rustc_main]` attribute is used internally to specify test entry point function" |
| ... | ... | @@ -32,7 +33,7 @@ pub(crate) struct RustcMustImplementOneOfParser; |
| 32 | 33 | |
| 33 | 34 | impl SingleAttributeParser for RustcMustImplementOneOfParser { |
| 34 | 35 | const PATH: &[Symbol] = &[sym::rustc_must_implement_one_of]; |
| 35 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 36 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 36 | 37 | const STABILITY: AttributeStability = unstable!( |
| 37 | 38 | rustc_attrs, |
| 38 | 39 | "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete definition of a trait. Its syntax and semantics are highly experimental and will be subject to change before stabilization" |
| ... | ... | @@ -78,7 +79,7 @@ pub(crate) struct RustcNeverReturnsNullPtrParser; |
| 78 | 79 | |
| 79 | 80 | impl NoArgsAttributeParser for RustcNeverReturnsNullPtrParser { |
| 80 | 81 | const PATH: &[Symbol] = &[sym::rustc_never_returns_null_ptr]; |
| 81 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 82 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 82 | 83 | Allow(Target::Fn), |
| 83 | 84 | Allow(Target::Method(MethodKind::Inherent)), |
| 84 | 85 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -93,7 +94,7 @@ pub(crate) struct RustcNoImplicitAutorefsParser; |
| 93 | 94 | |
| 94 | 95 | impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser { |
| 95 | 96 | const PATH: &[Symbol] = &[sym::rustc_no_implicit_autorefs]; |
| 96 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 97 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 97 | 98 | Allow(Target::Fn), |
| 98 | 99 | Allow(Target::Method(MethodKind::Inherent)), |
| 99 | 100 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -109,7 +110,7 @@ pub(crate) struct RustcLegacyConstGenericsParser; |
| 109 | 110 | |
| 110 | 111 | impl SingleAttributeParser for RustcLegacyConstGenericsParser { |
| 111 | 112 | const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics]; |
| 112 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 113 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 113 | 114 | const TEMPLATE: AttributeTemplate = template!(List: &["N"]); |
| 114 | 115 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 115 | 116 | |
| ... | ... | @@ -149,7 +150,7 @@ pub(crate) struct RustcInheritOverflowChecksParser; |
| 149 | 150 | |
| 150 | 151 | impl NoArgsAttributeParser for RustcInheritOverflowChecksParser { |
| 151 | 152 | const PATH: &[Symbol] = &[sym::rustc_inherit_overflow_checks]; |
| 152 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 153 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 153 | 154 | Allow(Target::Fn), |
| 154 | 155 | Allow(Target::Method(MethodKind::Inherent)), |
| 155 | 156 | Allow(Target::Method(MethodKind::TraitImpl)), |
| ... | ... | @@ -163,7 +164,7 @@ pub(crate) struct RustcLintOptDenyFieldAccessParser; |
| 163 | 164 | |
| 164 | 165 | impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser { |
| 165 | 166 | const PATH: &[Symbol] = &[sym::rustc_lint_opt_deny_field_access]; |
| 166 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]); | |
| 167 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Field)]); | |
| 167 | 168 | const TEMPLATE: AttributeTemplate = template!(Word); |
| 168 | 169 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 169 | 170 | fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> { |
| ... | ... | @@ -178,7 +179,7 @@ pub(crate) struct RustcLintOptTyParser; |
| 178 | 179 | |
| 179 | 180 | impl NoArgsAttributeParser for RustcLintOptTyParser { |
| 180 | 181 | const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty]; |
| 181 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 182 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 182 | 183 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 183 | 184 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; |
| 184 | 185 | } |
| ... | ... | @@ -305,7 +306,7 @@ impl AttributeParser for RustcCguTestAttributeParser { |
| 305 | 306 | ), |
| 306 | 307 | ]; |
| 307 | 308 | |
| 308 | const ALLOWED_TARGETS: AllowedTargets = | |
| 309 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 309 | 310 | AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]); |
| 310 | 311 | |
| 311 | 312 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
| ... | ... | @@ -317,7 +318,7 @@ pub(crate) struct RustcDeprecatedSafe2024Parser; |
| 317 | 318 | |
| 318 | 319 | impl SingleAttributeParser for RustcDeprecatedSafe2024Parser { |
| 319 | 320 | const PATH: &[Symbol] = &[sym::rustc_deprecated_safe_2024]; |
| 320 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 321 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 321 | 322 | Allow(Target::Fn), |
| 322 | 323 | Allow(Target::Method(MethodKind::Inherent)), |
| 323 | 324 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -347,7 +348,7 @@ pub(crate) struct RustcConversionSuggestionParser; |
| 347 | 348 | |
| 348 | 349 | impl NoArgsAttributeParser for RustcConversionSuggestionParser { |
| 349 | 350 | const PATH: &[Symbol] = &[sym::rustc_conversion_suggestion]; |
| 350 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 351 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 351 | 352 | Allow(Target::Fn), |
| 352 | 353 | Allow(Target::Method(MethodKind::Inherent)), |
| 353 | 354 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -362,7 +363,8 @@ pub(crate) struct RustcCaptureAnalysisParser; |
| 362 | 363 | |
| 363 | 364 | impl NoArgsAttributeParser for RustcCaptureAnalysisParser { |
| 364 | 365 | const PATH: &[Symbol] = &[sym::rustc_capture_analysis]; |
| 365 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]); | |
| 366 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 367 | AllowedTargets::AllowList(&[Allow(Target::Closure)]); | |
| 366 | 368 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 367 | 369 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis; |
| 368 | 370 | } |
| ... | ... | @@ -371,7 +373,7 @@ pub(crate) struct RustcNeverTypeOptionsParser; |
| 371 | 373 | |
| 372 | 374 | impl SingleAttributeParser for RustcNeverTypeOptionsParser { |
| 373 | 375 | const PATH: &[Symbol] = &[sym::rustc_never_type_options]; |
| 374 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 376 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 375 | 377 | const TEMPLATE: AttributeTemplate = template!(List: &[ |
| 376 | 378 | r#"fallback = "unit", "never", "no""#, |
| 377 | 379 | r#"diverging_block_default = "unit", "never""#, |
| ... | ... | @@ -444,7 +446,7 @@ pub(crate) struct RustcTrivialFieldReadsParser; |
| 444 | 446 | |
| 445 | 447 | impl NoArgsAttributeParser for RustcTrivialFieldReadsParser { |
| 446 | 448 | const PATH: &[Symbol] = &[sym::rustc_trivial_field_reads]; |
| 447 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 449 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 448 | 450 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 449 | 451 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads; |
| 450 | 452 | } |
| ... | ... | @@ -453,7 +455,7 @@ pub(crate) struct RustcNoMirInlineParser; |
| 453 | 455 | |
| 454 | 456 | impl NoArgsAttributeParser for RustcNoMirInlineParser { |
| 455 | 457 | const PATH: &[Symbol] = &[sym::rustc_no_mir_inline]; |
| 456 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 458 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 457 | 459 | Allow(Target::Fn), |
| 458 | 460 | Allow(Target::Method(MethodKind::Inherent)), |
| 459 | 461 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -469,7 +471,7 @@ pub(crate) struct RustcNoWritableParser; |
| 469 | 471 | impl NoArgsAttributeParser for RustcNoWritableParser { |
| 470 | 472 | const PATH: &[Symbol] = &[sym::rustc_no_writable]; |
| 471 | 473 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; |
| 472 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 474 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 473 | 475 | Allow(Target::Fn), |
| 474 | 476 | Allow(Target::Closure), |
| 475 | 477 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -484,7 +486,7 @@ pub(crate) struct RustcLintQueryInstabilityParser; |
| 484 | 486 | |
| 485 | 487 | impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { |
| 486 | 488 | const PATH: &[Symbol] = &[sym::rustc_lint_query_instability]; |
| 487 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 489 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 488 | 490 | Allow(Target::Fn), |
| 489 | 491 | Allow(Target::Method(MethodKind::Inherent)), |
| 490 | 492 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -499,7 +501,7 @@ pub(crate) struct RustcRegionsParser; |
| 499 | 501 | |
| 500 | 502 | impl NoArgsAttributeParser for RustcRegionsParser { |
| 501 | 503 | const PATH: &[Symbol] = &[sym::rustc_regions]; |
| 502 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 504 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 503 | 505 | Allow(Target::Fn), |
| 504 | 506 | Allow(Target::Method(MethodKind::Inherent)), |
| 505 | 507 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -514,7 +516,7 @@ pub(crate) struct RustcLintUntrackedQueryInformationParser; |
| 514 | 516 | |
| 515 | 517 | impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser { |
| 516 | 518 | const PATH: &[Symbol] = &[sym::rustc_lint_untracked_query_information]; |
| 517 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 519 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 518 | 520 | Allow(Target::Fn), |
| 519 | 521 | Allow(Target::Method(MethodKind::Inherent)), |
| 520 | 522 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| ... | ... | @@ -529,7 +531,7 @@ pub(crate) struct RustcSimdMonomorphizeLaneLimitParser; |
| 529 | 531 | |
| 530 | 532 | impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser { |
| 531 | 533 | const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit]; |
| 532 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 534 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 533 | 535 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); |
| 534 | 536 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 535 | 537 | |
| ... | ... | @@ -543,7 +545,7 @@ pub(crate) struct RustcScalableVectorParser; |
| 543 | 545 | |
| 544 | 546 | impl SingleAttributeParser for RustcScalableVectorParser { |
| 545 | 547 | const PATH: &[Symbol] = &[sym::rustc_scalable_vector]; |
| 546 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 548 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 547 | 549 | const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]); |
| 548 | 550 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 549 | 551 | |
| ... | ... | @@ -565,7 +567,7 @@ pub(crate) struct LangParser; |
| 565 | 567 | |
| 566 | 568 | impl SingleAttributeParser for LangParser { |
| 567 | 569 | const PATH: &[Symbol] = &[sym::lang]; |
| 568 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes` | |
| 570 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked; | |
| 569 | 571 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); |
| 570 | 572 | const STABILITY: AttributeStability = unstable!(lang_items); |
| 571 | 573 | |
| ... | ... | @@ -576,6 +578,24 @@ impl SingleAttributeParser for LangParser { |
| 576 | 578 | cx.emit_err(UnknownLangItem { span: cx.attr_span, name }); |
| 577 | 579 | return None; |
| 578 | 580 | }; |
| 581 | ||
| 582 | // Only weak lang items may be applied to foreign items | |
| 583 | if [Target::ForeignFn, Target::ForeignStatic, Target::ForeignTy, Target::ForeignMod] | |
| 584 | .contains(&cx.target) | |
| 585 | && !lang_item.is_weak() | |
| 586 | { | |
| 587 | cx.emit_err(UnknownExternLangItem { span: cx.attr_span, lang_item: lang_item.name() }); | |
| 588 | return None; | |
| 589 | } | |
| 590 | ||
| 591 | // Check the target | |
| 592 | let allowed_targets: &[_] = if lang_item == LangItem::PanicImpl { | |
| 593 | &[Allow(Target::Fn), Allow(Target::ForeignFn)] | |
| 594 | } else { | |
| 595 | &[Allow(lang_item.target())] | |
| 596 | }; | |
| 597 | cx.check_target(&format!(" = \"{name}\""), &AllowedTargets::AllowList(allowed_targets)); | |
| 598 | ||
| 579 | 599 | Some(AttributeKind::Lang(lang_item)) |
| 580 | 600 | } |
| 581 | 601 | } |
| ... | ... | @@ -584,7 +604,7 @@ pub(crate) struct RustcHasIncoherentInherentImplsParser; |
| 584 | 604 | |
| 585 | 605 | impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParser { |
| 586 | 606 | const PATH: &[Symbol] = &[sym::rustc_has_incoherent_inherent_impls]; |
| 587 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 607 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 588 | 608 | Allow(Target::Trait), |
| 589 | 609 | Allow(Target::Struct), |
| 590 | 610 | Allow(Target::Enum), |
| ... | ... | @@ -599,7 +619,7 @@ pub(crate) struct PanicHandlerParser; |
| 599 | 619 | |
| 600 | 620 | impl NoArgsAttributeParser for PanicHandlerParser { |
| 601 | 621 | const PATH: &[Symbol] = &[sym::panic_handler]; |
| 602 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes` | |
| 622 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 603 | 623 | const STABILITY: AttributeStability = AttributeStability::Stable; |
| 604 | 624 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Lang(LangItem::PanicImpl); |
| 605 | 625 | } |
| ... | ... | @@ -608,7 +628,7 @@ pub(crate) struct RustcNounwindParser; |
| 608 | 628 | |
| 609 | 629 | impl NoArgsAttributeParser for RustcNounwindParser { |
| 610 | 630 | const PATH: &[Symbol] = &[sym::rustc_nounwind]; |
| 611 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 631 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 612 | 632 | Allow(Target::Fn), |
| 613 | 633 | Allow(Target::ForeignFn), |
| 614 | 634 | Allow(Target::Method(MethodKind::Inherent)), |
| ... | ... | @@ -623,7 +643,7 @@ pub(crate) struct RustcOffloadKernelParser; |
| 623 | 643 | |
| 624 | 644 | impl NoArgsAttributeParser for RustcOffloadKernelParser { |
| 625 | 645 | const PATH: &[Symbol] = &[sym::rustc_offload_kernel]; |
| 626 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 646 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 627 | 647 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 628 | 648 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel; |
| 629 | 649 | } |
| ... | ... | @@ -636,7 +656,7 @@ impl CombineAttributeParser for RustcMirParser { |
| 636 | 656 | type Item = RustcMirKind; |
| 637 | 657 | |
| 638 | 658 | const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcMir(items); |
| 639 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 659 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 640 | 660 | Allow(Target::Fn), |
| 641 | 661 | Allow(Target::Method(MethodKind::Inherent)), |
| 642 | 662 | Allow(Target::Method(MethodKind::TraitImpl)), |
| ... | ... | @@ -712,7 +732,7 @@ pub(crate) struct RustcNonConstTraitMethodParser; |
| 712 | 732 | |
| 713 | 733 | impl NoArgsAttributeParser for RustcNonConstTraitMethodParser { |
| 714 | 734 | const PATH: &[Symbol] = &[sym::rustc_non_const_trait_method]; |
| 715 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 735 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 716 | 736 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| 717 | 737 | Allow(Target::Method(MethodKind::Trait { body: false })), |
| 718 | 738 | ]); |
| ... | ... | @@ -731,7 +751,7 @@ impl CombineAttributeParser for RustcCleanParser { |
| 731 | 751 | type Item = RustcCleanAttribute; |
| 732 | 752 | |
| 733 | 753 | const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcClean(items); |
| 734 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 754 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 735 | 755 | // tidy-alphabetical-start |
| 736 | 756 | Allow(Target::AssocConst), |
| 737 | 757 | Allow(Target::AssocTy), |
| ... | ... | @@ -824,7 +844,7 @@ pub(crate) struct RustcIfThisChangedParser; |
| 824 | 844 | |
| 825 | 845 | impl SingleAttributeParser for RustcIfThisChangedParser { |
| 826 | 846 | const PATH: &[Symbol] = &[sym::rustc_if_this_changed]; |
| 827 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 847 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 828 | 848 | // tidy-alphabetical-start |
| 829 | 849 | Allow(Target::AssocConst), |
| 830 | 850 | Allow(Target::AssocTy), |
| ... | ... | @@ -882,7 +902,7 @@ impl CombineAttributeParser for RustcThenThisWouldNeedParser { |
| 882 | 902 | |
| 883 | 903 | const CONVERT: ConvertFn<Self::Item> = |
| 884 | 904 | |items, _span| AttributeKind::RustcThenThisWouldNeed(items); |
| 885 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 905 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 886 | 906 | // tidy-alphabetical-start |
| 887 | 907 | Allow(Target::AssocConst), |
| 888 | 908 | Allow(Target::AssocTy), |
| ... | ... | @@ -929,7 +949,7 @@ pub(crate) struct RustcInsignificantDtorParser; |
| 929 | 949 | |
| 930 | 950 | impl NoArgsAttributeParser for RustcInsignificantDtorParser { |
| 931 | 951 | const PATH: &[Symbol] = &[sym::rustc_insignificant_dtor]; |
| 932 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 952 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 933 | 953 | Allow(Target::Enum), |
| 934 | 954 | Allow(Target::Struct), |
| 935 | 955 | Allow(Target::ForeignTy), |
| ... | ... | @@ -942,7 +962,7 @@ pub(crate) struct RustcEffectiveVisibilityParser; |
| 942 | 962 | |
| 943 | 963 | impl NoArgsAttributeParser for RustcEffectiveVisibilityParser { |
| 944 | 964 | const PATH: &[Symbol] = &[sym::rustc_effective_visibility]; |
| 945 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 965 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 946 | 966 | Allow(Target::Use), |
| 947 | 967 | Allow(Target::Static), |
| 948 | 968 | Allow(Target::Const), |
| ... | ... | @@ -981,7 +1001,7 @@ pub(crate) struct RustcDiagnosticItemParser; |
| 981 | 1001 | |
| 982 | 1002 | impl SingleAttributeParser for RustcDiagnosticItemParser { |
| 983 | 1003 | const PATH: &[Symbol] = &[sym::rustc_diagnostic_item]; |
| 984 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 1004 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 985 | 1005 | Allow(Target::Trait), |
| 986 | 1006 | Allow(Target::Struct), |
| 987 | 1007 | Allow(Target::Enum), |
| ... | ... | @@ -1016,7 +1036,7 @@ pub(crate) struct RustcDoNotConstCheckParser; |
| 1016 | 1036 | |
| 1017 | 1037 | impl NoArgsAttributeParser for RustcDoNotConstCheckParser { |
| 1018 | 1038 | const PATH: &[Symbol] = &[sym::rustc_do_not_const_check]; |
| 1019 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 1039 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 1020 | 1040 | Allow(Target::Fn), |
| 1021 | 1041 | Allow(Target::Method(MethodKind::Inherent)), |
| 1022 | 1042 | Allow(Target::Method(MethodKind::TraitImpl)), |
| ... | ... | @@ -1034,7 +1054,7 @@ pub(crate) struct RustcNonnullOptimizationGuaranteedParser; |
| 1034 | 1054 | |
| 1035 | 1055 | impl NoArgsAttributeParser for RustcNonnullOptimizationGuaranteedParser { |
| 1036 | 1056 | const PATH: &[Symbol] = &[sym::rustc_nonnull_optimization_guaranteed]; |
| 1037 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 1057 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]); | |
| 1038 | 1058 | const STABILITY: AttributeStability = unstable!( |
| 1039 | 1059 | rustc_attrs, |
| 1040 | 1060 | "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document guaranteed niche optimizations in the standard library", |
| ... | ... | @@ -1047,7 +1067,7 @@ pub(crate) struct RustcStrictCoherenceParser; |
| 1047 | 1067 | |
| 1048 | 1068 | impl NoArgsAttributeParser for RustcStrictCoherenceParser { |
| 1049 | 1069 | const PATH: &[Symbol] = &[sym::rustc_strict_coherence]; |
| 1050 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 1070 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 1051 | 1071 | Allow(Target::Trait), |
| 1052 | 1072 | Allow(Target::Struct), |
| 1053 | 1073 | Allow(Target::Enum), |
| ... | ... | @@ -1062,7 +1082,7 @@ pub(crate) struct RustcReservationImplParser; |
| 1062 | 1082 | |
| 1063 | 1083 | impl SingleAttributeParser for RustcReservationImplParser { |
| 1064 | 1084 | const PATH: &[Symbol] = &[sym::rustc_reservation_impl]; |
| 1065 | const ALLOWED_TARGETS: AllowedTargets = | |
| 1085 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 1066 | 1086 | AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]); |
| 1067 | 1087 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "reservation message"); |
| 1068 | 1088 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| ... | ... | @@ -1079,7 +1099,7 @@ pub(crate) struct PreludeImportParser; |
| 1079 | 1099 | |
| 1080 | 1100 | impl NoArgsAttributeParser for PreludeImportParser { |
| 1081 | 1101 | const PATH: &[Symbol] = &[sym::prelude_import]; |
| 1082 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Use)]); | |
| 1102 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Use)]); | |
| 1083 | 1103 | const STABILITY: AttributeStability = unstable!(prelude_import); |
| 1084 | 1104 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PreludeImport; |
| 1085 | 1105 | } |
| ... | ... | @@ -1088,7 +1108,7 @@ pub(crate) struct RustcDocPrimitiveParser; |
| 1088 | 1108 | |
| 1089 | 1109 | impl SingleAttributeParser for RustcDocPrimitiveParser { |
| 1090 | 1110 | const PATH: &[Symbol] = &[sym::rustc_doc_primitive]; |
| 1091 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]); | |
| 1111 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Mod)]); | |
| 1092 | 1112 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name"); |
| 1093 | 1113 | const STABILITY: AttributeStability = unstable!( |
| 1094 | 1114 | rustc_attrs, |
| ... | ... | @@ -1107,7 +1127,7 @@ pub(crate) struct RustcIntrinsicParser; |
| 1107 | 1127 | |
| 1108 | 1128 | impl NoArgsAttributeParser for RustcIntrinsicParser { |
| 1109 | 1129 | const PATH: &[Symbol] = &[sym::rustc_intrinsic]; |
| 1110 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 1130 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 1111 | 1131 | const STABILITY: AttributeStability = unstable!(intrinsics); |
| 1112 | 1132 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsic; |
| 1113 | 1133 | } |
| ... | ... | @@ -1116,7 +1136,7 @@ pub(crate) struct RustcIntrinsicConstStableIndirectParser; |
| 1116 | 1136 | |
| 1117 | 1137 | impl NoArgsAttributeParser for RustcIntrinsicConstStableIndirectParser { |
| 1118 | 1138 | const PATH: &'static [Symbol] = &[sym::rustc_intrinsic_const_stable_indirect]; |
| 1119 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 1139 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 1120 | 1140 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 1121 | 1141 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect; |
| 1122 | 1142 | } |
| ... | ... | @@ -1125,7 +1145,7 @@ pub(crate) struct RustcExhaustiveParser; |
| 1125 | 1145 | |
| 1126 | 1146 | impl NoArgsAttributeParser for RustcExhaustiveParser { |
| 1127 | 1147 | const PATH: &'static [Symbol] = &[sym::rustc_must_match_exhaustively]; |
| 1128 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Enum)]); | |
| 1148 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Enum)]); | |
| 1129 | 1149 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 1130 | 1150 | const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcMustMatchExhaustively; |
| 1131 | 1151 | } |
compiler/rustc_attr_parsing/src/attributes/semantics.rs+2-2| ... | ... | @@ -5,7 +5,7 @@ use super::prelude::*; |
| 5 | 5 | pub(crate) struct MayDangleParser; |
| 6 | 6 | impl NoArgsAttributeParser for MayDangleParser { |
| 7 | 7 | const PATH: &[Symbol] = &[sym::may_dangle]; |
| 8 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs` | |
| 8 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs` | |
| 9 | 9 | const STABILITY: AttributeStability = unstable!(dropck_eyepatch); |
| 10 | 10 | const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle; |
| 11 | 11 | } |
| ... | ... | @@ -14,7 +14,7 @@ pub(crate) struct ComptimeParser; |
| 14 | 14 | impl NoArgsAttributeParser for ComptimeParser { |
| 15 | 15 | const PATH: &[Symbol] = &[sym::rustc_comptime]; |
| 16 | 16 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; |
| 17 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 17 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 18 | 18 | Allow(Target::Method(MethodKind::Inherent)), |
| 19 | 19 | Allow(Target::Fn), |
| 20 | 20 | ]); |
compiler/rustc_attr_parsing/src/attributes/splat.rs+1-1| ... | ... | @@ -9,7 +9,7 @@ pub(crate) struct SplatParser; |
| 9 | 9 | |
| 10 | 10 | impl NoArgsAttributeParser for SplatParser { |
| 11 | 11 | const PATH: &[Symbol] = &[sym::splat]; |
| 12 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Param)]); | |
| 12 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Param)]); | |
| 13 | 13 | const STABILITY: AttributeStability = |
| 14 | 14 | unstable!(splat, "the `#[splat]` attribute is experimental"); |
| 15 | 15 | const CREATE: fn(Span) -> AttributeKind = AttributeKind::Splat; |
compiler/rustc_attr_parsing/src/attributes/stability.rs+6-6| ... | ... | @@ -13,7 +13,7 @@ use super::prelude::*; |
| 13 | 13 | use super::util::parse_version; |
| 14 | 14 | use crate::session_diagnostics; |
| 15 | 15 | |
| 16 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 16 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 17 | 17 | Allow(Target::Fn), |
| 18 | 18 | Allow(Target::Struct), |
| 19 | 19 | Allow(Target::Enum), |
| ... | ... | @@ -102,7 +102,7 @@ impl AttributeParser for StabilityParser { |
| 102 | 102 | }, |
| 103 | 103 | ), |
| 104 | 104 | ]; |
| 105 | const ALLOWED_TARGETS: AllowedTargets = ALLOWED_TARGETS; | |
| 105 | const ALLOWED_TARGETS: AllowedTargets<'_> = ALLOWED_TARGETS; | |
| 106 | 106 | |
| 107 | 107 | fn finalize(mut self, cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
| 108 | 108 | if let Some(atum) = self.allowed_through_unstable_modules { |
| ... | ... | @@ -158,7 +158,7 @@ impl AttributeParser for BodyStabilityParser { |
| 158 | 158 | } |
| 159 | 159 | }, |
| 160 | 160 | )]; |
| 161 | const ALLOWED_TARGETS: AllowedTargets = ALLOWED_TARGETS; | |
| 161 | const ALLOWED_TARGETS: AllowedTargets<'_> = ALLOWED_TARGETS; | |
| 162 | 162 | |
| 163 | 163 | fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> { |
| 164 | 164 | let (stability, span) = self.stability?; |
| ... | ... | @@ -171,7 +171,7 @@ pub(crate) struct RustcConstStableIndirectParser; |
| 171 | 171 | impl NoArgsAttributeParser for RustcConstStableIndirectParser { |
| 172 | 172 | const PATH: &[Symbol] = &[sym::rustc_const_stable_indirect]; |
| 173 | 173 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore; |
| 174 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 174 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 175 | 175 | Allow(Target::Fn), |
| 176 | 176 | Allow(Target::Method(MethodKind::Inherent)), |
| 177 | 177 | ]); |
| ... | ... | @@ -233,7 +233,7 @@ impl AttributeParser for ConstStabilityParser { |
| 233 | 233 | this.promotable = true; |
| 234 | 234 | }), |
| 235 | 235 | ]; |
| 236 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 236 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 237 | 237 | Allow(Target::Fn), |
| 238 | 238 | Allow(Target::Method(MethodKind::Inherent)), |
| 239 | 239 | Allow(Target::Method(MethodKind::TraitImpl)), |
| ... | ... | @@ -460,7 +460,7 @@ pub(crate) struct UnstableRemovedParser; |
| 460 | 460 | impl CombineAttributeParser for UnstableRemovedParser { |
| 461 | 461 | type Item = UnstableRemovedFeature; |
| 462 | 462 | const PATH: &[Symbol] = &[sym::unstable_removed]; |
| 463 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 463 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 464 | 464 | const TEMPLATE: AttributeTemplate = |
| 465 | 465 | template!(List: &[r#"feature = "name", reason = "...", link = "...", since = "version""#]); |
| 466 | 466 | const STABILITY: AttributeStability = unstable!(staged_api); |
compiler/rustc_attr_parsing/src/attributes/test_attrs.rs+8-8| ... | ... | @@ -9,7 +9,7 @@ pub(crate) struct IgnoreParser; |
| 9 | 9 | impl SingleAttributeParser for IgnoreParser { |
| 10 | 10 | const PATH: &[Symbol] = &[sym::ignore]; |
| 11 | 11 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; |
| 12 | const ALLOWED_TARGETS: AllowedTargets = | |
| 12 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 13 | 13 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]); |
| 14 | 14 | const TEMPLATE: AttributeTemplate = template!( |
| 15 | 15 | Word, NameValueStr: "reason", |
| ... | ... | @@ -51,7 +51,7 @@ pub(crate) struct ShouldPanicParser; |
| 51 | 51 | impl SingleAttributeParser for ShouldPanicParser { |
| 52 | 52 | const PATH: &[Symbol] = &[sym::should_panic]; |
| 53 | 53 | const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; |
| 54 | const ALLOWED_TARGETS: AllowedTargets = | |
| 54 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 55 | 55 | AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]); |
| 56 | 56 | const TEMPLATE: AttributeTemplate = template!( |
| 57 | 57 | Word, List: &[r#"expected = "reason""#], NameValueStr: "reason", |
| ... | ... | @@ -83,7 +83,7 @@ pub(crate) struct ReexportTestHarnessMainParser; |
| 83 | 83 | |
| 84 | 84 | impl SingleAttributeParser for ReexportTestHarnessMainParser { |
| 85 | 85 | const PATH: &[Symbol] = &[sym::reexport_test_harness_main]; |
| 86 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 86 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 87 | 87 | const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); |
| 88 | 88 | const STABILITY: AttributeStability = unstable!(custom_test_frameworks); |
| 89 | 89 | |
| ... | ... | @@ -105,7 +105,7 @@ pub(crate) struct RustcAbiParser; |
| 105 | 105 | impl SingleAttributeParser for RustcAbiParser { |
| 106 | 106 | const PATH: &[Symbol] = &[sym::rustc_abi]; |
| 107 | 107 | const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::debug, sym::assert_eq]); |
| 108 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 108 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 109 | 109 | Allow(Target::TyAlias), |
| 110 | 110 | Allow(Target::Fn), |
| 111 | 111 | Allow(Target::ForeignFn), |
| ... | ... | @@ -150,7 +150,7 @@ pub(crate) struct RustcDelayedBugFromInsideQueryParser; |
| 150 | 150 | |
| 151 | 151 | impl NoArgsAttributeParser for RustcDelayedBugFromInsideQueryParser { |
| 152 | 152 | const PATH: &[Symbol] = &[sym::rustc_delayed_bug_from_inside_query]; |
| 153 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 153 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); | |
| 154 | 154 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 155 | 155 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDelayedBugFromInsideQuery; |
| 156 | 156 | } |
| ... | ... | @@ -159,7 +159,7 @@ pub(crate) struct RustcEvaluateWhereClausesParser; |
| 159 | 159 | |
| 160 | 160 | impl NoArgsAttributeParser for RustcEvaluateWhereClausesParser { |
| 161 | 161 | const PATH: &[Symbol] = &[sym::rustc_evaluate_where_clauses]; |
| 162 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 162 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 163 | 163 | Allow(Target::Fn), |
| 164 | 164 | Allow(Target::Method(MethodKind::Inherent)), |
| 165 | 165 | Allow(Target::Method(MethodKind::Trait { body: true })), |
| ... | ... | @@ -174,7 +174,7 @@ pub(crate) struct TestRunnerParser; |
| 174 | 174 | |
| 175 | 175 | impl SingleAttributeParser for TestRunnerParser { |
| 176 | 176 | const PATH: &[Symbol] = &[sym::test_runner]; |
| 177 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 177 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); | |
| 178 | 178 | const TEMPLATE: AttributeTemplate = template!(List: &["path"]); |
| 179 | 179 | const STABILITY: AttributeStability = unstable!(custom_test_frameworks); |
| 180 | 180 | |
| ... | ... | @@ -194,7 +194,7 @@ pub(crate) struct RustcTestMarkerParser; |
| 194 | 194 | |
| 195 | 195 | impl SingleAttributeParser for RustcTestMarkerParser { |
| 196 | 196 | const PATH: &[Symbol] = &[sym::rustc_test_marker]; |
| 197 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 197 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 198 | 198 | Allow(Target::Const), |
| 199 | 199 | Allow(Target::Fn), |
| 200 | 200 | Allow(Target::Static), |
compiler/rustc_attr_parsing/src/attributes/traits.rs+10-10| ... | ... | @@ -12,7 +12,7 @@ use crate::target_checking::Policy::{Allow, Warn}; |
| 12 | 12 | pub(crate) struct RustcSkipDuringMethodDispatchParser; |
| 13 | 13 | impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser { |
| 14 | 14 | const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; |
| 15 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 15 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 16 | 16 | |
| 17 | 17 | const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]); |
| 18 | 18 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| ... | ... | @@ -52,7 +52,7 @@ impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser { |
| 52 | 52 | pub(crate) struct RustcParenSugarParser; |
| 53 | 53 | impl NoArgsAttributeParser for RustcParenSugarParser { |
| 54 | 54 | const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; |
| 55 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 55 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 56 | 56 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 57 | 57 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcParenSugar; |
| 58 | 58 | } |
| ... | ... | @@ -62,7 +62,7 @@ impl NoArgsAttributeParser for RustcParenSugarParser { |
| 62 | 62 | pub(crate) struct MarkerParser; |
| 63 | 63 | impl NoArgsAttributeParser for MarkerParser { |
| 64 | 64 | const PATH: &[Symbol] = &[sym::marker]; |
| 65 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 65 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 66 | 66 | Allow(Target::Trait), |
| 67 | 67 | Warn(Target::Field), |
| 68 | 68 | Warn(Target::Arm), |
| ... | ... | @@ -75,7 +75,7 @@ impl NoArgsAttributeParser for MarkerParser { |
| 75 | 75 | pub(crate) struct RustcDenyExplicitImplParser; |
| 76 | 76 | impl NoArgsAttributeParser for RustcDenyExplicitImplParser { |
| 77 | 77 | const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl]; |
| 78 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 78 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 79 | 79 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 80 | 80 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDenyExplicitImpl; |
| 81 | 81 | } |
| ... | ... | @@ -83,7 +83,7 @@ impl NoArgsAttributeParser for RustcDenyExplicitImplParser { |
| 83 | 83 | pub(crate) struct RustcDynIncompatibleTraitParser; |
| 84 | 84 | impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser { |
| 85 | 85 | const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait]; |
| 86 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 86 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 87 | 87 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 88 | 88 | const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait; |
| 89 | 89 | } |
| ... | ... | @@ -93,7 +93,7 @@ impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser { |
| 93 | 93 | pub(crate) struct RustcSpecializationTraitParser; |
| 94 | 94 | impl NoArgsAttributeParser for RustcSpecializationTraitParser { |
| 95 | 95 | const PATH: &[Symbol] = &[sym::rustc_specialization_trait]; |
| 96 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 96 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 97 | 97 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 98 | 98 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcSpecializationTrait; |
| 99 | 99 | } |
| ... | ... | @@ -101,7 +101,7 @@ impl NoArgsAttributeParser for RustcSpecializationTraitParser { |
| 101 | 101 | pub(crate) struct RustcUnsafeSpecializationMarkerParser; |
| 102 | 102 | impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser { |
| 103 | 103 | const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker]; |
| 104 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 104 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 105 | 105 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 106 | 106 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcUnsafeSpecializationMarker; |
| 107 | 107 | } |
| ... | ... | @@ -111,7 +111,7 @@ impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser { |
| 111 | 111 | pub(crate) struct RustcCoinductiveParser; |
| 112 | 112 | impl NoArgsAttributeParser for RustcCoinductiveParser { |
| 113 | 113 | const PATH: &[Symbol] = &[sym::rustc_coinductive]; |
| 114 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 114 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| 115 | 115 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 116 | 116 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoinductive; |
| 117 | 117 | } |
| ... | ... | @@ -119,7 +119,7 @@ impl NoArgsAttributeParser for RustcCoinductiveParser { |
| 119 | 119 | pub(crate) struct RustcAllowIncoherentImplParser; |
| 120 | 120 | impl NoArgsAttributeParser for RustcAllowIncoherentImplParser { |
| 121 | 121 | const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl]; |
| 122 | const ALLOWED_TARGETS: AllowedTargets = | |
| 122 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 123 | 123 | AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]); |
| 124 | 124 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 125 | 125 | const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl; |
| ... | ... | @@ -128,7 +128,7 @@ impl NoArgsAttributeParser for RustcAllowIncoherentImplParser { |
| 128 | 128 | pub(crate) struct FundamentalParser; |
| 129 | 129 | impl NoArgsAttributeParser for FundamentalParser { |
| 130 | 130 | const PATH: &[Symbol] = &[sym::fundamental]; |
| 131 | const ALLOWED_TARGETS: AllowedTargets = | |
| 131 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 132 | 132 | AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]); |
| 133 | 133 | const STABILITY: AttributeStability = unstable!(fundamental); |
| 134 | 134 | const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; |
compiler/rustc_attr_parsing/src/attributes/transparency.rs+2-1| ... | ... | @@ -11,7 +11,8 @@ impl SingleAttributeParser for RustcMacroTransparencyParser { |
| 11 | 11 | cx.dcx().span_err(vec![used, unused], "multiple macro transparency attributes"); |
| 12 | 12 | }); |
| 13 | 13 | const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| 14 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); | |
| 14 | const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| 15 | AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); | |
| 15 | 16 | const TEMPLATE: AttributeTemplate = |
| 16 | 17 | template!(NameValueStr: ["transparent", "semiopaque", "opaque"]); |
| 17 | 18 |
compiler/rustc_attr_parsing/src/attributes/unroll.rs+1-1| ... | ... | @@ -7,7 +7,7 @@ use super::prelude::*; |
| 7 | 7 | pub(crate) struct UnrollParser; |
| 8 | 8 | impl SingleAttributeParser for UnrollParser { |
| 9 | 9 | const PATH: &[Symbol] = &[sym::unroll]; |
| 10 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ | |
| 10 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| 11 | 11 | Allow(Target::Loop), |
| 12 | 12 | Allow(Target::ForLoop), |
| 13 | 13 | Allow(Target::While), |
compiler/rustc_attr_parsing/src/context.rs+1-1| ... | ... | @@ -85,7 +85,7 @@ pub(super) struct GroupTypeInner { |
| 85 | 85 | pub(super) struct GroupTypeInnerAccept { |
| 86 | 86 | pub(super) template: AttributeTemplate, |
| 87 | 87 | pub(super) accept_fn: AcceptFn, |
| 88 | pub(super) allowed_targets: AllowedTargets, | |
| 88 | pub(super) allowed_targets: AllowedTargets<'static>, | |
| 89 | 89 | pub(super) safety: AttributeSafety, |
| 90 | 90 | pub(super) stability: AttributeStability, |
| 91 | 91 | pub(super) finalizer: FinalizeFn, |
compiler/rustc_attr_parsing/src/diagnostics.rs+9-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | use rustc_errors::{Applicability, DiagArgValue, E0232, MultiSpan}; | |
| 1 | use rustc_errors::{Applicability, DiagArgValue, E0232, E0264, MultiSpan}; | |
| 2 | 2 | use rustc_hir::AttrPath; |
| 3 | 3 | use rustc_macros::{Diagnostic, Subdiagnostic}; |
| 4 | 4 | use rustc_span::{Span, Symbol}; |
| ... | ... | @@ -801,3 +801,11 @@ pub(crate) struct UnsafeAttribute { |
| 801 | 801 | pub attr_path: AttrPath, |
| 802 | 802 | pub note: &'static str, |
| 803 | 803 | } |
| 804 | ||
| 805 | #[derive(Diagnostic)] | |
| 806 | #[diag("unknown external lang item: `{$lang_item}`", code = E0264)] | |
| 807 | pub(crate) struct UnknownExternLangItem { | |
| 808 | #[primary_span] | |
| 809 | pub span: Span, | |
| 810 | pub lang_item: Symbol, | |
| 811 | } |
compiler/rustc_attr_parsing/src/session_diagnostics.rs+1-1| ... | ... | @@ -337,7 +337,7 @@ pub(crate) struct InvalidTarget { |
| 337 | 337 | pub target: &'static str, |
| 338 | 338 | pub applied: DiagArgValue, |
| 339 | 339 | pub only: &'static str, |
| 340 | pub attribute_args: &'static str, | |
| 340 | pub attribute_args: String, | |
| 341 | 341 | #[subdiagnostic] |
| 342 | 342 | pub help: Option<InvalidTargetHelp>, |
| 343 | 343 | #[warning( |
compiler/rustc_attr_parsing/src/target_checking.rs+10-10| ... | ... | @@ -16,9 +16,9 @@ use crate::target_checking::Policy::Allow; |
| 16 | 16 | use crate::{AttributeParser, ShouldEmit}; |
| 17 | 17 | |
| 18 | 18 | #[derive(Debug)] |
| 19 | pub(crate) enum AllowedTargets { | |
| 20 | AllowList(&'static [Policy]), | |
| 21 | AllowListWarnRest(&'static [Policy]), | |
| 19 | pub(crate) enum AllowedTargets<'a> { | |
| 20 | AllowList(&'a [Policy]), | |
| 21 | AllowListWarnRest(&'a [Policy]), | |
| 22 | 22 | /// This is useful for argument-dependent target checking. |
| 23 | 23 | /// If debug assertions are enabled, |
| 24 | 24 | /// this emits a delayed bug if the `cx.check_target(...)` method is not called during attribute parsing. |
| ... | ... | @@ -31,7 +31,7 @@ pub(crate) enum AllowedResult { |
| 31 | 31 | Error, |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | impl AllowedTargets { | |
| 34 | impl AllowedTargets<'_> { | |
| 35 | 35 | pub(crate) fn is_allowed(&self, target: Target) -> AllowedResult { |
| 36 | 36 | match self { |
| 37 | 37 | AllowedTargets::AllowList(list) => { |
| ... | ... | @@ -94,8 +94,8 @@ pub(crate) enum Policy { |
| 94 | 94 | |
| 95 | 95 | impl<'sess> AttributeParser<'sess> { |
| 96 | 96 | pub(crate) fn check_target( |
| 97 | allowed_targets: &AllowedTargets, | |
| 98 | attribute_args: &'static str, | |
| 97 | allowed_targets: &AllowedTargets<'_>, | |
| 98 | attribute_args: &str, | |
| 99 | 99 | cx: &mut AcceptContext<'_, 'sess>, |
| 100 | 100 | ) { |
| 101 | 101 | if matches!(cx.should_emit, ShouldEmit::Nothing) { |
| ... | ... | @@ -137,7 +137,7 @@ impl<'sess> AttributeParser<'sess> { |
| 137 | 137 | target: cx.target.plural_name(), |
| 138 | 138 | only: if only { "only " } else { "" }, |
| 139 | 139 | applied: DiagArgValue::StrListSepByAnd(applied.into_iter().map(Cow::Owned).collect()), |
| 140 | attribute_args, | |
| 140 | attribute_args: attribute_args.to_string(), | |
| 141 | 141 | help: Self::target_checking_help(attribute_args, cx), |
| 142 | 142 | previously_accepted: matches!(result, AllowedResult::Warn) && !is_diagnostic_attr, |
| 143 | 143 | on_macro_call: matches!(cx.target, Target::MacroCall), |
| ... | ... | @@ -173,7 +173,7 @@ impl<'sess> AttributeParser<'sess> { |
| 173 | 173 | } |
| 174 | 174 | |
| 175 | 175 | fn target_checking_help( |
| 176 | attribute_args: &'static str, | |
| 176 | attribute_args: &str, | |
| 177 | 177 | cx: &AcceptContext<'_, '_>, |
| 178 | 178 | ) -> Option<InvalidTargetHelp> { |
| 179 | 179 | match &*cx.attr_path.segments { |
| ... | ... | @@ -443,8 +443,8 @@ fn filter_targets( |
| 443 | 443 | impl<'f, 'sess> AcceptContext<'f, 'sess> { |
| 444 | 444 | pub(crate) fn check_target( |
| 445 | 445 | &mut self, |
| 446 | attribute_args: &'static str, | |
| 447 | allowed_targets: &AllowedTargets, | |
| 446 | attribute_args: &str, | |
| 447 | allowed_targets: &AllowedTargets<'_>, | |
| 448 | 448 | ) { |
| 449 | 449 | self.ignore_target_checks(); |
| 450 | 450 | AttributeParser::check_target(allowed_targets, attribute_args, self); |
compiler/rustc_builtin_macros/src/format.rs+3-1| ... | ... | @@ -607,6 +607,8 @@ fn make_format_args( |
| 607 | 607 | // If there's a lot of unused arguments, |
| 608 | 608 | // let's check if this format arguments looks like another syntax (printf / shell). |
| 609 | 609 | let detect_foreign_fmt = unused.len() > args.explicit_args().len() / 2; |
| 610 | let foreign_fmt_str = | |
| 611 | if append_newline { fmt_str.strip_suffix('\n').unwrap_or(fmt_str) } else { fmt_str }; | |
| 610 | 612 | report_missing_placeholders( |
| 611 | 613 | ecx, |
| 612 | 614 | unused, |
| ... | ... | @@ -616,7 +618,7 @@ fn make_format_args( |
| 616 | 618 | &invalid_refs, |
| 617 | 619 | detect_foreign_fmt, |
| 618 | 620 | str_style, |
| 619 | fmt_str, | |
| 621 | foreign_fmt_str, | |
| 620 | 622 | uncooked_fmt_str.1.as_str(), |
| 621 | 623 | fmt_span, |
| 622 | 624 | ); |
compiler/rustc_codegen_cranelift/src/abi/mod.rs+3-3| ... | ... | @@ -16,9 +16,9 @@ use rustc_abi::{CanonAbi, ExternAbi, X86Call}; |
| 16 | 16 | use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization; |
| 17 | 17 | use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall; |
| 18 | 18 | use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; |
| 19 | use rustc_middle::ty::TypeVisitableExt; | |
| 20 | 19 | use rustc_middle::ty::layout::FnAbiOf; |
| 21 | 20 | use rustc_middle::ty::print::with_no_trimmed_paths; |
| 21 | use rustc_middle::ty::{ShimKind, TypeVisitableExt}; | |
| 22 | 22 | use rustc_session::Session; |
| 23 | 23 | use rustc_span::Spanned; |
| 24 | 24 | use rustc_target::callconv::{FnAbi, PassMode}; |
| ... | ... | @@ -467,7 +467,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( |
| 467 | 467 | } |
| 468 | 468 | // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, |
| 469 | 469 | // it is `func returning noop future` |
| 470 | InstanceKind::DropGlue(_, None) => { | |
| 470 | InstanceKind::Shim(ShimKind::DropGlue(_, None)) => { | |
| 471 | 471 | // empty drop glue - a nop. |
| 472 | 472 | let dest = target.expect("Non terminating drop_in_place_real???"); |
| 473 | 473 | let ret_block = fx.get_block(dest); |
| ... | ... | @@ -725,7 +725,7 @@ pub(crate) fn codegen_drop<'tcx>( |
| 725 | 725 | let ret_block = fx.get_block(target); |
| 726 | 726 | |
| 727 | 727 | // AsyncDropGlueCtorShim can't be here |
| 728 | if let ty::InstanceKind::DropGlue(_, None) = drop_instance.def { | |
| 728 | if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_instance.def { | |
| 729 | 729 | // we don't actually need to drop anything |
| 730 | 730 | fx.bcx.ins().jump(ret_block, &[]); |
| 731 | 731 | } else { |
compiler/rustc_codegen_cranelift/src/constant.rs+1-1| ... | ... | @@ -53,7 +53,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( |
| 53 | 53 | ) -> CValue<'tcx> { |
| 54 | 54 | let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { |
| 55 | 55 | let instance = ty::Instance { |
| 56 | def: ty::InstanceKind::ThreadLocalShim(def_id), | |
| 56 | def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), | |
| 57 | 57 | args: ty::GenericArgs::empty(), |
| 58 | 58 | }; |
| 59 | 59 | let func_ref = fx.get_function_ref(instance); |
compiler/rustc_codegen_ssa/src/back/symbol_export.rs+13-5| ... | ... | @@ -11,7 +11,9 @@ use rustc_middle::middle::exported_symbols::{ |
| 11 | 11 | ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, |
| 12 | 12 | }; |
| 13 | 13 | use rustc_middle::query::LocalCrate; |
| 14 | use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt}; | |
| 14 | use rustc_middle::ty::{ | |
| 15 | self, GenericArgKind, GenericArgsRef, Instance, ShimKind, SymbolName, Ty, TyCtxt, | |
| 16 | }; | |
| 15 | 17 | use rustc_middle::util::Providers; |
| 16 | 18 | use rustc_session::config::CrateType; |
| 17 | 19 | use rustc_span::Span; |
| ... | ... | @@ -332,7 +334,10 @@ fn exported_generic_symbols_provider_local<'tcx>( |
| 332 | 334 | )); |
| 333 | 335 | } |
| 334 | 336 | } |
| 335 | MonoItem::Fn(Instance { def: InstanceKind::DropGlue(_, Some(ty)), args }) => { | |
| 337 | MonoItem::Fn(Instance { | |
| 338 | def: InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))), | |
| 339 | args, | |
| 340 | }) => { | |
| 336 | 341 | // A little sanity-check |
| 337 | 342 | assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty))); |
| 338 | 343 | |
| ... | ... | @@ -356,7 +361,7 @@ fn exported_generic_symbols_provider_local<'tcx>( |
| 356 | 361 | } |
| 357 | 362 | } |
| 358 | 363 | MonoItem::Fn(Instance { |
| 359 | def: InstanceKind::AsyncDropGlueCtorShim(_, ty), | |
| 364 | def: InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, ty)), | |
| 360 | 365 | args, |
| 361 | 366 | }) => { |
| 362 | 367 | // A little sanity-check |
| ... | ... | @@ -371,7 +376,10 @@ fn exported_generic_symbols_provider_local<'tcx>( |
| 371 | 376 | }, |
| 372 | 377 | )); |
| 373 | 378 | } |
| 374 | MonoItem::Fn(Instance { def: InstanceKind::AsyncDropGlue(def, ty), args: _ }) => { | |
| 379 | MonoItem::Fn(Instance { | |
| 380 | def: InstanceKind::Shim(ShimKind::AsyncDropGlue(def, ty)), | |
| 381 | args: _, | |
| 382 | }) => { | |
| 375 | 383 | symbols.push(( |
| 376 | 384 | ExportedSymbol::AsyncDropGlue(def, ty), |
| 377 | 385 | SymbolExportInfo { |
| ... | ... | @@ -578,7 +586,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( |
| 578 | 586 | rustc_symbol_mangling::symbol_name_for_instance_in_crate( |
| 579 | 587 | tcx, |
| 580 | 588 | ty::Instance { |
| 581 | def: ty::InstanceKind::ThreadLocalShim(def_id), | |
| 589 | def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), | |
| 582 | 590 | args: ty::GenericArgs::empty(), |
| 583 | 591 | }, |
| 584 | 592 | instantiating_crate, |
compiler/rustc_codegen_ssa/src/mir/block.rs+6-3| ... | ... | @@ -618,7 +618,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
| 618 | 618 | let ty = self.monomorphize(ty); |
| 619 | 619 | let drop_fn = Instance::resolve_drop_glue(bx.tcx(), ty); |
| 620 | 620 | |
| 621 | if let ty::InstanceKind::DropGlue(_, None) = drop_fn.def { | |
| 621 | if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_fn.def { | |
| 622 | 622 | // we don't actually need to drop anything. |
| 623 | 623 | return helper.funclet_br(self, bx, target, mergeable_succ, &[]); |
| 624 | 624 | } |
| ... | ... | @@ -934,7 +934,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
| 934 | 934 | match instance.def { |
| 935 | 935 | // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, |
| 936 | 936 | // it is `func returning noop future` |
| 937 | ty::InstanceKind::DropGlue(_, None) => { | |
| 937 | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => { | |
| 938 | 938 | // Empty drop glue; a no-op. |
| 939 | 939 | let target = target.unwrap(); |
| 940 | 940 | return helper.funclet_br(self, bx, target, mergeable_succ, &[]); |
| ... | ... | @@ -1317,7 +1317,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
| 1317 | 1317 | } |
| 1318 | 1318 | LocalRef::Operand(arg) => { |
| 1319 | 1319 | let Ref(place_value) = arg.val else { |
| 1320 | bug!("only `Ref` should use `PassMode::Indirect`"); | |
| 1320 | bug!( | |
| 1321 | "only `Ref` should use `PassMode::Indirect`, but got {:?}", | |
| 1322 | arg.val | |
| 1323 | ); | |
| 1321 | 1324 | }; |
| 1322 | 1325 | bx.typed_place_copy(place_value, tmp.val, fn_abi.args[i].layout); |
| 1323 | 1326 | op.val = arg.val; |
compiler/rustc_codegen_ssa/src/mir/rvalue.rs+1-1| ... | ... | @@ -665,7 +665,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
| 665 | 665 | let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id) |
| 666 | 666 | { |
| 667 | 667 | let instance = ty::Instance { |
| 668 | def: ty::InstanceKind::ThreadLocalShim(def_id), | |
| 668 | def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), | |
| 669 | 669 | args: ty::GenericArgs::empty(), |
| 670 | 670 | }; |
| 671 | 671 | let fn_ptr = bx.get_fn_addr(instance); |
compiler/rustc_const_eval/src/interpret/call.rs+13-13| ... | ... | @@ -428,7 +428,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { |
| 428 | 428 | // Determine whether this is a non-capturing closure. That's relevant as their first |
| 429 | 429 | // argument can be skipped (and that's the only kind of argument skipping we allow). |
| 430 | 430 | let is_non_capturing_closure = |
| 431 | (matches!(instance.def, ty::InstanceKind::ClosureOnceShim { .. }) | |
| 431 | (matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. })) | |
| 432 | 432 | || self.tcx.is_closure_like(def_id)) |
| 433 | 433 | && { |
| 434 | 434 | let arg = &callee_fn_abi.args[0]; |
| ... | ... | @@ -652,18 +652,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { |
| 652 | 652 | interp_ok(()) |
| 653 | 653 | } |
| 654 | 654 | } |
| 655 | ty::InstanceKind::VTableShim(..) | |
| 656 | | ty::InstanceKind::ReifyShim(..) | |
| 657 | | ty::InstanceKind::ClosureOnceShim { .. } | |
| 658 | | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 659 | | ty::InstanceKind::FnPtrShim(..) | |
| 660 | | ty::InstanceKind::DropGlue(..) | |
| 661 | | ty::InstanceKind::CloneShim(..) | |
| 662 | | ty::InstanceKind::FnPtrAddrShim(..) | |
| 663 | | ty::InstanceKind::ThreadLocalShim(..) | |
| 664 | | ty::InstanceKind::AsyncDropGlueCtorShim(..) | |
| 665 | | ty::InstanceKind::AsyncDropGlue(..) | |
| 666 | | ty::InstanceKind::FutureDropPollShim(..) | |
| 655 | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) | |
| 656 | | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) | |
| 657 | | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) | |
| 658 | | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) | |
| 659 | | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) | |
| 660 | | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) | |
| 661 | | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) | |
| 662 | | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) | |
| 663 | | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) | |
| 664 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(..)) | |
| 665 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) | |
| 666 | | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | |
| 667 | 667 | | ty::InstanceKind::Item(_) => { |
| 668 | 668 | // We need MIR for this fn. |
| 669 | 669 | // Note that this can be an intrinsic, if we are executing its fallback body. |
compiler/rustc_const_eval/src/interpret/step.rs+1-1| ... | ... | @@ -607,7 +607,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { |
| 607 | 607 | enter_trace_span!(M, resolve::resolve_drop_glue, ty = ?place.layout.ty); |
| 608 | 608 | Instance::resolve_drop_glue(*self.tcx, place.layout.ty) |
| 609 | 609 | }; |
| 610 | if let ty::InstanceKind::DropGlue(_, None) = instance.def { | |
| 610 | if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = instance.def { | |
| 611 | 611 | // This is the branch we enter if and only if the dropped type has no drop glue |
| 612 | 612 | // whatsoever. This can happen as a result of monomorphizing a drop of a |
| 613 | 613 | // generic. In order to make sure that generic and non-generic code behaves |
compiler/rustc_error_codes/src/error_codes/E0718.md+3-1| ... | ... | @@ -1,8 +1,10 @@ |
| 1 | #### Note: this error code is no longer emitted by the compiler. | |
| 2 | ||
| 1 | 3 | A `#[lang = ".."]` attribute was placed on the wrong item type. |
| 2 | 4 | |
| 3 | 5 | Erroneous code example: |
| 4 | 6 | |
| 5 | ```compile_fail,E0718 | |
| 7 | ```compile_fail | |
| 6 | 8 | #![feature(lang_items)] |
| 7 | 9 | |
| 8 | 10 | #[lang = "owned_box"] |
compiler/rustc_hir/src/hir.rs+24-4| ... | ... | @@ -3852,14 +3852,34 @@ pub enum OpaqueTyOrigin<D> { |
| 3852 | 3852 | }, |
| 3853 | 3853 | } |
| 3854 | 3854 | |
| 3855 | #[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] | |
| 3856 | pub enum DelegationSelfTyPropagationKind { | |
| 3857 | /// Used when self type is explicitly specified in free-to-trait reuse | |
| 3858 | /// `reuse <() as Trait>::foo;`. | |
| 3859 | SelfTy(HirId /* Self ty id */), | |
| 3860 | /// Used when infer instead of a self type is specified or self type | |
| 3861 | /// is not specified at all: `reuse Trait::foo; reuse <_ as Trait>::foo;`. | |
| 3862 | SelfParam, | |
| 3863 | } | |
| 3864 | ||
| 3855 | 3865 | #[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] |
| 3856 | 3866 | pub struct DelegationInfo { |
| 3857 | 3867 | pub call_expr_id: HirId, |
| 3858 | 3868 | pub call_path_res: Option<DefId>, |
| 3859 | pub parent_args_segment_id: Option<HirId>, | |
| 3860 | pub child_args_segment_id: Option<HirId>, | |
| 3861 | pub self_ty_id: Option<HirId>, | |
| 3862 | pub propagate_self_ty: bool, | |
| 3869 | ||
| 3870 | /// Id of the child segment in delegation: `reuse Trait::foo`, | |
| 3871 | /// `child_seg_id` points to `foo`. | |
| 3872 | pub child_seg_id: HirId, | |
| 3873 | ||
| 3874 | /// Ids of parent and child segments, `Some` when we need to take | |
| 3875 | /// generic args of those segments for signature/predicates inheritance. | |
| 3876 | /// `None` in trait impl case or when error delegation is generated, meaning | |
| 3877 | /// we should not access those segments for generic args lowering. | |
| 3878 | /// When `child_seg_id_for_sig` is Some it always equals `child_seg_id`. | |
| 3879 | pub parent_seg_id_for_sig: Option<HirId>, | |
| 3880 | pub child_seg_id_for_sig: Option<HirId>, | |
| 3881 | ||
| 3882 | pub self_ty_propagation_kind: Option<DelegationSelfTyPropagationKind>, | |
| 3863 | 3883 | pub group_id: Option<(LocalExpnId, bool /* unused_target_expr */)>, |
| 3864 | 3884 | } |
| 3865 | 3885 |
compiler/rustc_hir_analysis/src/delegation.rs+83-157| ... | ... | @@ -5,16 +5,15 @@ |
| 5 | 5 | use std::debug_assert_matches; |
| 6 | 6 | |
| 7 | 7 | use rustc_data_structures::fx::FxHashMap; |
| 8 | use rustc_hir::PathSegment; | |
| 9 | 8 | use rustc_hir::def::DefKind; |
| 10 | 9 | use rustc_hir::def_id::{DefId, LocalDefId}; |
| 10 | use rustc_hir::{DelegationSelfTyPropagationKind, PathSegment}; | |
| 11 | 11 | use rustc_middle::ty::{ |
| 12 | 12 | self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, |
| 13 | 13 | }; |
| 14 | 14 | use rustc_span::{ErrorGuaranteed, Span, kw}; |
| 15 | 15 | |
| 16 | 16 | use crate::collect::ItemCtxt; |
| 17 | use crate::diagnostics::DelegationSelfTypeNotSpecified; | |
| 18 | 17 | use crate::hir_ty_lowering::HirTyLowerer; |
| 19 | 18 | |
| 20 | 19 | type RemapTable = FxHashMap<u32, u32>; |
| ... | ... | @@ -65,8 +64,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamIndexRemapper<'tcx> { |
| 65 | 64 | } |
| 66 | 65 | } |
| 67 | 66 | |
| 67 | #[derive(Debug)] | |
| 68 | 68 | enum SelfPositionKind { |
| 69 | AfterLifetimes(bool /* Should propagate self ty */), | |
| 69 | AfterLifetimes(Option<DelegationSelfTyPropagationKind>), | |
| 70 | 70 | Zero, |
| 71 | 71 | None, |
| 72 | 72 | } |
| ... | ... | @@ -83,8 +83,8 @@ fn create_self_position_kind( |
| 83 | 83 | | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero, |
| 84 | 84 | |
| 85 | 85 | (FnKind::Free, FnKind::AssocTrait) => { |
| 86 | let propagate_self_ty = tcx.hir_delegation_info(delegation_id).propagate_self_ty; | |
| 87 | SelfPositionKind::AfterLifetimes(propagate_self_ty) | |
| 86 | let kind = tcx.hir_delegation_info(delegation_id).self_ty_propagation_kind; | |
| 87 | SelfPositionKind::AfterLifetimes(kind) | |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | _ => SelfPositionKind::None, |
| ... | ... | @@ -268,28 +268,6 @@ fn get_parent_and_inheritance_kind<'tcx>( |
| 268 | 268 | } |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | fn get_delegation_self_ty_or_err(tcx: TyCtxt<'_>, delegation_id: LocalDefId) -> Ty<'_> { | |
| 272 | tcx.hir_delegation_info(delegation_id) | |
| 273 | .self_ty_id | |
| 274 | .map(|id| { | |
| 275 | let ctx = ItemCtxt::new(tcx, delegation_id); | |
| 276 | ctx.lower_ty(tcx.hir_node(id).expect_ty()) | |
| 277 | }) | |
| 278 | .unwrap_or_else(|| { | |
| 279 | // It is possible to attempt to get self type when it is used in signature | |
| 280 | // (i.e., `fn default() -> Self`), so emit error here in addition to possible | |
| 281 | // `mismatched types` error (see #156388). | |
| 282 | let err = DelegationSelfTypeNotSpecified { span: tcx.def_span(delegation_id) }; | |
| 283 | tcx.dcx().emit_err(err); | |
| 284 | ||
| 285 | Ty::new_error_with_message( | |
| 286 | tcx, | |
| 287 | tcx.def_span(delegation_id), | |
| 288 | "the self type must be specified", | |
| 289 | ) | |
| 290 | }) | |
| 291 | } | |
| 292 | ||
| 293 | 271 | fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option<Ty<'tcx>> { |
| 294 | 272 | let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id"); |
| 295 | 273 | let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); |
| ... | ... | @@ -302,14 +280,24 @@ fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> |
| 302 | 280 | | (FnKind::AssocTrait, FnKind::AssocTrait) => { |
| 303 | 281 | match create_self_position_kind(tcx, delegation_id, sig_id) { |
| 304 | 282 | SelfPositionKind::None => None, |
| 305 | SelfPositionKind::AfterLifetimes(propagate_self_ty) => { | |
| 306 | if propagate_self_ty { | |
| 307 | Some(get_delegation_self_ty_or_err(tcx, delegation_id)) | |
| 308 | } else { | |
| 309 | // Both sig parent and child lifetimes are in included in this count. | |
| 310 | let index = tcx.generics_of(delegation_id).own_counts().lifetimes; | |
| 311 | Some(Ty::new_param(tcx, index as u32, kw::SelfUpper)) | |
| 312 | } | |
| 283 | SelfPositionKind::AfterLifetimes(propagation_kind) => { | |
| 284 | Some(match propagation_kind { | |
| 285 | Some(kind) => match kind { | |
| 286 | DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => { | |
| 287 | let ctx = ItemCtxt::new(tcx, delegation_id); | |
| 288 | ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty()) | |
| 289 | } | |
| 290 | DelegationSelfTyPropagationKind::SelfParam => { | |
| 291 | let index = tcx.generics_of(delegation_id).own_counts().lifetimes; | |
| 292 | Ty::new_param(tcx, index as u32, kw::SelfUpper) | |
| 293 | } | |
| 294 | }, | |
| 295 | None => Ty::new_error_with_message( | |
| 296 | tcx, | |
| 297 | tcx.def_span(delegation_id), | |
| 298 | "self propagation kind must be specified for `AfterLifetimes` variant", | |
| 299 | ), | |
| 300 | }) | |
| 313 | 301 | } |
| 314 | 302 | SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)), |
| 315 | 303 | } |
| ... | ... | @@ -348,137 +336,69 @@ fn create_generic_args<'tcx>( |
| 348 | 336 | sig_id: DefId, |
| 349 | 337 | delegation_id: LocalDefId, |
| 350 | 338 | mut parent_args: &[ty::GenericArg<'tcx>], |
| 351 | child_args: &[ty::GenericArg<'tcx>], | |
| 339 | mut child_args: &[ty::GenericArg<'tcx>], | |
| 352 | 340 | ) -> Vec<ty::GenericArg<'tcx>> { |
| 353 | let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); | |
| 354 | ||
| 341 | let delegation_generics = tcx.generics_of(delegation_id); | |
| 355 | 342 | let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id); |
| 356 | 343 | |
| 357 | let deleg_parent_args_without_self_count = | |
| 358 | get_delegation_parent_args_count_without_self(tcx, delegation_id, sig_id); | |
| 359 | ||
| 360 | let delegation_generics = tcx.generics_of(delegation_id); | |
| 361 | 344 | let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count(); |
| 362 | 345 | let synth_args = &delegation_args[real_args_count..]; |
| 363 | let delegation_args = &delegation_args[..real_args_count]; | |
| 364 | ||
| 365 | let args = match (caller_kind, callee_kind) { | |
| 366 | (FnKind::Free, FnKind::Free) | |
| 367 | | (FnKind::Free, FnKind::AssocTrait) | |
| 368 | | (FnKind::AssocInherentImpl, FnKind::Free) | |
| 369 | | (FnKind::AssocTrait, FnKind::Free) | |
| 370 | | (FnKind::AssocTrait, FnKind::AssocTrait) => delegation_args, | |
| 371 | 346 | |
| 372 | (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { | |
| 373 | // Special case, as user specifies Trait args in trait impl header, we want to treat | |
| 374 | // them as parent args. We always generate a function whose generics match | |
| 375 | // child generics in trait. | |
| 376 | let parent = tcx.local_parent(delegation_id); | |
| 377 | parent_args = | |
| 378 | tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args; | |
| 379 | ||
| 380 | assert!(child_args.is_empty(), "Child args can not be used in trait impl case"); | |
| 381 | ||
| 382 | tcx.mk_args(&delegation_args[delegation_generics.parent_count..]) | |
| 383 | } | |
| 384 | ||
| 385 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { | |
| 386 | let self_ty = | |
| 387 | tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(); | |
| 347 | let mut delegation_parent_args = | |
| 348 | &delegation_args[delegation_generics.has_self as usize..delegation_generics.parent_count]; | |
| 388 | 349 | |
| 389 | tcx.mk_args_from_iter( | |
| 390 | std::iter::once(ty::GenericArg::from(self_ty)) | |
| 391 | .chain(delegation_args.iter().copied()), | |
| 392 | ) | |
| 393 | } | |
| 350 | let delegation_args = &delegation_args[delegation_generics.parent_count..]; | |
| 394 | 351 | |
| 395 | // For trait impl's `sig_id` is always equal to the corresponding trait method. | |
| 396 | // For inherent methods delegation is not yet supported. | |
| 397 | (FnKind::AssocTraitImpl, _) | |
| 398 | | (_, FnKind::AssocTraitImpl) | |
| 399 | | (_, FnKind::AssocInherentImpl) => unreachable!(), | |
| 400 | }; | |
| 352 | let kinds = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); | |
| 353 | if matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) { | |
| 354 | // Special case, as user specifies Trait args in trait impl header, we want to treat | |
| 355 | // them as parent args. We always generate a function whose generics match | |
| 356 | // child generics in trait. | |
| 357 | let parent = tcx.local_parent(delegation_id); | |
| 401 | 358 | |
| 402 | let mut new_args = vec![]; | |
| 359 | parent_args = | |
| 360 | tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args; | |
| 403 | 361 | |
| 404 | let self_pos_kind = create_self_position_kind(tcx, delegation_id, sig_id); | |
| 405 | let mut lifetimes_end_pos; | |
| 362 | child_args = | |
| 363 | &delegation_args[delegation_args.len() - delegation_generics.own_params.len()..]; | |
| 406 | 364 | |
| 407 | if !parent_args.is_empty() { | |
| 408 | let parent_args_lifetimes_count = | |
| 409 | parent_args.iter().filter(|a| a.as_region().is_some()).count(); | |
| 410 | ||
| 411 | match self_pos_kind { | |
| 412 | SelfPositionKind::AfterLifetimes { .. } => { | |
| 413 | new_args.extend(&parent_args[1..1 + parent_args_lifetimes_count]); | |
| 365 | delegation_parent_args = &[]; | |
| 366 | } | |
| 414 | 367 | |
| 415 | lifetimes_end_pos = parent_args_lifetimes_count; | |
| 368 | let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into()); | |
| 416 | 369 | |
| 417 | new_args.push(parent_args[0]); | |
| 370 | // Remove `Self` from parent args (it is always at the `0th` index) as it is | |
| 371 | // added manually. | |
| 372 | if self_type.is_some() && !parent_args.is_empty() { | |
| 373 | parent_args = &parent_args[1..]; | |
| 374 | } | |
| 418 | 375 | |
| 419 | new_args.extend(&parent_args[1 + parent_args_lifetimes_count..]); | |
| 376 | let (zero_self, after_lifetimes_self) = | |
| 377 | match create_self_position_kind(tcx, delegation_id, sig_id) { | |
| 378 | SelfPositionKind::AfterLifetimes(_) => { | |
| 379 | assert!(self_type.is_some()); | |
| 380 | (None, self_type) | |
| 420 | 381 | } |
| 421 | 382 | SelfPositionKind::Zero => { |
| 422 | lifetimes_end_pos = 1 /* Self */ + parent_args_lifetimes_count; | |
| 423 | new_args.extend_from_slice(parent_args); | |
| 424 | ||
| 425 | for i in 0..deleg_parent_args_without_self_count { | |
| 426 | new_args.insert(1 + i, args[1 + i]); | |
| 427 | } | |
| 428 | ||
| 429 | lifetimes_end_pos += deleg_parent_args_without_self_count; | |
| 383 | assert!(self_type.is_some()); | |
| 384 | (self_type, None) | |
| 430 | 385 | } |
| 431 | // If we have parent args then we obtained them from trait, then self must be somewhere | |
| 432 | SelfPositionKind::None => unreachable!(), | |
| 386 | SelfPositionKind::None => (None, None), | |
| 433 | 387 | }; |
| 434 | } else { | |
| 435 | let self_impact = matches!(self_pos_kind, SelfPositionKind::Zero) as usize; | |
| 436 | ||
| 437 | lifetimes_end_pos = self_impact | |
| 438 | + deleg_parent_args_without_self_count | |
| 439 | + &args[self_impact + deleg_parent_args_without_self_count..] | |
| 440 | .iter() | |
| 441 | .filter(|a| a.as_region().is_some()) | |
| 442 | .count(); | |
| 443 | ||
| 444 | new_args.extend_from_slice(args); | |
| 445 | ||
| 446 | // Parent args are empty, then if we should propagate self ty (meaning Self generic | |
| 447 | // param was not generated) then we should insert it, as it won't be in `args`. | |
| 448 | if matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(true)) { | |
| 449 | new_args.insert( | |
| 450 | lifetimes_end_pos, | |
| 451 | ty::GenericArg::from(get_delegation_self_ty_or_err(tcx, delegation_id)), | |
| 452 | ); | |
| 453 | } | |
| 454 | } | |
| 455 | ||
| 456 | if !child_args.is_empty() { | |
| 457 | let child_lifetimes_count = child_args.iter().filter(|a| a.as_region().is_some()).count(); | |
| 458 | ||
| 459 | for i in 0..child_lifetimes_count { | |
| 460 | new_args.insert(lifetimes_end_pos + i, child_args[i]); | |
| 461 | } | |
| 462 | 388 | |
| 463 | new_args.extend_from_slice(&child_args[child_lifetimes_count..]); | |
| 464 | } else if !parent_args.is_empty() { | |
| 465 | let child_args = &delegation_args[delegation_generics.parent_count..]; | |
| 466 | ||
| 467 | let child_lifetimes_count = | |
| 468 | child_args.iter().take_while(|a| a.as_region().is_some()).count(); | |
| 469 | ||
| 470 | for i in 0..child_lifetimes_count { | |
| 471 | new_args.insert(lifetimes_end_pos + i, child_args[i]); | |
| 472 | } | |
| 473 | ||
| 474 | // If self_ty is propagated it means that Self generic param was not generated. | |
| 475 | let skip_self = matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(false)); | |
| 476 | new_args.extend(&child_args[child_lifetimes_count + skip_self as usize..]); | |
| 477 | } | |
| 478 | ||
| 479 | new_args.extend(synth_args); | |
| 480 | ||
| 481 | new_args | |
| 389 | let zero_self = zero_self.as_ref().into_iter(); | |
| 390 | let after_lifetimes_self = after_lifetimes_self.as_ref().into_iter(); | |
| 391 | ||
| 392 | zero_self | |
| 393 | .chain(delegation_parent_args) | |
| 394 | .chain(parent_args.iter().filter(|a| a.as_region().is_some())) | |
| 395 | .chain(child_args.iter().filter(|a| a.as_region().is_some())) | |
| 396 | .chain(after_lifetimes_self) | |
| 397 | .chain(parent_args.iter().filter(|a| a.as_region().is_none())) | |
| 398 | .chain(child_args.iter().filter(|a| a.as_region().is_none())) | |
| 399 | .chain(synth_args) | |
| 400 | .copied() | |
| 401 | .collect::<Vec<_>>() | |
| 482 | 402 | } |
| 483 | 403 | |
| 484 | 404 | pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( |
| ... | ... | @@ -541,7 +461,10 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( |
| 541 | 461 | let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id); |
| 542 | 462 | let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args); |
| 543 | 463 | let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id); |
| 544 | let filter_self_preds = matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(true)); | |
| 464 | let filter_self_preds = matches!( | |
| 465 | self_pos_kind, | |
| 466 | SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..))) | |
| 467 | ); | |
| 545 | 468 | |
| 546 | 469 | let collector = PredicatesCollector { tcx, preds: vec![], args, folder, filter_self_preds }; |
| 547 | 470 | let (parent, inh_kind) = get_parent_and_inheritance_kind(tcx, def_id, sig_id); |
| ... | ... | @@ -640,18 +563,21 @@ pub(crate) fn delegation_user_specified_args<'tcx>( |
| 640 | 563 | |
| 641 | 564 | let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id); |
| 642 | 565 | let lowerer = ctx.lowerer(); |
| 566 | let parent_args = info | |
| 567 | .parent_seg_id_for_sig | |
| 568 | .and_then(get_segment) | |
| 569 | .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Trait)) | |
| 570 | .map(|(segment, def_id)| { | |
| 571 | let self_ty = get_delegation_self_ty(tcx, delegation_id); | |
| 643 | 572 | |
| 644 | let parent_args = info.parent_args_segment_id.and_then(get_segment).map(|(segment, def_id)| { | |
| 645 | let self_ty = get_delegation_self_ty(tcx, delegation_id); | |
| 646 | ||
| 647 | lowerer | |
| 648 | .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty) | |
| 649 | .0 | |
| 650 | .as_slice() | |
| 651 | }); | |
| 573 | lowerer | |
| 574 | .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty) | |
| 575 | .0 | |
| 576 | .as_slice() | |
| 577 | }); | |
| 652 | 578 | |
| 653 | 579 | let child_args = info |
| 654 | .child_args_segment_id | |
| 580 | .child_seg_id_for_sig | |
| 655 | 581 | .and_then(get_segment) |
| 656 | 582 | .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Fn | DefKind::AssocFn)) |
| 657 | 583 | .map(|(segment, def_id)| { |
compiler/rustc_hir_analysis/src/diagnostics.rs-8| ... | ... | @@ -1582,14 +1582,6 @@ pub(crate) struct UnsupportedDelegation<'a> { |
| 1582 | 1582 | pub callee_span: Span, |
| 1583 | 1583 | } |
| 1584 | 1584 | |
| 1585 | #[derive(Diagnostic)] | |
| 1586 | #[diag("delegation self type is not specified")] | |
| 1587 | #[help("consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`")] | |
| 1588 | pub(crate) struct DelegationSelfTypeNotSpecified { | |
| 1589 | #[primary_span] | |
| 1590 | pub span: Span, | |
| 1591 | } | |
| 1592 | ||
| 1593 | 1585 | #[derive(Diagnostic)] |
| 1594 | 1586 | #[diag("inferred lifetimes are not allowed in delegations as we need to inherit signature")] |
| 1595 | 1587 | pub(crate) struct ElidedLifetimesAreNotAllowedInDelegations { |
compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs+26-18| ... | ... | @@ -6,7 +6,7 @@ use rustc_errors::{ |
| 6 | 6 | }; |
| 7 | 7 | use rustc_hir::def::{DefKind, Res}; |
| 8 | 8 | use rustc_hir::def_id::DefId; |
| 9 | use rustc_hir::{self as hir, GenericArg}; | |
| 9 | use rustc_hir::{self as hir, DelegationInfo, GenericArg}; | |
| 10 | 10 | use rustc_middle::ty::{ |
| 11 | 11 | self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, |
| 12 | 12 | }; |
| ... | ... | @@ -430,8 +430,17 @@ pub(crate) fn check_generic_arg_count( |
| 430 | 430 | prohibit_assoc_item_constraint(cx, c, None); |
| 431 | 431 | } |
| 432 | 432 | |
| 433 | let explicit_late_bound = | |
| 434 | prohibit_explicit_late_bound_lifetimes(cx, gen_params, gen_args, gen_pos); | |
| 433 | let tcx = cx.tcx(); | |
| 434 | let parent_def = tcx.hir_get_parent_item(seg.hir_id).def_id; | |
| 435 | ||
| 436 | // Suppress this warning for delegations as it is compiler generated and lifetimes are | |
| 437 | // propagated while late-bound lifetimes may be present. | |
| 438 | let explicit_late_bound = match tcx.hir_opt_delegation_info(parent_def) { | |
| 439 | Some(DelegationInfo { child_seg_id, .. }) if seg.hir_id == *child_seg_id => { | |
| 440 | ExplicitLateBound::No | |
| 441 | } | |
| 442 | _ => prohibit_explicit_late_bound_lifetimes(cx, gen_params, gen_args, gen_pos), | |
| 443 | }; | |
| 435 | 444 | |
| 436 | 445 | let mut invalid_args = vec![]; |
| 437 | 446 | |
| ... | ... | @@ -458,7 +467,7 @@ pub(crate) fn check_generic_arg_count( |
| 458 | 467 | }; |
| 459 | 468 | |
| 460 | 469 | let reported = cx.dcx().emit_err(WrongNumberOfGenericArgs::new( |
| 461 | cx.tcx(), | |
| 470 | tcx, | |
| 462 | 471 | gen_args_info, |
| 463 | 472 | seg, |
| 464 | 473 | gen_params, |
| ... | ... | @@ -536,20 +545,19 @@ pub(crate) fn check_generic_arg_count( |
| 536 | 545 | .map(|param| param.name) |
| 537 | 546 | .collect(); |
| 538 | 547 | if constraint_names == param_names { |
| 539 | let has_assoc_ty_with_same_name = | |
| 540 | if let DefKind::Trait = cx.tcx().def_kind(def_id) { | |
| 541 | gen_args.constraints.iter().any(|constraint| { | |
| 542 | traits::supertrait_def_ids(cx.tcx(), def_id).any(|trait_did| { | |
| 543 | cx.probe_trait_that_defines_assoc_item( | |
| 544 | trait_did, | |
| 545 | ty::AssocTag::Type, | |
| 546 | constraint.ident, | |
| 547 | ) | |
| 548 | }) | |
| 548 | let has_assoc_ty_with_same_name = if let DefKind::Trait = tcx.def_kind(def_id) { | |
| 549 | gen_args.constraints.iter().any(|constraint| { | |
| 550 | traits::supertrait_def_ids(tcx, def_id).any(|trait_did| { | |
| 551 | cx.probe_trait_that_defines_assoc_item( | |
| 552 | trait_did, | |
| 553 | ty::AssocTag::Type, | |
| 554 | constraint.ident, | |
| 555 | ) | |
| 549 | 556 | }) |
| 550 | } else { | |
| 551 | false | |
| 552 | }; | |
| 557 | }) | |
| 558 | } else { | |
| 559 | false | |
| 560 | }; | |
| 553 | 561 | // We set this to true and delay emitting `WrongNumberOfGenericArgs` |
| 554 | 562 | // to provide a succinct error for cases like issue #113073, |
| 555 | 563 | // but only if when we don't have any assoc type with the same name with a |
| ... | ... | @@ -573,7 +581,7 @@ pub(crate) fn check_generic_arg_count( |
| 573 | 581 | let reported = gen_args.has_err().unwrap_or_else(|| { |
| 574 | 582 | cx.dcx() |
| 575 | 583 | .create_err(WrongNumberOfGenericArgs::new( |
| 576 | cx.tcx(), | |
| 584 | tcx, | |
| 577 | 585 | gen_args_info, |
| 578 | 586 | seg, |
| 579 | 587 | gen_params, |
compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs+15-1| ... | ... | @@ -2522,15 +2522,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 2522 | 2522 | ) -> Const<'tcx> { |
| 2523 | 2523 | let tcx = self.tcx(); |
| 2524 | 2524 | |
| 2525 | let found_tuple = || { | |
| 2526 | tcx.sess | |
| 2527 | .source_map() | |
| 2528 | .span_to_snippet(span) | |
| 2529 | .map(|snippet| format!("`{snippet}`")) | |
| 2530 | .unwrap_or_else(|_| "const tuple".to_string()) | |
| 2531 | }; | |
| 2532 | ||
| 2525 | 2533 | let tys = match ty.kind() { |
| 2526 | 2534 | ty::Tuple(tys) => tys, |
| 2527 | 2535 | ty::Error(e) => return Const::new_error(tcx, *e), |
| 2528 | 2536 | _ => { |
| 2529 | let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty)); | |
| 2537 | let e = | |
| 2538 | tcx.dcx().span_err(span, format!("expected `{}`, found {}", ty, found_tuple())); | |
| 2530 | 2539 | return Const::new_error(tcx, e); |
| 2531 | 2540 | } |
| 2532 | 2541 | }; |
| 2533 | 2542 | |
| 2543 | if exprs.len() != tys.len() { | |
| 2544 | let e = tcx.dcx().span_err(span, format!("expected `{}`, found {}", ty, found_tuple())); | |
| 2545 | return Const::new_error(tcx, e); | |
| 2546 | } | |
| 2547 | ||
| 2534 | 2548 | let exprs = exprs |
| 2535 | 2549 | .iter() |
| 2536 | 2550 | .zip(tys.iter()) |
compiler/rustc_hir_typeck/src/cast.rs+20-1| ... | ... | @@ -739,9 +739,21 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 739 | 739 | ); |
| 740 | 740 | } |
| 741 | 741 | |
| 742 | fn expr_span_for_type_resolution(&self, fcx: &FnCtxt<'a, 'tcx>) -> Span { | |
| 743 | if let hir::ExprKind::Index(_, idx, _) = self.expr.kind | |
| 744 | && fcx.resolve_vars_if_possible(self.expr_ty).is_ty_var() | |
| 745 | && fcx.resolve_vars_if_possible(fcx.node_ty(idx.hir_id)).is_ty_var() | |
| 746 | { | |
| 747 | index_operand_ambiguity_span(idx) | |
| 748 | } else { | |
| 749 | self.expr_span | |
| 750 | } | |
| 751 | } | |
| 752 | ||
| 742 | 753 | #[instrument(skip(fcx), level = "debug")] |
| 743 | 754 | pub(crate) fn check(mut self, fcx: &FnCtxt<'a, 'tcx>) { |
| 744 | self.expr_ty = fcx.structurally_resolve_type(self.expr_span, self.expr_ty); | |
| 755 | let expr_span = self.expr_span_for_type_resolution(fcx); | |
| 756 | self.expr_ty = fcx.structurally_resolve_type(expr_span, self.expr_ty); | |
| 745 | 757 | self.cast_ty = fcx.structurally_resolve_type(self.cast_span, self.cast_ty); |
| 746 | 758 | |
| 747 | 759 | debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty); |
| ... | ... | @@ -1169,3 +1181,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 1169 | 1181 | } |
| 1170 | 1182 | } |
| 1171 | 1183 | } |
| 1184 | ||
| 1185 | fn index_operand_ambiguity_span(expr: &hir::Expr<'_>) -> Span { | |
| 1186 | match expr.kind { | |
| 1187 | hir::ExprKind::MethodCall(segment, ..) => segment.ident.span, | |
| 1188 | _ => expr.span, | |
| 1189 | } | |
| 1190 | } |
compiler/rustc_hir_typeck/src/check.rs+1-1| ... | ... | @@ -90,7 +90,7 @@ pub(super) fn check_fn<'a, 'tcx>( |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | // Check that argument is Sized. |
| 93 | if !params_can_be_unsized { | |
| 93 | if !params_can_be_unsized || fn_sig.abi() == rustc_abi::ExternAbi::RustTail { | |
| 94 | 94 | fcx.require_type_is_sized( |
| 95 | 95 | param_ty, |
| 96 | 96 | param.ty_span, |
compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs+121-1| ... | ... | @@ -4,8 +4,11 @@ use rustc_hir as hir; |
| 4 | 4 | use rustc_hir::def::{DefKind, Res}; |
| 5 | 5 | use rustc_hir::def_id::DefId; |
| 6 | 6 | use rustc_infer::traits::ObligationCauseCode; |
| 7 | use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; | |
| 7 | use rustc_middle::ty::{ | |
| 8 | self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, | |
| 9 | }; | |
| 8 | 10 | use rustc_span::{Span, kw}; |
| 11 | use rustc_trait_selection::infer::InferCtxtExt; | |
| 9 | 12 | use rustc_trait_selection::traits; |
| 10 | 13 | |
| 11 | 14 | use crate::FnCtxt; |
| ... | ... | @@ -37,6 +40,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 37 | 40 | &self, |
| 38 | 41 | error: &mut traits::FulfillmentError<'tcx>, |
| 39 | 42 | ) -> bool { |
| 43 | if self.adjust_binop_index_operand(error) { | |
| 44 | return true; | |
| 45 | } | |
| 46 | ||
| 40 | 47 | let (def_id, hir_id, idx, flavor) = match *error.obligation.cause.code().peel_derives() { |
| 41 | 48 | ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) => { |
| 42 | 49 | (def_id, hir_id, idx, ClauseFlavor::Where) |
| ... | ... | @@ -165,6 +172,119 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 165 | 172 | } |
| 166 | 173 | } |
| 167 | 174 | |
| 175 | fn adjust_binop_index_operand(&self, error: &mut traits::FulfillmentError<'tcx>) -> bool { | |
| 176 | let ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, .. } = | |
| 177 | *error.obligation.cause.code().peel_derives() | |
| 178 | else { | |
| 179 | return false; | |
| 180 | }; | |
| 181 | if !matches!(error.code, traits::FulfillmentErrorCode::Ambiguity { .. }) | |
| 182 | || !error.obligation.predicate.has_infer() | |
| 183 | { | |
| 184 | return false; | |
| 185 | } | |
| 186 | ||
| 187 | let hir::Node::Expr(lhs_expr) = self.tcx.hir_node(lhs_hir_id) else { | |
| 188 | return false; | |
| 189 | }; | |
| 190 | let hir::Node::Expr(rhs_expr) = self.tcx.hir_node(rhs_hir_id) else { | |
| 191 | return false; | |
| 192 | }; | |
| 193 | let Some(binop) = self.binop_for_operands(lhs_hir_id, rhs_hir_id) else { | |
| 194 | return false; | |
| 195 | }; | |
| 196 | let hir::ExprKind::Index(indexed_expr, idx, _) = rhs_expr.kind else { | |
| 197 | return false; | |
| 198 | }; | |
| 199 | if !self.resolve_vars_if_possible(self.node_ty(idx.hir_id)).is_ty_var() { | |
| 200 | return false; | |
| 201 | } | |
| 202 | let lhs_ty = self.resolve_vars_if_possible(self.node_ty(lhs_expr.hir_id)); | |
| 203 | let indexed_ty = self.resolve_vars_if_possible(self.node_ty(indexed_expr.hir_id)); | |
| 204 | let rhs_ty = match *indexed_ty.kind() { | |
| 205 | ty::Array(element_ty, _) | ty::Slice(element_ty) => element_ty, | |
| 206 | ty::Ref(_, pointee_ty, _) => match *pointee_ty.kind() { | |
| 207 | ty::Array(element_ty, _) | ty::Slice(element_ty) => element_ty, | |
| 208 | _ => self.resolve_vars_if_possible(self.node_ty(rhs_expr.hir_id)), | |
| 209 | }, | |
| 210 | _ => self.resolve_vars_if_possible(self.node_ty(rhs_expr.hir_id)), | |
| 211 | }; | |
| 212 | if !self.binop_accepts_types(binop.node, lhs_ty, rhs_ty) { | |
| 213 | return false; | |
| 214 | } | |
| 215 | ||
| 216 | error.obligation.cause.span = match idx.kind { | |
| 217 | hir::ExprKind::MethodCall(segment, ..) => segment.ident.span, | |
| 218 | _ => idx.span, | |
| 219 | }; | |
| 220 | true | |
| 221 | } | |
| 222 | ||
| 223 | fn binop_for_operands( | |
| 224 | &self, | |
| 225 | lhs_hir_id: hir::HirId, | |
| 226 | rhs_hir_id: hir::HirId, | |
| 227 | ) -> Option<hir::BinOp> { | |
| 228 | let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(rhs_hir_id) else { | |
| 229 | return None; | |
| 230 | }; | |
| 231 | let hir::ExprKind::Binary(binop, lhs_expr, rhs_expr) = parent_expr.kind else { | |
| 232 | return None; | |
| 233 | }; | |
| 234 | (lhs_expr.hir_id == lhs_hir_id && rhs_expr.hir_id == rhs_hir_id).then_some(binop) | |
| 235 | } | |
| 236 | ||
| 237 | fn binop_accepts_types( | |
| 238 | &self, | |
| 239 | binop: hir::BinOpKind, | |
| 240 | lhs_ty: Ty<'tcx>, | |
| 241 | rhs_ty: Ty<'tcx>, | |
| 242 | ) -> bool { | |
| 243 | let lhs_ty = self.deref_ty_if_possible(lhs_ty); | |
| 244 | let rhs_ty = self.deref_ty_if_possible(rhs_ty); | |
| 245 | if lhs_ty.references_error() || rhs_ty.references_error() { | |
| 246 | return true; | |
| 247 | } | |
| 248 | ||
| 249 | match binop { | |
| 250 | hir::BinOpKind::Shl | hir::BinOpKind::Shr => { | |
| 251 | lhs_ty.is_integral() && rhs_ty.is_integral() | |
| 252 | } | |
| 253 | hir::BinOpKind::Add | |
| 254 | | hir::BinOpKind::Sub | |
| 255 | | hir::BinOpKind::Mul | |
| 256 | | hir::BinOpKind::Div | |
| 257 | | hir::BinOpKind::Rem => { | |
| 258 | self.can_eq(self.param_env, lhs_ty, rhs_ty) | |
| 259 | && (lhs_ty.is_integral() || lhs_ty.is_floating_point()) | |
| 260 | && (rhs_ty.is_integral() || rhs_ty.is_floating_point()) | |
| 261 | } | |
| 262 | hir::BinOpKind::BitXor | hir::BinOpKind::BitAnd | hir::BinOpKind::BitOr => { | |
| 263 | self.can_eq(self.param_env, lhs_ty, rhs_ty) | |
| 264 | && ((lhs_ty.is_integral() && rhs_ty.is_integral()) | |
| 265 | || (lhs_ty.is_bool() && rhs_ty.is_bool())) | |
| 266 | } | |
| 267 | hir::BinOpKind::Eq | |
| 268 | | hir::BinOpKind::Ne | |
| 269 | | hir::BinOpKind::Lt | |
| 270 | | hir::BinOpKind::Le | |
| 271 | | hir::BinOpKind::Ge | |
| 272 | | hir::BinOpKind::Gt => { | |
| 273 | self.can_eq(self.param_env, lhs_ty, rhs_ty) | |
| 274 | && lhs_ty.is_scalar() | |
| 275 | && rhs_ty.is_scalar() | |
| 276 | } | |
| 277 | hir::BinOpKind::And | hir::BinOpKind::Or => lhs_ty.is_bool() && rhs_ty.is_bool(), | |
| 278 | } | |
| 279 | } | |
| 280 | ||
| 281 | fn deref_ty_if_possible(&self, ty: Ty<'tcx>) -> Ty<'tcx> { | |
| 282 | match ty.kind() { | |
| 283 | ty::Ref(_, ty, hir::Mutability::Not) => *ty, | |
| 284 | _ => ty, | |
| 285 | } | |
| 286 | } | |
| 287 | ||
| 168 | 288 | fn point_at_expr_if_possible( |
| 169 | 289 | &self, |
| 170 | 290 | error: &mut traits::FulfillmentError<'tcx>, |
compiler/rustc_hir_typeck/src/op.rs+1| ... | ... | @@ -313,6 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 313 | 313 | } |
| 314 | 314 | |
| 315 | 315 | self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); |
| 316 | ||
| 316 | 317 | method.sig.output() |
| 317 | 318 | } |
| 318 | 319 | // error types are considered "builtin" |
compiler/rustc_hir_typeck/src/writeback.rs+1-1| ... | ... | @@ -348,7 +348,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { |
| 348 | 348 | fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx, AmbigArg>) { |
| 349 | 349 | intravisit::walk_ty(self, hir_ty); |
| 350 | 350 | // If there are type checking errors, Type privacy pass will stop, |
| 351 | // so we may not get the type from hid_id, see #104513 | |
| 351 | // so we may not get the type from hir_id, see #104513 | |
| 352 | 352 | if let Some(ty) = self.fcx.node_ty_opt(hir_ty.hir_id) { |
| 353 | 353 | let ty = self.resolve(ty, &hir_ty.span); |
| 354 | 354 | self.write_ty_to_typeck_results(hir_ty.hir_id, ty); |
compiler/rustc_middle/src/middle/codegen_fn_attrs.rs+7-4| ... | ... | @@ -8,7 +8,7 @@ use rustc_span::Symbol; |
| 8 | 8 | use rustc_target::spec::SanitizerSet; |
| 9 | 9 | |
| 10 | 10 | use crate::mono::Visibility; |
| 11 | use crate::ty::{InstanceKind, TyCtxt}; | |
| 11 | use crate::ty::{InstanceKind, ShimKind, TyCtxt}; | |
| 12 | 12 | |
| 13 | 13 | impl<'tcx> TyCtxt<'tcx> { |
| 14 | 14 | pub fn codegen_instance_attrs( |
| ... | ... | @@ -33,7 +33,7 @@ impl<'tcx> TyCtxt<'tcx> { |
| 33 | 33 | // |
| 34 | 34 | // A `ClosureOnceShim` with the track_caller attribute does not have a symbol, |
| 35 | 35 | // and therefore can be skipped here. |
| 36 | if let InstanceKind::ReifyShim(_, _) = instance_kind | |
| 36 | if let InstanceKind::Shim(ShimKind::Reify(_, _)) = instance_kind | |
| 37 | 37 | && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER) |
| 38 | 38 | { |
| 39 | 39 | if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { |
| ... | ... | @@ -54,8 +54,11 @@ impl<'tcx> TyCtxt<'tcx> { |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | // Ensure closure shims have the optimization properties of their closure applied to them. |
| 57 | if let InstanceKind::ClosureOnceShim { call_once: _, closure, track_caller: _ } = | |
| 58 | instance_kind | |
| 57 | if let InstanceKind::Shim(ShimKind::ClosureOnce { | |
| 58 | call_once: _, | |
| 59 | closure, | |
| 60 | track_caller: _, | |
| 61 | }) = instance_kind | |
| 59 | 62 | { |
| 60 | 63 | let closure_attrs = self.codegen_fn_attrs(closure); |
| 61 | 64 | attrs.to_mut().optimize = closure_attrs.optimize; |
compiler/rustc_middle/src/middle/exported_symbols.rs+1-1| ... | ... | @@ -75,7 +75,7 @@ impl<'tcx> ExportedSymbol<'tcx> { |
| 75 | 75 | tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty)) |
| 76 | 76 | } |
| 77 | 77 | ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance { |
| 78 | def: ty::InstanceKind::ThreadLocalShim(def_id), | |
| 78 | def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), | |
| 79 | 79 | args: ty::GenericArgs::empty(), |
| 80 | 80 | }), |
| 81 | 81 | ExportedSymbol::NoDefId(symbol_name) => symbol_name, |
compiler/rustc_middle/src/mir/mod.rs+4-4| ... | ... | @@ -32,8 +32,8 @@ use crate::mir::interpret::{AllocRange, Scalar}; |
| 32 | 32 | use crate::ty::codec::{TyDecoder, TyEncoder}; |
| 33 | 33 | use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; |
| 34 | 34 | use crate::ty::{ |
| 35 | self, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypeVisitableExt, | |
| 36 | TypingEnv, UserTypeAnnotationIndex, | |
| 35 | self, GenericArg, GenericArgsRef, Instance, InstanceKind, List, ShimKind, Ty, TyCtxt, | |
| 36 | TypeVisitableExt, TypingEnv, UserTypeAnnotationIndex, | |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | 39 | mod basic_blocks; |
| ... | ... | @@ -127,8 +127,8 @@ impl<'tcx> MirSource<'tcx> { |
| 127 | 127 | MirSource { instance: InstanceKind::Item(def_id), promoted: None } |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | pub fn from_instance(instance: InstanceKind<'tcx>) -> Self { | |
| 131 | MirSource { instance, promoted: None } | |
| 130 | pub fn from_shim(shim: ShimKind<'tcx>) -> Self { | |
| 131 | MirSource { instance: InstanceKind::Shim(shim), promoted: None } | |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | 134 | #[inline] |
compiler/rustc_middle/src/mir/pretty.rs+4-4| ... | ... | @@ -218,7 +218,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { |
| 218 | 218 | // All drop shims have the same DefId, so we have to add the type |
| 219 | 219 | // to get unique file names. |
| 220 | 220 | let shim_disambiguator = match source.instance { |
| 221 | ty::InstanceKind::DropGlue(_, Some(ty)) => { | |
| 221 | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) => { | |
| 222 | 222 | // Unfortunately, pretty-printed types are not very filename-friendly. |
| 223 | 223 | // We do some filtering. |
| 224 | 224 | let mut s = ".".to_owned(); |
| ... | ... | @@ -229,7 +229,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { |
| 229 | 229 | })); |
| 230 | 230 | s |
| 231 | 231 | } |
| 232 | ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => { | |
| 232 | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, ty)) => { | |
| 233 | 233 | let mut s = ".".to_owned(); |
| 234 | 234 | s.extend(ty.to_string().chars().filter_map(|c| match c { |
| 235 | 235 | ' ' => None, |
| ... | ... | @@ -238,7 +238,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { |
| 238 | 238 | })); |
| 239 | 239 | s |
| 240 | 240 | } |
| 241 | ty::InstanceKind::AsyncDropGlue(_, ty) => { | |
| 241 | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) => { | |
| 242 | 242 | let ty::Coroutine(_, args) = ty.kind() else { |
| 243 | 243 | bug!(); |
| 244 | 244 | }; |
| ... | ... | @@ -251,7 +251,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { |
| 251 | 251 | })); |
| 252 | 252 | s |
| 253 | 253 | } |
| 254 | ty::InstanceKind::FutureDropPollShim(_, proxy_cor, impl_cor) => { | |
| 254 | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, proxy_cor, impl_cor)) => { | |
| 255 | 255 | let mut s = ".".to_owned(); |
| 256 | 256 | s.extend(proxy_cor.to_string().chars().filter_map(|c| match c { |
| 257 | 257 | ' ' => None, |
compiler/rustc_middle/src/mir/visit.rs+15-15| ... | ... | @@ -347,27 +347,27 @@ macro_rules! make_mir_visitor { |
| 347 | 347 | ty::InstanceKind::Item(_def_id) => {} |
| 348 | 348 | |
| 349 | 349 | ty::InstanceKind::Intrinsic(_def_id) |
| 350 | | ty::InstanceKind::VTableShim(_def_id) | |
| 351 | | ty::InstanceKind::ReifyShim(_def_id, _) | |
| 350 | | ty::InstanceKind::Shim(ty::ShimKind::VTable(_def_id)) | |
| 351 | | ty::InstanceKind::Shim(ty::ShimKind::Reify(_def_id, _)) | |
| 352 | 352 | | ty::InstanceKind::Virtual(_def_id, _) |
| 353 | | ty::InstanceKind::ThreadLocalShim(_def_id) | |
| 354 | | ty::InstanceKind::ClosureOnceShim { call_once: _def_id, closure: _, track_caller: _ } | |
| 355 | | ty::InstanceKind::ConstructCoroutineInClosureShim { | |
| 353 | | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_def_id)) | |
| 354 | | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { call_once: _def_id, closure: _, track_caller: _ }) | |
| 355 | | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { | |
| 356 | 356 | coroutine_closure_def_id: _def_id, |
| 357 | 357 | receiver_by_ref: _, |
| 358 | } | |
| 359 | | ty::InstanceKind::DropGlue(_def_id, None) => {} | |
| 360 | ||
| 361 | ty::InstanceKind::FnPtrShim(_def_id, ty) | |
| 362 | | ty::InstanceKind::DropGlue(_def_id, Some(ty)) | |
| 363 | | ty::InstanceKind::CloneShim(_def_id, ty) | |
| 364 | | ty::InstanceKind::FnPtrAddrShim(_def_id, ty) | |
| 365 | | ty::InstanceKind::AsyncDropGlue(_def_id, ty) | |
| 366 | | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, ty) => { | |
| 358 | }) | |
| 359 | | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, None)) => {} | |
| 360 | ||
| 361 | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(_def_id, ty)) | |
| 362 | | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, Some(ty))) | |
| 363 | | ty::InstanceKind::Shim(ty::ShimKind::Clone(_def_id, ty)) | |
| 364 | | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(_def_id, ty)) | |
| 365 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_def_id, ty)) | |
| 366 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_def_id, ty)) => { | |
| 367 | 367 | // FIXME(eddyb) use a better `TyContext` here. |
| 368 | 368 | self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); |
| 369 | 369 | } |
| 370 | ty::InstanceKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty) => { | |
| 370 | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_def_id, proxy_ty, impl_ty)) => { | |
| 371 | 371 | self.visit_ty($(& $mutability)? *proxy_ty, TyContext::Location(location)); |
| 372 | 372 | self.visit_ty($(& $mutability)? *impl_ty, TyContext::Location(location)); |
| 373 | 373 | } |
compiler/rustc_middle/src/mono.rs+15-15| ... | ... | @@ -22,7 +22,7 @@ use tracing::debug; |
| 22 | 22 | use crate::dep_graph::dep_node::{make_compile_codegen_unit, make_compile_mono_item}; |
| 23 | 23 | use crate::dep_graph::{DepNode, WorkProduct, WorkProductId}; |
| 24 | 24 | use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; |
| 25 | use crate::ty::{self, GenericArgs, Instance, InstanceKind, SymbolName, Ty, TyCtxt}; | |
| 25 | use crate::ty::{self, GenericArgs, Instance, InstanceKind, ShimKind, SymbolName, Ty, TyCtxt}; | |
| 26 | 26 | |
| 27 | 27 | /// Describes how a monomorphization will be instantiated in object files. |
| 28 | 28 | #[derive(PartialEq)] |
| ... | ... | @@ -173,7 +173,7 @@ impl<'tcx> MonoItem<'tcx> { |
| 173 | 173 | // incrementality (which wants small CGUs with as many things GloballyShared as possible). |
| 174 | 174 | // The heuristics implemented here do better than a completely naive approach in the |
| 175 | 175 | // compiler benchmark suite, but there is no reason to believe they are optimal. |
| 176 | if let InstanceKind::DropGlue(_, Some(ty)) = instance.def { | |
| 176 | if let InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))) = instance.def { | |
| 177 | 177 | if tcx.sess.opts.optimize == OptLevel::No { |
| 178 | 178 | return InstantiationMode::GloballyShared { may_conflict: false }; |
| 179 | 179 | } |
| ... | ... | @@ -523,20 +523,20 @@ impl<'tcx> CodegenUnit<'tcx> { |
| 523 | 523 | match item { |
| 524 | 524 | MonoItem::Fn(ref instance) => match instance.def { |
| 525 | 525 | InstanceKind::Item(def) => def.as_local().map(|_| def), |
| 526 | InstanceKind::VTableShim(..) | |
| 527 | | InstanceKind::ReifyShim(..) | |
| 528 | | InstanceKind::Intrinsic(..) | |
| 529 | | InstanceKind::FnPtrShim(..) | |
| 526 | InstanceKind::Intrinsic(..) | |
| 530 | 527 | | InstanceKind::Virtual(..) |
| 531 | | InstanceKind::ClosureOnceShim { .. } | |
| 532 | | InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 533 | | InstanceKind::DropGlue(..) | |
| 534 | | InstanceKind::CloneShim(..) | |
| 535 | | InstanceKind::ThreadLocalShim(..) | |
| 536 | | InstanceKind::FnPtrAddrShim(..) | |
| 537 | | InstanceKind::AsyncDropGlue(..) | |
| 538 | | InstanceKind::FutureDropPollShim(..) | |
| 539 | | InstanceKind::AsyncDropGlueCtorShim(..) => None, | |
| 528 | | InstanceKind::Shim(ShimKind::VTable(..)) | |
| 529 | | InstanceKind::Shim(ShimKind::Reify(..)) | |
| 530 | | InstanceKind::Shim(ShimKind::FnPtr(..)) | |
| 531 | | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) | |
| 532 | | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | |
| 533 | | InstanceKind::Shim(ShimKind::DropGlue(..)) | |
| 534 | | InstanceKind::Shim(ShimKind::Clone(..)) | |
| 535 | | InstanceKind::Shim(ShimKind::ThreadLocal(..)) | |
| 536 | | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) | |
| 537 | | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) | |
| 538 | | InstanceKind::Shim(ShimKind::FutureDropPoll(..)) | |
| 539 | | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => None, | |
| 540 | 540 | }, |
| 541 | 541 | MonoItem::Static(def_id) => def_id.as_local().map(|_| def_id), |
| 542 | 542 | MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.to_def_id()), |
compiler/rustc_middle/src/queries.rs+2-2| ... | ... | @@ -1400,10 +1400,10 @@ rustc_queries! { |
| 1400 | 1400 | } |
| 1401 | 1401 | |
| 1402 | 1402 | /// Generates a MIR body for the shim. |
| 1403 | query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> { | |
| 1403 | query mir_shims(key: ty::ShimKind<'tcx>) -> &'tcx mir::Body<'tcx> { | |
| 1404 | 1404 | arena_cache |
| 1405 | 1405 | desc { |
| 1406 | "generating MIR shim for `{}`, instance={:?}", | |
| 1406 | "generating MIR shim for `{}`, kind={:?}", | |
| 1407 | 1407 | tcx.def_path_str(key.def_id()), |
| 1408 | 1408 | key |
| 1409 | 1409 | } |
compiler/rustc_middle/src/query/keys.rs+6| ... | ... | @@ -63,6 +63,12 @@ impl QueryKey for () { |
| 63 | 63 | } |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | impl<'tcx> QueryKey for ty::ShimKind<'tcx> { | |
| 67 | fn default_span(&self, tcx: TyCtxt<'_>) -> Span { | |
| 68 | tcx.def_span(self.def_id()) | |
| 69 | } | |
| 70 | } | |
| 71 | ||
| 66 | 72 | impl<'tcx> QueryKey for ty::InstanceKind<'tcx> { |
| 67 | 73 | fn default_span(&self, tcx: TyCtxt<'_>) -> Span { |
| 68 | 74 | tcx.def_span(self.def_id()) |
compiler/rustc_middle/src/ty/instance.rs+155-102| ... | ... | @@ -75,12 +75,28 @@ pub enum InstanceKind<'tcx> { |
| 75 | 75 | /// caller. |
| 76 | 76 | Intrinsic(DefId), |
| 77 | 77 | |
| 78 | /// Dynamic dispatch to `<dyn Trait as Trait>::fn`. | |
| 79 | /// | |
| 80 | /// This `InstanceKind` may have a callable MIR as the default implementation. | |
| 81 | /// Calls to `Virtual` instances must be codegen'd as virtual calls through the vtable. | |
| 82 | /// *This means we might not know exactly what is being called.* | |
| 83 | /// | |
| 84 | /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more | |
| 85 | /// details on that). | |
| 86 | Virtual(DefId, usize), | |
| 87 | ||
| 88 | Shim(ShimKind<'tcx>), | |
| 89 | } | |
| 90 | ||
| 91 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | |
| 92 | #[derive(TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable, Lift)] | |
| 93 | pub enum ShimKind<'tcx> { | |
| 78 | 94 | /// `<T as Trait>::method` where `method` receives unsizeable `self: Self` (part of the |
| 79 | 95 | /// `unsized_fn_params` feature). |
| 80 | 96 | /// |
| 81 | 97 | /// The generated shim will take `Self` via `*mut Self` - conceptually this is `&owned Self` - |
| 82 | 98 | /// and dereference the argument to call the original function. |
| 83 | VTableShim(DefId), | |
| 99 | VTable(DefId), | |
| 84 | 100 | |
| 85 | 101 | /// `fn()` pointer where the function itself cannot be turned into a pointer. |
| 86 | 102 | /// |
| ... | ... | @@ -99,22 +115,12 @@ pub enum InstanceKind<'tcx> { |
| 99 | 115 | /// |
| 100 | 116 | /// This field will only be populated if we are compiling in a mode that needs these shims |
| 101 | 117 | /// to be separable, currently only when KCFI is enabled. |
| 102 | ReifyShim(DefId, Option<ReifyReason>), | |
| 118 | Reify(DefId, Option<ReifyReason>), | |
| 103 | 119 | |
| 104 | 120 | /// `<fn() as FnTrait>::call_*` (generated `FnTrait` implementation for `fn()` pointers). |
| 105 | 121 | /// |
| 106 | 122 | /// `DefId` is `FnTrait::call_*`. |
| 107 | FnPtrShim(DefId, Ty<'tcx>), | |
| 108 | ||
| 109 | /// Dynamic dispatch to `<dyn Trait as Trait>::fn`. | |
| 110 | /// | |
| 111 | /// This `InstanceKind` may have a callable MIR as the default implementation. | |
| 112 | /// Calls to `Virtual` instances must be codegen'd as virtual calls through the vtable. | |
| 113 | /// *This means we might not know exactly what is being called.* | |
| 114 | /// | |
| 115 | /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more | |
| 116 | /// details on that). | |
| 117 | Virtual(DefId, usize), | |
| 123 | FnPtr(DefId, Ty<'tcx>), | |
| 118 | 124 | |
| 119 | 125 | /// `<[FnMut/Fn closure] as FnOnce>::call_once`. |
| 120 | 126 | /// |
| ... | ... | @@ -122,14 +128,14 @@ pub enum InstanceKind<'tcx> { |
| 122 | 128 | /// |
| 123 | 129 | /// This generates a body that will just borrow the (owned) self type, |
| 124 | 130 | /// and dispatch to the `FnMut::call_mut` instance for the closure. |
| 125 | ClosureOnceShim { call_once: DefId, closure: DefId, track_caller: bool }, | |
| 131 | ClosureOnce { call_once: DefId, closure: DefId, track_caller: bool }, | |
| 126 | 132 | |
| 127 | 133 | /// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once` |
| 128 | 134 | /// |
| 129 | 135 | /// The body generated here differs significantly from the `ClosureOnceShim`, |
| 130 | 136 | /// since we need to generate a distinct coroutine type that will move the |
| 131 | 137 | /// closure's upvars *out* of the closure. |
| 132 | ConstructCoroutineInClosureShim { | |
| 138 | ConstructCoroutineInClosure { | |
| 133 | 139 | coroutine_closure_def_id: DefId, |
| 134 | 140 | // Whether the generated MIR body takes the coroutine by-ref. This is |
| 135 | 141 | // because the signature of `<{async fn} as FnMut>::call_mut` is: |
| ... | ... | @@ -142,10 +148,10 @@ pub enum InstanceKind<'tcx> { |
| 142 | 148 | /// Compiler-generated accessor for thread locals which returns a reference to the thread local |
| 143 | 149 | /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking |
| 144 | 150 | /// native support. |
| 145 | ThreadLocalShim(DefId), | |
| 151 | ThreadLocal(DefId), | |
| 146 | 152 | |
| 147 | 153 | /// Proxy shim for async drop of future (def_id, proxy_cor_ty, impl_cor_ty) |
| 148 | FutureDropPollShim(DefId, Ty<'tcx>, Ty<'tcx>), | |
| 154 | FutureDropPoll(DefId, Ty<'tcx>, Ty<'tcx>), | |
| 149 | 155 | |
| 150 | 156 | /// `core::ptr::drop_glue::<T>`. |
| 151 | 157 | /// |
| ... | ... | @@ -162,20 +168,20 @@ pub enum InstanceKind<'tcx> { |
| 162 | 168 | /// Additionally, arrays, tuples, and closures get a `Clone` shim even if they aren't `Copy`. |
| 163 | 169 | /// |
| 164 | 170 | /// The `DefId` is for `Clone::clone`, the `Ty` is the type `T` with the builtin `Clone` impl. |
| 165 | CloneShim(DefId, Ty<'tcx>), | |
| 171 | Clone(DefId, Ty<'tcx>), | |
| 166 | 172 | |
| 167 | 173 | /// Compiler-generated `<T as FnPtr>::addr` implementation. |
| 168 | 174 | /// |
| 169 | 175 | /// Automatically generated for all potentially higher-ranked `fn(I) -> R` types. |
| 170 | 176 | /// |
| 171 | 177 | /// The `DefId` is for `FnPtr::addr`, the `Ty` is the type `T`. |
| 172 | FnPtrAddrShim(DefId, Ty<'tcx>), | |
| 178 | FnPtrAddr(DefId, Ty<'tcx>), | |
| 173 | 179 | |
| 174 | 180 | /// `core::future::async_drop::async_drop_in_place::<'_, T>`. |
| 175 | 181 | /// |
| 176 | 182 | /// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty` |
| 177 | 183 | /// is the type `T`. |
| 178 | AsyncDropGlueCtorShim(DefId, Ty<'tcx>), | |
| 184 | AsyncDropGlueCtor(DefId, Ty<'tcx>), | |
| 179 | 185 | |
| 180 | 186 | /// `core::future::async_drop::async_drop_in_place::<'_, T>::{closure}`. |
| 181 | 187 | /// |
| ... | ... | @@ -228,10 +234,12 @@ impl<'tcx> Instance<'tcx> { |
| 228 | 234 | InstanceKind::Item(def) => tcx |
| 229 | 235 | .upstream_monomorphizations_for(def) |
| 230 | 236 | .and_then(|monos| monos.get(&self.args).cloned()), |
| 231 | InstanceKind::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.args), | |
| 232 | InstanceKind::AsyncDropGlue(_, _) => None, | |
| 233 | InstanceKind::FutureDropPollShim(_, _, _) => None, | |
| 234 | InstanceKind::AsyncDropGlueCtorShim(_, _) => { | |
| 237 | InstanceKind::Shim(ShimKind::DropGlue(_, Some(_))) => { | |
| 238 | tcx.upstream_drop_glue_for(self.args) | |
| 239 | } | |
| 240 | InstanceKind::Shim(ShimKind::AsyncDropGlue(_, _)) => None, | |
| 241 | InstanceKind::Shim(ShimKind::FutureDropPoll(_, _, _)) => None, | |
| 242 | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, _)) => { | |
| 235 | 243 | tcx.upstream_async_drop_glue_for(self.args) |
| 236 | 244 | } |
| 237 | 245 | _ => None, |
| ... | ... | @@ -244,45 +252,18 @@ impl<'tcx> InstanceKind<'tcx> { |
| 244 | 252 | pub fn def_id(self) -> DefId { |
| 245 | 253 | match self { |
| 246 | 254 | InstanceKind::Item(def_id) |
| 247 | | InstanceKind::VTableShim(def_id) | |
| 248 | | InstanceKind::ReifyShim(def_id, _) | |
| 249 | | InstanceKind::FnPtrShim(def_id, _) | |
| 250 | 255 | | InstanceKind::Virtual(def_id, _) |
| 251 | | InstanceKind::Intrinsic(def_id) | |
| 252 | | InstanceKind::ThreadLocalShim(def_id) | |
| 253 | | InstanceKind::ClosureOnceShim { call_once: def_id, closure: _, track_caller: _ } | |
| 254 | | ty::InstanceKind::ConstructCoroutineInClosureShim { | |
| 255 | coroutine_closure_def_id: def_id, | |
| 256 | receiver_by_ref: _, | |
| 257 | } | |
| 258 | | InstanceKind::DropGlue(def_id, _) | |
| 259 | | InstanceKind::CloneShim(def_id, _) | |
| 260 | | InstanceKind::FnPtrAddrShim(def_id, _) | |
| 261 | | InstanceKind::FutureDropPollShim(def_id, _, _) | |
| 262 | | InstanceKind::AsyncDropGlue(def_id, _) | |
| 263 | | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id, | |
| 256 | | InstanceKind::Intrinsic(def_id) => def_id, | |
| 257 | InstanceKind::Shim(shim) => shim.def_id(), | |
| 264 | 258 | } |
| 265 | 259 | } |
| 266 | 260 | |
| 267 | 261 | /// Returns the `DefId` of instances which might not require codegen locally. |
| 268 | 262 | pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> { |
| 269 | 263 | match self { |
| 270 | ty::InstanceKind::Item(def) => Some(def), | |
| 271 | ty::InstanceKind::DropGlue(def_id, Some(_)) | |
| 272 | | InstanceKind::AsyncDropGlueCtorShim(def_id, _) | |
| 273 | | InstanceKind::AsyncDropGlue(def_id, _) | |
| 274 | | InstanceKind::FutureDropPollShim(def_id, ..) | |
| 275 | | InstanceKind::ThreadLocalShim(def_id) => Some(def_id), | |
| 276 | InstanceKind::VTableShim(..) | |
| 277 | | InstanceKind::ReifyShim(..) | |
| 278 | | InstanceKind::FnPtrShim(..) | |
| 279 | | InstanceKind::Virtual(..) | |
| 280 | | InstanceKind::Intrinsic(..) | |
| 281 | | InstanceKind::ClosureOnceShim { .. } | |
| 282 | | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 283 | | InstanceKind::DropGlue(..) | |
| 284 | | InstanceKind::CloneShim(..) | |
| 285 | | InstanceKind::FnPtrAddrShim(..) => None, | |
| 264 | InstanceKind::Item(def) => Some(def), | |
| 265 | InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) => None, | |
| 266 | InstanceKind::Shim(shim) => shim.def_id_if_not_guaranteed_local_codegen(), | |
| 286 | 267 | } |
| 287 | 268 | } |
| 288 | 269 | |
| ... | ... | @@ -293,31 +274,28 @@ impl<'tcx> InstanceKind<'tcx> { |
| 293 | 274 | /// `generates_cgu_internal_copy` for more information. |
| 294 | 275 | pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool { |
| 295 | 276 | use rustc_hir::definitions::DefPathData; |
| 296 | let def_id = match *self { | |
| 297 | ty::InstanceKind::Item(def) => def, | |
| 298 | ty::InstanceKind::DropGlue(_, Some(ty)) => return ty.is_array(), | |
| 299 | ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => return ty.is_coroutine(), | |
| 300 | ty::InstanceKind::FutureDropPollShim(_, _, _) => return false, | |
| 301 | ty::InstanceKind::AsyncDropGlue(_, _) => return false, | |
| 302 | ty::InstanceKind::ThreadLocalShim(_) => return false, | |
| 303 | _ => return true, | |
| 304 | }; | |
| 305 | matches!( | |
| 306 | tcx.def_key(def_id).disambiguated_data.data, | |
| 307 | DefPathData::Ctor | DefPathData::Closure | |
| 308 | ) | |
| 277 | match *self { | |
| 278 | InstanceKind::Item(def_id) => matches!( | |
| 279 | tcx.def_key(def_id).disambiguated_data.data, | |
| 280 | DefPathData::Ctor | DefPathData::Closure | |
| 281 | ), | |
| 282 | InstanceKind::Shim(shim) => shim.requires_inline(), | |
| 283 | InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) => true, | |
| 284 | } | |
| 309 | 285 | } |
| 310 | 286 | |
| 311 | 287 | pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { |
| 312 | 288 | match *self { |
| 313 | 289 | InstanceKind::Item(def_id) |
| 314 | 290 | | InstanceKind::Virtual(def_id, _) |
| 315 | | InstanceKind::VTableShim(def_id) => { | |
| 291 | | InstanceKind::Shim(ShimKind::VTable(def_id)) => { | |
| 316 | 292 | tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) |
| 317 | 293 | } |
| 318 | InstanceKind::ClosureOnceShim { call_once: _, closure: _, track_caller } => { | |
| 319 | track_caller | |
| 320 | } | |
| 294 | InstanceKind::Shim(ShimKind::ClosureOnce { | |
| 295 | call_once: _, | |
| 296 | closure: _, | |
| 297 | track_caller, | |
| 298 | }) => track_caller, | |
| 321 | 299 | _ => false, |
| 322 | 300 | } |
| 323 | 301 | } |
| ... | ... | @@ -330,22 +308,79 @@ impl<'tcx> InstanceKind<'tcx> { |
| 330 | 308 | /// body should perform necessary instantiations. |
| 331 | 309 | pub fn has_polymorphic_mir_body(&self) -> bool { |
| 332 | 310 | match *self { |
| 333 | InstanceKind::CloneShim(..) | |
| 334 | | InstanceKind::ThreadLocalShim(..) | |
| 335 | | InstanceKind::FnPtrAddrShim(..) | |
| 336 | | InstanceKind::FnPtrShim(..) | |
| 337 | | InstanceKind::DropGlue(_, Some(_)) | |
| 338 | | InstanceKind::FutureDropPollShim(..) | |
| 339 | | InstanceKind::AsyncDropGlue(_, _) => false, | |
| 340 | InstanceKind::AsyncDropGlueCtorShim(_, _) => false, | |
| 341 | InstanceKind::ClosureOnceShim { .. } | |
| 342 | | InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 343 | | InstanceKind::DropGlue(..) | |
| 344 | | InstanceKind::Item(_) | |
| 345 | | InstanceKind::Intrinsic(..) | |
| 346 | | InstanceKind::ReifyShim(..) | |
| 347 | | InstanceKind::Virtual(..) | |
| 348 | | InstanceKind::VTableShim(..) => true, | |
| 311 | InstanceKind::Item(_) | InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..) => true, | |
| 312 | InstanceKind::Shim(shim) => shim.has_polymorphic_mir_body(), | |
| 313 | } | |
| 314 | } | |
| 315 | } | |
| 316 | ||
| 317 | impl<'tcx> ShimKind<'tcx> { | |
| 318 | #[inline] | |
| 319 | pub fn def_id(self) -> DefId { | |
| 320 | match self { | |
| 321 | ShimKind::VTable(def_id) | |
| 322 | | ShimKind::Reify(def_id, _) | |
| 323 | | ShimKind::FnPtr(def_id, _) | |
| 324 | | ShimKind::ThreadLocal(def_id) | |
| 325 | | ShimKind::ClosureOnce { call_once: def_id, closure: _, track_caller: _ } | |
| 326 | | ShimKind::ConstructCoroutineInClosure { | |
| 327 | coroutine_closure_def_id: def_id, | |
| 328 | receiver_by_ref: _, | |
| 329 | } | |
| 330 | | ShimKind::DropGlue(def_id, _) | |
| 331 | | ShimKind::Clone(def_id, _) | |
| 332 | | ShimKind::FnPtrAddr(def_id, _) | |
| 333 | | ShimKind::FutureDropPoll(def_id, _, _) | |
| 334 | | ShimKind::AsyncDropGlue(def_id, _) | |
| 335 | | ShimKind::AsyncDropGlueCtor(def_id, _) => def_id, | |
| 336 | } | |
| 337 | } | |
| 338 | ||
| 339 | /// Returns the `DefId` of instances which might not require codegen locally. | |
| 340 | pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> { | |
| 341 | match self { | |
| 342 | ShimKind::DropGlue(def_id, Some(_)) | |
| 343 | | ShimKind::AsyncDropGlueCtor(def_id, _) | |
| 344 | | ShimKind::AsyncDropGlue(def_id, _) | |
| 345 | | ShimKind::FutureDropPoll(def_id, ..) | |
| 346 | | ShimKind::ThreadLocal(def_id) => Some(def_id), | |
| 347 | ShimKind::VTable(..) | |
| 348 | | ShimKind::Reify(..) | |
| 349 | | ShimKind::FnPtr(..) | |
| 350 | | ShimKind::ClosureOnce { .. } | |
| 351 | | ShimKind::ConstructCoroutineInClosure { .. } | |
| 352 | | ShimKind::DropGlue(..) | |
| 353 | | ShimKind::Clone(..) | |
| 354 | | ShimKind::FnPtrAddr(..) => None, | |
| 355 | } | |
| 356 | } | |
| 357 | ||
| 358 | pub fn requires_inline(&self) -> bool { | |
| 359 | match self { | |
| 360 | ShimKind::DropGlue(_, Some(ty)) => ty.is_array(), | |
| 361 | ShimKind::AsyncDropGlueCtor(_, ty) => ty.is_coroutine(), | |
| 362 | ShimKind::FutureDropPoll(_, _, _) => false, | |
| 363 | ShimKind::AsyncDropGlue(_, _) => false, | |
| 364 | ShimKind::ThreadLocal(_) => false, | |
| 365 | _ => true, | |
| 366 | } | |
| 367 | } | |
| 368 | ||
| 369 | pub fn has_polymorphic_mir_body(&self) -> bool { | |
| 370 | match *self { | |
| 371 | ShimKind::Clone(..) | |
| 372 | | ShimKind::ThreadLocal(..) | |
| 373 | | ShimKind::FnPtrAddr(..) | |
| 374 | | ShimKind::FnPtr(..) | |
| 375 | | ShimKind::DropGlue(_, Some(_)) | |
| 376 | | ShimKind::FutureDropPoll(..) | |
| 377 | | ShimKind::AsyncDropGlue(_, _) => false, | |
| 378 | ShimKind::AsyncDropGlueCtor(_, _) => false, | |
| 379 | ShimKind::ClosureOnce { .. } | |
| 380 | | ShimKind::ConstructCoroutineInClosure { .. } | |
| 381 | | ShimKind::DropGlue(..) | |
| 382 | | ShimKind::Reify(..) | |
| 383 | | ShimKind::VTable(..) => true, | |
| 349 | 384 | } |
| 350 | 385 | } |
| 351 | 386 | } |
| ... | ... | @@ -416,7 +451,11 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { |
| 416 | 451 | continue; |
| 417 | 452 | } else { |
| 418 | 453 | return Instance { |
| 419 | def: ty::InstanceKind::FutureDropPollShim(poll_def_id, first_cor, cor_ty), | |
| 454 | def: ty::InstanceKind::Shim(ShimKind::FutureDropPoll( | |
| 455 | poll_def_id, | |
| 456 | first_cor, | |
| 457 | cor_ty, | |
| 458 | )), | |
| 420 | 459 | args: proxy_args, |
| 421 | 460 | }; |
| 422 | 461 | } |
| ... | ... | @@ -426,12 +465,16 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { |
| 426 | 465 | }; |
| 427 | 466 | if first_cor != cor_ty { |
| 428 | 467 | return Instance { |
| 429 | def: ty::InstanceKind::FutureDropPollShim(poll_def_id, first_cor, cor_ty), | |
| 468 | def: ty::InstanceKind::Shim(ShimKind::FutureDropPoll( | |
| 469 | poll_def_id, | |
| 470 | first_cor, | |
| 471 | cor_ty, | |
| 472 | )), | |
| 430 | 473 | args: proxy_args, |
| 431 | 474 | }; |
| 432 | 475 | } else { |
| 433 | 476 | return Instance { |
| 434 | def: ty::InstanceKind::AsyncDropGlue(poll_def_id, cor_ty), | |
| 477 | def: ty::InstanceKind::Shim(ShimKind::AsyncDropGlue(poll_def_id, cor_ty)), | |
| 435 | 478 | args: child_args, |
| 436 | 479 | }; |
| 437 | 480 | } |
| ... | ... | @@ -599,11 +642,11 @@ impl<'tcx> Instance<'tcx> { |
| 599 | 642 | match resolved.def { |
| 600 | 643 | InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => { |
| 601 | 644 | debug!(" => fn pointer created for function with #[track_caller]"); |
| 602 | resolved.def = InstanceKind::ReifyShim(def, reason); | |
| 645 | resolved.def = InstanceKind::Shim(ShimKind::Reify(def, reason)); | |
| 603 | 646 | } |
| 604 | 647 | InstanceKind::Virtual(def_id, _) => { |
| 605 | 648 | debug!(" => fn pointer created for virtual call"); |
| 606 | resolved.def = InstanceKind::ReifyShim(def_id, reason); | |
| 649 | resolved.def = InstanceKind::Shim(ShimKind::Reify(def_id, reason)); | |
| 607 | 650 | } |
| 608 | 651 | _ if tcx.sess.is_sanitizer_kcfi_enabled() => { |
| 609 | 652 | // Reify `::call`-like method implementations |
| ... | ... | @@ -611,7 +654,10 @@ impl<'tcx> Instance<'tcx> { |
| 611 | 654 | // Reroute through a reify via the *unresolved* instance. The resolved one can't |
| 612 | 655 | // be directly reified because it's closure-like. The reify can handle the |
| 613 | 656 | // unresolved instance. |
| 614 | resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args } | |
| 657 | resolved = Instance { | |
| 658 | def: InstanceKind::Shim(ShimKind::Reify(def_id, reason)), | |
| 659 | args, | |
| 660 | } | |
| 615 | 661 | // Reify `Trait::method` implementations if the trait is dyn-compatible. |
| 616 | 662 | } else if let Some(assoc) = tcx.opt_associated_item(def_id) |
| 617 | 663 | && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) = |
| ... | ... | @@ -620,7 +666,8 @@ impl<'tcx> Instance<'tcx> { |
| 620 | 666 | { |
| 621 | 667 | // If this function could also go in a vtable, we need to `ReifyShim` it with |
| 622 | 668 | // KCFI because it can only attach one type per function. |
| 623 | resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason) | |
| 669 | resolved.def = | |
| 670 | InstanceKind::Shim(ShimKind::Reify(resolved.def_id(), reason)) | |
| 624 | 671 | } |
| 625 | 672 | } |
| 626 | 673 | _ => {} |
| ... | ... | @@ -645,7 +692,7 @@ impl<'tcx> Instance<'tcx> { |
| 645 | 692 | |
| 646 | 693 | if is_vtable_shim { |
| 647 | 694 | debug!(" => associated item with unsizeable self: Self"); |
| 648 | return Instance { def: InstanceKind::VTableShim(def_id), args }; | |
| 695 | return Instance { def: InstanceKind::Shim(ShimKind::VTable(def_id)), args }; | |
| 649 | 696 | } |
| 650 | 697 | |
| 651 | 698 | let mut resolved = Instance::expect_resolve(tcx, typing_env, def_id, args, span); |
| ... | ... | @@ -688,19 +735,22 @@ impl<'tcx> Instance<'tcx> { |
| 688 | 735 | // Create a shim for the `FnOnce/FnMut/Fn` method we are calling |
| 689 | 736 | // - unlike functions, invoking a closure always goes through a |
| 690 | 737 | // trait. |
| 691 | resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }; | |
| 738 | resolved = Instance { | |
| 739 | def: InstanceKind::Shim(ShimKind::Reify(def_id, reason)), | |
| 740 | args, | |
| 741 | }; | |
| 692 | 742 | } else { |
| 693 | 743 | debug!( |
| 694 | 744 | " => vtable fn pointer created for function with #[track_caller]: {:?}", |
| 695 | 745 | def |
| 696 | 746 | ); |
| 697 | resolved.def = InstanceKind::ReifyShim(def, reason); | |
| 747 | resolved.def = InstanceKind::Shim(ShimKind::Reify(def, reason)); | |
| 698 | 748 | } |
| 699 | 749 | } |
| 700 | 750 | } |
| 701 | 751 | InstanceKind::Virtual(def_id, _) => { |
| 702 | 752 | debug!(" => vtable fn pointer created for virtual call"); |
| 703 | resolved.def = InstanceKind::ReifyShim(def_id, reason) | |
| 753 | resolved.def = InstanceKind::Shim(ShimKind::Reify(def_id, reason)) | |
| 704 | 754 | } |
| 705 | 755 | _ => {} |
| 706 | 756 | } |
| ... | ... | @@ -770,8 +820,11 @@ impl<'tcx> Instance<'tcx> { |
| 770 | 820 | .def_id; |
| 771 | 821 | let track_caller = |
| 772 | 822 | tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER); |
| 773 | let def = | |
| 774 | ty::InstanceKind::ClosureOnceShim { call_once, closure: closure_did, track_caller }; | |
| 823 | let def = ty::InstanceKind::Shim(ShimKind::ClosureOnce { | |
| 824 | call_once, | |
| 825 | closure: closure_did, | |
| 826 | track_caller, | |
| 827 | }); | |
| 775 | 828 | |
| 776 | 829 | let self_ty = Ty::new_closure(tcx, closure_did, args); |
| 777 | 830 |
compiler/rustc_middle/src/ty/mod.rs+5-16| ... | ... | @@ -85,7 +85,7 @@ pub use self::context::{ |
| 85 | 85 | CtxtInterners, CurrentGcx, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls, |
| 86 | 86 | }; |
| 87 | 87 | pub use self::fold::*; |
| 88 | pub use self::instance::{Instance, InstanceKind, ReifyReason}; | |
| 88 | pub use self::instance::{Instance, InstanceKind, ReifyReason, ShimKind}; | |
| 89 | 89 | pub(crate) use self::list::RawList; |
| 90 | 90 | pub use self::list::{List, ListWithCachedTypeInfo}; |
| 91 | 91 | pub use self::opaque_types::OpaqueTypeKey; |
| ... | ... | @@ -1803,20 +1803,9 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1803 | 1803 | _ => self.optimized_mir(def), |
| 1804 | 1804 | } |
| 1805 | 1805 | } |
| 1806 | ty::InstanceKind::VTableShim(..) | |
| 1807 | | ty::InstanceKind::ReifyShim(..) | |
| 1808 | | ty::InstanceKind::Intrinsic(..) | |
| 1809 | | ty::InstanceKind::FnPtrShim(..) | |
| 1810 | | ty::InstanceKind::Virtual(..) | |
| 1811 | | ty::InstanceKind::ClosureOnceShim { .. } | |
| 1812 | | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 1813 | | ty::InstanceKind::FutureDropPollShim(..) | |
| 1814 | | ty::InstanceKind::DropGlue(..) | |
| 1815 | | ty::InstanceKind::CloneShim(..) | |
| 1816 | | ty::InstanceKind::ThreadLocalShim(..) | |
| 1817 | | ty::InstanceKind::FnPtrAddrShim(..) | |
| 1818 | | ty::InstanceKind::AsyncDropGlueCtorShim(..) | |
| 1819 | | ty::InstanceKind::AsyncDropGlue(..) => self.mir_shims(instance), | |
| 1806 | ty::InstanceKind::Intrinsic(..) => bug!("intrinsics have no instance MIR"), | |
| 1807 | ty::InstanceKind::Virtual(..) => bug!("virtual dispatches have no instance MIR"), | |
| 1808 | ty::InstanceKind::Shim(shim) => self.mir_shims(shim), | |
| 1820 | 1809 | }; |
| 1821 | 1810 | |
| 1822 | 1811 | assert!( |
| ... | ... | @@ -1942,7 +1931,7 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1942 | 1931 | if args[0].has_placeholders() || args[0].has_non_region_param() { |
| 1943 | 1932 | return Err(self.layout_error(LayoutError::TooGeneric(ty()))); |
| 1944 | 1933 | } |
| 1945 | let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args)); | |
| 1934 | let instance = ShimKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args)); | |
| 1946 | 1935 | self.mir_shims(instance) |
| 1947 | 1936 | .coroutine_layout_raw() |
| 1948 | 1937 | .ok_or_else(|| self.layout_error(LayoutError::Unknown(ty()))) |
compiler/rustc_middle/src/ty/print/mod.rs+31-24| ... | ... | @@ -367,35 +367,42 @@ impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print<P> for ty::Instance<'tcx> { |
| 367 | 367 | cx.print_def_path(self.def_id(), self.args)?; |
| 368 | 368 | match self.def { |
| 369 | 369 | ty::InstanceKind::Item(_) => {} |
| 370 | ty::InstanceKind::VTableShim(_) => cx.write_str(" - shim(vtable)")?, | |
| 371 | ty::InstanceKind::ReifyShim(_, None) => cx.write_str(" - shim(reify)")?, | |
| 372 | ty::InstanceKind::ReifyShim(_, Some(ty::ReifyReason::FnPtr)) => { | |
| 373 | cx.write_str(" - shim(reify-fnptr)")? | |
| 374 | } | |
| 375 | ty::InstanceKind::ReifyShim(_, Some(ty::ReifyReason::Vtable)) => { | |
| 376 | cx.write_str(" - shim(reify-vtable)")? | |
| 377 | } | |
| 378 | ty::InstanceKind::ThreadLocalShim(_) => cx.write_str(" - shim(tls)")?, | |
| 379 | 370 | ty::InstanceKind::Intrinsic(_) => cx.write_str(" - intrinsic")?, |
| 380 | 371 | ty::InstanceKind::Virtual(_, num) => cx.write_str(&format!(" - virtual#{num}"))?, |
| 381 | ty::InstanceKind::FnPtrShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, | |
| 382 | ty::InstanceKind::ClosureOnceShim { .. } => cx.write_str(" - shim")?, | |
| 383 | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } => cx.write_str(" - shim")?, | |
| 384 | ty::InstanceKind::DropGlue(_, None) => cx.write_str(" - shim(None)")?, | |
| 385 | ty::InstanceKind::DropGlue(_, Some(ty)) => { | |
| 386 | cx.write_str(&format!(" - shim(Some({ty}))"))? | |
| 372 | ty::InstanceKind::Shim(shim) => { | |
| 373 | cx.write_str(" - ")?; | |
| 374 | shim.print(cx)?; | |
| 375 | } | |
| 376 | } | |
| 377 | Ok(()) | |
| 378 | } | |
| 379 | } | |
| 380 | ||
| 381 | impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print<P> for ty::ShimKind<'tcx> { | |
| 382 | fn print(&self, cx: &mut P) -> Result<(), PrintError> { | |
| 383 | match self { | |
| 384 | ty::ShimKind::VTable(_) => cx.write_str("shim(vtable)"), | |
| 385 | ty::ShimKind::Reify(_, None) => cx.write_str("shim(reify)"), | |
| 386 | ty::ShimKind::Reify(_, Some(ty::ReifyReason::FnPtr)) => { | |
| 387 | cx.write_str("shim(reify-fnptr)") | |
| 387 | 388 | } |
| 388 | ty::InstanceKind::CloneShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, | |
| 389 | ty::InstanceKind::FnPtrAddrShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, | |
| 390 | ty::InstanceKind::FutureDropPollShim(_, proxy_ty, impl_ty) => { | |
| 391 | cx.write_str(&format!(" - dropshim({proxy_ty}-{impl_ty})"))? | |
| 389 | ty::ShimKind::Reify(_, Some(ty::ReifyReason::Vtable)) => { | |
| 390 | cx.write_str("shim(reify-vtable)") | |
| 392 | 391 | } |
| 393 | ty::InstanceKind::AsyncDropGlue(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, | |
| 394 | ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => { | |
| 395 | cx.write_str(&format!(" - shim(Some({ty}))"))? | |
| 392 | ty::ShimKind::ThreadLocal(_) => cx.write_str("shim(tls)"), | |
| 393 | ty::ShimKind::FnPtr(_, ty) => cx.write_str(&format!("shim({ty})")), | |
| 394 | ty::ShimKind::ClosureOnce { .. } => cx.write_str("shim"), | |
| 395 | ty::ShimKind::ConstructCoroutineInClosure { .. } => cx.write_str("shim"), | |
| 396 | ty::ShimKind::DropGlue(_, None) => cx.write_str("shim(None)"), | |
| 397 | ty::ShimKind::DropGlue(_, Some(ty)) => cx.write_str(&format!("shim(Some({ty}))")), | |
| 398 | ty::ShimKind::Clone(_, ty) => cx.write_str(&format!("shim({ty})")), | |
| 399 | ty::ShimKind::FnPtrAddr(_, ty) => cx.write_str(&format!("shim({ty})")), | |
| 400 | ty::ShimKind::FutureDropPoll(_, proxy_ty, impl_ty) => { | |
| 401 | cx.write_str(&format!("dropshim({proxy_ty}-{impl_ty})")) | |
| 396 | 402 | } |
| 397 | }; | |
| 398 | Ok(()) | |
| 403 | ty::ShimKind::AsyncDropGlue(_, ty) => cx.write_str(&format!("shim({ty})")), | |
| 404 | ty::ShimKind::AsyncDropGlueCtor(_, ty) => cx.write_str(&format!("shim(Some({ty}))")), | |
| 405 | } | |
| 399 | 406 | } |
| 400 | 407 | } |
| 401 | 408 |
compiler/rustc_mir_build/src/check_tail_calls.rs+20-1| ... | ... | @@ -147,7 +147,9 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { |
| 147 | 147 | // ``` |
| 148 | 148 | // we should think what is the expected behavior here. |
| 149 | 149 | // (we should probably just accept this by revealing opaques?) |
| 150 | if caller_sig.inputs_and_output != callee_sig.inputs_and_output { | |
| 150 | if caller_sig.inputs_and_output != callee_sig.inputs_and_output | |
| 151 | && !matches!(callee_sig.abi(), ExternAbi::RustTail) | |
| 152 | { | |
| 151 | 153 | let caller_ty = self.tcx.type_of(self.caller_def_id).skip_binder(); |
| 152 | 154 | |
| 153 | 155 | self.report_signature_mismatch( |
| ... | ... | @@ -189,6 +191,12 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { |
| 189 | 191 | if callee_sig.c_variadic() { |
| 190 | 192 | self.report_c_variadic_callee(expr.span); |
| 191 | 193 | } |
| 194 | ||
| 195 | for &arg_ty in callee_sig.inputs() { | |
| 196 | if !arg_ty.is_sized(self.tcx, self.typing_env) { | |
| 197 | self.report_unsized_argument(expr.span, arg_ty); | |
| 198 | } | |
| 199 | } | |
| 192 | 200 | } |
| 193 | 201 | |
| 194 | 202 | /// Returns true if the caller function needs a location argument |
| ... | ... | @@ -417,6 +425,17 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { |
| 417 | 425 | |
| 418 | 426 | self.found_errors = Err(err); |
| 419 | 427 | } |
| 428 | ||
| 429 | fn report_unsized_argument(&mut self, sp: Span, arg_ty: Ty<'tcx>) { | |
| 430 | let err = self | |
| 431 | .tcx | |
| 432 | .dcx() | |
| 433 | .struct_span_err(sp, format!("unsized arguments cannot be used in a tail call")) | |
| 434 | .with_note(format!("unsized argument of type `{arg_ty}`")) | |
| 435 | .emit(); | |
| 436 | ||
| 437 | self.found_errors = Err(err); | |
| 438 | } | |
| 420 | 439 | } |
| 421 | 440 | |
| 422 | 441 | impl<'a, 'tcx> Visitor<'a, 'tcx> for TailCallCkVisitor<'a, 'tcx> { |
compiler/rustc_mir_transform/src/coroutine/by_move_body.rs+4-2| ... | ... | @@ -223,8 +223,10 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( |
| 223 | 223 | None, |
| 224 | 224 | &mut PerParentDisambiguatorState::new(parent_def_id), |
| 225 | 225 | ); |
| 226 | by_move_body.source = | |
| 227 | mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id())); | |
| 226 | by_move_body.source = mir::MirSource { | |
| 227 | instance: InstanceKind::Item(body_def.def_id().to_def_id()), | |
| 228 | promoted: None, | |
| 229 | }; | |
| 228 | 230 | |
| 229 | 231 | if let Some(dumper) = MirDumper::new(tcx, "built", &by_move_body) { |
| 230 | 232 | dumper.set_disambiguator(&"after").dump_mir(&by_move_body); |
compiler/rustc_mir_transform/src/coroutine/drop.rs+1-1| ... | ... | @@ -206,7 +206,7 @@ pub(super) fn create_coroutine_drop_shim<'tcx>( |
| 206 | 206 | // Update the body's def to become the drop glue. |
| 207 | 207 | let coroutine_instance = body.source.instance; |
| 208 | 208 | let drop_glue = tcx.require_lang_item(LangItem::DropGlue, body.span); |
| 209 | let drop_instance = InstanceKind::DropGlue(drop_glue, Some(coroutine_ty)); | |
| 209 | let drop_instance = InstanceKind::Shim(ShimKind::DropGlue(drop_glue, Some(coroutine_ty))); | |
| 210 | 210 | |
| 211 | 211 | // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible |
| 212 | 212 | // filename. |
compiler/rustc_mir_transform/src/coroutine/mod.rs+1-1| ... | ... | @@ -71,7 +71,7 @@ use rustc_index::{Idx, IndexVec, indexvec}; |
| 71 | 71 | use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; |
| 72 | 72 | use rustc_middle::mir::*; |
| 73 | 73 | use rustc_middle::ty::{ |
| 74 | self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt, | |
| 74 | self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, ShimKind, Ty, TyCtxt, | |
| 75 | 75 | }; |
| 76 | 76 | use rustc_middle::{bug, span_bug}; |
| 77 | 77 | use rustc_mir_dataflow::impls::always_storage_live_locals; |
compiler/rustc_mir_transform/src/inline.rs+18-15| ... | ... | @@ -15,7 +15,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; |
| 15 | 15 | use rustc_middle::mir::visit::*; |
| 16 | 16 | use rustc_middle::mir::*; |
| 17 | 17 | use rustc_middle::ty::{ |
| 18 | self, Instance, InstanceKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized, | |
| 18 | self, Instance, InstanceKind, ShimKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized, | |
| 19 | 19 | }; |
| 20 | 20 | use rustc_session::config::{DebugInfo, OptLevel}; |
| 21 | 21 | use rustc_span::Spanned; |
| ... | ... | @@ -739,18 +739,21 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( |
| 739 | 739 | // the correct param-env for types being dropped. Stall resolving |
| 740 | 740 | // the MIR for this instance until all of its const params are |
| 741 | 741 | // substituted. |
| 742 | InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => { | |
| 742 | InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))) | |
| 743 | if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => | |
| 744 | { | |
| 743 | 745 | debug!("still needs substitution"); |
| 744 | 746 | return Err("implementation limitation -- HACK for dropping polymorphic type"); |
| 745 | 747 | } |
| 746 | InstanceKind::AsyncDropGlue(_, ty) | InstanceKind::AsyncDropGlueCtorShim(_, ty) => { | |
| 748 | InstanceKind::Shim(ShimKind::AsyncDropGlue(_, ty)) | |
| 749 | | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, ty)) => { | |
| 747 | 750 | return if ty.still_further_specializable() { |
| 748 | 751 | Err("still needs substitution") |
| 749 | 752 | } else { |
| 750 | 753 | Ok(()) |
| 751 | 754 | }; |
| 752 | 755 | } |
| 753 | InstanceKind::FutureDropPollShim(_, ty, ty2) => { | |
| 756 | InstanceKind::Shim(ShimKind::FutureDropPoll(_, ty, ty2)) => { | |
| 754 | 757 | return if ty.still_further_specializable() || ty2.still_further_specializable() { |
| 755 | 758 | Err("still needs substitution") |
| 756 | 759 | } else { |
| ... | ... | @@ -762,15 +765,15 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( |
| 762 | 765 | // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we |
| 763 | 766 | // do not need to catch this here, we can wait until the inliner decides to continue |
| 764 | 767 | // inlining a second time. |
| 765 | InstanceKind::VTableShim(_) | |
| 766 | | InstanceKind::ReifyShim(..) | |
| 767 | | InstanceKind::FnPtrShim(..) | |
| 768 | | InstanceKind::ClosureOnceShim { .. } | |
| 769 | | InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 770 | | InstanceKind::DropGlue(..) | |
| 771 | | InstanceKind::CloneShim(..) | |
| 772 | | InstanceKind::ThreadLocalShim(..) | |
| 773 | | InstanceKind::FnPtrAddrShim(..) => return Ok(()), | |
| 768 | InstanceKind::Shim(ShimKind::VTable(_)) | |
| 769 | | InstanceKind::Shim(ShimKind::Reify(..)) | |
| 770 | | InstanceKind::Shim(ShimKind::FnPtr(..)) | |
| 771 | | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) | |
| 772 | | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | |
| 773 | | InstanceKind::Shim(ShimKind::DropGlue(..)) | |
| 774 | | InstanceKind::Shim(ShimKind::Clone(..)) | |
| 775 | | InstanceKind::Shim(ShimKind::ThreadLocal(..)) | |
| 776 | | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return Ok(()), | |
| 774 | 777 | } |
| 775 | 778 | |
| 776 | 779 | if inliner.tcx().is_constructor(callee_def_id) { |
| ... | ... | @@ -1370,8 +1373,8 @@ fn try_instance_mir<'tcx>( |
| 1370 | 1373 | tcx: TyCtxt<'tcx>, |
| 1371 | 1374 | instance: InstanceKind<'tcx>, |
| 1372 | 1375 | ) -> Result<&'tcx Body<'tcx>, &'static str> { |
| 1373 | if let ty::InstanceKind::DropGlue(_, Some(ty)) | ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) = | |
| 1374 | instance | |
| 1376 | if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) | |
| 1377 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, ty)) = instance | |
| 1375 | 1378 | && let ty::Adt(def, args) = ty.kind() |
| 1376 | 1379 | { |
| 1377 | 1380 | let fields = def.all_fields(); |
compiler/rustc_mir_transform/src/inline/cycle.rs+13-13| ... | ... | @@ -4,7 +4,7 @@ use rustc_data_structures::unord::UnordSet; |
| 4 | 4 | use rustc_hir::def_id::{DefId, LocalDefId}; |
| 5 | 5 | use rustc_hir::limit::Limit; |
| 6 | 6 | use rustc_middle::mir::TerminatorKind; |
| 7 | use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, TyCtxt, TypeVisitableExt}; | |
| 7 | use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, ShimKind, TyCtxt, TypeVisitableExt}; | |
| 8 | 8 | use rustc_span::sym; |
| 9 | 9 | use tracing::{instrument, trace}; |
| 10 | 10 | |
| ... | ... | @@ -26,24 +26,24 @@ fn should_recurse<'tcx>(tcx: TyCtxt<'tcx>, callee: ty::Instance<'tcx>) -> bool { |
| 26 | 26 | // These have MIR and if that MIR is inlined, instantiated and then inlining is run |
| 27 | 27 | // again, a function item can end up getting inlined. Thus we'll be able to cause |
| 28 | 28 | // a cycle that way |
| 29 | InstanceKind::VTableShim(_) | |
| 30 | | InstanceKind::ReifyShim(..) | |
| 31 | | InstanceKind::FnPtrShim(..) | |
| 32 | | InstanceKind::ClosureOnceShim { .. } | |
| 33 | | InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 34 | | InstanceKind::ThreadLocalShim { .. } | |
| 35 | | InstanceKind::CloneShim(..) => {} | |
| 29 | InstanceKind::Shim(ShimKind::VTable(_)) | |
| 30 | | InstanceKind::Shim(ShimKind::Reify(..)) | |
| 31 | | InstanceKind::Shim(ShimKind::FnPtr(..)) | |
| 32 | | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) | |
| 33 | | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | |
| 34 | | InstanceKind::Shim(ShimKind::ThreadLocal { .. }) | |
| 35 | | InstanceKind::Shim(ShimKind::Clone(..)) => {} | |
| 36 | 36 | |
| 37 | 37 | // This shim does not call any other functions, thus there can be no recursion. |
| 38 | InstanceKind::FnPtrAddrShim(..) => return false, | |
| 38 | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return false, | |
| 39 | 39 | |
| 40 | 40 | // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to |
| 41 | 41 | // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this |
| 42 | 42 | // needs some more analysis. |
| 43 | InstanceKind::DropGlue(..) | |
| 44 | | InstanceKind::FutureDropPollShim(..) | |
| 45 | | InstanceKind::AsyncDropGlue(..) | |
| 46 | | InstanceKind::AsyncDropGlueCtorShim(..) => { | |
| 43 | InstanceKind::Shim(ShimKind::DropGlue(..)) | |
| 44 | | InstanceKind::Shim(ShimKind::FutureDropPoll(..)) | |
| 45 | | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) | |
| 46 | | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => { | |
| 47 | 47 | if callee.has_param() { |
| 48 | 48 | return false; |
| 49 | 49 | } |
compiler/rustc_mir_transform/src/lint_and_remove_uninhabited.rs+17-6| ... | ... | @@ -93,8 +93,8 @@ fn find_unreachable_code_from<'tcx>( |
| 93 | 93 | bb: BasicBlock, |
| 94 | 94 | body: &Body<'tcx>, |
| 95 | 95 | ) -> Option<(SourceInfo, &'static str)> { |
| 96 | let bb = &body.basic_blocks[bb]; | |
| 97 | for stmt in &bb.statements { | |
| 96 | let bbdata = &body.basic_blocks[bb]; | |
| 97 | for stmt in &bbdata.statements { | |
| 98 | 98 | match &stmt.kind { |
| 99 | 99 | // Ignore the implicit `()` return place assignment for unit functions/blocks |
| 100 | 100 | StatementKind::Assign((_, Rvalue::Use(Operand::Constant(const_), _))) |
| ... | ... | @@ -108,7 +108,10 @@ fn find_unreachable_code_from<'tcx>( |
| 108 | 108 | StatementKind::Assign((place, _)) if place.as_local() == Some(RETURN_PLACE) => { |
| 109 | 109 | continue; |
| 110 | 110 | } |
| 111 | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => { | |
| 111 | // Ignore statements inserted by MIR building that do not correspond to user code. | |
| 112 | StatementKind::StorageLive(_) | |
| 113 | | StatementKind::StorageDead(_) | |
| 114 | | StatementKind::BackwardIncompatibleDropHint { .. } => { | |
| 112 | 115 | continue; |
| 113 | 116 | } |
| 114 | 117 | StatementKind::FakeRead(..) => return Some((stmt.source_info, "definition")), |
| ... | ... | @@ -116,10 +119,18 @@ fn find_unreachable_code_from<'tcx>( |
| 116 | 119 | } |
| 117 | 120 | } |
| 118 | 121 | |
| 119 | let term = bb.terminator(); | |
| 122 | let term = bbdata.terminator(); | |
| 120 | 123 | match term.kind { |
| 121 | // No user code in this bb, and our goto target may be reachable via other paths | |
| 122 | TerminatorKind::Goto { .. } | TerminatorKind::Return => None, | |
| 124 | // The user does not care for `goto` and compiler-generated drops. If the target block is | |
| 125 | // only reachable through those terminators, continue searching there. | |
| 126 | TerminatorKind::Goto { target } | TerminatorKind::Drop { target, .. } => { | |
| 127 | if &body.basic_blocks.predecessors()[target][..] == &[bb] { | |
| 128 | find_unreachable_code_from(target, body) | |
| 129 | } else { | |
| 130 | None | |
| 131 | } | |
| 132 | } | |
| 133 | TerminatorKind::Return => None, | |
| 123 | 134 | _ => Some((term.source_info, "expression")), |
| 124 | 135 | } |
| 125 | 136 | } |
compiler/rustc_mir_transform/src/shim.rs+42-55| ... | ... | @@ -31,16 +31,15 @@ pub(super) fn provide(providers: &mut Providers) { |
| 31 | 31 | providers.mir_shims = make_shim; |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<'tcx> { | |
| 35 | debug!("make_shim({:?})", instance); | |
| 34 | fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { | |
| 35 | debug!("make_shim({:?})", shim); | |
| 36 | 36 | |
| 37 | let mut result = match instance { | |
| 38 | ty::InstanceKind::Item(..) => bug!("item {:?} passed to make_shim", instance), | |
| 39 | ty::InstanceKind::VTableShim(def_id) => { | |
| 37 | let mut result = match shim { | |
| 38 | ty::ShimKind::VTable(def_id) => { | |
| 40 | 39 | let adjustment = Adjustment::Deref { source: DerefSource::MutPtr }; |
| 41 | build_call_shim(tcx, instance, Some(adjustment), CallKind::Direct(def_id)) | |
| 40 | build_call_shim(tcx, shim, Some(adjustment), CallKind::Direct(def_id)) | |
| 42 | 41 | } |
| 43 | ty::InstanceKind::FnPtrShim(def_id, ty) => { | |
| 42 | ty::ShimKind::FnPtr(def_id, ty) => { | |
| 44 | 43 | let trait_ = tcx.parent(def_id); |
| 45 | 44 | // Supports `Fn` or `async Fn` traits. |
| 46 | 45 | let adjustment = match tcx |
| ... | ... | @@ -53,17 +52,17 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< |
| 53 | 52 | None => bug!("fn pointer {:?} is not an fn", ty), |
| 54 | 53 | }; |
| 55 | 54 | |
| 56 | build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect(ty)) | |
| 55 | build_call_shim(tcx, shim, Some(adjustment), CallKind::Indirect(ty)) | |
| 57 | 56 | } |
| 58 | 57 | // We are generating a call back to our def-id, which the |
| 59 | 58 | // codegen backend knows to turn to an actual call, be it |
| 60 | 59 | // a virtual call, or a direct call to a function for which |
| 61 | 60 | // indirect calls must be codegen'd differently than direct ones |
| 62 | 61 | // (such as `#[track_caller]`). |
| 63 | ty::InstanceKind::ReifyShim(def_id, _) => { | |
| 64 | build_call_shim(tcx, instance, None, CallKind::Direct(def_id)) | |
| 62 | ty::ShimKind::Reify(def_id, _) => { | |
| 63 | build_call_shim(tcx, shim, None, CallKind::Direct(def_id)) | |
| 65 | 64 | } |
| 66 | ty::InstanceKind::ClosureOnceShim { call_once: _, closure: _, track_caller: _ } => { | |
| 65 | ty::ShimKind::ClosureOnce { call_once: _, closure: _, track_caller: _ } => { | |
| 67 | 66 | let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP); |
| 68 | 67 | let call_mut = tcx |
| 69 | 68 | .associated_items(fn_mut) |
| ... | ... | @@ -72,15 +71,14 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< |
| 72 | 71 | .unwrap() |
| 73 | 72 | .def_id; |
| 74 | 73 | |
| 75 | build_call_shim(tcx, instance, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) | |
| 74 | build_call_shim(tcx, shim, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) | |
| 76 | 75 | } |
| 77 | 76 | |
| 78 | ty::InstanceKind::ConstructCoroutineInClosureShim { | |
| 79 | coroutine_closure_def_id, | |
| 80 | receiver_by_ref, | |
| 81 | } => build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref), | |
| 77 | ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref } => { | |
| 78 | build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref) | |
| 79 | } | |
| 82 | 80 | |
| 83 | ty::InstanceKind::DropGlue(def_id, ty) => { | |
| 81 | ty::ShimKind::DropGlue(def_id, ty) => { | |
| 84 | 82 | // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end |
| 85 | 83 | // of this function. Is this intentional? |
| 86 | 84 | if let Some(&ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) { |
| ... | ... | @@ -110,7 +108,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< |
| 110 | 108 | |
| 111 | 109 | let mut body = |
| 112 | 110 | EarlyBinder::bind(body.clone()).instantiate(tcx, args).skip_norm_wip(); |
| 113 | debug!("make_shim({:?}) = {:?}", instance, body); | |
| 111 | debug!("make_shim({:?}) = {:?}", shim, body); | |
| 114 | 112 | |
| 115 | 113 | pm::run_passes( |
| 116 | 114 | tcx, |
| ... | ... | @@ -129,10 +127,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< |
| 129 | 127 | |
| 130 | 128 | build_drop_shim(tcx, def_id, ty, ty::TypingEnv::post_analysis(tcx, def_id)) |
| 131 | 129 | } |
| 132 | ty::InstanceKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance), | |
| 133 | ty::InstanceKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), | |
| 134 | ty::InstanceKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), | |
| 135 | ty::InstanceKind::FutureDropPollShim(def_id, proxy_ty, impl_ty) => { | |
| 130 | ty::ShimKind::ThreadLocal(..) => build_thread_local_shim(tcx, shim), | |
| 131 | ty::ShimKind::Clone(def_id, ty) => build_clone_shim(tcx, def_id, ty), | |
| 132 | ty::ShimKind::FnPtrAddr(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), | |
| 133 | ty::ShimKind::FutureDropPoll(def_id, proxy_ty, impl_ty) => { | |
| 136 | 134 | let mut body = |
| 137 | 135 | async_destructor_ctor::build_future_drop_poll_shim(tcx, def_id, proxy_ty, impl_ty); |
| 138 | 136 | |
| ... | ... | @@ -148,10 +146,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< |
| 148 | 146 | pm::Optimizations::Allowed, |
| 149 | 147 | ); |
| 150 | 148 | run_optimization_passes(tcx, &mut body); |
| 151 | debug!("make_shim({:?}) = {:?}", instance, body); | |
| 149 | debug!("make_shim({:?}) = {:?}", shim, body); | |
| 152 | 150 | return body; |
| 153 | 151 | } |
| 154 | ty::InstanceKind::AsyncDropGlue(def_id, ty) => { | |
| 152 | ty::ShimKind::AsyncDropGlue(def_id, ty) => { | |
| 155 | 153 | let mut body = async_destructor_ctor::build_async_drop_shim(tcx, def_id, ty); |
| 156 | 154 | |
| 157 | 155 | // Main pass required here is StateTransform to convert sync drop ladder |
| ... | ... | @@ -170,23 +168,17 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< |
| 170 | 168 | Some(MirPhase::Runtime(RuntimePhase::PostCleanup)), |
| 171 | 169 | ); |
| 172 | 170 | run_optimization_passes(tcx, &mut body); |
| 173 | debug!("make_shim({:?}) = {:?}", instance, body); | |
| 171 | debug!("make_shim({:?}) = {:?}", shim, body); | |
| 174 | 172 | return body; |
| 175 | 173 | } |
| 176 | 174 | |
| 177 | ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) => { | |
| 175 | ty::ShimKind::AsyncDropGlueCtor(def_id, ty) => { | |
| 178 | 176 | let body = async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty); |
| 179 | debug!("make_shim({:?}) = {:?}", instance, body); | |
| 177 | debug!("make_shim({:?}) = {:?}", shim, body); | |
| 180 | 178 | return body; |
| 181 | 179 | } |
| 182 | ty::InstanceKind::Virtual(..) => { | |
| 183 | bug!("InstanceKind::Virtual ({:?}) is for direct calls only", instance) | |
| 184 | } | |
| 185 | ty::InstanceKind::Intrinsic(_) => { | |
| 186 | bug!("creating shims from intrinsics ({:?}) is unsupported", instance) | |
| 187 | } | |
| 188 | 180 | }; |
| 189 | debug!("make_shim({:?}) = untransformed {:?}", instance, result); | |
| 181 | debug!("make_shim({:?}) = untransformed {:?}", shim, result); | |
| 190 | 182 | |
| 191 | 183 | deref_finder(tcx, &mut result, false); |
| 192 | 184 | |
| ... | ... | @@ -211,7 +203,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< |
| 211 | 203 | Some(MirPhase::Runtime(RuntimePhase::Optimized)), |
| 212 | 204 | ); |
| 213 | 205 | |
| 214 | debug!("make_shim({:?}) = {:?}", instance, result); | |
| 206 | debug!("make_shim({:?}) = {:?}", shim, result); | |
| 215 | 207 | |
| 216 | 208 | result |
| 217 | 209 | } |
| ... | ... | @@ -300,7 +292,7 @@ pub fn build_drop_shim<'tcx>( |
| 300 | 292 | } |
| 301 | 293 | block(&mut blocks, TerminatorKind::Return); |
| 302 | 294 | |
| 303 | let source = MirSource::from_instance(ty::InstanceKind::DropGlue(def_id, ty)); | |
| 295 | let source = MirSource::from_shim(ty::ShimKind::DropGlue(def_id, ty)); | |
| 304 | 296 | let mut body = |
| 305 | 297 | new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); |
| 306 | 298 | |
| ... | ... | @@ -480,11 +472,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { |
| 480 | 472 | } |
| 481 | 473 | } |
| 482 | 474 | |
| 483 | fn build_thread_local_shim<'tcx>( | |
| 484 | tcx: TyCtxt<'tcx>, | |
| 485 | instance: ty::InstanceKind<'tcx>, | |
| 486 | ) -> Body<'tcx> { | |
| 487 | let def_id = instance.def_id(); | |
| 475 | fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { | |
| 476 | let def_id = shim.def_id(); | |
| 488 | 477 | |
| 489 | 478 | let span = tcx.def_span(def_id); |
| 490 | 479 | let source_info = SourceInfo::outermost(span); |
| ... | ... | @@ -502,7 +491,7 @@ fn build_thread_local_shim<'tcx>( |
| 502 | 491 | )]); |
| 503 | 492 | |
| 504 | 493 | new_body( |
| 505 | MirSource::from_instance(instance), | |
| 494 | MirSource::from_shim(shim), | |
| 506 | 495 | blocks, |
| 507 | 496 | IndexVec::from_raw(vec![LocalDecl::new(tcx.thread_local_ptr_ty(def_id), span)]), |
| 508 | 497 | 0, |
| ... | ... | @@ -565,10 +554,8 @@ impl<'tcx> CloneShimBuilder<'tcx> { |
| 565 | 554 | } |
| 566 | 555 | |
| 567 | 556 | fn into_mir(self) -> Body<'tcx> { |
| 568 | let source = MirSource::from_instance(ty::InstanceKind::CloneShim( | |
| 569 | self.def_id, | |
| 570 | self.sig.inputs_and_output[0], | |
| 571 | )); | |
| 557 | let source = | |
| 558 | MirSource::from_shim(ty::ShimKind::Clone(self.def_id, self.sig.inputs_and_output[0])); | |
| 572 | 559 | new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span) |
| 573 | 560 | } |
| 574 | 561 | |
| ... | ... | @@ -776,14 +763,14 @@ impl<'tcx> CloneShimBuilder<'tcx> { |
| 776 | 763 | #[instrument(level = "debug", skip(tcx), ret)] |
| 777 | 764 | fn build_call_shim<'tcx>( |
| 778 | 765 | tcx: TyCtxt<'tcx>, |
| 779 | instance: ty::InstanceKind<'tcx>, | |
| 766 | shim: ty::ShimKind<'tcx>, | |
| 780 | 767 | rcvr_adjustment: Option<Adjustment>, |
| 781 | 768 | call_kind: CallKind<'tcx>, |
| 782 | 769 | ) -> Body<'tcx> { |
| 783 | 770 | // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used |
| 784 | 771 | // to instantiate into the signature of the shim. It is not necessary for users of this |
| 785 | 772 | // MIR body to perform further instantiations (see `InstanceKind::has_polymorphic_mir_body`). |
| 786 | let (sig_args, untuple_args) = if let ty::InstanceKind::FnPtrShim(_, ty) = instance { | |
| 773 | let (sig_args, untuple_args) = if let ty::ShimKind::FnPtr(_, ty) = shim { | |
| 787 | 774 | let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx)); |
| 788 | 775 | |
| 789 | 776 | let untuple_args = sig.inputs(); |
| ... | ... | @@ -796,12 +783,12 @@ fn build_call_shim<'tcx>( |
| 796 | 783 | (None, None) |
| 797 | 784 | }; |
| 798 | 785 | |
| 799 | let def_id = instance.def_id(); | |
| 786 | let def_id = shim.def_id(); | |
| 800 | 787 | |
| 801 | 788 | let sig = tcx.fn_sig(def_id); |
| 802 | 789 | let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig)); |
| 803 | 790 | |
| 804 | assert_eq!(sig_args.is_some(), !instance.has_polymorphic_mir_body()); | |
| 791 | assert_eq!(sig_args.is_some(), !shim.has_polymorphic_mir_body()); | |
| 805 | 792 | let mut sig = if let Some(sig_args) = sig_args { |
| 806 | 793 | sig.instantiate(tcx, &sig_args).skip_norm_wip() |
| 807 | 794 | } else { |
| ... | ... | @@ -830,14 +817,14 @@ fn build_call_shim<'tcx>( |
| 830 | 817 | DerefSource::MutRef => Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fnty), |
| 831 | 818 | DerefSource::MutPtr => Ty::new_mut_ptr(tcx, fnty), |
| 832 | 819 | }, |
| 833 | Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {instance:?}"), | |
| 820 | Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {shim:?}"), | |
| 834 | 821 | }; |
| 835 | 822 | sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); |
| 836 | 823 | } |
| 837 | 824 | |
| 838 | 825 | // FIXME: Avoid having to adjust the signature both here and in |
| 839 | 826 | // `fn_sig_for_fn_abi`. |
| 840 | if let ty::InstanceKind::VTableShim(..) = instance { | |
| 827 | if let ty::ShimKind::VTable(..) = shim { | |
| 841 | 828 | // Modify fn(self, ...) to fn(self: *mut Self, ...) |
| 842 | 829 | let mut inputs_and_output = sig.inputs_and_output.to_vec(); |
| 843 | 830 | let self_arg = &mut inputs_and_output[0]; |
| ... | ... | @@ -995,7 +982,7 @@ fn build_call_shim<'tcx>( |
| 995 | 982 | } |
| 996 | 983 | |
| 997 | 984 | let mut body = |
| 998 | new_body(MirSource::from_instance(instance), blocks, local_decls, sig.inputs().len(), span); | |
| 985 | new_body(MirSource::from_shim(shim), blocks, local_decls, sig.inputs().len(), span); | |
| 999 | 986 | |
| 1000 | 987 | if let ExternAbi::RustCall = sig.abi() { |
| 1001 | 988 | body.spread_arg = Some(Local::new(sig.inputs().len())); |
| ... | ... | @@ -1119,7 +1106,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t |
| 1119 | 1106 | Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), |
| 1120 | 1107 | false, |
| 1121 | 1108 | ); |
| 1122 | let source = MirSource::from_instance(ty::InstanceKind::FnPtrAddrShim(def_id, self_ty)); | |
| 1109 | let source = MirSource::from_shim(ty::ShimKind::FnPtrAddr(def_id, self_ty)); | |
| 1123 | 1110 | new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span) |
| 1124 | 1111 | } |
| 1125 | 1112 | |
| ... | ... | @@ -1218,7 +1205,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( |
| 1218 | 1205 | false, |
| 1219 | 1206 | ); |
| 1220 | 1207 | |
| 1221 | let source = MirSource::from_instance(ty::InstanceKind::ConstructCoroutineInClosureShim { | |
| 1208 | let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosure { | |
| 1222 | 1209 | coroutine_closure_def_id, |
| 1223 | 1210 | receiver_by_ref, |
| 1224 | 1211 | }); |
compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs+10-10| ... | ... | @@ -106,7 +106,7 @@ pub(super) fn build_async_drop_shim<'tcx>( |
| 106 | 106 | ); |
| 107 | 107 | block(&mut blocks, TerminatorKind::Return); |
| 108 | 108 | |
| 109 | let source = MirSource::from_instance(ty::InstanceKind::AsyncDropGlue(def_id, ty)); | |
| 109 | let source = MirSource::from_shim(ty::ShimKind::AsyncDropGlue(def_id, ty)); | |
| 110 | 110 | let mut body = |
| 111 | 111 | new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); |
| 112 | 112 | |
| ... | ... | @@ -175,17 +175,17 @@ pub(super) fn build_future_drop_poll_shim<'tcx>( |
| 175 | 175 | proxy_ty: Ty<'tcx>, |
| 176 | 176 | impl_ty: Ty<'tcx>, |
| 177 | 177 | ) -> Body<'tcx> { |
| 178 | let instance = ty::InstanceKind::FutureDropPollShim(def_id, proxy_ty, impl_ty); | |
| 178 | let shim = ty::ShimKind::FutureDropPoll(def_id, proxy_ty, impl_ty); | |
| 179 | 179 | let ty::Coroutine(coroutine_def_id, _) = impl_ty.kind() else { |
| 180 | bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", instance); | |
| 180 | bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", shim); | |
| 181 | 181 | }; |
| 182 | 182 | |
| 183 | 183 | let span = tcx.def_span(def_id); |
| 184 | 184 | |
| 185 | 185 | if tcx.is_async_drop_in_place_coroutine(*coroutine_def_id) { |
| 186 | build_adrop_for_adrop_shim(tcx, proxy_ty, impl_ty, span, instance) | |
| 186 | build_adrop_for_adrop_shim(tcx, proxy_ty, impl_ty, span, shim) | |
| 187 | 187 | } else { |
| 188 | build_adrop_for_coroutine_shim(tcx, proxy_ty, impl_ty, span, instance) | |
| 188 | build_adrop_for_coroutine_shim(tcx, proxy_ty, impl_ty, span, shim) | |
| 189 | 189 | } |
| 190 | 190 | } |
| 191 | 191 | |
| ... | ... | @@ -198,16 +198,16 @@ fn build_adrop_for_coroutine_shim<'tcx>( |
| 198 | 198 | proxy_ty: Ty<'tcx>, |
| 199 | 199 | impl_ty: Ty<'tcx>, |
| 200 | 200 | span: Span, |
| 201 | instance: ty::InstanceKind<'tcx>, | |
| 201 | shim: ty::ShimKind<'tcx>, | |
| 202 | 202 | ) -> Body<'tcx> { |
| 203 | 203 | let ty::Coroutine(coroutine_def_id, impl_args) = impl_ty.kind() else { |
| 204 | bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", instance); | |
| 204 | bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", shim); | |
| 205 | 205 | }; |
| 206 | 206 | let source_info = SourceInfo::outermost(span); |
| 207 | 207 | let body = tcx.optimized_mir(*coroutine_def_id).future_drop_poll().unwrap(); |
| 208 | 208 | let mut body: Body<'tcx> = |
| 209 | 209 | EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args).skip_norm_wip(); |
| 210 | body.source.instance = instance; | |
| 210 | body.source.instance = ty::InstanceKind::Shim(shim); | |
| 211 | 211 | body.phase = MirPhase::Runtime(RuntimePhase::Initial); |
| 212 | 212 | body.var_debug_info.clear(); |
| 213 | 213 | |
| ... | ... | @@ -291,7 +291,7 @@ fn build_adrop_for_adrop_shim<'tcx>( |
| 291 | 291 | proxy_ty: Ty<'tcx>, |
| 292 | 292 | impl_ty: Ty<'tcx>, |
| 293 | 293 | span: Span, |
| 294 | instance: ty::InstanceKind<'tcx>, | |
| 294 | shim: ty::ShimKind<'tcx>, | |
| 295 | 295 | ) -> Body<'tcx> { |
| 296 | 296 | let source_info = SourceInfo::outermost(span); |
| 297 | 297 | let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty); |
| ... | ... | @@ -413,7 +413,7 @@ fn build_adrop_for_adrop_shim<'tcx>( |
| 413 | 413 | false, |
| 414 | 414 | )); |
| 415 | 415 | |
| 416 | let source = MirSource::from_instance(instance); | |
| 416 | let source = MirSource::from_shim(shim); | |
| 417 | 417 | let mut body = new_body(source, blocks, locals, sig.inputs().len(), span); |
| 418 | 418 | body.phase = MirPhase::Runtime(RuntimePhase::Initial); |
| 419 | 419 | return body; |
compiler/rustc_monomorphize/src/collector.rs+17-17| ... | ... | @@ -226,8 +226,8 @@ use rustc_middle::query::TyCtxtAt; |
| 226 | 226 | use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; |
| 227 | 227 | use rustc_middle::ty::layout::ValidityRequirement; |
| 228 | 228 | use rustc_middle::ty::{ |
| 229 | self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable, | |
| 230 | TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, | |
| 229 | self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, ShimKind, Ty, TyCtxt, | |
| 230 | TypeFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, | |
| 231 | 231 | }; |
| 232 | 232 | use rustc_middle::util::Providers; |
| 233 | 233 | use rustc_middle::{bug, span_bug}; |
| ... | ... | @@ -447,7 +447,7 @@ fn collect_items_rec<'tcx>( |
| 447 | 447 | used_items.push(respan( |
| 448 | 448 | starting_item.span, |
| 449 | 449 | MonoItem::Fn(Instance { |
| 450 | def: InstanceKind::ThreadLocalShim(def_id), | |
| 450 | def: InstanceKind::Shim(ShimKind::ThreadLocal(def_id)), | |
| 451 | 451 | args: GenericArgs::empty(), |
| 452 | 452 | }), |
| 453 | 453 | )); |
| ... | ... | @@ -1013,10 +1013,10 @@ fn visit_instance_use<'tcx>( |
| 1013 | 1013 | bug!("{:?} being reified", instance); |
| 1014 | 1014 | } |
| 1015 | 1015 | } |
| 1016 | ty::InstanceKind::ThreadLocalShim(..) => { | |
| 1016 | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => { | |
| 1017 | 1017 | bug!("{:?} being reified", instance); |
| 1018 | 1018 | } |
| 1019 | ty::InstanceKind::DropGlue(_, None) => { | |
| 1019 | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => { | |
| 1020 | 1020 | // Don't need to emit noop drop glue if we are calling directly. |
| 1021 | 1021 | // |
| 1022 | 1022 | // Note that we also optimize away the call to visit_instance_use in vtable construction |
| ... | ... | @@ -1025,18 +1025,18 @@ fn visit_instance_use<'tcx>( |
| 1025 | 1025 | output.push(create_fn_mono_item(tcx, instance, source)); |
| 1026 | 1026 | } |
| 1027 | 1027 | } |
| 1028 | ty::InstanceKind::DropGlue(_, Some(_)) | |
| 1029 | | ty::InstanceKind::FutureDropPollShim(..) | |
| 1030 | | ty::InstanceKind::AsyncDropGlue(_, _) | |
| 1031 | | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) | |
| 1032 | | ty::InstanceKind::VTableShim(..) | |
| 1033 | | ty::InstanceKind::ReifyShim(..) | |
| 1034 | | ty::InstanceKind::ClosureOnceShim { .. } | |
| 1035 | | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 1036 | | ty::InstanceKind::Item(..) | |
| 1037 | | ty::InstanceKind::FnPtrShim(..) | |
| 1038 | | ty::InstanceKind::CloneShim(..) | |
| 1039 | | ty::InstanceKind::FnPtrAddrShim(..) => { | |
| 1028 | ty::InstanceKind::Item(..) | |
| 1029 | | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(_))) | |
| 1030 | | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | |
| 1031 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, _)) | |
| 1032 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, _)) | |
| 1033 | | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) | |
| 1034 | | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) | |
| 1035 | | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) | |
| 1036 | | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) | |
| 1037 | | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) | |
| 1038 | | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) | |
| 1039 | | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) => { | |
| 1040 | 1040 | output.push(create_fn_mono_item(tcx, instance, source)); |
| 1041 | 1041 | } |
| 1042 | 1042 | } |
compiler/rustc_monomorphize/src/partitioning.rs+29-29| ... | ... | @@ -115,7 +115,7 @@ use rustc_middle::mono::{ |
| 115 | 115 | MonoItemPartitions, Visibility, |
| 116 | 116 | }; |
| 117 | 117 | use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths}; |
| 118 | use rustc_middle::ty::{self, InstanceKind, TyCtxt}; | |
| 118 | use rustc_middle::ty::{self, InstanceKind, ShimKind, TyCtxt}; | |
| 119 | 119 | use rustc_middle::util::Providers; |
| 120 | 120 | use rustc_session::CodegenUnits; |
| 121 | 121 | use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath}; |
| ... | ... | @@ -630,20 +630,20 @@ fn characteristic_def_id_of_mono_item<'tcx>( |
| 630 | 630 | MonoItem::Fn(instance) => { |
| 631 | 631 | let def_id = match instance.def { |
| 632 | 632 | ty::InstanceKind::Item(def) => def, |
| 633 | ty::InstanceKind::VTableShim(..) | |
| 634 | | ty::InstanceKind::ReifyShim(..) | |
| 635 | | ty::InstanceKind::FnPtrShim(..) | |
| 636 | | ty::InstanceKind::ClosureOnceShim { .. } | |
| 637 | | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 638 | | ty::InstanceKind::Intrinsic(..) | |
| 639 | | ty::InstanceKind::DropGlue(..) | |
| 633 | ty::InstanceKind::Intrinsic(..) | |
| 640 | 634 | | ty::InstanceKind::Virtual(..) |
| 641 | | ty::InstanceKind::CloneShim(..) | |
| 642 | | ty::InstanceKind::ThreadLocalShim(..) | |
| 643 | | ty::InstanceKind::FnPtrAddrShim(..) | |
| 644 | | ty::InstanceKind::FutureDropPollShim(..) | |
| 645 | | ty::InstanceKind::AsyncDropGlue(..) | |
| 646 | | ty::InstanceKind::AsyncDropGlueCtorShim(..) => return None, | |
| 635 | | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) | |
| 636 | | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) | |
| 637 | | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) | |
| 638 | | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) | |
| 639 | | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) | |
| 640 | | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) | |
| 641 | | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) | |
| 642 | | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) | |
| 643 | | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) | |
| 644 | | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | |
| 645 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) | |
| 646 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(..)) => return None, | |
| 647 | 647 | }; |
| 648 | 648 | |
| 649 | 649 | // If this is a method, we want to put it into the same module as |
| ... | ... | @@ -794,27 +794,27 @@ fn mono_item_visibility<'tcx>( |
| 794 | 794 | |
| 795 | 795 | let def_id = match instance.def { |
| 796 | 796 | InstanceKind::Item(def_id) |
| 797 | | InstanceKind::DropGlue(def_id, Some(_)) | |
| 798 | | InstanceKind::FutureDropPollShim(def_id, _, _) | |
| 799 | | InstanceKind::AsyncDropGlue(def_id, _) | |
| 800 | | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id, | |
| 797 | | InstanceKind::Shim(ShimKind::DropGlue(def_id, Some(_))) | |
| 798 | | InstanceKind::Shim(ShimKind::FutureDropPoll(def_id, _, _)) | |
| 799 | | InstanceKind::Shim(ShimKind::AsyncDropGlue(def_id, _)) | |
| 800 | | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(def_id, _)) => def_id, | |
| 801 | 801 | |
| 802 | 802 | // We match the visibility of statics here |
| 803 | InstanceKind::ThreadLocalShim(def_id) => { | |
| 803 | InstanceKind::Shim(ShimKind::ThreadLocal(def_id)) => { | |
| 804 | 804 | return static_visibility(tcx, can_be_internalized, def_id); |
| 805 | 805 | } |
| 806 | 806 | |
| 807 | 807 | // These are all compiler glue and such, never exported, always hidden. |
| 808 | InstanceKind::VTableShim(..) | |
| 809 | | InstanceKind::ReifyShim(..) | |
| 810 | | InstanceKind::FnPtrShim(..) | |
| 808 | InstanceKind::Shim(ShimKind::VTable(..)) | |
| 809 | | InstanceKind::Shim(ShimKind::Reify(..)) | |
| 810 | | InstanceKind::Shim(ShimKind::FnPtr(..)) | |
| 811 | 811 | | InstanceKind::Virtual(..) |
| 812 | 812 | | InstanceKind::Intrinsic(..) |
| 813 | | InstanceKind::ClosureOnceShim { .. } | |
| 814 | | InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 815 | | InstanceKind::DropGlue(..) | |
| 816 | | InstanceKind::CloneShim(..) | |
| 817 | | InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden, | |
| 813 | | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) | |
| 814 | | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | |
| 815 | | InstanceKind::Shim(ShimKind::DropGlue(..)) | |
| 816 | | InstanceKind::Shim(ShimKind::Clone(..)) | |
| 817 | | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return Visibility::Hidden, | |
| 818 | 818 | }; |
| 819 | 819 | |
| 820 | 820 | // Both the `start_fn` lang item and `main` itself should not be exported, |
| ... | ... | @@ -1331,8 +1331,8 @@ pub(crate) fn provide(providers: &mut Providers) { |
| 1331 | 1331 | // "Normal" functions size estimate: the number of |
| 1332 | 1332 | // statements, plus one for the terminator. |
| 1333 | 1333 | InstanceKind::Item(..) |
| 1334 | | InstanceKind::DropGlue(..) | |
| 1335 | | InstanceKind::AsyncDropGlueCtorShim(..) => { | |
| 1334 | | InstanceKind::Shim(ShimKind::DropGlue(..)) | |
| 1335 | | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => { | |
| 1336 | 1336 | let mir = tcx.instance_mir(instance.def); |
| 1337 | 1337 | mir.basic_blocks |
| 1338 | 1338 | .iter() |
compiler/rustc_parse/Cargo.toml+1-1| ... | ... | @@ -6,7 +6,7 @@ edition = "2024" |
| 6 | 6 | [dependencies] |
| 7 | 7 | # tidy-alphabetical-start |
| 8 | 8 | bitflags = "2.4.1" |
| 9 | rustc-literal-escaper = "0.0.7" | |
| 9 | rustc-literal-escaper = "0.0.8" | |
| 10 | 10 | rustc_ast = { path = "../rustc_ast" } |
| 11 | 11 | rustc_ast_pretty = { path = "../rustc_ast_pretty" } |
| 12 | 12 | rustc_data_structures = { path = "../rustc_data_structures" } |
compiler/rustc_parse_format/Cargo.toml+1-1| ... | ... | @@ -5,7 +5,7 @@ edition = "2024" |
| 5 | 5 | |
| 6 | 6 | [dependencies] |
| 7 | 7 | # tidy-alphabetical-start |
| 8 | rustc-literal-escaper = "0.0.7" | |
| 8 | rustc-literal-escaper = "0.0.8" | |
| 9 | 9 | rustc_lexer = { path = "../rustc_lexer" } |
| 10 | 10 | # tidy-alphabetical-end |
| 11 | 11 |
compiler/rustc_passes/src/diagnostics.rs-20| ... | ... | @@ -5,7 +5,6 @@ use rustc_errors::codes::*; |
| 5 | 5 | use rustc_errors::{ |
| 6 | 6 | Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, msg, |
| 7 | 7 | }; |
| 8 | use rustc_hir::Target; | |
| 9 | 8 | use rustc_macros::{Diagnostic, Subdiagnostic}; |
| 10 | 9 | use rustc_middle::ty::{MainDefinition, Ty}; |
| 11 | 10 | use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; |
| ... | ... | @@ -326,14 +325,6 @@ pub(crate) struct DeprecatedAnnotationHasNoEffect { |
| 326 | 325 | pub span: Span, |
| 327 | 326 | } |
| 328 | 327 | |
| 329 | #[derive(Diagnostic)] | |
| 330 | #[diag("unknown external lang item: `{$lang_item}`", code = E0264)] | |
| 331 | pub(crate) struct UnknownExternLangItem { | |
| 332 | #[primary_span] | |
| 333 | pub span: Span, | |
| 334 | pub lang_item: Symbol, | |
| 335 | } | |
| 336 | ||
| 337 | 328 | #[derive(Diagnostic)] |
| 338 | 329 | #[diag("`#[panic_handler]` function required, but not found")] |
| 339 | 330 | pub(crate) struct MissingPanicHandler; |
| ... | ... | @@ -398,17 +389,6 @@ pub(crate) struct LangItemWithTargetFeature { |
| 398 | 389 | pub sig_span: Span, |
| 399 | 390 | } |
| 400 | 391 | |
| 401 | #[derive(Diagnostic)] | |
| 402 | #[diag("`{$name}` lang item must be applied to a {$expected_target}", code = E0718)] | |
| 403 | pub(crate) struct LangItemOnIncorrectTarget { | |
| 404 | #[primary_span] | |
| 405 | #[label("attribute should be applied to a {$expected_target}, not a {$actual_target}")] | |
| 406 | pub span: Span, | |
| 407 | pub name: Symbol, | |
| 408 | pub expected_target: Target, | |
| 409 | pub actual_target: Target, | |
| 410 | } | |
| 411 | ||
| 412 | 392 | #[derive(Diagnostic)] |
| 413 | 393 | #[diag("duplicate diagnostic item in crate `{$crate_name}`: `{$name}`")] |
| 414 | 394 | pub(crate) struct DuplicateDiagnosticItemInCrate { |
compiler/rustc_passes/src/lang_items.rs+9-14| ... | ... | @@ -18,9 +18,7 @@ use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; |
| 18 | 18 | use rustc_session::cstore::ExternCrate; |
| 19 | 19 | use rustc_span::{Span, Symbol, sym}; |
| 20 | 20 | |
| 21 | use crate::diagnostics::{ | |
| 22 | DuplicateLangItem, IncorrectCrateType, IncorrectTarget, LangItemOnIncorrectTarget, | |
| 23 | }; | |
| 21 | use crate::diagnostics::{DuplicateLangItem, IncorrectCrateType, IncorrectTarget}; | |
| 24 | 22 | use crate::weak_lang_items; |
| 25 | 23 | |
| 26 | 24 | pub(crate) enum Duplicate { |
| ... | ... | @@ -63,8 +61,14 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { |
| 63 | 61 | ) { |
| 64 | 62 | if let Some((name, attr_span)) = extract_ast(attrs) { |
| 65 | 63 | match LangItem::from_name(name) { |
| 66 | // Known lang item with attribute on correct target. | |
| 67 | Some(lang_item) if actual_target == lang_item.target() => { | |
| 64 | // Known lang item | |
| 65 | Some(lang_item) => { | |
| 66 | if actual_target != lang_item.target() { | |
| 67 | self.tcx | |
| 68 | .dcx() | |
| 69 | .delayed_bug("lang item target is checked in attribute parser"); | |
| 70 | return; | |
| 71 | } | |
| 68 | 72 | self.collect_item_extended( |
| 69 | 73 | lang_item, |
| 70 | 74 | def_id, |
| ... | ... | @@ -74,15 +78,6 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { |
| 74 | 78 | actual_target, |
| 75 | 79 | ); |
| 76 | 80 | } |
| 77 | // Known lang item with attribute on incorrect target. | |
| 78 | Some(lang_item) => { | |
| 79 | self.tcx.dcx().emit_err(LangItemOnIncorrectTarget { | |
| 80 | span: attr_span, | |
| 81 | name, | |
| 82 | expected_target: lang_item.target(), | |
| 83 | actual_target, | |
| 84 | }); | |
| 85 | } | |
| 86 | 81 | // Unknown lang item. |
| 87 | 82 | _ => { |
| 88 | 83 | self.tcx.dcx().delayed_bug("unknown lang item"); |
compiler/rustc_passes/src/weak_lang_items.rs+10-16| ... | ... | @@ -9,9 +9,7 @@ use rustc_middle::middle::lang_items::required; |
| 9 | 9 | use rustc_middle::ty::TyCtxt; |
| 10 | 10 | use rustc_session::config::CrateType; |
| 11 | 11 | |
| 12 | use crate::diagnostics::{ | |
| 13 | MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd, UnknownExternLangItem, | |
| 14 | }; | |
| 12 | use crate::diagnostics::{MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd}; | |
| 15 | 13 | use crate::lang_items::extract_ast; |
| 16 | 14 | |
| 17 | 15 | /// Checks the crate for usage of weak lang items, returning a vector of all the |
| ... | ... | @@ -28,27 +26,23 @@ pub(crate) fn check_crate( |
| 28 | 26 | items.missing.push(LangItem::EhPersonality); |
| 29 | 27 | } |
| 30 | 28 | |
| 31 | visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate); | |
| 29 | visit::Visitor::visit_crate(&mut WeakLangItemVisitor { items }, krate); | |
| 32 | 30 | |
| 33 | 31 | verify(tcx, items); |
| 34 | 32 | } |
| 35 | 33 | |
| 36 | struct WeakLangItemVisitor<'a, 'tcx> { | |
| 37 | tcx: TyCtxt<'tcx>, | |
| 34 | struct WeakLangItemVisitor<'a> { | |
| 38 | 35 | items: &'a mut lang_items::LanguageItems, |
| 39 | 36 | } |
| 40 | 37 | |
| 41 | impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> { | |
| 38 | impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_> { | |
| 42 | 39 | fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) { |
| 43 | if let Some((lang_item, _)) = extract_ast(&i.attrs) { | |
| 44 | if let Some(item) = LangItem::from_name(lang_item) | |
| 45 | && item.is_weak() | |
| 46 | { | |
| 47 | if self.items.get(item).is_none() { | |
| 48 | self.items.missing.push(item); | |
| 49 | } | |
| 50 | } else { | |
| 51 | self.tcx.dcx().emit_err(UnknownExternLangItem { span: i.span, lang_item }); | |
| 40 | if let Some((lang_item, _)) = extract_ast(&i.attrs) | |
| 41 | && let Some(item) = LangItem::from_name(lang_item) | |
| 42 | && item.is_weak() | |
| 43 | { | |
| 44 | if self.items.get(item).is_none() { | |
| 45 | self.items.missing.push(item); | |
| 52 | 46 | } |
| 53 | 47 | } |
| 54 | 48 | } |
compiler/rustc_proc_macro/Cargo.toml+1-1| ... | ... | @@ -16,7 +16,7 @@ doctest = false |
| 16 | 16 | |
| 17 | 17 | [dependencies] |
| 18 | 18 | # tidy-alphabetical-start |
| 19 | rustc-literal-escaper = "0.0.7" | |
| 19 | rustc-literal-escaper = "0.0.8" | |
| 20 | 20 | # tidy-alphabetical-end |
| 21 | 21 | |
| 22 | 22 | [features] |
compiler/rustc_public/src/unstable/convert/stable/ty.rs+1-12| ... | ... | @@ -994,18 +994,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { |
| 994 | 994 | ty::InstanceKind::Virtual(_def_id, idx) => { |
| 995 | 995 | crate::mir::mono::InstanceKind::Virtual { idx } |
| 996 | 996 | } |
| 997 | ty::InstanceKind::VTableShim(..) | |
| 998 | | ty::InstanceKind::ReifyShim(..) | |
| 999 | | ty::InstanceKind::FnPtrAddrShim(..) | |
| 1000 | | ty::InstanceKind::ClosureOnceShim { .. } | |
| 1001 | | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } | |
| 1002 | | ty::InstanceKind::ThreadLocalShim(..) | |
| 1003 | | ty::InstanceKind::DropGlue(..) | |
| 1004 | | ty::InstanceKind::CloneShim(..) | |
| 1005 | | ty::InstanceKind::FnPtrShim(..) | |
| 1006 | | ty::InstanceKind::FutureDropPollShim(..) | |
| 1007 | | ty::InstanceKind::AsyncDropGlue(..) | |
| 1008 | | ty::InstanceKind::AsyncDropGlueCtorShim(..) => crate::mir::mono::InstanceKind::Shim, | |
| 997 | ty::InstanceKind::Shim(..) => crate::mir::mono::InstanceKind::Shim, | |
| 1009 | 998 | }; |
| 1010 | 999 | crate::mir::mono::Instance { def, kind } |
| 1011 | 1000 | } |
compiler/rustc_public_bridge/src/context/impls.rs+1-1| ... | ... | @@ -645,7 +645,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { |
| 645 | 645 | |
| 646 | 646 | /// Check if this is an empty DropGlue shim. |
| 647 | 647 | pub fn is_empty_drop_shim(&self, instance: ty::Instance<'tcx>) -> bool { |
| 648 | matches!(instance.def, ty::InstanceKind::DropGlue(_, None)) | |
| 648 | matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None))) | |
| 649 | 649 | } |
| 650 | 650 | |
| 651 | 651 | /// Convert a non-generic crate item into an instance. |
compiler/rustc_resolve/src/build_reduced_graph.rs+5-5| ... | ... | @@ -548,7 +548,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { |
| 548 | 548 | root_id, |
| 549 | 549 | vis, |
| 550 | 550 | vis_span: item.vis.span, |
| 551 | on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, &item.attrs), | |
| 551 | on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs), | |
| 552 | 552 | }); |
| 553 | 553 | |
| 554 | 554 | self.r.indeterminate_imports.push(import); |
| ... | ... | @@ -863,7 +863,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { |
| 863 | 863 | || ast::attr::contains_name(&item.attrs, sym::no_implicit_prelude), |
| 864 | 864 | ); |
| 865 | 865 | self.parent_scope.module = module.to_module(); |
| 866 | if let Some(directive) = OnUnknownData::from_attrs(self.r.tcx, &item.attrs) { | |
| 866 | if let Some(directive) = OnUnknownData::from_attrs(self.r, &item.attrs) { | |
| 867 | 867 | self.r.on_unknown_data.insert(local_def_id, directive); |
| 868 | 868 | } |
| 869 | 869 | } |
| ... | ... | @@ -1040,7 +1040,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { |
| 1040 | 1040 | module_path: Vec::new(), |
| 1041 | 1041 | vis, |
| 1042 | 1042 | vis_span: item.vis.span, |
| 1043 | on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, &item.attrs), | |
| 1043 | on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs), | |
| 1044 | 1044 | }); |
| 1045 | 1045 | if used { |
| 1046 | 1046 | self.r.import_use_map.insert(import, Used::Other); |
| ... | ... | @@ -1172,7 +1172,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { |
| 1172 | 1172 | module_path: Vec::new(), |
| 1173 | 1173 | vis: Visibility::Restricted(CRATE_DEF_ID), |
| 1174 | 1174 | vis_span: item.vis.span, |
| 1175 | on_unknown_attr: OnUnknownData::from_attrs(this.r.tcx, &item.attrs), | |
| 1175 | on_unknown_attr: OnUnknownData::from_attrs(this.r, &item.attrs), | |
| 1176 | 1176 | }) |
| 1177 | 1177 | }; |
| 1178 | 1178 | |
| ... | ... | @@ -1353,7 +1353,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { |
| 1353 | 1353 | module_path: Vec::new(), |
| 1354 | 1354 | vis, |
| 1355 | 1355 | vis_span: item.vis.span, |
| 1356 | on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, &item.attrs), | |
| 1356 | on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs), | |
| 1357 | 1357 | }); |
| 1358 | 1358 | self.r.import_use_map.insert(import, Used::Other); |
| 1359 | 1359 | let import_decl = self.r.new_import_decl(decl, import); |
compiler/rustc_resolve/src/def_collector.rs+2-2| ... | ... | @@ -186,7 +186,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { |
| 186 | 186 | // Does that prevents errors from happening? maybe |
| 187 | 187 | let mut parser = AttributeParser::new( |
| 188 | 188 | &self.r.tcx.sess, |
| 189 | self.r.tcx.features(), | |
| 189 | self.r.features, | |
| 190 | 190 | self.r.tcx().registered_tools(()), |
| 191 | 191 | ShouldEmit::Nothing, |
| 192 | 192 | ); |
| ... | ... | @@ -433,7 +433,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { |
| 433 | 433 | // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so |
| 434 | 434 | // to avoid affecting stable we have to feature gate the not creating |
| 435 | 435 | // anon consts |
| 436 | if !self.r.tcx.features().min_generic_const_args() { | |
| 436 | if !self.r.features.min_generic_const_args() { | |
| 437 | 437 | let parent = self |
| 438 | 438 | .create_def(constant.id, None, DefKind::AnonConst, constant.value.span) |
| 439 | 439 | .def_id(); |
compiler/rustc_resolve/src/error_helper.rs+11-7| ... | ... | @@ -1628,7 +1628,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1628 | 1628 | in_module.for_each_child(self, |this, ident, orig_ident_span, ns, name_binding| { |
| 1629 | 1629 | // Avoid non-importable candidates. |
| 1630 | 1630 | if name_binding.is_assoc_item() |
| 1631 | && !this.tcx.features().import_trait_associated_functions() | |
| 1631 | && !this.features.import_trait_associated_functions() | |
| 1632 | 1632 | { |
| 1633 | 1633 | return; |
| 1634 | 1634 | } |
| ... | ... | @@ -1809,10 +1809,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1809 | 1809 | }) => { |
| 1810 | 1810 | if span.allows_unstable(feature) { |
| 1811 | 1811 | true |
| 1812 | } else if self.tcx.features().enabled(feature) { | |
| 1812 | } else if self.features.enabled(feature) { | |
| 1813 | 1813 | true |
| 1814 | 1814 | } else if let Some(implied_by) = implied_by |
| 1815 | && self.tcx.features().enabled(implied_by) | |
| 1815 | && self.features.enabled(implied_by) | |
| 1816 | 1816 | { |
| 1817 | 1817 | true |
| 1818 | 1818 | } else { |
| ... | ... | @@ -4144,13 +4144,17 @@ pub(crate) struct OnUnknownData { |
| 4144 | 4144 | } |
| 4145 | 4145 | |
| 4146 | 4146 | impl OnUnknownData { |
| 4147 | pub(crate) fn from_attrs<'tcx>( | |
| 4148 | tcx: TyCtxt<'tcx>, | |
| 4147 | pub(crate) fn from_attrs( | |
| 4148 | r: &Resolver<'_, '_>, | |
| 4149 | 4149 | attrs: &[ast::Attribute], |
| 4150 | 4150 | ) -> Option<OnUnknownData> { |
| 4151 | if tcx.features().diagnostic_on_unknown() | |
| 4151 | if r.features.diagnostic_on_unknown() | |
| 4152 | 4152 | && let Some(Attribute::Parsed(AttributeKind::OnUnknown { directive, .. })) = |
| 4153 | AttributeParser::parse_limited(tcx.sess, attrs, &[sym::diagnostic, sym::on_unknown]) | |
| 4153 | AttributeParser::parse_limited( | |
| 4154 | r.tcx.sess, | |
| 4155 | attrs, | |
| 4156 | &[sym::diagnostic, sym::on_unknown], | |
| 4157 | ) | |
| 4154 | 4158 | { |
| 4155 | 4159 | Some(Self { directive: directive? }) |
| 4156 | 4160 | } else { |
compiler/rustc_resolve/src/ident.rs+83-34| ... | ... | @@ -23,9 +23,9 @@ use crate::late::{ |
| 23 | 23 | use crate::macros::{MacroRulesScope, sub_namespace_match}; |
| 24 | 24 | use crate::{ |
| 25 | 25 | AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind, |
| 26 | Determinacy, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl, LocalModule, Module, | |
| 27 | ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, Res, ResolutionError, | |
| 28 | Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, diagnostics, | |
| 26 | Determinacy, ExternModule, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl, | |
| 27 | LocalModule, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, | |
| 28 | Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, diagnostics, | |
| 29 | 29 | }; |
| 30 | 30 | |
| 31 | 31 | #[derive(Copy, Clone)] |
| ... | ... | @@ -608,21 +608,36 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 608 | 608 | finalize.map(|f| Finalize { used: Used::Scope, ..f }), |
| 609 | 609 | ) |
| 610 | 610 | }; |
| 611 | let decl = self.reborrow().resolve_ident_in_module_non_globs_unadjusted( | |
| 612 | module, | |
| 613 | ident, | |
| 614 | orig_ident_span, | |
| 615 | ns, | |
| 616 | adjusted_parent_scope, | |
| 617 | if matches!(scope_set, ScopeSet::Module(..)) { | |
| 618 | Shadowing::Unrestricted | |
| 619 | } else { | |
| 620 | Shadowing::Restricted | |
| 621 | }, | |
| 622 | adjusted_finalize, | |
| 623 | ignore_decl, | |
| 624 | ignore_import, | |
| 625 | ); | |
| 611 | let shadowing = if matches!(scope_set, ScopeSet::Module(..)) { | |
| 612 | Shadowing::Unrestricted | |
| 613 | } else { | |
| 614 | Shadowing::Restricted | |
| 615 | }; | |
| 616 | let decl = if module.is_local() { | |
| 617 | self.reborrow().resolve_ident_in_local_module_non_globs_unadjusted( | |
| 618 | module.expect_local(), | |
| 619 | ident, | |
| 620 | orig_ident_span, | |
| 621 | ns, | |
| 622 | adjusted_parent_scope, | |
| 623 | shadowing, | |
| 624 | adjusted_finalize, | |
| 625 | ignore_decl, | |
| 626 | ignore_import, | |
| 627 | ) | |
| 628 | } else { | |
| 629 | self.reborrow().resolve_ident_in_extern_module_non_globs_unadjusted( | |
| 630 | module.expect_extern(), | |
| 631 | ident, | |
| 632 | orig_ident_span, | |
| 633 | ns, | |
| 634 | adjusted_parent_scope, | |
| 635 | shadowing, | |
| 636 | adjusted_finalize, | |
| 637 | ignore_decl, | |
| 638 | ) | |
| 639 | }; | |
| 640 | ||
| 626 | 641 | match decl { |
| 627 | 642 | Ok(decl) => { |
| 628 | 643 | if let Some(lint_id) = derive_fallback_lint_id { |
| ... | ... | @@ -746,7 +761,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 746 | 761 | Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) { |
| 747 | 762 | Some(decl) => { |
| 748 | 763 | if matches!(ident.name, sym::f16) |
| 749 | && !self.tcx.features().f16() | |
| 764 | && !self.features.f16() | |
| 750 | 765 | && !orig_ident_span.allows_unstable(sym::f16) |
| 751 | 766 | && finalize.is_some() |
| 752 | 767 | { |
| ... | ... | @@ -759,7 +774,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 759 | 774 | .emit(); |
| 760 | 775 | } |
| 761 | 776 | if matches!(ident.name, sym::f128) |
| 762 | && !self.tcx.features().f128() | |
| 777 | && !self.features.f128() | |
| 763 | 778 | && !orig_ident_span.allows_unstable(sym::f128) |
| 764 | 779 | && finalize.is_some() |
| 765 | 780 | { |
| ... | ... | @@ -1078,10 +1093,49 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1078 | 1093 | } |
| 1079 | 1094 | } |
| 1080 | 1095 | |
| 1081 | /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in `module`. | |
| 1082 | fn resolve_ident_in_module_non_globs_unadjusted<'r>( | |
| 1096 | /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in an external `module`. | |
| 1097 | fn resolve_ident_in_extern_module_non_globs_unadjusted<'r>( | |
| 1083 | 1098 | mut self: CmResolver<'r, 'ra, 'tcx>, |
| 1084 | module: Module<'ra>, | |
| 1099 | module: ExternModule<'ra>, | |
| 1100 | ident: IdentKey, | |
| 1101 | orig_ident_span: Span, | |
| 1102 | ns: Namespace, | |
| 1103 | parent_scope: &ParentScope<'ra>, | |
| 1104 | shadowing: Shadowing, | |
| 1105 | finalize: Option<Finalize>, | |
| 1106 | // This binding should be ignored during in-module resolution, so that we don't get | |
| 1107 | // "self-confirming" import resolutions during import validation and checking. | |
| 1108 | ignore_decl: Option<Decl<'ra>>, | |
| 1109 | ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> { | |
| 1110 | let key = BindingKey::new(ident, ns); | |
| 1111 | let resolution = | |
| 1112 | &*self.resolution(module.to_module(), key).ok_or(ControlFlow::Continue(Determined))?; | |
| 1113 | ||
| 1114 | let binding = resolution.non_glob_decl.filter(|b| Some(*b) != ignore_decl); | |
| 1115 | ||
| 1116 | if let Some(finalize) = finalize { | |
| 1117 | return self.get_mut().finalize_module_binding( | |
| 1118 | ident, | |
| 1119 | orig_ident_span, | |
| 1120 | binding, | |
| 1121 | parent_scope, | |
| 1122 | finalize, | |
| 1123 | shadowing, | |
| 1124 | ); | |
| 1125 | } | |
| 1126 | ||
| 1127 | // Items and single imports are not shadowable, if we have one, then it's determined. | |
| 1128 | if let Some(binding) = binding { | |
| 1129 | let accessible = self.is_accessible_from(binding.vis(), parent_scope.module); | |
| 1130 | return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; | |
| 1131 | } | |
| 1132 | Err(ControlFlow::Continue(Determined)) | |
| 1133 | } | |
| 1134 | ||
| 1135 | /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in a local `module`. | |
| 1136 | fn resolve_ident_in_local_module_non_globs_unadjusted<'r>( | |
| 1137 | mut self: CmResolver<'r, 'ra, 'tcx>, | |
| 1138 | module: LocalModule<'ra>, | |
| 1085 | 1139 | ident: IdentKey, |
| 1086 | 1140 | orig_ident_span: Span, |
| 1087 | 1141 | ns: Namespace, |
| ... | ... | @@ -1098,7 +1152,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1098 | 1152 | // doesn't need to be mutable. It will fail when there is a cycle of imports, and without |
| 1099 | 1153 | // the exclusive access infinite recursion will crash the compiler with stack overflow. |
| 1100 | 1154 | let resolution = &*self |
| 1101 | .resolution_or_default(module, key, orig_ident_span) | |
| 1155 | .resolution_or_default(module.to_module(), key, orig_ident_span) | |
| 1102 | 1156 | .try_borrow_mut_unchecked() |
| 1103 | 1157 | .map_err(|_| ControlFlow::Continue(Determined))?; |
| 1104 | 1158 | |
| ... | ... | @@ -1121,11 +1175,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1121 | 1175 | return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; |
| 1122 | 1176 | } |
| 1123 | 1177 | |
| 1124 | // In extern modules everything is determined from the start. | |
| 1125 | if !module.is_local() { | |
| 1126 | return Err(ControlFlow::Continue(Determined)); | |
| 1127 | }; | |
| 1128 | ||
| 1129 | 1178 | // Check if one of single imports can still define the name, block if it can. |
| 1130 | 1179 | if self.reborrow().single_import_can_define_name( |
| 1131 | 1180 | &resolution, |
| ... | ... | @@ -1535,7 +1584,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1535 | 1584 | } |
| 1536 | 1585 | |
| 1537 | 1586 | RibKind::ConstParamTy => { |
| 1538 | if !self.tcx.features().generic_const_parameter_types() { | |
| 1587 | if !self.features.generic_const_parameter_types() { | |
| 1539 | 1588 | if let Some(span) = finalize { |
| 1540 | 1589 | self.report_error( |
| 1541 | 1590 | span, |
| ... | ... | @@ -1564,7 +1613,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1564 | 1613 | } |
| 1565 | 1614 | NoConstantGenericsReason::NonTrivialConstArg => { |
| 1566 | 1615 | ResolutionError::ParamInNonTrivialAnonConst { |
| 1567 | is_gca: self.tcx.features().generic_const_args(), | |
| 1616 | is_gca: self.features.generic_const_args(), | |
| 1568 | 1617 | name: rib_ident.name, |
| 1569 | 1618 | param_kind: ParamKindInNonTrivialAnonConst::Type, |
| 1570 | 1619 | } |
| ... | ... | @@ -1629,7 +1678,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1629 | 1678 | | RibKind::ForwardGenericParamBan(_) => continue, |
| 1630 | 1679 | |
| 1631 | 1680 | RibKind::ConstParamTy => { |
| 1632 | if !self.tcx.features().generic_const_parameter_types() { | |
| 1681 | if !self.features.generic_const_parameter_types() { | |
| 1633 | 1682 | if let Some(span) = finalize { |
| 1634 | 1683 | self.report_error( |
| 1635 | 1684 | span, |
| ... | ... | @@ -1656,7 +1705,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1656 | 1705 | } |
| 1657 | 1706 | NoConstantGenericsReason::NonTrivialConstArg => { |
| 1658 | 1707 | ResolutionError::ParamInNonTrivialAnonConst { |
| 1659 | is_gca: self.tcx.features().generic_const_args(), | |
| 1708 | is_gca: self.features.generic_const_args(), | |
| 1660 | 1709 | name: rib_ident.name, |
| 1661 | 1710 | param_kind: ParamKindInNonTrivialAnonConst::Const { |
| 1662 | 1711 | name: rib_ident.name, |
| ... | ... | @@ -2019,7 +2068,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 2019 | 2068 | module, |
| 2020 | 2069 | || { |
| 2021 | 2070 | let import_inherent_item_error_flag = |
| 2022 | self.tcx.features().import_trait_associated_functions() | |
| 2071 | self.features.import_trait_associated_functions() | |
| 2023 | 2072 | && matches!( |
| 2024 | 2073 | res, |
| 2025 | 2074 | Res::Def( |
compiler/rustc_resolve/src/imports.rs+3-4| ... | ... | @@ -779,7 +779,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 779 | 779 | match import_decls[ns] { |
| 780 | 780 | PendingDecl::Ready(Some(import_decl)) => { |
| 781 | 781 | if import_decl.is_assoc_item() |
| 782 | && !this.tcx.features().import_trait_associated_functions() | |
| 782 | && !this.features.import_trait_associated_functions() | |
| 783 | 783 | { |
| 784 | 784 | feature_err( |
| 785 | 785 | this.tcx.sess, |
| ... | ... | @@ -822,8 +822,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 822 | 822 | continue; |
| 823 | 823 | }; |
| 824 | 824 | |
| 825 | if module.is_trait() && !self.tcx.features().import_trait_associated_functions() | |
| 826 | { | |
| 825 | if module.is_trait() && !self.features.import_trait_associated_functions() { | |
| 827 | 826 | feature_err( |
| 828 | 827 | self.tcx.sess, |
| 829 | 828 | sym::import_trait_associated_functions, |
| ... | ... | @@ -1487,7 +1486,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1487 | 1486 | |
| 1488 | 1487 | // If importing of trait asscoiated items is enabled, an also find an |
| 1489 | 1488 | // `Enum`, then note that inherent associated items cannot be imported. |
| 1490 | let note = if self.tcx.features().import_trait_associated_functions() | |
| 1489 | let note = if self.features.import_trait_associated_functions() | |
| 1491 | 1490 | && let PathResult::Module(ModuleOrUniformRoot::Module(m)) = path_res |
| 1492 | 1491 | && let Some(Res::Def(DefKind::Enum, _)) = m.res() |
| 1493 | 1492 | { |
compiler/rustc_resolve/src/late.rs+11-12| ... | ... | @@ -1664,7 +1664,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 1664 | 1664 | }; |
| 1665 | 1665 | // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better |
| 1666 | 1666 | // diagnostics, so we don't mention anything about const param tys having generics at all. |
| 1667 | if !self.r.tcx.features().generic_const_parameter_types() { | |
| 1667 | if !self.r.features.generic_const_parameter_types() { | |
| 1668 | 1668 | forward_ty_ban_rib_const_param_ty.bindings.clear(); |
| 1669 | 1669 | forward_const_ban_rib_const_param_ty.bindings.clear(); |
| 1670 | 1670 | } |
| ... | ... | @@ -1701,7 +1701,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 1701 | 1701 | |
| 1702 | 1702 | this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty); |
| 1703 | 1703 | this.ribs[ValueNS].push(forward_const_ban_rib_const_param_ty); |
| 1704 | if this.r.tcx.features().generic_const_parameter_types() { | |
| 1704 | if this.r.features.generic_const_parameter_types() { | |
| 1705 | 1705 | this.visit_ty(ty) |
| 1706 | 1706 | } else { |
| 1707 | 1707 | this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy)); |
| ... | ... | @@ -1812,8 +1812,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 1812 | 1812 | } |
| 1813 | 1813 | |
| 1814 | 1814 | LifetimeRibKind::ImplTrait => { |
| 1815 | if self.r.tcx.features().anonymous_lifetime_in_impl_trait() | |
| 1816 | { | |
| 1815 | if self.r.features.anonymous_lifetime_in_impl_trait() { | |
| 1817 | 1816 | None |
| 1818 | 1817 | } else { |
| 1819 | 1818 | Some(LifetimeUseSet::Many) |
| ... | ... | @@ -2991,7 +2990,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 2991 | 2990 | self.with_generic_param_rib( |
| 2992 | 2991 | &generics.params, |
| 2993 | 2992 | RibKind::Item( |
| 2994 | if self.r.tcx.features().generic_const_items() { | |
| 2993 | if self.r.features.generic_const_items() { | |
| 2995 | 2994 | HasGenericParams::Yes(generics.span) |
| 2996 | 2995 | } else { |
| 2997 | 2996 | HasGenericParams::No |
| ... | ... | @@ -3008,7 +3007,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 3008 | 3007 | LifetimeRibKind::Elided(LifetimeRes::Static), |
| 3009 | 3008 | |this| { |
| 3010 | 3009 | if rhs_kind.is_type_const() |
| 3011 | && !this.r.tcx.features().generic_const_parameter_types() | |
| 3010 | && !this.r.features.generic_const_parameter_types() | |
| 3012 | 3011 | { |
| 3013 | 3012 | this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { |
| 3014 | 3013 | this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { |
| ... | ... | @@ -3255,7 +3254,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 3255 | 3254 | RibKind::Normal => { |
| 3256 | 3255 | // FIXME(non_lifetime_binders): Stop special-casing |
| 3257 | 3256 | // const params to error out here. |
| 3258 | if self.r.tcx.features().non_lifetime_binders() | |
| 3257 | if self.r.features.non_lifetime_binders() | |
| 3259 | 3258 | && matches!(param.kind, GenericParamKind::Type { .. }) |
| 3260 | 3259 | { |
| 3261 | 3260 | Res::Def(def_kind, def_id.to_def_id()) |
| ... | ... | @@ -3409,7 +3408,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 3409 | 3408 | |this| { |
| 3410 | 3409 | this.visit_generics(generics); |
| 3411 | 3410 | if rhs_kind.is_type_const() |
| 3412 | && !this.r.tcx.features().generic_const_parameter_types() | |
| 3411 | && !this.r.features.generic_const_parameter_types() | |
| 3413 | 3412 | { |
| 3414 | 3413 | this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { |
| 3415 | 3414 | this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { |
| ... | ... | @@ -5038,10 +5037,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 5038 | 5037 | let tcx = self.r.tcx(); |
| 5039 | 5038 | |
| 5040 | 5039 | let gate_err_sym_msg = match prim { |
| 5041 | PrimTy::Float(FloatTy::F16) if !tcx.features().f16() => { | |
| 5040 | PrimTy::Float(FloatTy::F16) if !self.r.features.f16() => { | |
| 5042 | 5041 | Some((sym::f16, "the type `f16` is unstable")) |
| 5043 | 5042 | } |
| 5044 | PrimTy::Float(FloatTy::F128) if !tcx.features().f128() => { | |
| 5043 | PrimTy::Float(FloatTy::F128) if !self.r.features.f128() => { | |
| 5045 | 5044 | Some((sym::f128, "the type `f128` is unstable")) |
| 5046 | 5045 | } |
| 5047 | 5046 | _ => None, |
| ... | ... | @@ -5196,8 +5195,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 5196 | 5195 | AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes, |
| 5197 | 5196 | AnonConstKind::InlineConst => ConstantHasGenerics::Yes, |
| 5198 | 5197 | AnonConstKind::ConstArg(_) => { |
| 5199 | if self.r.tcx.features().generic_const_exprs() | |
| 5200 | || self.r.tcx.features().min_generic_const_args() | |
| 5198 | if self.r.features.generic_const_exprs() | |
| 5199 | || self.r.features.min_generic_const_args() | |
| 5201 | 5200 | || is_trivial_const_arg |
| 5202 | 5201 | { |
| 5203 | 5202 | ConstantHasGenerics::Yes |
compiler/rustc_resolve/src/late/diagnostics.rs+4-5| ... | ... | @@ -1775,8 +1775,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { |
| 1775 | 1775 | // const generics. Of course, `Struct` and `Enum` may contain ty params, too, but the |
| 1776 | 1776 | // benefits of including them here outweighs the small number of false positives. |
| 1777 | 1777 | Some(Res::Def(DefKind::Struct | DefKind::Enum, _)) |
| 1778 | if self.r.tcx.features().adt_const_params() | |
| 1779 | || self.r.tcx.features().min_adt_const_params() => | |
| 1778 | if self.r.features.adt_const_params() || self.r.features.min_adt_const_params() => | |
| 1780 | 1779 | { |
| 1781 | 1780 | Applicability::MaybeIncorrect |
| 1782 | 1781 | } |
| ... | ... | @@ -3977,7 +3976,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { |
| 3977 | 3976 | }) |
| 3978 | 3977 | .emit(), |
| 3979 | 3978 | NoConstantGenericsReason::NonTrivialConstArg => { |
| 3980 | assert!(!self.r.tcx.features().generic_const_exprs()); | |
| 3979 | assert!(!self.r.features.generic_const_exprs()); | |
| 3981 | 3980 | self.r |
| 3982 | 3981 | .dcx() |
| 3983 | 3982 | .create_err(diagnostics::ParamInNonTrivialAnonConst { |
| ... | ... | @@ -3985,8 +3984,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { |
| 3985 | 3984 | name: lifetime_ref.ident.name, |
| 3986 | 3985 | param_kind: diagnostics::ParamKindInNonTrivialAnonConst::Lifetime, |
| 3987 | 3986 | help: self.r.tcx.sess.is_nightly_build(), |
| 3988 | is_gca: self.r.tcx.features().generic_const_args(), | |
| 3989 | help_gca: self.r.tcx.features().generic_const_args(), | |
| 3987 | is_gca: self.r.features.generic_const_args(), | |
| 3988 | help_gca: self.r.features.generic_const_args(), | |
| 3990 | 3989 | }) |
| 3991 | 3990 | .emit() |
| 3992 | 3991 | } |
compiler/rustc_resolve/src/lib.rs+8-8| ... | ... | @@ -50,7 +50,7 @@ use rustc_data_structures::sync::{FreezeReadGuard, FreezeWriteGuard}; |
| 50 | 50 | use rustc_data_structures::unord::{UnordItems, UnordMap, UnordSet}; |
| 51 | 51 | use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed, LintBuffer}; |
| 52 | 52 | use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; |
| 53 | use rustc_feature::BUILTIN_ATTRIBUTES; | |
| 53 | use rustc_feature::{BUILTIN_ATTRIBUTES, Features}; | |
| 54 | 54 | use rustc_hir::attrs::StrippedCfgItem; |
| 55 | 55 | use rustc_hir::def::Namespace::{self, *}; |
| 56 | 56 | use rustc_hir::def::{ |
| ... | ... | @@ -1550,7 +1550,8 @@ pub struct Resolver<'ra, 'tcx> { |
| 1550 | 1550 | impl_trait_names: FxHashMap<NodeId, Symbol> = default::fx_hash_map(), |
| 1551 | 1551 | |
| 1552 | 1552 | /// Stores `#[diagnostic::on_unknown]` attributes placed on module declarations. |
| 1553 | on_unknown_data: FxHashMap<LocalDefId, OnUnknownData>, | |
| 1553 | on_unknown_data: FxHashMap<LocalDefId, OnUnknownData> = default::fx_hash_map(), | |
| 1554 | features: &'tcx Features, | |
| 1554 | 1555 | } |
| 1555 | 1556 | |
| 1556 | 1557 | /// This provides memory for the rest of the crate. The `'ra` lifetime that is |
| ... | ... | @@ -1808,11 +1809,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1808 | 1809 | let registered_tools = tcx.registered_tools(()); |
| 1809 | 1810 | let edition = tcx.sess.edition(); |
| 1810 | 1811 | |
| 1811 | let mut on_unknown_data = default::fx_hash_map(); | |
| 1812 | if let Some(directive) = OnUnknownData::from_attrs(tcx, attrs) { | |
| 1813 | on_unknown_data.insert(CRATE_DEF_ID, directive); | |
| 1814 | } | |
| 1815 | ||
| 1816 | 1812 | let mut resolver = Resolver { |
| 1817 | 1813 | tcx, |
| 1818 | 1814 | |
| ... | ... | @@ -1880,10 +1876,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1880 | 1876 | current_crate_outer_attr_insert_span, |
| 1881 | 1877 | disambiguators: Default::default(), |
| 1882 | 1878 | delegation_infos: Default::default(), |
| 1883 | on_unknown_data, | |
| 1879 | features: tcx.features(), | |
| 1884 | 1880 | .. |
| 1885 | 1881 | }; |
| 1886 | 1882 | |
| 1883 | if let Some(directive) = OnUnknownData::from_attrs(&resolver, attrs) { | |
| 1884 | resolver.on_unknown_data.insert(CRATE_DEF_ID, directive); | |
| 1885 | } | |
| 1886 | ||
| 1887 | 1887 | let root_parent_scope = ParentScope::module(graph_root, resolver.arenas); |
| 1888 | 1888 | resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope); |
| 1889 | 1889 | resolver.feed_visibility(crate_feed, Visibility::Public); |
compiler/rustc_resolve/src/macros.rs+5-6| ... | ... | @@ -699,7 +699,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 699 | 699 | } |
| 700 | 700 | |
| 701 | 701 | // We are trying to avoid reporting this error if other related errors were reported. |
| 702 | if res != Res::Err && inner_attr && !self.tcx.features().custom_inner_attributes() { | |
| 702 | if res != Res::Err && inner_attr && !self.features.custom_inner_attributes() { | |
| 703 | 703 | let is_macro = match res { |
| 704 | 704 | Res::Def(..) => true, |
| 705 | 705 | Res::NonMacroAttr(..) => false, |
| ... | ... | @@ -727,8 +727,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 727 | 727 | && let [namespace, attribute, ..] = &*path.segments |
| 728 | 728 | && namespace.ident.name == sym::diagnostic |
| 729 | 729 | && !DIAGNOSTIC_ATTRIBUTES.iter().any(|(attr, feature)| { |
| 730 | attribute.ident.name == *attr | |
| 731 | && feature.is_none_or(|f| self.tcx.features().enabled(f)) | |
| 730 | attribute.ident.name == *attr && feature.is_none_or(|f| self.features.enabled(f)) | |
| 732 | 731 | }) |
| 733 | 732 | { |
| 734 | 733 | let name = attribute.ident.name; |
| ... | ... | @@ -750,7 +749,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 750 | 749 | let candidates = DIAGNOSTIC_ATTRIBUTES |
| 751 | 750 | .iter() |
| 752 | 751 | .filter_map(|(attr, feature)| { |
| 753 | feature.is_none_or(|f| self.tcx.features().enabled(f)).then_some(*attr) | |
| 752 | feature.is_none_or(|f| self.features.enabled(f)).then_some(*attr) | |
| 754 | 753 | }) |
| 755 | 754 | .collect::<Vec<_>>(); |
| 756 | 755 | |
| ... | ... | @@ -1112,7 +1111,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1112 | 1111 | let feature = stability.feature; |
| 1113 | 1112 | |
| 1114 | 1113 | let is_allowed = |
| 1115 | |feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature); | |
| 1114 | |feature| self.features.enabled(feature) || span.allows_unstable(feature); | |
| 1116 | 1115 | let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature)); |
| 1117 | 1116 | if !is_allowed(feature) && !allowed_by_implication { |
| 1118 | 1117 | stability::report_unstable( |
| ... | ... | @@ -1242,7 +1241,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 1242 | 1241 | ) -> SyntaxExtension { |
| 1243 | 1242 | let mut ext = compile_declarative_macro( |
| 1244 | 1243 | self.tcx.sess, |
| 1245 | self.tcx.features(), | |
| 1244 | self.features, | |
| 1246 | 1245 | macro_def, |
| 1247 | 1246 | ident, |
| 1248 | 1247 | attrs, |
compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs+3-3| ... | ... | @@ -310,7 +310,7 @@ pub(crate) fn transform_instance<'tcx>( |
| 310 | 310 | // FIXME: account for async-drop-glue |
| 311 | 311 | if (matches!(instance.def, ty::InstanceKind::Virtual(..)) |
| 312 | 312 | && tcx.is_lang_item(instance.def_id(), LangItem::DropGlue)) |
| 313 | || matches!(instance.def, ty::InstanceKind::DropGlue(..)) | |
| 313 | || matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..))) | |
| 314 | 314 | { |
| 315 | 315 | // Adjust the type ids of DropGlues |
| 316 | 316 | // |
| ... | ... | @@ -364,7 +364,7 @@ pub(crate) fn transform_instance<'tcx>( |
| 364 | 364 | tcx.types.unit |
| 365 | 365 | }; |
| 366 | 366 | instance.args = tcx.mk_args_trait(self_ty, instance.args.into_iter().skip(1)); |
| 367 | } else if let ty::InstanceKind::VTableShim(def_id) = instance.def | |
| 367 | } else if let ty::InstanceKind::Shim(ty::ShimKind::VTable(def_id)) = instance.def | |
| 368 | 368 | && let Some(trait_id) = tcx.trait_of_assoc(def_id) |
| 369 | 369 | { |
| 370 | 370 | // Adjust the type ids of VTableShims to the type id expected in the call sites for the |
| ... | ... | @@ -461,7 +461,7 @@ pub(crate) fn transform_instance<'tcx>( |
| 461 | 461 | |
| 462 | 462 | fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option<DefId> { |
| 463 | 463 | match instance.def { |
| 464 | ty::InstanceKind::Item(def_id) | ty::InstanceKind::FnPtrShim(def_id, _) => { | |
| 464 | ty::InstanceKind::Item(def_id) | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(def_id, _)) => { | |
| 465 | 465 | tcx.opt_associated_item(def_id).map(|item| item.def_id) |
| 466 | 466 | } |
| 467 | 467 | _ => None, |
compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs+2-2| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | use std::hash::Hasher; |
| 8 | 8 | |
| 9 | use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, Ty, TyCtxt}; | |
| 9 | use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, ShimKind, Ty, TyCtxt}; | |
| 10 | 10 | use rustc_target::callconv::FnAbi; |
| 11 | 11 | use twox_hash::XxHash64; |
| 12 | 12 | |
| ... | ... | @@ -46,7 +46,7 @@ pub fn typeid_for_instance<'tcx>( |
| 46 | 46 | // |
| 47 | 47 | // This was implemented for KCFI support in #123106 and #123052 (which introduced the |
| 48 | 48 | // ReifyReason). The tracking issue for KCFI support for Rust is #123479. |
| 49 | if matches!(instance.def, InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr))) { | |
| 49 | if matches!(instance.def, InstanceKind::Shim(ShimKind::Reify(_, Some(ReifyReason::FnPtr)))) { | |
| 50 | 50 | options.insert(TypeIdOptions::USE_CONCRETE_SELF); |
| 51 | 51 | } |
| 52 | 52 | // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the |
compiler/rustc_symbol_mangling/src/legacy.rs+12-9| ... | ... | @@ -62,13 +62,13 @@ pub(super) fn mangle<'tcx>( |
| 62 | 62 | let mut p = LegacySymbolMangler { tcx, path: SymbolPath::new(), keep_within_component: false }; |
| 63 | 63 | p.print_def_path( |
| 64 | 64 | def_id, |
| 65 | if let ty::InstanceKind::DropGlue(_, _) | |
| 66 | | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) | |
| 67 | | ty::InstanceKind::FutureDropPollShim(_, _, _) = instance.def | |
| 65 | if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, _)) | |
| 66 | | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, _)) | |
| 67 | | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, _, _)) = instance.def | |
| 68 | 68 | { |
| 69 | 69 | // Add the name of the dropped type to the symbol name |
| 70 | 70 | &*instance.args |
| 71 | } else if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def { | |
| 71 | } else if let ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) = instance.def { | |
| 72 | 72 | let ty::Coroutine(_, cor_args) = ty.kind() else { |
| 73 | 73 | bug!(); |
| 74 | 74 | }; |
| ... | ... | @@ -81,13 +81,13 @@ pub(super) fn mangle<'tcx>( |
| 81 | 81 | .unwrap(); |
| 82 | 82 | |
| 83 | 83 | match instance.def { |
| 84 | ty::InstanceKind::ThreadLocalShim(..) => { | |
| 84 | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => { | |
| 85 | 85 | p.write_str("{{tls-shim}}").unwrap(); |
| 86 | 86 | } |
| 87 | ty::InstanceKind::VTableShim(..) => { | |
| 87 | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) => { | |
| 88 | 88 | p.write_str("{{vtable-shim}}").unwrap(); |
| 89 | 89 | } |
| 90 | ty::InstanceKind::ReifyShim(_, reason) => { | |
| 90 | ty::InstanceKind::Shim(ty::ShimKind::Reify(_, reason)) => { | |
| 91 | 91 | p.write_str("{{reify-shim").unwrap(); |
| 92 | 92 | match reason { |
| 93 | 93 | Some(ReifyReason::FnPtr) => p.write_str("-fnptr").unwrap(), |
| ... | ... | @@ -98,14 +98,17 @@ pub(super) fn mangle<'tcx>( |
| 98 | 98 | } |
| 99 | 99 | // FIXME(async_closures): This shouldn't be needed when we fix |
| 100 | 100 | // `Instance::ty`/`Instance::def_id`. |
| 101 | ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } => { | |
| 101 | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { | |
| 102 | receiver_by_ref, | |
| 103 | .. | |
| 104 | }) => { | |
| 102 | 105 | p.write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" }) |
| 103 | 106 | .unwrap(); |
| 104 | 107 | } |
| 105 | 108 | _ => {} |
| 106 | 109 | } |
| 107 | 110 | |
| 108 | if let ty::InstanceKind::FutureDropPollShim(..) = instance.def { | |
| 111 | if let ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) = instance.def { | |
| 109 | 112 | let _ = p.write_str("{{drop-shim}}"); |
| 110 | 113 | } |
| 111 | 114 |
compiler/rustc_symbol_mangling/src/v0.rs+19-13| ... | ... | @@ -49,25 +49,31 @@ pub(super) fn mangle<'tcx>( |
| 49 | 49 | |
| 50 | 50 | // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance. |
| 51 | 51 | let shim_kind = match instance.def { |
| 52 | ty::InstanceKind::ThreadLocalShim(_) => Some("tls"), | |
| 53 | ty::InstanceKind::VTableShim(_) => Some("vtable"), | |
| 54 | ty::InstanceKind::ReifyShim(_, None) => Some("reify"), | |
| 55 | ty::InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr)) => Some("reify_fnptr"), | |
| 56 | ty::InstanceKind::ReifyShim(_, Some(ReifyReason::Vtable)) => Some("reify_vtable"), | |
| 52 | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_)) => Some("tls"), | |
| 53 | ty::InstanceKind::Shim(ty::ShimKind::VTable(_)) => Some("vtable"), | |
| 54 | ty::InstanceKind::Shim(ty::ShimKind::Reify(_, None)) => Some("reify"), | |
| 55 | ty::InstanceKind::Shim(ty::ShimKind::Reify(_, Some(ReifyReason::FnPtr))) => { | |
| 56 | Some("reify_fnptr") | |
| 57 | } | |
| 58 | ty::InstanceKind::Shim(ty::ShimKind::Reify(_, Some(ReifyReason::Vtable))) => { | |
| 59 | Some("reify_vtable") | |
| 60 | } | |
| 57 | 61 | |
| 58 | 62 | // FIXME(async_closures): This shouldn't be needed when we fix |
| 59 | 63 | // `Instance::ty`/`Instance::def_id`. |
| 60 | ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: true, .. } => { | |
| 61 | Some("by_move") | |
| 62 | } | |
| 63 | ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: false, .. } => { | |
| 64 | Some("by_ref") | |
| 65 | } | |
| 66 | ty::InstanceKind::FutureDropPollShim(_, _, _) => Some("drop"), | |
| 64 | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { | |
| 65 | receiver_by_ref: true, | |
| 66 | .. | |
| 67 | }) => Some("by_move"), | |
| 68 | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { | |
| 69 | receiver_by_ref: false, | |
| 70 | .. | |
| 71 | }) => Some("by_ref"), | |
| 72 | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, _, _)) => Some("drop"), | |
| 67 | 73 | _ => None, |
| 68 | 74 | }; |
| 69 | 75 | |
| 70 | if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def { | |
| 76 | if let ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) = instance.def { | |
| 71 | 77 | let ty::Coroutine(_, cor_args) = ty.kind() else { |
| 72 | 78 | bug!(); |
| 73 | 79 | }; |
compiler/rustc_target/src/callconv/mod.rs+3| ... | ... | @@ -827,6 +827,9 @@ impl<'a, Ty> FnAbi<'a, Ty> { |
| 827 | 827 | ArgAttribute::default() |
| 828 | 828 | }; |
| 829 | 829 | arg.cast_to_with_attrs(Reg { kind: RegKind::Integer, size }, attr.into()); |
| 830 | } else if self.conv == CanonAbi::RustTail { | |
| 831 | assert!(arg.layout.is_sized(), "extern \"tail\" arguments must be sized"); | |
| 832 | arg.pass_by_stack_offset(None); | |
| 830 | 833 | } |
| 831 | 834 | } |
| 832 | 835 |
compiler/rustc_ty_utils/src/abi.rs+25-21| ... | ... | @@ -10,7 +10,7 @@ use rustc_middle::query::Providers; |
| 10 | 10 | use rustc_middle::ty::layout::{ |
| 11 | 11 | FnAbiError, HasTyCtxt, HasTypingEnv, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind, |
| 12 | 12 | }; |
| 13 | use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, Unnormalized}; | |
| 13 | use rustc_middle::ty::{self, InstanceKind, ShimKind, Ty, TyCtxt, Unnormalized}; | |
| 14 | 14 | use rustc_span::DUMMY_SP; |
| 15 | 15 | use rustc_span::def_id::DefId; |
| 16 | 16 | use rustc_target::callconv::{ |
| ... | ... | @@ -38,7 +38,7 @@ fn fn_sig_for_fn_abi<'tcx>( |
| 38 | 38 | instance: ty::Instance<'tcx>, |
| 39 | 39 | typing_env: ty::TypingEnv<'tcx>, |
| 40 | 40 | ) -> ty::FnSig<'tcx> { |
| 41 | if let InstanceKind::ThreadLocalShim(..) = instance.def { | |
| 41 | if let InstanceKind::Shim(ShimKind::ThreadLocal(..)) = instance.def { | |
| 42 | 42 | return tcx.mk_fn_sig_safe_rust_abi([], tcx.thread_local_ptr_ty(instance.def_id())); |
| 43 | 43 | } |
| 44 | 44 | |
| ... | ... | @@ -50,7 +50,7 @@ fn fn_sig_for_fn_abi<'tcx>( |
| 50 | 50 | ); |
| 51 | 51 | |
| 52 | 52 | // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. |
| 53 | if let ty::InstanceKind::VTableShim(..) = instance.def { | |
| 53 | if let ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) = instance.def { | |
| 54 | 54 | let mut inputs_and_output = sig.inputs_and_output.to_vec(); |
| 55 | 55 | inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]); |
| 56 | 56 | sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); |
| ... | ... | @@ -82,22 +82,23 @@ fn fn_sig_for_fn_abi<'tcx>( |
| 82 | 82 | // a separate def-id for these bodies. |
| 83 | 83 | let mut coroutine_kind = args.as_coroutine_closure().kind(); |
| 84 | 84 | |
| 85 | let env_ty = | |
| 86 | if let InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } = | |
| 87 | instance.def | |
| 88 | { | |
| 89 | coroutine_kind = ty::ClosureKind::FnOnce; | |
| 90 | ||
| 91 | // Implementations of `FnMut` and `Fn` for coroutine-closures | |
| 92 | // still take their receiver by ref. | |
| 93 | if receiver_by_ref { | |
| 94 | Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) | |
| 95 | } else { | |
| 96 | coroutine_ty | |
| 97 | } | |
| 85 | let env_ty = if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { | |
| 86 | receiver_by_ref, | |
| 87 | .. | |
| 88 | }) = instance.def | |
| 89 | { | |
| 90 | coroutine_kind = ty::ClosureKind::FnOnce; | |
| 91 | ||
| 92 | // Implementations of `FnMut` and `Fn` for coroutine-closures | |
| 93 | // still take their receiver by ref. | |
| 94 | if receiver_by_ref { | |
| 95 | Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) | |
| 98 | 96 | } else { |
| 99 | tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased) | |
| 100 | }; | |
| 97 | coroutine_ty | |
| 98 | } | |
| 99 | } else { | |
| 100 | tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased) | |
| 101 | }; | |
| 101 | 102 | |
| 102 | 103 | let sig = tcx.instantiate_bound_regions_with_erased(sig); |
| 103 | 104 | |
| ... | ... | @@ -264,7 +265,8 @@ impl<'tcx> FnAbiDesc<'tcx> { |
| 264 | 265 | ) -> Self { |
| 265 | 266 | let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query; |
| 266 | 267 | let is_virtual_call = matches!(instance.def, ty::InstanceKind::Virtual(..)); |
| 267 | let is_tls_shim_call = matches!(instance.def, ty::InstanceKind::ThreadLocalShim(_)); | |
| 268 | let is_tls_shim_call = | |
| 269 | matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_))); | |
| 268 | 270 | Self { |
| 269 | 271 | layout_cx: LayoutCx::new(tcx, typing_env), |
| 270 | 272 | sig: tcx.normalize_erasing_regions( |
| ... | ... | @@ -458,8 +460,10 @@ fn fn_abi_sanity_check<'tcx>( |
| 458 | 460 | // omitted entirely in the calling convention. |
| 459 | 461 | assert!(arg.is_ignore()); |
| 460 | 462 | } |
| 461 | if let PassMode::Indirect { on_stack, .. } = arg.mode { | |
| 462 | assert!(!on_stack, "rust abi shouldn't use on_stack"); | |
| 463 | if let PassMode::Indirect { on_stack, .. } = arg.mode | |
| 464 | && spec_abi != ExternAbi::RustTail | |
| 465 | { | |
| 466 | assert!(!on_stack, "rustic abi {spec_abi:?} shouldn't use on_stack"); | |
| 463 | 467 | } |
| 464 | 468 | } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { |
| 465 | 469 | assert_matches!( |
compiler/rustc_ty_utils/src/instance.rs+35-21| ... | ... | @@ -38,16 +38,16 @@ fn resolve_instance_raw<'tcx>( |
| 38 | 38 | } else if tcx.is_lang_item(def_id, LangItem::DropGlue) { |
| 39 | 39 | let ty = args.type_at(0); |
| 40 | 40 | |
| 41 | if ty.needs_drop(tcx, typing_env) { | |
| 41 | let shim = if ty.needs_drop(tcx, typing_env) { | |
| 42 | 42 | debug!(" => nontrivial drop glue"); |
| 43 | 43 | match *ty.kind() { |
| 44 | 44 | ty::Coroutine(coroutine_def_id, ..) => { |
| 45 | 45 | // FIXME: sync drop of coroutine with async drop (generate both versions?) |
| 46 | 46 | // Currently just ignored |
| 47 | 47 | if tcx.optimized_mir(coroutine_def_id).coroutine_drop_async().is_some() { |
| 48 | ty::InstanceKind::DropGlue(def_id, None) | |
| 48 | ty::ShimKind::DropGlue(def_id, None) | |
| 49 | 49 | } else { |
| 50 | ty::InstanceKind::DropGlue(def_id, Some(ty)) | |
| 50 | ty::ShimKind::DropGlue(def_id, Some(ty)) | |
| 51 | 51 | } |
| 52 | 52 | } |
| 53 | 53 | ty::Closure(..) |
| ... | ... | @@ -57,14 +57,15 @@ fn resolve_instance_raw<'tcx>( |
| 57 | 57 | | ty::Dynamic(..) |
| 58 | 58 | | ty::Array(..) |
| 59 | 59 | | ty::Slice(..) |
| 60 | | ty::UnsafeBinder(..) => ty::InstanceKind::DropGlue(def_id, Some(ty)), | |
| 60 | | ty::UnsafeBinder(..) => ty::ShimKind::DropGlue(def_id, Some(ty)), | |
| 61 | 61 | // Drop shims can only be built from ADTs. |
| 62 | 62 | _ => return Ok(None), |
| 63 | 63 | } |
| 64 | 64 | } else { |
| 65 | 65 | debug!(" => trivial drop glue"); |
| 66 | ty::InstanceKind::DropGlue(def_id, None) | |
| 67 | } | |
| 66 | ty::ShimKind::DropGlue(def_id, None) | |
| 67 | }; | |
| 68 | ty::InstanceKind::Shim(shim) | |
| 68 | 69 | } else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) { |
| 69 | 70 | let ty = args.type_at(0); |
| 70 | 71 | |
| ... | ... | @@ -82,14 +83,14 @@ fn resolve_instance_raw<'tcx>( |
| 82 | 83 | _ => return Ok(None), |
| 83 | 84 | } |
| 84 | 85 | debug!(" => nontrivial async drop glue ctor"); |
| 85 | ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) | |
| 86 | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(def_id, ty)) | |
| 86 | 87 | } else { |
| 87 | 88 | debug!(" => trivial async drop glue ctor"); |
| 88 | ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) | |
| 89 | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(def_id, ty)) | |
| 89 | 90 | } |
| 90 | 91 | } else if tcx.is_async_drop_in_place_coroutine(def_id) { |
| 91 | 92 | let ty = args.type_at(0); |
| 92 | ty::InstanceKind::AsyncDropGlue(def_id, ty) | |
| 93 | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(def_id, ty)) | |
| 93 | 94 | } else { |
| 94 | 95 | debug!(" => free item"); |
| 95 | 96 | ty::InstanceKind::Item(def_id) |
| ... | ... | @@ -279,7 +280,7 @@ fn resolve_associated_item<'tcx>( |
| 279 | 280 | }; |
| 280 | 281 | |
| 281 | 282 | Some(Instance { |
| 282 | def: ty::InstanceKind::CloneShim(trait_item_id, self_ty), | |
| 283 | def: ty::InstanceKind::Shim(ty::ShimKind::Clone(trait_item_id, self_ty)), | |
| 283 | 284 | args: rcvr_args, |
| 284 | 285 | }) |
| 285 | 286 | } else { |
| ... | ... | @@ -296,7 +297,10 @@ fn resolve_associated_item<'tcx>( |
| 296 | 297 | return Ok(None); |
| 297 | 298 | } |
| 298 | 299 | Some(Instance { |
| 299 | def: ty::InstanceKind::FnPtrAddrShim(trait_item_id, self_ty), | |
| 300 | def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr( | |
| 301 | trait_item_id, | |
| 302 | self_ty, | |
| 303 | )), | |
| 300 | 304 | args: rcvr_args, |
| 301 | 305 | }) |
| 302 | 306 | } else { |
| ... | ... | @@ -326,7 +330,10 @@ fn resolve_associated_item<'tcx>( |
| 326 | 330 | Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) |
| 327 | 331 | } |
| 328 | 332 | ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { |
| 329 | def: ty::InstanceKind::FnPtrShim(trait_item_id, rcvr_args.type_at(0)), | |
| 333 | def: ty::InstanceKind::Shim(ty::ShimKind::FnPtr( | |
| 334 | trait_item_id, | |
| 335 | rcvr_args.type_at(0), | |
| 336 | )), | |
| 330 | 337 | args: rcvr_args, |
| 331 | 338 | }), |
| 332 | 339 | ty::CoroutineClosure(coroutine_closure_def_id, args) => { |
| ... | ... | @@ -339,10 +346,12 @@ fn resolve_associated_item<'tcx>( |
| 339 | 346 | Some(Instance::new_raw(coroutine_closure_def_id, args)) |
| 340 | 347 | } else { |
| 341 | 348 | Some(Instance { |
| 342 | def: ty::InstanceKind::ConstructCoroutineInClosureShim { | |
| 343 | coroutine_closure_def_id, | |
| 344 | receiver_by_ref: target_kind != ty::ClosureKind::FnOnce, | |
| 345 | }, | |
| 349 | def: ty::InstanceKind::Shim( | |
| 350 | ty::ShimKind::ConstructCoroutineInClosure { | |
| 351 | coroutine_closure_def_id, | |
| 352 | receiver_by_ref: target_kind != ty::ClosureKind::FnOnce, | |
| 353 | }, | |
| 354 | ), | |
| 346 | 355 | args, |
| 347 | 356 | }) |
| 348 | 357 | } |
| ... | ... | @@ -362,10 +371,12 @@ fn resolve_associated_item<'tcx>( |
| 362 | 371 | // If we're computing `AsyncFnOnce` for a by-ref closure then |
| 363 | 372 | // construct a new body that has the right return types. |
| 364 | 373 | Some(Instance { |
| 365 | def: ty::InstanceKind::ConstructCoroutineInClosureShim { | |
| 366 | coroutine_closure_def_id, | |
| 367 | receiver_by_ref: false, | |
| 368 | }, | |
| 374 | def: ty::InstanceKind::Shim( | |
| 375 | ty::ShimKind::ConstructCoroutineInClosure { | |
| 376 | coroutine_closure_def_id, | |
| 377 | receiver_by_ref: false, | |
| 378 | }, | |
| 379 | ), | |
| 369 | 380 | args, |
| 370 | 381 | }) |
| 371 | 382 | } else { |
| ... | ... | @@ -376,7 +387,10 @@ fn resolve_associated_item<'tcx>( |
| 376 | 387 | Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) |
| 377 | 388 | } |
| 378 | 389 | ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { |
| 379 | def: ty::InstanceKind::FnPtrShim(trait_item_id, rcvr_args.type_at(0)), | |
| 390 | def: ty::InstanceKind::Shim(ty::ShimKind::FnPtr( | |
| 391 | trait_item_id, | |
| 392 | rcvr_args.type_at(0), | |
| 393 | )), | |
| 380 | 394 | args: rcvr_args, |
| 381 | 395 | }), |
| 382 | 396 | _ => bug!( |
compiler/rustc_type_ir/src/generic_arg.rs-13| ... | ... | @@ -18,16 +18,3 @@ pub enum GenericArgKind<I: Interner> { |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | impl<I: Interner> Eq for GenericArgKind<I> {} |
| 21 | ||
| 22 | #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] | |
| 23 | #[derive(GenericTypeVisitable)] | |
| 24 | #[cfg_attr( | |
| 25 | feature = "nightly", | |
| 26 | derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) | |
| 27 | )] | |
| 28 | pub enum TermKind<I: Interner> { | |
| 29 | Ty(I::Ty), | |
| 30 | Const(I::Const), | |
| 31 | } | |
| 32 | ||
| 33 | impl<I: Interner> Eq for TermKind<I> {} |
compiler/rustc_type_ir/src/lib.rs+2| ... | ... | @@ -52,6 +52,7 @@ mod pattern; |
| 52 | 52 | mod predicate; |
| 53 | 53 | mod predicate_kind; |
| 54 | 54 | mod region_kind; |
| 55 | mod term_kind; | |
| 55 | 56 | mod ty; |
| 56 | 57 | mod ty_info; |
| 57 | 58 | mod ty_kind; |
| ... | ... | @@ -81,6 +82,7 @@ pub use predicate_kind::*; |
| 81 | 82 | pub use region_kind::*; |
| 82 | 83 | pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy}; |
| 83 | 84 | use rustc_type_ir_macros::GenericTypeVisitable; |
| 85 | pub use term_kind::*; | |
| 84 | 86 | pub use ty::{Alias, *}; |
| 85 | 87 | pub use ty_info::*; |
| 86 | 88 | pub use ty_kind::*; |
compiler/rustc_type_ir/src/predicate.rs+4-353| ... | ... | @@ -9,10 +9,9 @@ use rustc_type_ir_macros::{ |
| 9 | 9 | }; |
| 10 | 10 | |
| 11 | 11 | use crate::inherent::*; |
| 12 | use crate::ty::AliasTerm; | |
| 13 | 12 | use crate::upcast::{Upcast, UpcastFrom}; |
| 14 | 13 | use crate::visit::TypeVisitableExt as _; |
| 15 | use crate::{self as ty, Alias, AliasTyKind, Interner, UnevaluatedConstKind}; | |
| 14 | use crate::{self as ty, Alias, Interner}; | |
| 16 | 15 | |
| 17 | 16 | /// `A: 'region` |
| 18 | 17 | #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)] |
| ... | ... | @@ -505,7 +504,7 @@ impl<I: Interner> ExistentialProjection<I> { |
| 505 | 504 | debug_assert!(!self_ty.has_escaping_bound_vars()); |
| 506 | 505 | |
| 507 | 506 | ProjectionPredicate { |
| 508 | projection_term: AliasTerm::new( | |
| 507 | projection_term: ty::AliasTerm::new( | |
| 509 | 508 | interner, |
| 510 | 509 | interner.alias_term_kind_from_def_id(self.def_id.into()), |
| 511 | 510 | [self_ty.into()].iter().chain(self.args.iter()), |
| ... | ... | @@ -537,354 +536,6 @@ impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> { |
| 537 | 536 | } |
| 538 | 537 | } |
| 539 | 538 | |
| 540 | #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 541 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic, GenericTypeVisitable)] | |
| 542 | #[cfg_attr( | |
| 543 | feature = "nightly", | |
| 544 | derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext) | |
| 545 | )] | |
| 546 | pub enum AliasTermKind<I: Interner> { | |
| 547 | /// A projection `<Type as Trait>::AssocType`. | |
| 548 | /// | |
| 549 | /// Can get normalized away if monomorphic enough. | |
| 550 | /// | |
| 551 | /// The `def_id` is the `DefId` of the `TraitItem` for the associated type. | |
| 552 | /// | |
| 553 | /// Note that the `def_id` is not the `DefId` of the `TraitRef` containing this | |
| 554 | /// associated type, which is in `interner.associated_item(def_id).container`, | |
| 555 | /// aka. `interner.parent(def_id)`. | |
| 556 | ProjectionTy { def_id: I::TraitAssocTyId }, | |
| 557 | ||
| 558 | /// An associated type in an inherent `impl` | |
| 559 | /// | |
| 560 | /// The `def_id` is the `DefId` of the `ImplItem` for the associated type. | |
| 561 | InherentTy { def_id: I::InherentAssocTyId }, | |
| 562 | ||
| 563 | /// An opaque type (usually from `impl Trait` in type aliases or function return types) | |
| 564 | /// | |
| 565 | /// `def_id` is the `DefId` of the `OpaqueType` item. | |
| 566 | /// | |
| 567 | /// Can only be normalized away in `PostAnalysis` mode or its defining scope. | |
| 568 | /// | |
| 569 | /// During codegen, `interner.type_of(def_id)` can be used to get the type of the | |
| 570 | /// underlying type if the type is an opaque. | |
| 571 | OpaqueTy { def_id: I::OpaqueTyId }, | |
| 572 | ||
| 573 | /// A type alias that actually checks its trait bounds. | |
| 574 | /// | |
| 575 | /// Currently only used if the type alias references opaque types. | |
| 576 | /// Can always be normalized away. | |
| 577 | FreeTy { def_id: I::FreeTyAliasId }, | |
| 578 | ||
| 579 | /// An unevaluated anonymous constants. | |
| 580 | AnonConst { def_id: I::UnevaluatedConstId }, | |
| 581 | /// An unevaluated const coming from an associated const. | |
| 582 | ProjectionConst { def_id: I::TraitAssocConstId }, | |
| 583 | /// A top level const item not part of a trait or impl. | |
| 584 | FreeConst { def_id: I::FreeConstAliasId }, | |
| 585 | /// An associated const in an inherent `impl` | |
| 586 | InherentConst { def_id: I::InherentAssocConstId }, | |
| 587 | } | |
| 588 | ||
| 589 | impl<I: Interner> AliasTermKind<I> { | |
| 590 | pub fn descr(self) -> &'static str { | |
| 591 | match self { | |
| 592 | AliasTermKind::ProjectionTy { .. } => "associated type", | |
| 593 | AliasTermKind::ProjectionConst { .. } => "associated const", | |
| 594 | AliasTermKind::InherentTy { .. } => "inherent associated type", | |
| 595 | AliasTermKind::InherentConst { .. } => "inherent associated const", | |
| 596 | AliasTermKind::OpaqueTy { .. } => "opaque type", | |
| 597 | AliasTermKind::FreeTy { .. } => "type alias", | |
| 598 | AliasTermKind::FreeConst { .. } => "unevaluated constant", | |
| 599 | AliasTermKind::AnonConst { .. } => "unevaluated constant", | |
| 600 | } | |
| 601 | } | |
| 602 | ||
| 603 | pub fn is_type(self) -> bool { | |
| 604 | match self { | |
| 605 | AliasTermKind::ProjectionTy { .. } | |
| 606 | | AliasTermKind::InherentTy { .. } | |
| 607 | | AliasTermKind::OpaqueTy { .. } | |
| 608 | | AliasTermKind::FreeTy { .. } => true, | |
| 609 | ||
| 610 | AliasTermKind::AnonConst { .. } | |
| 611 | | AliasTermKind::ProjectionConst { .. } | |
| 612 | | AliasTermKind::InherentConst { .. } | |
| 613 | | AliasTermKind::FreeConst { .. } => false, | |
| 614 | } | |
| 615 | } | |
| 616 | ||
| 617 | pub fn is_trait_projection(self) -> bool { | |
| 618 | match self { | |
| 619 | AliasTermKind::ProjectionTy { .. } | AliasTermKind::ProjectionConst { .. } => true, | |
| 620 | AliasTermKind::InherentTy { .. } | |
| 621 | | AliasTermKind::OpaqueTy { .. } | |
| 622 | | AliasTermKind::FreeTy { .. } | |
| 623 | | AliasTermKind::AnonConst { .. } | |
| 624 | | AliasTermKind::FreeConst { .. } | |
| 625 | | AliasTermKind::InherentConst { .. } => false, | |
| 626 | } | |
| 627 | } | |
| 628 | } | |
| 629 | ||
| 630 | impl<I: Interner> From<ty::AliasTyKind<I>> for AliasTermKind<I> { | |
| 631 | fn from(value: ty::AliasTyKind<I>) -> Self { | |
| 632 | match value { | |
| 633 | ty::Projection { def_id } => AliasTermKind::ProjectionTy { def_id }, | |
| 634 | ty::Opaque { def_id } => AliasTermKind::OpaqueTy { def_id }, | |
| 635 | ty::Free { def_id } => AliasTermKind::FreeTy { def_id }, | |
| 636 | ty::Inherent { def_id } => AliasTermKind::InherentTy { def_id }, | |
| 637 | } | |
| 638 | } | |
| 639 | } | |
| 640 | ||
| 641 | impl<I: Interner> From<ty::UnevaluatedConstKind<I>> for AliasTermKind<I> { | |
| 642 | fn from(value: ty::UnevaluatedConstKind<I>) -> Self { | |
| 643 | match value { | |
| 644 | ty::UnevaluatedConstKind::Projection { def_id } => { | |
| 645 | AliasTermKind::ProjectionConst { def_id } | |
| 646 | } | |
| 647 | ty::UnevaluatedConstKind::Inherent { def_id } => { | |
| 648 | AliasTermKind::InherentConst { def_id } | |
| 649 | } | |
| 650 | ty::UnevaluatedConstKind::Free { def_id } => AliasTermKind::FreeConst { def_id }, | |
| 651 | ty::UnevaluatedConstKind::Anon { def_id } => AliasTermKind::AnonConst { def_id }, | |
| 652 | } | |
| 653 | } | |
| 654 | } | |
| 655 | ||
| 656 | impl<I: Interner> AliasTerm<I> { | |
| 657 | pub fn new_from_args( | |
| 658 | interner: I, | |
| 659 | kind: AliasTermKind<I>, | |
| 660 | args: I::GenericArgs, | |
| 661 | ) -> AliasTerm<I> { | |
| 662 | if cfg!(debug_assertions) { | |
| 663 | let def_id = match kind { | |
| 664 | AliasTermKind::ProjectionTy { def_id } => def_id.into(), | |
| 665 | AliasTermKind::InherentTy { def_id } => def_id.into(), | |
| 666 | AliasTermKind::OpaqueTy { def_id } => def_id.into(), | |
| 667 | AliasTermKind::FreeTy { def_id } => def_id.into(), | |
| 668 | AliasTermKind::AnonConst { def_id } => def_id.into(), | |
| 669 | AliasTermKind::ProjectionConst { def_id } => def_id.into(), | |
| 670 | AliasTermKind::FreeConst { def_id } => def_id.into(), | |
| 671 | AliasTermKind::InherentConst { def_id } => def_id.into(), | |
| 672 | }; | |
| 673 | interner.debug_assert_args_compatible(def_id, args); | |
| 674 | } | |
| 675 | AliasTerm { kind, args, _use_alias_new_instead: () } | |
| 676 | } | |
| 677 | ||
| 678 | pub fn new( | |
| 679 | interner: I, | |
| 680 | kind: AliasTermKind<I>, | |
| 681 | args: impl IntoIterator<Item: Into<I::GenericArg>>, | |
| 682 | ) -> AliasTerm<I> { | |
| 683 | let args = interner.mk_args_from_iter(args.into_iter().map(Into::into)); | |
| 684 | Self::new_from_args(interner, kind, args) | |
| 685 | } | |
| 686 | ||
| 687 | pub fn new_from_def_id(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> { | |
| 688 | let kind = interner.alias_term_kind_from_def_id(def_id); | |
| 689 | Self::new_from_args(interner, kind, args) | |
| 690 | } | |
| 691 | ||
| 692 | pub fn expect_ty(self) -> ty::AliasTy<I> { | |
| 693 | let kind = match self.kind { | |
| 694 | AliasTermKind::ProjectionTy { def_id } => AliasTyKind::Projection { def_id }, | |
| 695 | AliasTermKind::InherentTy { def_id } => AliasTyKind::Inherent { def_id }, | |
| 696 | AliasTermKind::OpaqueTy { def_id } => AliasTyKind::Opaque { def_id }, | |
| 697 | AliasTermKind::FreeTy { def_id } => AliasTyKind::Free { def_id }, | |
| 698 | kind @ (AliasTermKind::InherentConst { .. } | |
| 699 | | AliasTermKind::FreeConst { .. } | |
| 700 | | AliasTermKind::AnonConst { .. } | |
| 701 | | AliasTermKind::ProjectionConst { .. }) => { | |
| 702 | panic!("Cannot turn `{}` into `AliasTy`", kind.descr()) | |
| 703 | } | |
| 704 | }; | |
| 705 | ty::AliasTy { kind, args: self.args, _use_alias_new_instead: () } | |
| 706 | } | |
| 707 | ||
| 708 | pub fn expect_ct(self) -> ty::UnevaluatedConst<I> { | |
| 709 | let kind = match self.kind { | |
| 710 | AliasTermKind::InherentConst { def_id } => UnevaluatedConstKind::Inherent { def_id }, | |
| 711 | AliasTermKind::FreeConst { def_id } => UnevaluatedConstKind::Free { def_id }, | |
| 712 | AliasTermKind::AnonConst { def_id } => UnevaluatedConstKind::Anon { def_id }, | |
| 713 | AliasTermKind::ProjectionConst { def_id } => { | |
| 714 | UnevaluatedConstKind::Projection { def_id } | |
| 715 | } | |
| 716 | kind @ (AliasTermKind::ProjectionTy { .. } | |
| 717 | | AliasTermKind::InherentTy { .. } | |
| 718 | | AliasTermKind::OpaqueTy { .. } | |
| 719 | | AliasTermKind::FreeTy { .. }) => { | |
| 720 | panic!("Cannot turn `{}` into `UnevaluatedConst`", kind.descr()) | |
| 721 | } | |
| 722 | }; | |
| 723 | ty::UnevaluatedConst { kind, args: self.args, _use_alias_new_instead: () } | |
| 724 | } | |
| 725 | ||
| 726 | pub fn to_term(self, interner: I) -> I::Term { | |
| 727 | let alias_ty = |kind| { | |
| 728 | Ty::new_alias(interner, ty::AliasTy::new_from_args(interner, kind, self.args)).into() | |
| 729 | }; | |
| 730 | let unevaluated_const = |kind| { | |
| 731 | I::Const::new_unevaluated( | |
| 732 | interner, | |
| 733 | ty::UnevaluatedConst::new(interner, kind, self.args), | |
| 734 | ) | |
| 735 | .into() | |
| 736 | }; | |
| 737 | match self.kind { | |
| 738 | AliasTermKind::FreeConst { def_id } => { | |
| 739 | unevaluated_const(UnevaluatedConstKind::Free { def_id }) | |
| 740 | } | |
| 741 | AliasTermKind::InherentConst { def_id } => { | |
| 742 | unevaluated_const(UnevaluatedConstKind::Inherent { def_id }) | |
| 743 | } | |
| 744 | AliasTermKind::AnonConst { def_id } => { | |
| 745 | unevaluated_const(UnevaluatedConstKind::Anon { def_id }) | |
| 746 | } | |
| 747 | AliasTermKind::ProjectionConst { def_id } => { | |
| 748 | unevaluated_const(UnevaluatedConstKind::Projection { def_id }) | |
| 749 | } | |
| 750 | AliasTermKind::ProjectionTy { def_id } => alias_ty(ty::Projection { def_id }), | |
| 751 | AliasTermKind::InherentTy { def_id } => alias_ty(ty::Inherent { def_id }), | |
| 752 | AliasTermKind::OpaqueTy { def_id } => alias_ty(ty::Opaque { def_id }), | |
| 753 | AliasTermKind::FreeTy { def_id } => alias_ty(ty::Free { def_id }), | |
| 754 | } | |
| 755 | } | |
| 756 | ||
| 757 | pub fn with_args(self, interner: I, args: I::GenericArgs) -> Self { | |
| 758 | Self::new_from_args(interner, self.kind, args) | |
| 759 | } | |
| 760 | ||
| 761 | pub fn expect_projection_ty_def_id(self) -> I::TraitAssocTyId { | |
| 762 | match self.kind { | |
| 763 | AliasTermKind::ProjectionTy { def_id } => def_id, | |
| 764 | kind => panic!("expected projection ty, found {kind:?}"), | |
| 765 | } | |
| 766 | } | |
| 767 | ||
| 768 | pub fn expect_opaque_ty_def_id(self) -> I::OpaqueTyId { | |
| 769 | match self.kind { | |
| 770 | AliasTermKind::OpaqueTy { def_id } => def_id, | |
| 771 | kind => panic!("expected opaque ty, found {kind:?}"), | |
| 772 | } | |
| 773 | } | |
| 774 | } | |
| 775 | ||
| 776 | /// The following methods work only with (trait) associated term projections. | |
| 777 | // FIXME: Replace by an impl on Alias<ProjectionAliasTermKind> | |
| 778 | impl<I: Interner> AliasTerm<I> { | |
| 779 | pub fn self_ty(self) -> I::Ty { | |
| 780 | self.args.type_at(0) | |
| 781 | } | |
| 782 | ||
| 783 | pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { | |
| 784 | AliasTerm::new( | |
| 785 | interner, | |
| 786 | self.kind, | |
| 787 | [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), | |
| 788 | ) | |
| 789 | } | |
| 790 | ||
| 791 | pub fn expect_projection_def_id(self) -> I::TraitAssocTermId { | |
| 792 | match self.kind { | |
| 793 | AliasTermKind::ProjectionTy { def_id } => def_id.into(), | |
| 794 | AliasTermKind::ProjectionConst { def_id } => def_id.into(), | |
| 795 | kind => panic!("expected projection alias, found {kind:?}"), | |
| 796 | } | |
| 797 | } | |
| 798 | ||
| 799 | pub fn trait_def_id(self, interner: I) -> I::TraitId { | |
| 800 | interner.projection_parent(self.expect_projection_def_id()) | |
| 801 | } | |
| 802 | ||
| 803 | /// Extracts the underlying trait reference and own args from this projection. | |
| 804 | /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`, | |
| 805 | /// then this function would return a `T: StreamingIterator` trait reference and | |
| 806 | /// `['a]` as the own args. | |
| 807 | pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) { | |
| 808 | interner.trait_ref_and_own_args_for_alias(self.expect_projection_def_id(), self.args) | |
| 809 | } | |
| 810 | ||
| 811 | /// Extracts the underlying trait reference from this projection. | |
| 812 | /// For example, if this is a projection of `<T as Iterator>::Item`, | |
| 813 | /// then this function would return a `T: Iterator` trait reference. | |
| 814 | /// | |
| 815 | /// WARNING: This will drop the args for generic associated types | |
| 816 | /// consider calling [Self::trait_ref_and_own_args] to get those | |
| 817 | /// as well. | |
| 818 | pub fn trait_ref(self, interner: I) -> TraitRef<I> { | |
| 819 | self.trait_ref_and_own_args(interner).0 | |
| 820 | } | |
| 821 | ||
| 822 | /// Extract the own args from this projection. | |
| 823 | /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`, | |
| 824 | /// then this function would return the slice `['a]` as the own args. | |
| 825 | pub fn own_args(self, interner: I) -> I::GenericArgsSlice { | |
| 826 | self.trait_ref_and_own_args(interner).1 | |
| 827 | } | |
| 828 | } | |
| 829 | ||
| 830 | /// The following methods work only with inherent associated term projections. | |
| 831 | // FIXME: Replace by an impl on Alias<InherentAliasTermKind> | |
| 832 | impl<I: Interner> AliasTerm<I> { | |
| 833 | pub fn expect_inherent_def_id(self) -> I::InherentAssocTermId { | |
| 834 | match self.kind { | |
| 835 | AliasTermKind::InherentTy { def_id } => def_id.into(), | |
| 836 | AliasTermKind::InherentConst { def_id } => def_id.into(), | |
| 837 | kind => panic!("expected inherent alias, found {kind:?}"), | |
| 838 | } | |
| 839 | } | |
| 840 | ||
| 841 | /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that. | |
| 842 | /// | |
| 843 | /// Does the following transformation: | |
| 844 | /// | |
| 845 | /// ```text | |
| 846 | /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m] | |
| 847 | /// | |
| 848 | /// I_i impl args | |
| 849 | /// P_j GAT args | |
| 850 | /// ``` | |
| 851 | pub fn rebase_inherent_args_onto_impl( | |
| 852 | self, | |
| 853 | impl_args: I::GenericArgs, | |
| 854 | interner: I, | |
| 855 | ) -> I::GenericArgs { | |
| 856 | debug_assert!(matches!( | |
| 857 | self.kind, | |
| 858 | AliasTermKind::InherentTy { .. } | AliasTermKind::InherentConst { .. } | |
| 859 | )); | |
| 860 | interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1))) | |
| 861 | } | |
| 862 | } | |
| 863 | ||
| 864 | /// The following methods work only with free term aliases. | |
| 865 | // FIXME: Replace by an impl on Alias<FreeAliasTermKind> | |
| 866 | impl<I: Interner> AliasTerm<I> { | |
| 867 | pub fn expect_free_def_id(self) -> I::FreeTermAliasId { | |
| 868 | match self.kind { | |
| 869 | AliasTermKind::FreeTy { def_id } => def_id.into(), | |
| 870 | AliasTermKind::FreeConst { def_id } => def_id.into(), | |
| 871 | kind => panic!("expected free alias, found {kind:?}"), | |
| 872 | } | |
| 873 | } | |
| 874 | } | |
| 875 | ||
| 876 | impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> { | |
| 877 | fn from(ty: ty::AliasTy<I>) -> Self { | |
| 878 | AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () } | |
| 879 | } | |
| 880 | } | |
| 881 | ||
| 882 | impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> { | |
| 883 | fn from(ty: ty::UnevaluatedConst<I>) -> Self { | |
| 884 | AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () } | |
| 885 | } | |
| 886 | } | |
| 887 | ||
| 888 | 539 | /// This kind of predicate has no *direct* correspondent in the |
| 889 | 540 | /// syntax, but it roughly corresponds to the syntactic forms: |
| 890 | 541 | /// |
| ... | ... | @@ -904,7 +555,7 @@ impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> { |
| 904 | 555 | derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) |
| 905 | 556 | )] |
| 906 | 557 | pub struct ProjectionPredicate<I: Interner> { |
| 907 | pub projection_term: AliasTerm<I>, | |
| 558 | pub projection_term: ty::AliasTerm<I>, | |
| 908 | 559 | pub term: I::Term, |
| 909 | 560 | } |
| 910 | 561 | |
| ... | ... | @@ -966,7 +617,7 @@ impl<I: Interner> fmt::Debug for ProjectionPredicate<I> { |
| 966 | 617 | feature = "nightly", |
| 967 | 618 | derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) |
| 968 | 619 | )] |
| 969 | pub struct NormalizesTo<I: Interner, K = AliasTermKind<I>> { | |
| 620 | pub struct NormalizesTo<I: Interner, K = ty::AliasTermKind<I>> { | |
| 970 | 621 | pub alias: Alias<I, K>, |
| 971 | 622 | pub term: I::Term, |
| 972 | 623 | } |
compiler/rustc_type_ir/src/region_constraint.rs+35-13| ... | ... | @@ -840,7 +840,15 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling< |
| 840 | 840 | escaping_outlives, |
| 841 | 841 | I::BoundVarKinds::from_vars(infcx.cx(), bound_vars), |
| 842 | 842 | ); |
| 843 | candidates.push(RegionConstraint::AliasTyOutlivesViaEnv(bound_outlives)); | |
| 843 | let candidate = RegionConstraint::AliasTyOutlivesViaEnv(bound_outlives); | |
| 844 | if max_universe(infcx, candidate.clone()) < u { | |
| 845 | candidates.push(candidate); | |
| 846 | } else { | |
| 847 | // `PlaceholderReplacer` only folds regions. A non-lifetime binder can leave | |
| 848 | // a placeholder type in `u`, so this type-outlives constraint cannot be | |
| 849 | // handled by the region-outlives-only eager placeholder machinery. | |
| 850 | candidates.push(Ambiguity); | |
| 851 | } | |
| 844 | 852 | } |
| 845 | 853 | |
| 846 | 854 | let assumptions = match assumptions { |
| ... | ... | @@ -885,12 +893,17 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling< |
| 885 | 893 | |
| 886 | 894 | // while we did skip the binder, bound vars aren't in any universe so |
| 887 | 895 | // this can't be an escaping bound var |
| 888 | candidates.extend( | |
| 889 | regions_outliving(escaping_r, assumptions, infcx.cx()) | |
| 890 | .filter(|r2| max_universe(infcx, *r2) < u) | |
| 891 | .map(|r2| AliasTyOutlivesViaEnv(bound_alias.map_bound(|alias| (alias, r2)))) | |
| 892 | .collect::<Vec<_>>(), | |
| 893 | ); | |
| 896 | for r2 in regions_outliving(escaping_r, assumptions, infcx.cx()) | |
| 897 | .filter(|r2| max_universe(infcx, *r2) < u) | |
| 898 | { | |
| 899 | let candidate = | |
| 900 | AliasTyOutlivesViaEnv(bound_alias.map_bound(|alias| (alias, r2))); | |
| 901 | if max_universe(infcx, candidate.clone()) < u { | |
| 902 | candidates.push(candidate); | |
| 903 | } else { | |
| 904 | candidates.push(Ambiguity); | |
| 905 | } | |
| 906 | } | |
| 894 | 907 | } |
| 895 | 908 | |
| 896 | 909 | // I'm not convinced our handling here is *complete* so for now |
| ... | ... | @@ -978,11 +991,14 @@ pub fn regions_outlived_by_placeholder<I: Interner>( |
| 978 | 991 | } |
| 979 | 992 | |
| 980 | 993 | /// The largest universe a variable or placeholder was from in `t` |
| 981 | pub fn max_universe<Infcx: InferCtxtLike<Interner = I>, I: Interner, T: TypeVisitable<I>>( | |
| 994 | pub fn max_universe<Infcx: InferCtxtLike<Interner = I>, I: Interner, T: TypeFoldable<I>>( | |
| 982 | 995 | infcx: &Infcx, |
| 983 | 996 | t: T, |
| 984 | 997 | ) -> UniverseIndex { |
| 985 | 998 | let mut visitor = MaxUniverse::new(infcx); |
| 999 | // `max_universe` is also used while rewriting constraints to lower universes, | |
| 1000 | // so do not rely on callers having already resolved non-region infer vars. | |
| 1001 | let t = infcx.resolve_vars_if_possible(t); | |
| 986 | 1002 | t.visit_with(&mut visitor); |
| 987 | 1003 | visitor.max_universe() |
| 988 | 1004 | } |
| ... | ... | @@ -1036,11 +1052,17 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeVisitor<I> |
| 1036 | 1052 | fn visit_region(&mut self, r: I::Region) { |
| 1037 | 1053 | match r.kind() { |
| 1038 | 1054 | RegionKind::RePlaceholder(p) => self.max_universe = self.max_universe.max(p.universe), |
| 1039 | RegionKind::ReVar(var) => { | |
| 1040 | let u = self.infcx.universe_of_lt(var).unwrap(); | |
| 1041 | debug!("var {var:?} in universe {u:?}"); | |
| 1042 | self.max_universe = self.max_universe.max(u); | |
| 1043 | } | |
| 1055 | RegionKind::ReVar(var) => match self.infcx.opportunistic_resolve_lt_var(var).kind() { | |
| 1056 | RegionKind::RePlaceholder(p) => { | |
| 1057 | self.max_universe = self.max_universe.max(p.universe) | |
| 1058 | } | |
| 1059 | RegionKind::ReVar(var) => { | |
| 1060 | let u = self.infcx.universe_of_lt(var).unwrap(); | |
| 1061 | debug!("var {var:?} in universe {u:?}"); | |
| 1062 | self.max_universe = self.max_universe.max(u); | |
| 1063 | } | |
| 1064 | _ => (), | |
| 1065 | }, | |
| 1044 | 1066 | _ => (), |
| 1045 | 1067 | } |
| 1046 | 1068 | } |
compiler/rustc_type_ir/src/term_kind.rs created+372| ... | ... | @@ -0,0 +1,372 @@ |
| 1 | use derive_where::derive_where; | |
| 2 | #[cfg(feature = "nightly")] | |
| 3 | use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext}; | |
| 4 | use rustc_type_ir_macros::{ | |
| 5 | GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, | |
| 6 | }; | |
| 7 | ||
| 8 | use crate::inherent::*; | |
| 9 | use crate::{self as ty, AliasTerm, Interner}; | |
| 10 | ||
| 11 | #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] | |
| 12 | #[derive(GenericTypeVisitable)] | |
| 13 | #[cfg_attr( | |
| 14 | feature = "nightly", | |
| 15 | derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) | |
| 16 | )] | |
| 17 | pub enum TermKind<I: Interner> { | |
| 18 | Ty(I::Ty), | |
| 19 | Const(I::Const), | |
| 20 | } | |
| 21 | ||
| 22 | impl<I: Interner> Eq for TermKind<I> {} | |
| 23 | ||
| 24 | #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 25 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic, GenericTypeVisitable)] | |
| 26 | #[cfg_attr( | |
| 27 | feature = "nightly", | |
| 28 | derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext) | |
| 29 | )] | |
| 30 | pub enum AliasTermKind<I: Interner> { | |
| 31 | /// A projection `<Type as Trait>::AssocType`. | |
| 32 | /// | |
| 33 | /// Can get normalized away if monomorphic enough. | |
| 34 | /// | |
| 35 | /// The `def_id` is the `DefId` of the `TraitItem` for the associated type. | |
| 36 | /// | |
| 37 | /// Note that the `def_id` is not the `DefId` of the `TraitRef` containing this | |
| 38 | /// associated type, which is in `interner.associated_item(def_id).container`, | |
| 39 | /// aka. `interner.parent(def_id)`. | |
| 40 | ProjectionTy { def_id: I::TraitAssocTyId }, | |
| 41 | ||
| 42 | /// An associated type in an inherent `impl` | |
| 43 | /// | |
| 44 | /// The `def_id` is the `DefId` of the `ImplItem` for the associated type. | |
| 45 | InherentTy { def_id: I::InherentAssocTyId }, | |
| 46 | ||
| 47 | /// An opaque type (usually from `impl Trait` in type aliases or function return types) | |
| 48 | /// | |
| 49 | /// `def_id` is the `DefId` of the `OpaqueType` item. | |
| 50 | /// | |
| 51 | /// Can only be normalized away in `PostAnalysis` mode or its defining scope. | |
| 52 | /// | |
| 53 | /// During codegen, `interner.type_of(def_id)` can be used to get the type of the | |
| 54 | /// underlying type if the type is an opaque. | |
| 55 | OpaqueTy { def_id: I::OpaqueTyId }, | |
| 56 | ||
| 57 | /// A type alias that actually checks its trait bounds. | |
| 58 | /// | |
| 59 | /// Currently only used if the type alias references opaque types. | |
| 60 | /// Can always be normalized away. | |
| 61 | FreeTy { def_id: I::FreeTyAliasId }, | |
| 62 | ||
| 63 | /// An unevaluated anonymous constants. | |
| 64 | AnonConst { def_id: I::UnevaluatedConstId }, | |
| 65 | /// An unevaluated const coming from an associated const. | |
| 66 | ProjectionConst { def_id: I::TraitAssocConstId }, | |
| 67 | /// A top level const item not part of a trait or impl. | |
| 68 | FreeConst { def_id: I::FreeConstAliasId }, | |
| 69 | /// An associated const in an inherent `impl` | |
| 70 | InherentConst { def_id: I::InherentAssocConstId }, | |
| 71 | } | |
| 72 | ||
| 73 | impl<I: Interner> AliasTermKind<I> { | |
| 74 | pub fn descr(self) -> &'static str { | |
| 75 | match self { | |
| 76 | AliasTermKind::ProjectionTy { .. } => "associated type", | |
| 77 | AliasTermKind::ProjectionConst { .. } => "associated const", | |
| 78 | AliasTermKind::InherentTy { .. } => "inherent associated type", | |
| 79 | AliasTermKind::InherentConst { .. } => "inherent associated const", | |
| 80 | AliasTermKind::OpaqueTy { .. } => "opaque type", | |
| 81 | AliasTermKind::FreeTy { .. } => "type alias", | |
| 82 | AliasTermKind::FreeConst { .. } => "unevaluated constant", | |
| 83 | AliasTermKind::AnonConst { .. } => "unevaluated constant", | |
| 84 | } | |
| 85 | } | |
| 86 | ||
| 87 | pub fn is_type(self) -> bool { | |
| 88 | match self { | |
| 89 | AliasTermKind::ProjectionTy { .. } | |
| 90 | | AliasTermKind::InherentTy { .. } | |
| 91 | | AliasTermKind::OpaqueTy { .. } | |
| 92 | | AliasTermKind::FreeTy { .. } => true, | |
| 93 | ||
| 94 | AliasTermKind::AnonConst { .. } | |
| 95 | | AliasTermKind::ProjectionConst { .. } | |
| 96 | | AliasTermKind::InherentConst { .. } | |
| 97 | | AliasTermKind::FreeConst { .. } => false, | |
| 98 | } | |
| 99 | } | |
| 100 | ||
| 101 | pub fn is_trait_projection(self) -> bool { | |
| 102 | match self { | |
| 103 | AliasTermKind::ProjectionTy { .. } | AliasTermKind::ProjectionConst { .. } => true, | |
| 104 | AliasTermKind::InherentTy { .. } | |
| 105 | | AliasTermKind::OpaqueTy { .. } | |
| 106 | | AliasTermKind::FreeTy { .. } | |
| 107 | | AliasTermKind::AnonConst { .. } | |
| 108 | | AliasTermKind::FreeConst { .. } | |
| 109 | | AliasTermKind::InherentConst { .. } => false, | |
| 110 | } | |
| 111 | } | |
| 112 | } | |
| 113 | ||
| 114 | impl<I: Interner> From<ty::AliasTyKind<I>> for AliasTermKind<I> { | |
| 115 | fn from(value: ty::AliasTyKind<I>) -> Self { | |
| 116 | match value { | |
| 117 | ty::Projection { def_id } => AliasTermKind::ProjectionTy { def_id }, | |
| 118 | ty::Opaque { def_id } => AliasTermKind::OpaqueTy { def_id }, | |
| 119 | ty::Free { def_id } => AliasTermKind::FreeTy { def_id }, | |
| 120 | ty::Inherent { def_id } => AliasTermKind::InherentTy { def_id }, | |
| 121 | } | |
| 122 | } | |
| 123 | } | |
| 124 | ||
| 125 | impl<I: Interner> From<ty::UnevaluatedConstKind<I>> for AliasTermKind<I> { | |
| 126 | fn from(value: ty::UnevaluatedConstKind<I>) -> Self { | |
| 127 | match value { | |
| 128 | ty::UnevaluatedConstKind::Projection { def_id } => { | |
| 129 | AliasTermKind::ProjectionConst { def_id } | |
| 130 | } | |
| 131 | ty::UnevaluatedConstKind::Inherent { def_id } => { | |
| 132 | AliasTermKind::InherentConst { def_id } | |
| 133 | } | |
| 134 | ty::UnevaluatedConstKind::Free { def_id } => AliasTermKind::FreeConst { def_id }, | |
| 135 | ty::UnevaluatedConstKind::Anon { def_id } => AliasTermKind::AnonConst { def_id }, | |
| 136 | } | |
| 137 | } | |
| 138 | } | |
| 139 | ||
| 140 | impl<I: Interner> AliasTerm<I> { | |
| 141 | pub fn new_from_args( | |
| 142 | interner: I, | |
| 143 | kind: AliasTermKind<I>, | |
| 144 | args: I::GenericArgs, | |
| 145 | ) -> AliasTerm<I> { | |
| 146 | if cfg!(debug_assertions) { | |
| 147 | let def_id = match kind { | |
| 148 | AliasTermKind::ProjectionTy { def_id } => def_id.into(), | |
| 149 | AliasTermKind::InherentTy { def_id } => def_id.into(), | |
| 150 | AliasTermKind::OpaqueTy { def_id } => def_id.into(), | |
| 151 | AliasTermKind::FreeTy { def_id } => def_id.into(), | |
| 152 | AliasTermKind::AnonConst { def_id } => def_id.into(), | |
| 153 | AliasTermKind::ProjectionConst { def_id } => def_id.into(), | |
| 154 | AliasTermKind::FreeConst { def_id } => def_id.into(), | |
| 155 | AliasTermKind::InherentConst { def_id } => def_id.into(), | |
| 156 | }; | |
| 157 | interner.debug_assert_args_compatible(def_id, args); | |
| 158 | } | |
| 159 | AliasTerm { kind, args, _use_alias_new_instead: () } | |
| 160 | } | |
| 161 | ||
| 162 | pub fn new( | |
| 163 | interner: I, | |
| 164 | kind: AliasTermKind<I>, | |
| 165 | args: impl IntoIterator<Item: Into<I::GenericArg>>, | |
| 166 | ) -> AliasTerm<I> { | |
| 167 | let args = interner.mk_args_from_iter(args.into_iter().map(Into::into)); | |
| 168 | Self::new_from_args(interner, kind, args) | |
| 169 | } | |
| 170 | ||
| 171 | pub fn new_from_def_id(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> { | |
| 172 | let kind = interner.alias_term_kind_from_def_id(def_id); | |
| 173 | Self::new_from_args(interner, kind, args) | |
| 174 | } | |
| 175 | ||
| 176 | pub fn expect_ty(self) -> ty::AliasTy<I> { | |
| 177 | let kind = match self.kind { | |
| 178 | AliasTermKind::ProjectionTy { def_id } => ty::AliasTyKind::Projection { def_id }, | |
| 179 | AliasTermKind::InherentTy { def_id } => ty::AliasTyKind::Inherent { def_id }, | |
| 180 | AliasTermKind::OpaqueTy { def_id } => ty::AliasTyKind::Opaque { def_id }, | |
| 181 | AliasTermKind::FreeTy { def_id } => ty::AliasTyKind::Free { def_id }, | |
| 182 | kind @ (AliasTermKind::InherentConst { .. } | |
| 183 | | AliasTermKind::FreeConst { .. } | |
| 184 | | AliasTermKind::AnonConst { .. } | |
| 185 | | AliasTermKind::ProjectionConst { .. }) => { | |
| 186 | panic!("Cannot turn `{}` into `AliasTy`", kind.descr()) | |
| 187 | } | |
| 188 | }; | |
| 189 | ty::AliasTy { kind, args: self.args, _use_alias_new_instead: () } | |
| 190 | } | |
| 191 | ||
| 192 | pub fn expect_ct(self) -> ty::UnevaluatedConst<I> { | |
| 193 | let kind = match self.kind { | |
| 194 | AliasTermKind::InherentConst { def_id } => { | |
| 195 | ty::UnevaluatedConstKind::Inherent { def_id } | |
| 196 | } | |
| 197 | AliasTermKind::FreeConst { def_id } => ty::UnevaluatedConstKind::Free { def_id }, | |
| 198 | AliasTermKind::AnonConst { def_id } => ty::UnevaluatedConstKind::Anon { def_id }, | |
| 199 | AliasTermKind::ProjectionConst { def_id } => { | |
| 200 | ty::UnevaluatedConstKind::Projection { def_id } | |
| 201 | } | |
| 202 | kind @ (AliasTermKind::ProjectionTy { .. } | |
| 203 | | AliasTermKind::InherentTy { .. } | |
| 204 | | AliasTermKind::OpaqueTy { .. } | |
| 205 | | AliasTermKind::FreeTy { .. }) => { | |
| 206 | panic!("Cannot turn `{}` into `UnevaluatedConst`", kind.descr()) | |
| 207 | } | |
| 208 | }; | |
| 209 | ty::UnevaluatedConst { kind, args: self.args, _use_alias_new_instead: () } | |
| 210 | } | |
| 211 | ||
| 212 | pub fn to_term(self, interner: I) -> I::Term { | |
| 213 | let alias_ty = |kind| { | |
| 214 | Ty::new_alias(interner, ty::AliasTy::new_from_args(interner, kind, self.args)).into() | |
| 215 | }; | |
| 216 | let unevaluated_const = |kind| { | |
| 217 | I::Const::new_unevaluated( | |
| 218 | interner, | |
| 219 | ty::UnevaluatedConst::new(interner, kind, self.args), | |
| 220 | ) | |
| 221 | .into() | |
| 222 | }; | |
| 223 | match self.kind { | |
| 224 | AliasTermKind::FreeConst { def_id } => { | |
| 225 | unevaluated_const(ty::UnevaluatedConstKind::Free { def_id }) | |
| 226 | } | |
| 227 | AliasTermKind::InherentConst { def_id } => { | |
| 228 | unevaluated_const(ty::UnevaluatedConstKind::Inherent { def_id }) | |
| 229 | } | |
| 230 | AliasTermKind::AnonConst { def_id } => { | |
| 231 | unevaluated_const(ty::UnevaluatedConstKind::Anon { def_id }) | |
| 232 | } | |
| 233 | AliasTermKind::ProjectionConst { def_id } => { | |
| 234 | unevaluated_const(ty::UnevaluatedConstKind::Projection { def_id }) | |
| 235 | } | |
| 236 | AliasTermKind::ProjectionTy { def_id } => alias_ty(ty::Projection { def_id }), | |
| 237 | AliasTermKind::InherentTy { def_id } => alias_ty(ty::Inherent { def_id }), | |
| 238 | AliasTermKind::OpaqueTy { def_id } => alias_ty(ty::Opaque { def_id }), | |
| 239 | AliasTermKind::FreeTy { def_id } => alias_ty(ty::Free { def_id }), | |
| 240 | } | |
| 241 | } | |
| 242 | ||
| 243 | pub fn with_args(self, interner: I, args: I::GenericArgs) -> Self { | |
| 244 | Self::new_from_args(interner, self.kind, args) | |
| 245 | } | |
| 246 | ||
| 247 | pub fn expect_projection_ty_def_id(self) -> I::TraitAssocTyId { | |
| 248 | match self.kind { | |
| 249 | AliasTermKind::ProjectionTy { def_id } => def_id, | |
| 250 | kind => panic!("expected projection ty, found {kind:?}"), | |
| 251 | } | |
| 252 | } | |
| 253 | ||
| 254 | pub fn expect_opaque_ty_def_id(self) -> I::OpaqueTyId { | |
| 255 | match self.kind { | |
| 256 | AliasTermKind::OpaqueTy { def_id } => def_id, | |
| 257 | kind => panic!("expected opaque ty, found {kind:?}"), | |
| 258 | } | |
| 259 | } | |
| 260 | } | |
| 261 | ||
| 262 | /// The following methods work only with (trait) associated term projections. | |
| 263 | // FIXME: Replace by an impl on Alias<ProjectionAliasTermKind> | |
| 264 | impl<I: Interner> AliasTerm<I> { | |
| 265 | pub fn self_ty(self) -> I::Ty { | |
| 266 | self.args.type_at(0) | |
| 267 | } | |
| 268 | ||
| 269 | pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { | |
| 270 | AliasTerm::new( | |
| 271 | interner, | |
| 272 | self.kind, | |
| 273 | [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), | |
| 274 | ) | |
| 275 | } | |
| 276 | ||
| 277 | pub fn expect_projection_def_id(self) -> I::TraitAssocTermId { | |
| 278 | match self.kind { | |
| 279 | AliasTermKind::ProjectionTy { def_id } => def_id.into(), | |
| 280 | AliasTermKind::ProjectionConst { def_id } => def_id.into(), | |
| 281 | kind => panic!("expected projection alias, found {kind:?}"), | |
| 282 | } | |
| 283 | } | |
| 284 | ||
| 285 | pub fn trait_def_id(self, interner: I) -> I::TraitId { | |
| 286 | interner.projection_parent(self.expect_projection_def_id()) | |
| 287 | } | |
| 288 | ||
| 289 | /// Extracts the underlying trait reference and own args from this projection. | |
| 290 | /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`, | |
| 291 | /// then this function would return a `T: StreamingIterator` trait reference and | |
| 292 | /// `['a]` as the own args. | |
| 293 | pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) { | |
| 294 | interner.trait_ref_and_own_args_for_alias(self.expect_projection_def_id(), self.args) | |
| 295 | } | |
| 296 | ||
| 297 | /// Extracts the underlying trait reference from this projection. | |
| 298 | /// For example, if this is a projection of `<T as Iterator>::Item`, | |
| 299 | /// then this function would return a `T: Iterator` trait reference. | |
| 300 | /// | |
| 301 | /// WARNING: This will drop the args for generic associated types | |
| 302 | /// consider calling [Self::trait_ref_and_own_args] to get those | |
| 303 | /// as well. | |
| 304 | pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> { | |
| 305 | self.trait_ref_and_own_args(interner).0 | |
| 306 | } | |
| 307 | ||
| 308 | /// Extract the own args from this projection. | |
| 309 | /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`, | |
| 310 | /// then this function would return the slice `['a]` as the own args. | |
| 311 | pub fn own_args(self, interner: I) -> I::GenericArgsSlice { | |
| 312 | self.trait_ref_and_own_args(interner).1 | |
| 313 | } | |
| 314 | } | |
| 315 | ||
| 316 | /// The following methods work only with inherent associated term projections. | |
| 317 | // FIXME: Replace by an impl on Alias<InherentAliasTermKind> | |
| 318 | impl<I: Interner> AliasTerm<I> { | |
| 319 | pub fn expect_inherent_def_id(self) -> I::InherentAssocTermId { | |
| 320 | match self.kind { | |
| 321 | AliasTermKind::InherentTy { def_id } => def_id.into(), | |
| 322 | AliasTermKind::InherentConst { def_id } => def_id.into(), | |
| 323 | kind => panic!("expected inherent alias, found {kind:?}"), | |
| 324 | } | |
| 325 | } | |
| 326 | ||
| 327 | /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that. | |
| 328 | /// | |
| 329 | /// Does the following transformation: | |
| 330 | /// | |
| 331 | /// ```text | |
| 332 | /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m] | |
| 333 | /// | |
| 334 | /// I_i impl args | |
| 335 | /// P_j GAT args | |
| 336 | /// ``` | |
| 337 | pub fn rebase_inherent_args_onto_impl( | |
| 338 | self, | |
| 339 | impl_args: I::GenericArgs, | |
| 340 | interner: I, | |
| 341 | ) -> I::GenericArgs { | |
| 342 | debug_assert!(matches!( | |
| 343 | self.kind, | |
| 344 | AliasTermKind::InherentTy { .. } | AliasTermKind::InherentConst { .. } | |
| 345 | )); | |
| 346 | interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1))) | |
| 347 | } | |
| 348 | } | |
| 349 | ||
| 350 | /// The following methods work only with free term aliases. | |
| 351 | // FIXME: Replace by an impl on Alias<FreeAliasTermKind> | |
| 352 | impl<I: Interner> AliasTerm<I> { | |
| 353 | pub fn expect_free_def_id(self) -> I::FreeTermAliasId { | |
| 354 | match self.kind { | |
| 355 | AliasTermKind::FreeTy { def_id } => def_id.into(), | |
| 356 | AliasTermKind::FreeConst { def_id } => def_id.into(), | |
| 357 | kind => panic!("expected free alias, found {kind:?}"), | |
| 358 | } | |
| 359 | } | |
| 360 | } | |
| 361 | ||
| 362 | impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> { | |
| 363 | fn from(ty: ty::AliasTy<I>) -> Self { | |
| 364 | AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () } | |
| 365 | } | |
| 366 | } | |
| 367 | ||
| 368 | impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> { | |
| 369 | fn from(ty: ty::UnevaluatedConst<I>) -> Self { | |
| 370 | AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () } | |
| 371 | } | |
| 372 | } |
compiler/rustc_type_ir/src/ty/alias.rs+1-3| ... | ... | @@ -5,9 +5,7 @@ use rustc_type_ir_macros::{ |
| 5 | 5 | GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, |
| 6 | 6 | }; |
| 7 | 7 | |
| 8 | use crate::predicate::AliasTermKind; | |
| 9 | use crate::ty_kind::AliasTyKind; | |
| 10 | use crate::{Interner, UnevaluatedConstKind}; | |
| 8 | use crate::{AliasTermKind, AliasTyKind, Interner, UnevaluatedConstKind}; | |
| 11 | 9 | |
| 12 | 10 | /// Represents an alias of a type, constant, or other term-like item. |
| 13 | 11 | /// |
library/Cargo.lock+2-2| ... | ... | @@ -283,9 +283,9 @@ dependencies = [ |
| 283 | 283 | |
| 284 | 284 | [[package]] |
| 285 | 285 | name = "rustc-literal-escaper" |
| 286 | version = "0.0.7" | |
| 286 | version = "0.0.8" | |
| 287 | 287 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 288 | checksum = "8be87abb9e40db7466e0681dc8ecd9dcfd40360cb10b4c8fe24a7c4c3669b198" | |
| 288 | checksum = "bfe6f213fb658c8fb95baabd5420393438cf5a98d707f5dd701d9197c705f71e" | |
| 289 | 289 | dependencies = [ |
| 290 | 290 | "rustc-std-workspace-core", |
| 291 | 291 | ] |
library/alloc/src/string.rs+19-1| ... | ... | @@ -2239,15 +2239,33 @@ impl FromUtf8Error { |
| 2239 | 2239 | /// invalid sequences, and [`String::from_utf8_lossy_owned`] for the |
| 2240 | 2240 | /// `String` function which corresponds to this function. |
| 2241 | 2241 | /// |
| 2242 | /// This is useful in conjunction with [`String::from_utf8`] when you need | |
| 2243 | /// to branch on whether the bytes are valid UTF-8, but still want to | |
| 2244 | /// recover a lossily converted `String` in the error case. Use | |
| 2245 | /// [`String::from_utf8_lossy_owned`] if you always need a lossily converted | |
| 2246 | /// `String`. | |
| 2247 | /// | |
| 2248 | /// Since the original [`String::from_utf8`] error records where validation | |
| 2249 | /// stopped, this method does not need to re-check the already valid prefix | |
| 2250 | /// of the byte sequence. | |
| 2251 | /// | |
| 2242 | 2252 | /// # Examples |
| 2243 | 2253 | /// |
| 2244 | 2254 | /// ``` |
| 2245 | 2255 | /// #![feature(string_from_utf8_lossy_owned)] |
| 2246 | 2256 | /// // some invalid bytes |
| 2247 | 2257 | /// let input: Vec<u8> = b"Hello \xF0\x90\x80World".into(); |
| 2248 | /// let output = String::from_utf8(input).unwrap_or_else(|e| e.into_utf8_lossy()); | |
| 2258 | /// | |
| 2259 | /// let (output, had_invalid_utf8) = match String::from_utf8(input) { | |
| 2260 | /// Ok(output) => (output, false), | |
| 2261 | /// Err(error) => { | |
| 2262 | /// // The bytes were not valid UTF-8, but we can still recover a string. | |
| 2263 | /// (error.into_utf8_lossy(), true) | |
| 2264 | /// } | |
| 2265 | /// }; | |
| 2249 | 2266 | /// |
| 2250 | 2267 | /// assert_eq!(String::from("Hello �World"), output); |
| 2268 | /// assert!(had_invalid_utf8); | |
| 2251 | 2269 | /// ``` |
| 2252 | 2270 | #[must_use] |
| 2253 | 2271 | #[cfg(not(no_global_oom_handling))] |
library/core/src/char/methods.rs+27-24| ... | ... | @@ -495,7 +495,7 @@ impl char { |
| 495 | 495 | || args.escape_grapheme_extender && self.is_grapheme_extender() |
| 496 | 496 | || self.is_default_ignorable() |
| 497 | 497 | || self.is_format_control() |
| 498 | || self.is_unassigned() => | |
| 498 | || !self.is_assigned() => | |
| 499 | 499 | { |
| 500 | 500 | EscapeDebug::unicode(self) |
| 501 | 501 | } |
| ... | ... | @@ -1139,8 +1139,9 @@ impl char { |
| 1139 | 1139 | /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt |
| 1140 | 1140 | /// |
| 1141 | 1141 | #[must_use] |
| 1142 | #[unstable(feature = "char_unassigned_private_use", issue = "158322")] | |
| 1142 | 1143 | #[inline] |
| 1143 | const fn is_private_use(self) -> bool { | |
| 1144 | pub const fn is_private_use(self) -> bool { | |
| 1144 | 1145 | // According to |
| 1145 | 1146 | // https://www.unicode.org/policies/stability_policy.html#Property_Value, |
| 1146 | 1147 | // the set of codepoints in `Co` will never change. |
| ... | ... | @@ -1176,54 +1177,56 @@ impl char { |
| 1176 | 1177 | self > '\u{AC}' && unicode::Cf(self) |
| 1177 | 1178 | } |
| 1178 | 1179 | |
| 1179 | /// Returns `true` if this `char` has not yet been assigned a meaning by Unicode, as of | |
| 1180 | /// Returns `true` if this `char` has been assigned a meaning by Unicode, as of | |
| 1180 | 1181 | /// [`UNICODE_VERSION`]. |
| 1181 | 1182 | /// |
| 1182 | 1183 | /// [`UNICODE_VERSION`]: Self::UNICODE_VERSION |
| 1183 | 1184 | /// |
| 1184 | /// These characters may have a meaning assigned in the future, | |
| 1185 | /// except for the 66 [noncharacters] which will never be assigned a meaning. | |
| 1186 | /// | |
| 1187 | /// [noncharacters]: https://www.unicode.org/faq/private_use#noncharacters | |
| 1188 | /// | |
| 1189 | 1185 | /// Many of Unicode's [stability policies] apply only to assigned characters. |
| 1190 | 1186 | /// |
| 1191 | 1187 | /// [stability policies]: https://www.unicode.org/policies/stability_policy.html |
| 1192 | 1188 | /// |
| 1193 | /// Unassigned characters (code points with the general category of `Cn`) are [described] in Chapter 4 | |
| 1194 | /// (Character Properties) of the Unicode Standard, and [specified] in the Unicode Character Database | |
| 1195 | /// by their exclusion from [`UnicodeData.txt`]. | |
| 1189 | /// Currently unassigned characters (characters for which this method returns `false`) | |
| 1190 | /// may have a meaning assigned in a future version of Unicode, | |
| 1191 | /// except for the 66 [noncharacters] which will never be assigned a meaning. | |
| 1192 | /// | |
| 1193 | /// [noncharacters]: https://www.unicode.org/faq/private_use.html#noncharacters | |
| 1194 | /// | |
| 1195 | /// A character is considered assigned if it is present in [`UnicodeData.txt`]. | |
| 1196 | /// Unassigned characters have general category `Cn`, as [described] in Chapter 4 | |
| 1197 | /// (Character Properties) of the Unicode Standard. | |
| 1196 | 1198 | /// |
| 1197 | /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153 | |
| 1198 | /// [specified]: https://www.unicode.org/reports/tr44/#GC_Values_Table | |
| 1199 | 1199 | /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt |
| 1200 | /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153 | |
| 1200 | 1201 | /// |
| 1201 | 1202 | /// # Examples |
| 1202 | 1203 | /// |
| 1203 | 1204 | /// Basic usage: |
| 1204 | 1205 | /// |
| 1205 | /// ```ignore(private) | |
| 1206 | /// assert!('\u{FFFE}'.is_unassigned()); // noncharacter, will never be assigned | |
| 1207 | /// | |
| 1208 | /// //assert!('\u{7AAAA}'.is_unassigned()); // not currently assigned, but may be in the future, | |
| 1209 | /// // so we shouldn't rely on the current status | |
| 1206 | /// ``` | |
| 1207 | /// #![feature(char_unassigned_private_use)] | |
| 1208 | /// assert!('γ'.is_assigned()); // once a character is assigned, it stays assigned forever | |
| 1209 | /// assert!(!'\u{FFFE}'.is_assigned()); // noncharacter, will never be assigned | |
| 1210 | 1210 | /// |
| 1211 | /// assert!(!'γ'.is_unassigned()); // once a character is assigned, it stays assigned forever | |
| 1211 | /// // Not currently assigned, but may be in the future, | |
| 1212 | /// // so we shouldn't rely on the current status | |
| 1213 | /// /* assert!(!'\u{7AAAA}'.is_assigned()); */ | |
| 1212 | 1214 | /// ``` |
| 1213 | 1215 | #[must_use] |
| 1216 | #[unstable(feature = "char_unassigned_private_use", issue = "158322")] | |
| 1214 | 1217 | #[inline] |
| 1215 | fn is_unassigned(self) -> bool { | |
| 1218 | pub fn is_assigned(self) -> bool { | |
| 1216 | 1219 | match self { |
| 1217 | '\0'..='\u{377}' => false, | |
| 1218 | '\u{378}'..='\u{3FFFD}' => unicode::Cn_planes_0_3(self), | |
| 1220 | '\0'..='\u{377}' => true, | |
| 1221 | '\u{378}'..='\u{3FFFD}' => !unicode::Cn_planes_0_3(self), | |
| 1219 | 1222 | // Assigned character ranges in planes 4 and above. |
| 1220 | 1223 | // `src/tools/unicode-table-generator/src/main.rs` asserts that this is correct |
| 1221 | 1224 | '\u{E0001}' |
| 1222 | 1225 | | '\u{E0020}'..='\u{E007F}' |
| 1223 | 1226 | | '\u{E0100}'..='\u{E01EF}' |
| 1224 | 1227 | | '\u{F0000}'..='\u{FFFFD}' |
| 1225 | | '\u{100000}'..='\u{10FFFD}' => false, | |
| 1226 | _ => true, | |
| 1228 | | '\u{100000}'..='\u{10FFFD}' => true, | |
| 1229 | _ => false, | |
| 1227 | 1230 | } |
| 1228 | 1231 | } |
| 1229 | 1232 |
library/core/src/io/error.rs+7| ... | ... | @@ -238,6 +238,11 @@ pub enum ErrorKind { |
| 238 | 238 | #[unstable(feature = "io_error_inprogress", issue = "130840")] |
| 239 | 239 | InProgress, |
| 240 | 240 | |
| 241 | /// The process or the whole system has reached its limit on the number of | |
| 242 | /// open files or sockets. | |
| 243 | #[unstable(feature = "io_error_too_many_open_files", issue = "158319")] | |
| 244 | TooManyOpenFiles, | |
| 245 | ||
| 241 | 246 | // "Unusual" error kinds which do not correspond simply to (sets |
| 242 | 247 | // of) OS error codes, should be added just above this comment. |
| 243 | 248 | // `Other` and `Uncategorized` should remain at the end: |
| ... | ... | @@ -309,6 +314,7 @@ impl ErrorKind { |
| 309 | 314 | StorageFull => "no storage space", |
| 310 | 315 | TimedOut => "timed out", |
| 311 | 316 | TooManyLinks => "too many links", |
| 317 | TooManyOpenFiles => "too many open files", | |
| 312 | 318 | Uncategorized => "uncategorized error", |
| 313 | 319 | UnexpectedEof => "unexpected end of file", |
| 314 | 320 | Unsupported => "unsupported", |
| ... | ... | @@ -379,6 +385,7 @@ impl ErrorKind { |
| 379 | 385 | Unsupported, |
| 380 | 386 | OutOfMemory, |
| 381 | 387 | InProgress, |
| 388 | TooManyOpenFiles, | |
| 382 | 389 | Uncategorized, |
| 383 | 390 | }) |
| 384 | 391 | } |
library/core/src/macros/mod.rs+8-8| ... | ... | @@ -40,7 +40,7 @@ macro_rules! panic { |
| 40 | 40 | #[rustc_diagnostic_item = "assert_eq_macro"] |
| 41 | 41 | #[allow_internal_unstable(panic_internals)] |
| 42 | 42 | macro_rules! assert_eq { |
| 43 | ($left:expr, $right:expr $(,)?) => { | |
| 43 | ($left:expr, $right:expr $(,)?) => {{ | |
| 44 | 44 | match (&$left, &$right) { |
| 45 | 45 | (left_val, right_val) => { |
| 46 | 46 | if !(*left_val == *right_val) { |
| ... | ... | @@ -52,8 +52,8 @@ macro_rules! assert_eq { |
| 52 | 52 | } |
| 53 | 53 | } |
| 54 | 54 | } |
| 55 | }; | |
| 56 | ($left:expr, $right:expr, $($arg:tt)+) => { | |
| 55 | }}; | |
| 56 | ($left:expr, $right:expr, $($arg:tt)+) => {{ | |
| 57 | 57 | match (&$left, &$right) { |
| 58 | 58 | (left_val, right_val) => { |
| 59 | 59 | if !(*left_val == *right_val) { |
| ... | ... | @@ -65,7 +65,7 @@ macro_rules! assert_eq { |
| 65 | 65 | } |
| 66 | 66 | } |
| 67 | 67 | } |
| 68 | }; | |
| 68 | }}; | |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | /// Asserts that two expressions are not equal to each other (using [`PartialEq`]). |
| ... | ... | @@ -96,7 +96,7 @@ macro_rules! assert_eq { |
| 96 | 96 | #[rustc_diagnostic_item = "assert_ne_macro"] |
| 97 | 97 | #[allow_internal_unstable(panic_internals)] |
| 98 | 98 | macro_rules! assert_ne { |
| 99 | ($left:expr, $right:expr $(,)?) => { | |
| 99 | ($left:expr, $right:expr $(,)?) => {{ | |
| 100 | 100 | match (&$left, &$right) { |
| 101 | 101 | (left_val, right_val) => { |
| 102 | 102 | if *left_val == *right_val { |
| ... | ... | @@ -108,8 +108,8 @@ macro_rules! assert_ne { |
| 108 | 108 | } |
| 109 | 109 | } |
| 110 | 110 | } |
| 111 | }; | |
| 112 | ($left:expr, $right:expr, $($arg:tt)+) => { | |
| 111 | }}; | |
| 112 | ($left:expr, $right:expr, $($arg:tt)+) => {{ | |
| 113 | 113 | match (&($left), &($right)) { |
| 114 | 114 | (left_val, right_val) => { |
| 115 | 115 | if *left_val == *right_val { |
| ... | ... | @@ -121,7 +121,7 @@ macro_rules! assert_ne { |
| 121 | 121 | } |
| 122 | 122 | } |
| 123 | 123 | } |
| 124 | }; | |
| 124 | }}; | |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | 127 | /// Asserts that an expression matches the provided pattern. |
library/core/src/net/parser.rs+44-53| ... | ... | @@ -63,11 +63,6 @@ impl<'a> Parser<'a> { |
| 63 | 63 | if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(kind)) |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | /// Peek the next character from the input | |
| 67 | fn peek_char(&self) -> Option<char> { | |
| 68 | self.state.first().map(|&b| char::from(b)) | |
| 69 | } | |
| 70 | ||
| 71 | 66 | /// Reads the next character from the input |
| 72 | 67 | fn read_char(&mut self) -> Option<char> { |
| 73 | 68 | self.state.split_first().map(|(&b, tail)| { |
| ... | ... | @@ -100,60 +95,56 @@ impl<'a> Parser<'a> { |
| 100 | 95 | }) |
| 101 | 96 | } |
| 102 | 97 | |
| 103 | // Read a number off the front of the input in the given radix, stopping | |
| 104 | // at the first non-digit character or eof. Fails if the number has more | |
| 105 | // digits than max_digits or if there is no number. | |
| 106 | // | |
| 107 | // INVARIANT: `max_digits` must be less than the number of digits that `u32` | |
| 108 | // can represent. | |
| 109 | fn read_number<T: ReadNumberHelper + TryFrom<u32>>( | |
| 98 | /// Reads a number off the front of the input in the given radix, stopping at the first | |
| 99 | /// non-digit character or eof. Fails if the number has more digits than `max_digits`, if there | |
| 100 | /// is no number, if the number overflows `T`, or if there are leading zeros but | |
| 101 | /// `allow_zero_prefix` is false. | |
| 102 | /// | |
| 103 | /// `max_digits` must be in 1..=6. | |
| 104 | fn read_radix_max_digits<T: ReadNumberHelper + TryFrom<u32>>( | |
| 110 | 105 | &mut self, |
| 111 | 106 | radix: u32, |
| 112 | max_digits: Option<usize>, | |
| 107 | max_digits: u32, | |
| 113 | 108 | allow_zero_prefix: bool, |
| 114 | 109 | ) -> Option<T> { |
| 115 | self.read_atomically(move |p| { | |
| 116 | let mut digit_count = 0; | |
| 117 | let has_leading_zero = p.peek_char() == Some('0'); | |
| 118 | ||
| 119 | // If max_digits.is_some(), then we are parsing a `u8` or `u16` and | |
| 120 | // don't need to use checked arithmetic since it fits within a `u32`. | |
| 121 | let result = if let Some(max_digits) = max_digits { | |
| 122 | // u32::MAX = 4_294_967_295u32, which is 10 digits long. | |
| 123 | // `max_digits` must be less than 10 to not overflow a `u32`. | |
| 124 | debug_assert!(max_digits < 10); | |
| 125 | ||
| 126 | let mut result = 0_u32; | |
| 127 | while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) { | |
| 128 | result *= radix; | |
| 129 | result += digit; | |
| 130 | digit_count += 1; | |
| 131 | ||
| 132 | if digit_count > max_digits { | |
| 133 | return None; | |
| 134 | } | |
| 135 | } | |
| 136 | ||
| 137 | result.try_into().ok() | |
| 138 | } else { | |
| 139 | let mut result = T::ZERO; | |
| 110 | debug_assert!(1 <= max_digits); | |
| 111 | debug_assert!(max_digits <= 6); // Works for any radix in u32 | |
| 112 | self.read_atomically(|p| { | |
| 113 | let first = p.read_char()?.to_digit(radix)?; | |
| 114 | let mut result = first; | |
| 115 | let mut digit_count = 1; | |
| 140 | 116 | |
| 141 | while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) { | |
| 142 | result = result.checked_mul(radix)?; | |
| 143 | result = result.checked_add(digit)?; | |
| 144 | digit_count += 1; | |
| 117 | while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) { | |
| 118 | if digit_count >= max_digits { | |
| 119 | return None; | |
| 145 | 120 | } |
| 121 | result *= radix; | |
| 122 | result += digit; | |
| 123 | digit_count += 1; | |
| 124 | } | |
| 146 | 125 | |
| 147 | Some(result) | |
| 148 | }; | |
| 149 | ||
| 150 | if digit_count == 0 { | |
| 151 | None | |
| 152 | } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 { | |
| 126 | if !allow_zero_prefix && first == 0 && digit_count > 1 { | |
| 153 | 127 | None |
| 154 | 128 | } else { |
| 155 | result | |
| 129 | result.try_into().ok() | |
| 130 | } | |
| 131 | }) | |
| 132 | } | |
| 133 | ||
| 134 | /// Reads a decimal number off the front of the input, stopping at the first non-digit character | |
| 135 | /// or eof. Fails if there is no number, or if the number overflows `T`. Allows an arbitrary | |
| 136 | /// amount of leading zeros. | |
| 137 | fn read_decimal<T: ReadNumberHelper>(&mut self) -> Option<T> { | |
| 138 | self.read_atomically(|p| { | |
| 139 | let first = p.read_char()?.to_digit(10)?; | |
| 140 | let mut result = T::ZERO.checked_add(first)?; | |
| 141 | ||
| 142 | while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(10)) { | |
| 143 | result = result.checked_mul(10)?; | |
| 144 | result = result.checked_add(digit)?; | |
| 156 | 145 | } |
| 146 | ||
| 147 | Some(result) | |
| 157 | 148 | }) |
| 158 | 149 | } |
| 159 | 150 | |
| ... | ... | @@ -166,7 +157,7 @@ impl<'a> Parser<'a> { |
| 166 | 157 | *slot = p.read_separator('.', i, |p| { |
| 167 | 158 | // Disallow octal number in IP string. |
| 168 | 159 | // https://tools.ietf.org/html/rfc6943#section-3.1.1 |
| 169 | p.read_number(10, Some(3), false) | |
| 160 | p.read_radix_max_digits(10, 3, false) | |
| 170 | 161 | })?; |
| 171 | 162 | } |
| 172 | 163 | |
| ... | ... | @@ -198,7 +189,7 @@ impl<'a> Parser<'a> { |
| 198 | 189 | } |
| 199 | 190 | } |
| 200 | 191 | |
| 201 | let group = p.read_separator(':', i, |p| p.read_number(16, Some(4), true)); | |
| 192 | let group = p.read_separator(':', i, |p| p.read_radix_max_digits(16, 4, true)); | |
| 202 | 193 | |
| 203 | 194 | match group { |
| 204 | 195 | Some(g) => *slot = g, |
| ... | ... | @@ -250,7 +241,7 @@ impl<'a> Parser<'a> { |
| 250 | 241 | fn read_port(&mut self) -> Option<u16> { |
| 251 | 242 | self.read_atomically(|p| { |
| 252 | 243 | p.read_given_char(':')?; |
| 253 | p.read_number(10, None, true) | |
| 244 | p.read_decimal() | |
| 254 | 245 | }) |
| 255 | 246 | } |
| 256 | 247 | |
| ... | ... | @@ -258,7 +249,7 @@ impl<'a> Parser<'a> { |
| 258 | 249 | fn read_scope_id(&mut self) -> Option<u32> { |
| 259 | 250 | self.read_atomically(|p| { |
| 260 | 251 | p.read_given_char('%')?; |
| 261 | p.read_number(10, None, true) | |
| 252 | p.read_decimal() | |
| 262 | 253 | }) |
| 263 | 254 | } |
| 264 | 255 |
library/core/src/num/int_macros.rs+1-1| ... | ... | @@ -1181,7 +1181,7 @@ macro_rules! int_impl { |
| 1181 | 1181 | ( |
| 1182 | 1182 | lhs: $SelfT = self, |
| 1183 | 1183 | rhs: $SelfT = rhs, |
| 1184 | ) => rhs > 0 && lhs % rhs == 0 && (lhs != <$SelfT>::MIN || rhs != -1), | |
| 1184 | ) => rhs != 0 && lhs % rhs == 0 && (lhs != <$SelfT>::MIN || rhs != -1), | |
| 1185 | 1185 | ); |
| 1186 | 1186 | // SAFETY: Same precondition |
| 1187 | 1187 | unsafe { intrinsics::exact_div(self, rhs) } |
library/core/src/slice/mod.rs+2| ... | ... | @@ -2530,6 +2530,7 @@ impl<T> [T] { |
| 2530 | 2530 | F: FnMut(&T) -> bool, |
| 2531 | 2531 | { |
| 2532 | 2532 | let index = self.iter().position(pred)?; |
| 2533 | // Slice bounds checks optimized are away (as of June 2026) | |
| 2533 | 2534 | Some((&self[..index], &self[index + 1..])) |
| 2534 | 2535 | } |
| 2535 | 2536 | |
| ... | ... | @@ -2558,6 +2559,7 @@ impl<T> [T] { |
| 2558 | 2559 | F: FnMut(&T) -> bool, |
| 2559 | 2560 | { |
| 2560 | 2561 | let index = self.iter().rposition(pred)?; |
| 2562 | // Slice bounds checks optimized are away (as of June 2026) | |
| 2561 | 2563 | Some((&self[..index], &self[index + 1..])) |
| 2562 | 2564 | } |
| 2563 | 2565 |
library/coretests/benches/net/addr_parser.rs+155-21| ... | ... | @@ -3,76 +3,210 @@ use core::str::FromStr; |
| 3 | 3 | |
| 4 | 4 | use test::{Bencher, black_box}; |
| 5 | 5 | |
| 6 | const IPV4_STR: &str = "192.168.0.1"; | |
| 7 | const IPV4_STR_PORT: &str = "192.168.0.1:8080"; | |
| 8 | ||
| 9 | const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1"; | |
| 10 | const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1"; | |
| 11 | const IPV6_STR_V4: &str = "2001:db8::192.168.0.1"; | |
| 12 | const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080"; | |
| 13 | const IPV6_STR_PORT_SCOPE_ID: &str = "[2001:db8::c0a8:1%1337]:8080"; | |
| 6 | const IPV4: &[&str] = &[ | |
| 7 | "192.168.0.1", | |
| 8 | "8.8.8.8", | |
| 9 | "127.0.0.1", | |
| 10 | "255.255.255.255", | |
| 11 | "0.0.0.0", | |
| 12 | "10.0.0.1", | |
| 13 | "203.0.113.42", | |
| 14 | "172.16.254.1", | |
| 15 | "100.64.0.1", | |
| 16 | "1.2.3.4", | |
| 17 | ]; | |
| 18 | ||
| 19 | const IPV4_PORT: &[&str] = &[ | |
| 20 | "192.168.0.1:8080", | |
| 21 | "8.8.8.8:53", | |
| 22 | "127.0.0.1:65535", | |
| 23 | "255.255.255.255:1", | |
| 24 | "0.0.0.0:80", | |
| 25 | "10.0.0.1:443", | |
| 26 | "203.0.113.42:22", | |
| 27 | "172.16.254.1:3306", | |
| 28 | "100.64.0.1:8443", | |
| 29 | "1.2.3.4:0", | |
| 30 | ]; | |
| 31 | ||
| 32 | const IPV6_FULL: &[&str] = &[ | |
| 33 | "2001:db8:0:0:0:0:c0a8:1", | |
| 34 | "2001:db8:85a3:8d3:1319:8a2e:370:7348", | |
| 35 | "fe80:0:0:0:0:0:0:1", | |
| 36 | "ff02:0:0:0:0:0:0:101", | |
| 37 | "2001:4860:4860:0:0:0:0:8888", | |
| 38 | "2606:4700:4700:0:0:0:0:1111", | |
| 39 | "fd00:0:0:0:0:0:0:1", | |
| 40 | "fec0:0:0:0:0:0:0:abcd", | |
| 41 | "1:2:3:4:5:6:7:8", | |
| 42 | "abcd:ef01:2345:6789:abcd:ef01:2345:6789", | |
| 43 | ]; | |
| 44 | ||
| 45 | const IPV6_COMPRESS: &[&str] = &[ | |
| 46 | "2001:db8::c0a8:1", | |
| 47 | "::1", | |
| 48 | "fe80::1", | |
| 49 | "2001:db8::", | |
| 50 | "ff02::1:2", | |
| 51 | "64:ff9b::", | |
| 52 | "::", | |
| 53 | "2001:4860:4860::8888", | |
| 54 | "2606:4700:4700::1111", | |
| 55 | "fe80::1ff:fe23:4567:890a", | |
| 56 | ]; | |
| 57 | ||
| 58 | const IPV6_V4: &[&str] = &[ | |
| 59 | "2001:db8::192.168.0.1", | |
| 60 | "::ffff:192.168.0.1", | |
| 61 | "64:ff9b::192.0.2.33", | |
| 62 | "::ffff:8.8.8.8", | |
| 63 | "::192.168.0.1", | |
| 64 | "::ffff:255.255.255.255", | |
| 65 | "2001:db8:0:0:0:0:192.168.0.1", | |
| 66 | "64:ff9b::10.0.0.1", | |
| 67 | "::ffff:1.2.3.4", | |
| 68 | "::ffff:127.0.0.1", | |
| 69 | ]; | |
| 70 | ||
| 71 | const IPV6_PORT: &[&str] = &[ | |
| 72 | "[2001:db8::c0a8:1]:8080", | |
| 73 | "[::1]:443", | |
| 74 | "[fe80::1]:53", | |
| 75 | "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:22", | |
| 76 | "[::]:80", | |
| 77 | "[2001:4860:4860::8888]:443", | |
| 78 | "[2606:4700:4700::1111]:53", | |
| 79 | "[fe80::1ff:fe23:4567:890a]:8080", | |
| 80 | "[64:ff9b::192.0.2.33]:443", | |
| 81 | "[::ffff:8.8.8.8]:53", | |
| 82 | ]; | |
| 83 | ||
| 84 | const IPV6_PORT_SCOPE_ID: &[&str] = &[ | |
| 85 | "[2001:db8::c0a8:1%1337]:8080", | |
| 86 | "[fe80::1%1]:53", | |
| 87 | "[fe80::1%999999]:443", | |
| 88 | "[fe80::1%0]:80", | |
| 89 | "[fe80::1ff:fe23:4567:890a%2]:8080", | |
| 90 | "[::1%1]:443", | |
| 91 | "[fe80::abcd%15]:22", | |
| 92 | "[ff02::1%42]:5353", | |
| 93 | "[fe80::1%4294967295]:443", | |
| 94 | "[2001:db8::1%100]:8080", | |
| 95 | ]; | |
| 14 | 96 | |
| 15 | 97 | #[bench] |
| 16 | 98 | fn bench_parse_ipv4(b: &mut Bencher) { |
| 17 | b.iter(|| Ipv4Addr::from_str(black_box(IPV4_STR))); | |
| 99 | b.iter(|| { | |
| 100 | for s in IPV4 { | |
| 101 | let _ = black_box(Ipv4Addr::from_str(black_box(s))); | |
| 102 | } | |
| 103 | }); | |
| 18 | 104 | } |
| 19 | 105 | |
| 20 | 106 | #[bench] |
| 21 | 107 | fn bench_parse_ipv6_full(b: &mut Bencher) { |
| 22 | b.iter(|| Ipv6Addr::from_str(black_box(IPV6_STR_FULL))); | |
| 108 | b.iter(|| { | |
| 109 | for s in IPV6_FULL { | |
| 110 | let _ = black_box(Ipv6Addr::from_str(black_box(s))); | |
| 111 | } | |
| 112 | }); | |
| 23 | 113 | } |
| 24 | 114 | |
| 25 | 115 | #[bench] |
| 26 | 116 | fn bench_parse_ipv6_compress(b: &mut Bencher) { |
| 27 | b.iter(|| Ipv6Addr::from_str(black_box(IPV6_STR_COMPRESS))); | |
| 117 | b.iter(|| { | |
| 118 | for s in IPV6_COMPRESS { | |
| 119 | let _ = black_box(Ipv6Addr::from_str(black_box(s))); | |
| 120 | } | |
| 121 | }); | |
| 28 | 122 | } |
| 29 | 123 | |
| 30 | 124 | #[bench] |
| 31 | 125 | fn bench_parse_ipv6_v4(b: &mut Bencher) { |
| 32 | b.iter(|| Ipv6Addr::from_str(black_box(IPV6_STR_V4))); | |
| 126 | b.iter(|| { | |
| 127 | for s in IPV6_V4 { | |
| 128 | let _ = black_box(Ipv6Addr::from_str(black_box(s))); | |
| 129 | } | |
| 130 | }); | |
| 33 | 131 | } |
| 34 | 132 | |
| 35 | 133 | #[bench] |
| 36 | 134 | fn bench_parse_ipaddr_v4(b: &mut Bencher) { |
| 37 | b.iter(|| IpAddr::from_str(black_box(IPV4_STR))); | |
| 135 | b.iter(|| { | |
| 136 | for s in IPV4 { | |
| 137 | let _ = black_box(IpAddr::from_str(black_box(s))); | |
| 138 | } | |
| 139 | }); | |
| 38 | 140 | } |
| 39 | 141 | |
| 40 | 142 | #[bench] |
| 41 | 143 | fn bench_parse_ipaddr_v6_full(b: &mut Bencher) { |
| 42 | b.iter(|| IpAddr::from_str(black_box(IPV6_STR_FULL))); | |
| 144 | b.iter(|| { | |
| 145 | for s in IPV6_FULL { | |
| 146 | let _ = black_box(IpAddr::from_str(black_box(s))); | |
| 147 | } | |
| 148 | }); | |
| 43 | 149 | } |
| 44 | 150 | |
| 45 | 151 | #[bench] |
| 46 | 152 | fn bench_parse_ipaddr_v6_compress(b: &mut Bencher) { |
| 47 | b.iter(|| IpAddr::from_str(black_box(IPV6_STR_COMPRESS))); | |
| 153 | b.iter(|| { | |
| 154 | for s in IPV6_COMPRESS { | |
| 155 | let _ = black_box(IpAddr::from_str(black_box(s))); | |
| 156 | } | |
| 157 | }); | |
| 48 | 158 | } |
| 49 | 159 | |
| 50 | 160 | #[bench] |
| 51 | 161 | fn bench_parse_ipaddr_v6_v4(b: &mut Bencher) { |
| 52 | b.iter(|| IpAddr::from_str(black_box(IPV6_STR_V4))); | |
| 162 | b.iter(|| { | |
| 163 | for s in IPV6_V4 { | |
| 164 | let _ = black_box(IpAddr::from_str(black_box(s))); | |
| 165 | } | |
| 166 | }); | |
| 53 | 167 | } |
| 54 | 168 | |
| 55 | 169 | #[bench] |
| 56 | 170 | fn bench_parse_socket_v4(b: &mut Bencher) { |
| 57 | b.iter(|| SocketAddrV4::from_str(black_box(IPV4_STR_PORT))); | |
| 171 | b.iter(|| { | |
| 172 | for s in IPV4_PORT { | |
| 173 | let _ = black_box(SocketAddrV4::from_str(black_box(s))); | |
| 174 | } | |
| 175 | }); | |
| 58 | 176 | } |
| 59 | 177 | |
| 60 | 178 | #[bench] |
| 61 | 179 | fn bench_parse_socket_v6(b: &mut Bencher) { |
| 62 | b.iter(|| SocketAddrV6::from_str(black_box(IPV6_STR_PORT))); | |
| 180 | b.iter(|| { | |
| 181 | for s in IPV6_PORT { | |
| 182 | let _ = black_box(SocketAddrV6::from_str(black_box(s))); | |
| 183 | } | |
| 184 | }); | |
| 63 | 185 | } |
| 64 | 186 | |
| 65 | 187 | #[bench] |
| 66 | 188 | fn bench_parse_socket_v6_scope_id(b: &mut Bencher) { |
| 67 | b.iter(|| SocketAddrV6::from_str(black_box(IPV6_STR_PORT_SCOPE_ID))); | |
| 189 | b.iter(|| { | |
| 190 | for s in IPV6_PORT_SCOPE_ID { | |
| 191 | let _ = black_box(SocketAddrV6::from_str(black_box(s))); | |
| 192 | } | |
| 193 | }); | |
| 68 | 194 | } |
| 69 | 195 | |
| 70 | 196 | #[bench] |
| 71 | 197 | fn bench_parse_socketaddr_v4(b: &mut Bencher) { |
| 72 | b.iter(|| SocketAddr::from_str(black_box(IPV4_STR_PORT))); | |
| 198 | b.iter(|| { | |
| 199 | for s in IPV4_PORT { | |
| 200 | let _ = black_box(SocketAddr::from_str(black_box(s))); | |
| 201 | } | |
| 202 | }); | |
| 73 | 203 | } |
| 74 | 204 | |
| 75 | 205 | #[bench] |
| 76 | 206 | fn bench_parse_socketaddr_v6(b: &mut Bencher) { |
| 77 | b.iter(|| SocketAddr::from_str(black_box(IPV6_STR_PORT))); | |
| 207 | b.iter(|| { | |
| 208 | for s in IPV6_PORT { | |
| 209 | let _ = black_box(SocketAddr::from_str(black_box(s))); | |
| 210 | } | |
| 211 | }); | |
| 78 | 212 | } |
library/coretests/tests/macros.rs+13-1| ... | ... | @@ -241,7 +241,19 @@ fn temporary_scope_introduction() { |
| 241 | 241 | |
| 242 | 242 | (assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); |
| 243 | 243 | (assert_matches!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); |
| 244 | ||
| 245 | 244 | (debug_assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); |
| 246 | 245 | (debug_assert_matches!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); |
| 246 | ||
| 247 | (assert_eq!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); | |
| 248 | (assert_eq!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); | |
| 249 | (debug_assert_eq!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val)); | |
| 250 | (debug_assert_eq!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val)); | |
| 251 | ||
| 252 | (assert_ne!(*MutRefWithDrop(&mut val).0, 1), std::mem::take(&mut val)); | |
| 253 | (assert_ne!(*MutRefWithDrop(&mut val).0, 1, "msg"), std::mem::take(&mut val)); | |
| 254 | (debug_assert_ne!(*MutRefWithDrop(&mut val).0, 1), std::mem::take(&mut val)); | |
| 255 | (debug_assert_ne!(*MutRefWithDrop(&mut val).0, 1, "msg"), std::mem::take(&mut val)); | |
| 256 | ||
| 257 | (assert!(*MutRefWithDrop(&mut val).0 == 0), std::mem::take(&mut val)); | |
| 258 | (assert!(*MutRefWithDrop(&mut val).0 == 0, "msg"), std::mem::take(&mut val)); | |
| 247 | 259 | } |
library/proc_macro/Cargo.toml+1-1| ... | ... | @@ -9,7 +9,7 @@ std = { path = "../std" } |
| 9 | 9 | # `core` when resolving doc links. Without this line a different `core` will be |
| 10 | 10 | # loaded from sysroot causing duplicate lang items and other similar errors. |
| 11 | 11 | core = { path = "../core" } |
| 12 | rustc-literal-escaper = { version = "0.0.7", features = ["rustc-dep-of-std"] } | |
| 12 | rustc-literal-escaper = { version = "0.0.8", features = ["rustc-dep-of-std"] } | |
| 13 | 13 | |
| 14 | 14 | [features] |
| 15 | 15 | default = ["rustc-dep-of-std"] |
library/proc_macro/src/bridge/buffer.rs+2-30| ... | ... | @@ -1,8 +1,7 @@ |
| 1 | 1 | //! Buffer management for same-process client<->server communication. |
| 2 | 2 | |
| 3 | use std::io::{self, Write}; | |
| 4 | 3 | use std::mem::{self, ManuallyDrop}; |
| 5 | use std::ops::{Deref, DerefMut}; | |
| 4 | use std::ops::Deref; | |
| 6 | 5 | use std::slice; |
| 7 | 6 | |
| 8 | 7 | #[repr(C)] |
| ... | ... | @@ -32,13 +31,6 @@ impl Deref for Buffer { |
| 32 | 31 | } |
| 33 | 32 | } |
| 34 | 33 | |
| 35 | impl DerefMut for Buffer { | |
| 36 | #[inline] | |
| 37 | fn deref_mut(&mut self) -> &mut [u8] { | |
| 38 | unsafe { slice::from_raw_parts_mut(self.data, self.len) } | |
| 39 | } | |
| 40 | } | |
| 41 | ||
| 42 | 34 | impl Buffer { |
| 43 | 35 | #[inline] |
| 44 | 36 | pub(super) fn new() -> Self { |
| ... | ... | @@ -99,25 +91,6 @@ impl Buffer { |
| 99 | 91 | } |
| 100 | 92 | } |
| 101 | 93 | |
| 102 | impl Write for Buffer { | |
| 103 | #[inline] | |
| 104 | fn write(&mut self, xs: &[u8]) -> io::Result<usize> { | |
| 105 | self.extend_from_slice(xs); | |
| 106 | Ok(xs.len()) | |
| 107 | } | |
| 108 | ||
| 109 | #[inline] | |
| 110 | fn write_all(&mut self, xs: &[u8]) -> io::Result<()> { | |
| 111 | self.extend_from_slice(xs); | |
| 112 | Ok(()) | |
| 113 | } | |
| 114 | ||
| 115 | #[inline] | |
| 116 | fn flush(&mut self) -> io::Result<()> { | |
| 117 | Ok(()) | |
| 118 | } | |
| 119 | } | |
| 120 | ||
| 121 | 94 | impl Drop for Buffer { |
| 122 | 95 | #[inline] |
| 123 | 96 | fn drop(&mut self) { |
| ... | ... | @@ -128,8 +101,7 @@ impl Drop for Buffer { |
| 128 | 101 | |
| 129 | 102 | impl From<Vec<u8>> for Buffer { |
| 130 | 103 | fn from(v: Vec<u8>) -> Self { |
| 131 | let mut v = ManuallyDrop::new(v); | |
| 132 | let (data, len, capacity) = (v.as_mut_ptr(), v.len(), v.capacity()); | |
| 104 | let (data, len, capacity) = v.into_raw_parts(); | |
| 133 | 105 | |
| 134 | 106 | // This utility function is nested in here because it can *only* |
| 135 | 107 | // be safely called on `Buffer`s created by *this* `proc_macro`. |
library/proc_macro/src/bridge/client.rs+1-1| ... | ... | @@ -282,7 +282,7 @@ impl Client { |
| 282 | 282 | pub const fn expand1(f: impl Fn(crate::TokenStream) -> crate::TokenStream + Copy) -> Self { |
| 283 | 283 | Client { |
| 284 | 284 | run: super::selfless_reify::reify_to_extern_c_fn_hrt_bridge(move |bridge| { |
| 285 | run_client(bridge, |input| f(input)) | |
| 285 | run_client(bridge, f) | |
| 286 | 286 | }), |
| 287 | 287 | } |
| 288 | 288 | } |
library/proc_macro/src/bridge/rpc.rs+1-2| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | 1 | //! Serialization for client-server communication. |
| 2 | 2 | |
| 3 | use std::io::Write; | |
| 4 | 3 | use std::num::NonZero; |
| 5 | 4 | |
| 6 | 5 | use super::buffer::Buffer; |
| ... | ... | @@ -209,7 +208,7 @@ impl<S> Encode<S> for &str { |
| 209 | 208 | fn encode(self, w: &mut Buffer, s: &mut S) { |
| 210 | 209 | let bytes = self.as_bytes(); |
| 211 | 210 | bytes.len().encode(w, s); |
| 212 | w.write_all(bytes).unwrap(); | |
| 211 | w.extend_from_slice(bytes); | |
| 213 | 212 | } |
| 214 | 213 | } |
| 215 | 214 |
library/proc_macro/src/lib.rs+11-13| ... | ... | @@ -37,7 +37,7 @@ |
| 37 | 37 | #![warn(unreachable_pub)] |
| 38 | 38 | #![deny(unsafe_op_in_unsafe_fn)] |
| 39 | 39 | |
| 40 | #[unstable(feature = "proc_macro_internals", issue = "27812")] | |
| 40 | #[unstable(feature = "proc_macro_internals", issue = "none")] | |
| 41 | 41 | #[doc(hidden)] |
| 42 | 42 | pub mod bridge; |
| 43 | 43 | |
| ... | ... | @@ -296,7 +296,7 @@ impl TokenStream { |
| 296 | 296 | /// Checks if this `TokenStream` is empty. |
| 297 | 297 | #[stable(feature = "proc_macro_lib2", since = "1.29.0")] |
| 298 | 298 | pub fn is_empty(&self) -> bool { |
| 299 | self.0.as_ref().map(|h| BridgeMethods::ts_is_empty(h)).unwrap_or(true) | |
| 299 | self.0.as_ref().map(BridgeMethods::ts_is_empty).unwrap_or(true) | |
| 300 | 300 | } |
| 301 | 301 | |
| 302 | 302 | /// Parses this `TokenStream` as an expression and attempts to expand any |
| ... | ... | @@ -575,9 +575,7 @@ pub mod token_stream { |
| 575 | 575 | type IntoIter = IntoIter; |
| 576 | 576 | |
| 577 | 577 | fn into_iter(self) -> IntoIter { |
| 578 | IntoIter( | |
| 579 | self.0.map(|v| BridgeMethods::ts_into_trees(v)).unwrap_or_default().into_iter(), | |
| 580 | ) | |
| 578 | IntoIter(self.0.map(BridgeMethods::ts_into_trees).unwrap_or_default().into_iter()) | |
| 581 | 579 | } |
| 582 | 580 | } |
| 583 | 581 | } |
| ... | ... | @@ -595,7 +593,7 @@ pub macro quote($($t:tt)*) { |
| 595 | 593 | /* compiler built-in */ |
| 596 | 594 | } |
| 597 | 595 | |
| 598 | #[unstable(feature = "proc_macro_internals", issue = "27812")] | |
| 596 | #[unstable(feature = "proc_macro_internals", issue = "none")] | |
| 599 | 597 | #[doc(hidden)] |
| 600 | 598 | mod quote; |
| 601 | 599 | |
| ... | ... | @@ -755,14 +753,14 @@ impl Span { |
| 755 | 753 | |
| 756 | 754 | // Used by the implementation of `Span::quote` |
| 757 | 755 | #[doc(hidden)] |
| 758 | #[unstable(feature = "proc_macro_internals", issue = "27812")] | |
| 756 | #[unstable(feature = "proc_macro_internals", issue = "none")] | |
| 759 | 757 | pub fn save_span(&self) -> usize { |
| 760 | 758 | BridgeMethods::span_save_span(self.0) |
| 761 | 759 | } |
| 762 | 760 | |
| 763 | 761 | // Used by the implementation of `Span::quote` |
| 764 | 762 | #[doc(hidden)] |
| 765 | #[unstable(feature = "proc_macro_internals", issue = "27812")] | |
| 763 | #[unstable(feature = "proc_macro_internals", issue = "none")] | |
| 766 | 764 | pub fn recover_proc_macro_span(id: usize) -> Span { |
| 767 | 765 | Span(BridgeMethods::span_recover_proc_macro_span(id)) |
| 768 | 766 | } |
| ... | ... | @@ -1296,7 +1294,7 @@ macro_rules! unsuffixed_int_literals { |
| 1296 | 1294 | /// specified on this token, meaning that invocations like |
| 1297 | 1295 | /// `Literal::i8_unsuffixed(1)` are equivalent to |
| 1298 | 1296 | /// `Literal::u32_unsuffixed(1)`. |
| 1299 | /// Literals created from negative numbers might not survive rountrips through | |
| 1297 | /// Literals created from negative numbers might not survive roundtrips through | |
| 1300 | 1298 | /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). |
| 1301 | 1299 | /// |
| 1302 | 1300 | /// Literals created through this method have the `Span::call_site()` |
| ... | ... | @@ -1416,7 +1414,7 @@ impl Literal { |
| 1416 | 1414 | /// This constructor is similar to those like `Literal::i8_unsuffixed` where |
| 1417 | 1415 | /// the float's value is emitted directly into the token but no suffix is |
| 1418 | 1416 | /// used, so it may be inferred to be a `f64` later in the compiler. |
| 1419 | /// Literals created from negative numbers might not survive rountrips through | |
| 1417 | /// Literals created from negative numbers might not survive roundtrips through | |
| 1420 | 1418 | /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). |
| 1421 | 1419 | /// |
| 1422 | 1420 | /// # Panics |
| ... | ... | @@ -1441,7 +1439,7 @@ impl Literal { |
| 1441 | 1439 | /// specified is the preceding part of the token and `f32` is the suffix of |
| 1442 | 1440 | /// the token. This token will always be inferred to be an `f32` in the |
| 1443 | 1441 | /// compiler. |
| 1444 | /// Literals created from negative numbers might not survive rountrips through | |
| 1442 | /// Literals created from negative numbers might not survive roundtrips through | |
| 1445 | 1443 | /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). |
| 1446 | 1444 | /// |
| 1447 | 1445 | /// # Panics |
| ... | ... | @@ -1461,7 +1459,7 @@ impl Literal { |
| 1461 | 1459 | /// This constructor is similar to those like `Literal::i8_unsuffixed` where |
| 1462 | 1460 | /// the float's value is emitted directly into the token but no suffix is |
| 1463 | 1461 | /// used, so it may be inferred to be a `f64` later in the compiler. |
| 1464 | /// Literals created from negative numbers might not survive rountrips through | |
| 1462 | /// Literals created from negative numbers might not survive roundtrips through | |
| 1465 | 1463 | /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). |
| 1466 | 1464 | /// |
| 1467 | 1465 | /// # Panics |
| ... | ... | @@ -1486,7 +1484,7 @@ impl Literal { |
| 1486 | 1484 | /// specified is the preceding part of the token and `f64` is the suffix of |
| 1487 | 1485 | /// the token. This token will always be inferred to be an `f64` in the |
| 1488 | 1486 | /// compiler. |
| 1489 | /// Literals created from negative numbers might not survive rountrips through | |
| 1487 | /// Literals created from negative numbers might not survive roundtrips through | |
| 1490 | 1488 | /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal). |
| 1491 | 1489 | /// |
| 1492 | 1490 | /// # Panics |
library/std/src/lib.rs+1| ... | ... | @@ -355,6 +355,7 @@ |
| 355 | 355 | #![feature(int_from_ascii)] |
| 356 | 356 | #![feature(io_error_inprogress)] |
| 357 | 357 | #![feature(io_error_more)] |
| 358 | #![feature(io_error_too_many_open_files)] | |
| 358 | 359 | #![feature(io_error_uncategorized)] |
| 359 | 360 | #![feature(io_slice_as_bytes)] |
| 360 | 361 | #![feature(ip)] |
library/std/src/os/mod.rs+66-117| ... | ... | @@ -6,121 +6,83 @@ |
| 6 | 6 | |
| 7 | 7 | pub mod raw; |
| 8 | 8 | |
| 9 | // The code below could be written clearer using `cfg_if!`. However, the items below are | |
| 10 | // publicly exported by `std` and external tools can have trouble analysing them because of the use | |
| 11 | // of a macro that is not vendored by Rust and included in the toolchain. | |
| 12 | // See https://github.com/rust-analyzer/rust-analyzer/issues/6038. | |
| 9 | // # Important platforms | |
| 13 | 10 | |
| 14 | // On certain platforms right now the "main modules" modules that are | |
| 15 | // documented don't compile (missing things in `libc` which is empty), | |
| 16 | // so just omit them with an empty module and add the "unstable" attribute. | |
| 17 | ||
| 18 | // darwin, unix, linux, wasi and windows are handled a bit differently. | |
| 19 | #[cfg(all( | |
| 20 | doc, | |
| 21 | any( | |
| 22 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 23 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 24 | ) | |
| 25 | ))] | |
| 26 | #[unstable(issue = "none", feature = "std_internals")] | |
| 27 | pub mod darwin {} | |
| 28 | #[cfg(all( | |
| 29 | doc, | |
| 30 | any( | |
| 31 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 32 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 33 | ) | |
| 34 | ))] | |
| 35 | #[unstable(issue = "none", feature = "std_internals")] | |
| 36 | pub mod unix {} | |
| 37 | #[cfg(all( | |
| 38 | doc, | |
| 39 | any( | |
| 40 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 41 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 42 | ) | |
| 43 | ))] | |
| 44 | #[unstable(issue = "none", feature = "std_internals")] | |
| 45 | pub mod linux {} | |
| 46 | #[cfg(all( | |
| 47 | doc, | |
| 48 | any( | |
| 49 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 50 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 51 | ) | |
| 52 | ))] | |
| 53 | #[unstable(issue = "none", feature = "std_internals")] | |
| 54 | pub mod wasi {} | |
| 55 | #[cfg(all( | |
| 56 | doc, | |
| 11 | // We always want to show documentation for the most important platforms, | |
| 12 | // so these are handled specially here. | |
| 13 | // | |
| 14 | // FIXME: On certain platforms compilation errors (due to empty `libc`), | |
| 15 | // prevent this, so we substitute an unstable empty module. | |
| 16 | #[cfg(doc)] | |
| 17 | cfg_select! { | |
| 57 | 18 | any( |
| 58 | 19 | all(target_arch = "wasm32", not(target_os = "wasi")), |
| 59 | 20 | all(target_vendor = "fortanix", target_env = "sgx") |
| 60 | ) | |
| 61 | ))] | |
| 62 | #[unstable(issue = "none", feature = "std_internals")] | |
| 63 | pub mod windows {} | |
| 21 | ) => { | |
| 22 | #[unstable(issue = "none", feature = "std_internals")] | |
| 23 | pub mod darwin {} | |
| 64 | 24 | |
| 65 | // darwin | |
| 66 | #[cfg(not(all( | |
| 67 | doc, | |
| 68 | any( | |
| 69 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 70 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 71 | ) | |
| 72 | )))] | |
| 73 | #[cfg(any(target_vendor = "apple", doc))] | |
| 74 | pub mod darwin; | |
| 25 | #[unstable(issue = "none", feature = "std_internals")] | |
| 26 | pub mod unix {} | |
| 75 | 27 | |
| 76 | // unix | |
| 77 | #[cfg(not(all( | |
| 78 | doc, | |
| 79 | any( | |
| 80 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 81 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 82 | ) | |
| 83 | )))] | |
| 84 | #[cfg(all(not(target_os = "hermit"), any(unix, doc)))] | |
| 85 | pub mod unix; | |
| 28 | #[unstable(issue = "none", feature = "std_internals")] | |
| 29 | pub mod linux {} | |
| 86 | 30 | |
| 87 | // linux | |
| 88 | #[cfg(not(all( | |
| 89 | doc, | |
| 90 | any( | |
| 91 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 92 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 93 | ) | |
| 94 | )))] | |
| 95 | #[cfg(any(target_os = "linux", doc))] | |
| 96 | pub mod linux; | |
| 31 | #[unstable(issue = "none", feature = "std_internals")] | |
| 32 | pub mod wasi {} | |
| 97 | 33 | |
| 98 | // wasi | |
| 99 | #[cfg(not(all( | |
| 100 | doc, | |
| 101 | any( | |
| 102 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 103 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 104 | ) | |
| 105 | )))] | |
| 106 | #[cfg(any(target_os = "wasi", any(target_env = "p1", target_env = "p2"), doc))] | |
| 107 | pub mod wasi; | |
| 34 | #[unstable(issue = "none", feature = "std_internals")] | |
| 35 | pub mod windows {} | |
| 36 | } | |
| 37 | _ => { | |
| 38 | // important platforms | |
| 39 | pub mod darwin; | |
| 40 | pub mod linux; | |
| 41 | pub mod unix; | |
| 42 | pub mod wasi; | |
| 43 | pub mod wasip2; | |
| 44 | pub mod windows; | |
| 45 | } | |
| 46 | } | |
| 47 | #[cfg(not(doc))] // to prevent double module declarations | |
| 48 | cfg_select! { | |
| 49 | target_family = "unix" => { | |
| 50 | pub mod unix; | |
| 51 | #[cfg(target_vendor = "apple")] | |
| 52 | pub mod darwin; | |
| 53 | #[cfg(target_os = "linux")] | |
| 54 | pub mod linux; | |
| 55 | } | |
| 56 | target_family = "wasm" => { | |
| 57 | #[cfg(any(target_env = "p1", target_env = "p2"))] | |
| 58 | pub mod wasi; | |
| 59 | #[cfg(target_env = "p2")] | |
| 60 | pub mod wasip2; | |
| 61 | } | |
| 62 | target_family = "windows" => { | |
| 63 | pub mod windows; | |
| 64 | } | |
| 65 | _ => { /* handled below */ } | |
| 66 | } | |
| 108 | 67 | |
| 109 | #[cfg(any(all(target_os = "wasi", target_env = "p2"), doc))] | |
| 110 | pub mod wasip2; | |
| 68 | // # Special modules | |
| 111 | 69 | |
| 112 | // windows | |
| 113 | #[cfg(not(all( | |
| 114 | doc, | |
| 115 | any( | |
| 116 | all(target_arch = "wasm32", not(target_os = "wasi")), | |
| 117 | all(target_vendor = "fortanix", target_env = "sgx") | |
| 118 | ) | |
| 119 | )))] | |
| 120 | #[cfg(any(windows, doc))] | |
| 121 | pub mod windows; | |
| 70 | #[cfg(any( | |
| 71 | unix, | |
| 72 | target_os = "hermit", | |
| 73 | target_os = "trusty", | |
| 74 | target_os = "wasi", | |
| 75 | target_os = "motor", | |
| 76 | doc | |
| 77 | ))] | |
| 78 | pub mod fd; | |
| 79 | ||
| 80 | #[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))] | |
| 81 | mod net; | |
| 82 | ||
| 83 | // # Ordinary platforms | |
| 84 | // `cfg(doc)` not handled specially | |
| 122 | 85 | |
| 123 | // Others. | |
| 124 | 86 | #[cfg(target_os = "aix")] |
| 125 | 87 | pub mod aix; |
| 126 | 88 | #[cfg(target_os = "android")] |
| ... | ... | @@ -183,16 +145,3 @@ pub mod vita; |
| 183 | 145 | pub mod vxworks; |
| 184 | 146 | #[cfg(target_os = "xous")] |
| 185 | 147 | pub mod xous; |
| 186 | ||
| 187 | #[cfg(any( | |
| 188 | unix, | |
| 189 | target_os = "hermit", | |
| 190 | target_os = "trusty", | |
| 191 | target_os = "wasi", | |
| 192 | target_os = "motor", | |
| 193 | doc | |
| 194 | ))] | |
| 195 | pub mod fd; | |
| 196 | ||
| 197 | #[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))] | |
| 198 | mod net; |
library/std/src/sync/poison.rs-3| ... | ... | @@ -57,9 +57,6 @@ |
| 57 | 57 | //! |
| 58 | 58 | //! [`Once`]: crate::sync::Once |
| 59 | 59 | |
| 60 | // If we are not unwinding, `PoisonError` is uninhabited. | |
| 61 | #![cfg_attr(not(panic = "unwind"), expect(unreachable_code))] | |
| 62 | ||
| 63 | 60 | #[stable(feature = "rust1", since = "1.0.0")] |
| 64 | 61 | pub use self::condvar::Condvar; |
| 65 | 62 | #[unstable(feature = "mapped_lock_guards", issue = "117108")] |
library/std/src/sys/fs/vexos.rs+1-1| ... | ... | @@ -612,7 +612,7 @@ fn map_fresult(fresult: vex_sdk::FRESULT) -> io::Result<()> { |
| 612 | 612 | Err(io::const_error!(io::ErrorKind::OutOfMemory, "not enough memory for the operation")) |
| 613 | 613 | } |
| 614 | 614 | vex_sdk::FRESULT::FR_TOO_MANY_OPEN_FILES => Err(io::const_error!( |
| 615 | io::ErrorKind::Uncategorized, | |
| 615 | io::ErrorKind::TooManyOpenFiles, | |
| 616 | 616 | "maximum number of open files has been reached", |
| 617 | 617 | )), |
| 618 | 618 | vex_sdk::FRESULT::FR_INVALID_PARAMETER => { |
library/std/src/sys/io/error/unix.rs+1| ... | ... | @@ -137,6 +137,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { |
| 137 | 137 | libc::ETXTBSY => ExecutableFileBusy, |
| 138 | 138 | libc::EXDEV => CrossesDevices, |
| 139 | 139 | libc::EINPROGRESS => InProgress, |
| 140 | libc::EMFILE | libc::ENFILE => TooManyOpenFiles, | |
| 140 | 141 | libc::EOPNOTSUPP => Unsupported, |
| 141 | 142 | |
| 142 | 143 | libc::EACCES | libc::EPERM => PermissionDenied, |
library/std/src/sys/io/error/wasi.rs+1| ... | ... | @@ -59,6 +59,7 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { |
| 59 | 59 | libc::ETXTBSY => ExecutableFileBusy, |
| 60 | 60 | libc::EXDEV => CrossesDevices, |
| 61 | 61 | libc::EINPROGRESS => InProgress, |
| 62 | libc::EMFILE | libc::ENFILE => TooManyOpenFiles, | |
| 62 | 63 | libc::EOPNOTSUPP => Unsupported, |
| 63 | 64 | libc::EACCES | libc::EPERM => PermissionDenied, |
| 64 | 65 | libc::EWOULDBLOCK => WouldBlock, |
library/std/src/sys/io/error/windows.rs+2| ... | ... | @@ -61,6 +61,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { |
| 61 | 61 | c::ERROR_POSSIBLE_DEADLOCK => return Deadlock, |
| 62 | 62 | c::ERROR_NOT_SAME_DEVICE => return CrossesDevices, |
| 63 | 63 | c::ERROR_TOO_MANY_LINKS => return TooManyLinks, |
| 64 | c::ERROR_TOO_MANY_OPEN_FILES => return TooManyOpenFiles, | |
| 64 | 65 | c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename, |
| 65 | 66 | c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop, |
| 66 | 67 | _ => {} |
| ... | ... | @@ -81,6 +82,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { |
| 81 | 82 | c::WSAENETDOWN => NetworkDown, |
| 82 | 83 | c::WSAENETUNREACH => NetworkUnreachable, |
| 83 | 84 | c::WSAEDQUOT => QuotaExceeded, |
| 85 | c::WSAEMFILE => TooManyOpenFiles, | |
| 84 | 86 | // Not a perfect mapping but this error is only returned when writing to |
| 85 | 87 | // a socket after shutting down the write-end. On Unix targets, EPIPE is |
| 86 | 88 | // returned in those cases. |
src/bootstrap/src/core/build_steps/dist.rs-5| ... | ... | @@ -1201,11 +1201,6 @@ impl Step for Src { |
| 1201 | 1201 | // not needed and contains symlinks which rustup currently |
| 1202 | 1202 | // chokes on when unpacking. |
| 1203 | 1203 | "library/backtrace/crates", |
| 1204 | // these are 30MB combined and aren't necessary for building | |
| 1205 | // the standard library. | |
| 1206 | "library/stdarch/Cargo.toml", | |
| 1207 | "library/stdarch/crates/stdarch-verify", | |
| 1208 | "library/stdarch/crates/intrinsic-test", | |
| 1209 | 1204 | ], |
| 1210 | 1205 | &dst_src, |
| 1211 | 1206 | ); |
src/ci/scripts/install-mingw.sh+2-2| ... | ... | @@ -6,8 +6,8 @@ IFS=$'\n\t' |
| 6 | 6 | |
| 7 | 7 | source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" |
| 8 | 8 | |
| 9 | MINGW_ARCHIVE_32="i686-14.1.0-release-posix-dwarf-msvcrt-rt_v12-rev0.7z" | |
| 10 | MINGW_ARCHIVE_64="x86_64-14.1.0-release-posix-seh-msvcrt-rt_v12-rev0.7z" | |
| 9 | MINGW_ARCHIVE_32="i686-14.2.0-release-posix-dwarf-msvcrt-rt_v12-rev2.7z" | |
| 10 | MINGW_ARCHIVE_64="x86_64-14.2.0-release-posix-seh-msvcrt-rt_v12-rev2.7z" | |
| 11 | 11 | LLVM_MINGW_ARCHIVE_AARCH64="llvm-mingw-20251104-ucrt-aarch64.zip" |
| 12 | 12 | LLVM_MINGW_ARCHIVE_X86_64="llvm-mingw-20251104-ucrt-x86_64.zip" |
| 13 | 13 |
src/doc/rustc/src/platform-support/windows-gnu.md+12| ... | ... | @@ -26,6 +26,18 @@ They follow Windows calling convention for `extern "C"`. |
| 26 | 26 | |
| 27 | 27 | Like with any other Windows target, created binaries are in PE format. |
| 28 | 28 | |
| 29 | ### C toolchain | |
| 30 | ||
| 31 | The targets are built and tested using a reasonably modern C toolchain, and it should be considered as the oldest supported version: | |
| 32 | ||
| 33 | * GNU Binutils 2.44 | |
| 34 | * GCC 14.2 | |
| 35 | * mingw-w64 12.0.0 | |
| 36 | * MSVCRT library as the default | |
| 37 | ||
| 38 | Using older tools (especially Binutils) may not work properly, due to the number of issues plaguing older versions of Binutils. | |
| 39 | The supported toolchain versions are subject to change. | |
| 40 | ||
| 29 | 41 | ## Building Rust programs |
| 30 | 42 | |
| 31 | 43 | Rust does ship a pre-compiled std library for those targets. |
src/tools/clippy/clippy_dev/Cargo.toml+1-1| ... | ... | @@ -10,7 +10,7 @@ clap = { version = "4.4", features = ["derive"] } |
| 10 | 10 | indoc = "1.0" |
| 11 | 11 | itertools = "0.12" |
| 12 | 12 | opener = "0.8" |
| 13 | rustc-literal-escaper = "0.0.7" | |
| 13 | rustc-literal-escaper = "0.0.8" | |
| 14 | 14 | walkdir = "2.3" |
| 15 | 15 | |
| 16 | 16 | [package.metadata.rust-analyzer] |
src/tools/lint-docs/Cargo.toml+1-1| ... | ... | @@ -7,7 +7,7 @@ description = "A script to extract the lint documentation for the rustc book." |
| 7 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
| 8 | 8 | |
| 9 | 9 | [dependencies] |
| 10 | rustc-literal-escaper = "0.0.7" | |
| 10 | rustc-literal-escaper = "0.0.8" | |
| 11 | 11 | serde_json = "1.0.57" |
| 12 | 12 | tempfile = "3.1.0" |
| 13 | 13 | walkdir = "2.3.1" |
src/tools/miri/tests/pass/c-variadic.rs+15| ... | ... | @@ -106,6 +106,20 @@ fn various_types() { |
| 106 | 106 | } |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | fn equal_up_to_free_lifetime() { | |
| 110 | // Types are considered equal up to free lifetimes: `*const &'static str` | |
| 111 | // is the same as `*const &'a str`. | |
| 112 | // Bound lifetimes (using e.g. `for<'_>`) are different. | |
| 113 | #[expect(improper_ctypes_definitions)] | |
| 114 | pub unsafe extern "C" fn foo(mut args: ...) -> &'static str { | |
| 115 | unsafe { *args.next_arg::<*const &'static str>() } | |
| 116 | } | |
| 117 | ||
| 118 | let data = String::from("abc"); | |
| 119 | let x: &str = data.as_str(); | |
| 120 | assert_eq!(unsafe { foo(&raw const x) }, "abc"); | |
| 121 | } | |
| 122 | ||
| 109 | 123 | fn clone() { |
| 110 | 124 | if cfg!(force_intrinsic_fallback) { |
| 111 | 125 | // Skip this test when we use the fallback bodies. The fallback body does |
| ... | ... | @@ -170,6 +184,7 @@ fn main() { |
| 170 | 184 | forward_by_ref(); |
| 171 | 185 | nested(); |
| 172 | 186 | various_types(); |
| 187 | equal_up_to_free_lifetime(); | |
| 173 | 188 | clone(); |
| 174 | 189 | clone_and_advance(); |
| 175 | 190 | } |
src/tools/rust-analyzer/.github/FUNDING.yml created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | github: rustfoundation | |
| 2 | custom: ["rust-lang.org/funding"] |
src/tools/rust-analyzer/.github/actions/github-release/Dockerfile+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | FROM node:slim | |
| 1 | FROM node:24.16-slim@sha256:ca520832af80fa37a57c14077ed0fcdd83b5aefccc356059fdc3a9a05b78ae1f | |
| 2 | 2 | |
| 3 | 3 | COPY . /action |
| 4 | 4 | WORKDIR /action |
src/tools/rust-analyzer/.gitignore+1| ... | ... | @@ -7,6 +7,7 @@ vendor/ |
| 7 | 7 | *.log |
| 8 | 8 | *.iml |
| 9 | 9 | .vscode/settings.json |
| 10 | .vim/coc-settings.json | |
| 10 | 11 | .DS_Store |
| 11 | 12 | /out/ |
| 12 | 13 | /dump.lsif |
src/tools/rust-analyzer/Cargo.lock-10| ... | ... | @@ -1002,15 +1002,6 @@ dependencies = [ |
| 1002 | 1002 | "typed-arena", |
| 1003 | 1003 | ] |
| 1004 | 1004 | |
| 1005 | [[package]] | |
| 1006 | name = "home" | |
| 1007 | version = "0.5.12" | |
| 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1009 | checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" | |
| 1010 | dependencies = [ | |
| 1011 | "windows-sys 0.61.2", | |
| 1012 | ] | |
| 1013 | ||
| 1014 | 1005 | [[package]] |
| 1015 | 1006 | name = "icu_collections" |
| 1016 | 1007 | version = "2.2.0" |
| ... | ... | @@ -3116,7 +3107,6 @@ name = "toolchain" |
| 3116 | 3107 | version = "0.0.0" |
| 3117 | 3108 | dependencies = [ |
| 3118 | 3109 | "camino", |
| 3119 | "home", | |
| 3120 | 3110 | ] |
| 3121 | 3111 | |
| 3122 | 3112 | [[package]] |
src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs+5-4| ... | ... | @@ -671,6 +671,7 @@ impl<'db> ExprCollector<'db> { |
| 671 | 671 | } |
| 672 | 672 | |
| 673 | 673 | pl.params() |
| 674 | .filter(|it| it.dotdotdot_token().is_none()) | |
| 674 | 675 | .map(|it| { |
| 675 | 676 | let type_ref = self.lower_type_ref_opt(it.ty(), impl_trait_lower_fn); |
| 676 | 677 | let name = match it.pat() { |
| ... | ... | @@ -2403,6 +2404,10 @@ impl<'db> ExprCollector<'db> { |
| 2403 | 2404 | statements: &mut Vec<Statement>, |
| 2404 | 2405 | mac: ast::MacroExpr, |
| 2405 | 2406 | ) -> Option<ExprId> { |
| 2407 | if !self.check_cfg(&ast::Expr::MacroExpr(mac.clone())) { | |
| 2408 | return None; | |
| 2409 | } | |
| 2410 | ||
| 2406 | 2411 | let mac_call = mac.macro_call()?; |
| 2407 | 2412 | let syntax_ptr = AstPtr::new(&ast::Expr::from(mac)); |
| 2408 | 2413 | let macro_ptr = AstPtr::new(&mac_call); |
| ... | ... | @@ -2446,10 +2451,6 @@ impl<'db> ExprCollector<'db> { |
| 2446 | 2451 | } |
| 2447 | 2452 | ast::Stmt::ExprStmt(stmt) => { |
| 2448 | 2453 | let expr = stmt.expr(); |
| 2449 | match &expr { | |
| 2450 | Some(expr) if !self.check_cfg(expr) => return, | |
| 2451 | _ => (), | |
| 2452 | } | |
| 2453 | 2454 | let has_semi = stmt.semicolon_token().is_some(); |
| 2454 | 2455 | // Note that macro could be expanded to multiple statements |
| 2455 | 2456 | if let Some(ast::Expr::MacroExpr(mac)) = expr { |
src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs+28| ... | ... | @@ -688,3 +688,31 @@ fn foo() { |
| 688 | 688 | }"#]], |
| 689 | 689 | ); |
| 690 | 690 | } |
| 691 | ||
| 692 | #[test] | |
| 693 | fn foo() { | |
| 694 | pretty_print( | |
| 695 | r#" | |
| 696 | macro_rules! foo { | |
| 697 | () => { | |
| 698 | 1 | |
| 699 | }; | |
| 700 | } | |
| 701 | ||
| 702 | fn foo() -> i64 { | |
| 703 | #[cfg(true)] | |
| 704 | { | |
| 705 | 5 | |
| 706 | } | |
| 707 | #[cfg(false)] | |
| 708 | foo!() | |
| 709 | } | |
| 710 | "#, | |
| 711 | expect![[r#" | |
| 712 | fn foo() { | |
| 713 | { | |
| 714 | 5 | |
| 715 | } | |
| 716 | }"#]], | |
| 717 | ); | |
| 718 | } |
src/tools/rust-analyzer/crates/hir-expand/src/db.rs-5| ... | ... | @@ -141,11 +141,6 @@ pub trait ExpandDatabase: SourceDatabase { |
| 141 | 141 | fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContext; |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | #[salsa_macros::interned(no_lifetime, id = span::SyntaxContext, revisions = usize::MAX)] | |
| 145 | pub struct SyntaxContextWrapper { | |
| 146 | pub data: SyntaxContext, | |
| 147 | } | |
| 148 | ||
| 149 | 144 | fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId, edition: Edition) -> SyntaxContext { |
| 150 | 145 | match file { |
| 151 | 146 | HirFileId::FileId(_) => SyntaxContext::root(edition), |
src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs+12-4| ... | ... | @@ -87,18 +87,24 @@ fn intern_const_ref<'db>( |
| 87 | 87 | let valtree = match (ty.kind(), value) { |
| 88 | 88 | (TyKind::Uint(uint), Literal::Uint(value, _)) => { |
| 89 | 89 | let size = uint.bit_width().map(Size::from_bits).unwrap_or(data_layout.pointer_size()); |
| 90 | let scalar = ScalarInt::try_from_uint(*value, size).unwrap(); | |
| 90 | let Some(scalar) = ScalarInt::try_from_uint(*value, size) else { | |
| 91 | return Ok(Const::error(interner)); | |
| 92 | }; | |
| 91 | 93 | ValTreeKind::Leaf(scalar) |
| 92 | 94 | } |
| 93 | 95 | (TyKind::Uint(uint), Literal::Int(value, _)) => { |
| 94 | 96 | // `Literal::Int` is the default, so we also need to account for the type being uint. |
| 95 | 97 | let size = uint.bit_width().map(Size::from_bits).unwrap_or(data_layout.pointer_size()); |
| 96 | let scalar = ScalarInt::try_from_uint(*value as u128, size).unwrap(); | |
| 98 | let Some(scalar) = ScalarInt::try_from_uint(*value as u128, size) else { | |
| 99 | return Ok(Const::error(interner)); | |
| 100 | }; | |
| 97 | 101 | ValTreeKind::Leaf(scalar) |
| 98 | 102 | } |
| 99 | 103 | (TyKind::Int(int), Literal::Int(value, _)) => { |
| 100 | 104 | let size = int.bit_width().map(Size::from_bits).unwrap_or(data_layout.pointer_size()); |
| 101 | let scalar = ScalarInt::try_from_int(*value, size).unwrap(); | |
| 105 | let Some(scalar) = ScalarInt::try_from_int(*value, size) else { | |
| 106 | return Ok(Const::error(interner)); | |
| 107 | }; | |
| 102 | 108 | ValTreeKind::Leaf(scalar) |
| 103 | 109 | } |
| 104 | 110 | (TyKind::Bool, Literal::Bool(value)) => ValTreeKind::Leaf(ScalarInt::from(*value)), |
| ... | ... | @@ -219,7 +225,9 @@ pub fn usize_const<'db>(db: &'db dyn HirDatabase, value: Option<u128>, krate: Cr |
| 219 | 225 | return Const::error(interner); |
| 220 | 226 | }; |
| 221 | 227 | let usize_ty = interner.default_types().types.usize; |
| 222 | let scalar = ScalarInt::try_from_uint(value, data_layout.pointer_size()).unwrap(); | |
| 228 | let Some(scalar) = ScalarInt::try_from_uint(value, data_layout.pointer_size()) else { | |
| 229 | return Const::error(interner); | |
| 230 | }; | |
| 223 | 231 | Const::new_valtree(interner, usize_ty, ValTreeKind::Leaf(scalar)) |
| 224 | 232 | } |
| 225 | 233 |
src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs+13| ... | ... | @@ -2633,6 +2633,19 @@ fn const_generic_subst_fn() { |
| 2633 | 2633 | ); |
| 2634 | 2634 | } |
| 2635 | 2635 | |
| 2636 | #[test] | |
| 2637 | fn const_generic_fixed_width() { | |
| 2638 | check_number( | |
| 2639 | r#" | |
| 2640 | const fn m<const N: u64>() -> u64 { | |
| 2641 | N | |
| 2642 | } | |
| 2643 | const GOAL: u64 = m::<0>(); | |
| 2644 | "#, | |
| 2645 | 0, | |
| 2646 | ); | |
| 2647 | } | |
| 2648 | ||
| 2636 | 2649 | #[test] |
| 2637 | 2650 | fn layout_of_type_with_associated_type_field_defined_inside_body() { |
| 2638 | 2651 | check_number( |
src/tools/rust-analyzer/crates/hir-ty/src/db.rs+2-15| ... | ... | @@ -6,8 +6,8 @@ use base_db::{Crate, target::TargetLoadError}; |
| 6 | 6 | use either::Either; |
| 7 | 7 | use hir_def::{ |
| 8 | 8 | AdtId, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, EnumVariantId, |
| 9 | ExpressionStoreOwnerId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, | |
| 10 | LocalFieldId, ModuleId, StaticId, TraitId, TypeAliasId, VariantId, | |
| 9 | ExpressionStoreOwnerId, FunctionId, GenericDefId, HasModule, ImplId, LocalFieldId, ModuleId, | |
| 10 | StaticId, TraitId, TypeAliasId, VariantId, | |
| 11 | 11 | builtin_derive::BuiltinDeriveImplMethod, |
| 12 | 12 | db::DefDatabase, |
| 13 | 13 | expr_store::ExpressionStore, |
| ... | ... | @@ -294,19 +294,6 @@ fn hir_database_is_dyn_compatible() { |
| 294 | 294 | fn _assert_dyn_compatible(_: &dyn HirDatabase) {} |
| 295 | 295 | } |
| 296 | 296 | |
| 297 | #[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] | |
| 298 | #[derive(PartialOrd, Ord)] | |
| 299 | pub struct InternedLifetimeParamId { | |
| 300 | /// This stores the param and its index. | |
| 301 | pub loc: (LifetimeParamId, u32), | |
| 302 | } | |
| 303 | ||
| 304 | #[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] | |
| 305 | #[derive(PartialOrd, Ord)] | |
| 306 | pub struct InternedConstParamId { | |
| 307 | pub loc: ConstParamId, | |
| 308 | } | |
| 309 | ||
| 310 | 297 | #[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] |
| 311 | 298 | #[derive(PartialOrd, Ord)] |
| 312 | 299 | pub struct InternedOpaqueTyId { |
src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs+2-1| ... | ... | @@ -1016,8 +1016,9 @@ impl<'a, 'b, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'b, 'db, D> { |
| 1016 | 1016 | } |
| 1017 | 1017 | } |
| 1018 | 1018 | Pat::Expr(expr) => { |
| 1019 | // Destructuring assignment. | |
| 1020 | 1019 | this.mutate_expr(expr)?; |
| 1020 | // Destructuring assignment moves | |
| 1021 | this.consume_or_copy(place); | |
| 1021 | 1022 | } |
| 1022 | 1023 | Pat::Or(_) |
| 1023 | 1024 | | Pat::Box { .. } |
src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs+31-21| ... | ... | @@ -1935,25 +1935,37 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { |
| 1935 | 1935 | Ok(Interval::new(addr, 4)) |
| 1936 | 1936 | } |
| 1937 | 1937 | TyKind::Int(int_ty) => { |
| 1938 | let size = int_ty.bit_width().unwrap_or(self.ptr_size() as u64); | |
| 1939 | let value = valtree.inner().to_leaf().to_int(Size::from_bytes(size)); | |
| 1940 | let addr = self.heap_allocate(size as usize, size as usize)?; | |
| 1941 | self.write_memory(addr, &value.to_le_bytes()[..size as usize])?; | |
| 1942 | Ok(Interval::new(addr, size as usize)) | |
| 1938 | let size = int_ty | |
| 1939 | .bit_width() | |
| 1940 | .map(Size::from_bits) | |
| 1941 | .unwrap_or_else(|| Size::from_bytes(self.ptr_size() as u64)); | |
| 1942 | let bytes = size.bytes_usize(); | |
| 1943 | ||
| 1944 | let value = valtree.inner().to_leaf().to_int(size); | |
| 1945 | let addr = self.heap_allocate(bytes, bytes)?; | |
| 1946 | self.write_memory(addr, &value.to_le_bytes()[..bytes])?; | |
| 1947 | Ok(Interval::new(addr, bytes)) | |
| 1943 | 1948 | } |
| 1944 | 1949 | TyKind::Uint(uint_ty) => { |
| 1945 | let size = uint_ty.bit_width().unwrap_or(self.ptr_size() as u64); | |
| 1946 | let value = valtree.inner().to_leaf().to_uint(Size::from_bytes(size)); | |
| 1947 | let addr = self.heap_allocate(size as usize, size as usize)?; | |
| 1948 | self.write_memory(addr, &value.to_le_bytes()[..size as usize])?; | |
| 1949 | Ok(Interval::new(addr, size as usize)) | |
| 1950 | let size = uint_ty | |
| 1951 | .bit_width() | |
| 1952 | .map(Size::from_bits) | |
| 1953 | .unwrap_or_else(|| Size::from_bytes(self.ptr_size() as u64)); | |
| 1954 | let bytes = size.bytes_usize(); | |
| 1955 | ||
| 1956 | let value = valtree.inner().to_leaf().to_uint(size); | |
| 1957 | let addr = self.heap_allocate(bytes, bytes)?; | |
| 1958 | self.write_memory(addr, &value.to_le_bytes()[..bytes])?; | |
| 1959 | Ok(Interval::new(addr, bytes)) | |
| 1950 | 1960 | } |
| 1951 | 1961 | TyKind::Float(float_ty) => { |
| 1952 | let size = float_ty.bit_width(); | |
| 1953 | let value = valtree.inner().to_leaf().to_uint(Size::from_bytes(size)); | |
| 1954 | let addr = self.heap_allocate(size as usize, size as usize)?; | |
| 1955 | self.write_memory(addr, &value.to_le_bytes()[..size as usize])?; | |
| 1956 | Ok(Interval::new(addr, size as usize)) | |
| 1962 | let size = Size::from_bits(float_ty.bit_width()); | |
| 1963 | let bytes = size.bytes_usize(); | |
| 1964 | ||
| 1965 | let value = valtree.inner().to_leaf().to_uint(size); | |
| 1966 | let addr = self.heap_allocate(bytes, bytes)?; | |
| 1967 | self.write_memory(addr, &value.to_le_bytes()[..bytes])?; | |
| 1968 | Ok(Interval::new(addr, bytes)) | |
| 1957 | 1969 | } |
| 1958 | 1970 | TyKind::RawPtr(..) => { |
| 1959 | 1971 | let size = self.ptr_size(); |
| ... | ... | @@ -1995,15 +2007,13 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { |
| 1995 | 2007 | _ => not_supported!("unsupported const"), |
| 1996 | 2008 | }) |
| 1997 | 2009 | .collect::<Result<'_, Vec<_>>>()?; |
| 2010 | let item_size = item_layout.size.bytes_usize(); | |
| 1998 | 2011 | let items_addr = self.heap_allocate( |
| 1999 | items.len() * (item_layout.size.bits() as usize), | |
| 2000 | item_layout.align.bits_usize(), | |
| 2012 | items.len() * item_size, | |
| 2013 | item_layout.align.bytes() as usize, | |
| 2001 | 2014 | )?; |
| 2002 | 2015 | for (i, item) in items.iter().enumerate() { |
| 2003 | self.copy_from_interval( | |
| 2004 | items_addr.offset(i * (item_layout.size.bits() as usize)), | |
| 2005 | *item, | |
| 2006 | )?; | |
| 2016 | self.copy_from_interval(items_addr.offset(i * item_size), *item)?; | |
| 2007 | 2017 | } |
| 2008 | 2018 | let ref_addr = self.heap_allocate(self.ptr_size() * 2, self.ptr_size())?; |
| 2009 | 2019 | self.write_memory(ref_addr, &items_addr.to_bytes())?; |
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs+1-1| ... | ... | @@ -843,7 +843,7 @@ impl<'db> InferCtxt<'db> { |
| 843 | 843 | GenericArgs::for_item(self.interner, def_id, |_index, kind, _| self.var_for_def(kind, span)) |
| 844 | 844 | } |
| 845 | 845 | |
| 846 | /// Like `fresh_args_for_item()`, but first uses the args from `first`. | |
| 846 | /// Like [`Self::fresh_args_for_item`], but first uses the args from `first`. | |
| 847 | 847 | pub fn fill_rest_fresh_args( |
| 848 | 848 | &self, |
| 849 | 849 | span: Span, |
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs+5-2| ... | ... | @@ -1128,6 +1128,9 @@ impl<'db> Interner for DbInterner<'db> { |
| 1128 | 1128 | SolverDefId::ConstId(def_id) => { |
| 1129 | 1129 | AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) } |
| 1130 | 1130 | } |
| 1131 | SolverDefId::StaticId(def_id) => { | |
| 1132 | AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) } | |
| 1133 | } | |
| 1131 | 1134 | SolverDefId::AnonConstId(def_id) => { |
| 1132 | 1135 | AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) } |
| 1133 | 1136 | } |
| ... | ... | @@ -2626,8 +2629,8 @@ macro_rules! impl_gc_visit_slice { |
| 2626 | 2629 | } |
| 2627 | 2630 | |
| 2628 | 2631 | #[inline] |
| 2629 | fn visit_slice(header: &[<Self as ::intern::SliceInternable>::SliceType], gc: &mut ::intern::GarbageCollector) { | |
| 2630 | header.generic_visit_with(gc); | |
| 2632 | fn visit_slice(slice: &[<Self as ::intern::SliceInternable>::SliceType], gc: &mut ::intern::GarbageCollector) { | |
| 2633 | slice.generic_visit_with(gc); | |
| 2631 | 2634 | } |
| 2632 | 2635 | } |
| 2633 | 2636 | )* |
src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs+37| ... | ... | @@ -617,3 +617,40 @@ fn foo(foo: &Foo) { |
| 617 | 617 | expect!["102..126;85..88;114..117 ByRef(Immutable) *foo &'<erased> Foo"], |
| 618 | 618 | ); |
| 619 | 619 | } |
| 620 | ||
| 621 | #[test] | |
| 622 | fn method_call_field_access_regression() { | |
| 623 | check_closure_captures( | |
| 624 | r#" | |
| 625 | //- minicore:copy, fn | |
| 626 | struct NonCopy; | |
| 627 | ||
| 628 | struct Wrapper { | |
| 629 | field: NonCopy, | |
| 630 | } | |
| 631 | ||
| 632 | impl Wrapper { | |
| 633 | fn wrapped(&self) -> NonCopy { | |
| 634 | NonCopy | |
| 635 | } | |
| 636 | } | |
| 637 | ||
| 638 | pub struct Wrapper2 { | |
| 639 | field1: NonCopy, | |
| 640 | field2: NonCopy, | |
| 641 | } | |
| 642 | ||
| 643 | fn fun(wrapper: Wrapper) { | |
| 644 | pub fn update<T>(_: impl FnOnce(&mut T)) { | |
| 645 | todo!() | |
| 646 | } | |
| 647 | ||
| 648 | update::<Wrapper2>(|this| { | |
| 649 | this.field1 = wrapper.wrapped(); | |
| 650 | this.field2 = wrapper.field; | |
| 651 | }); | |
| 652 | } | |
| 653 | "#, | |
| 654 | expect!["319..411;206..213;350..357,391..398 ByValue wrapper Wrapper"], | |
| 655 | ); | |
| 656 | } |
src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs+20| ... | ... | @@ -394,6 +394,26 @@ fn main() { |
| 394 | 394 | ); |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | #[test] | |
| 398 | fn static_as_array_len_does_not_panic() { | |
| 399 | check_no_mismatches( | |
| 400 | r#" | |
| 401 | static S: usize = 8; | |
| 402 | const A: [u8; S] = [0; 8]; | |
| 403 | "#, | |
| 404 | ); | |
| 405 | } | |
| 406 | ||
| 407 | #[test] | |
| 408 | fn oversized_array_len_does_not_panic() { | |
| 409 | // The array length literal does not fit in `usize`; interning it must not panic. | |
| 410 | check_no_mismatches( | |
| 411 | r#" | |
| 412 | fn f(_: [u8; 18446744073709551616]) {} | |
| 413 | "#, | |
| 414 | ); | |
| 415 | } | |
| 416 | ||
| 397 | 417 | #[test] |
| 398 | 418 | fn another_20654_case() { |
| 399 | 419 | check_no_mismatches( |
src/tools/rust-analyzer/crates/hir-ty/src/traits.rs+4-1| ... | ... | @@ -20,7 +20,7 @@ use hir_expand::name::Name; |
| 20 | 20 | use intern::sym; |
| 21 | 21 | use rustc_type_ir::{ |
| 22 | 22 | TypeVisitableExt, TypingMode, |
| 23 | inherent::{BoundExistentialPredicates, IntoKind}, | |
| 23 | inherent::{BoundExistentialPredicates, IntoKind, Ty as _}, | |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | 26 | use crate::{ |
| ... | ... | @@ -154,6 +154,9 @@ pub fn implements_trait_unique_with_infcx<'db>( |
| 154 | 154 | |
| 155 | 155 | let args = create_args(&infcx); |
| 156 | 156 | let trait_ref = rustc_type_ir::TraitRef::new_from_args(interner, trait_.into(), args); |
| 157 | if trait_ref.self_ty().is_ty_error() { | |
| 158 | return false; | |
| 159 | } | |
| 157 | 160 | |
| 158 | 161 | let obligation = Obligation::new(interner, ObligationCause::dummy(), env.param_env, trait_ref); |
| 159 | 162 | infcx.predicate_must_hold_modulo_regions(&obligation) |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs-4| ... | ... | @@ -1236,15 +1236,11 @@ fn main { |
| 1236 | 1236 | fn destructure_in_sub_pattern() { |
| 1237 | 1237 | check_sub_pattern_assist( |
| 1238 | 1238 | r#" |
| 1239 | #![feature(bindings_after_at)] | |
| 1240 | ||
| 1241 | 1239 | fn main() { |
| 1242 | 1240 | let $0t = (1,2); |
| 1243 | 1241 | } |
| 1244 | 1242 | "#, |
| 1245 | 1243 | r#" |
| 1246 | #![feature(bindings_after_at)] | |
| 1247 | ||
| 1248 | 1244 | fn main() { |
| 1249 | 1245 | let t @ ($0_0, _1) = (1,2); |
| 1250 | 1246 | } |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs+107-70| ... | ... | @@ -17,9 +17,10 @@ use syntax::{ |
| 17 | 17 | ast::{ |
| 18 | 18 | self, HasVisibility, |
| 19 | 19 | edit::{AstNodeEdit, IndentLevel}, |
| 20 | make, | |
| 20 | syntax_factory::SyntaxFactory, | |
| 21 | 21 | }, |
| 22 | match_ast, ted, | |
| 22 | match_ast, | |
| 23 | syntax_editor::{Position, SyntaxEditor}, | |
| 23 | 24 | }; |
| 24 | 25 | |
| 25 | 26 | use crate::{AssistContext, Assists}; |
| ... | ... | @@ -121,15 +122,18 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> |
| 121 | 122 | let (usages_to_be_processed, record_fields, use_stmts_to_be_inserted) = |
| 122 | 123 | module.get_usages_and_record_fields(ctx, module_text_range); |
| 123 | 124 | |
| 125 | let make = SyntaxFactory::without_mappings(); | |
| 126 | ||
| 124 | 127 | builder.edit_file(ctx.vfs_file_id()); |
| 125 | 128 | use_stmts_to_be_inserted.into_iter().for_each(|(_, use_stmt)| { |
| 126 | 129 | builder.insert(ctx.selection_trimmed().end(), format!("\n{use_stmt}")); |
| 127 | 130 | }); |
| 128 | 131 | |
| 129 | let import_items = module.resolve_imports(curr_parent_module, ctx); | |
| 130 | module.change_visibility(record_fields); | |
| 132 | let import_items = module.resolve_imports(curr_parent_module, ctx, &make); | |
| 133 | module.change_visibility(record_fields, &make); | |
| 131 | 134 | |
| 132 | let module_def = generate_module_def(&impl_parent, &module).indent(old_item_indent); | |
| 135 | let module_def = | |
| 136 | generate_module_def(&impl_parent, &module, &make).indent(old_item_indent); | |
| 133 | 137 | |
| 134 | 138 | let mut usages_to_be_processed_for_cur_file = vec![]; |
| 135 | 139 | for (file_id, usages) in usages_to_be_processed { |
| ... | ... | @@ -185,6 +189,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> |
| 185 | 189 | fn generate_module_def( |
| 186 | 190 | parent_impl: &Option<ast::Impl>, |
| 187 | 191 | Module { name, body_items, use_items }: &Module, |
| 192 | make: &SyntaxFactory, | |
| 188 | 193 | ) -> ast::Module { |
| 189 | 194 | let items: Vec<_> = if let Some(impl_) = parent_impl.as_ref() |
| 190 | 195 | && let Some(self_ty) = impl_.self_ty() |
| ... | ... | @@ -195,11 +200,15 @@ fn generate_module_def( |
| 195 | 200 | .filter_map(ast::AssocItem::cast) |
| 196 | 201 | .map(|it| it.indent(IndentLevel(1))) |
| 197 | 202 | .collect_vec(); |
| 198 | let assoc_item_list = make::assoc_item_list(Some(assoc_items)).clone_for_update(); | |
| 199 | let impl_ = impl_.reset_indent(); | |
| 200 | ted::replace(impl_.get_or_create_assoc_item_list().syntax(), assoc_item_list.syntax()); | |
| 203 | let impl_reset = impl_.reset_indent(); | |
| 204 | let (editor, impl_root) = SyntaxEditor::with_ast_node(&impl_reset); | |
| 205 | let assoc_item_list = editor.make().assoc_item_list(assoc_items); | |
| 206 | if let Some(existing_list) = impl_root.assoc_item_list() { | |
| 207 | editor.replace(existing_list.syntax(), assoc_item_list.syntax()); | |
| 208 | } | |
| 209 | let impl_ = ast::Impl::cast(editor.finish().new_root().clone()).unwrap(); | |
| 201 | 210 | // Add the import for enum/struct corresponding to given impl block |
| 202 | let use_impl = make_use_stmt_of_node_with_super(self_ty.syntax()); | |
| 211 | let use_impl = make_use_stmt_of_node_with_super(self_ty.syntax(), make); | |
| 203 | 212 | once(use_impl) |
| 204 | 213 | .chain(use_items.iter().cloned()) |
| 205 | 214 | .chain(once(ast::Item::Impl(impl_))) |
| ... | ... | @@ -209,19 +218,18 @@ fn generate_module_def( |
| 209 | 218 | }; |
| 210 | 219 | |
| 211 | 220 | let items = items.into_iter().map(|it| it.reset_indent().indent(IndentLevel(1))).collect_vec(); |
| 212 | let module_body = make::item_list(Some(items)); | |
| 213 | ||
| 214 | let module_name = make::name(name); | |
| 215 | make::mod_(module_name, Some(module_body)) | |
| 221 | let module_body = make.item_list(items); | |
| 222 | let module_name = make.name(name); | |
| 223 | make.mod_(module_name, Some(module_body)) | |
| 216 | 224 | } |
| 217 | 225 | |
| 218 | fn make_use_stmt_of_node_with_super(node_syntax: &SyntaxNode) -> ast::Item { | |
| 219 | let super_path = make::ext::ident_path("super"); | |
| 220 | let node_path = make::ext::ident_path(&node_syntax.to_string()); | |
| 221 | let use_ = make::use_( | |
| 226 | fn make_use_stmt_of_node_with_super(node_syntax: &SyntaxNode, make: &SyntaxFactory) -> ast::Item { | |
| 227 | let super_path = make.ident_path("super"); | |
| 228 | let node_path = make.path_from_text(&node_syntax.to_string()); | |
| 229 | let use_ = make.use_( | |
| 230 | [], | |
| 222 | 231 | None, |
| 223 | None, | |
| 224 | make::use_tree(make::join_paths(vec![super_path, node_path]), None, None, false), | |
| 232 | make.use_tree(make.path_concat(super_path, node_path), None, None, false), | |
| 225 | 233 | ); |
| 226 | 234 | |
| 227 | 235 | ast::Item::from(use_) |
| ... | ... | @@ -385,18 +393,30 @@ impl Module { |
| 385 | 393 | if use_.syntax().parent().is_some_and(|parent| parent == covering_node) |
| 386 | 394 | && use_stmts_set.insert(use_.syntax().text_range().start()) |
| 387 | 395 | { |
| 388 | let use_ = use_stmts_to_be_inserted | |
| 389 | .entry(use_.syntax().text_range().start()) | |
| 390 | .or_insert_with(|| use_.clone_subtree().clone_for_update()); | |
| 391 | for seg in use_ | |
| 392 | .syntax() | |
| 393 | .descendants() | |
| 394 | .filter_map(ast::NameRef::cast) | |
| 395 | .filter(|seg| seg.syntax().to_string() == name_ref.to_string()) | |
| 396 | { | |
| 397 | let new_ref = make::path_from_text(&format!("{mod_name}::{seg}")) | |
| 398 | .clone_for_update(); | |
| 399 | ted::replace(seg.syntax().parent()?, new_ref.syntax()); | |
| 396 | let key = use_.syntax().text_range().start(); | |
| 397 | let entry = | |
| 398 | use_stmts_to_be_inserted.entry(key).or_insert_with(|| use_.clone()); | |
| 399 | let (editor, edit_root) = SyntaxEditor::with_ast_node(&*entry); | |
| 400 | let replacements: Vec<_> = { | |
| 401 | let make = editor.make(); | |
| 402 | edit_root | |
| 403 | .syntax() | |
| 404 | .descendants() | |
| 405 | .filter_map(ast::NameRef::cast) | |
| 406 | .filter(|seg| seg.syntax().to_string() == name_ref.to_string()) | |
| 407 | .filter_map(|seg| { | |
| 408 | Some(( | |
| 409 | seg.syntax().parent()?, | |
| 410 | make.path_from_text(&format!("{mod_name}::{seg}")), | |
| 411 | )) | |
| 412 | }) | |
| 413 | .collect() | |
| 414 | }; | |
| 415 | if !replacements.is_empty() { | |
| 416 | for (parent, new_ref) in &replacements { | |
| 417 | editor.replace(parent, new_ref.syntax()); | |
| 418 | } | |
| 419 | *entry = ast::Use::cast(editor.finish().new_root().clone()).unwrap(); | |
| 400 | 420 | } |
| 401 | 421 | } |
| 402 | 422 | } |
| ... | ... | @@ -407,18 +427,23 @@ impl Module { |
| 407 | 427 | } |
| 408 | 428 | } |
| 409 | 429 | |
| 410 | fn change_visibility(&mut self, record_fields: Vec<SyntaxNode>) { | |
| 430 | fn change_visibility(&mut self, record_fields: Vec<SyntaxNode>, make: &SyntaxFactory) { | |
| 431 | for item in &mut self.body_items { | |
| 432 | let (_, root) = SyntaxEditor::with_ast_node(&item.reset_indent()); | |
| 433 | *item = root; | |
| 434 | } | |
| 435 | ||
| 411 | 436 | let (mut replacements, record_field_parents, impls) = |
| 412 | get_replacements_for_visibility_change(&mut self.body_items, false); | |
| 437 | get_replacements_for_visibility_change(&self.body_items); | |
| 413 | 438 | |
| 414 | let mut impl_items = impls | |
| 439 | let impl_items = impls | |
| 415 | 440 | .into_iter() |
| 416 | 441 | .flat_map(|impl_| impl_.syntax().descendants()) |
| 417 | 442 | .filter_map(ast::Item::cast) |
| 418 | 443 | .collect_vec(); |
| 419 | 444 | |
| 420 | 445 | let (mut impl_item_replacements, _, _) = |
| 421 | get_replacements_for_visibility_change(&mut impl_items, true); | |
| 446 | get_replacements_for_visibility_change(&impl_items); | |
| 422 | 447 | |
| 423 | 448 | replacements.append(&mut impl_item_replacements); |
| 424 | 449 | |
| ... | ... | @@ -432,17 +457,39 @@ impl Module { |
| 432 | 457 | } |
| 433 | 458 | } |
| 434 | 459 | |
| 435 | for (vis, syntax) in replacements { | |
| 436 | let item = syntax.children_with_tokens().find(|node_or_token| { | |
| 437 | match node_or_token.kind() { | |
| 438 | // We're skipping comments, doc comments, and attribute macros that may precede the keyword | |
| 439 | // that the visibility should be placed before. | |
| 440 | SyntaxKind::COMMENT | SyntaxKind::ATTR | SyntaxKind::WHITESPACE => false, | |
| 441 | _ => true, | |
| 442 | } | |
| 443 | }); | |
| 460 | for body_item in &mut self.body_items { | |
| 461 | let insert_targets: Vec<_> = replacements | |
| 462 | .iter() | |
| 463 | .filter(|(vis, syntax)| { | |
| 464 | vis.is_none() | |
| 465 | && (syntax == body_item.syntax() | |
| 466 | || syntax.ancestors().any(|a| &a == body_item.syntax())) | |
| 467 | }) | |
| 468 | .filter_map(|(_, syntax)| { | |
| 469 | syntax.children_with_tokens().find(|nt| { | |
| 470 | !matches!( | |
| 471 | nt.kind(), | |
| 472 | SyntaxKind::COMMENT | SyntaxKind::ATTR | SyntaxKind::WHITESPACE | |
| 473 | ) | |
| 474 | }) | |
| 475 | }) | |
| 476 | .collect(); | |
| 444 | 477 | |
| 445 | add_change_vis(vis, item); | |
| 478 | if insert_targets.is_empty() { | |
| 479 | continue; | |
| 480 | } | |
| 481 | ||
| 482 | let (editor, _) = SyntaxEditor::new(body_item.syntax().clone()); | |
| 483 | for target in insert_targets { | |
| 484 | editor.insert_all( | |
| 485 | Position::before(target), | |
| 486 | vec![ | |
| 487 | make.visibility_pub_crate().syntax().clone().into(), | |
| 488 | make.whitespace(" ").into(), | |
| 489 | ], | |
| 490 | ); | |
| 491 | } | |
| 492 | *body_item = ast::Item::cast(editor.finish().new_root().clone()).unwrap(); | |
| 446 | 493 | } |
| 447 | 494 | } |
| 448 | 495 | |
| ... | ... | @@ -450,6 +497,7 @@ impl Module { |
| 450 | 497 | &mut self, |
| 451 | 498 | module: Option<ast::Module>, |
| 452 | 499 | ctx: &AssistContext<'_, '_>, |
| 500 | make: &SyntaxFactory, | |
| 453 | 501 | ) -> Vec<TextRange> { |
| 454 | 502 | let mut imports_to_remove = vec![]; |
| 455 | 503 | let mut node_set = FxHashSet::default(); |
| ... | ... | @@ -476,7 +524,8 @@ impl Module { |
| 476 | 524 | }) |
| 477 | 525 | .for_each(|(node, def)| { |
| 478 | 526 | if node_set.insert(node.to_string()) |
| 479 | && let Some(import) = self.process_def_in_sel(def, &node, &module, ctx) | |
| 527 | && let Some(import) = | |
| 528 | self.process_def_in_sel(def, &node, &module, ctx, make) | |
| 480 | 529 | { |
| 481 | 530 | check_intersection_and_push(&mut imports_to_remove, import); |
| 482 | 531 | } |
| ... | ... | @@ -492,6 +541,7 @@ impl Module { |
| 492 | 541 | use_node: &SyntaxNode, |
| 493 | 542 | curr_parent_module: &Option<ast::Module>, |
| 494 | 543 | ctx: &AssistContext<'_, '_>, |
| 544 | make: &SyntaxFactory, | |
| 495 | 545 | ) -> Option<TextRange> { |
| 496 | 546 | //We only need to find in the current file |
| 497 | 547 | let selection_range = ctx.selection_trimmed(); |
| ... | ... | @@ -567,7 +617,7 @@ impl Module { |
| 567 | 617 | // mod -> ust_stmt transversal |
| 568 | 618 | // true | false -> super import insertion |
| 569 | 619 | // true | true -> super import insertion |
| 570 | let super_use_node = make_use_stmt_of_node_with_super(use_node); | |
| 620 | let super_use_node = make_use_stmt_of_node_with_super(use_node, make); | |
| 571 | 621 | self.use_items.insert(0, super_use_node); |
| 572 | 622 | } |
| 573 | 623 | None => {} |
| ... | ... | @@ -590,14 +640,14 @@ impl Module { |
| 590 | 640 | if !first_path_in_use_tree_str.contains("super") |
| 591 | 641 | && !first_path_in_use_tree_str.contains("crate") |
| 592 | 642 | { |
| 593 | let super_path = make::ext::ident_path("super"); | |
| 643 | let super_path = make.ident_path("super"); | |
| 594 | 644 | use_tree_str.push(super_path); |
| 595 | 645 | } |
| 596 | 646 | } |
| 597 | 647 | |
| 598 | 648 | use_tree_paths = Some(use_tree_str); |
| 599 | 649 | } else if def_in_mod && def_out_sel { |
| 600 | let super_use_node = make_use_stmt_of_node_with_super(use_node); | |
| 650 | let super_use_node = make_use_stmt_of_node_with_super(use_node, make); | |
| 601 | 651 | self.use_items.insert(0, super_use_node); |
| 602 | 652 | } |
| 603 | 653 | } |
| ... | ... | @@ -609,7 +659,7 @@ impl Module { |
| 609 | 659 | && let Some(first_path_in_use_tree) = use_tree_paths.first() |
| 610 | 660 | && first_path_in_use_tree.to_string().contains("super") |
| 611 | 661 | { |
| 612 | use_tree_paths.insert(0, make::ext::ident_path("super")); | |
| 662 | use_tree_paths.insert(0, make.ident_path("super")); | |
| 613 | 663 | } |
| 614 | 664 | |
| 615 | 665 | let is_item = matches!( |
| ... | ... | @@ -624,12 +674,12 @@ impl Module { |
| 624 | 674 | | Definition::TypeAlias(_) |
| 625 | 675 | ); |
| 626 | 676 | |
| 627 | if (def_out_sel || !is_item) && use_stmt_not_in_sel { | |
| 628 | let use_ = make::use_( | |
| 629 | None, | |
| 630 | None, | |
| 631 | make::use_tree(make::join_paths(use_tree_paths), None, None, false), | |
| 632 | ); | |
| 677 | if (def_out_sel || !is_item) | |
| 678 | && use_stmt_not_in_sel | |
| 679 | && let Some(joined) = | |
| 680 | use_tree_paths.into_iter().reduce(|acc, p| make.path_concat(acc, p)) | |
| 681 | { | |
| 682 | let use_ = make.use_([], None, make.use_tree(joined, None, None, false)); | |
| 633 | 683 | self.use_items.insert(0, ast::Item::from(use_)); |
| 634 | 684 | } |
| 635 | 685 | } |
| ... | ... | @@ -741,8 +791,7 @@ fn check_def_in_mod_and_out_sel( |
| 741 | 791 | } |
| 742 | 792 | |
| 743 | 793 | fn get_replacements_for_visibility_change( |
| 744 | items: &mut [ast::Item], | |
| 745 | is_clone_for_updated: bool, | |
| 794 | items: &[ast::Item], | |
| 746 | 795 | ) -> ( |
| 747 | 796 | Vec<(Option<ast::Visibility>, SyntaxNode)>, |
| 748 | 797 | Vec<(Option<ast::Visibility>, SyntaxNode)>, |
| ... | ... | @@ -753,9 +802,6 @@ fn get_replacements_for_visibility_change( |
| 753 | 802 | let mut impls = Vec::new(); |
| 754 | 803 | |
| 755 | 804 | for item in items { |
| 756 | if !is_clone_for_updated { | |
| 757 | *item = item.clone_for_update(); | |
| 758 | } | |
| 759 | 805 | //Use stmts are ignored |
| 760 | 806 | macro_rules! push_to_replacement { |
| 761 | 807 | ($it:ident) => { |
| ... | ... | @@ -812,15 +858,6 @@ fn get_use_tree_paths_from_path( |
| 812 | 858 | Some(use_tree_str) |
| 813 | 859 | } |
| 814 | 860 | |
| 815 | fn add_change_vis(vis: Option<ast::Visibility>, node_or_token_opt: Option<syntax::SyntaxElement>) { | |
| 816 | if vis.is_none() | |
| 817 | && let Some(node_or_token) = node_or_token_opt | |
| 818 | { | |
| 819 | let pub_crate_vis = make::visibility_pub_crate().clone_for_update(); | |
| 820 | ted::insert(ted::Position::before(node_or_token), pub_crate_vis.syntax()); | |
| 821 | } | |
| 822 | } | |
| 823 | ||
| 824 | 861 | fn indent_range_before_given_node(node: &SyntaxNode) -> Option<TextRange> { |
| 825 | 862 | node.siblings_with_tokens(syntax::Direction::Prev) |
| 826 | 863 | .find(|x| x.kind() == WHITESPACE) |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs+148-68| ... | ... | @@ -1,19 +1,20 @@ |
| 1 | 1 | use either::{Either, for_both}; |
| 2 | use hir::{PathResolution, Semantics}; | |
| 2 | use hir::{EditionedFileId, PathResolution, Semantics}; | |
| 3 | 3 | use ide_db::{ |
| 4 | EditionedFileId, RootDatabase, | |
| 4 | RootDatabase, | |
| 5 | 5 | defs::Definition, |
| 6 | search::{FileReference, FileReferenceNode, UsageSearchResult}, | |
| 6 | search::{FileReference, UsageSearchResult}, | |
| 7 | 7 | }; |
| 8 | 8 | use syntax::{ |
| 9 | Direction, TextRange, | |
| 9 | Direction, T, TextRange, | |
| 10 | 10 | ast::{self, AstNode, AstToken, HasName}, |
| 11 | syntax_editor::{Element, SyntaxEditor}, | |
| 11 | syntax_editor::{Element, Position, SyntaxEditor}, | |
| 12 | 12 | }; |
| 13 | 13 | |
| 14 | 14 | use crate::{ |
| 15 | 15 | AssistId, |
| 16 | 16 | assist_context::{AssistContext, Assists}, |
| 17 | utils::{cover_edit_range, original_range_in}, | |
| 17 | 18 | }; |
| 18 | 19 | |
| 19 | 20 | // Assist: inline_local_variable |
| ... | ... | @@ -34,11 +35,12 @@ use crate::{ |
| 34 | 35 | // ``` |
| 35 | 36 | pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> { |
| 36 | 37 | let file_id = ctx.file_id(); |
| 38 | let source = ctx.source_file().syntax(); | |
| 37 | 39 | let range = ctx.selection_trimmed(); |
| 38 | 40 | let InlineData { let_stmt, delete_let, references, target } = |
| 39 | if let Some(path_expr) = ctx.find_node_at_offset::<ast::PathExpr>() { | |
| 41 | if let Some(path_expr) = ctx.find_node_at_offset_with_descend::<ast::PathExpr>() { | |
| 40 | 42 | inline_usage(&ctx.sema, path_expr, range, file_id) |
| 41 | } else if let Some(let_stmt) = ctx.find_node_at_offset() { | |
| 43 | } else if let Some(let_stmt) = ctx.find_node_at_offset_with_descend() { | |
| 42 | 44 | inline_let(&ctx.sema, let_stmt, range, file_id) |
| 43 | 45 | } else { |
| 44 | 46 | None |
| ... | ... | @@ -47,71 +49,65 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_, ' |
| 47 | 49 | either::Either::Left(it) => it.initializer()?, |
| 48 | 50 | either::Either::Right(it) => it.expr()?, |
| 49 | 51 | }; |
| 50 | ||
| 51 | let wrap_in_parens = references | |
| 52 | .into_iter() | |
| 53 | .filter_map(|FileReference { range, name, .. }| match name { | |
| 54 | FileReferenceNode::NameRef(name) => Some((range, name)), | |
| 55 | _ => None, | |
| 56 | }) | |
| 57 | .map(|(range, name_ref)| { | |
| 58 | if range != name_ref.syntax().text_range() { | |
| 59 | // Do not rename inside macros | |
| 60 | // FIXME: This feels like a bad heuristic for macros | |
| 61 | return None; | |
| 52 | let needs_parens = |name_ref: &ast::NameRef| { | |
| 53 | let usage_node = | |
| 54 | name_ref.syntax().ancestors().find(|it| ast::PathExpr::can_cast(it.kind())); | |
| 55 | let usage_parent = usage_node.as_ref().and_then(|it| it.parent()); | |
| 56 | match (usage_node, usage_parent) { | |
| 57 | (Some(usage), Some(parent)) => { | |
| 58 | initializer_expr.needs_parens_in_place_of(&parent, &usage) | |
| 62 | 59 | } |
| 63 | let usage_node = | |
| 64 | name_ref.syntax().ancestors().find(|it| ast::PathExpr::can_cast(it.kind())); | |
| 65 | let usage_parent_option = usage_node.as_ref().and_then(|it| it.parent()); | |
| 66 | let usage_parent = match usage_parent_option { | |
| 67 | Some(u) => u, | |
| 68 | None => return Some((name_ref, false)), | |
| 69 | }; | |
| 70 | let should_wrap = initializer_expr | |
| 71 | .needs_parens_in_place_of(&usage_parent, usage_node.as_ref().unwrap()); | |
| 72 | Some((name_ref, should_wrap)) | |
| 73 | }) | |
| 74 | .collect::<Option<Vec<_>>>()?; | |
| 75 | ||
| 76 | let target = match target { | |
| 77 | ast::NameOrNameRef::Name(it) => it.syntax().clone(), | |
| 78 | ast::NameOrNameRef::NameRef(it) => it.syntax().clone(), | |
| 60 | _ => false, | |
| 61 | } | |
| 79 | 62 | }; |
| 80 | 63 | |
| 81 | 64 | acc.add( |
| 82 | 65 | AssistId::refactor_inline("inline_local_variable"), |
| 83 | 66 | "Inline variable", |
| 84 | target.text_range(), | |
| 85 | move |builder| { | |
| 86 | let editor = builder.make_editor(&target); | |
| 67 | target, | |
| 68 | |builder| { | |
| 69 | let editor = builder.make_editor(source); | |
| 87 | 70 | let make = editor.make(); |
| 88 | if delete_let { | |
| 89 | editor.delete(let_stmt.syntax()); | |
| 90 | ||
| 71 | if delete_let | |
| 72 | && let Some(original) = original_range_in(file_id, &ctx.sema, let_stmt.syntax()) | |
| 73 | { | |
| 74 | let place = cover_edit_range(source, original); | |
| 75 | editor.delete_all(place.clone()); | |
| 76 | ||
| 77 | // Processing let-expr in let-chain | |
| 78 | // FIXME: process let-expr in macro, but this case is very rare | |
| 91 | 79 | if let Some(bin_expr) = let_stmt.syntax().parent().and_then(ast::BinExpr::cast) |
| 92 | 80 | && let Some(op_token) = bin_expr.op_token() |
| 93 | 81 | { |
| 94 | 82 | editor.delete(&op_token); |
| 95 | 83 | remove_whitespace(op_token, Direction::Prev, &editor); |
| 96 | remove_whitespace(let_stmt.syntax(), Direction::Prev, &editor); | |
| 84 | remove_whitespace(place.start(), Direction::Prev, &editor); | |
| 97 | 85 | } else { |
| 98 | remove_whitespace(let_stmt.syntax(), Direction::Next, &editor); | |
| 86 | remove_whitespace(place.end(), Direction::Next, &editor); | |
| 99 | 87 | } |
| 100 | 88 | } |
| 101 | 89 | |
| 102 | for (name, should_wrap) in wrap_in_parens { | |
| 103 | let replacement = if should_wrap { | |
| 90 | for FileReference { range, name, .. } in references { | |
| 91 | let Some(name) = name.as_name_ref().cloned() else { continue }; | |
| 92 | let replacement = if needs_parens(&name) { | |
| 104 | 93 | make.expr_paren(initializer_expr.clone()).into() |
| 105 | 94 | } else { |
| 106 | 95 | initializer_expr.clone() |
| 107 | 96 | }; |
| 108 | 97 | |
| 109 | if let Some(record_field) = ast::RecordExprField::for_field_name(&name) { | |
| 98 | let place = cover_edit_range(source, range); | |
| 99 | if ast::RecordExprField::for_field_name(&name).is_some() { | |
| 110 | 100 | cov_mark::hit!(inline_field_shorthand); |
| 111 | let replacement = make.record_expr_field(name, Some(replacement)); | |
| 112 | editor.replace(record_field.syntax(), replacement.syntax()); | |
| 101 | editor.insert_all( | |
| 102 | Position::after(place.end()), | |
| 103 | vec![ | |
| 104 | make.token(T![:]).into(), | |
| 105 | make.whitespace(" ").into(), | |
| 106 | replacement.syntax().clone().into(), | |
| 107 | ], | |
| 108 | ); | |
| 113 | 109 | } else { |
| 114 | editor.replace(name.syntax(), replacement.syntax()); | |
| 110 | editor.replace_all(place, vec![replacement.syntax().clone().into()]); | |
| 115 | 111 | } |
| 116 | 112 | } |
| 117 | 113 | builder.add_file_edits(ctx.vfs_file_id(), editor); |
| ... | ... | @@ -122,7 +118,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_, ' |
| 122 | 118 | struct InlineData { |
| 123 | 119 | let_stmt: Either<ast::LetStmt, ast::LetExpr>, |
| 124 | 120 | delete_let: bool, |
| 125 | target: ast::NameOrNameRef, | |
| 121 | target: TextRange, | |
| 126 | 122 | references: Vec<FileReference>, |
| 127 | 123 | } |
| 128 | 124 | |
| ... | ... | @@ -140,20 +136,18 @@ fn inline_let( |
| 140 | 136 | cov_mark::hit!(test_not_inline_mut_variable); |
| 141 | 137 | return None; |
| 142 | 138 | } |
| 143 | if !bind_pat.syntax().text_range().contains_range(range) { | |
| 139 | let target = original_range_in(file_id, sema, bind_pat.name()?.syntax())?; | |
| 140 | if !target.contains_range(range) { | |
| 144 | 141 | cov_mark::hit!(not_applicable_outside_of_bind_pat); |
| 145 | 142 | return None; |
| 146 | 143 | } |
| 147 | 144 | |
| 148 | 145 | let local = sema.to_def(&bind_pat)?; |
| 149 | let UsageSearchResult { mut references } = Definition::Local(local).usages(sema).all(); | |
| 150 | match references.remove(&file_id) { | |
| 151 | Some(references) => Some(InlineData { | |
| 152 | let_stmt, | |
| 153 | delete_let: true, | |
| 154 | target: ast::NameOrNameRef::Name(bind_pat.name()?), | |
| 155 | references, | |
| 156 | }), | |
| 146 | let UsageSearchResult { references } = Definition::Local(local).usages(sema).all(); | |
| 147 | let references = references.into_iter().flat_map(|it| it.1).collect::<Vec<_>>(); | |
| 148 | ||
| 149 | match references.first() { | |
| 150 | Some(_) => Some(InlineData { let_stmt, delete_let: true, target, references }), | |
| 157 | 151 | None => { |
| 158 | 152 | cov_mark::hit!(test_not_applicable_if_variable_unused); |
| 159 | 153 | None |
| ... | ... | @@ -169,7 +163,8 @@ fn inline_usage( |
| 169 | 163 | ) -> Option<InlineData> { |
| 170 | 164 | let path = path_expr.path()?; |
| 171 | 165 | let name = path.as_single_name_ref()?; |
| 172 | if !name.syntax().text_range().contains_range(range) { | |
| 166 | let target = original_range_in(file_id, sema, name.syntax())?; | |
| 167 | if !target.contains_range(range) { | |
| 173 | 168 | cov_mark::hit!(test_not_inline_selection_too_broad); |
| 174 | 169 | return None; |
| 175 | 170 | } |
| ... | ... | @@ -193,12 +188,12 @@ fn inline_usage( |
| 193 | 188 | |
| 194 | 189 | let let_stmt = AstNode::cast(bind_pat.syntax().parent()?)?; |
| 195 | 190 | |
| 196 | let UsageSearchResult { mut references } = Definition::Local(local).usages(sema).all(); | |
| 197 | let mut references = references.remove(&file_id)?; | |
| 191 | let UsageSearchResult { references } = Definition::Local(local).usages(sema).all(); | |
| 192 | let mut references = references.into_iter().flat_map(|it| it.1).collect::<Vec<_>>(); | |
| 198 | 193 | let delete_let = references.len() == 1; |
| 199 | 194 | references.retain(|fref| fref.name.as_name_ref() == Some(&name)); |
| 200 | 195 | |
| 201 | Some(InlineData { let_stmt, delete_let, target: ast::NameOrNameRef::NameRef(name), references }) | |
| 196 | Some(InlineData { let_stmt, delete_let, target, references }) | |
| 202 | 197 | } |
| 203 | 198 | |
| 204 | 199 | fn remove_whitespace(elem: impl Element, dir: Direction, editor: &SyntaxEditor) { |
| ... | ... | @@ -969,8 +964,8 @@ fn main() { |
| 969 | 964 | } |
| 970 | 965 | |
| 971 | 966 | #[test] |
| 972 | fn not_applicable_on_local_usage_in_macro() { | |
| 973 | check_assist_not_applicable( | |
| 967 | fn local_usage_in_macro() { | |
| 968 | check_assist( | |
| 974 | 969 | inline_local_variable, |
| 975 | 970 | r#" |
| 976 | 971 | macro_rules! m { |
| ... | ... | @@ -978,11 +973,19 @@ macro_rules! m { |
| 978 | 973 | } |
| 979 | 974 | fn f() { |
| 980 | 975 | let xyz = 0; |
| 981 | m!(xyz$0); // replacing it would break the macro | |
| 976 | m!(xyz$0); // some macros may break, but it's best to support them | |
| 977 | } | |
| 978 | "#, | |
| 979 | r#" | |
| 980 | macro_rules! m { | |
| 981 | ($i:ident) => { $i } | |
| 982 | } | |
| 983 | fn f() { | |
| 984 | m!(0); // some macros may break, but it's best to support them | |
| 982 | 985 | } |
| 983 | 986 | "#, |
| 984 | 987 | ); |
| 985 | check_assist_not_applicable( | |
| 988 | check_assist( | |
| 986 | 989 | inline_local_variable, |
| 987 | 990 | r#" |
| 988 | 991 | macro_rules! m { |
| ... | ... | @@ -990,7 +993,84 @@ macro_rules! m { |
| 990 | 993 | } |
| 991 | 994 | fn f() { |
| 992 | 995 | let xyz$0 = 0; |
| 993 | m!(xyz); // replacing it would break the macro | |
| 996 | m!(xyz); // some macros may break, but it's best to support them | |
| 997 | } | |
| 998 | "#, | |
| 999 | r#" | |
| 1000 | macro_rules! m { | |
| 1001 | ($i:ident) => { $i } | |
| 1002 | } | |
| 1003 | fn f() { | |
| 1004 | m!(0); // some macros may break, but it's best to support them | |
| 1005 | } | |
| 1006 | "#, | |
| 1007 | ); | |
| 1008 | } | |
| 1009 | ||
| 1010 | #[test] | |
| 1011 | fn local_def_in_macro() { | |
| 1012 | check_assist( | |
| 1013 | inline_local_variable, | |
| 1014 | r#" | |
| 1015 | macro_rules! i { | |
| 1016 | ($($t:tt)*) => { $($t)* } | |
| 1017 | } | |
| 1018 | fn f() { | |
| 1019 | i!(let xyz = 0;); | |
| 1020 | _ = xyz$0; | |
| 1021 | } | |
| 1022 | "#, | |
| 1023 | r#" | |
| 1024 | macro_rules! i { | |
| 1025 | ($($t:tt)*) => { $($t)* } | |
| 1026 | } | |
| 1027 | fn f() { | |
| 1028 | i!(); | |
| 1029 | _ = 0; | |
| 1030 | } | |
| 1031 | "#, | |
| 1032 | ); | |
| 1033 | check_assist( | |
| 1034 | inline_local_variable, | |
| 1035 | r#" | |
| 1036 | macro_rules! i { | |
| 1037 | ($($t:tt)*) => { $($t)* } | |
| 1038 | } | |
| 1039 | fn f() { | |
| 1040 | i!(let xyz = 0;); | |
| 1041 | _ = xyz$0; | |
| 1042 | _ = xyz; | |
| 1043 | } | |
| 1044 | "#, | |
| 1045 | r#" | |
| 1046 | macro_rules! i { | |
| 1047 | ($($t:tt)*) => { $($t)* } | |
| 1048 | } | |
| 1049 | fn f() { | |
| 1050 | i!(let xyz = 0;); | |
| 1051 | _ = 0; | |
| 1052 | _ = xyz; | |
| 1053 | } | |
| 1054 | "#, | |
| 1055 | ); | |
| 1056 | check_assist( | |
| 1057 | inline_local_variable, | |
| 1058 | r#" | |
| 1059 | macro_rules! i { | |
| 1060 | ($($t:tt)*) => { $($t)* } | |
| 1061 | } | |
| 1062 | fn f() { | |
| 1063 | i!(let $0xyz = 0;); | |
| 1064 | _ = xyz; | |
| 1065 | } | |
| 1066 | "#, | |
| 1067 | r#" | |
| 1068 | macro_rules! i { | |
| 1069 | ($($t:tt)*) => { $($t)* } | |
| 1070 | } | |
| 1071 | fn f() { | |
| 1072 | i!(); | |
| 1073 | _ = 0; | |
| 994 | 1074 | } |
| 995 | 1075 | "#, |
| 996 | 1076 | ); |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_macro.rs+59-8| ... | ... | @@ -1,8 +1,11 @@ |
| 1 | 1 | use hir::db::ExpandDatabase; |
| 2 | 2 | use ide_db::syntax_helpers::prettify_macro_expansion; |
| 3 | use syntax::ast::{self, AstNode, edit::AstNodeEdit}; | |
| 3 | use syntax::ast::{self, AstNode, edit::IndentLevel}; | |
| 4 | 4 | |
| 5 | use crate::{AssistContext, AssistId, Assists}; | |
| 5 | use crate::{ | |
| 6 | AssistContext, AssistId, Assists, | |
| 7 | utils::{cover_edit_range, original_range_in}, | |
| 8 | }; | |
| 6 | 9 | |
| 7 | 10 | // Assist: inline_macro |
| 8 | 11 | // |
| ... | ... | @@ -36,24 +39,40 @@ use crate::{AssistContext, AssistId, Assists}; |
| 36 | 39 | // } |
| 37 | 40 | // ``` |
| 38 | 41 | pub(crate) fn inline_macro(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> { |
| 39 | let unexpanded = ctx.find_node_at_offset::<ast::MacroCall>()?; | |
| 40 | let macro_call = ctx.sema.to_def(&unexpanded)?; | |
| 42 | let source = ctx.source_file().syntax(); | |
| 43 | let sel = ctx.selection_trimmed(); | |
| 44 | let (macro_call, text_range) = ctx | |
| 45 | .sema | |
| 46 | .find_nodes_at_offset_with_descend::<ast::MacroCall>(source, ctx.offset()) | |
| 47 | .find_map(|macro_call_node| { | |
| 48 | let macro_call = ctx.sema.to_def(&macro_call_node)?; | |
| 49 | let original_range = | |
| 50 | original_range_in(ctx.file_id(), &ctx.sema, macro_call_node.syntax())?; | |
| 51 | original_range.contains_range(sel).then_some((macro_call, original_range)) | |
| 52 | })?; | |
| 41 | 53 | let target_crate_id = ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate(ctx.db()).into(); |
| 42 | let text_range = unexpanded.syntax().text_range(); | |
| 43 | 54 | |
| 44 | 55 | acc.add( |
| 45 | 56 | AssistId::refactor_inline("inline_macro"), |
| 46 | 57 | "Inline macro".to_owned(), |
| 47 | 58 | text_range, |
| 48 | 59 | |builder| { |
| 49 | let editor = builder.make_editor(unexpanded.syntax()); | |
| 50 | 60 | let expanded = ctx.sema.parse_or_expand(macro_call.into()); |
| 51 | 61 | let span_map = ctx.sema.db.expansion_span_map(macro_call); |
| 52 | 62 | // Don't call `prettify_macro_expansion()` outside the actual assist action; it does some heavy rowan tree manipulation, |
| 53 | 63 | // which can be very costly for big macros when it is done *even without the assist being invoked*. |
| 54 | 64 | let expanded = prettify_macro_expansion(ctx.db(), expanded, span_map, target_crate_id); |
| 55 | let expanded = ast::edit::indent(&expanded, unexpanded.indent_level()); | |
| 56 | editor.replace(unexpanded.syntax(), expanded); | |
| 65 | ||
| 66 | // macro_call is from an expansion, use source position for indent | |
| 67 | let indent = source | |
| 68 | .token_at_offset(text_range.start()) | |
| 69 | .right_biased() | |
| 70 | .map_or_else(IndentLevel::zero, |t| IndentLevel::from_token(&t)); | |
| 71 | let expanded = ast::edit::indent(&expanded, indent); | |
| 72 | ||
| 73 | let editor = builder.make_editor(source); | |
| 74 | let place = cover_edit_range(source, text_range); | |
| 75 | editor.replace_all(place, vec![expanded.into()]); | |
| 57 | 76 | builder.add_file_edits(ctx.vfs_file_id(), editor); |
| 58 | 77 | }, |
| 59 | 78 | ) |
| ... | ... | @@ -103,6 +122,7 @@ macro_rules! num { |
| 103 | 122 | "# |
| 104 | 123 | }; |
| 105 | 124 | } |
| 125 | ||
| 106 | 126 | #[test] |
| 107 | 127 | fn inline_macro_target() { |
| 108 | 128 | check_assist_target( |
| ... | ... | @@ -376,6 +396,37 @@ fn bar() { |
| 376 | 396 | fn bar() { |
| 377 | 397 | a::Foo; |
| 378 | 398 | } |
| 399 | "#, | |
| 400 | ); | |
| 401 | } | |
| 402 | ||
| 403 | #[test] | |
| 404 | fn inline_macro_in_macro() { | |
| 405 | check_assist( | |
| 406 | inline_macro, | |
| 407 | r#" | |
| 408 | macro_rules! foo { () => { 2 }; } | |
| 409 | macro_rules! m { ($($tt:tt)*) => { $($tt)* }; } | |
| 410 | fn f() { m! { $0foo!(); } } | |
| 411 | "#, | |
| 412 | r#" | |
| 413 | macro_rules! foo { () => { 2 }; } | |
| 414 | macro_rules! m { ($($tt:tt)*) => { $($tt)* }; } | |
| 415 | fn f() { m! { 2; } } | |
| 416 | "#, | |
| 417 | ); | |
| 418 | check_assist( | |
| 419 | inline_macro, | |
| 420 | r#" | |
| 421 | //- proc_macros: identity | |
| 422 | macro_rules! foo { () => { 2 }; } | |
| 423 | #[proc_macros::identity] | |
| 424 | fn f() { $0foo!(); } | |
| 425 | "#, | |
| 426 | r#" | |
| 427 | macro_rules! foo { () => { 2 }; } | |
| 428 | #[proc_macros::identity] | |
| 429 | fn f() { 2; } | |
| 379 | 430 | "#, |
| 380 | 431 | ); |
| 381 | 432 | } |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs+76-1| ... | ... | @@ -135,7 +135,20 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_, '_>) |
| 135 | 135 | PathResolution::SelfType(imp) => { |
| 136 | 136 | concrete_type = imp.source(ctx.db())?.value.self_ty()?; |
| 137 | 137 | } |
| 138 | // FIXME: should also work in ADT definitions | |
| 138 | PathResolution::Def(hir::ModuleDef::Adt(adt)) => { | |
| 139 | let make = SyntaxFactory::without_mappings(); | |
| 140 | let src = adt.source(ctx.db())?.value; | |
| 141 | let name = src.name()?; | |
| 142 | let generic_params = src.generic_param_list(); | |
| 143 | let name_ref = make.name_ref(&name.text()); | |
| 144 | let segment = match generic_params { | |
| 145 | Some(params) => { | |
| 146 | make.path_segment_generics(name_ref, params.to_generic_args(&make)) | |
| 147 | } | |
| 148 | None => make.path_segment(name_ref), | |
| 149 | }; | |
| 150 | concrete_type = make.ty_path_from_segments([segment], false); | |
| 151 | } | |
| 139 | 152 | _ => return None, |
| 140 | 153 | } |
| 141 | 154 | |
| ... | ... | @@ -996,6 +1009,68 @@ trait Tr { |
| 996 | 1009 | ); |
| 997 | 1010 | } |
| 998 | 1011 | |
| 1012 | #[test] | |
| 1013 | fn inline_self_type_in_adt_definition() { | |
| 1014 | check_assist( | |
| 1015 | inline_type_alias, | |
| 1016 | r#" | |
| 1017 | enum Foo { | |
| 1018 | A(i32), | |
| 1019 | B(Box<Self$0>), | |
| 1020 | } | |
| 1021 | "#, | |
| 1022 | r#" | |
| 1023 | enum Foo { | |
| 1024 | A(i32), | |
| 1025 | B(Box<Foo>), | |
| 1026 | } | |
| 1027 | "#, | |
| 1028 | ); | |
| 1029 | check_assist( | |
| 1030 | inline_type_alias, | |
| 1031 | r#" | |
| 1032 | struct Foo { | |
| 1033 | a: Box<Self$0>, | |
| 1034 | } | |
| 1035 | "#, | |
| 1036 | r#" | |
| 1037 | struct Foo { | |
| 1038 | a: Box<Foo>, | |
| 1039 | } | |
| 1040 | "#, | |
| 1041 | ); | |
| 1042 | check_assist( | |
| 1043 | inline_type_alias, | |
| 1044 | r#" | |
| 1045 | struct Foo<T> { | |
| 1046 | a: T, | |
| 1047 | b: Box<Self$0>, | |
| 1048 | } | |
| 1049 | "#, | |
| 1050 | r#" | |
| 1051 | struct Foo<T> { | |
| 1052 | a: T, | |
| 1053 | b: Box<Foo<T>>, | |
| 1054 | } | |
| 1055 | "#, | |
| 1056 | ); | |
| 1057 | check_assist( | |
| 1058 | inline_type_alias, | |
| 1059 | r#" | |
| 1060 | union Foo { | |
| 1061 | a: u32, | |
| 1062 | b: std::mem::ManuallyDrop<Box<Self$0>>, | |
| 1063 | } | |
| 1064 | "#, | |
| 1065 | r#" | |
| 1066 | union Foo { | |
| 1067 | a: u32, | |
| 1068 | b: std::mem::ManuallyDrop<Box<Foo>>, | |
| 1069 | } | |
| 1070 | "#, | |
| 1071 | ); | |
| 1072 | } | |
| 1073 | ||
| 999 | 1074 | #[test] |
| 1000 | 1075 | fn inline_types_with_lifetime() { |
| 1001 | 1076 | check_assist( |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs+114-81| ... | ... | @@ -1,10 +1,12 @@ |
| 1 | use either::Either; | |
| 2 | 1 | use ide_db::imports::{ |
| 3 | 2 | insert_use::{ImportGranularity, InsertUseConfig}, |
| 4 | 3 | merge_imports::{MergeBehavior, try_merge_imports, try_merge_trees}, |
| 5 | 4 | }; |
| 6 | 5 | use syntax::{ |
| 7 | AstNode, SyntaxElement, SyntaxNode, algo::neighbor, ast, match_ast, syntax_editor::Removable, | |
| 6 | AstNode, SyntaxElement, | |
| 7 | algo::neighbor, | |
| 8 | ast, match_ast, | |
| 9 | syntax_editor::{Removable, SyntaxEditor}, | |
| 8 | 10 | }; |
| 9 | 11 | |
| 10 | 12 | use crate::{ |
| ... | ... | @@ -13,8 +15,6 @@ use crate::{ |
| 13 | 15 | utils::next_prev, |
| 14 | 16 | }; |
| 15 | 17 | |
| 16 | use Edit::*; | |
| 17 | ||
| 18 | 18 | // Assist: merge_imports |
| 19 | 19 | // |
| 20 | 20 | // Merges neighbor imports with a common prefix. |
| ... | ... | @@ -28,16 +28,17 @@ use Edit::*; |
| 28 | 28 | // use std::{fmt::Formatter, io}; |
| 29 | 29 | // ``` |
| 30 | 30 | pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> { |
| 31 | let (target, edits) = if ctx.has_empty_selection() { | |
| 31 | let (target, editor) = if ctx.has_empty_selection() { | |
| 32 | 32 | // Merge a neighbor |
| 33 | 33 | cov_mark::hit!(merge_with_use_item_neighbors); |
| 34 | 34 | let tree = ctx.find_node_at_offset::<ast::UseTree>()?.top_use_tree(); |
| 35 | 35 | let target = tree.syntax().text_range(); |
| 36 | 36 | |
| 37 | 37 | let use_item = tree.syntax().parent().and_then(ast::Use::cast)?; |
| 38 | let mut neighbor = next_prev().find_map(|dir| neighbor(&use_item, dir)).into_iter(); | |
| 39 | let edits = use_item.try_merge_from(&mut neighbor, &ctx.config.insert_use); | |
| 40 | (target, edits?) | |
| 38 | let neighbor = next_prev().find_map(|dir| neighbor(&use_item, dir))?; | |
| 39 | let (editor, _) = SyntaxEditor::new(use_item.syntax().parent()?.ancestors().last()?); | |
| 40 | merge_uses(use_item, vec![neighbor], &ctx.config.insert_use, &editor)?; | |
| 41 | (target, editor) | |
| 41 | 42 | } else { |
| 42 | 43 | // Merge selected |
| 43 | 44 | let selection_range = ctx.selection_trimmed(); |
| ... | ... | @@ -50,104 +51,80 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> O |
| 50 | 51 | }); |
| 51 | 52 | |
| 52 | 53 | let first_selected = selected_nodes.next()?; |
| 53 | let edits = match_ast! { | |
| 54 | let (editor, _) = SyntaxEditor::new(parent_node.ancestors().last().unwrap()); | |
| 55 | match_ast! { | |
| 54 | 56 | match first_selected { |
| 55 | 57 | ast::Use(use_item) => { |
| 56 | 58 | cov_mark::hit!(merge_with_selected_use_item_neighbors); |
| 57 | use_item.try_merge_from(&mut selected_nodes.filter_map(ast::Use::cast), &ctx.config.insert_use) | |
| 59 | merge_uses( | |
| 60 | use_item, | |
| 61 | selected_nodes.filter_map(ast::Use::cast).collect(), | |
| 62 | &ctx.config.insert_use, | |
| 63 | &editor, | |
| 64 | )?; | |
| 58 | 65 | }, |
| 59 | 66 | ast::UseTree(use_tree) => { |
| 60 | 67 | cov_mark::hit!(merge_with_selected_use_tree_neighbors); |
| 61 | use_tree.try_merge_from(&mut selected_nodes.filter_map(ast::UseTree::cast), &ctx.config.insert_use) | |
| 68 | merge_use_trees( | |
| 69 | use_tree, | |
| 70 | selected_nodes.filter_map(ast::UseTree::cast).collect(), | |
| 71 | &editor, | |
| 72 | )?; | |
| 62 | 73 | }, |
| 63 | 74 | _ => return None, |
| 64 | 75 | } |
| 65 | }; | |
| 66 | (selection_range, edits?) | |
| 67 | }; | |
| 68 | ||
| 69 | let parent_node = match ctx.covering_element() { | |
| 70 | SyntaxElement::Node(n) => n, | |
| 71 | SyntaxElement::Token(t) => t.parent()?, | |
| 76 | } | |
| 77 | (selection_range, editor) | |
| 72 | 78 | }; |
| 73 | 79 | |
| 74 | 80 | acc.add(AssistId::refactor_rewrite("merge_imports"), "Merge imports", target, |builder| { |
| 75 | let editor = builder.make_editor(&parent_node); | |
| 76 | ||
| 77 | for edit in edits { | |
| 78 | match edit { | |
| 79 | Remove(it) => { | |
| 80 | let node = it.as_ref(); | |
| 81 | if let Some(left) = node.left() { | |
| 82 | left.remove(&editor); | |
| 83 | } else if let Some(right) = node.right() { | |
| 84 | right.remove(&editor); | |
| 85 | } | |
| 86 | } | |
| 87 | Replace(old, new) => { | |
| 88 | editor.replace(old, &new); | |
| 89 | } | |
| 90 | } | |
| 91 | } | |
| 92 | 81 | builder.add_file_edits(ctx.vfs_file_id(), editor); |
| 93 | 82 | }) |
| 94 | 83 | } |
| 95 | 84 | |
| 96 | trait Merge: AstNode + Clone { | |
| 97 | fn try_merge_from( | |
| 98 | self, | |
| 99 | items: &mut dyn Iterator<Item = Self>, | |
| 100 | cfg: &InsertUseConfig, | |
| 101 | ) -> Option<Vec<Edit>> { | |
| 102 | let mut edits = Vec::new(); | |
| 103 | let mut merged = self.clone(); | |
| 104 | for item in items { | |
| 105 | merged = merged.try_merge(&item, cfg)?; | |
| 106 | edits.push(Edit::Remove(item.into_either())); | |
| 107 | } | |
| 108 | if !edits.is_empty() { | |
| 109 | edits.push(Edit::replace(self, merged)); | |
| 110 | Some(edits) | |
| 111 | } else { | |
| 112 | None | |
| 113 | } | |
| 85 | fn merge_uses( | |
| 86 | first: ast::Use, | |
| 87 | rest: Vec<ast::Use>, | |
| 88 | cfg: &InsertUseConfig, | |
| 89 | editor: &SyntaxEditor, | |
| 90 | ) -> Option<()> { | |
| 91 | if rest.is_empty() { | |
| 92 | return None; | |
| 114 | 93 | } |
| 115 | fn try_merge(&self, other: &Self, cfg: &InsertUseConfig) -> Option<Self>; | |
| 116 | fn into_either(self) -> Either<ast::Use, ast::UseTree>; | |
| 117 | } | |
| 118 | 94 | |
| 119 | impl Merge for ast::Use { | |
| 120 | fn try_merge(&self, other: &Self, cfg: &InsertUseConfig) -> Option<Self> { | |
| 121 | let mb = match cfg.granularity { | |
| 122 | ImportGranularity::One => MergeBehavior::One, | |
| 123 | _ => MergeBehavior::Crate, | |
| 124 | }; | |
| 125 | try_merge_imports(self, other, mb) | |
| 95 | let mb = match cfg.granularity { | |
| 96 | ImportGranularity::One => MergeBehavior::One, | |
| 97 | _ => MergeBehavior::Crate, | |
| 98 | }; | |
| 99 | let mut merged = first.clone(); | |
| 100 | for item in &rest { | |
| 101 | merged = try_merge_imports(editor.make(), &merged, item, mb)?; | |
| 126 | 102 | } |
| 127 | fn into_either(self) -> Either<ast::Use, ast::UseTree> { | |
| 128 | Either::Left(self) | |
| 103 | for item in rest { | |
| 104 | item.remove(editor); | |
| 129 | 105 | } |
| 106 | editor.replace(first.syntax(), merged.syntax()); | |
| 107 | Some(()) | |
| 130 | 108 | } |
| 131 | 109 | |
| 132 | impl Merge for ast::UseTree { | |
| 133 | fn try_merge(&self, other: &Self, _: &InsertUseConfig) -> Option<Self> { | |
| 134 | try_merge_trees(self, other, MergeBehavior::Crate) | |
| 110 | fn merge_use_trees( | |
| 111 | first: ast::UseTree, | |
| 112 | rest: Vec<ast::UseTree>, | |
| 113 | editor: &SyntaxEditor, | |
| 114 | ) -> Option<()> { | |
| 115 | if rest.is_empty() { | |
| 116 | return None; | |
| 135 | 117 | } |
| 136 | fn into_either(self) -> Either<ast::Use, ast::UseTree> { | |
| 137 | Either::Right(self) | |
| 138 | } | |
| 139 | } | |
| 140 | 118 | |
| 141 | #[derive(Debug)] | |
| 142 | enum Edit { | |
| 143 | Remove(Either<ast::Use, ast::UseTree>), | |
| 144 | Replace(SyntaxNode, SyntaxNode), | |
| 145 | } | |
| 146 | ||
| 147 | impl Edit { | |
| 148 | fn replace(old: impl AstNode, new: impl AstNode) -> Self { | |
| 149 | Edit::Replace(old.syntax().clone(), new.syntax().clone()) | |
| 119 | let mut merged = first.clone(); | |
| 120 | for item in &rest { | |
| 121 | merged = try_merge_trees(editor.make(), &merged, item, MergeBehavior::Crate)?; | |
| 122 | } | |
| 123 | for item in rest { | |
| 124 | item.remove(editor); | |
| 150 | 125 | } |
| 126 | editor.replace(first.syntax(), merged.syntax()); | |
| 127 | Some(()) | |
| 151 | 128 | } |
| 152 | 129 | |
| 153 | 130 | #[cfg(test)] |
| ... | ... | @@ -558,6 +535,62 @@ use foo::{bar, baz}; |
| 558 | 535 | ); |
| 559 | 536 | } |
| 560 | 537 | |
| 538 | #[test] | |
| 539 | fn mod_indent_whitespace() { | |
| 540 | check_assist( | |
| 541 | merge_imports, | |
| 542 | r" | |
| 543 | mod tests { | |
| 544 | use foo$0::bar; | |
| 545 | use foo::baz; | |
| 546 | fn feature() {} | |
| 547 | } | |
| 548 | ", | |
| 549 | r" | |
| 550 | mod tests { | |
| 551 | use foo::{bar, baz}; | |
| 552 | fn feature() {} | |
| 553 | } | |
| 554 | ", | |
| 555 | ); | |
| 556 | check_assist( | |
| 557 | merge_imports, | |
| 558 | r" | |
| 559 | mod tests { | |
| 560 | use foo$0::bar; | |
| 561 | use foo::baz; | |
| 562 | ||
| 563 | fn feature() {} | |
| 564 | } | |
| 565 | ", | |
| 566 | r" | |
| 567 | mod tests { | |
| 568 | use foo::{bar, baz}; | |
| 569 | ||
| 570 | fn feature() {} | |
| 571 | } | |
| 572 | ", | |
| 573 | ); | |
| 574 | check_assist( | |
| 575 | merge_imports, | |
| 576 | r" | |
| 577 | mod tests { | |
| 578 | use foo::bar; | |
| 579 | use foo$0::baz; | |
| 580 | ||
| 581 | fn feature() {} | |
| 582 | } | |
| 583 | ", | |
| 584 | r" | |
| 585 | mod tests { | |
| 586 | use foo::{bar, baz}; | |
| 587 | ||
| 588 | fn feature() {} | |
| 589 | } | |
| 590 | ", | |
| 591 | ); | |
| 592 | } | |
| 593 | ||
| 561 | 594 | #[test] |
| 562 | 595 | fn works_with_trailing_comma() { |
| 563 | 596 | check_assist( |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/normalize_import.rs+5-3| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | use ide_db::imports::merge_imports::try_normalize_import; |
| 2 | use syntax::{AstNode, ast}; | |
| 2 | use syntax::{AstNode, ast, syntax_editor::SyntaxEditor}; | |
| 3 | 3 | |
| 4 | 4 | use crate::{ |
| 5 | 5 | AssistId, |
| ... | ... | @@ -25,11 +25,13 @@ pub(crate) fn normalize_import(acc: &mut Assists, ctx: &AssistContext<'_, '_>) - |
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | 27 | let target = use_item.syntax().text_range(); |
| 28 | let (editor, _) = SyntaxEditor::new(use_item.syntax().ancestors().last().unwrap()); | |
| 28 | 29 | let normalized_use_item = |
| 29 | try_normalize_import(&use_item, ctx.config.insert_use.granularity.into())?; | |
| 30 | try_normalize_import(editor.make(), &use_item, ctx.config.insert_use.granularity.into())?; | |
| 31 | editor.replace(use_item.syntax(), normalized_use_item.syntax()); | |
| 30 | 32 | |
| 31 | 33 | acc.add(AssistId::refactor_rewrite("normalize_import"), "Normalize import", target, |builder| { |
| 32 | builder.replace_ast(use_item, normalized_use_item); | |
| 34 | builder.add_file_edits(ctx.vfs_file_id(), editor); | |
| 33 | 35 | }) |
| 34 | 36 | } |
| 35 | 37 |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs+70-9| ... | ... | @@ -17,7 +17,7 @@ use crate::{ |
| 17 | 17 | AssistContext, AssistId, Assists, |
| 18 | 18 | utils::{ |
| 19 | 19 | does_pat_match_variant, does_pat_variant_nested_or_literal, unwrap_trivial_block, |
| 20 | wrap_paren, | |
| 20 | wrap_paren_in_guard_chain, | |
| 21 | 21 | }, |
| 22 | 22 | }; |
| 23 | 23 | |
| ... | ... | @@ -303,7 +303,7 @@ pub(crate) fn replace_match_with_if_let( |
| 303 | 303 | _ => make.expr_let(if_let_pat, scrutinee).into(), |
| 304 | 304 | }; |
| 305 | 305 | let condition = if let Some(guard) = guard { |
| 306 | let guard = wrap_paren(guard, make, ast::prec::ExprPrecedence::LAnd); | |
| 306 | let guard = wrap_paren_in_guard_chain(guard, make); | |
| 307 | 307 | make.expr_bin(condition, ast::BinaryOp::LogicOp(ast::LogicOp::And), guard).into() |
| 308 | 308 | } else { |
| 309 | 309 | condition |
| ... | ... | @@ -712,13 +712,11 @@ impl VariantData { |
| 712 | 712 | check_assist( |
| 713 | 713 | replace_if_let_with_match, |
| 714 | 714 | r#" |
| 715 | #![feature(if_let_guard)] | |
| 716 | 715 | fn main() { |
| 717 | 716 | if $0let true = true && let Some(1) = None {} else { other() } |
| 718 | 717 | } |
| 719 | 718 | "#, |
| 720 | 719 | r#" |
| 721 | #![feature(if_let_guard)] | |
| 722 | 720 | fn main() { |
| 723 | 721 | match true { |
| 724 | 722 | true if let Some(1) = None => {} |
| ... | ... | @@ -731,7 +729,6 @@ fn main() { |
| 731 | 729 | check_assist( |
| 732 | 730 | replace_if_let_with_match, |
| 733 | 731 | r#" |
| 734 | #![feature(if_let_guard)] | |
| 735 | 732 | fn main() { |
| 736 | 733 | if true { |
| 737 | 734 | $0if let ParenExpr(expr) = cond |
| ... | ... | @@ -758,7 +755,6 @@ fn main() { |
| 758 | 755 | } |
| 759 | 756 | "#, |
| 760 | 757 | r#" |
| 761 | #![feature(if_let_guard)] | |
| 762 | 758 | fn main() { |
| 763 | 759 | if true { |
| 764 | 760 | match cond { |
| ... | ... | @@ -816,13 +812,11 @@ fn main() { |
| 816 | 812 | check_assist( |
| 817 | 813 | replace_if_let_with_match, |
| 818 | 814 | r#" |
| 819 | #![feature(if_let_guard)] | |
| 820 | 815 | fn main() { |
| 821 | 816 | if $0let true = true && let Some(1) = None {} |
| 822 | 817 | } |
| 823 | 818 | "#, |
| 824 | 819 | r#" |
| 825 | #![feature(if_let_guard)] | |
| 826 | 820 | fn main() { |
| 827 | 821 | match true { |
| 828 | 822 | true if let Some(1) = None => {} |
| ... | ... | @@ -2460,7 +2454,7 @@ fn main() { |
| 2460 | 2454 | } |
| 2461 | 2455 | |
| 2462 | 2456 | #[test] |
| 2463 | fn test_replace_match_with_if_let_chain() { | |
| 2457 | fn test_replace_match_with_if_let_with_simple_guard() { | |
| 2464 | 2458 | check_assist( |
| 2465 | 2459 | replace_match_with_if_let, |
| 2466 | 2460 | r#" |
| ... | ... | @@ -2504,6 +2498,73 @@ fn main() { |
| 2504 | 2498 | ); |
| 2505 | 2499 | } |
| 2506 | 2500 | |
| 2501 | #[test] | |
| 2502 | fn test_replace_match_with_if_let_with_if_let_guard() { | |
| 2503 | check_assist( | |
| 2504 | replace_match_with_if_let, | |
| 2505 | r#" | |
| 2506 | fn main() { | |
| 2507 | match$0 Some(0) { | |
| 2508 | Some(n) if let Some(m) = n.checked_add(1) => (), | |
| 2509 | _ => code(), | |
| 2510 | } | |
| 2511 | } | |
| 2512 | "#, | |
| 2513 | r#" | |
| 2514 | fn main() { | |
| 2515 | if let Some(n) = Some(0) && let Some(m) = n.checked_add(1) { | |
| 2516 | () | |
| 2517 | } else { | |
| 2518 | code() | |
| 2519 | } | |
| 2520 | } | |
| 2521 | "#, | |
| 2522 | ); | |
| 2523 | ||
| 2524 | check_assist( | |
| 2525 | replace_match_with_if_let, | |
| 2526 | r#" | |
| 2527 | fn main() { | |
| 2528 | match$0 Some(0) { | |
| 2529 | Some(n) if let Some(m) = n.checked_add(1) && m > 5 => (), | |
| 2530 | _ => code(), | |
| 2531 | } | |
| 2532 | } | |
| 2533 | "#, | |
| 2534 | r#" | |
| 2535 | fn main() { | |
| 2536 | if let Some(n) = Some(0) && let Some(m) = n.checked_add(1) && m > 5 { | |
| 2537 | () | |
| 2538 | } else { | |
| 2539 | code() | |
| 2540 | } | |
| 2541 | } | |
| 2542 | "#, | |
| 2543 | ); | |
| 2544 | ||
| 2545 | // what if the `let` expr is not the first one in the guard? | |
| 2546 | check_assist( | |
| 2547 | replace_match_with_if_let, | |
| 2548 | r#" | |
| 2549 | fn main() { | |
| 2550 | match$0 Some(0) { | |
| 2551 | Some(n) if n > 5 && let Some(m) = n.checked_add(1) => (), | |
| 2552 | _ => code(), | |
| 2553 | } | |
| 2554 | } | |
| 2555 | "#, | |
| 2556 | r#" | |
| 2557 | fn main() { | |
| 2558 | if let Some(n) = Some(0) && n > 5 && let Some(m) = n.checked_add(1) { | |
| 2559 | () | |
| 2560 | } else { | |
| 2561 | code() | |
| 2562 | } | |
| 2563 | } | |
| 2564 | "#, | |
| 2565 | ); | |
| 2566 | } | |
| 2567 | ||
| 2507 | 2568 | #[test] |
| 2508 | 2569 | fn test_replace_match_with_if_let_not_applicable_pat2_is_ident_pat() { |
| 2509 | 2570 | check_assist_not_applicable( |
src/tools/rust-analyzer/crates/ide-assists/src/utils.rs+29| ... | ... | @@ -110,6 +110,26 @@ fn needs_parens_in_call(make: &SyntaxFactory, param: &ast::Expr) -> bool { |
| 110 | 110 | param.needs_parens_in_place_of(call.syntax(), callable.syntax()) |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | pub(crate) fn wrap_paren_in_guard_chain(guard: ast::Expr, make: &SyntaxFactory) -> ast::Expr { | |
| 114 | if needs_parens_in_guard_chain(make, &guard) { make.expr_paren(guard).into() } else { guard } | |
| 115 | } | |
| 116 | ||
| 117 | fn needs_parens_in_guard_chain(make: &SyntaxFactory, guard: &ast::Expr) -> bool { | |
| 118 | let ast::Expr::BinExpr(if_let_and_guard) = make.expr_bin_op( | |
| 119 | make.expr_unit(), | |
| 120 | ast::BinaryOp::LogicOp(ast::LogicOp::And), | |
| 121 | make.expr_unit(), | |
| 122 | ) else { | |
| 123 | stdx::never!("`SyntaxFactory::expr_bin_op` returns a `BinExpr`"); | |
| 124 | return false; | |
| 125 | }; | |
| 126 | let Some(fake_guard) = if_let_and_guard.rhs() else { | |
| 127 | stdx::never!("invalid make call"); | |
| 128 | return false; | |
| 129 | }; | |
| 130 | guard.needs_parens_in_place_of(if_let_and_guard.syntax(), fake_guard.syntax()) | |
| 131 | } | |
| 132 | ||
| 113 | 133 | /// This is a method with a heuristics to support test methods annotated with custom test annotations, such as |
| 114 | 134 | /// `#[test_case(...)]`, `#[tokio::test]` and similar. |
| 115 | 135 | /// Also a regular `#[test]` annotation is supported. |
| ... | ... | @@ -1177,6 +1197,15 @@ pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bo |
| 1177 | 1197 | is_const |
| 1178 | 1198 | } |
| 1179 | 1199 | |
| 1200 | pub(crate) fn original_range_in( | |
| 1201 | file_id: hir::EditionedFileId, | |
| 1202 | sema: &Semantics<'_, RootDatabase>, | |
| 1203 | value: &SyntaxNode, | |
| 1204 | ) -> Option<TextRange> { | |
| 1205 | let original = sema.original_range_opt(value)?; | |
| 1206 | (original.file_id == file_id).then_some(original.range) | |
| 1207 | } | |
| 1208 | ||
| 1180 | 1209 | // FIXME: #20460 When hir-ty can analyze the `never` statement at the end of block, remove it |
| 1181 | 1210 | pub(crate) fn is_never_block( |
| 1182 | 1211 | sema: &Semantics<'_, RootDatabase>, |
src/tools/rust-analyzer/crates/ide-completion/src/config.rs+1| ... | ... | @@ -45,6 +45,7 @@ pub enum AutoImportExclusionType { |
| 45 | 45 | Always, |
| 46 | 46 | Methods, |
| 47 | 47 | SubItems, |
| 48 | Variants, | |
| 48 | 49 | } |
| 49 | 50 | |
| 50 | 51 | #[derive(Clone, Debug, PartialEq, Eq)] |
src/tools/rust-analyzer/crates/ide-completion/src/context.rs+12| ... | ... | @@ -868,10 +868,22 @@ impl<'a, 'db> CompletionContext<'a, 'db> { |
| 868 | 868 | _ => None, |
| 869 | 869 | }) |
| 870 | 870 | .collect::<Vec<_>>(); |
| 871 | let exclude_variants = exclude_flyimport | |
| 872 | .iter() | |
| 873 | .flat_map(|it| match it { | |
| 874 | (ModuleDef::Adt(hir::Adt::Enum(enum_)), AutoImportExclusionType::Variants) => { | |
| 875 | enum_.variants(db) | |
| 876 | } | |
| 877 | _ => vec![], | |
| 878 | }) | |
| 879 | .collect::<Vec<_>>(); | |
| 871 | 880 | exclude_flyimport |
| 872 | 881 | .extend(exclude_traits.iter().map(|&t| (t.into(), AutoImportExclusionType::Always))); |
| 873 | 882 | exclude_flyimport |
| 874 | 883 | .extend(exclude_subitems.into_iter().map(|it| (it, AutoImportExclusionType::Always))); |
| 884 | exclude_flyimport.extend( | |
| 885 | exclude_variants.into_iter().map(|it| (it.into(), AutoImportExclusionType::Always)), | |
| 886 | ); | |
| 875 | 887 | |
| 876 | 888 | // FIXME: This should be part of `CompletionAnalysis` / `expand_and_analyze` |
| 877 | 889 | let complete_semicolon = if !config.add_semicolon_to_unit { |
src/tools/rust-analyzer/crates/ide-completion/src/render.rs+1-1| ... | ... | @@ -2372,7 +2372,7 @@ impl S { |
| 2372 | 2372 | } |
| 2373 | 2373 | fn foo(s: S) { s.$0 } |
| 2374 | 2374 | "#, |
| 2375 | CompletionItemKind::SymbolKind(SymbolKind::Method), | |
| 2375 | SymbolKind::Method, | |
| 2376 | 2376 | expect![[r#" |
| 2377 | 2377 | [ |
| 2378 | 2378 | CompletionItem { |
src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs+98| ... | ... | @@ -3041,6 +3041,76 @@ fn foo() { |
| 3041 | 3041 | ); |
| 3042 | 3042 | } |
| 3043 | 3043 | |
| 3044 | #[test] | |
| 3045 | fn flyimport_excluded_enum_variants_from_flyimport() { | |
| 3046 | check_with_config( | |
| 3047 | CompletionConfig { | |
| 3048 | exclude_flyimport: vec![( | |
| 3049 | "ra_test_fixture::Foo".to_owned(), | |
| 3050 | AutoImportExclusionType::Variants, | |
| 3051 | )], | |
| 3052 | ..TEST_CONFIG | |
| 3053 | }, | |
| 3054 | r#" | |
| 3055 | enum Foo { | |
| 3056 | Variant1, | |
| 3057 | Variant2, | |
| 3058 | } | |
| 3059 | fn foo() { | |
| 3060 | V$0 | |
| 3061 | } | |
| 3062 | "#, | |
| 3063 | expect![[r#" | |
| 3064 | ct CONST Unit | |
| 3065 | en Enum Enum | |
| 3066 | en Foo Foo | |
| 3067 | fn foo() fn() | |
| 3068 | fn function() fn() | |
| 3069 | ma makro!(…) macro_rules! makro | |
| 3070 | md module:: | |
| 3071 | sc STATIC Unit | |
| 3072 | st Record Record | |
| 3073 | st Tuple Tuple | |
| 3074 | st Unit Unit | |
| 3075 | un Union Union | |
| 3076 | ev TupleV(…) TupleV(u32) | |
| 3077 | bt u32 u32 | |
| 3078 | kw async | |
| 3079 | kw const | |
| 3080 | kw crate:: | |
| 3081 | kw enum | |
| 3082 | kw extern | |
| 3083 | kw false | |
| 3084 | kw fn | |
| 3085 | kw for | |
| 3086 | kw if | |
| 3087 | kw if let | |
| 3088 | kw impl | |
| 3089 | kw impl for | |
| 3090 | kw let | |
| 3091 | kw letm | |
| 3092 | kw loop | |
| 3093 | kw match | |
| 3094 | kw mod | |
| 3095 | kw return | |
| 3096 | kw self:: | |
| 3097 | kw static | |
| 3098 | kw struct | |
| 3099 | kw trait | |
| 3100 | kw true | |
| 3101 | kw type | |
| 3102 | kw union | |
| 3103 | kw unsafe | |
| 3104 | kw use | |
| 3105 | kw while | |
| 3106 | kw while let | |
| 3107 | sn macro_rules | |
| 3108 | sn pd | |
| 3109 | sn ppd | |
| 3110 | "#]], | |
| 3111 | ); | |
| 3112 | } | |
| 3113 | ||
| 3044 | 3114 | #[test] |
| 3045 | 3115 | fn excluded_trait_method_is_excluded_from_path_completion() { |
| 3046 | 3116 | check_with_config( |
| ... | ... | @@ -4109,3 +4179,31 @@ fn main() { |
| 4109 | 4179 | "#]], |
| 4110 | 4180 | ); |
| 4111 | 4181 | } |
| 4182 | ||
| 4183 | #[test] | |
| 4184 | fn no_await_on_error_type() { | |
| 4185 | check( | |
| 4186 | r#" | |
| 4187 | //- minicore: future | |
| 4188 | fn foo(t: T) { | |
| 4189 | let _ = t.$0; | |
| 4190 | } | |
| 4191 | "#, | |
| 4192 | expect![[r#" | |
| 4193 | sn box Box::new(expr) | |
| 4194 | sn call function(expr) | |
| 4195 | sn const const {} | |
| 4196 | sn dbg dbg!(expr) | |
| 4197 | sn dbgr dbg!(&expr) | |
| 4198 | sn deref *expr | |
| 4199 | sn if if expr {} | |
| 4200 | sn match match expr {} | |
| 4201 | sn not !expr | |
| 4202 | sn ref &expr | |
| 4203 | sn refm &mut expr | |
| 4204 | sn return return expr | |
| 4205 | sn unsafe unsafe {} | |
| 4206 | sn while while expr {} | |
| 4207 | "#]], | |
| 4208 | ); | |
| 4209 | } |
src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs+6-1| ... | ... | @@ -1,16 +1,21 @@ |
| 1 | 1 | //! Applies changes to the IDE state transactionally. |
| 2 | 2 | |
| 3 | use std::time::{Duration, Instant}; | |
| 4 | ||
| 3 | 5 | use profile::Bytes; |
| 4 | 6 | use salsa::Database as _; |
| 5 | 7 | |
| 6 | 8 | use crate::{ChangeWithProcMacros, RootDatabase}; |
| 7 | 9 | |
| 8 | 10 | impl RootDatabase { |
| 9 | pub fn apply_change(&mut self, change: ChangeWithProcMacros) { | |
| 11 | pub fn apply_change(&mut self, change: ChangeWithProcMacros) -> Duration { | |
| 10 | 12 | let _p = tracing::info_span!("RootDatabase::apply_change").entered(); |
| 13 | let now = Instant::now(); | |
| 11 | 14 | self.trigger_cancellation(); |
| 15 | let elapsed = now.elapsed(); | |
| 12 | 16 | tracing::trace!("apply_change {:?}", change); |
| 13 | 17 | change.apply(self); |
| 18 | elapsed | |
| 14 | 19 | } |
| 15 | 20 | |
| 16 | 21 | // Feature: Memory Usage |
src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs+5-3| ... | ... | @@ -17,7 +17,7 @@ use crate::{ |
| 17 | 17 | RootDatabase, |
| 18 | 18 | imports::merge_imports::{ |
| 19 | 19 | MergeBehavior, NormalizationStyle, common_prefix, eq_attrs, eq_visibility, |
| 20 | try_merge_imports, use_tree_cmp, | |
| 20 | try_merge_imports, use_tree_cmp, wrap_in_tree_list, | |
| 21 | 21 | }, |
| 22 | 22 | }; |
| 23 | 23 | |
| ... | ... | @@ -251,7 +251,7 @@ fn insert_use_with_alias_option_with_editor( |
| 251 | 251 | let mut use_tree = make.use_tree(path, None, alias, false); |
| 252 | 252 | if mb == Some(MergeBehavior::One) |
| 253 | 253 | && use_tree.path().is_some() |
| 254 | && let Some(wrapped) = use_tree.wrap_in_tree_list_with_editor() | |
| 254 | && let Some(wrapped) = wrap_in_tree_list(&use_tree, make) | |
| 255 | 255 | { |
| 256 | 256 | use_tree = wrapped; |
| 257 | 257 | } |
| ... | ... | @@ -263,7 +263,9 @@ fn insert_use_with_alias_option_with_editor( |
| 263 | 263 | for existing_use in |
| 264 | 264 | scope.as_syntax_node().children().filter_map(ast::Use::cast).filter(filter) |
| 265 | 265 | { |
| 266 | if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { | |
| 266 | if let Some(merged) = | |
| 267 | try_merge_imports(syntax_editor.make(), &existing_use, &use_item, mb) | |
| 268 | { | |
| 267 | 269 | syntax_editor.replace(existing_use.syntax(), merged.syntax()); |
| 268 | 270 | return; |
| 269 | 271 | } |
src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs+7-3| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | use stdx::trim_indent; |
| 2 | use syntax::ast::syntax_factory::SyntaxFactory; | |
| 2 | 3 | use test_fixture::WithFixture; |
| 3 | 4 | use test_utils::{CURSOR_MARKER, assert_eq_text}; |
| 4 | 5 | |
| ... | ... | @@ -1430,7 +1431,8 @@ fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior |
| 1430 | 1431 | .find_map(ast::Use::cast) |
| 1431 | 1432 | .unwrap(); |
| 1432 | 1433 | |
| 1433 | let result = try_merge_imports(&use0, &use1, mb); | |
| 1434 | let make = SyntaxFactory::without_mappings(); | |
| 1435 | let result = try_merge_imports(&make, &use0, &use1, mb); | |
| 1434 | 1436 | assert_eq!(result.map(|u| u.to_string()), None); |
| 1435 | 1437 | } |
| 1436 | 1438 | |
| ... | ... | @@ -1495,7 +1497,8 @@ fn check_merge(ra_fixture0: &str, ra_fixture1: &str, last: &str, mb: MergeBehavi |
| 1495 | 1497 | .find_map(ast::Use::cast) |
| 1496 | 1498 | .unwrap(); |
| 1497 | 1499 | |
| 1498 | let result = try_merge_imports(&use0, &use1, mb); | |
| 1500 | let make = SyntaxFactory::without_mappings(); | |
| 1501 | let result = try_merge_imports(&make, &use0, &use1, mb); | |
| 1499 | 1502 | assert_eq!(result.map(|u| u.to_string().trim().to_owned()), Some(last.trim().to_owned())); |
| 1500 | 1503 | } |
| 1501 | 1504 | |
| ... | ... | @@ -1525,7 +1528,8 @@ fn merge_gated_imports_with_different_values() { |
| 1525 | 1528 | .find_map(ast::Use::cast) |
| 1526 | 1529 | .unwrap(); |
| 1527 | 1530 | |
| 1528 | let result = try_merge_imports(&use0, &use1, MergeBehavior::Crate); | |
| 1531 | let make = SyntaxFactory::without_mappings(); | |
| 1532 | let result = try_merge_imports(&make, &use0, &use1, MergeBehavior::Crate); | |
| 1529 | 1533 | assert_eq!(result, None); |
| 1530 | 1534 | } |
| 1531 | 1535 |
src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs+397-267| ... | ... | @@ -4,12 +4,12 @@ use std::cmp::Ordering; |
| 4 | 4 | use itertools::{EitherOrBoth, Itertools}; |
| 5 | 5 | use parser::T; |
| 6 | 6 | use syntax::{ |
| 7 | Direction, SyntaxElement, ToSmolStr, algo, | |
| 7 | ToSmolStr, | |
| 8 | 8 | ast::{ |
| 9 | self, AstNode, HasAttrs, HasName, HasVisibility, PathSegmentKind, edit_in_place::Removable, | |
| 10 | make, | |
| 9 | self, AstNode, HasAttrs, HasName, HasVisibility, PathSegmentKind, | |
| 10 | syntax_factory::SyntaxFactory, | |
| 11 | 11 | }, |
| 12 | ted::{self, Position}, | |
| 12 | syntax_editor::{Position, SyntaxEditor}, | |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | 15 | use crate::syntax_helpers::node_ext::vis_eq; |
| ... | ... | @@ -39,8 +39,8 @@ impl MergeBehavior { |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | /// Merge `rhs` into `lhs` keeping both intact. |
| 42 | /// Returned AST is mutable. | |
| 43 | 42 | pub fn try_merge_imports( |
| 43 | make: &SyntaxFactory, | |
| 44 | 44 | lhs: &ast::Use, |
| 45 | 45 | rhs: &ast::Use, |
| 46 | 46 | merge_behavior: MergeBehavior, |
| ... | ... | @@ -53,39 +53,39 @@ pub fn try_merge_imports( |
| 53 | 53 | return None; |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | let lhs = lhs.clone_subtree().clone_for_update(); | |
| 57 | let rhs = rhs.clone_subtree().clone_for_update(); | |
| 58 | 56 | let lhs_tree = lhs.use_tree()?; |
| 59 | 57 | let rhs_tree = rhs.use_tree()?; |
| 60 | try_merge_trees_mut(&lhs_tree, &rhs_tree, merge_behavior)?; | |
| 58 | let merged_tree = try_merge_trees_with_factory(lhs_tree, rhs_tree, merge_behavior, make)?; | |
| 61 | 59 | |
| 62 | 60 | // Ignore `None` result because normalization should not affect the merge result. |
| 63 | try_normalize_use_tree_mut(&lhs_tree, merge_behavior.into()); | |
| 61 | let use_tree = try_normalize_use_tree(merged_tree.clone(), merge_behavior.into(), make) | |
| 62 | .unwrap_or(merged_tree); | |
| 64 | 63 | |
| 65 | Some(lhs) | |
| 64 | make_use_with_tree(lhs, use_tree) | |
| 66 | 65 | } |
| 67 | 66 | |
| 68 | 67 | /// Merge `rhs` into `lhs` keeping both intact. |
| 69 | /// Returned AST is mutable. | |
| 70 | 68 | pub fn try_merge_trees( |
| 69 | make: &SyntaxFactory, | |
| 71 | 70 | lhs: &ast::UseTree, |
| 72 | 71 | rhs: &ast::UseTree, |
| 73 | 72 | merge: MergeBehavior, |
| 74 | 73 | ) -> Option<ast::UseTree> { |
| 75 | let lhs = lhs.clone_subtree().clone_for_update(); | |
| 76 | let rhs = rhs.clone_subtree().clone_for_update(); | |
| 77 | try_merge_trees_mut(&lhs, &rhs, merge)?; | |
| 74 | let merged = try_merge_trees_with_factory(lhs.clone(), rhs.clone(), merge, make)?; | |
| 78 | 75 | |
| 79 | 76 | // Ignore `None` result because normalization should not affect the merge result. |
| 80 | try_normalize_use_tree_mut(&lhs, merge.into()); | |
| 81 | ||
| 82 | Some(lhs) | |
| 77 | Some(try_normalize_use_tree(merged.clone(), merge.into(), make).unwrap_or(merged)) | |
| 83 | 78 | } |
| 84 | 79 | |
| 85 | fn try_merge_trees_mut(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior) -> Option<()> { | |
| 80 | fn try_merge_trees_with_factory( | |
| 81 | mut lhs: ast::UseTree, | |
| 82 | mut rhs: ast::UseTree, | |
| 83 | merge: MergeBehavior, | |
| 84 | make: &SyntaxFactory, | |
| 85 | ) -> Option<ast::UseTree> { | |
| 86 | 86 | if merge == MergeBehavior::One { |
| 87 | lhs.wrap_in_tree_list(); | |
| 88 | rhs.wrap_in_tree_list(); | |
| 87 | lhs = wrap_in_tree_list(&lhs, make).unwrap_or(lhs); | |
| 88 | rhs = wrap_in_tree_list(&rhs, make).unwrap_or(rhs); | |
| 89 | 89 | } else { |
| 90 | 90 | let lhs_path = lhs.path()?; |
| 91 | 91 | let rhs_path = rhs.path()?; |
| ... | ... | @@ -100,46 +100,53 @@ fn try_merge_trees_mut(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehav |
| 100 | 100 | // and we can safely return here |
| 101 | 101 | let lhs_name = lhs.rename().and_then(|lhs_name| lhs_name.name()); |
| 102 | 102 | let rhs_name = rhs.rename().and_then(|rhs_name| rhs_name.name()); |
| 103 | if lhs_name != rhs_name { | |
| 103 | if lhs_name.as_ref().map(|name| name.text()) | |
| 104 | != rhs_name.as_ref().map(|name| name.text()) | |
| 105 | { | |
| 104 | 106 | return None; |
| 105 | 107 | } |
| 106 | 108 | |
| 107 | ted::replace(lhs.syntax(), rhs.syntax()); | |
| 108 | // we can safely return here, in this case `recursive_merge` doesn't do anything | |
| 109 | return Some(()); | |
| 109 | return Some(rhs); | |
| 110 | 110 | } else { |
| 111 | lhs.split_prefix(&lhs_prefix); | |
| 112 | rhs.split_prefix(&rhs_prefix); | |
| 111 | lhs = split_prefix(&lhs, &lhs_prefix, make)?; | |
| 112 | rhs = split_prefix(&rhs, &rhs_prefix, make)?; | |
| 113 | 113 | } |
| 114 | 114 | } |
| 115 | recursive_merge(lhs, rhs, merge) | |
| 115 | recursive_merge(lhs, rhs, merge, make) | |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | /// Recursively merges rhs to lhs |
| 119 | 119 | #[must_use] |
| 120 | fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior) -> Option<()> { | |
| 120 | fn recursive_merge( | |
| 121 | lhs: ast::UseTree, | |
| 122 | rhs: ast::UseTree, | |
| 123 | merge: MergeBehavior, | |
| 124 | make: &SyntaxFactory, | |
| 125 | ) -> Option<ast::UseTree> { | |
| 121 | 126 | let mut use_trees: Vec<ast::UseTree> = lhs |
| 122 | .use_tree_list() | |
| 123 | .into_iter() | |
| 124 | .flat_map(|list| list.use_trees()) | |
| 125 | // We use Option here to early return from this function(this is not the | |
| 126 | // same as a `filter` op). | |
| 127 | .use_tree_list()? | |
| 128 | .use_trees() | |
| 129 | // We use Option here to early return from this function. This is not the | |
| 130 | // same as a `filter` op. | |
| 127 | 131 | .map(|tree| merge.is_tree_allowed(&tree).then_some(tree)) |
| 128 | 132 | .collect::<Option<_>>()?; |
| 133 | ||
| 129 | 134 | // Sorts the use trees similar to rustfmt's algorithm for ordering imports |
| 130 | 135 | // (see `use_tree_cmp` doc). |
| 131 | 136 | use_trees.sort_unstable_by(use_tree_cmp); |
| 132 | for rhs_t in rhs.use_tree_list().into_iter().flat_map(|list| list.use_trees()) { | |
| 137 | ||
| 138 | for rhs_t in rhs.use_tree_list()?.use_trees() { | |
| 133 | 139 | if !merge.is_tree_allowed(&rhs_t) { |
| 134 | 140 | return None; |
| 135 | 141 | } |
| 136 | 142 | |
| 137 | 143 | match use_trees.binary_search_by(|lhs_t| use_tree_cmp_bin_search(lhs_t, &rhs_t)) { |
| 138 | 144 | Ok(idx) => { |
| 139 | let lhs_t = &mut use_trees[idx]; | |
| 145 | let mut lhs_t = use_trees[idx].clone(); | |
| 140 | 146 | let lhs_path = lhs_t.path()?; |
| 141 | 147 | let rhs_path = rhs_t.path()?; |
| 142 | 148 | let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?; |
| 149 | ||
| 143 | 150 | if lhs_prefix == lhs_path && rhs_prefix == rhs_path { |
| 144 | 151 | let tree_is_self = |tree: &ast::UseTree| { |
| 145 | 152 | tree.path().as_ref().map(path_is_self).unwrap_or(false) |
| ... | ... | @@ -157,20 +164,20 @@ fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior) |
| 157 | 164 | }; |
| 158 | 165 | |
| 159 | 166 | if lhs_t.rename().and_then(|x| x.underscore_token()).is_some() { |
| 160 | ted::replace(lhs_t.syntax(), rhs_t.syntax()); | |
| 161 | *lhs_t = rhs_t; | |
| 167 | use_trees[idx] = rhs_t; | |
| 162 | 168 | continue; |
| 163 | 169 | } |
| 164 | 170 | |
| 165 | match (tree_contains_self(lhs_t), tree_contains_self(&rhs_t)) { | |
| 171 | match (tree_contains_self(&lhs_t), tree_contains_self(&rhs_t)) { | |
| 166 | 172 | (Some(true), None) => { |
| 167 | remove_subtree_if_only_self(lhs_t); | |
| 173 | lhs_t = remove_subtree_if_only_self(lhs_t, make)?; | |
| 174 | use_trees[idx] = lhs_t; | |
| 168 | 175 | continue; |
| 169 | 176 | } |
| 170 | 177 | (None, Some(true)) => { |
| 171 | ted::replace(lhs_t.syntax(), rhs_t.syntax()); | |
| 172 | *lhs_t = rhs_t; | |
| 173 | remove_subtree_if_only_self(lhs_t); | |
| 178 | lhs_t = rhs_t; | |
| 179 | lhs_t = remove_subtree_if_only_self(lhs_t, make)?; | |
| 180 | use_trees[idx] = lhs_t; | |
| 174 | 181 | continue; |
| 175 | 182 | } |
| 176 | 183 | _ => (), |
| ... | ... | @@ -180,9 +187,11 @@ fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior) |
| 180 | 187 | continue; |
| 181 | 188 | } |
| 182 | 189 | } |
| 183 | lhs_t.split_prefix(&lhs_prefix); | |
| 184 | rhs_t.split_prefix(&rhs_prefix); | |
| 185 | recursive_merge(lhs_t, &rhs_t, merge)?; | |
| 190 | ||
| 191 | lhs_t = split_prefix(&lhs_t, &lhs_prefix, make)?; | |
| 192 | let rhs_t = split_prefix(&rhs_t, &rhs_prefix, make)?; | |
| 193 | lhs_t = recursive_merge(lhs_t, rhs_t, merge, make)?; | |
| 194 | use_trees[idx] = lhs_t; | |
| 186 | 195 | } |
| 187 | 196 | Err(_) |
| 188 | 197 | if merge == MergeBehavior::Module |
| ... | ... | @@ -192,15 +201,12 @@ fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior) |
| 192 | 201 | return None; |
| 193 | 202 | } |
| 194 | 203 | Err(insert_idx) => { |
| 195 | use_trees.insert(insert_idx, rhs_t.clone()); | |
| 196 | // We simply add the use tree to the end of tree list. Ordering of use trees | |
| 197 | // and imports is done by the `try_normalize_*` functions. The sorted `use_trees` | |
| 198 | // vec is only used for binary search. | |
| 199 | lhs.get_or_create_use_tree_list().add_use_tree(rhs_t); | |
| 204 | use_trees.insert(insert_idx, rhs_t); | |
| 200 | 205 | } |
| 201 | 206 | } |
| 202 | 207 | } |
| 203 | Some(()) | |
| 208 | ||
| 209 | with_use_tree_list(&lhs, use_trees, make) | |
| 204 | 210 | } |
| 205 | 211 | |
| 206 | 212 | /// Style to follow when normalizing a use tree. |
| ... | ... | @@ -250,241 +256,216 @@ impl From<MergeBehavior> for NormalizationStyle { |
| 250 | 256 | /// - `foo::{bar::Qux, bar::{self}}` -> `{foo::bar::{self, Qux}}` |
| 251 | 257 | /// - `foo::bar::{self}` -> `{foo::bar}` |
| 252 | 258 | /// - `foo::bar` -> `{foo::bar}` |
| 253 | pub fn try_normalize_import(use_item: &ast::Use, style: NormalizationStyle) -> Option<ast::Use> { | |
| 254 | let use_item = use_item.clone_subtree().clone_for_update(); | |
| 255 | try_normalize_use_tree_mut(&use_item.use_tree()?, style)?; | |
| 256 | Some(use_item) | |
| 259 | pub fn try_normalize_import( | |
| 260 | make: &SyntaxFactory, | |
| 261 | use_item: &ast::Use, | |
| 262 | style: NormalizationStyle, | |
| 263 | ) -> Option<ast::Use> { | |
| 264 | let use_tree = try_normalize_use_tree(use_item.use_tree()?, style, make)?; | |
| 265 | ||
| 266 | make_use_with_tree(use_item, use_tree) | |
| 257 | 267 | } |
| 258 | 268 | |
| 259 | fn try_normalize_use_tree_mut(use_tree: &ast::UseTree, style: NormalizationStyle) -> Option<()> { | |
| 269 | fn try_normalize_use_tree( | |
| 270 | use_tree: ast::UseTree, | |
| 271 | style: NormalizationStyle, | |
| 272 | make: &SyntaxFactory, | |
| 273 | ) -> Option<ast::UseTree> { | |
| 260 | 274 | if style == NormalizationStyle::One { |
| 275 | let mut use_tree = use_tree; | |
| 261 | 276 | let mut modified = false; |
| 262 | modified |= use_tree.wrap_in_tree_list().is_some(); | |
| 263 | modified |= recursive_normalize(use_tree, style).is_some(); | |
| 264 | if !modified { | |
| 265 | // Either the use tree was already normalized or its semantically empty. | |
| 266 | return None; | |
| 277 | if let Some(wrapped) = wrap_in_tree_list(&use_tree, make) { | |
| 278 | use_tree = wrapped; | |
| 279 | modified = true; | |
| 267 | 280 | } |
| 268 | } else { | |
| 269 | recursive_normalize(use_tree, NormalizationStyle::Default)?; | |
| 281 | if let Some(normalized) = recursive_normalize(use_tree.clone(), style, make) { | |
| 282 | use_tree = normalized; | |
| 283 | modified = true; | |
| 284 | } | |
| 285 | return modified.then_some(use_tree); | |
| 270 | 286 | } |
| 271 | Some(()) | |
| 287 | ||
| 288 | recursive_normalize(use_tree, NormalizationStyle::Default, make) | |
| 272 | 289 | } |
| 273 | 290 | |
| 274 | 291 | /// Recursively normalizes a use tree and its subtrees (if any). |
| 275 | fn recursive_normalize(use_tree: &ast::UseTree, style: NormalizationStyle) -> Option<()> { | |
| 292 | fn recursive_normalize( | |
| 293 | use_tree: ast::UseTree, | |
| 294 | style: NormalizationStyle, | |
| 295 | make: &SyntaxFactory, | |
| 296 | ) -> Option<ast::UseTree> { | |
| 276 | 297 | let use_tree_list = use_tree.use_tree_list()?; |
| 277 | let merge_subtree_into_parent_tree = |single_subtree: &ast::UseTree| { | |
| 278 | let subtree_is_only_self = single_subtree.path().as_ref().is_some_and(path_is_self); | |
| 279 | ||
| 280 | let merged_path = match (use_tree.path(), single_subtree.path()) { | |
| 281 | // If the subtree is `{self}` then we cannot merge: `use | |
| 282 | // foo::bar::{self}` is not equivalent to `use foo::bar`. See | |
| 283 | // https://github.com/rust-lang/rust-analyzer/pull/17140#issuecomment-2079189725. | |
| 284 | _ if subtree_is_only_self => None, | |
| 285 | ||
| 286 | (None, None) => None, | |
| 287 | (Some(outer), None) => Some(outer), | |
| 288 | (None, Some(inner)) => Some(inner), | |
| 289 | (Some(outer), Some(inner)) => Some(make::path_concat(outer, inner).clone_for_update()), | |
| 290 | }; | |
| 291 | ||
| 292 | if merged_path.is_some() | |
| 293 | || single_subtree.use_tree_list().is_some() | |
| 294 | || single_subtree.star_token().is_some() | |
| 298 | let mut subtrees = use_tree_list.use_trees().collect::<Vec<_>>(); | |
| 299 | if subtrees.len() == 1 { | |
| 300 | if style == NormalizationStyle::One { | |
| 301 | let subtree = subtrees.pop()?; | |
| 302 | let normalized = recursive_normalize(subtree, NormalizationStyle::Default, make)?; | |
| 303 | return with_use_tree_list(&use_tree, vec![normalized], make); | |
| 304 | } | |
| 305 | ||
| 306 | let merged = merge_single_subtree_into_parent_tree(use_tree, make)?; | |
| 307 | return Some(recursive_normalize(merged.clone(), style, make).unwrap_or(merged)); | |
| 308 | } | |
| 309 | ||
| 310 | let mut modified = false; | |
| 311 | let mut new_use_tree_list = Vec::new(); | |
| 312 | for subtree in subtrees { | |
| 313 | if one_style_tree_list(&subtree).is_some() { | |
| 314 | let mut elements = Vec::new(); | |
| 315 | flatten_one_style_tree(subtree, &mut elements, &mut modified, make); | |
| 316 | new_use_tree_list.extend(elements); | |
| 317 | modified = true; | |
| 318 | } else if let Some(normalized) = | |
| 319 | recursive_normalize(subtree.clone(), NormalizationStyle::Default, make) | |
| 295 | 320 | { |
| 296 | ted::remove_all_iter(use_tree.syntax().children_with_tokens()); | |
| 297 | if let Some(path) = merged_path { | |
| 298 | ted::insert_raw(Position::first_child_of(use_tree.syntax()), path.syntax()); | |
| 299 | if single_subtree.use_tree_list().is_some() || single_subtree.star_token().is_some() | |
| 321 | new_use_tree_list.push(normalized); | |
| 322 | modified = true; | |
| 323 | } else { | |
| 324 | new_use_tree_list.push(subtree); | |
| 325 | } | |
| 326 | } | |
| 327 | ||
| 328 | let mut use_tree = | |
| 329 | if modified { with_use_tree_list(&use_tree, new_use_tree_list, make)? } else { use_tree }; | |
| 330 | ||
| 331 | let mut use_tree_list = use_tree.use_tree_list()?.use_trees().collect::<Vec<_>>(); | |
| 332 | let mut anchor_idx = 0; | |
| 333 | let mut merged_any = false; | |
| 334 | while anchor_idx < use_tree_list.len() { | |
| 335 | let mut candidate_idx = anchor_idx + 1; | |
| 336 | while candidate_idx < use_tree_list.len() { | |
| 337 | if let Some(mut merged) = try_merge_trees_with_factory( | |
| 338 | use_tree_list[anchor_idx].clone(), | |
| 339 | use_tree_list[candidate_idx].clone(), | |
| 340 | MergeBehavior::Crate, | |
| 341 | make, | |
| 342 | ) { | |
| 343 | if let Some(normalized) = | |
| 344 | recursive_normalize(merged.clone(), NormalizationStyle::Default, make) | |
| 300 | 345 | { |
| 301 | ted::insert_raw( | |
| 302 | Position::last_child_of(use_tree.syntax()), | |
| 303 | make::token(T![::]), | |
| 304 | ); | |
| 346 | merged = normalized; | |
| 305 | 347 | } |
| 348 | ||
| 349 | use_tree_list[anchor_idx] = merged; | |
| 350 | use_tree_list.remove(candidate_idx); | |
| 351 | merged_any = true; | |
| 352 | } else { | |
| 353 | candidate_idx += 1; | |
| 306 | 354 | } |
| 307 | if let Some(inner_use_tree_list) = single_subtree.use_tree_list() { | |
| 308 | ted::insert_raw( | |
| 309 | Position::last_child_of(use_tree.syntax()), | |
| 310 | inner_use_tree_list.syntax(), | |
| 311 | ); | |
| 312 | } else if single_subtree.star_token().is_some() { | |
| 313 | ted::insert_raw(Position::last_child_of(use_tree.syntax()), make::token(T![*])); | |
| 314 | } else if let Some(rename) = single_subtree.rename() { | |
| 315 | ted::insert_raw( | |
| 316 | Position::last_child_of(use_tree.syntax()), | |
| 317 | make::tokens::single_space(), | |
| 318 | ); | |
| 319 | ted::insert_raw(Position::last_child_of(use_tree.syntax()), rename.syntax()); | |
| 320 | } | |
| 321 | Some(()) | |
| 322 | } else { | |
| 323 | // Bail on semantically empty use trees. | |
| 324 | None | |
| 325 | 355 | } |
| 326 | }; | |
| 327 | let one_style_tree_list = |subtree: &ast::UseTree| match ( | |
| 328 | subtree.path().is_none() && subtree.star_token().is_none() && subtree.rename().is_none(), | |
| 329 | subtree.use_tree_list(), | |
| 330 | ) { | |
| 331 | (true, tree_list) => tree_list, | |
| 332 | _ => None, | |
| 333 | }; | |
| 334 | let add_element_to_list = |elem: SyntaxElement, elements: &mut Vec<SyntaxElement>| { | |
| 335 | if !elements.is_empty() { | |
| 336 | elements.push(make::token(T![,]).into()); | |
| 337 | elements.push(make::tokens::single_space().into()); | |
| 356 | ||
| 357 | anchor_idx += 1; | |
| 358 | } | |
| 359 | if merged_any { | |
| 360 | use_tree = with_use_tree_list(&use_tree, use_tree_list, make)?; | |
| 361 | modified = true; | |
| 362 | } | |
| 363 | ||
| 364 | if style != NormalizationStyle::One { | |
| 365 | let subtrees = use_tree.use_tree_list()?.use_trees().collect::<Vec<_>>(); | |
| 366 | if subtrees.len() == 1 | |
| 367 | && let Some(merged) = merge_single_subtree_into_parent_tree(use_tree.clone(), make) | |
| 368 | { | |
| 369 | use_tree = merged; | |
| 370 | modified = true; | |
| 338 | 371 | } |
| 339 | elements.push(elem); | |
| 340 | }; | |
| 341 | if let Some((single_subtree,)) = use_tree_list.use_trees().collect_tuple() { | |
| 342 | if style == NormalizationStyle::One { | |
| 343 | // Only normalize descendant subtrees if the normalization style is "one". | |
| 344 | recursive_normalize(&single_subtree, NormalizationStyle::Default)?; | |
| 345 | } else { | |
| 346 | // Otherwise, merge the single subtree into it's parent (if possible) | |
| 347 | // and then normalize the result. | |
| 348 | merge_subtree_into_parent_tree(&single_subtree)?; | |
| 349 | recursive_normalize(use_tree, style); | |
| 372 | } | |
| 373 | ||
| 374 | if let Some(list) = use_tree.use_tree_list() { | |
| 375 | let mut use_tree_list = list.use_trees().collect::<Vec<_>>(); | |
| 376 | if use_tree_list | |
| 377 | .windows(2) | |
| 378 | .any(|trees| use_tree_cmp_bin_search(&trees[0], &trees[1]).is_gt()) | |
| 379 | { | |
| 380 | use_tree_list.sort_unstable_by(use_tree_cmp_bin_search); | |
| 381 | use_tree = with_use_tree_list(&use_tree, use_tree_list, make)?; | |
| 382 | modified = true; | |
| 350 | 383 | } |
| 351 | } else { | |
| 352 | // Tracks whether any changes have been made to the use tree. | |
| 353 | let mut modified = false; | |
| 384 | } | |
| 354 | 385 | |
| 355 | // Recursively un-nests (if necessary) and then normalizes each subtree in the tree list. | |
| 356 | for subtree in use_tree_list.use_trees() { | |
| 357 | if let Some(one_tree_list) = one_style_tree_list(&subtree) { | |
| 358 | let mut elements = Vec::new(); | |
| 359 | let mut one_tree_list_iter = one_tree_list.use_trees(); | |
| 360 | let mut prev_skipped = Vec::new(); | |
| 361 | loop { | |
| 362 | let mut prev_skipped_iter = prev_skipped.into_iter(); | |
| 363 | let mut curr_skipped = Vec::new(); | |
| 364 | ||
| 365 | while let Some(sub_sub_tree) = | |
| 366 | one_tree_list_iter.next().or(prev_skipped_iter.next()) | |
| 367 | { | |
| 368 | if let Some(sub_one_tree_list) = one_style_tree_list(&sub_sub_tree) { | |
| 369 | curr_skipped.extend(sub_one_tree_list.use_trees()); | |
| 370 | } else { | |
| 371 | modified |= | |
| 372 | recursive_normalize(&sub_sub_tree, NormalizationStyle::Default) | |
| 373 | .is_some(); | |
| 374 | add_element_to_list( | |
| 375 | sub_sub_tree.syntax().clone().into(), | |
| 376 | &mut elements, | |
| 377 | ); | |
| 378 | } | |
| 379 | } | |
| 386 | modified.then_some(use_tree) | |
| 387 | } | |
| 380 | 388 | |
| 381 | if curr_skipped.is_empty() { | |
| 382 | // Un-nesting is complete. | |
| 383 | break; | |
| 384 | } | |
| 385 | prev_skipped = curr_skipped; | |
| 386 | } | |
| 389 | fn flatten_one_style_tree( | |
| 390 | subtree: ast::UseTree, | |
| 391 | elements: &mut Vec<ast::UseTree>, | |
| 392 | modified: &mut bool, | |
| 393 | make: &SyntaxFactory, | |
| 394 | ) { | |
| 395 | let Some(one_tree_list) = one_style_tree_list(&subtree) else { return }; | |
| 396 | let mut one_tree_list_iter = one_tree_list.use_trees(); | |
| 397 | let mut prev_skipped = Vec::new(); | |
| 398 | loop { | |
| 399 | let mut prev_skipped_iter = prev_skipped.into_iter(); | |
| 400 | let mut curr_skipped = Vec::new(); | |
| 387 | 401 | |
| 388 | // Either removes the subtree (if its semantically empty) or replaces it with | |
| 389 | // the un-nested elements. | |
| 390 | if elements.is_empty() { | |
| 391 | subtree.remove(); | |
| 392 | } else { | |
| 393 | ted::replace_with_many(subtree.syntax(), elements); | |
| 394 | } | |
| 395 | // Silence unused assignment warning on `modified`. | |
| 396 | let _ = modified; | |
| 397 | modified = true; | |
| 402 | while let Some(sub_sub_tree) = | |
| 403 | one_tree_list_iter.next().or_else(|| prev_skipped_iter.next()) | |
| 404 | { | |
| 405 | if let Some(sub_one_tree_list) = one_style_tree_list(&sub_sub_tree) { | |
| 406 | curr_skipped.extend(sub_one_tree_list.use_trees()); | |
| 407 | } else if let Some(normalized) = | |
| 408 | recursive_normalize(sub_sub_tree.clone(), NormalizationStyle::Default, make) | |
| 409 | { | |
| 410 | *modified = true; | |
| 411 | elements.push(normalized); | |
| 398 | 412 | } else { |
| 399 | modified |= recursive_normalize(&subtree, NormalizationStyle::Default).is_some(); | |
| 413 | elements.push(sub_sub_tree); | |
| 400 | 414 | } |
| 401 | 415 | } |
| 402 | 416 | |
| 403 | // Merge all merge-able subtrees. | |
| 404 | let mut tree_list_iter = use_tree_list.use_trees(); | |
| 405 | let mut anchor = tree_list_iter.next()?; | |
| 406 | let mut prev_skipped = Vec::new(); | |
| 407 | loop { | |
| 408 | let mut has_merged = false; | |
| 409 | let mut prev_skipped_iter = prev_skipped.into_iter(); | |
| 410 | let mut next_anchor = None; | |
| 411 | let mut curr_skipped = Vec::new(); | |
| 412 | ||
| 413 | while let Some(candidate) = tree_list_iter.next().or(prev_skipped_iter.next()) { | |
| 414 | let result = try_merge_trees_mut(&anchor, &candidate, MergeBehavior::Crate); | |
| 415 | if result.is_some() { | |
| 416 | // Remove merged subtree. | |
| 417 | candidate.remove(); | |
| 418 | has_merged = true; | |
| 419 | } else if next_anchor.is_none() { | |
| 420 | next_anchor = Some(candidate); | |
| 421 | } else { | |
| 422 | curr_skipped.push(candidate); | |
| 423 | } | |
| 424 | } | |
| 425 | ||
| 426 | if has_merged { | |
| 427 | // Normalize the merge result. | |
| 428 | recursive_normalize(&anchor, NormalizationStyle::Default); | |
| 429 | modified = true; | |
| 430 | } | |
| 417 | if curr_skipped.is_empty() { | |
| 418 | break; | |
| 419 | } | |
| 420 | prev_skipped = curr_skipped; | |
| 421 | } | |
| 422 | } | |
| 431 | 423 | |
| 432 | let (Some(next_anchor), true) = (next_anchor, !curr_skipped.is_empty()) else { | |
| 433 | // Merging is complete. | |
| 434 | break; | |
| 435 | }; | |
| 424 | fn merge_single_subtree_into_parent_tree( | |
| 425 | use_tree: ast::UseTree, | |
| 426 | make: &SyntaxFactory, | |
| 427 | ) -> Option<ast::UseTree> { | |
| 428 | let single_subtree = get_single_subtree(&use_tree)?; | |
| 429 | let subtree_is_only_self = single_subtree.path().as_ref().is_some_and(path_is_self); | |
| 430 | ||
| 431 | let merged_path = match (use_tree.path(), single_subtree.path()) { | |
| 432 | _ if subtree_is_only_self => None, | |
| 433 | (None, None) => None, | |
| 434 | (Some(outer), None) => Some(outer), | |
| 435 | (None, Some(inner)) => Some(inner), | |
| 436 | (Some(outer), Some(inner)) => Some(make.path_concat(outer, inner)), | |
| 437 | }; | |
| 436 | 438 | |
| 437 | // Try to merge the remaining subtrees in the next iteration. | |
| 438 | anchor = next_anchor; | |
| 439 | prev_skipped = curr_skipped; | |
| 440 | } | |
| 439 | let list = single_subtree.use_tree_list(); | |
| 440 | let list_is_none = list.is_none(); | |
| 441 | let star = single_subtree.star_token().is_some(); | |
| 442 | if merged_path.is_some() || list.is_some() || star { | |
| 443 | let rename = (!star && list_is_none).then(|| single_subtree.rename()).flatten(); | |
| 444 | make_use_tree_from_parts(make, merged_path, list, rename, star) | |
| 445 | } else { | |
| 446 | None | |
| 447 | } | |
| 448 | } | |
| 441 | 449 | |
| 442 | let mut subtrees: Vec<_> = use_tree_list.use_trees().collect(); | |
| 443 | // Merge the remaining subtree into its parent, if its only one and | |
| 444 | // the normalization style is not "one". | |
| 445 | if subtrees.len() == 1 && style != NormalizationStyle::One { | |
| 446 | modified |= merge_subtree_into_parent_tree(&subtrees[0]).is_some(); | |
| 447 | } | |
| 448 | // Order the remaining subtrees (if necessary). | |
| 449 | if subtrees.len() > 1 { | |
| 450 | let mut did_sort = false; | |
| 451 | subtrees.sort_unstable_by(|a, b| { | |
| 452 | let order = use_tree_cmp_bin_search(a, b); | |
| 453 | if !did_sort && order == Ordering::Less { | |
| 454 | did_sort = true; | |
| 455 | } | |
| 456 | order | |
| 457 | }); | |
| 458 | if did_sort { | |
| 459 | let start = use_tree_list | |
| 460 | .l_curly_token() | |
| 461 | .and_then(|l_curly| algo::non_trivia_sibling(l_curly.into(), Direction::Next)) | |
| 462 | .filter(|it| it.kind() != T!['}']); | |
| 463 | let end = use_tree_list | |
| 464 | .r_curly_token() | |
| 465 | .and_then(|r_curly| algo::non_trivia_sibling(r_curly.into(), Direction::Prev)) | |
| 466 | .filter(|it| it.kind() != T!['{']); | |
| 467 | if let Some((start, end)) = start.zip(end) { | |
| 468 | // Attempt to insert elements while preserving preceding and trailing trivia. | |
| 469 | let mut elements = Vec::new(); | |
| 470 | for subtree in subtrees { | |
| 471 | add_element_to_list(subtree.syntax().clone().into(), &mut elements); | |
| 472 | } | |
| 473 | ted::replace_all(start..=end, elements); | |
| 474 | } else { | |
| 475 | let new_use_tree_list = make::use_tree_list(subtrees).clone_for_update(); | |
| 476 | ted::replace(use_tree_list.syntax(), new_use_tree_list.syntax()); | |
| 477 | } | |
| 478 | modified = true; | |
| 479 | } | |
| 480 | } | |
| 450 | fn one_style_tree_list(subtree: &ast::UseTree) -> Option<ast::UseTreeList> { | |
| 451 | (subtree.path().is_none() && subtree.star_token().is_none() && subtree.rename().is_none()) | |
| 452 | .then(|| subtree.use_tree_list()) | |
| 453 | .flatten() | |
| 454 | } | |
| 481 | 455 | |
| 482 | if !modified { | |
| 483 | // Either the use tree was already normalized or its semantically empty. | |
| 484 | return None; | |
| 456 | fn remove_subtree_if_only_self( | |
| 457 | use_tree: ast::UseTree, | |
| 458 | make: &SyntaxFactory, | |
| 459 | ) -> Option<ast::UseTree> { | |
| 460 | let Some(single_subtree) = get_single_subtree(&use_tree) else { | |
| 461 | return Some(use_tree); | |
| 462 | }; | |
| 463 | match (use_tree.path(), single_subtree.path()) { | |
| 464 | (Some(path), Some(inner)) if path_is_self(&inner) => { | |
| 465 | Some(make.use_tree(path, None, use_tree.rename(), false)) | |
| 485 | 466 | } |
| 467 | _ => Some(use_tree), | |
| 486 | 468 | } |
| 487 | Some(()) | |
| 488 | 469 | } |
| 489 | 470 | |
| 490 | 471 | /// Traverses both paths until they differ, returning the common prefix of both. |
| ... | ... | @@ -513,10 +494,9 @@ pub fn common_prefix(lhs: &ast::Path, rhs: &ast::Path) -> Option<(ast::Path, ast |
| 513 | 494 | fn use_tree_cmp_bin_search(lhs: &ast::UseTree, rhs: &ast::UseTree) -> Ordering { |
| 514 | 495 | let lhs_is_simple_path = lhs.is_simple_path() && lhs.rename().is_none(); |
| 515 | 496 | let rhs_is_simple_path = rhs.is_simple_path() && rhs.rename().is_none(); |
| 516 | match ( | |
| 517 | lhs.path().as_ref().and_then(ast::Path::first_segment), | |
| 518 | rhs.path().as_ref().and_then(ast::Path::first_segment), | |
| 519 | ) { | |
| 497 | let lhs_segment = lhs.path().and_then(|path| path.first_segment()); | |
| 498 | let rhs_segment = rhs.path().and_then(|path| path.first_segment()); | |
| 499 | match (lhs_segment, rhs_segment) { | |
| 520 | 500 | (None, None) => match (lhs_is_simple_path, rhs_is_simple_path) { |
| 521 | 501 | (true, true) => Ordering::Equal, |
| 522 | 502 | (true, false) => Ordering::Less, |
| ... | ... | @@ -701,14 +681,164 @@ fn get_single_subtree(use_tree: &ast::UseTree) -> Option<ast::UseTree> { |
| 701 | 681 | .map(|(single_subtree,)| single_subtree) |
| 702 | 682 | } |
| 703 | 683 | |
| 704 | fn remove_subtree_if_only_self(use_tree: &ast::UseTree) { | |
| 705 | let Some(single_subtree) = get_single_subtree(use_tree) else { return }; | |
| 706 | match (use_tree.path(), single_subtree.path()) { | |
| 707 | (Some(_), Some(inner)) if path_is_self(&inner) => { | |
| 708 | ted::remove_all_iter(single_subtree.syntax().children_with_tokens()); | |
| 709 | } | |
| 710 | _ => (), | |
| 684 | fn make_use_with_tree(original: &ast::Use, use_tree: ast::UseTree) -> Option<ast::Use> { | |
| 685 | let (editor, use_item) = SyntaxEditor::with_ast_node(original); | |
| 686 | let original_tree = use_item.use_tree()?; | |
| 687 | editor.replace(original_tree.syntax(), use_tree.syntax()); | |
| 688 | let edit = editor.finish(); | |
| 689 | ast::Use::cast(edit.new_root().clone()) | |
| 690 | } | |
| 691 | ||
| 692 | fn make_use_tree_list( | |
| 693 | make: &SyntaxFactory, | |
| 694 | use_trees: Vec<ast::UseTree>, | |
| 695 | style_source: Option<&ast::UseTreeList>, | |
| 696 | ) -> Option<ast::UseTreeList> { | |
| 697 | let use_tree_list = make.use_tree_list(use_trees); | |
| 698 | let Some(style_source) = style_source else { | |
| 699 | return Some(use_tree_list); | |
| 700 | }; | |
| 701 | ||
| 702 | let source_l_curly = style_source.l_curly_token()?; | |
| 703 | let source_r_curly = style_source.r_curly_token()?; | |
| 704 | ||
| 705 | let leading_ws = source_l_curly.next_token().filter(|token| token.kind().is_trivia()); | |
| 706 | ||
| 707 | let trailing_ws = source_r_curly.prev_token().filter(|token| token.kind().is_trivia()); | |
| 708 | ||
| 709 | let source_trailing_token = trailing_ws | |
| 710 | .as_ref() | |
| 711 | .and_then(|token| token.prev_token()) | |
| 712 | .or_else(|| source_r_curly.prev_token()); | |
| 713 | ||
| 714 | let source_has_trailing_comma = | |
| 715 | source_trailing_token.is_some_and(|token| token.kind() == T![,]); | |
| 716 | ||
| 717 | let (editor, use_tree_list) = SyntaxEditor::with_ast_node(&use_tree_list); | |
| 718 | let make = editor.make(); | |
| 719 | ||
| 720 | if let Some(leading_ws) = leading_ws { | |
| 721 | editor.insert( | |
| 722 | Position::after(use_tree_list.l_curly_token()?), | |
| 723 | make.whitespace(leading_ws.text()), | |
| 724 | ); | |
| 725 | } | |
| 726 | ||
| 727 | let r_curly = use_tree_list.r_curly_token()?; | |
| 728 | ||
| 729 | let generated_has_trailing_comma = r_curly | |
| 730 | .prev_token() | |
| 731 | .and_then(|token| if token.kind().is_trivia() { token.prev_token() } else { Some(token) }) | |
| 732 | .is_some_and(|token| token.kind() == T![,]); | |
| 733 | ||
| 734 | let mut trailing = Vec::new(); | |
| 735 | ||
| 736 | if source_has_trailing_comma | |
| 737 | && !generated_has_trailing_comma | |
| 738 | && use_tree_list.use_trees().next().is_some() | |
| 739 | { | |
| 740 | trailing.push(make.token(T![,]).into()); | |
| 741 | } | |
| 742 | ||
| 743 | if let Some(trailing_ws) = trailing_ws { | |
| 744 | trailing.push(make.whitespace(trailing_ws.text()).into()); | |
| 745 | } | |
| 746 | ||
| 747 | if !trailing.is_empty() { | |
| 748 | editor.insert_all(Position::before(r_curly), trailing); | |
| 749 | } | |
| 750 | ||
| 751 | let edit = editor.finish(); | |
| 752 | ast::UseTreeList::cast(edit.new_root().clone()) | |
| 753 | } | |
| 754 | ||
| 755 | fn make_use_tree_from_list(make: &SyntaxFactory, list: ast::UseTreeList) -> Option<ast::UseTree> { | |
| 756 | let placeholder = make.use_tree_glob(); | |
| 757 | let (editor, use_tree) = SyntaxEditor::with_ast_node(&placeholder); | |
| 758 | let first_child = use_tree.syntax().first_child_or_token()?; | |
| 759 | let last_child = use_tree.syntax().last_child_or_token()?; | |
| 760 | editor.replace_all(first_child..=last_child, vec![list.syntax().clone().into()]); | |
| 761 | let edit = editor.finish(); | |
| 762 | ast::UseTree::cast(edit.new_root().clone()) | |
| 763 | } | |
| 764 | ||
| 765 | fn make_use_tree_from_parts( | |
| 766 | make: &SyntaxFactory, | |
| 767 | path: Option<ast::Path>, | |
| 768 | list: Option<ast::UseTreeList>, | |
| 769 | rename: Option<ast::Rename>, | |
| 770 | star: bool, | |
| 771 | ) -> Option<ast::UseTree> { | |
| 772 | match (path, list, star) { | |
| 773 | (Some(path), list, star) => Some(make.use_tree(path, list, rename, star)), | |
| 774 | (None, Some(list), false) if rename.is_none() => make_use_tree_from_list(make, list), | |
| 775 | (None, None, true) if rename.is_none() => Some(make.use_tree_glob()), | |
| 776 | (None, None, false) if rename.is_none() => None, | |
| 777 | _ => None, | |
| 778 | } | |
| 779 | } | |
| 780 | ||
| 781 | fn with_use_tree_list( | |
| 782 | use_tree: &ast::UseTree, | |
| 783 | use_trees: Vec<ast::UseTree>, | |
| 784 | make: &SyntaxFactory, | |
| 785 | ) -> Option<ast::UseTree> { | |
| 786 | let list = make_use_tree_list(make, use_trees, use_tree.use_tree_list().as_ref())?; | |
| 787 | make_use_tree_from_parts( | |
| 788 | make, | |
| 789 | use_tree.path(), | |
| 790 | Some(list), | |
| 791 | use_tree.rename(), | |
| 792 | use_tree.star_token().is_some(), | |
| 793 | ) | |
| 794 | } | |
| 795 | ||
| 796 | pub(crate) fn wrap_in_tree_list( | |
| 797 | use_tree: &ast::UseTree, | |
| 798 | make: &SyntaxFactory, | |
| 799 | ) -> Option<ast::UseTree> { | |
| 800 | if use_tree.path().is_none() | |
| 801 | && use_tree.use_tree_list().is_some() | |
| 802 | && use_tree.rename().is_none() | |
| 803 | && use_tree.star_token().is_none() | |
| 804 | { | |
| 805 | return None; | |
| 711 | 806 | } |
| 807 | ||
| 808 | let list = make_use_tree_list(make, vec![use_tree.clone()], None)?; | |
| 809 | make_use_tree_from_list(make, list) | |
| 810 | } | |
| 811 | ||
| 812 | fn split_prefix( | |
| 813 | use_tree: &ast::UseTree, | |
| 814 | prefix: &ast::Path, | |
| 815 | make: &SyntaxFactory, | |
| 816 | ) -> Option<ast::UseTree> { | |
| 817 | let path = use_tree.path()?; | |
| 818 | if path == *prefix && use_tree.use_tree_list().is_some() { | |
| 819 | return Some(use_tree.clone()); | |
| 820 | } | |
| 821 | ||
| 822 | let suffix = if path == *prefix { | |
| 823 | if use_tree.star_token().is_some() { | |
| 824 | make.use_tree_glob() | |
| 825 | } else { | |
| 826 | let self_path = make.path_unqualified(make.path_segment_self()); | |
| 827 | make.use_tree(self_path, None, use_tree.rename(), false) | |
| 828 | } | |
| 829 | } else { | |
| 830 | let suffix_segments = path.segments().skip(prefix.segments().count()); | |
| 831 | let suffix_path = make.path_from_segments(suffix_segments, false); | |
| 832 | make.use_tree( | |
| 833 | suffix_path, | |
| 834 | use_tree.use_tree_list(), | |
| 835 | use_tree.rename(), | |
| 836 | use_tree.star_token().is_some(), | |
| 837 | ) | |
| 838 | }; | |
| 839 | ||
| 840 | let list = make_use_tree_list(make, vec![suffix], None)?; | |
| 841 | Some(make.use_tree(prefix.clone(), Some(list), None, false)) | |
| 712 | 842 | } |
| 713 | 843 | |
| 714 | 844 | // Taken from rustfmt |
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs-1| ... | ... | @@ -1025,7 +1025,6 @@ fn _slice(bar: &[i32]) -> bool { |
| 1025 | 1025 | check_diagnostics( |
| 1026 | 1026 | r#" |
| 1027 | 1027 | //- minicore: coerce_unsized, dispatch_from_dyn |
| 1028 | #![feature(trait_upcasting)] | |
| 1029 | 1028 | trait Foo {} |
| 1030 | 1029 | trait Bar: Foo {} |
| 1031 | 1030 |
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs+24| ... | ... | @@ -354,6 +354,30 @@ fn f() { |
| 354 | 354 | ) |
| 355 | 355 | } |
| 356 | 356 | |
| 357 | #[test] | |
| 358 | fn varargs_fn_pointer() { | |
| 359 | check_diagnostics( | |
| 360 | r#" | |
| 361 | struct Funcs { | |
| 362 | f: unsafe extern "C" fn(u8, u8, ...) -> i32, | |
| 363 | g: unsafe extern "C" fn(...) -> i32, | |
| 364 | } | |
| 365 | ||
| 366 | fn f(funcs: Funcs) { | |
| 367 | unsafe { | |
| 368 | (funcs.f)(0, 1); | |
| 369 | (funcs.f)(0, 1, 2); | |
| 370 | (funcs.f)(0); | |
| 371 | //^ error: expected 2 arguments, found 1 | |
| 372 | (funcs.g)(); | |
| 373 | (funcs.g)(0); | |
| 374 | (funcs.g)(0, 1); | |
| 375 | } | |
| 376 | } | |
| 377 | "#, | |
| 378 | ) | |
| 379 | } | |
| 380 | ||
| 357 | 381 | #[test] |
| 358 | 382 | fn arg_count_lambda() { |
| 359 | 383 | check_diagnostics( |
src/tools/rust-analyzer/crates/ide/src/lib.rs+3-2| ... | ... | @@ -60,6 +60,7 @@ mod view_mir; |
| 60 | 60 | mod view_syntax_tree; |
| 61 | 61 | |
| 62 | 62 | use std::panic::{AssertUnwindSafe, UnwindSafe}; |
| 63 | use std::time::Duration; | |
| 63 | 64 | |
| 64 | 65 | use cfg::CfgOptions; |
| 65 | 66 | use fetch_crates::CrateInfo; |
| ... | ... | @@ -197,8 +198,8 @@ impl AnalysisHost { |
| 197 | 198 | |
| 198 | 199 | /// Applies changes to the current state of the world. If there are |
| 199 | 200 | /// outstanding snapshots, they will be canceled. |
| 200 | pub fn apply_change(&mut self, change: ChangeWithProcMacros) { | |
| 201 | self.db.apply_change(change); | |
| 201 | pub fn apply_change(&mut self, change: ChangeWithProcMacros) -> Duration { | |
| 202 | self.db.apply_change(change) | |
| 202 | 203 | } |
| 203 | 204 | |
| 204 | 205 | /// NB: this clears the database |
src/tools/rust-analyzer/crates/ide/src/navigation_target.rs-1| ... | ... | @@ -50,7 +50,6 @@ pub struct NavigationTarget { |
| 50 | 50 | pub kind: Option<SymbolKind>, |
| 51 | 51 | pub container_name: Option<Symbol>, |
| 52 | 52 | pub description: Option<String>, |
| 53 | // FIXME: Use the database lifetime here. | |
| 54 | 53 | pub docs: Option<Documentation<'static>>, |
| 55 | 54 | /// In addition to a `name` field, a `NavigationTarget` may also be aliased |
| 56 | 55 | /// In such cases we want a `NavigationTarget` to be accessible by its alias |
src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html+6-6| ... | ... | @@ -128,9 +128,9 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd |
| 128 | 128 | <span class="keyword">let</span> <span class="variable declaration mutable reference">y</span> <span class="operator">=</span> <span class="operator">&</span><span class="keyword">mut</span> <span class="variable mutable">x</span><span class="semicolon">;</span> |
| 129 | 129 | <span class="keyword">let</span> <span class="variable declaration reference">z</span> <span class="operator">=</span> <span class="operator">&</span><span class="variable mutable reference">y</span><span class="semicolon">;</span> |
| 130 | 130 | |
| 131 | <span class="keyword">let</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="colon">:</span> <span class="variable declaration">z</span><span class="comma">,</span> <span class="variable callable declaration">y</span> <span class="brace">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="colon">:</span> <span class="variable reference">z</span><span class="comma">,</span> <span class="variable mutable reference">y</span> <span class="brace">}</span><span class="semicolon">;</span> | |
| 131 | <span class="keyword">let</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="colon">:</span> <span class="variable declaration">z</span><span class="comma">,</span> <span class="variable declaration">y</span> <span class="brace">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="colon">:</span> <span class="variable reference">z</span><span class="comma">,</span> <span class="variable mutable reference">y</span> <span class="brace">}</span><span class="semicolon">;</span> | |
| 132 | 132 | |
| 133 | <span class="variable callable">y</span><span class="semicolon">;</span> | |
| 133 | <span class="variable">y</span><span class="semicolon">;</span> | |
| 134 | 134 | |
| 135 | 135 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="unresolved_reference">y</span><span class="colon">:</span> <span class="variable mutable">x</span> <span class="brace">}</span><span class="semicolon">;</span> |
| 136 | 136 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="unresolved_reference">y</span><span class="colon">:</span> <span class="variable mutable">x</span> <span class="brace">}</span><span class="semicolon">;</span> |
| ... | ... | @@ -143,7 +143,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd |
| 143 | 143 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="method mutable reference">qux</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
| 144 | 144 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="method">baz</span><span class="parenthesis">(</span><span class="variable mutable">copy</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
| 145 | 145 | |
| 146 | <span class="keyword">let</span> <span class="variable callable declaration">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param callable declaration">x</span><span class="punctuation">|</span> <span class="value_param callable">x</span><span class="semicolon">;</span> | |
| 146 | <span class="keyword">let</span> <span class="variable callable declaration">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="semicolon">;</span> | |
| 147 | 147 | <span class="keyword">let</span> <span class="variable callable declaration">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="method associated consuming">baz</span><span class="semicolon">;</span> |
| 148 | 148 | |
| 149 | 149 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="comma">,</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
| ... | ... | @@ -173,13 +173,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd |
| 173 | 173 | <span class="brace">}</span> |
| 174 | 174 | |
| 175 | 175 | <span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function async declaration">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
| 176 | <span class="keyword">let</span> <span class="variable callable declaration">song</span> <span class="operator">=</span> <span class="unresolved_reference">learn_song</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword async control">await</span><span class="semicolon">;</span> | |
| 177 | <span class="unresolved_reference">sing_song</span><span class="parenthesis">(</span><span class="variable callable">song</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword async control">await</span><span class="semicolon">;</span> | |
| 176 | <span class="keyword">let</span> <span class="variable declaration">song</span> <span class="operator">=</span> <span class="unresolved_reference">learn_song</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword async control">await</span><span class="semicolon">;</span> | |
| 177 | <span class="unresolved_reference">sing_song</span><span class="parenthesis">(</span><span class="variable consuming">song</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword async control">await</span><span class="semicolon">;</span> | |
| 178 | 178 | <span class="brace">}</span> |
| 179 | 179 | |
| 180 | 180 | <span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function async declaration">async_main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
| 181 | 181 | <span class="keyword">let</span> <span class="variable declaration">f1</span> <span class="operator">=</span> <span class="function async">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
| 182 | <span class="keyword">let</span> <span class="variable callable declaration">f2</span> <span class="operator">=</span> <span class="unresolved_reference">dance</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> | |
| 182 | <span class="keyword">let</span> <span class="variable declaration">f2</span> <span class="operator">=</span> <span class="unresolved_reference">dance</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> | |
| 183 | 183 | <span class="unresolved_reference">futures</span><span class="operator">::</span><span class="unresolved_reference">join</span><span class="macro_bang">!</span><span class="parenthesis">(</span>f1<span class="comma">,</span> f2<span class="parenthesis">)</span><span class="semicolon">;</span> |
| 184 | 184 | <span class="brace">}</span> |
| 185 | 185 |
src/tools/rust-analyzer/crates/intern/Cargo.toml-1| ... | ... | @@ -12,7 +12,6 @@ rust-version.workspace = true |
| 12 | 12 | [lib] |
| 13 | 13 | doctest = false |
| 14 | 14 | |
| 15 | ||
| 16 | 15 | [dependencies] |
| 17 | 16 | dashmap.workspace = true |
| 18 | 17 | # We need to freeze the version of the crate, as it needs to match with dashmap |
src/tools/rust-analyzer/crates/intern/src/gc.rs+31-13| ... | ... | @@ -34,9 +34,7 @@ impl<T: Internable + GcInternedVisit> Storage for InternedStorage<T> { |
| 34 | 34 | for item in storage { |
| 35 | 35 | let item = item.key(); |
| 36 | 36 | let addr = Arc::as_ptr(item).addr(); |
| 37 | if Arc::strong_count(item) > 1 { | |
| 38 | // The item is referenced from the outside. | |
| 39 | gc.alive.insert(addr); | |
| 37 | if Arc::strong_count(item) > 1 && gc.alive.insert(addr) { | |
| 40 | 38 | item.visit_with(gc); |
| 41 | 39 | } |
| 42 | 40 | } |
| ... | ... | @@ -60,9 +58,7 @@ impl<T: SliceInternable + GcInternedSliceVisit> Storage for InternedSliceStorage |
| 60 | 58 | for item in storage { |
| 61 | 59 | let item = item.key(); |
| 62 | 60 | let addr = ThinArc::as_ptr(item).addr(); |
| 63 | if ThinArc::strong_count(item) > 1 { | |
| 64 | // The item is referenced from the outside. | |
| 65 | gc.alive.insert(addr); | |
| 61 | if ThinArc::strong_count(item) > 1 && gc.alive.insert(addr) { | |
| 66 | 62 | T::visit_header(&item.header.header, gc); |
| 67 | 63 | T::visit_slice(&item.slice, gc); |
| 68 | 64 | } |
| ... | ... | @@ -81,7 +77,7 @@ pub trait GcInternedVisit { |
| 81 | 77 | |
| 82 | 78 | pub trait GcInternedSliceVisit: SliceInternable { |
| 83 | 79 | fn visit_header(header: &Self::Header, gc: &mut GarbageCollector); |
| 84 | fn visit_slice(header: &[Self::SliceType], gc: &mut GarbageCollector); | |
| 80 | fn visit_slice(slice: &[Self::SliceType], gc: &mut GarbageCollector); | |
| 85 | 81 | } |
| 86 | 82 | |
| 87 | 83 | #[derive(Default)] |
| ... | ... | @@ -103,11 +99,13 @@ impl GarbageCollector { |
| 103 | 99 | self.storages.push(&InternedSliceStorage::<T>(PhantomData)); |
| 104 | 100 | } |
| 105 | 101 | |
| 102 | /// Collects unreachable GC-managed interned values. | |
| 103 | /// | |
| 106 | 104 | /// # Safety |
| 107 | 105 | /// |
| 108 | 106 | /// - This cannot be called if there are some not-yet-recorded type values. |
| 109 | /// - All relevant storages must have been added; that is, within the full graph of values, | |
| 110 | /// the added storages must form a DAG. | |
| 107 | /// - All storages that can contain live GC-managed values must have been added, and those | |
| 108 | /// storages must be closed over the GC-managed values reachable from them. | |
| 111 | 109 | /// - [`GcInternedVisit`] and [`GcInternedSliceVisit`] must mark all values reachable from the node. |
| 112 | 110 | pub unsafe fn collect(mut self) { |
| 113 | 111 | if cfg!(feature = "prevent-gc") { |
| ... | ... | @@ -136,8 +134,9 @@ impl GarbageCollector { |
| 136 | 134 | &mut self, |
| 137 | 135 | interned: InternedRef<'_, T>, |
| 138 | 136 | ) -> ControlFlow<()> { |
| 137 | const { assert!(T::USE_GC) }; | |
| 138 | ||
| 139 | 139 | if interned.strong_count() > 1 { |
| 140 | // It will be visited anyway, so short-circuit | |
| 141 | 140 | return ControlFlow::Break(()); |
| 142 | 141 | } |
| 143 | 142 | let addr = interned.as_raw().addr(); |
| ... | ... | @@ -148,8 +147,9 @@ impl GarbageCollector { |
| 148 | 147 | &mut self, |
| 149 | 148 | interned: InternedSliceRef<'_, T>, |
| 150 | 149 | ) -> ControlFlow<()> { |
| 150 | const { assert!(T::USE_GC) }; | |
| 151 | ||
| 151 | 152 | if interned.strong_count() > 1 { |
| 152 | // It will be visited anyway, so short-circuit | |
| 153 | 153 | return ControlFlow::Break(()); |
| 154 | 154 | } |
| 155 | 155 | let addr = interned.as_raw().addr(); |
| ... | ... | @@ -240,7 +240,7 @@ mod tests { |
| 240 | 240 | impl GcInternedSliceVisit for StringSlice { |
| 241 | 241 | fn visit_header(_header: &Self::Header, _gc: &mut GarbageCollector) {} |
| 242 | 242 | |
| 243 | fn visit_slice(_header: &[Self::SliceType], _gc: &mut GarbageCollector) {} | |
| 243 | fn visit_slice(_slice: &[Self::SliceType], _gc: &mut GarbageCollector) {} | |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | 246 | let (a, d) = { |
| ... | ... | @@ -276,6 +276,10 @@ mod tests { |
| 276 | 276 | gc.add_storage::<GcString>(); |
| 277 | 277 | unsafe { gc.collect() }; |
| 278 | 278 | |
| 279 | if !cfg!(feature = "prevent-gc") { | |
| 280 | assert_eq!(<GcString as crate::Internable>::storage().get().len(), 1); | |
| 281 | assert_eq!(<StringSlice as crate::SliceInternable>::storage().get().len(), 1); | |
| 282 | } | |
| 279 | 283 | assert_eq!(a.0, "abc"); |
| 280 | 284 | assert_eq!(d.header.length, 2); |
| 281 | 285 | assert_eq!(d.header.header, "abc"); |
| ... | ... | @@ -288,6 +292,11 @@ mod tests { |
| 288 | 292 | gc.add_slice_storage::<StringSlice>(); |
| 289 | 293 | gc.add_storage::<GcString>(); |
| 290 | 294 | unsafe { gc.collect() }; |
| 295 | ||
| 296 | if !cfg!(feature = "prevent-gc") { | |
| 297 | assert_eq!(<GcString as crate::Internable>::storage().get().len(), 0); | |
| 298 | assert_eq!(<StringSlice as crate::SliceInternable>::storage().get().len(), 0); | |
| 299 | } | |
| 291 | 300 | } |
| 292 | 301 | |
| 293 | 302 | #[test] |
| ... | ... | @@ -309,7 +318,7 @@ mod tests { |
| 309 | 318 | impl GcInternedSliceVisit for StringSlice { |
| 310 | 319 | fn visit_header(_header: &Self::Header, _gc: &mut GarbageCollector) {} |
| 311 | 320 | |
| 312 | fn visit_slice(_header: &[Self::SliceType], _gc: &mut GarbageCollector) {} | |
| 321 | fn visit_slice(_slice: &[Self::SliceType], _gc: &mut GarbageCollector) {} | |
| 313 | 322 | } |
| 314 | 323 | |
| 315 | 324 | let outer = { |
| ... | ... | @@ -322,6 +331,10 @@ mod tests { |
| 322 | 331 | gc.add_storage::<GcInterned>(); |
| 323 | 332 | unsafe { gc.collect() }; |
| 324 | 333 | |
| 334 | if !cfg!(feature = "prevent-gc") { | |
| 335 | assert_eq!(<GcInterned as crate::Internable>::storage().get().len(), 1); | |
| 336 | assert_eq!(<StringSlice as crate::SliceInternable>::storage().get().len(), 1); | |
| 337 | } | |
| 325 | 338 | assert_eq!(outer.0.header.header, "abc"); |
| 326 | 339 | assert_eq!(outer.0.slice, [123, 456, 789]); |
| 327 | 340 | |
| ... | ... | @@ -331,5 +344,10 @@ mod tests { |
| 331 | 344 | gc.add_slice_storage::<StringSlice>(); |
| 332 | 345 | gc.add_storage::<GcInterned>(); |
| 333 | 346 | unsafe { gc.collect() }; |
| 347 | ||
| 348 | if !cfg!(feature = "prevent-gc") { | |
| 349 | assert_eq!(<GcInterned as crate::Internable>::storage().get().len(), 0); | |
| 350 | assert_eq!(<StringSlice as crate::SliceInternable>::storage().get().len(), 0); | |
| 351 | } | |
| 334 | 352 | } |
| 335 | 353 | } |
src/tools/rust-analyzer/crates/parser/src/output.rs+1-1| ... | ... | @@ -18,7 +18,7 @@ pub struct Output { |
| 18 | 18 | /// |
| 19 | 19 | /// ```text |
| 20 | 20 | /// |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover| |
| 21 | /// `````` | |
| 21 | /// ``` | |
| 22 | 22 | event: Vec<u32>, |
| 23 | 23 | error: Vec<String>, |
| 24 | 24 | } |
src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml+1-1| ... | ... | @@ -29,7 +29,7 @@ line-index.workspace = true |
| 29 | 29 | proc-macro-test.path = "./proc-macro-test" |
| 30 | 30 | |
| 31 | 31 | [features] |
| 32 | default = ["in-rust-tree"] | |
| 32 | default = [] | |
| 33 | 33 | in-rust-tree = [] |
| 34 | 34 | |
| 35 | 35 | [lints] |
src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs+1-1| ... | ... | @@ -560,7 +560,7 @@ impl WorkspaceBuildScripts { |
| 560 | 560 | |
| 561 | 561 | // FIXME: Find a better way to know if it is a dylib. |
| 562 | 562 | fn is_dylib(path: &Utf8Path) -> bool { |
| 563 | match path.extension().map(|e| e.to_owned().to_lowercase()) { | |
| 563 | match path.extension().map(|e| e.to_ascii_lowercase()) { | |
| 564 | 564 | None => false, |
| 565 | 565 | Some(ext) => matches!(ext.as_str(), "dll" | "dylib" | "so"), |
| 566 | 566 | } |
src/tools/rust-analyzer/crates/project-model/src/workspace.rs+10-3| ... | ... | @@ -811,6 +811,7 @@ impl ProjectWorkspace { |
| 811 | 811 | .packages() |
| 812 | 812 | .map(|pkg| { |
| 813 | 813 | let is_local = cargo[pkg].is_local; |
| 814 | let is_member = cargo[pkg].is_member; | |
| 814 | 815 | let pkg_root = cargo[pkg].manifest.parent().to_path_buf(); |
| 815 | 816 | |
| 816 | 817 | let mut include = vec![pkg_root.clone()]; |
| ... | ... | @@ -844,9 +845,11 @@ impl ProjectWorkspace { |
| 844 | 845 | let mut exclude = vec![pkg_root.join(".git")]; |
| 845 | 846 | if is_local { |
| 846 | 847 | include.extend(self.extra_includes.iter().cloned()); |
| 847 | ||
| 848 | 848 | exclude.push(pkg_root.join("target")); |
| 849 | } else { | |
| 849 | } | |
| 850 | if !is_member { | |
| 851 | // For non-workspace-members, we only resolve library targets, | |
| 852 | // so none of these need to be loaded into the VFS. | |
| 850 | 853 | exclude.push(pkg_root.join("tests")); |
| 851 | 854 | exclude.push(pkg_root.join("examples")); |
| 852 | 855 | exclude.push(pkg_root.join("benches")); |
| ... | ... | @@ -874,6 +877,7 @@ impl ProjectWorkspace { |
| 874 | 877 | .chain(cargo_script.iter().flat_map(|(cargo, build_scripts, _)| { |
| 875 | 878 | cargo.packages().map(|pkg| { |
| 876 | 879 | let is_local = cargo[pkg].is_local; |
| 880 | let is_member = cargo[pkg].is_member; | |
| 877 | 881 | let pkg_root = cargo[pkg].manifest.parent().to_path_buf(); |
| 878 | 882 | |
| 879 | 883 | let mut include = vec![pkg_root.clone()]; |
| ... | ... | @@ -909,7 +913,10 @@ impl ProjectWorkspace { |
| 909 | 913 | include.extend(self.extra_includes.iter().cloned()); |
| 910 | 914 | |
| 911 | 915 | exclude.push(pkg_root.join("target")); |
| 912 | } else { | |
| 916 | } | |
| 917 | if !is_member { | |
| 918 | // For non-workspace-members, we only resolve library targets, | |
| 919 | // so none of these need to be loaded into the VFS. | |
| 913 | 920 | exclude.push(pkg_root.join("tests")); |
| 914 | 921 | exclude.push(pkg_root.join("examples")); |
| 915 | 922 | exclude.push(pkg_root.join("benches")); |
src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs+1| ... | ... | @@ -64,6 +64,7 @@ impl Tester { |
| 64 | 64 | fn new() -> Result<Self> { |
| 65 | 65 | let mut path = AbsPathBuf::assert_utf8(std::env::temp_dir()); |
| 66 | 66 | path.push("ra-rustc-test"); |
| 67 | std::fs::create_dir_all(&path)?; | |
| 67 | 68 | let tmp_file = path.join("ra-rustc-test.rs"); |
| 68 | 69 | std::fs::write(&tmp_file, "")?; |
| 69 | 70 | let cargo_config = CargoConfig { |
src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs+1-1| ... | ... | @@ -237,7 +237,7 @@ impl flags::Scip { |
| 237 | 237 | let token = si.tokens.get(id).unwrap(); |
| 238 | 238 | |
| 239 | 239 | let Some(definition) = token.definition else { |
| 240 | break; | |
| 240 | continue; | |
| 241 | 241 | }; |
| 242 | 242 | |
| 243 | 243 | let file_id = definition.file_id; |
src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs+9-2| ... | ... | @@ -662,9 +662,12 @@ config_data! { |
| 662 | 662 | /// For traits the type "methods" can be used to only exclude the methods but not the trait |
| 663 | 663 | /// itself. |
| 664 | 664 | /// |
| 665 | /// For modules the type "subItems" can be used to only exclude the all items in it but not the module | |
| 665 | /// For modules the type "sub_items" can be used to only exclude the all items in it but not the module | |
| 666 | 666 | /// itself. This does not include items defined in nested modules. |
| 667 | 667 | /// |
| 668 | /// For enums the type "variants" can be used to only exclude the all variants in it but not the enum | |
| 669 | /// itself. | |
| 670 | /// | |
| 668 | 671 | /// This setting also inherits `#rust-analyzer.completion.excludeTraits#`. |
| 669 | 672 | completion_autoimport_exclude: Vec<AutoImportExclusion> = vec![ |
| 670 | 673 | AutoImportExclusion::Verbose { path: "core::borrow::Borrow".to_owned(), r#type: AutoImportExclusionType::Methods }, |
| ... | ... | @@ -1944,6 +1947,9 @@ impl Config { |
| 1944 | 1947 | AutoImportExclusionType::SubItems => { |
| 1945 | 1948 | ide_completion::AutoImportExclusionType::SubItems |
| 1946 | 1949 | } |
| 1950 | AutoImportExclusionType::Variants => { | |
| 1951 | ide_completion::AutoImportExclusionType::Variants | |
| 1952 | } | |
| 1947 | 1953 | }, |
| 1948 | 1954 | ), |
| 1949 | 1955 | }) |
| ... | ... | @@ -3004,6 +3010,7 @@ pub enum AutoImportExclusionType { |
| 3004 | 3010 | Always, |
| 3005 | 3011 | Methods, |
| 3006 | 3012 | SubItems, |
| 3013 | Variants, | |
| 3007 | 3014 | } |
| 3008 | 3015 | |
| 3009 | 3016 | #[derive(Serialize, Deserialize, Debug, Clone)] |
| ... | ... | @@ -4135,7 +4142,7 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json |
| 4135 | 4142 | }, |
| 4136 | 4143 | "type": { |
| 4137 | 4144 | "type": "string", |
| 4138 | "enum": ["always", "methods", "subItems"], | |
| 4145 | "enum": ["always", "methods", "sub_items", "variants"], | |
| 4139 | 4146 | "enumDescriptions": [ |
| 4140 | 4147 | "Do not show this item or its methods (if it is a trait) in auto-import completions.", |
| 4141 | 4148 | "Do not show this trait's methods in auto-import completions.", |
src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs+4-4| ... | ... | @@ -330,7 +330,7 @@ impl GlobalState { |
| 330 | 330 | this |
| 331 | 331 | } |
| 332 | 332 | |
| 333 | pub(crate) fn process_changes(&mut self) -> bool { | |
| 333 | pub(crate) fn process_changes(&mut self) -> (bool, Option<Duration>) { | |
| 334 | 334 | let _p = span!(Level::INFO, "GlobalState::process_changes").entered(); |
| 335 | 335 | // We cannot directly resolve a change in a ratoml file to a format |
| 336 | 336 | // that can be used by the config module because config talks |
| ... | ... | @@ -343,7 +343,7 @@ impl GlobalState { |
| 343 | 343 | let mut guard = self.vfs.write(); |
| 344 | 344 | let changed_files = guard.0.take_changes(); |
| 345 | 345 | if changed_files.is_empty() { |
| 346 | return false; | |
| 346 | return (false, None); | |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | let (change, modified_rust_files, workspace_structure_change) = |
| ... | ... | @@ -439,7 +439,7 @@ impl GlobalState { |
| 439 | 439 | (change, modified_rust_files, workspace_structure_change) |
| 440 | 440 | }); |
| 441 | 441 | |
| 442 | self.analysis_host.apply_change(change); | |
| 442 | let cancellation_time = self.analysis_host.apply_change(change); | |
| 443 | 443 | |
| 444 | 444 | if !modified_ratoml_files.is_empty() |
| 445 | 445 | || !self.config.same_source_root_parent_map(&self.local_roots_parent_map) |
| ... | ... | @@ -561,7 +561,7 @@ impl GlobalState { |
| 561 | 561 | } |
| 562 | 562 | } |
| 563 | 563 | |
| 564 | true | |
| 564 | (true, Some(cancellation_time)) | |
| 565 | 565 | } |
| 566 | 566 | |
| 567 | 567 | pub(crate) fn snapshot(&self) -> GlobalStateSnapshot { |
src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs+79-36| ... | ... | @@ -307,15 +307,11 @@ impl GlobalState { |
| 307 | 307 | let _p = tracing::info_span!("GlobalState::handle_event", event = %event).entered(); |
| 308 | 308 | |
| 309 | 309 | let event_dbg_msg = format!("{event:?}"); |
| 310 | tracing::debug!(?loop_start, ?event, "handle_event"); | |
| 311 | if tracing::enabled!(tracing::Level::TRACE) { | |
| 312 | let task_queue_len = self.task_pool.handle.len(); | |
| 313 | if task_queue_len > 0 { | |
| 314 | tracing::trace!("task queue len: {}", task_queue_len); | |
| 315 | } | |
| 316 | } | |
| 310 | tracing::debug!(?event, "handle_event"); | |
| 317 | 311 | |
| 318 | 312 | let was_quiescent = self.is_quiescent(); |
| 313 | ||
| 314 | let mut cancellation_time = None; | |
| 319 | 315 | match event { |
| 320 | 316 | Event::Lsp(msg) => match msg { |
| 321 | 317 | lsp_server::Message::Request(req) => self.on_new_request(loop_start, req), |
| ... | ... | @@ -326,7 +322,9 @@ impl GlobalState { |
| 326 | 322 | let _p = tracing::info_span!("GlobalState::handle_event/queued_task").entered(); |
| 327 | 323 | self.handle_deferred_task(task); |
| 328 | 324 | // Coalesce multiple deferred task events into one loop turn |
| 329 | while let Ok(task) = self.deferred_task_queue.receiver.try_recv() { | |
| 325 | while loop_start.elapsed() < Duration::from_millis(50) | |
| 326 | && let Ok(task) = self.deferred_task_queue.receiver.try_recv() | |
| 327 | { | |
| 330 | 328 | self.handle_deferred_task(task); |
| 331 | 329 | } |
| 332 | 330 | } |
| ... | ... | @@ -334,14 +332,16 @@ impl GlobalState { |
| 334 | 332 | let _p = tracing::info_span!("GlobalState::handle_event/task").entered(); |
| 335 | 333 | let mut prime_caches_progress = Vec::new(); |
| 336 | 334 | |
| 337 | self.handle_task(&mut prime_caches_progress, task); | |
| 335 | cancellation_time = self.handle_task(&mut prime_caches_progress, task); | |
| 338 | 336 | // Coalesce multiple task events into one loop turn |
| 339 | while let Ok(task) = self.task_pool.receiver.try_recv() { | |
| 337 | while loop_start.elapsed() < Duration::from_millis(50) | |
| 338 | && let Ok(task) = self.task_pool.receiver.try_recv() | |
| 339 | { | |
| 340 | 340 | self.handle_task(&mut prime_caches_progress, task); |
| 341 | 341 | } |
| 342 | 342 | |
| 343 | 343 | let title = "Indexing"; |
| 344 | let cancel_token = Some("rustAnalyzer/cachePriming".to_owned()); | |
| 344 | let cancel_token = || Some("rustAnalyzer/cachePriming".to_owned()); | |
| 345 | 345 | |
| 346 | 346 | let mut last_report = None; |
| 347 | 347 | for progress in prime_caches_progress { |
| ... | ... | @@ -352,7 +352,7 @@ impl GlobalState { |
| 352 | 352 | Progress::Begin, |
| 353 | 353 | None, |
| 354 | 354 | Some(0.0), |
| 355 | cancel_token.clone(), | |
| 355 | cancel_token(), | |
| 356 | 356 | ); |
| 357 | 357 | } |
| 358 | 358 | PrimeCachesProgress::Report(report) => { |
| ... | ... | @@ -387,6 +387,16 @@ impl GlobalState { |
| 387 | 387 | if cancelled { |
| 388 | 388 | self.prime_caches_queue |
| 389 | 389 | .request_op("restart after cancellation".to_owned(), ()); |
| 390 | } else if self.config.check_on_save(None) | |
| 391 | && self.config.flycheck_workspace(None) | |
| 392 | && !self.fetch_build_data_queue.op_requested() | |
| 393 | { | |
| 394 | // Priming finished; now run the deferred initial workspace flycheck | |
| 395 | // (kept off the critical path so `cargo check` doesn't contend with | |
| 396 | // cache priming for CPU). | |
| 397 | self.flycheck | |
| 398 | .iter() | |
| 399 | .for_each(|flycheck| flycheck.restart_workspace(None)); | |
| 390 | 400 | } |
| 391 | 401 | if let Some((message, fraction, title)) = last_report.take() { |
| 392 | 402 | self.report_progress( |
| ... | ... | @@ -394,7 +404,7 @@ impl GlobalState { |
| 394 | 404 | Progress::Report, |
| 395 | 405 | message, |
| 396 | 406 | Some(fraction), |
| 397 | cancel_token.clone(), | |
| 407 | cancel_token(), | |
| 398 | 408 | ); |
| 399 | 409 | } |
| 400 | 410 | self.report_progress( |
| ... | ... | @@ -402,7 +412,7 @@ impl GlobalState { |
| 402 | 412 | Progress::End, |
| 403 | 413 | None, |
| 404 | 414 | Some(1.0), |
| 405 | cancel_token.clone(), | |
| 415 | cancel_token(), | |
| 406 | 416 | ); |
| 407 | 417 | } |
| 408 | 418 | }; |
| ... | ... | @@ -413,7 +423,7 @@ impl GlobalState { |
| 413 | 423 | Progress::Report, |
| 414 | 424 | message, |
| 415 | 425 | Some(fraction), |
| 416 | cancel_token.clone(), | |
| 426 | cancel_token(), | |
| 417 | 427 | ); |
| 418 | 428 | } |
| 419 | 429 | } |
| ... | ... | @@ -422,7 +432,9 @@ impl GlobalState { |
| 422 | 432 | let mut last_progress_report = None; |
| 423 | 433 | self.handle_vfs_msg(message, &mut last_progress_report); |
| 424 | 434 | // Coalesce many VFS event into a single loop turn |
| 425 | while let Ok(message) = self.loader.receiver.try_recv() { | |
| 435 | while loop_start.elapsed() < Duration::from_millis(50) | |
| 436 | && let Ok(message) = self.loader.receiver.try_recv() | |
| 437 | { | |
| 426 | 438 | self.handle_vfs_msg(message, &mut last_progress_report); |
| 427 | 439 | } |
| 428 | 440 | if let Some((message, fraction)) = last_progress_report { |
| ... | ... | @@ -439,7 +451,9 @@ impl GlobalState { |
| 439 | 451 | let mut cargo_finished = false; |
| 440 | 452 | self.handle_flycheck_msg(message, &mut cargo_finished); |
| 441 | 453 | // Coalesce many flycheck updates into a single loop turn |
| 442 | while let Ok(message) = self.flycheck_receiver.try_recv() { | |
| 454 | while loop_start.elapsed() < Duration::from_millis(50) | |
| 455 | && let Ok(message) = self.flycheck_receiver.try_recv() | |
| 456 | { | |
| 443 | 457 | self.handle_flycheck_msg(message, &mut cargo_finished); |
| 444 | 458 | } |
| 445 | 459 | if cargo_finished { |
| ... | ... | @@ -453,14 +467,18 @@ impl GlobalState { |
| 453 | 467 | let _p = tracing::info_span!("GlobalState::handle_event/test_result").entered(); |
| 454 | 468 | self.handle_cargo_test_msg(message); |
| 455 | 469 | // Coalesce many test result event into a single loop turn |
| 456 | while let Ok(message) = self.test_run_receiver.try_recv() { | |
| 470 | while loop_start.elapsed() < Duration::from_millis(50) | |
| 471 | && let Ok(message) = self.test_run_receiver.try_recv() | |
| 472 | { | |
| 457 | 473 | self.handle_cargo_test_msg(message); |
| 458 | 474 | } |
| 459 | 475 | } |
| 460 | 476 | Event::DiscoverProject(message) => { |
| 461 | 477 | self.handle_discover_msg(message); |
| 462 | 478 | // Coalesce many project discovery events into a single loop turn. |
| 463 | while let Ok(message) = self.discover_receiver.try_recv() { | |
| 479 | while loop_start.elapsed() < Duration::from_millis(50) | |
| 480 | && let Ok(message) = self.discover_receiver.try_recv() | |
| 481 | { | |
| 464 | 482 | self.handle_discover_msg(message); |
| 465 | 483 | } |
| 466 | 484 | } |
| ... | ... | @@ -469,26 +487,29 @@ impl GlobalState { |
| 469 | 487 | } |
| 470 | 488 | } |
| 471 | 489 | let event_handling_duration = loop_start.elapsed(); |
| 472 | let (state_changed, memdocs_added_or_removed) = if self.vfs_done { | |
| 473 | if let Some(cause) = self.wants_to_switch.take() { | |
| 474 | self.switch_workspaces(cause); | |
| 475 | } | |
| 476 | (self.process_changes(), self.mem_docs.take_changes()) | |
| 477 | } else { | |
| 478 | (false, false) | |
| 490 | let ((state_changed, changes_cancellation_time), memdocs_added_or_removed) = | |
| 491 | if self.vfs_done { | |
| 492 | if let Some(cause) = self.wants_to_switch.take() { | |
| 493 | cancellation_time = match (cancellation_time, self.switch_workspaces(cause)) { | |
| 494 | (Some(a), Some(b)) => Some(a + b), | |
| 495 | (Some(d), None) | (None, Some(d)) => Some(d), | |
| 496 | (None, None) => None, | |
| 497 | }; | |
| 498 | } | |
| 499 | (self.process_changes(), self.mem_docs.take_changes()) | |
| 500 | } else { | |
| 501 | ((false, None), false) | |
| 502 | }; | |
| 503 | cancellation_time = match (cancellation_time, changes_cancellation_time) { | |
| 504 | (Some(a), Some(b)) => Some(a + b), | |
| 505 | (Some(d), None) | (None, Some(d)) => Some(d), | |
| 506 | (None, None) => None, | |
| 479 | 507 | }; |
| 480 | 508 | |
| 481 | 509 | let mut gc_elapsed = None; |
| 482 | 510 | if self.is_quiescent() { |
| 483 | 511 | let became_quiescent = !was_quiescent; |
| 484 | 512 | if became_quiescent { |
| 485 | if self.config.check_on_save(None) | |
| 486 | && self.config.flycheck_workspace(None) | |
| 487 | && !self.fetch_build_data_queue.op_requested() | |
| 488 | { | |
| 489 | // Project has loaded properly, kick off initial flycheck | |
| 490 | self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None)); | |
| 491 | } | |
| 492 | 513 | // delay initial cache priming until proc macros are loaded, or we will load up a bunch of garbage into salsa |
| 493 | 514 | let proc_macros_loaded = self.config.prefill_caches() |
| 494 | 515 | && (!self.config.expand_proc_macros() |
| ... | ... | @@ -496,6 +517,19 @@ impl GlobalState { |
| 496 | 517 | if proc_macros_loaded { |
| 497 | 518 | self.prime_caches_queue.request_op("became quiescent".to_owned(), ()); |
| 498 | 519 | } |
| 520 | if self.config.check_on_save(None) | |
| 521 | && self.config.flycheck_workspace(None) | |
| 522 | && !self.fetch_build_data_queue.op_requested() | |
| 523 | { | |
| 524 | if !self.config.prefill_caches() { | |
| 525 | self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None)); | |
| 526 | } else if proc_macros_loaded | |
| 527 | && !self.prime_caches_queue.op_in_progress() | |
| 528 | && !self.prime_caches_queue.op_requested() | |
| 529 | { | |
| 530 | self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None)); | |
| 531 | } | |
| 532 | } | |
| 499 | 533 | } |
| 500 | 534 | |
| 501 | 535 | let client_refresh = became_quiescent || state_changed; |
| ... | ... | @@ -593,11 +627,13 @@ impl GlobalState { |
| 593 | 627 | tracing::warn!( |
| 594 | 628 | "overly long loop turn took {loop_duration:?}:\n\ |
| 595 | 629 | (event handling took {event_handling_duration:?}): {event_dbg_msg}\n\ |
| 630 | (cancellation took {cancellation_time:?}) | |
| 596 | 631 | (garbage collection took {gc_elapsed:?})" |
| 597 | 632 | ); |
| 598 | 633 | self.poke_rust_analyzer_developer(format!( |
| 599 | 634 | "overly long loop turn took {loop_duration:?}:\n\ |
| 600 | 635 | (event handling took {event_handling_duration:?}): {event_dbg_msg}\n\ |
| 636 | (cancellation took {cancellation_time:?}) | |
| 601 | 637 | (garbage collection took {gc_elapsed:?})" |
| 602 | 638 | )); |
| 603 | 639 | } |
| ... | ... | @@ -803,7 +839,12 @@ impl GlobalState { |
| 803 | 839 | } |
| 804 | 840 | } |
| 805 | 841 | |
| 806 | fn handle_task(&mut self, prime_caches_progress: &mut Vec<PrimeCachesProgress>, task: Task) { | |
| 842 | fn handle_task( | |
| 843 | &mut self, | |
| 844 | prime_caches_progress: &mut Vec<PrimeCachesProgress>, | |
| 845 | task: Task, | |
| 846 | ) -> Option<Duration> { | |
| 847 | let mut cancellation_time = None; | |
| 807 | 848 | match task { |
| 808 | 849 | Task::Response(response) => self.respond(response), |
| 809 | 850 | // Only retry requests that haven't been cancelled. Otherwise we do unnecessary work. |
| ... | ... | @@ -906,8 +947,9 @@ impl GlobalState { |
| 906 | 947 | ProcMacroProgress::Report(msg) => (Some(Progress::Report), Some(msg)), |
| 907 | 948 | ProcMacroProgress::End(change) => { |
| 908 | 949 | self.fetch_proc_macros_queue.op_completed(true); |
| 909 | self.analysis_host.apply_change(change); | |
| 910 | self.finish_loading_crate_graph(); | |
| 950 | cancellation_time = Some(self.analysis_host.apply_change(change)); | |
| 951 | // FIXME This feels a bit off, this should go through similar machinery as build scripts? | |
| 952 | _ = self.finish_loading_crate_graph(); | |
| 911 | 953 | (Some(Progress::End), None) |
| 912 | 954 | } |
| 913 | 955 | }; |
| ... | ... | @@ -921,6 +963,7 @@ impl GlobalState { |
| 921 | 963 | self.send_notification::<lsp_ext::DiscoveredTests>(tests); |
| 922 | 964 | } |
| 923 | 965 | } |
| 966 | cancellation_time | |
| 924 | 967 | } |
| 925 | 968 | |
| 926 | 969 | fn handle_vfs_msg( |
src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs+22-22| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | //! project is currently loading and we don't have a full project model, we |
| 14 | 14 | //! still want to respond to various requests. |
| 15 | 15 | // FIXME: This is a mess that needs some untangling work |
| 16 | use std::{iter, mem, sync::atomic::AtomicUsize}; | |
| 16 | use std::{iter, mem, sync::atomic::AtomicUsize, time::Duration}; | |
| 17 | 17 | |
| 18 | 18 | use hir::{ChangeWithProcMacros, ProcMacrosBuilder, db::DefDatabase}; |
| 19 | 19 | use ide_db::{ |
| ... | ... | @@ -468,25 +468,22 @@ impl GlobalState { |
| 468 | 468 | }); |
| 469 | 469 | } |
| 470 | 470 | |
| 471 | pub(crate) fn switch_workspaces(&mut self, cause: Cause) { | |
| 471 | pub(crate) fn switch_workspaces(&mut self, cause: Cause) -> Option<Duration> { | |
| 472 | 472 | let _p = tracing::info_span!("GlobalState::switch_workspaces").entered(); |
| 473 | 473 | tracing::info!(%cause, "will switch workspaces"); |
| 474 | 474 | |
| 475 | let Some(FetchWorkspaceResponse { workspaces, force_crate_graph_reload }) = | |
| 476 | self.fetch_workspaces_queue.last_op_result() | |
| 477 | else { | |
| 478 | return; | |
| 479 | }; | |
| 475 | let FetchWorkspaceResponse { workspaces, force_crate_graph_reload } = | |
| 476 | self.fetch_workspaces_queue.last_op_result()?; | |
| 480 | 477 | let switching_from_empty_workspace = self.workspaces.is_empty(); |
| 481 | 478 | |
| 482 | 479 | info!(%cause, ?force_crate_graph_reload, %switching_from_empty_workspace); |
| 483 | 480 | if self.fetch_workspace_error().is_err() && !switching_from_empty_workspace { |
| 484 | 481 | if *force_crate_graph_reload { |
| 485 | self.recreate_crate_graph(cause, false); | |
| 482 | return self.recreate_crate_graph(cause, false); | |
| 486 | 483 | } |
| 487 | 484 | // It only makes sense to switch to a partially broken workspace |
| 488 | 485 | // if we don't have any workspace at all yet. |
| 489 | return; | |
| 486 | return None; | |
| 490 | 487 | } |
| 491 | 488 | |
| 492 | 489 | let workspaces = |
| ... | ... | @@ -501,7 +498,7 @@ impl GlobalState { |
| 501 | 498 | if same_workspaces { |
| 502 | 499 | if switching_from_empty_workspace { |
| 503 | 500 | // Switching from empty to empty is a no-op |
| 504 | return; | |
| 501 | return None; | |
| 505 | 502 | } |
| 506 | 503 | if let Some(FetchBuildDataResponse { workspaces, build_scripts }) = |
| 507 | 504 | self.fetch_build_data_queue.last_op_result() |
| ... | ... | @@ -524,20 +521,20 @@ impl GlobalState { |
| 524 | 521 | } else { |
| 525 | 522 | info!("build scripts do not match the version of the active workspace"); |
| 526 | 523 | if *force_crate_graph_reload { |
| 527 | self.recreate_crate_graph(cause, switching_from_empty_workspace); | |
| 524 | return self.recreate_crate_graph(cause, switching_from_empty_workspace); | |
| 528 | 525 | } |
| 529 | 526 | |
| 530 | 527 | // Current build scripts do not match the version of the active |
| 531 | 528 | // workspace, so there's nothing for us to update. |
| 532 | return; | |
| 529 | return None; | |
| 533 | 530 | } |
| 534 | 531 | } else { |
| 535 | 532 | if *force_crate_graph_reload { |
| 536 | self.recreate_crate_graph(cause, switching_from_empty_workspace); | |
| 533 | return self.recreate_crate_graph(cause, switching_from_empty_workspace); | |
| 537 | 534 | } |
| 538 | 535 | |
| 539 | 536 | // No build scripts but unchanged workspaces, nothing to do here |
| 540 | return; | |
| 537 | return None; | |
| 541 | 538 | } |
| 542 | 539 | } else { |
| 543 | 540 | info!("abandon build scripts for workspaces"); |
| ... | ... | @@ -560,7 +557,7 @@ impl GlobalState { |
| 560 | 557 | // `switch_workspaces()` will be called again when build scripts already run, which should |
| 561 | 558 | // take a short time. If we update the workspace now we will invalidate proc macros and cfgs, |
| 562 | 559 | // and then when build scripts complete we will invalidate them again. |
| 563 | return; | |
| 560 | return None; | |
| 564 | 561 | } |
| 565 | 562 | } |
| 566 | 563 | } |
| ... | ... | @@ -733,13 +730,15 @@ impl GlobalState { |
| 733 | 730 | self.local_roots_parent_map = Arc::new(self.source_root_config.source_root_parent_map()); |
| 734 | 731 | |
| 735 | 732 | info!(?cause, "recreating the crate graph"); |
| 736 | self.recreate_crate_graph(cause, switching_from_empty_workspace); | |
| 733 | let cancellation_time = self.recreate_crate_graph(cause, switching_from_empty_workspace); | |
| 737 | 734 | |
| 738 | 735 | info!("did switch workspaces"); |
| 736 | cancellation_time | |
| 739 | 737 | } |
| 740 | 738 | |
| 741 | fn recreate_crate_graph(&mut self, cause: String, initial_build: bool) { | |
| 739 | fn recreate_crate_graph(&mut self, cause: String, initial_build: bool) -> Option<Duration> { | |
| 742 | 740 | info!(?cause, "Building Crate Graph"); |
| 741 | let mut cancellation_time = None; | |
| 743 | 742 | self.report_progress( |
| 744 | 743 | "Building CrateGraph", |
| 745 | 744 | crate::lsp::utils::Progress::Begin, |
| ... | ... | @@ -795,9 +794,8 @@ impl GlobalState { |
| 795 | 794 | } |
| 796 | 795 | |
| 797 | 796 | change.set_crate_graph(crate_graph); |
| 798 | self.analysis_host.apply_change(change); | |
| 799 | ||
| 800 | self.finish_loading_crate_graph(); | |
| 797 | cancellation_time = Some(self.analysis_host.apply_change(change)); | |
| 798 | _ = self.finish_loading_crate_graph(); | |
| 801 | 799 | } else { |
| 802 | 800 | change.set_crate_graph(crate_graph); |
| 803 | 801 | self.fetch_proc_macros_queue.request_op(cause, (change, proc_macro_paths)); |
| ... | ... | @@ -810,11 +808,13 @@ impl GlobalState { |
| 810 | 808 | None, |
| 811 | 809 | None, |
| 812 | 810 | ); |
| 811 | cancellation_time | |
| 813 | 812 | } |
| 814 | 813 | |
| 815 | pub(crate) fn finish_loading_crate_graph(&mut self) { | |
| 816 | self.process_changes(); | |
| 814 | pub(crate) fn finish_loading_crate_graph(&mut self) -> Option<Duration> { | |
| 815 | let (_, cancellation_time) = self.process_changes(); | |
| 817 | 816 | self.reload_flycheck(); |
| 817 | cancellation_time | |
| 818 | 818 | } |
| 819 | 819 | |
| 820 | 820 | pub(super) fn fetch_workspace_error(&self) -> Result<(), String> { |
src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs+11-1| ... | ... | @@ -153,6 +153,9 @@ impl CargoTargetSpec { |
| 153 | 153 | Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => { |
| 154 | 154 | config.test_command |
| 155 | 155 | } |
| 156 | Some(CargoTargetSpec { target_kind: TargetKind::Bench, .. }) => { | |
| 157 | config.bench_command | |
| 158 | } | |
| 156 | 159 | _ => "run".to_owned(), |
| 157 | 160 | }; |
| 158 | 161 | cargo_args.push(subcommand); |
| ... | ... | @@ -225,6 +228,9 @@ impl CargoTargetSpec { |
| 225 | 228 | Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => { |
| 226 | 229 | (config.test_override_command, None) |
| 227 | 230 | } |
| 231 | Some(CargoTargetSpec { target_kind: TargetKind::Bench, .. }) => { | |
| 232 | (config.bench_override_command, None) | |
| 233 | } | |
| 228 | 234 | _ => (None, None), |
| 229 | 235 | }, |
| 230 | 236 | }; |
| ... | ... | @@ -319,7 +325,11 @@ impl CargoTargetSpec { |
| 319 | 325 | |
| 320 | 326 | pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) { |
| 321 | 327 | buf.push("--package".to_owned()); |
| 322 | buf.push(self.package); | |
| 328 | if self.package.contains(":") { | |
| 329 | buf.push(self.package_id.to_string()); | |
| 330 | } else { | |
| 331 | buf.push(self.package); | |
| 332 | } | |
| 323 | 333 | |
| 324 | 334 | // Can't mix --doc with other target flags |
| 325 | 335 | if let RunnableKind::DocTest { .. } = kind { |
src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs-4| ... | ... | @@ -40,10 +40,6 @@ impl<T> TaskPool<T> { |
| 40 | 40 | }) |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | pub(crate) fn len(&self) -> usize { | |
| 44 | self.pool.len() | |
| 45 | } | |
| 46 | ||
| 47 | 43 | pub(crate) fn is_empty(&self) -> bool { |
| 48 | 44 | self.pool.is_empty() |
| 49 | 45 | } |
src/tools/rust-analyzer/crates/syntax/src/ast.rs-1| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | //! Abstract Syntax Tree, layered on top of untyped `SyntaxNode`s |
| 2 | 2 | |
| 3 | 3 | pub mod edit; |
| 4 | pub mod edit_in_place; | |
| 5 | 4 | mod expr_ext; |
| 6 | 5 | mod generated; |
| 7 | 6 | pub mod make; |
src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs+130-1| ... | ... | @@ -13,7 +13,7 @@ use crate::{ |
| 13 | 13 | SyntaxKind::{ATTR, COMMENT, WHITESPACE}, |
| 14 | 14 | SyntaxNode, SyntaxToken, |
| 15 | 15 | ast::{self, AstNode, HasName, make}, |
| 16 | syntax_editor::{Position, SyntaxEditor, SyntaxMappingBuilder}, | |
| 16 | syntax_editor::{Position, Removable, SyntaxEditor, SyntaxMappingBuilder}, | |
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | 19 | use super::syntax_factory::SyntaxFactory; |
| ... | ... | @@ -263,6 +263,109 @@ pub fn indent(node: &SyntaxNode, level: IndentLevel) -> SyntaxNode { |
| 263 | 263 | level.clone_increase_indent(node) |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | impl ast::GenericParamList { | |
| 267 | /// Constructs a matching [`ast::GenericArgList`] | |
| 268 | pub fn to_generic_args(&self, make: &SyntaxFactory) -> ast::GenericArgList { | |
| 269 | let args = self.generic_params().filter_map(|param| match param { | |
| 270 | ast::GenericParam::LifetimeParam(it) => { | |
| 271 | Some(ast::GenericArg::LifetimeArg(make.lifetime_arg(it.lifetime()?))) | |
| 272 | } | |
| 273 | ast::GenericParam::TypeParam(it) => { | |
| 274 | Some(ast::GenericArg::TypeArg(make.type_arg(make.ty_name(it.name()?)))) | |
| 275 | } | |
| 276 | ast::GenericParam::ConstParam(it) => { | |
| 277 | // Name-only const params get parsed as `TypeArg`s | |
| 278 | Some(ast::GenericArg::TypeArg(make.type_arg(make.ty_name(it.name()?)))) | |
| 279 | } | |
| 280 | }); | |
| 281 | ||
| 282 | make::generic_arg_list(args) | |
| 283 | } | |
| 284 | } | |
| 285 | ||
| 286 | impl ast::UseTree { | |
| 287 | /// Deletes the usetree node represented by the input. Recursively removes parents, including use nodes that become empty. | |
| 288 | pub fn remove_recursive(self, editor: &SyntaxEditor) { | |
| 289 | let parent = self.syntax().parent(); | |
| 290 | ||
| 291 | if let Some(u) = parent.clone().and_then(ast::Use::cast) { | |
| 292 | u.remove(editor); | |
| 293 | } else if let Some(u) = parent.and_then(ast::UseTreeList::cast) { | |
| 294 | if u.use_trees().nth(1).is_none() | |
| 295 | || u.use_trees().all(|use_tree| { | |
| 296 | use_tree.syntax() == self.syntax() || editor.deleted(use_tree.syntax()) | |
| 297 | }) | |
| 298 | { | |
| 299 | u.parent_use_tree().remove_recursive(editor); | |
| 300 | return; | |
| 301 | } | |
| 302 | self.remove(editor); | |
| 303 | u.remove_unnecessary_braces(editor); | |
| 304 | } | |
| 305 | } | |
| 306 | ||
| 307 | /// Splits off the given prefix, making it the path component of the use tree, | |
| 308 | /// appending the rest of the path to all UseTreeList items. | |
| 309 | /// | |
| 310 | /// # Examples | |
| 311 | /// | |
| 312 | /// `prefix$0::suffix` -> `prefix::{suffix}` | |
| 313 | /// | |
| 314 | /// `prefix$0` -> `prefix::{self}` | |
| 315 | /// | |
| 316 | /// `prefix$0::*` -> `prefix::{*}` | |
| 317 | pub fn split_prefix_with_editor(&self, editor: &SyntaxEditor, prefix: &ast::Path) { | |
| 318 | debug_assert_eq!(self.path(), Some(prefix.top_path())); | |
| 319 | ||
| 320 | let make = editor.make(); | |
| 321 | let path = self.path().unwrap(); | |
| 322 | let suffix = if path == *prefix { | |
| 323 | if self.use_tree_list().is_some() { | |
| 324 | return; | |
| 325 | } else if self.star_token().is_some() { | |
| 326 | make.use_tree_glob() | |
| 327 | } else { | |
| 328 | let self_path = make.path_unqualified(make.path_segment_self()); | |
| 329 | make.use_tree(self_path, None, self.rename(), false) | |
| 330 | } | |
| 331 | } else { | |
| 332 | let suffix_segments = path.segments().skip(prefix.segments().count()); | |
| 333 | let suffix_path = make.path_from_segments(suffix_segments, false); | |
| 334 | make.use_tree( | |
| 335 | suffix_path, | |
| 336 | self.use_tree_list(), | |
| 337 | self.rename(), | |
| 338 | self.star_token().is_some(), | |
| 339 | ) | |
| 340 | }; | |
| 341 | let use_tree_list = make.use_tree_list(once(suffix)); | |
| 342 | let new_use_tree = make.use_tree(prefix.clone(), Some(use_tree_list), None, false); | |
| 343 | ||
| 344 | editor.replace(self.syntax(), new_use_tree.syntax()); | |
| 345 | } | |
| 346 | } | |
| 347 | ||
| 348 | impl ast::RecordExprField { | |
| 349 | /// This will either replace the initializer, or in the case that this is a shorthand convert | |
| 350 | /// the initializer into the name ref and insert the expr as the new initializer. | |
| 351 | pub fn replace_expr(&self, editor: &SyntaxEditor, expr: ast::Expr) { | |
| 352 | if self.name_ref().is_some() { | |
| 353 | if let Some(prev) = self.expr() { | |
| 354 | editor.replace(prev.syntax(), expr.syntax()); | |
| 355 | } | |
| 356 | } else if let Some(ast::Expr::PathExpr(path_expr)) = self.expr() | |
| 357 | && let Some(path) = path_expr.path() | |
| 358 | && let Some(name_ref) = path.as_single_name_ref() | |
| 359 | { | |
| 360 | // shorthand `{ x }` → expand to `{ x: expr }` | |
| 361 | let new_field = editor | |
| 362 | .make() | |
| 363 | .record_expr_field(editor.make().name_ref(&name_ref.text()), Some(expr)); | |
| 364 | editor.replace(self.syntax(), new_field.syntax()); | |
| 365 | } | |
| 366 | } | |
| 367 | } | |
| 368 | ||
| 266 | 369 | #[test] |
| 267 | 370 | fn test_increase_indent() { |
| 268 | 371 | let arm_list = { |
| ... | ... | @@ -285,3 +388,29 @@ fn test_increase_indent() { |
| 285 | 388 | }" |
| 286 | 389 | ); |
| 287 | 390 | } |
| 391 | ||
| 392 | #[test] | |
| 393 | fn split_prefix_inserts_self() { | |
| 394 | check_split_prefix("use foo;", "foo::{self}"); | |
| 395 | } | |
| 396 | ||
| 397 | #[test] | |
| 398 | fn split_prefix_preserves_rename() { | |
| 399 | check_split_prefix("use foo as bar;", "foo::{self as bar}"); | |
| 400 | } | |
| 401 | ||
| 402 | #[test] | |
| 403 | fn split_prefix_wraps_glob() { | |
| 404 | check_split_prefix("use foo::*;", "foo::{*}"); | |
| 405 | } | |
| 406 | ||
| 407 | #[cfg(test)] | |
| 408 | fn check_split_prefix(before: &str, expected: &str) { | |
| 409 | let source = crate::SourceFile::parse(before, parser::Edition::CURRENT).tree(); | |
| 410 | let use_tree = source.syntax().descendants().find_map(ast::UseTree::cast).unwrap(); | |
| 411 | let (editor, use_tree) = SyntaxEditor::with_ast_node(&use_tree); | |
| 412 | let prefix = use_tree.path().unwrap(); | |
| 413 | use_tree.split_prefix_with_editor(&editor, &prefix); | |
| 414 | let edit = editor.finish(); | |
| 415 | assert_eq!(edit.new_root().to_string(), expected); | |
| 416 | } |
src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs deleted-318| ... | ... | @@ -1,318 +0,0 @@ |
| 1 | //! Structural editing for ast. | |
| 2 | ||
| 3 | use std::iter::{empty, once, successors}; | |
| 4 | ||
| 5 | use parser::T; | |
| 6 | ||
| 7 | use crate::{ | |
| 8 | AstNode, AstToken, Direction, | |
| 9 | algo::{self, neighbor}, | |
| 10 | ast::{self, make, syntax_factory::SyntaxFactory}, | |
| 11 | syntax_editor::SyntaxEditor, | |
| 12 | ted, | |
| 13 | }; | |
| 14 | ||
| 15 | use super::HasName; | |
| 16 | ||
| 17 | impl ast::GenericParamList { | |
| 18 | /// Constructs a matching [`ast::GenericArgList`] | |
| 19 | pub fn to_generic_args(&self, make: &SyntaxFactory) -> ast::GenericArgList { | |
| 20 | let args = self.generic_params().filter_map(|param| match param { | |
| 21 | ast::GenericParam::LifetimeParam(it) => { | |
| 22 | Some(ast::GenericArg::LifetimeArg(make.lifetime_arg(it.lifetime()?))) | |
| 23 | } | |
| 24 | ast::GenericParam::TypeParam(it) => { | |
| 25 | Some(ast::GenericArg::TypeArg(make.type_arg(make.ty_name(it.name()?)))) | |
| 26 | } | |
| 27 | ast::GenericParam::ConstParam(it) => { | |
| 28 | // Name-only const params get parsed as `TypeArg`s | |
| 29 | Some(ast::GenericArg::TypeArg(make.type_arg(make.ty_name(it.name()?)))) | |
| 30 | } | |
| 31 | }); | |
| 32 | ||
| 33 | make::generic_arg_list(args) | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | pub trait Removable: AstNode { | |
| 38 | fn remove(&self); | |
| 39 | } | |
| 40 | ||
| 41 | impl Removable for ast::UseTree { | |
| 42 | fn remove(&self) { | |
| 43 | for dir in [Direction::Next, Direction::Prev] { | |
| 44 | if let Some(next_use_tree) = neighbor(self, dir) { | |
| 45 | let separators = self | |
| 46 | .syntax() | |
| 47 | .siblings_with_tokens(dir) | |
| 48 | .skip(1) | |
| 49 | .take_while(|it| it.as_node() != Some(next_use_tree.syntax())); | |
| 50 | ted::remove_all_iter(separators); | |
| 51 | break; | |
| 52 | } | |
| 53 | } | |
| 54 | ted::remove(self.syntax()); | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | impl ast::UseTree { | |
| 59 | /// Editor variant of UseTree remove | |
| 60 | fn remove_with_editor(&self, editor: &SyntaxEditor) { | |
| 61 | for dir in [Direction::Next, Direction::Prev] { | |
| 62 | if let Some(next_use_tree) = neighbor(self, dir) { | |
| 63 | let separators = self | |
| 64 | .syntax() | |
| 65 | .siblings_with_tokens(dir) | |
| 66 | .skip(1) | |
| 67 | .take_while(|it| it.as_node() != Some(next_use_tree.syntax())); | |
| 68 | for separator in separators { | |
| 69 | editor.delete(separator); | |
| 70 | } | |
| 71 | break; | |
| 72 | } | |
| 73 | } | |
| 74 | editor.delete(self.syntax()); | |
| 75 | } | |
| 76 | ||
| 77 | /// Deletes the usetree node represented by the input. Recursively removes parents, including use nodes that become empty. | |
| 78 | pub fn remove_recursive(self, editor: &SyntaxEditor) { | |
| 79 | let parent = self.syntax().parent(); | |
| 80 | ||
| 81 | if let Some(u) = parent.clone().and_then(ast::Use::cast) { | |
| 82 | u.remove(editor); | |
| 83 | } else if let Some(u) = parent.and_then(ast::UseTreeList::cast) { | |
| 84 | if u.use_trees().nth(1).is_none() | |
| 85 | || u.use_trees().all(|use_tree| { | |
| 86 | use_tree.syntax() == self.syntax() || editor.deleted(use_tree.syntax()) | |
| 87 | }) | |
| 88 | { | |
| 89 | u.parent_use_tree().remove_recursive(editor); | |
| 90 | return; | |
| 91 | } | |
| 92 | self.remove_with_editor(editor); | |
| 93 | u.remove_unnecessary_braces(editor); | |
| 94 | } | |
| 95 | } | |
| 96 | ||
| 97 | pub fn get_or_create_use_tree_list(&self) -> ast::UseTreeList { | |
| 98 | match self.use_tree_list() { | |
| 99 | Some(it) => it, | |
| 100 | None => { | |
| 101 | let position = ted::Position::last_child_of(self.syntax()); | |
| 102 | let use_tree_list = make::use_tree_list(empty()).clone_for_update(); | |
| 103 | let mut elements = Vec::with_capacity(2); | |
| 104 | if self.coloncolon_token().is_none() { | |
| 105 | elements.push(make::token(T![::]).into()); | |
| 106 | } | |
| 107 | elements.push(use_tree_list.syntax().clone().into()); | |
| 108 | ted::insert_all_raw(position, elements); | |
| 109 | use_tree_list | |
| 110 | } | |
| 111 | } | |
| 112 | } | |
| 113 | ||
| 114 | /// Splits off the given prefix, making it the path component of the use tree, | |
| 115 | /// appending the rest of the path to all UseTreeList items. | |
| 116 | /// | |
| 117 | /// # Examples | |
| 118 | /// | |
| 119 | /// `prefix$0::suffix` -> `prefix::{suffix}` | |
| 120 | /// | |
| 121 | /// `prefix$0` -> `prefix::{self}` | |
| 122 | /// | |
| 123 | /// `prefix$0::*` -> `prefix::{*}` | |
| 124 | pub fn split_prefix(&self, prefix: &ast::Path) { | |
| 125 | debug_assert_eq!(self.path(), Some(prefix.top_path())); | |
| 126 | let path = self.path().unwrap(); | |
| 127 | if &path == prefix && self.use_tree_list().is_none() { | |
| 128 | if self.star_token().is_some() { | |
| 129 | // path$0::* -> * | |
| 130 | if let Some(a) = self.coloncolon_token() { | |
| 131 | ted::remove(a) | |
| 132 | } | |
| 133 | ted::remove(prefix.syntax()); | |
| 134 | } else { | |
| 135 | // path$0 -> self | |
| 136 | let self_suffix = | |
| 137 | make::path_unqualified(make::path_segment_self()).clone_for_update(); | |
| 138 | ted::replace(path.syntax(), self_suffix.syntax()); | |
| 139 | } | |
| 140 | } else if split_path_prefix(prefix).is_none() { | |
| 141 | return; | |
| 142 | } | |
| 143 | // At this point, prefix path is detached; _self_ use tree has suffix path. | |
| 144 | // Next, transform 'suffix' use tree into 'prefix::{suffix}' | |
| 145 | let subtree = self.clone_subtree().clone_for_update(); | |
| 146 | ted::remove_all_iter(self.syntax().children_with_tokens()); | |
| 147 | ted::insert(ted::Position::first_child_of(self.syntax()), prefix.syntax()); | |
| 148 | self.get_or_create_use_tree_list().add_use_tree(subtree); | |
| 149 | ||
| 150 | fn split_path_prefix(prefix: &ast::Path) -> Option<()> { | |
| 151 | let parent = prefix.parent_path()?; | |
| 152 | let segment = parent.segment()?; | |
| 153 | if algo::has_errors(segment.syntax()) { | |
| 154 | return None; | |
| 155 | } | |
| 156 | for p in successors(parent.parent_path(), |it| it.parent_path()) { | |
| 157 | p.segment()?; | |
| 158 | } | |
| 159 | if let Some(a) = prefix.parent_path().and_then(|p| p.coloncolon_token()) { | |
| 160 | ted::remove(a) | |
| 161 | } | |
| 162 | ted::remove(prefix.syntax()); | |
| 163 | Some(()) | |
| 164 | } | |
| 165 | } | |
| 166 | ||
| 167 | /// Editor variant of `split_prefix` | |
| 168 | pub fn split_prefix_with_editor(&self, editor: &SyntaxEditor, prefix: &ast::Path) { | |
| 169 | debug_assert_eq!(self.path(), Some(prefix.top_path())); | |
| 170 | ||
| 171 | let make = editor.make(); | |
| 172 | let path = self.path().unwrap(); | |
| 173 | let suffix = if path == *prefix && self.use_tree_list().is_none() { | |
| 174 | if self.star_token().is_some() { | |
| 175 | make.use_tree_glob() | |
| 176 | } else { | |
| 177 | let self_path = make.path_unqualified(make.path_segment_self()); | |
| 178 | make.use_tree(self_path, None, None, false) | |
| 179 | } | |
| 180 | } else { | |
| 181 | let suffix_segments = path.segments().skip(prefix.segments().count()); | |
| 182 | let suffix_path = make.path_from_segments(suffix_segments, false); | |
| 183 | make.use_tree( | |
| 184 | suffix_path, | |
| 185 | self.use_tree_list(), | |
| 186 | self.rename(), | |
| 187 | self.star_token().is_some(), | |
| 188 | ) | |
| 189 | }; | |
| 190 | let use_tree_list = make.use_tree_list(once(suffix)); | |
| 191 | let new_use_tree = make.use_tree(prefix.clone(), Some(use_tree_list), None, false); | |
| 192 | ||
| 193 | editor.replace(self.syntax(), new_use_tree.syntax()); | |
| 194 | } | |
| 195 | ||
| 196 | /// Wraps the use tree in use tree list with no top level path (if it isn't already). | |
| 197 | /// | |
| 198 | /// # Examples | |
| 199 | /// | |
| 200 | /// `foo::bar` -> `{foo::bar}` | |
| 201 | /// | |
| 202 | /// `{foo::bar}` -> `{foo::bar}` | |
| 203 | pub fn wrap_in_tree_list(&self) -> Option<()> { | |
| 204 | if self.use_tree_list().is_some() | |
| 205 | && self.path().is_none() | |
| 206 | && self.star_token().is_none() | |
| 207 | && self.rename().is_none() | |
| 208 | { | |
| 209 | return None; | |
| 210 | } | |
| 211 | let subtree = self.clone_subtree().clone_for_update(); | |
| 212 | ted::remove_all_iter(self.syntax().children_with_tokens()); | |
| 213 | ted::append_child( | |
| 214 | self.syntax(), | |
| 215 | make::use_tree_list(once(subtree)).clone_for_update().syntax(), | |
| 216 | ); | |
| 217 | Some(()) | |
| 218 | } | |
| 219 | } | |
| 220 | ||
| 221 | impl ast::UseTreeList { | |
| 222 | pub fn add_use_tree(&self, use_tree: ast::UseTree) { | |
| 223 | let (position, elements) = match self.use_trees().last() { | |
| 224 | Some(last_tree) => ( | |
| 225 | ted::Position::after(last_tree.syntax()), | |
| 226 | vec![ | |
| 227 | make::token(T![,]).into(), | |
| 228 | make::tokens::single_space().into(), | |
| 229 | use_tree.syntax.into(), | |
| 230 | ], | |
| 231 | ), | |
| 232 | None => { | |
| 233 | let position = match self.l_curly_token() { | |
| 234 | Some(l_curly) => ted::Position::after(l_curly), | |
| 235 | None => ted::Position::last_child_of(self.syntax()), | |
| 236 | }; | |
| 237 | (position, vec![use_tree.syntax.into()]) | |
| 238 | } | |
| 239 | }; | |
| 240 | ted::insert_all_raw(position, elements); | |
| 241 | } | |
| 242 | } | |
| 243 | ||
| 244 | impl ast::Use { | |
| 245 | fn remove(&self, editor: &SyntaxEditor) { | |
| 246 | let make = editor.make(); | |
| 247 | let next_ws = self | |
| 248 | .syntax() | |
| 249 | .next_sibling_or_token() | |
| 250 | .and_then(|it| it.into_token()) | |
| 251 | .and_then(ast::Whitespace::cast); | |
| 252 | if let Some(next_ws) = next_ws { | |
| 253 | let ws_text = next_ws.syntax().text(); | |
| 254 | if let Some(rest) = ws_text.strip_prefix('\n') { | |
| 255 | let next_use_removed = next_ws | |
| 256 | .syntax() | |
| 257 | .next_sibling_or_token() | |
| 258 | .and_then(|it| it.into_node()) | |
| 259 | .and_then(ast::Use::cast) | |
| 260 | .and_then(|use_| use_.use_tree()) | |
| 261 | .is_some_and(|use_tree| editor.deleted(use_tree.syntax())); | |
| 262 | if rest.is_empty() || next_use_removed { | |
| 263 | editor.delete(next_ws.syntax()); | |
| 264 | } else { | |
| 265 | editor.replace(next_ws.syntax(), make.whitespace(rest)); | |
| 266 | } | |
| 267 | } | |
| 268 | } | |
| 269 | let prev_ws = self | |
| 270 | .syntax() | |
| 271 | .prev_sibling_or_token() | |
| 272 | .and_then(|it| it.into_token()) | |
| 273 | .and_then(ast::Whitespace::cast); | |
| 274 | if let Some(prev_ws) = prev_ws { | |
| 275 | let ws_text = prev_ws.syntax().text(); | |
| 276 | let prev_newline = ws_text.rfind('\n').map(|x| x + 1).unwrap_or(0); | |
| 277 | let rest = &ws_text[0..prev_newline]; | |
| 278 | if rest.is_empty() { | |
| 279 | editor.delete(prev_ws.syntax()); | |
| 280 | } else { | |
| 281 | editor.replace(prev_ws.syntax(), make.whitespace(rest)); | |
| 282 | } | |
| 283 | } | |
| 284 | ||
| 285 | editor.delete(self.syntax()); | |
| 286 | } | |
| 287 | } | |
| 288 | ||
| 289 | impl ast::Impl { | |
| 290 | pub fn get_or_create_assoc_item_list(&self) -> ast::AssocItemList { | |
| 291 | if self.assoc_item_list().is_none() { | |
| 292 | let assoc_item_list = make::assoc_item_list(None).clone_for_update(); | |
| 293 | ted::append_child(self.syntax(), assoc_item_list.syntax()); | |
| 294 | } | |
| 295 | self.assoc_item_list().unwrap() | |
| 296 | } | |
| 297 | } | |
| 298 | ||
| 299 | impl ast::RecordExprField { | |
| 300 | /// This will either replace the initializer, or in the case that this is a shorthand convert | |
| 301 | /// the initializer into the name ref and insert the expr as the new initializer. | |
| 302 | pub fn replace_expr(&self, editor: &SyntaxEditor, expr: ast::Expr) { | |
| 303 | if self.name_ref().is_some() { | |
| 304 | if let Some(prev) = self.expr() { | |
| 305 | editor.replace(prev.syntax(), expr.syntax()); | |
| 306 | } | |
| 307 | } else if let Some(ast::Expr::PathExpr(path_expr)) = self.expr() | |
| 308 | && let Some(path) = path_expr.path() | |
| 309 | && let Some(name_ref) = path.as_single_name_ref() | |
| 310 | { | |
| 311 | // shorthand `{ x }` → expand to `{ x: expr }` | |
| 312 | let new_field = editor | |
| 313 | .make() | |
| 314 | .record_expr_field(editor.make().name_ref(&name_ref.text()), Some(expr)); | |
| 315 | editor.replace(self.syntax(), new_field.syntax()); | |
| 316 | } | |
| 317 | } | |
| 318 | } |
src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs+23| ... | ... | @@ -264,6 +264,14 @@ impl Expr { |
| 264 | 264 | return false; |
| 265 | 265 | } |
| 266 | 266 | |
| 267 | // Special-case `cond && <let-chain>` | |
| 268 | if let ast::Expr::BinExpr(parent) = parent | |
| 269 | && parent.op_kind() == Some(ast::BinaryOp::LogicOp(ast::LogicOp::And)) | |
| 270 | && self.contains_let_expr() | |
| 271 | { | |
| 272 | return false; | |
| 273 | } | |
| 274 | ||
| 267 | 275 | let (left, right, inv) = match self.is_ordered_before_parent_in_place_of(parent, place_of) { |
| 268 | 276 | true => (self, parent, false), |
| 269 | 277 | false => (parent, self, true), |
| ... | ... | @@ -551,4 +559,19 @@ impl Expr { |
| 551 | 559 | ForExpr(_) | IfExpr(_) | MatchExpr(_) | WhileExpr(_) | IncludeBytesExpr(_) => true, |
| 552 | 560 | } |
| 553 | 561 | } |
| 562 | ||
| 563 | fn contains_let_expr(&self) -> bool { | |
| 564 | use Expr::*; | |
| 565 | ||
| 566 | match self { | |
| 567 | LetExpr(_) => true, | |
| 568 | BinExpr(e) => { | |
| 569 | // if we find something other than a `&&`, then this can't be a let chain | |
| 570 | e.op_kind() == Some(ast::BinaryOp::LogicOp(ast::LogicOp::And)) | |
| 571 | && (e.lhs().is_none_or(|it| it.contains_let_expr()) | |
| 572 | || e.rhs().is_none_or(|it| it.contains_let_expr())) | |
| 573 | } | |
| 574 | _ => false, | |
| 575 | } | |
| 576 | } | |
| 554 | 577 | } |
src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs+31-2| ... | ... | @@ -4,8 +4,8 @@ use either::Either; |
| 4 | 4 | use crate::{ |
| 5 | 5 | AstNode, Edition, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, |
| 6 | 6 | ast::{ |
| 7 | self, HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, | |
| 8 | HasTypeBounds, HasVisibility, Lifetime, Param, RangeItem, make, | |
| 7 | self, HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasLoopBody, HasModuleItem, | |
| 8 | HasName, HasTypeBounds, HasVisibility, Lifetime, Param, RangeItem, make, | |
| 9 | 9 | }, |
| 10 | 10 | syntax_editor::SyntaxMappingBuilder, |
| 11 | 11 | }; |
| ... | ... | @@ -2015,6 +2015,35 @@ impl SyntaxFactory { |
| 2015 | 2015 | make::assoc_item_list(None).clone_for_update() |
| 2016 | 2016 | } |
| 2017 | 2017 | |
| 2018 | pub fn item_list(&self, items: impl IntoIterator<Item = ast::Item>) -> ast::ItemList { | |
| 2019 | let (items, input) = iterator_input(items); | |
| 2020 | let items_vec: Vec<_> = items.into_iter().collect(); | |
| 2021 | let ast = make::item_list(Some(items_vec)).clone_for_update(); | |
| 2022 | ||
| 2023 | if let Some(mut mapping) = self.mappings() { | |
| 2024 | let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | |
| 2025 | builder.map_children(input, ast.items().map(|item: ast::Item| item.syntax().clone())); | |
| 2026 | builder.finish(&mut mapping); | |
| 2027 | } | |
| 2028 | ||
| 2029 | ast | |
| 2030 | } | |
| 2031 | ||
| 2032 | pub fn mod_(&self, name: ast::Name, body: Option<ast::ItemList>) -> ast::Module { | |
| 2033 | let ast = make::mod_(name.clone(), body.clone()).clone_for_update(); | |
| 2034 | ||
| 2035 | if let Some(mut mapping) = self.mappings() { | |
| 2036 | let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | |
| 2037 | builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone()); | |
| 2038 | if let Some(body) = body { | |
| 2039 | builder.map_node(body.syntax().clone(), ast.item_list().unwrap().syntax().clone()); | |
| 2040 | } | |
| 2041 | builder.finish(&mut mapping); | |
| 2042 | } | |
| 2043 | ||
| 2044 | ast | |
| 2045 | } | |
| 2046 | ||
| 2018 | 2047 | pub fn attr_outer(&self, meta: ast::Meta) -> ast::Attr { |
| 2019 | 2048 | let ast = make::attr_outer(meta.clone()).clone_for_update(); |
| 2020 | 2049 |
src/tools/rust-analyzer/crates/syntax/src/lib.rs-1| ... | ... | @@ -39,7 +39,6 @@ pub mod ast; |
| 39 | 39 | pub mod fuzz; |
| 40 | 40 | pub mod hacks; |
| 41 | 41 | pub mod syntax_editor; |
| 42 | pub mod ted; | |
| 43 | 42 | pub mod utils; |
| 44 | 43 | |
| 45 | 44 | use std::{marker::PhantomData, ops::Range}; |
src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs+23-1| ... | ... | @@ -459,13 +459,35 @@ impl Removable for ast::Use { |
| 459 | 459 | if let Some(next_ws) = next_ws { |
| 460 | 460 | let ws_text = next_ws.syntax().text(); |
| 461 | 461 | if let Some(rest) = ws_text.strip_prefix('\n') { |
| 462 | if rest.is_empty() { | |
| 462 | let next_use_removed = next_ws | |
| 463 | .syntax() | |
| 464 | .next_sibling_or_token() | |
| 465 | .and_then(|it| it.into_node()) | |
| 466 | .and_then(ast::Use::cast) | |
| 467 | .and_then(|use_| use_.use_tree()) | |
| 468 | .is_some_and(|use_tree| editor.deleted(use_tree.syntax())); | |
| 469 | if rest.is_empty() || next_use_removed { | |
| 463 | 470 | editor.delete(next_ws.syntax()); |
| 464 | 471 | } else { |
| 465 | 472 | editor.replace(next_ws.syntax(), make.whitespace(rest)); |
| 466 | 473 | } |
| 467 | 474 | } |
| 468 | 475 | } |
| 476 | let prev_ws = self | |
| 477 | .syntax() | |
| 478 | .prev_sibling_or_token() | |
| 479 | .and_then(|it| it.into_token()) | |
| 480 | .and_then(ast::Whitespace::cast); | |
| 481 | if let Some(prev_ws) = prev_ws { | |
| 482 | let ws_text = prev_ws.syntax().text(); | |
| 483 | let prev_newline = ws_text.rfind('\n').map(|x| x + 1).unwrap_or(0); | |
| 484 | let rest = &ws_text[0..prev_newline]; | |
| 485 | if rest.is_empty() { | |
| 486 | editor.delete(prev_ws.syntax()); | |
| 487 | } else { | |
| 488 | editor.replace(prev_ws.syntax(), make.whitespace(rest)); | |
| 489 | } | |
| 490 | } | |
| 469 | 491 | |
| 470 | 492 | editor.delete(self.syntax()); |
| 471 | 493 | } |
src/tools/rust-analyzer/crates/syntax/src/ted.rs deleted-227| ... | ... | @@ -1,227 +0,0 @@ |
| 1 | //! Primitive tree editor, ed for trees. | |
| 2 | //! | |
| 3 | //! The `_raw`-suffixed functions insert elements as is, unsuffixed versions fix | |
| 4 | //! up elements around the edges. | |
| 5 | use std::{mem, ops::RangeInclusive}; | |
| 6 | ||
| 7 | use parser::T; | |
| 8 | use rowan::TextSize; | |
| 9 | ||
| 10 | use crate::{ | |
| 11 | SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, | |
| 12 | ast::{self, AstNode, edit::IndentLevel, make}, | |
| 13 | }; | |
| 14 | ||
| 15 | /// Utility trait to allow calling `ted` functions with references or owned | |
| 16 | /// nodes. Do not use outside of this module. | |
| 17 | pub trait Element { | |
| 18 | fn syntax_element(self) -> SyntaxElement; | |
| 19 | } | |
| 20 | ||
| 21 | impl<E: Element + Clone> Element for &'_ E { | |
| 22 | fn syntax_element(self) -> SyntaxElement { | |
| 23 | self.clone().syntax_element() | |
| 24 | } | |
| 25 | } | |
| 26 | impl Element for SyntaxElement { | |
| 27 | fn syntax_element(self) -> SyntaxElement { | |
| 28 | self | |
| 29 | } | |
| 30 | } | |
| 31 | impl Element for SyntaxNode { | |
| 32 | fn syntax_element(self) -> SyntaxElement { | |
| 33 | self.into() | |
| 34 | } | |
| 35 | } | |
| 36 | impl Element for SyntaxToken { | |
| 37 | fn syntax_element(self) -> SyntaxElement { | |
| 38 | self.into() | |
| 39 | } | |
| 40 | } | |
| 41 | ||
| 42 | #[derive(Debug)] | |
| 43 | pub struct Position { | |
| 44 | repr: PositionRepr, | |
| 45 | } | |
| 46 | ||
| 47 | #[derive(Debug)] | |
| 48 | enum PositionRepr { | |
| 49 | FirstChild(SyntaxNode), | |
| 50 | After(SyntaxElement), | |
| 51 | } | |
| 52 | ||
| 53 | impl Position { | |
| 54 | pub fn after(elem: impl Element) -> Position { | |
| 55 | let repr = PositionRepr::After(elem.syntax_element()); | |
| 56 | Position { repr } | |
| 57 | } | |
| 58 | pub fn before(elem: impl Element) -> Position { | |
| 59 | let elem = elem.syntax_element(); | |
| 60 | let repr = match elem.prev_sibling_or_token() { | |
| 61 | Some(it) => PositionRepr::After(it), | |
| 62 | None => PositionRepr::FirstChild(elem.parent().unwrap()), | |
| 63 | }; | |
| 64 | Position { repr } | |
| 65 | } | |
| 66 | pub fn first_child_of(node: &(impl Into<SyntaxNode> + Clone)) -> Position { | |
| 67 | let repr = PositionRepr::FirstChild(node.clone().into()); | |
| 68 | Position { repr } | |
| 69 | } | |
| 70 | pub fn last_child_of(node: &(impl Into<SyntaxNode> + Clone)) -> Position { | |
| 71 | let node = node.clone().into(); | |
| 72 | let repr = match node.last_child_or_token() { | |
| 73 | Some(it) => PositionRepr::After(it), | |
| 74 | None => PositionRepr::FirstChild(node), | |
| 75 | }; | |
| 76 | Position { repr } | |
| 77 | } | |
| 78 | pub fn offset(&self) -> TextSize { | |
| 79 | match &self.repr { | |
| 80 | PositionRepr::FirstChild(node) => node.text_range().start(), | |
| 81 | PositionRepr::After(elem) => elem.text_range().end(), | |
| 82 | } | |
| 83 | } | |
| 84 | } | |
| 85 | ||
| 86 | pub fn insert(position: Position, elem: impl Element) { | |
| 87 | insert_all(position, vec![elem.syntax_element()]); | |
| 88 | } | |
| 89 | pub fn insert_raw(position: Position, elem: impl Element) { | |
| 90 | insert_all_raw(position, vec![elem.syntax_element()]); | |
| 91 | } | |
| 92 | pub fn insert_all(position: Position, mut elements: Vec<SyntaxElement>) { | |
| 93 | if let Some(first) = elements.first() | |
| 94 | && let Some(ws) = ws_before(&position, first) | |
| 95 | { | |
| 96 | elements.insert(0, ws.into()); | |
| 97 | } | |
| 98 | if let Some(last) = elements.last() | |
| 99 | && let Some(ws) = ws_after(&position, last) | |
| 100 | { | |
| 101 | elements.push(ws.into()); | |
| 102 | } | |
| 103 | insert_all_raw(position, elements); | |
| 104 | } | |
| 105 | pub fn insert_all_raw(position: Position, elements: Vec<SyntaxElement>) { | |
| 106 | let (parent, index) = match position.repr { | |
| 107 | PositionRepr::FirstChild(parent) => (parent, 0), | |
| 108 | PositionRepr::After(child) => (child.parent().unwrap(), child.index() + 1), | |
| 109 | }; | |
| 110 | parent.splice_children(index..index, elements); | |
| 111 | } | |
| 112 | ||
| 113 | pub fn remove(elem: impl Element) { | |
| 114 | elem.syntax_element().detach(); | |
| 115 | } | |
| 116 | pub fn remove_all(range: RangeInclusive<SyntaxElement>) { | |
| 117 | replace_all(range, Vec::new()); | |
| 118 | } | |
| 119 | pub fn remove_all_iter(range: impl IntoIterator<Item = SyntaxElement>) { | |
| 120 | let mut it = range.into_iter(); | |
| 121 | if let Some(mut first) = it.next() { | |
| 122 | match it.last() { | |
| 123 | Some(mut last) => { | |
| 124 | if first.index() > last.index() { | |
| 125 | mem::swap(&mut first, &mut last); | |
| 126 | } | |
| 127 | remove_all(first..=last); | |
| 128 | } | |
| 129 | None => remove(first), | |
| 130 | } | |
| 131 | } | |
| 132 | } | |
| 133 | ||
| 134 | pub fn replace(old: impl Element, new: impl Element) { | |
| 135 | replace_with_many(old, vec![new.syntax_element()]); | |
| 136 | } | |
| 137 | pub fn replace_with_many(old: impl Element, new: Vec<SyntaxElement>) { | |
| 138 | let old = old.syntax_element(); | |
| 139 | replace_all(old.clone()..=old, new); | |
| 140 | } | |
| 141 | pub fn replace_all(range: RangeInclusive<SyntaxElement>, new: Vec<SyntaxElement>) { | |
| 142 | let start = range.start().index(); | |
| 143 | let end = range.end().index(); | |
| 144 | let parent = range.start().parent().unwrap(); | |
| 145 | parent.splice_children(start..end + 1, new); | |
| 146 | } | |
| 147 | ||
| 148 | pub fn append_child(node: &(impl Into<SyntaxNode> + Clone), child: impl Element) { | |
| 149 | let position = Position::last_child_of(node); | |
| 150 | insert(position, child); | |
| 151 | } | |
| 152 | pub fn append_child_raw(node: &(impl Into<SyntaxNode> + Clone), child: impl Element) { | |
| 153 | let position = Position::last_child_of(node); | |
| 154 | insert_raw(position, child); | |
| 155 | } | |
| 156 | ||
| 157 | pub fn prepend_child(node: &(impl Into<SyntaxNode> + Clone), child: impl Element) { | |
| 158 | let position = Position::first_child_of(node); | |
| 159 | insert(position, child); | |
| 160 | } | |
| 161 | ||
| 162 | fn ws_before(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> { | |
| 163 | let prev = match &position.repr { | |
| 164 | PositionRepr::FirstChild(_) => return None, | |
| 165 | PositionRepr::After(it) => it, | |
| 166 | }; | |
| 167 | ||
| 168 | if prev.kind() == T!['{'] | |
| 169 | && new.kind() == SyntaxKind::USE | |
| 170 | && let Some(item_list) = prev.parent().and_then(ast::ItemList::cast) | |
| 171 | { | |
| 172 | let mut indent = IndentLevel::from_element(&item_list.syntax().clone().into()); | |
| 173 | indent.0 += 1; | |
| 174 | return Some(make::tokens::whitespace(&format!("\n{indent}"))); | |
| 175 | } | |
| 176 | ||
| 177 | if prev.kind() == T!['{'] | |
| 178 | && ast::Stmt::can_cast(new.kind()) | |
| 179 | && let Some(stmt_list) = prev.parent().and_then(ast::StmtList::cast) | |
| 180 | { | |
| 181 | let mut indent = IndentLevel::from_element(&stmt_list.syntax().clone().into()); | |
| 182 | indent.0 += 1; | |
| 183 | return Some(make::tokens::whitespace(&format!("\n{indent}"))); | |
| 184 | } | |
| 185 | ||
| 186 | ws_between(prev, new) | |
| 187 | } | |
| 188 | fn ws_after(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> { | |
| 189 | let next = match &position.repr { | |
| 190 | PositionRepr::FirstChild(parent) => parent.first_child_or_token()?, | |
| 191 | PositionRepr::After(sibling) => sibling.next_sibling_or_token()?, | |
| 192 | }; | |
| 193 | ws_between(new, &next) | |
| 194 | } | |
| 195 | fn ws_between(left: &SyntaxElement, right: &SyntaxElement) -> Option<SyntaxToken> { | |
| 196 | if left.kind() == SyntaxKind::WHITESPACE || right.kind() == SyntaxKind::WHITESPACE { | |
| 197 | return None; | |
| 198 | } | |
| 199 | if right.kind() == T![;] || right.kind() == T![,] { | |
| 200 | return None; | |
| 201 | } | |
| 202 | if left.kind() == T![<] || right.kind() == T![>] { | |
| 203 | return None; | |
| 204 | } | |
| 205 | if left.kind() == T![&] && right.kind() == SyntaxKind::LIFETIME { | |
| 206 | return None; | |
| 207 | } | |
| 208 | if right.kind() == SyntaxKind::GENERIC_ARG_LIST { | |
| 209 | return None; | |
| 210 | } | |
| 211 | ||
| 212 | if right.kind() == SyntaxKind::USE { | |
| 213 | let mut indent = IndentLevel::from_element(left); | |
| 214 | if left.kind() == SyntaxKind::USE { | |
| 215 | indent.0 = IndentLevel::from_element(right).0.max(indent.0); | |
| 216 | } | |
| 217 | return Some(make::tokens::whitespace(&format!("\n{indent}"))); | |
| 218 | } | |
| 219 | if left.kind() == SyntaxKind::ATTR { | |
| 220 | let mut indent = IndentLevel::from_element(right); | |
| 221 | if right.kind() == SyntaxKind::ATTR { | |
| 222 | indent.0 = IndentLevel::from_element(left).0.max(indent.0); | |
| 223 | } | |
| 224 | return Some(make::tokens::whitespace(&format!("\n{indent}"))); | |
| 225 | } | |
| 226 | Some(make::tokens::single_space()) | |
| 227 | } |
src/tools/rust-analyzer/crates/toolchain/Cargo.toml-1| ... | ... | @@ -13,7 +13,6 @@ rust-version.workspace = true |
| 13 | 13 | doctest = false |
| 14 | 14 | |
| 15 | 15 | [dependencies] |
| 16 | home = "0.5.11" | |
| 17 | 16 | camino.workspace = true |
| 18 | 17 | |
| 19 | 18 | [lints] |
src/tools/rust-analyzer/crates/toolchain/src/lib.rs+1-1| ... | ... | @@ -119,7 +119,7 @@ fn get_cargo_home() -> Option<Utf8PathBuf> { |
| 119 | 119 | return Utf8PathBuf::try_from(PathBuf::from(path)).ok(); |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | if let Some(mut path) = home::home_dir() { | |
| 122 | if let Some(mut path) = env::home_dir() { | |
| 123 | 123 | path.push(".cargo"); |
| 124 | 124 | return Utf8PathBuf::try_from(path).ok(); |
| 125 | 125 | } |
src/tools/rust-analyzer/docs/book/src/configuration_generated.md+4-1| ... | ... | @@ -446,9 +446,12 @@ verbose form `{ "path": "path::to::item", type: "always" }`. |
| 446 | 446 | For traits the type "methods" can be used to only exclude the methods but not the trait |
| 447 | 447 | itself. |
| 448 | 448 | |
| 449 | For modules the type "subItems" can be used to only exclude the all items in it but not the module | |
| 449 | For modules the type "sub_items" can be used to only exclude the all items in it but not the module | |
| 450 | 450 | itself. This does not include items defined in nested modules. |
| 451 | 451 | |
| 452 | For enums the type "variants" can be used to only exclude the all variants in it but not the enum | |
| 453 | itself. | |
| 454 | ||
| 452 | 455 | This setting also inherits `#rust-analyzer.completion.excludeTraits#`. |
| 453 | 456 | |
| 454 | 457 |
src/tools/rust-analyzer/docs/book/src/contributing/README.md-7| ... | ... | @@ -206,13 +206,6 @@ To measure time for from-scratch analysis, use something like this: |
| 206 | 206 | cargo run --release -p rust-analyzer -- analysis-stats ../chalk/ |
| 207 | 207 | ``` |
| 208 | 208 | |
| 209 | For measuring time of incremental analysis, use either of these: | |
| 210 | ||
| 211 | ```bash | |
| 212 | cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --highlight ../chalk/chalk-engine/src/logic.rs | |
| 213 | cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --complete ../chalk/chalk-engine/src/logic.rs:94:0 | |
| 214 | ``` | |
| 215 | ||
| 216 | 209 | Look for `fn benchmark_xxx` tests for a quick way to reproduce performance problems. |
| 217 | 210 | |
| 218 | 211 | ## Release Process |
src/tools/rust-analyzer/editors/code/package.json+43-2| ... | ... | @@ -214,6 +214,11 @@ |
| 214 | 214 | "title": "Reload workspace", |
| 215 | 215 | "category": "rust-analyzer" |
| 216 | 216 | }, |
| 217 | { | |
| 218 | "command": "rust-analyzer.newProject", | |
| 219 | "title": "Create New Project...", | |
| 220 | "category": "rust-analyzer" | |
| 221 | }, | |
| 217 | 222 | { |
| 218 | 223 | "command": "rust-analyzer.rebuildProcMacros", |
| 219 | 224 | "title": "Rebuild proc macros and build scripts", |
| ... | ... | @@ -491,6 +496,23 @@ |
| 491 | 496 | "markdownDescription": "Do not start rust-analyzer server when the extension is activated.", |
| 492 | 497 | "default": false, |
| 493 | 498 | "type": "boolean" |
| 499 | }, | |
| 500 | "rust-analyzer.projectCreation.openAfterCreate": { | |
| 501 | "markdownDescription": "Control what happens after `rust-analyzer: Create New Project...` finishes creating a Cargo project.", | |
| 502 | "default": "ask", | |
| 503 | "enum": [ | |
| 504 | "ask", | |
| 505 | "open", | |
| 506 | "openNewWindow", | |
| 507 | "addToWorkspace" | |
| 508 | ], | |
| 509 | "enumDescriptions": [ | |
| 510 | "Prompt for how to open the new project.", | |
| 511 | "Open the new project in the current window.", | |
| 512 | "Open the new project in a new window.", | |
| 513 | "Add the new project to the current workspace, or open it if no workspace is open." | |
| 514 | ], | |
| 515 | "type": "string" | |
| 494 | 516 | } |
| 495 | 517 | } |
| 496 | 518 | }, |
| ... | ... | @@ -1333,7 +1355,7 @@ |
| 1333 | 1355 | "title": "Completion", |
| 1334 | 1356 | "properties": { |
| 1335 | 1357 | "rust-analyzer.completion.autoimport.exclude": { |
| 1336 | "markdownDescription": "A list of full paths to items to exclude from auto-importing completions.\n\nTraits in this list won't have their methods suggested in completions unless the trait\nis in scope.\n\nYou can either specify a string path which defaults to type \"always\" or use the more\nverbose form `{ \"path\": \"path::to::item\", type: \"always\" }`.\n\nFor traits the type \"methods\" can be used to only exclude the methods but not the trait\nitself.\n\nFor modules the type \"subItems\" can be used to only exclude the all items in it but not the module\nitself. This does not include items defined in nested modules.\n\nThis setting also inherits `#rust-analyzer.completion.excludeTraits#`.", | |
| 1358 | "markdownDescription": "A list of full paths to items to exclude from auto-importing completions.\n\nTraits in this list won't have their methods suggested in completions unless the trait\nis in scope.\n\nYou can either specify a string path which defaults to type \"always\" or use the more\nverbose form `{ \"path\": \"path::to::item\", type: \"always\" }`.\n\nFor traits the type \"methods\" can be used to only exclude the methods but not the trait\nitself.\n\nFor modules the type \"sub_items\" can be used to only exclude the all items in it but not the module\nitself. This does not include items defined in nested modules.\n\nFor enums the type \"variants\" can be used to only exclude the all variants in it but not the enum\nitself.\n\nThis setting also inherits `#rust-analyzer.completion.excludeTraits#`.", | |
| 1337 | 1359 | "default": [ |
| 1338 | 1360 | { |
| 1339 | 1361 | "path": "core::borrow::Borrow", |
| ... | ... | @@ -1361,7 +1383,8 @@ |
| 1361 | 1383 | "enum": [ |
| 1362 | 1384 | "always", |
| 1363 | 1385 | "methods", |
| 1364 | "subItems" | |
| 1386 | "sub_items", | |
| 1387 | "variants" | |
| 1365 | 1388 | ], |
| 1366 | 1389 | "enumDescriptions": [ |
| 1367 | 1390 | "Do not show this item or its methods (if it is a trait) in auto-import completions.", |
| ... | ... | @@ -3811,6 +3834,9 @@ |
| 3811 | 3834 | "command": "rust-analyzer.memoryUsage", |
| 3812 | 3835 | "when": "inRustProject" |
| 3813 | 3836 | }, |
| 3837 | { | |
| 3838 | "command": "rust-analyzer.newProject" | |
| 3839 | }, | |
| 3814 | 3840 | { |
| 3815 | 3841 | "command": "rust-analyzer.reloadWorkspace", |
| 3816 | 3842 | "when": "inRustProject" |
| ... | ... | @@ -3930,6 +3956,13 @@ |
| 3930 | 3956 | } |
| 3931 | 3957 | ] |
| 3932 | 3958 | }, |
| 3959 | "viewsWelcome": [ | |
| 3960 | { | |
| 3961 | "view": "explorer", | |
| 3962 | "contents": "Create a new Rust project.\n[Create Rust Project](command:rust-analyzer.newProject)", | |
| 3963 | "when": "workspaceFolderCount == 0" | |
| 3964 | } | |
| 3965 | ], | |
| 3933 | 3966 | "viewsContainers": { |
| 3934 | 3967 | "activitybar": [ |
| 3935 | 3968 | { |
| ... | ... | @@ -3955,6 +3988,14 @@ |
| 3955 | 3988 | "title": "Learn about rust-analyzer", |
| 3956 | 3989 | "description": "A brief introduction to get started with rust-analyzer. Learn about key features and resources to help you get the most out of the extension.", |
| 3957 | 3990 | "steps": [ |
| 3991 | { | |
| 3992 | "id": "create-project", | |
| 3993 | "title": "Create a Rust project", | |
| 3994 | "description": "Start a new Cargo binary or library project from VS Code.\n\n[Create a Rust Project](command:rust-analyzer.newProject)", | |
| 3995 | "media": { | |
| 3996 | "markdown": "./walkthrough-create-project.md" | |
| 3997 | } | |
| 3998 | }, | |
| 3958 | 3999 | { |
| 3959 | 4000 | "id": "setup", |
| 3960 | 4001 | "title": "Useful Setup Tips", |
src/tools/rust-analyzer/editors/code/src/commands.ts+1| ... | ... | @@ -33,6 +33,7 @@ import { log } from "./util"; |
| 33 | 33 | import type { SyntaxElement } from "./syntax_tree_provider"; |
| 34 | 34 | |
| 35 | 35 | export * from "./run"; |
| 36 | export { newProject } from "./new_project"; | |
| 36 | 37 | |
| 37 | 38 | export function analyzerStatus(ctx: CtxInit): Cmd { |
| 38 | 39 | const tdcp = new (class implements vscode.TextDocumentContentProvider { |
src/tools/rust-analyzer/editors/code/src/config.ts+4| ... | ... | @@ -447,6 +447,10 @@ export class Config { |
| 447 | 447 | return this.get<boolean>("initializeStopped"); |
| 448 | 448 | } |
| 449 | 449 | |
| 450 | get projectCreationOpenAfterCreate() { | |
| 451 | return this.get<string>("projectCreation.openAfterCreate"); | |
| 452 | } | |
| 453 | ||
| 450 | 454 | get askBeforeUpdateTest() { |
| 451 | 455 | return this.get<boolean>("runnables.askBeforeUpdateTest"); |
| 452 | 456 | } |
src/tools/rust-analyzer/editors/code/src/main.ts+6| ... | ... | @@ -161,6 +161,12 @@ function createCommands(): Record<string, CommandFactory> { |
| 161 | 161 | memoryUsage: { enabled: commands.memoryUsage }, |
| 162 | 162 | reloadWorkspace: { enabled: commands.reloadWorkspace }, |
| 163 | 163 | rebuildProcMacros: { enabled: commands.rebuildProcMacros }, |
| 164 | newProject: { | |
| 165 | // Project creation is a pure VS Code-side workflow and should stay available even in | |
| 166 | // empty windows before rust-analyzer has started or a Rust workspace exists. | |
| 167 | enabled: commands.newProject, | |
| 168 | disabled: commands.newProject, | |
| 169 | }, | |
| 164 | 170 | matchingBrace: { enabled: commands.matchingBrace }, |
| 165 | 171 | joinLines: { enabled: commands.joinLines }, |
| 166 | 172 | parentModule: { enabled: commands.parentModule }, |
src/tools/rust-analyzer/editors/code/src/new_project.ts created+311| ... | ... | @@ -0,0 +1,311 @@ |
| 1 | import * as vscode from "vscode"; | |
| 2 | ||
| 3 | import type { Ctx, Cmd } from "./ctx"; | |
| 4 | import * as ra from "./lsp_ext"; | |
| 5 | import { cargoPath } from "./toolchain"; | |
| 6 | import { log, spawnAsync } from "./util"; | |
| 7 | ||
| 8 | type NewProjectKind = "bin" | "lib"; | |
| 9 | type NewProjectOpenAction = "open" | "openNewWindow" | "addToWorkspace"; | |
| 10 | ||
| 11 | type NewProjectTemplate = { | |
| 12 | detail: string; | |
| 13 | id: NewProjectKind; | |
| 14 | label: string; | |
| 15 | }; | |
| 16 | ||
| 17 | type NewProjectCargo = { | |
| 18 | cargo: string; | |
| 19 | cargoEnv: NodeJS.ProcessEnv; | |
| 20 | }; | |
| 21 | ||
| 22 | const NEW_PROJECT_TEMPLATES: readonly NewProjectTemplate[] = [ | |
| 23 | { | |
| 24 | id: "bin", | |
| 25 | label: "Binary Application", | |
| 26 | detail: "Create a Cargo binary package (`cargo new --bin`)", | |
| 27 | }, | |
| 28 | { | |
| 29 | id: "lib", | |
| 30 | label: "Library", | |
| 31 | detail: "Create a Cargo library package (`cargo new --lib`)", | |
| 32 | }, | |
| 33 | ] as const; | |
| 34 | ||
| 35 | export function newProject(ctx: Ctx): Cmd { | |
| 36 | return async () => { | |
| 37 | const cargo = await resolveNewProjectCargo(ctx); | |
| 38 | ||
| 39 | const selectedKind = await promptForNewProjectTemplate(); | |
| 40 | if (!selectedKind) { | |
| 41 | return; | |
| 42 | } | |
| 43 | ||
| 44 | const parentFolder = await promptForNewProjectParentFolder(); | |
| 45 | if (!parentFolder) { | |
| 46 | return; | |
| 47 | } | |
| 48 | ||
| 49 | const projectName = await promptForNewProjectName(parentFolder); | |
| 50 | if (!projectName) { | |
| 51 | return; | |
| 52 | } | |
| 53 | ||
| 54 | if (!(await createNewProject(cargo, parentFolder, selectedKind, projectName))) { | |
| 55 | return; | |
| 56 | } | |
| 57 | ||
| 58 | const projectUri = vscode.Uri.joinPath(parentFolder, projectName); | |
| 59 | const defaultAction = determineNewProjectOpenAction( | |
| 60 | ctx.config.projectCreationOpenAfterCreate, | |
| 61 | Boolean(vscode.workspace.workspaceFolders?.length), | |
| 62 | ); | |
| 63 | const action = | |
| 64 | defaultAction === "ask" | |
| 65 | ? await promptForNewProjectOpenAction( | |
| 66 | projectName, | |
| 67 | Boolean(vscode.workspace.workspaceFolders?.length), | |
| 68 | ) | |
| 69 | : defaultAction; | |
| 70 | ||
| 71 | if (action) { | |
| 72 | await executeNewProjectOpenAction(ctx, action, projectUri); | |
| 73 | } | |
| 74 | }; | |
| 75 | } | |
| 76 | ||
| 77 | async function resolveNewProjectCargo(ctx: Ctx): Promise<NewProjectCargo> { | |
| 78 | // Use the same effective environment rust-analyzer uses elsewhere so project creation sees | |
| 79 | // toolchain wrappers, PATH overrides, and CARGO_HOME changes from configuration. | |
| 80 | const cargoEnv = { ...process.env, ...ctx.config.serverExtraEnv }; | |
| 81 | return { cargo: await cargoPath(cargoEnv), cargoEnv }; | |
| 82 | } | |
| 83 | ||
| 84 | async function promptForNewProjectTemplate(): Promise<NewProjectKind | undefined> { | |
| 85 | const selected = await vscode.window.showQuickPick(NEW_PROJECT_TEMPLATES, { | |
| 86 | placeHolder: "Select a Rust project kind", | |
| 87 | }); | |
| 88 | return selected?.id; | |
| 89 | } | |
| 90 | ||
| 91 | async function promptForNewProjectParentFolder(): Promise<vscode.Uri | undefined> { | |
| 92 | const selectedFolder = await vscode.window.showOpenDialog({ | |
| 93 | title: "Select the parent folder for the new Rust project", | |
| 94 | openLabel: "Select parent folder", | |
| 95 | canSelectFiles: false, | |
| 96 | canSelectFolders: true, | |
| 97 | canSelectMany: false, | |
| 98 | }); | |
| 99 | if (!selectedFolder?.length) { | |
| 100 | return undefined; | |
| 101 | } | |
| 102 | return selectedFolder[0]; | |
| 103 | } | |
| 104 | ||
| 105 | const CARGO_MANIFEST_NAME_PATTERN = /^[\p{Alphabetic}\p{Number}_-]+$/u; | |
| 106 | ||
| 107 | // Keep local validation focused on stable checks that can be reported in the input box, then let | |
| 108 | // `cargo new` remain the source of truth for package-name-specific identifier and keyword rules. | |
| 109 | export function validateNewProjectName( | |
| 110 | value: string, | |
| 111 | existingNames: readonly string[], | |
| 112 | ): string | undefined { | |
| 113 | const trimmedValue = value.trim(); | |
| 114 | if (trimmedValue.length === 0) { | |
| 115 | return "Project name cannot be empty."; | |
| 116 | } | |
| 117 | if (trimmedValue.includes("/") || trimmedValue.includes("\\")) { | |
| 118 | return "Project name cannot contain '/' or '\\' characters."; | |
| 119 | } | |
| 120 | if (trimmedValue === "." || trimmedValue === "..") { | |
| 121 | return "Project name cannot be '.' or '..'."; | |
| 122 | } | |
| 123 | if (!CARGO_MANIFEST_NAME_PATTERN.test(trimmedValue)) { | |
| 124 | return "Project name can contain only alphanumeric characters, '-' or '_'."; | |
| 125 | } | |
| 126 | if (existingNames.includes(trimmedValue)) { | |
| 127 | return "A file or folder with this name already exists."; | |
| 128 | } | |
| 129 | return undefined; | |
| 130 | } | |
| 131 | ||
| 132 | async function promptForNewProjectName(parentFolder: vscode.Uri): Promise<string | undefined> { | |
| 133 | let existingNames: string[] = []; | |
| 134 | try { | |
| 135 | const entries = await vscode.workspace.fs.readDirectory(parentFolder); | |
| 136 | existingNames = entries.map(([name]) => name); | |
| 137 | } catch (error) { | |
| 138 | log.error("Failed to read project parent folder", error); | |
| 139 | void vscode.window.showErrorMessage("Failed to read the selected parent folder."); | |
| 140 | return undefined; | |
| 141 | } | |
| 142 | ||
| 143 | const projectName = await vscode.window.showInputBox({ | |
| 144 | prompt: `Enter the new project name to create inside ${parentFolder.fsPath}`, | |
| 145 | validateInput: async (value) => validateNewProjectName(value, existingNames), | |
| 146 | }); | |
| 147 | return projectName?.trim(); | |
| 148 | } | |
| 149 | ||
| 150 | export function cargoNewArgs(kind: NewProjectKind, name: string): string[] { | |
| 151 | return ["new", kind === "bin" ? "--bin" : "--lib", name]; | |
| 152 | } | |
| 153 | ||
| 154 | async function createNewProject( | |
| 155 | cargo: NewProjectCargo, | |
| 156 | parentFolder: vscode.Uri, | |
| 157 | kind: NewProjectKind, | |
| 158 | projectName: string, | |
| 159 | ): Promise<boolean> { | |
| 160 | const args = cargoNewArgs(kind, projectName); | |
| 161 | const createResult = await vscode.window.withProgress( | |
| 162 | { | |
| 163 | location: vscode.ProgressLocation.Notification, | |
| 164 | title: `Creating Rust project ${projectName}`, | |
| 165 | }, | |
| 166 | async () => | |
| 167 | spawnAsync(cargo.cargo, args, { | |
| 168 | cwd: parentFolder.fsPath, | |
| 169 | env: cargo.cargoEnv, | |
| 170 | }), | |
| 171 | ); | |
| 172 | ||
| 173 | if (createResult.error || createResult.status !== 0) { | |
| 174 | const details = formatProcessDetails(createResult); | |
| 175 | await showNewProjectError("Failed to create Rust project.", details || undefined, { | |
| 176 | cargo: cargo.cargo, | |
| 177 | args, | |
| 178 | cwd: parentFolder.fsPath, | |
| 179 | error: createResult.error?.message, | |
| 180 | status: createResult.status, | |
| 181 | stderr: createResult.stderr || undefined, | |
| 182 | stdout: createResult.stdout || undefined, | |
| 183 | }); | |
| 184 | return false; | |
| 185 | } | |
| 186 | ||
| 187 | return true; | |
| 188 | } | |
| 189 | ||
| 190 | function formatProcessDetails(result: { error?: Error; stderr: string; stdout: string }): string { | |
| 191 | return [result.stderr, result.stdout, result.error?.message] | |
| 192 | .filter((value): value is string => Boolean(value && value.trim().length > 0)) | |
| 193 | .join("\n") | |
| 194 | .trim(); | |
| 195 | } | |
| 196 | ||
| 197 | async function showNewProjectError( | |
| 198 | message: string, | |
| 199 | details: string | undefined, | |
| 200 | logContext: { | |
| 201 | cargo: string; | |
| 202 | args: string[]; | |
| 203 | cwd?: string; | |
| 204 | error?: string; | |
| 205 | status: number | null; | |
| 206 | stderr?: string; | |
| 207 | stdout?: string; | |
| 208 | }, | |
| 209 | ): Promise<void> { | |
| 210 | // Keep command-failure logging focused on the invocation and process output. Environment | |
| 211 | // variables may contain secrets such as API keys, tokens, and credentials, so failure logs | |
| 212 | // must not dump the merged env here. | |
| 213 | const commandLine = [logContext.cargo, ...logContext.args].join(" "); | |
| 214 | log.error(message); | |
| 215 | log.error(`command: ${commandLine}`); | |
| 216 | if (logContext.cwd) { | |
| 217 | log.error(`cwd: ${logContext.cwd}`); | |
| 218 | } | |
| 219 | log.error(`exit status: ${String(logContext.status)}`); | |
| 220 | if (logContext.error) { | |
| 221 | log.error(`error: ${logContext.error}`); | |
| 222 | } | |
| 223 | if (logContext.stderr) { | |
| 224 | log.error(`stderr:\n${logContext.stderr}`); | |
| 225 | } | |
| 226 | if (logContext.stdout) { | |
| 227 | log.error(`stdout:\n${logContext.stdout}`); | |
| 228 | } | |
| 229 | const selection = await vscode.window.showErrorMessage( | |
| 230 | details ? `${message}\n${details}` : message, | |
| 231 | "Open Extension Logs", | |
| 232 | ); | |
| 233 | if (selection === "Open Extension Logs") { | |
| 234 | log.show(); | |
| 235 | } | |
| 236 | } | |
| 237 | ||
| 238 | export function determineNewProjectOpenAction( | |
| 239 | configuredAction: string | undefined, | |
| 240 | hasWorkspaceFolders: boolean, | |
| 241 | ): "ask" | NewProjectOpenAction { | |
| 242 | switch (configuredAction) { | |
| 243 | case "open": | |
| 244 | case "openNewWindow": | |
| 245 | return configuredAction; | |
| 246 | case "addToWorkspace": | |
| 247 | // Adding to a workspace only makes sense when one is already open. Falling back to | |
| 248 | // "open" keeps the setting usable in empty windows without adding another prompt path. | |
| 249 | return hasWorkspaceFolders ? configuredAction : "open"; | |
| 250 | default: | |
| 251 | return "ask"; | |
| 252 | } | |
| 253 | } | |
| 254 | ||
| 255 | async function promptForNewProjectOpenAction( | |
| 256 | projectName: string, | |
| 257 | hasWorkspaceFolders: boolean, | |
| 258 | ): Promise<NewProjectOpenAction | undefined> { | |
| 259 | let message = `Would you like to open ${projectName}?`; | |
| 260 | const open = "Open"; | |
| 261 | const openNewWindow = "Open in New Window"; | |
| 262 | const choices = [open, openNewWindow]; | |
| 263 | ||
| 264 | const addToWorkspace = "Add to VS Code Workspace"; | |
| 265 | if (hasWorkspaceFolders) { | |
| 266 | message = `Would you like to open ${projectName}, or add it to the current VS Code workspace?`; | |
| 267 | choices.push(addToWorkspace); | |
| 268 | } | |
| 269 | ||
| 270 | const result = await vscode.window.showInformationMessage( | |
| 271 | message, | |
| 272 | { modal: true, detail: "The default action can be configured in settings." }, | |
| 273 | ...choices, | |
| 274 | ); | |
| 275 | ||
| 276 | const actionMap: Record<string, NewProjectOpenAction> = { | |
| 277 | [open]: "open", | |
| 278 | [openNewWindow]: "openNewWindow", | |
| 279 | [addToWorkspace]: "addToWorkspace", | |
| 280 | }; | |
| 281 | return result ? actionMap[result] : undefined; | |
| 282 | } | |
| 283 | ||
| 284 | async function executeNewProjectOpenAction( | |
| 285 | ctx: Ctx, | |
| 286 | action: NewProjectOpenAction, | |
| 287 | projectUri: vscode.Uri, | |
| 288 | ): Promise<void> { | |
| 289 | if (action === "open") { | |
| 290 | await vscode.commands.executeCommand("vscode.openFolder", projectUri, { | |
| 291 | forceReuseWindow: true, | |
| 292 | }); | |
| 293 | return; | |
| 294 | } | |
| 295 | ||
| 296 | if (action === "openNewWindow") { | |
| 297 | await vscode.commands.executeCommand("vscode.openFolder", projectUri, { | |
| 298 | forceNewWindow: true, | |
| 299 | }); | |
| 300 | return; | |
| 301 | } | |
| 302 | ||
| 303 | const index = vscode.workspace.workspaceFolders?.length ?? 0; | |
| 304 | vscode.workspace.updateWorkspaceFolders(index, 0, { uri: projectUri }); | |
| 305 | // Reuse the existing workspace window when requested, but nudge rust-analyzer afterwards so | |
| 306 | // the newly added Cargo project is discovered immediately instead of waiting for a later | |
| 307 | // background refresh. | |
| 308 | if (ctx.client?.isRunning()) { | |
| 309 | await ctx.client.sendRequest(ra.reloadWorkspace); | |
| 310 | } | |
| 311 | } |
src/tools/rust-analyzer/editors/code/src/toolchain.ts+65-9| ... | ... | @@ -3,7 +3,7 @@ import * as os from "os"; |
| 3 | 3 | import * as path from "path"; |
| 4 | 4 | import * as readline from "readline"; |
| 5 | 5 | import * as vscode from "vscode"; |
| 6 | import { Env, log, memoizeAsync, unwrapUndefinable } from "./util"; | |
| 6 | import { Env, isWindows, log, memoizeAsync, unwrapUndefinable } from "./util"; | |
| 7 | 7 | import type { CargoRunnableArgs } from "./lsp_ext"; |
| 8 | 8 | |
| 9 | 9 | interface CompilationArtifact { |
| ... | ... | @@ -160,9 +160,46 @@ export function cargoPath(env?: Env): Promise<string> { |
| 160 | 160 | if (env?.["RUSTC_TOOLCHAIN"]) { |
| 161 | 161 | return Promise.resolve("cargo"); |
| 162 | 162 | } |
| 163 | if (env) { | |
| 164 | return getPathForExecutableWithEnv("cargo", env); | |
| 165 | } | |
| 163 | 166 | return getPathForExecutable("cargo"); |
| 164 | 167 | } |
| 165 | 168 | |
| 169 | /** | |
| 170 | * Resolves an executable using an explicitly supplied environment instead of the VS Code host | |
| 171 | * process environment. | |
| 172 | * | |
| 173 | * Some extension call sites already construct the exact env they will use for spawning, so path | |
| 174 | * resolution needs to honor that same `PATH`/`CARGO_HOME` view to avoid launching a different | |
| 175 | * toolchain than the one that was resolved. | |
| 176 | */ | |
| 177 | async function getPathForExecutableWithEnv( | |
| 178 | executableName: "cargo" | "rustc" | "rustup", | |
| 179 | env: Env, | |
| 180 | ): Promise<string> { | |
| 181 | const envVar = getEnvVar(env, executableName.toUpperCase()); | |
| 182 | if (envVar) { | |
| 183 | return envVar; | |
| 184 | } | |
| 185 | ||
| 186 | if (await lookupInPath(executableName, getEnvVar(env, "PATH") ?? "")) { | |
| 187 | return executableName; | |
| 188 | } | |
| 189 | ||
| 190 | const cargoHome = getCargoHomeFromPath(getEnvVar(env, "CARGO_HOME")); | |
| 191 | if (cargoHome) { | |
| 192 | for (const candidate of executableCandidates(executableName)) { | |
| 193 | const standardPath = vscode.Uri.joinPath(cargoHome, "bin", candidate); | |
| 194 | if (await isFileAtUri(standardPath)) { | |
| 195 | return standardPath.fsPath; | |
| 196 | } | |
| 197 | } | |
| 198 | } | |
| 199 | ||
| 200 | return executableName; | |
| 201 | } | |
| 202 | ||
| 166 | 203 | /** Mirrors `toolchain::get_path_for_executable()` implementation */ |
| 167 | 204 | const getPathForExecutable = memoizeAsync( |
| 168 | 205 | // We apply caching to decrease file-system interactions |
| ... | ... | @@ -172,23 +209,22 @@ const getPathForExecutable = memoizeAsync( |
| 172 | 209 | if (envVar) return envVar; |
| 173 | 210 | } |
| 174 | 211 | |
| 175 | if (await lookupInPath(executableName)) return executableName; | |
| 212 | if (await lookupInPath(executableName, process.env["PATH"] ?? "")) return executableName; | |
| 176 | 213 | |
| 177 | 214 | const cargoHome = getCargoHome(); |
| 178 | 215 | if (cargoHome) { |
| 179 | const standardPath = vscode.Uri.joinPath(cargoHome, "bin", executableName); | |
| 180 | if (await isFileAtUri(standardPath)) return standardPath.fsPath; | |
| 216 | for (const candidate of executableCandidates(executableName)) { | |
| 217 | const standardPath = vscode.Uri.joinPath(cargoHome, "bin", candidate); | |
| 218 | if (await isFileAtUri(standardPath)) return standardPath.fsPath; | |
| 219 | } | |
| 181 | 220 | } |
| 182 | 221 | return executableName; |
| 183 | 222 | }, |
| 184 | 223 | ); |
| 185 | 224 | |
| 186 | async function lookupInPath(exec: string): Promise<boolean> { | |
| 187 | const paths = process.env["PATH"] ?? ""; | |
| 188 | ||
| 225 | async function lookupInPath(exec: string, paths: string): Promise<boolean> { | |
| 189 | 226 | const candidates = paths.split(path.delimiter).flatMap((dirInPath) => { |
| 190 | const candidate = path.join(dirInPath, exec); | |
| 191 | return os.type() === "Windows_NT" ? [candidate, `${candidate}.exe`] : [candidate]; | |
| 227 | return executableCandidates(exec).map((candidate) => path.join(dirInPath, candidate)); | |
| 192 | 228 | }); |
| 193 | 229 | |
| 194 | 230 | for await (const isFile of candidates.map(isFileAtPath)) { |
| ... | ... | @@ -199,8 +235,28 @@ async function lookupInPath(exec: string): Promise<boolean> { |
| 199 | 235 | return false; |
| 200 | 236 | } |
| 201 | 237 | |
| 238 | function executableCandidates(executableName: string): string[] { | |
| 239 | // Keep the extension-side probe aligned with `crates/toolchain::probe_for_binary()`, which | |
| 240 | // checks both the bare executable name and the platform suffix such as `.exe` on Windows. | |
| 241 | // That matters for both PATH lookups and `$CARGO_HOME/bin/<tool>` fallbacks. | |
| 242 | return isWindows ? [executableName, `${executableName}.exe`] : [executableName]; | |
| 243 | } | |
| 244 | ||
| 245 | function getEnvVar(env: Env, name: string): string | undefined { | |
| 246 | if (!isWindows) { | |
| 247 | return env[name]; | |
| 248 | } | |
| 249 | ||
| 250 | const foldedName = name.toLowerCase(); | |
| 251 | return Object.entries(env).find(([key]) => key.toLowerCase() === foldedName)?.[1]; | |
| 252 | } | |
| 253 | ||
| 202 | 254 | function getCargoHome(): vscode.Uri | null { |
| 203 | 255 | const envVar = process.env["CARGO_HOME"]; |
| 256 | return getCargoHomeFromPath(envVar); | |
| 257 | } | |
| 258 | ||
| 259 | function getCargoHomeFromPath(envVar: string | undefined): vscode.Uri | null { | |
| 204 | 260 | if (envVar) return vscode.Uri.file(envVar); |
| 205 | 261 | |
| 206 | 262 | try { |
src/tools/rust-analyzer/editors/code/src/util.ts+5-1| ... | ... | @@ -22,6 +22,10 @@ class Log { |
| 22 | 22 | log: true, |
| 23 | 23 | }); |
| 24 | 24 | |
| 25 | show(): void { | |
| 26 | this.output.show(true); | |
| 27 | } | |
| 28 | ||
| 25 | 29 | trace(...messages: [unknown, ...unknown[]]): void { |
| 26 | 30 | this.output.trace(this.stringify(messages)); |
| 27 | 31 | } |
| ... | ... | @@ -40,7 +44,7 @@ class Log { |
| 40 | 44 | |
| 41 | 45 | error(...messages: [unknown, ...unknown[]]): void { |
| 42 | 46 | this.output.error(this.stringify(messages)); |
| 43 | this.output.show(true); | |
| 47 | this.show(); | |
| 44 | 48 | } |
| 45 | 49 | |
| 46 | 50 | private stringify(messages: unknown[]): string { |
src/tools/rust-analyzer/editors/code/tests/unit/commands.test.ts created+80| ... | ... | @@ -0,0 +1,80 @@ |
| 1 | import * as assert from "node:assert/strict"; | |
| 2 | ||
| 3 | import { | |
| 4 | cargoNewArgs, | |
| 5 | determineNewProjectOpenAction, | |
| 6 | validateNewProjectName, | |
| 7 | } from "../../src/new_project"; | |
| 8 | import type { Context } from "."; | |
| 9 | ||
| 10 | export async function getTests(ctx: Context) { | |
| 11 | await ctx.suite("New project command", (suite) => { | |
| 12 | suite.addTest("rejects empty project name", async () => { | |
| 13 | assert.equal(validateNewProjectName("", []), "Project name cannot be empty."); | |
| 14 | assert.equal(validateNewProjectName(" ", []), "Project name cannot be empty."); | |
| 15 | }); | |
| 16 | ||
| 17 | suite.addTest("rejects dot project names", async () => { | |
| 18 | assert.equal(validateNewProjectName(".", []), "Project name cannot be '.' or '..'."); | |
| 19 | assert.equal(validateNewProjectName("..", []), "Project name cannot be '.' or '..'."); | |
| 20 | }); | |
| 21 | ||
| 22 | suite.addTest("rejects path separators", async () => { | |
| 23 | assert.equal( | |
| 24 | validateNewProjectName("foo/bar", []), | |
| 25 | "Project name cannot contain '/' or '\\' characters.", | |
| 26 | ); | |
| 27 | assert.equal( | |
| 28 | validateNewProjectName("foo\\bar", []), | |
| 29 | "Project name cannot contain '/' or '\\' characters.", | |
| 30 | ); | |
| 31 | }); | |
| 32 | ||
| 33 | suite.addTest("rejects invalid Cargo package name characters", async () => { | |
| 34 | assert.equal( | |
| 35 | validateNewProjectName("foo.bar", []), | |
| 36 | "Project name can contain only alphanumeric characters, '-' or '_'.", | |
| 37 | ); | |
| 38 | assert.equal( | |
| 39 | validateNewProjectName("foo bar", []), | |
| 40 | "Project name can contain only alphanumeric characters, '-' or '_'.", | |
| 41 | ); | |
| 42 | assert.equal( | |
| 43 | validateNewProjectName("foo+bar", []), | |
| 44 | "Project name can contain only alphanumeric characters, '-' or '_'.", | |
| 45 | ); | |
| 46 | }); | |
| 47 | ||
| 48 | suite.addTest("rejects existing child folder collisions", async () => { | |
| 49 | assert.equal( | |
| 50 | validateNewProjectName("demo", ["demo"]), | |
| 51 | "A file or folder with this name already exists.", | |
| 52 | ); | |
| 53 | }); | |
| 54 | ||
| 55 | suite.addTest("accepts a normal project name", async () => { | |
| 56 | assert.equal(validateNewProjectName("demo-project", []), undefined); | |
| 57 | }); | |
| 58 | ||
| 59 | suite.addTest("resolves addToWorkspace fallback without workspace", async () => { | |
| 60 | assert.equal(determineNewProjectOpenAction("addToWorkspace", false), "open"); | |
| 61 | }); | |
| 62 | ||
| 63 | suite.addTest("keeps addToWorkspace when workspace exists", async () => { | |
| 64 | assert.equal(determineNewProjectOpenAction("addToWorkspace", true), "addToWorkspace"); | |
| 65 | }); | |
| 66 | ||
| 67 | suite.addTest("defaults to ask for unknown values", async () => { | |
| 68 | assert.equal(determineNewProjectOpenAction(undefined, true), "ask"); | |
| 69 | assert.equal(determineNewProjectOpenAction("ask", true), "ask"); | |
| 70 | }); | |
| 71 | ||
| 72 | suite.addTest("builds binary cargo args", async () => { | |
| 73 | assert.deepEqual(cargoNewArgs("bin", "demo"), ["new", "--bin", "demo"]); | |
| 74 | }); | |
| 75 | ||
| 76 | suite.addTest("builds library cargo args", async () => { | |
| 77 | assert.deepEqual(cargoNewArgs("lib", "demo"), ["new", "--lib", "demo"]); | |
| 78 | }); | |
| 79 | }); | |
| 80 | } |
src/tools/rust-analyzer/editors/code/tests/unit/launch_config.test.ts+48-1| ... | ... | @@ -1,5 +1,9 @@ |
| 1 | 1 | import * as assert from "assert"; |
| 2 | import { Cargo } from "../../src/toolchain"; | |
| 2 | import * as os from "os"; | |
| 3 | import * as path from "path"; | |
| 4 | import { mkdtemp, mkdir, rm, writeFile } from "fs/promises"; | |
| 5 | import { Cargo, cargoPath } from "../../src/toolchain"; | |
| 6 | import { isWindows, normalizeDriveLetter } from "../../src/util"; | |
| 3 | 7 | import type { Context } from "."; |
| 4 | 8 | |
| 5 | 9 | export async function getTests(ctx: Context) { |
| ... | ... | @@ -96,4 +100,47 @@ export async function getTests(ctx: Context) { |
| 96 | 100 | assert.notDeepStrictEqual(args.filter, undefined); |
| 97 | 101 | }); |
| 98 | 102 | }); |
| 103 | ||
| 104 | await ctx.suite("Toolchain resolution", (suite) => { | |
| 105 | suite.addTest("prefers explicit CARGO from provided env", async () => { | |
| 106 | const explicitCargo = path.join(os.tmpdir(), "custom-cargo"); | |
| 107 | assert.strictEqual(await cargoPath({ CARGO: explicitCargo }), explicitCargo); | |
| 108 | }); | |
| 109 | ||
| 110 | suite.addTest("resolves cargo from provided PATH", async () => { | |
| 111 | const tempDir = await mkdtemp(path.join(os.tmpdir(), "ra-cargo-path-")); | |
| 112 | try { | |
| 113 | const cargoBinary = path.join(tempDir, isWindows ? "cargo.exe" : "cargo"); | |
| 114 | await writeFile(cargoBinary, ""); | |
| 115 | ||
| 116 | const pathKey = isWindows ? "Path" : "PATH"; | |
| 117 | assert.strictEqual(await cargoPath({ [pathKey]: tempDir }), "cargo"); | |
| 118 | } finally { | |
| 119 | await rm(tempDir, { recursive: true, force: true }); | |
| 120 | } | |
| 121 | }); | |
| 122 | ||
| 123 | suite.addTest("resolves cargo from provided CARGO_HOME", async () => { | |
| 124 | const cargoHome = await mkdtemp(path.join(os.tmpdir(), "ra-cargo-home-")); | |
| 125 | try { | |
| 126 | const binDir = path.join(cargoHome, "bin"); | |
| 127 | await mkdir(binDir); | |
| 128 | const cargoBinary = path.join(binDir, isWindows ? "cargo.exe" : "cargo"); | |
| 129 | await writeFile(cargoBinary, ""); | |
| 130 | ||
| 131 | assert.strictEqual( | |
| 132 | normalizeComparablePath(await cargoPath({ PATH: "", CARGO_HOME: cargoHome })), | |
| 133 | normalizeComparablePath(cargoBinary), | |
| 134 | ); | |
| 135 | } finally { | |
| 136 | await rm(cargoHome, { recursive: true, force: true }); | |
| 137 | } | |
| 138 | }); | |
| 139 | }); | |
| 140 | } | |
| 141 | ||
| 142 | function normalizeComparablePath(filePath: string): string { | |
| 143 | // Windows path comparisons should ignore drive-letter casing because `fsPath` | |
| 144 | // may normalize it differently while still pointing to the same file. | |
| 145 | return normalizeDriveLetter(filePath, isWindows); | |
| 99 | 146 | } |
src/tools/rust-analyzer/editors/code/walkthrough-create-project.md created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | # Create a New Cargo Project | |
| 2 | ||
| 3 | Create a new Cargo project without leaving VS Code. | |
| 4 | ||
| 5 | The command lets you choose the package kind, parent folder, project name, and | |
| 6 | how the new project should be opened afterward. | |
| 7 | ||
| 8 | The project is created with Cargo, so the generated files and defaults match | |
| 9 | the normal `cargo new` experience. |
src/tools/rust-analyzer/rust-version+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | 029c9e18dd1f4668e1d42bb187c1c263dfe20093 | |
| 1 | 942ac9ce4116d4ea784c9882659372b34978b1f8 |
tests/pretty/delegation-self-rename.pp+8-5| ... | ... | @@ -19,15 +19,18 @@ impl <'a, A, const B: bool> Trait<'a, A, B> for X { } |
| 19 | 19 | #[attr = Inline(Hint)] |
| 20 | 20 | fn foo<'a, Self, A, const B: _, const B2: _, T, U, |
| 21 | 21 | impl FnOnce() -> usize>(self: _, arg1: _) -> _ where |
| 22 | 'a:'a { Trait::<'a, A, B>::foo::<B2, T, U>(self, arg1) } | |
| 22 | 'a:'a { <Self as Trait::<'a, A, B>>::foo::<B2, T, U>(self, arg1) } | |
| 23 | 23 | #[attr = Inline(Hint)] |
| 24 | 24 | fn bar<Self, impl FnOnce() -> usize>(self: _, arg1: _) |
| 25 | -> _ { Trait::<'static, (), true>::foo::<true, (), ()>(self, arg1) } | |
| 25 | -> | |
| 26 | _ { | |
| 27 | <Self as Trait::<'static, (), true>>::foo::<true, (), ()>(self, arg1) | |
| 28 | } | |
| 26 | 29 | |
| 27 | 30 | #[attr = Inline(Hint)] |
| 28 | 31 | fn foo2<'a, This, A, const B: _, const B2: _, T, U, |
| 29 | 32 | impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where |
| 30 | 'a:'a { foo::<This, A, B, B2, T, U>(arg0, arg1) } | |
| 33 | 'a:'a { foo::<'a, This, A, B, B2, T, U>(arg0, arg1) } | |
| 31 | 34 | #[attr = Inline(Hint)] |
| 32 | 35 | fn bar2<This, impl FnOnce() -> usize>(arg0: _, arg1: _) |
| 33 | 36 | -> _ { bar::<This>(arg0, arg1) } |
| ... | ... | @@ -36,7 +39,7 @@ trait Trait2 { |
| 36 | 39 | #[attr = Inline(Hint)] |
| 37 | 40 | fn foo3<'a, This, A, const B: _, const B2: _, T, U, |
| 38 | 41 | impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where |
| 39 | 'a:'a { foo2::<This, A, B, B2, T, U>(arg0, arg1) } | |
| 42 | 'a:'a { foo2::<'a, This, A, B, B2, T, U>(arg0, arg1) } | |
| 40 | 43 | #[attr = Inline(Hint)] |
| 41 | 44 | fn bar3<This, impl FnOnce() -> usize>(arg0: _, arg1: _) |
| 42 | 45 | -> _ { bar2::<This>(arg0, arg1) } |
| ... | ... | @@ -47,7 +50,7 @@ impl Trait2 for () { } |
| 47 | 50 | #[attr = Inline(Hint)] |
| 48 | 51 | fn foo4<'a, This, A, const B: _, const B2: _, T, U, |
| 49 | 52 | impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where |
| 50 | 'a:'a { <() as Trait2>::foo3::<This, A, B, B2, T, U>(arg0, arg1) } | |
| 53 | 'a:'a { <() as Trait2>::foo3::<'a, This, A, B, B2, T, U>(arg0, arg1) } | |
| 51 | 54 | #[attr = Inline(Hint)] |
| 52 | 55 | fn bar4<This, impl FnOnce() -> usize>(arg0: _, arg1: _) |
| 53 | 56 | -> _ { <() as Trait2>::bar3::<This>(arg0, arg1) } |
tests/ui/array-slice-vec/eval-array-expr.rs created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/23354>. | |
| 2 | //! Check expr in [expr; N] is always being evaluated. | |
| 3 | //! | |
| 4 | //! This used to trigger an LLVM assertion during compilation | |
| 5 | //@ run-fail | |
| 6 | //@ error-pattern:panic evaluated | |
| 7 | //@ needs-subprocess | |
| 8 | ||
| 9 | #[allow(unused_variables)] | |
| 10 | fn main() { | |
| 11 | let x = [panic!("panic evaluated"); 2]; | |
| 12 | } |
tests/ui/array-slice-vec/eval-empty-array-expr.rs created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/23354>. | |
| 2 | //! Check expr in [expr; N] is always being evaluated. | |
| 3 | //@ run-fail | |
| 4 | //@ error-pattern:panic evaluated | |
| 5 | //@ needs-subprocess | |
| 6 | ||
| 7 | #[allow(unused_variables)] | |
| 8 | fn main() { | |
| 9 | let x = [panic!("panic evaluated"); 0]; | |
| 10 | } |
tests/ui/associated-types/assoc-type-projection-in-default-method.rs created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22036>. | |
| 2 | //@ run-pass | |
| 3 | ||
| 4 | trait DigitCollection: Sized { | |
| 5 | type Iter: Iterator<Item = u8>; | |
| 6 | fn digit_iter(self) -> Self::Iter; | |
| 7 | ||
| 8 | fn digit_sum(self) -> u32 { | |
| 9 | self.digit_iter() | |
| 10 | .map(|digit: u8| digit as u32) | |
| 11 | .fold(0, |sum, digit| sum + digit) | |
| 12 | } | |
| 13 | } | |
| 14 | ||
| 15 | impl<I> DigitCollection for I where I: Iterator<Item=u8> { | |
| 16 | type Iter = I; | |
| 17 | ||
| 18 | fn digit_iter(self) -> I { | |
| 19 | self | |
| 20 | } | |
| 21 | } | |
| 22 | ||
| 23 | fn main() { | |
| 24 | let xs = vec![1, 2, 3, 4, 5]; | |
| 25 | assert_eq!(xs.into_iter().digit_sum(), 15); | |
| 26 | } |
tests/ui/associated-types/associated-type-projection-alias-in-field.rs created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22356>. | |
| 2 | ||
| 3 | //@ check-pass | |
| 4 | #![allow(type_alias_bounds)] | |
| 5 | ||
| 6 | ||
| 7 | use std::marker::PhantomData; | |
| 8 | ||
| 9 | pub struct Handle<T, I>(T, I); | |
| 10 | ||
| 11 | impl<T, I> Handle<T, I> { | |
| 12 | pub fn get_info(&self) -> &I { | |
| 13 | let Handle(_, ref info) = *self; | |
| 14 | info | |
| 15 | } | |
| 16 | } | |
| 17 | ||
| 18 | pub struct BufferHandle<D: Device, T> { | |
| 19 | raw: RawBufferHandle<D>, | |
| 20 | _marker: PhantomData<T>, | |
| 21 | } | |
| 22 | ||
| 23 | impl<D: Device, T> BufferHandle<D, T> { | |
| 24 | pub fn get_info(&self) -> &String { | |
| 25 | self.raw.get_info() | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | pub type RawBufferHandle<D: Device> = Handle<<D as Device>::Buffer, String>; | |
| 30 | ||
| 31 | pub trait Device { | |
| 32 | type Buffer; | |
| 33 | } | |
| 34 | ||
| 35 | fn main() {} |
tests/ui/associated-types/associated-type-unconstrained-lifetime.rs created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22886>. | |
| 2 | //! Test that associated type's inner state cannot be observed past | |
| 3 | //! borrow end via saved reference. | |
| 4 | //! | |
| 5 | //! This was possible as trait implementation with unconstrained lifetime | |
| 6 | //! allowed to use any lifetime for associated type, which introduced | |
| 7 | //! soundness holes. | |
| 8 | //! | |
| 9 | //! Fixed by prohibiting use of unconstrained lifetimes on associated types | |
| 10 | //! in <https://github.com/rust-lang/rust/pull/24461>. | |
| 11 | //! | |
| 12 | //! Related <https://github.com/rust-lang/rust/issues/22077>. | |
| 13 | ||
| 14 | fn crash_please() { | |
| 15 | let mut iter = Newtype(Some(Box::new(0))); | |
| 16 | let saved = iter.next().unwrap(); | |
| 17 | println!("{}", saved); | |
| 18 | iter.0 = None; | |
| 19 | println!("{}", saved); | |
| 20 | } | |
| 21 | ||
| 22 | struct Newtype(Option<Box<usize>>); | |
| 23 | ||
| 24 | impl<'a> Iterator for Newtype { //~ ERROR E0207 | |
| 25 | type Item = &'a Box<usize>; | |
| 26 | ||
| 27 | fn next(&mut self) -> Option<&Box<usize>> { | |
| 28 | self.0.as_ref() | |
| 29 | } | |
| 30 | } | |
| 31 | ||
| 32 | fn main() { } |
tests/ui/associated-types/associated-type-unconstrained-lifetime.stderr created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates | |
| 2 | --> $DIR/associated-type-unconstrained-lifetime.rs:24:6 | |
| 3 | | | |
| 4 | LL | impl<'a> Iterator for Newtype { | |
| 5 | | ^^ unconstrained lifetime parameter | |
| 6 | | | |
| 7 | help: use the lifetime parameter `'a` in the `Newtype` type and use it in the type definition | |
| 8 | | | |
| 9 | LL ~ struct Newtype<'a>(Option<Box<usize>>); | |
| 10 | LL | | |
| 11 | LL ~ impl<'a> Iterator for Newtype<'a> { | |
| 12 | | | |
| 13 | ||
| 14 | error: aborting due to 1 previous error | |
| 15 | ||
| 16 | For more information about this error, try `rustc --explain E0207`. |
tests/ui/associated-types/normalize-assoc-types.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22629>. | |
| 2 | //! Test transitive analysis for associated types. Collected types | |
| 3 | //! should be normalized and new obligations generated. | |
| 4 | ||
| 5 | //@ run-pass | |
| 6 | #![allow(unused_imports)] | |
| 7 | ||
| 8 | use std::borrow::{ToOwned, Cow}; | |
| 9 | ||
| 10 | fn assert_send<T: Send>(_: T) {} | |
| 11 | ||
| 12 | fn main() { | |
| 13 | assert_send(Cow::Borrowed("foo")); | |
| 14 | } |
tests/ui/associated-types/ret-associated-type.rs created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22258>. | |
| 2 | ||
| 3 | //@ run-pass | |
| 4 | use std::ops::Add; | |
| 5 | ||
| 6 | fn f<T: Add>(a: T, b: T) -> <T as Add>::Output { | |
| 7 | a + b | |
| 8 | } | |
| 9 | ||
| 10 | fn main() { | |
| 11 | println!("a + b is {}", f::<f32>(100f32, 200f32)); | |
| 12 | } |
tests/ui/associated-types/supertrait-bound-references-own-associated-type.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22673>. | |
| 2 | //@ check-pass | |
| 3 | ||
| 4 | trait Expr: PartialEq<Self::Item> { | |
| 5 | type Item; | |
| 6 | } | |
| 7 | ||
| 8 | fn main() {} |
tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.rs created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | //@ compile-flags: -Znext-solver -Zassumptions-on-binders | |
| 2 | ||
| 3 | // Regression test for #157778. | |
| 4 | // | |
| 5 | // A non-lifetime binder (`for<T>`) introduces a placeholder *type* in universe `u`. The | |
| 6 | // resulting alias-outlives constraint `<!T as Trait>::Assoc: 'r` stays in `u` because the | |
| 7 | // region-only rewrite (`PlaceholderReplacer` only folds regions) cannot pull a type | |
| 8 | // placeholder out of `u`. This used to trip an `assert!(max_universe < u)` and ICE in | |
| 9 | // `pull_region_outlives_constraints_out_of_universe`. The assumptions-on-binders machinery | |
| 10 | // is region-outlives-only, so we now report ambiguity instead of panicking. | |
| 11 | ||
| 12 | #![feature(non_lifetime_binders)] | |
| 13 | ||
| 14 | trait Trait { | |
| 15 | type Assoc; | |
| 16 | type Ref //~ ERROR cannot satisfy `<T as Trait>::Assoc: 'static` | |
| 17 | where | |
| 18 | for<T> T: Trait<Assoc: 'static>; | |
| 19 | } | |
| 20 | ||
| 21 | fn main() {} |
tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.stderr created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | error[E0284]: type annotations needed: cannot satisfy `<T as Trait>::Assoc: 'static` | |
| 2 | --> $DIR/non_lifetime_binder_alias_outlives.rs:16:5 | |
| 3 | | | |
| 4 | LL | / type Ref | |
| 5 | LL | | where | |
| 6 | LL | | for<T> T: Trait<Assoc: 'static>; | |
| 7 | | |________________________________________^ cannot satisfy `<T as Trait>::Assoc: 'static` | |
| 8 | | | |
| 9 | note: required by a bound in `Trait::Ref` | |
| 10 | --> $DIR/non_lifetime_binder_alias_outlives.rs:18:32 | |
| 11 | | | |
| 12 | LL | type Ref | |
| 13 | | --- required by a bound in this associated type | |
| 14 | LL | where | |
| 15 | LL | for<T> T: Trait<Assoc: 'static>; | |
| 16 | | ^^^^^^^ required by this bound in `Trait::Ref` | |
| 17 | ||
| 18 | error: aborting due to 1 previous error | |
| 19 | ||
| 20 | For more information about this error, try `rustc --explain E0284`. |
tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | //@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally | |
| 2 | ||
| 3 | // Regression test for an ICE in the `MaxUniverse` region visitor. When computing | |
| 4 | // the max universe of a region constraint, a `ReVar` term could already have been | |
| 5 | // unified with another region. `universe_of_lt` returns `None` for such a resolved | |
| 6 | // variable, so the visitor used to `unwrap()` `None` and panic. | |
| 7 | // | |
| 8 | // The missing `T` in `check` is intentional. It makes HIR ty lowering emit an | |
| 9 | // error while still leaving behind the region constraint that used to ICE. | |
| 10 | ||
| 11 | #![feature(min_generic_const_args, inherent_associated_types, generic_const_items)] | |
| 12 | ||
| 13 | struct Parent<'a> { | |
| 14 | a: &'a str, | |
| 15 | } | |
| 16 | ||
| 17 | impl<'a> Parent<'a> { | |
| 18 | type const CT<T: 'a>: usize = 0; | |
| 19 | } | |
| 20 | ||
| 21 | fn check() | |
| 22 | where | |
| 23 | [(); Parent::CT::<T>]:, | |
| 24 | //~^ ERROR cannot find type `T` in this scope | |
| 25 | { | |
| 26 | } | |
| 27 | ||
| 28 | fn main() {} |
tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | error[E0425]: cannot find type `T` in this scope | |
| 2 | --> $DIR/resolved-region-var-max-universe.rs:23:23 | |
| 3 | | | |
| 4 | LL | [(); Parent::CT::<T>]:, | |
| 5 | | ^ not found in this scope | |
| 6 | | | |
| 7 | help: you might be missing a type parameter | |
| 8 | | | |
| 9 | LL | fn check<T>() | |
| 10 | | +++ | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 | ||
| 14 | For more information about this error, try `rustc --explain E0425`. |
tests/ui/attributes/invalid-crate-type.rs+49| ... | ... | @@ -1,5 +1,8 @@ |
| 1 | 1 | // regression test for issue 11256 |
| 2 | 2 | #![crate_type="foo"] //~ ERROR invalid `crate_type` value |
| 3 | //~| NOTE `#[deny(unknown_crate_types)]` on by default | |
| 4 | //~| HELP did you mean | |
| 5 | //~| SUGGESTION lib | |
| 3 | 6 | |
| 4 | 7 | // Tests for suggestions (#53958) |
| 5 | 8 | |
| ... | ... | @@ -43,6 +46,52 @@ |
| 43 | 46 | //~| HELP did you mean |
| 44 | 47 | //~| SUGGESTION cdylib |
| 45 | 48 | |
| 49 | // substring matching tests | |
| 50 | #![crate_type="binary"] | |
| 51 | //~^ ERROR invalid `crate_type` value | |
| 52 | //~| HELP did you mean | |
| 53 | //~| SUGGESTION bin | |
| 54 | ||
| 55 | #![crate_type="library"] | |
| 56 | //~^ ERROR invalid `crate_type` value | |
| 57 | //~| HELP did you mean | |
| 58 | //~| SUGGESTION lib | |
| 59 | ||
| 60 | #![crate_type="rustlib"] | |
| 61 | //~^ ERROR invalid `crate_type` value | |
| 62 | //~| HELP did you mean | |
| 63 | //~| SUGGESTION rlib | |
| 64 | ||
| 65 | #![crate_type="dynamiclib"] | |
| 66 | //~^ ERROR invalid `crate_type` value | |
| 67 | //~| HELP did you mean | |
| 68 | //~| SUGGESTION dylib | |
| 69 | ||
| 70 | #![crate_type="dylibrary"] | |
| 71 | //~^ ERROR invalid `crate_type` value | |
| 72 | //~| HELP did you mean | |
| 73 | //~| SUGGESTION dylib | |
| 74 | ||
| 75 | #![crate_type="cdynamiclib"] | |
| 76 | //~^ ERROR invalid `crate_type` value | |
| 77 | //~| HELP did you mean | |
| 78 | //~| SUGGESTION cdylib | |
| 79 | ||
| 80 | #![crate_type="cdylibrary"] | |
| 81 | //~^ ERROR invalid `crate_type` value | |
| 82 | //~| HELP did you mean | |
| 83 | //~| SUGGESTION cdylib | |
| 84 | ||
| 85 | #![crate_type="staticlibrary"] | |
| 86 | //~^ ERROR invalid `crate_type` value | |
| 87 | //~| HELP did you mean | |
| 88 | //~| SUGGESTION staticlib | |
| 89 | ||
| 90 | #![crate_type="procedural-macro"] | |
| 91 | //~^ ERROR invalid `crate_type` value | |
| 92 | //~| HELP did you mean | |
| 93 | //~| SUGGESTION proc-macro | |
| 94 | ||
| 46 | 95 | fn main() { |
| 47 | 96 | return |
| 48 | 97 | } |
tests/ui/attributes/invalid-crate-type.stderr+64-10| ... | ... | @@ -2,57 +2,111 @@ error: invalid `crate_type` value |
| 2 | 2 | --> $DIR/invalid-crate-type.rs:2:15 |
| 3 | 3 | | |
| 4 | 4 | LL | #![crate_type="foo"] |
| 5 | | ^^^^^ | |
| 5 | | ^^^^^ help: did you mean: `"lib"` | |
| 6 | 6 | | |
| 7 | 7 | = note: `#[deny(unknown_crate_types)]` on by default |
| 8 | 8 | |
| 9 | 9 | error: invalid `crate_type` value |
| 10 | --> $DIR/invalid-crate-type.rs:6:15 | |
| 10 | --> $DIR/invalid-crate-type.rs:9:15 | |
| 11 | 11 | | |
| 12 | 12 | LL | #![crate_type="statoclib"] |
| 13 | 13 | | ^^^^^^^^^^^ help: did you mean: `"staticlib"` |
| 14 | 14 | |
| 15 | 15 | error: invalid `crate_type` value |
| 16 | --> $DIR/invalid-crate-type.rs:11:15 | |
| 16 | --> $DIR/invalid-crate-type.rs:14:15 | |
| 17 | 17 | | |
| 18 | 18 | LL | #![crate_type="procmacro"] |
| 19 | 19 | | ^^^^^^^^^^^ help: did you mean: `"proc-macro"` |
| 20 | 20 | |
| 21 | 21 | error: invalid `crate_type` value |
| 22 | --> $DIR/invalid-crate-type.rs:16:15 | |
| 22 | --> $DIR/invalid-crate-type.rs:19:15 | |
| 23 | 23 | | |
| 24 | 24 | LL | #![crate_type="static-lib"] |
| 25 | 25 | | ^^^^^^^^^^^^ help: did you mean: `"staticlib"` |
| 26 | 26 | |
| 27 | 27 | error: invalid `crate_type` value |
| 28 | --> $DIR/invalid-crate-type.rs:21:15 | |
| 28 | --> $DIR/invalid-crate-type.rs:24:15 | |
| 29 | 29 | | |
| 30 | 30 | LL | #![crate_type="drylib"] |
| 31 | 31 | | ^^^^^^^^ help: did you mean: `"dylib"` |
| 32 | 32 | |
| 33 | 33 | error: invalid `crate_type` value |
| 34 | --> $DIR/invalid-crate-type.rs:26:15 | |
| 34 | --> $DIR/invalid-crate-type.rs:29:15 | |
| 35 | 35 | | |
| 36 | 36 | LL | #![crate_type="dlib"] |
| 37 | 37 | | ^^^^^^ help: did you mean: `"lib"` |
| 38 | 38 | |
| 39 | 39 | error: invalid `crate_type` value |
| 40 | --> $DIR/invalid-crate-type.rs:31:15 | |
| 40 | --> $DIR/invalid-crate-type.rs:34:15 | |
| 41 | 41 | | |
| 42 | 42 | LL | #![crate_type="lob"] |
| 43 | 43 | | ^^^^^ help: did you mean: `"lib"` |
| 44 | 44 | |
| 45 | 45 | error: invalid `crate_type` value |
| 46 | --> $DIR/invalid-crate-type.rs:36:15 | |
| 46 | --> $DIR/invalid-crate-type.rs:39:15 | |
| 47 | 47 | | |
| 48 | 48 | LL | #![crate_type="bon"] |
| 49 | 49 | | ^^^^^ help: did you mean: `"bin"` |
| 50 | 50 | |
| 51 | 51 | error: invalid `crate_type` value |
| 52 | --> $DIR/invalid-crate-type.rs:41:15 | |
| 52 | --> $DIR/invalid-crate-type.rs:44:15 | |
| 53 | 53 | | |
| 54 | 54 | LL | #![crate_type="cdalib"] |
| 55 | 55 | | ^^^^^^^^ help: did you mean: `"cdylib"` |
| 56 | 56 | |
| 57 | error: aborting due to 9 previous errors | |
| 57 | error: invalid `crate_type` value | |
| 58 | --> $DIR/invalid-crate-type.rs:50:15 | |
| 59 | | | |
| 60 | LL | #![crate_type="binary"] | |
| 61 | | ^^^^^^^^ help: did you mean: `"bin"` | |
| 62 | ||
| 63 | error: invalid `crate_type` value | |
| 64 | --> $DIR/invalid-crate-type.rs:55:15 | |
| 65 | | | |
| 66 | LL | #![crate_type="library"] | |
| 67 | | ^^^^^^^^^ help: did you mean: `"lib"` | |
| 68 | ||
| 69 | error: invalid `crate_type` value | |
| 70 | --> $DIR/invalid-crate-type.rs:60:15 | |
| 71 | | | |
| 72 | LL | #![crate_type="rustlib"] | |
| 73 | | ^^^^^^^^^ help: did you mean: `"rlib"` | |
| 74 | ||
| 75 | error: invalid `crate_type` value | |
| 76 | --> $DIR/invalid-crate-type.rs:65:15 | |
| 77 | | | |
| 78 | LL | #![crate_type="dynamiclib"] | |
| 79 | | ^^^^^^^^^^^^ help: did you mean: `"dylib"` | |
| 80 | ||
| 81 | error: invalid `crate_type` value | |
| 82 | --> $DIR/invalid-crate-type.rs:70:15 | |
| 83 | | | |
| 84 | LL | #![crate_type="dylibrary"] | |
| 85 | | ^^^^^^^^^^^ help: did you mean: `"dylib"` | |
| 86 | ||
| 87 | error: invalid `crate_type` value | |
| 88 | --> $DIR/invalid-crate-type.rs:75:15 | |
| 89 | | | |
| 90 | LL | #![crate_type="cdynamiclib"] | |
| 91 | | ^^^^^^^^^^^^^ help: did you mean: `"cdylib"` | |
| 92 | ||
| 93 | error: invalid `crate_type` value | |
| 94 | --> $DIR/invalid-crate-type.rs:80:15 | |
| 95 | | | |
| 96 | LL | #![crate_type="cdylibrary"] | |
| 97 | | ^^^^^^^^^^^^ help: did you mean: `"cdylib"` | |
| 98 | ||
| 99 | error: invalid `crate_type` value | |
| 100 | --> $DIR/invalid-crate-type.rs:85:15 | |
| 101 | | | |
| 102 | LL | #![crate_type="staticlibrary"] | |
| 103 | | ^^^^^^^^^^^^^^^ help: did you mean: `"staticlib"` | |
| 104 | ||
| 105 | error: invalid `crate_type` value | |
| 106 | --> $DIR/invalid-crate-type.rs:90:15 | |
| 107 | | | |
| 108 | LL | #![crate_type="procedural-macro"] | |
| 109 | | ^^^^^^^^^^^^^^^^^^ help: did you mean: `"proc-macro"` | |
| 110 | ||
| 111 | error: aborting due to 18 previous errors | |
| 58 | 112 |
tests/ui/auto-traits/hashmap-send-requires-send-contents.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/21763>. | |
| 2 | //! Test HashMap only impl Send/Sync if its contents do | |
| 3 | ||
| 4 | //@ normalize-stderr: "(?:[A-Za-z]:[/\\]|/).*[\\/]hashbrown\S+" -> "$$HASHBROWN_SRC_LOCATION" | |
| 5 | ||
| 6 | use std::collections::HashMap; | |
| 7 | use std::rc::Rc; | |
| 8 | ||
| 9 | fn foo<T: Send>() {} | |
| 10 | ||
| 11 | fn main() { | |
| 12 | foo::<HashMap<Rc<()>, Rc<()>>>(); | |
| 13 | //~^ ERROR `Rc<()>` cannot be sent between threads safely | |
| 14 | } |
tests/ui/auto-traits/hashmap-send-requires-send-contents.stderr created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely | |
| 2 | --> $DIR/hashmap-send-requires-send-contents.rs:12:11 | |
| 3 | | | |
| 4 | LL | foo::<HashMap<Rc<()>, Rc<()>>>(); | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely | |
| 6 | | | |
| 7 | = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>` | |
| 8 | = note: required because it appears within the type `(Rc<()>, Rc<()>)` | |
| 9 | = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send` | |
| 10 | note: required because it appears within the type `hashbrown::map::HashMap<Rc<()>, Rc<()>, RandomState>` | |
| 11 | --> $HASHBROWN_SRC_LOCATION | |
| 12 | note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>` | |
| 13 | --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL | |
| 14 | note: required by a bound in `foo` | |
| 15 | --> $DIR/hashmap-send-requires-send-contents.rs:9:11 | |
| 16 | | | |
| 17 | LL | fn foo<T: Send>() {} | |
| 18 | | ^^^^ required by this bound in `foo` | |
| 19 | ||
| 20 | error: aborting due to 1 previous error | |
| 21 | ||
| 22 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/binop/add-ref-operand-method-lookup.rs created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/21922>. | |
| 2 | //! | |
| 3 | //! Ensure Add works with all value/reference operand combinations, | |
| 4 | //! both via the + operator and ufcs. | |
| 5 | //! | |
| 6 | //! Originally method lookup failed only for x + &y. | |
| 7 | ||
| 8 | //@ run-pass | |
| 9 | use std::ops::Add; | |
| 10 | fn show(z: i32) { | |
| 11 | println!("{}", z) | |
| 12 | } | |
| 13 | fn main() { | |
| 14 | let x = 23; | |
| 15 | let y = 42; | |
| 16 | show(Add::add( x, y)); | |
| 17 | show(Add::add( x, &y)); | |
| 18 | show(Add::add(&x, y)); | |
| 19 | show(Add::add(&x, &y)); | |
| 20 | show( x + y); | |
| 21 | show( x + &y); | |
| 22 | show(&x + y); | |
| 23 | show(&x + &y); | |
| 24 | } |
tests/ui/binop/infer-rhs-type.rs created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/21634>. | |
| 2 | //@ run-pass | |
| 3 | ||
| 4 | #[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))] | |
| 5 | fn main() { | |
| 6 | if let Ok(x) = "3.1415".parse::<f64>() { | |
| 7 | assert_eq!(false, x <= 0.0); | |
| 8 | } | |
| 9 | if let Ok(x) = "3.1415".parse::<f64>() { | |
| 10 | assert_eq!(3.1415, x + 0.0); | |
| 11 | } | |
| 12 | if let Ok(mut x) = "3.1415".parse::<f64>() { | |
| 13 | assert_eq!(8.1415, { x += 5.0; x }); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] | |
| 18 | fn main() {} |
tests/ui/box/match-box-deref-codegen.rs created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/25497>. | |
| 2 | //! Test box deref in match arm doesn't generate invalid LLVM IR. | |
| 3 | //! Related <https://github.com/rust-lang/rust/issues/18845>. | |
| 4 | //@ run-pass | |
| 5 | ||
| 6 | #[derive(Clone, Debug, PartialEq)] | |
| 7 | enum Expression { | |
| 8 | Dummy, | |
| 9 | Add(Box<Expression>), | |
| 10 | } | |
| 11 | ||
| 12 | use Expression::*; | |
| 13 | ||
| 14 | fn simplify(exp: Expression) -> Expression { | |
| 15 | match exp { | |
| 16 | Add(n) => *n.clone(), | |
| 17 | _ => Dummy | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | fn main() { | |
| 22 | assert_eq!(simplify(Add(Box::new(Dummy))), Dummy); | |
| 23 | } |
tests/ui/cast/dyn-any-to-fn-with-missing-generics.rs created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/23024>. | |
| 2 | use std::any::Any; | |
| 3 | ||
| 4 | fn main() | |
| 5 | { | |
| 6 | fn h(x:i32) -> i32 {3*x} | |
| 7 | let mut vfnfer:Vec<Box<dyn Any>> = vec![]; | |
| 8 | vfnfer.push(Box::new(h)); | |
| 9 | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); | |
| 10 | //~^ ERROR the precise format of `Fn`-family traits' | |
| 11 | //~| ERROR missing generics for trait `Fn` | |
| 12 | } |
tests/ui/cast/dyn-any-to-fn-with-missing-generics.stderr created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change | |
| 2 | --> $DIR/dyn-any-to-fn-with-missing-generics.rs:9:39 | |
| 3 | | | |
| 4 | LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); | |
| 5 | | ^^ help: use parenthetical notation instead: `Fn() -> ()` | |
| 6 | | | |
| 7 | = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information | |
| 8 | = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable | |
| 9 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 10 | ||
| 11 | error[E0107]: missing generics for trait `Fn` | |
| 12 | --> $DIR/dyn-any-to-fn-with-missing-generics.rs:9:39 | |
| 13 | | | |
| 14 | LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); | |
| 15 | | ^^ expected 1 generic argument | |
| 16 | | | |
| 17 | help: add missing generic argument | |
| 18 | | | |
| 19 | LL | println!("{:?}",(vfnfer[0] as dyn Fn<Args>)(3)); | |
| 20 | | ++++++ | |
| 21 | ||
| 22 | error: aborting due to 2 previous errors | |
| 23 | ||
| 24 | Some errors have detailed explanations: E0107, E0658. | |
| 25 | For more information about an error, try `rustc --explain E0107`. |
tests/ui/cast/raw-ptr-to-dyn-fn-raw-ptr.rs created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22034>. | |
| 2 | ||
| 3 | fn main() { | |
| 4 | let ptr: *mut () = core::ptr::null_mut(); | |
| 5 | let _: &mut dyn Fn() = unsafe { | |
| 6 | &mut *(ptr as *mut dyn Fn()) | |
| 7 | //~^ ERROR expected a `Fn()` closure, found `()` | |
| 8 | }; | |
| 9 | } |
tests/ui/cast/raw-ptr-to-dyn-fn-raw-ptr.stderr created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | error[E0277]: expected a `Fn()` closure, found `()` | |
| 2 | --> $DIR/raw-ptr-to-dyn-fn-raw-ptr.rs:6:16 | |
| 3 | | | |
| 4 | LL | &mut *(ptr as *mut dyn Fn()) | |
| 5 | | ^^^ expected an `Fn()` closure, found `()` | |
| 6 | | | |
| 7 | = help: the trait `Fn()` is not implemented for `()` | |
| 8 | = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` | |
| 9 | = note: required for the cast from `*mut ()` to `*mut dyn Fn()` | |
| 10 | ||
| 11 | error: aborting due to 1 previous error | |
| 12 | ||
| 13 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/codegen/match-enum-range-metadata-misopt.rs created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/26468>. | |
| 2 | //! Range bug in LLVM misoptimized second `if let` inside `for _ in 0..1` away. | |
| 3 | //@ run-pass | |
| 4 | ||
| 5 | #![allow(dead_code)] | |
| 6 | ||
| 7 | enum FooMode { | |
| 8 | Check = 0x1001, | |
| 9 | } | |
| 10 | ||
| 11 | enum BarMode { | |
| 12 | Check = 0x2001, | |
| 13 | } | |
| 14 | ||
| 15 | enum Mode { | |
| 16 | Foo(FooMode), | |
| 17 | Bar(BarMode), | |
| 18 | } | |
| 19 | ||
| 20 | #[inline(never)] | |
| 21 | fn broken(mode: &Mode) -> u32 { | |
| 22 | for _ in 0..1 { | |
| 23 | if let Mode::Foo(FooMode::Check) = *mode { return 17 } | |
| 24 | if let Mode::Bar(BarMode::Check) = *mode { return 19 } | |
| 25 | } | |
| 26 | return 42; | |
| 27 | } | |
| 28 | ||
| 29 | fn main() { | |
| 30 | let mode = Mode::Bar(BarMode::Check); | |
| 31 | assert_eq!(broken(&mode), 19); | |
| 32 | } |
tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | #![expect(incomplete_features)] |
| 3 | 3 | |
| 4 | 4 | struct Y { |
| 5 | stuff: [u8; { ([1, 2], 3, [4, 5]) }], //~ ERROR expected `usize`, found const tuple | |
| 5 | stuff: [u8; { ([1, 2], 3, [4, 5]) }], //~ ERROR expected `usize`, found `([1, 2], 3, [4, 5])` | |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | fn main() {} |
tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | error: expected `usize`, found const tuple | |
| 1 | error: expected `usize`, found `([1, 2], 3, [4, 5])` | |
| 2 | 2 | --> $DIR/tuple_expr_arg_bad-issue-151048.rs:5:19 |
| 3 | 3 | | |
| 4 | 4 | LL | stuff: [u8; { ([1, 2], 3, [4, 5]) }], |
tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | #![expect(incomplete_features)] |
| 3 | 3 | |
| 4 | 4 | pub fn takes_nested_tuple<const N: u32>() { |
| 5 | takes_nested_tuple::<{ () }> //~ ERROR expected `u32`, found const tuple | |
| 5 | takes_nested_tuple::<{ () }> //~ ERROR expected `u32`, found `()` | |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | fn main() {} |
tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | error: expected `u32`, found const tuple | |
| 1 | error: expected `u32`, found `()` | |
| 2 | 2 | --> $DIR/tuple_expr_arg_mismatch_type.rs:5:28 |
| 3 | 3 | | |
| 4 | 4 | LL | takes_nested_tuple::<{ () }> |
tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | #![feature(min_generic_const_args, adt_const_params)] | |
| 2 | ||
| 3 | // Regression test for an ICE in privacy checking while walking the `T` qself | |
| 4 | // of `T::ASSOC` inside a tuple const argument. | |
| 5 | ||
| 6 | fn takes_tuple<const N: ()>() {} | |
| 7 | ||
| 8 | fn generic_caller<T, const N: u32>() { | |
| 9 | takes_tuple::<{ (N, T::ASSOC) }>; | |
| 10 | //~^ ERROR expected `()`, found `(N, T::ASSOC)` | |
| 11 | } | |
| 12 | ||
| 13 | fn main() {} |
tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.stderr created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | error: expected `()`, found `(N, T::ASSOC)` | |
| 2 | --> $DIR/tuple_expr_arg_unbounded_assoc_const.rs:9:21 | |
| 3 | | | |
| 4 | LL | takes_tuple::<{ (N, T::ASSOC) }>; | |
| 5 | | ^^^^^^^^^^^^^ | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 |
tests/ui/consts/const-eval/c-variadic-fail.rs+10| ... | ... | @@ -119,6 +119,15 @@ unsafe fn read_cast_pointer() { |
| 119 | 119 | //~^ ERROR requested `*const u8` is incompatible with next argument of type `usize` |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | unsafe fn read_cast_lifetime() { | |
| 123 | // The types are equal up to free lifetimes. | |
| 124 | const { read_as::<*const &'static i32>(std::ptr::dangling::<&i32>()) }; | |
| 125 | ||
| 126 | // Bound lifetimes do matter. | |
| 127 | const { read_as::<*const fn(&'static ())>(std::ptr::dangling::<for<'a> fn(&'a ())>()) }; | |
| 128 | //~^ ERROR va_arg type mismatch: requested `*const fn(&())` is incompatible with next argument of type `*const for<'a> fn(&'a ())` | |
| 129 | } | |
| 130 | ||
| 122 | 131 | fn use_after_free() { |
| 123 | 132 | const unsafe extern "C" fn helper(ap: ...) -> [u8; size_of::<VaList>()] { |
| 124 | 133 | unsafe { std::mem::transmute(ap) } |
| ... | ... | @@ -196,6 +205,7 @@ fn main() { |
| 196 | 205 | read_too_many(); |
| 197 | 206 | read_cast_numeric(); |
| 198 | 207 | read_cast_pointer(); |
| 208 | read_cast_lifetime(); | |
| 199 | 209 | manual_copy_read(); |
| 200 | 210 | manual_copy_drop(); |
| 201 | 211 | manual_copy_forget(); |
tests/ui/consts/const-eval/c-variadic-fail.stderr+47-19| ... | ... | @@ -390,8 +390,36 @@ LL | const { read_as::<*const u8>(1usize) }; |
| 390 | 390 | | |
| 391 | 391 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 392 | 392 | |
| 393 | error[E0080]: va_arg type mismatch: requested `*const fn(&())` is incompatible with next argument of type `*const for<'a> fn(&'a ())` | |
| 394 | --> $DIR/c-variadic-fail.rs:127:13 | |
| 395 | | | |
| 396 | LL | const { read_as::<*const fn(&'static ())>(std::ptr::dangling::<for<'a> fn(&'a ())>()) }; | |
| 397 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_lifetime::{constant#1}` failed inside this call | |
| 398 | | | |
| 399 | note: inside `read_as::<*const fn(&())>` | |
| 400 | --> $DIR/c-variadic-fail.rs:37:5 | |
| 401 | | | |
| 402 | LL | ap.next_arg::<T>() | |
| 403 | | ^^^^^^^^^^^^^^^^^^ | |
| 404 | note: inside `VaList::<'_>::next_arg::<*const fn(&())>` | |
| 405 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL | |
| 406 | ||
| 407 | note: erroneous constant encountered | |
| 408 | --> $DIR/c-variadic-fail.rs:127:5 | |
| 409 | | | |
| 410 | LL | const { read_as::<*const fn(&'static ())>(std::ptr::dangling::<for<'a> fn(&'a ())>()) }; | |
| 411 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 412 | ||
| 413 | note: erroneous constant encountered | |
| 414 | --> $DIR/c-variadic-fail.rs:127:5 | |
| 415 | | | |
| 416 | LL | const { read_as::<*const fn(&'static ())>(std::ptr::dangling::<for<'a> fn(&'a ())>()) }; | |
| 417 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 418 | | | |
| 419 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 420 | ||
| 393 | 421 | error[E0080]: memory access failed: ALLOC0 has been freed, so this pointer is dangling |
| 394 | --> $DIR/c-variadic-fail.rs:131:13 | |
| 422 | --> $DIR/c-variadic-fail.rs:140:13 | |
| 395 | 423 | | |
| 396 | 424 | LL | ap.next_arg::<i32>(); |
| 397 | 425 | | ^^^^^^^^^^^^^^^^^^^^ evaluation of `use_after_free::{constant#0}` failed inside this call |
| ... | ... | @@ -400,7 +428,7 @@ note: inside `VaList::<'_>::next_arg::<i32>` |
| 400 | 428 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 401 | 429 | |
| 402 | 430 | note: erroneous constant encountered |
| 403 | --> $DIR/c-variadic-fail.rs:127:5 | |
| 431 | --> $DIR/c-variadic-fail.rs:136:5 | |
| 404 | 432 | | |
| 405 | 433 | LL | / const { |
| 406 | 434 | LL | | unsafe { |
| ... | ... | @@ -411,7 +439,7 @@ LL | | }; |
| 411 | 439 | | |_____^ |
| 412 | 440 | |
| 413 | 441 | note: erroneous constant encountered |
| 414 | --> $DIR/c-variadic-fail.rs:127:5 | |
| 442 | --> $DIR/c-variadic-fail.rs:136:5 | |
| 415 | 443 | | |
| 416 | 444 | LL | / const { |
| 417 | 445 | LL | | unsafe { |
| ... | ... | @@ -424,13 +452,13 @@ LL | | }; |
| 424 | 452 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 425 | 453 | |
| 426 | 454 | error[E0080]: using ALLOC1 as variable argument list pointer but it does not point to a variable argument list |
| 427 | --> $DIR/c-variadic-fail.rs:153:22 | |
| 455 | --> $DIR/c-variadic-fail.rs:162:22 | |
| 428 | 456 | | |
| 429 | 457 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 430 | 458 | | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_drop::{constant#0}` failed inside this call |
| 431 | 459 | | |
| 432 | 460 | note: inside `manual_copy_drop::helper` |
| 433 | --> $DIR/c-variadic-fail.rs:150:9 | |
| 461 | --> $DIR/c-variadic-fail.rs:159:9 | |
| 434 | 462 | | |
| 435 | 463 | LL | drop(ap); |
| 436 | 464 | | ^^^^^^^^ |
| ... | ... | @@ -442,13 +470,13 @@ note: inside `<VaList<'_> as Drop>::drop` |
| 442 | 470 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 443 | 471 | |
| 444 | 472 | note: erroneous constant encountered |
| 445 | --> $DIR/c-variadic-fail.rs:153:5 | |
| 473 | --> $DIR/c-variadic-fail.rs:162:5 | |
| 446 | 474 | | |
| 447 | 475 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 448 | 476 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 449 | 477 | |
| 450 | 478 | note: erroneous constant encountered |
| 451 | --> $DIR/c-variadic-fail.rs:153:5 | |
| 479 | --> $DIR/c-variadic-fail.rs:162:5 | |
| 452 | 480 | | |
| 453 | 481 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 454 | 482 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -456,13 +484,13 @@ LL | const { unsafe { helper(1, 2, 3) } }; |
| 456 | 484 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 457 | 485 | |
| 458 | 486 | error[E0080]: using ALLOC2 as variable argument list pointer but it does not point to a variable argument list |
| 459 | --> $DIR/c-variadic-fail.rs:169:22 | |
| 487 | --> $DIR/c-variadic-fail.rs:178:22 | |
| 460 | 488 | | |
| 461 | 489 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 462 | 490 | | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_forget::{constant#0}` failed inside this call |
| 463 | 491 | | |
| 464 | 492 | note: inside `manual_copy_forget::helper` |
| 465 | --> $DIR/c-variadic-fail.rs:166:9 | |
| 493 | --> $DIR/c-variadic-fail.rs:175:9 | |
| 466 | 494 | | |
| 467 | 495 | LL | drop(ap); |
| 468 | 496 | | ^^^^^^^^ |
| ... | ... | @@ -474,13 +502,13 @@ note: inside `<VaList<'_> as Drop>::drop` |
| 474 | 502 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 475 | 503 | |
| 476 | 504 | note: erroneous constant encountered |
| 477 | --> $DIR/c-variadic-fail.rs:169:5 | |
| 505 | --> $DIR/c-variadic-fail.rs:178:5 | |
| 478 | 506 | | |
| 479 | 507 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 480 | 508 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 481 | 509 | |
| 482 | 510 | note: erroneous constant encountered |
| 483 | --> $DIR/c-variadic-fail.rs:169:5 | |
| 511 | --> $DIR/c-variadic-fail.rs:178:5 | |
| 484 | 512 | | |
| 485 | 513 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 486 | 514 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -488,13 +516,13 @@ LL | const { unsafe { helper(1, 2, 3) } }; |
| 488 | 516 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 489 | 517 | |
| 490 | 518 | error[E0080]: using ALLOC3 as variable argument list pointer but it does not point to a variable argument list |
| 491 | --> $DIR/c-variadic-fail.rs:182:22 | |
| 519 | --> $DIR/c-variadic-fail.rs:191:22 | |
| 492 | 520 | | |
| 493 | 521 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 494 | 522 | | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_read::{constant#0}` failed inside this call |
| 495 | 523 | | |
| 496 | 524 | note: inside `manual_copy_read::helper` |
| 497 | --> $DIR/c-variadic-fail.rs:179:17 | |
| 525 | --> $DIR/c-variadic-fail.rs:188:17 | |
| 498 | 526 | | |
| 499 | 527 | LL | let _ = ap.next_arg::<i32>(); |
| 500 | 528 | | ^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -502,13 +530,13 @@ note: inside `VaList::<'_>::next_arg::<i32>` |
| 502 | 530 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 503 | 531 | |
| 504 | 532 | note: erroneous constant encountered |
| 505 | --> $DIR/c-variadic-fail.rs:182:5 | |
| 533 | --> $DIR/c-variadic-fail.rs:191:5 | |
| 506 | 534 | | |
| 507 | 535 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 508 | 536 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 509 | 537 | |
| 510 | 538 | note: erroneous constant encountered |
| 511 | --> $DIR/c-variadic-fail.rs:182:5 | |
| 539 | --> $DIR/c-variadic-fail.rs:191:5 | |
| 512 | 540 | | |
| 513 | 541 | LL | const { unsafe { helper(1, 2, 3) } }; |
| 514 | 542 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -516,7 +544,7 @@ LL | const { unsafe { helper(1, 2, 3) } }; |
| 516 | 544 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 517 | 545 | |
| 518 | 546 | error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got null pointer |
| 519 | --> $DIR/c-variadic-fail.rs:190:5 | |
| 547 | --> $DIR/c-variadic-fail.rs:199:5 | |
| 520 | 548 | | |
| 521 | 549 | LL | } |
| 522 | 550 | | ^ evaluation of `drop_of_invalid::{constant#0}` failed inside this call |
| ... | ... | @@ -527,7 +555,7 @@ note: inside `<VaList<'_> as Drop>::drop` |
| 527 | 555 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 528 | 556 | |
| 529 | 557 | note: erroneous constant encountered |
| 530 | --> $DIR/c-variadic-fail.rs:187:5 | |
| 558 | --> $DIR/c-variadic-fail.rs:196:5 | |
| 531 | 559 | | |
| 532 | 560 | LL | / const { |
| 533 | 561 | LL | | let mut invalid: MaybeUninit<VaList> = MaybeUninit::zeroed(); |
| ... | ... | @@ -536,7 +564,7 @@ LL | | } |
| 536 | 564 | | |_____^ |
| 537 | 565 | |
| 538 | 566 | note: erroneous constant encountered |
| 539 | --> $DIR/c-variadic-fail.rs:187:5 | |
| 567 | --> $DIR/c-variadic-fail.rs:196:5 | |
| 540 | 568 | | |
| 541 | 569 | LL | / const { |
| 542 | 570 | LL | | let mut invalid: MaybeUninit<VaList> = MaybeUninit::zeroed(); |
| ... | ... | @@ -546,6 +574,6 @@ LL | | } |
| 546 | 574 | | |
| 547 | 575 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 548 | 576 | |
| 549 | error: aborting due to 19 previous errors | |
| 577 | error: aborting due to 20 previous errors | |
| 550 | 578 | |
| 551 | 579 | For more information about this error, try `rustc --explain E0080`. |
tests/ui/delegation/generics/free-fn-to-trait-infer.rs deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | //@ compile-flags: -Z deduplicate-diagnostics=yes | |
| 2 | ||
| 3 | #![feature(fn_delegation)] | |
| 4 | ||
| 5 | trait Trait<T> { | |
| 6 | fn foo<U>(&self, _: U, _: T) {} | |
| 7 | } | |
| 8 | ||
| 9 | impl<T> Trait<T> for u8 {} | |
| 10 | ||
| 11 | reuse Trait::<_>::foo::<i32> as generic_arguments1; | |
| 12 | //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions | |
| 13 | reuse <u8 as Trait<_>>::foo as generic_arguments2; | |
| 14 | //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions | |
| 15 | reuse <_ as Trait<_>>::foo as generic_arguments3; | |
| 16 | //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions | |
| 17 | //~| ERROR the placeholder `_` is not allowed within types on item signatures for functions | |
| 18 | ||
| 19 | fn main() {} |
tests/ui/delegation/generics/free-fn-to-trait-infer.stderr deleted-27| ... | ... | @@ -1,27 +0,0 @@ |
| 1 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 2 | --> $DIR/free-fn-to-trait-infer.rs:11:15 | |
| 3 | | | |
| 4 | LL | reuse Trait::<_>::foo::<i32> as generic_arguments1; | |
| 5 | | ^ not allowed in type signatures | |
| 6 | ||
| 7 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 8 | --> $DIR/free-fn-to-trait-infer.rs:13:20 | |
| 9 | | | |
| 10 | LL | reuse <u8 as Trait<_>>::foo as generic_arguments2; | |
| 11 | | ^ not allowed in type signatures | |
| 12 | ||
| 13 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 14 | --> $DIR/free-fn-to-trait-infer.rs:15:8 | |
| 15 | | | |
| 16 | LL | reuse <_ as Trait<_>>::foo as generic_arguments3; | |
| 17 | | ^ not allowed in type signatures | |
| 18 | ||
| 19 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 20 | --> $DIR/free-fn-to-trait-infer.rs:15:19 | |
| 21 | | | |
| 22 | LL | reuse <_ as Trait<_>>::foo as generic_arguments3; | |
| 23 | | ^ not allowed in type signatures | |
| 24 | ||
| 25 | error: aborting due to 4 previous errors | |
| 26 | ||
| 27 | For more information about this error, try `rustc --explain E0121`. |
tests/ui/delegation/generics/free-to-trait-static-reuse.rs-8| ... | ... | @@ -20,17 +20,9 @@ reuse <usize as Trait>::static_method as bar { self + 1 } |
| 20 | 20 | reuse <usize as Trait>::static_method::<'static, Vec<i32>, false> as bar2; |
| 21 | 21 | |
| 22 | 22 | reuse Trait::static_method as error { self - 123 } |
| 23 | //~^ ERROR: type annotations needed | |
| 24 | //~| ERROR: delegation self type is not specified | |
| 25 | 23 | reuse Trait::<'static, i32, 123>::static_method as error2; |
| 26 | //~^ ERROR: type annotations needed | |
| 27 | //~| ERROR: delegation self type is not specified | |
| 28 | 24 | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; |
| 29 | //~^ ERROR: type annotations needed | |
| 30 | //~| ERROR: delegation self type is not specified | |
| 31 | 25 | reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 } |
| 32 | //~^ ERROR: type annotations needed | |
| 33 | //~| ERROR: delegation self type is not specified | |
| 34 | 26 | |
| 35 | 27 | reuse <String as Trait>::static_method as error5; |
| 36 | 28 | //~^ ERROR: the trait bound `String: Trait<'a, T, X>` is not satisfied |
tests/ui/delegation/generics/free-to-trait-static-reuse.stderr+7-100| ... | ... | @@ -1,43 +1,11 @@ |
| 1 | error: delegation self type is not specified | |
| 2 | --> $DIR/free-to-trait-static-reuse.rs:22:14 | |
| 3 | | | |
| 4 | LL | reuse Trait::static_method as error { self - 123 } | |
| 5 | | ^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function` | |
| 8 | ||
| 9 | error: delegation self type is not specified | |
| 10 | --> $DIR/free-to-trait-static-reuse.rs:25:35 | |
| 11 | | | |
| 12 | LL | reuse Trait::<'static, i32, 123>::static_method as error2; | |
| 13 | | ^^^^^^^^^^^^^ | |
| 14 | | | |
| 15 | = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function` | |
| 16 | ||
| 17 | error: delegation self type is not specified | |
| 18 | --> $DIR/free-to-trait-static-reuse.rs:28:35 | |
| 19 | | | |
| 20 | LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; | |
| 21 | | ^^^^^^^^^^^^^ | |
| 22 | | | |
| 23 | = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function` | |
| 24 | ||
| 25 | error: delegation self type is not specified | |
| 26 | --> $DIR/free-to-trait-static-reuse.rs:31:14 | |
| 27 | | | |
| 28 | LL | reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 } | |
| 29 | | ^^^^^^^^^^^^^ | |
| 30 | | | |
| 31 | = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function` | |
| 32 | ||
| 33 | 1 | error[E0277]: the trait bound `Struct: Bound<T>` is not satisfied |
| 34 | --> $DIR/free-to-trait-static-reuse.rs:39:49 | |
| 2 | --> $DIR/free-to-trait-static-reuse.rs:31:49 | |
| 35 | 3 | | |
| 36 | 4 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} |
| 37 | 5 | | ^^^^^^ unsatisfied trait bound |
| 38 | 6 | | |
| 39 | 7 | help: the trait `Bound<T>` is not implemented for `Struct` |
| 40 | --> $DIR/free-to-trait-static-reuse.rs:38:1 | |
| 8 | --> $DIR/free-to-trait-static-reuse.rs:30:1 | |
| 41 | 9 | | |
| 42 | 10 | LL | struct Struct; |
| 43 | 11 | | ^^^^^^^^^^^^^ |
| ... | ... | @@ -55,68 +23,8 @@ LL | where |
| 55 | 23 | LL | Self: Bound<T>, |
| 56 | 24 | | ^^^^^^^^ required by this bound in `Trait` |
| 57 | 25 | |
| 58 | error[E0283]: type annotations needed | |
| 59 | --> $DIR/free-to-trait-static-reuse.rs:22:14 | |
| 60 | | | |
| 61 | LL | reuse Trait::static_method as error { self - 123 } | |
| 62 | | ^^^^^^^^^^^^^ cannot infer type | |
| 63 | | | |
| 64 | note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found | |
| 65 | --> $DIR/free-to-trait-static-reuse.rs:14:1 | |
| 66 | | | |
| 67 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} | |
| 68 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 69 | ... | |
| 70 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} | |
| 71 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 72 | ||
| 73 | error[E0283]: type annotations needed | |
| 74 | --> $DIR/free-to-trait-static-reuse.rs:25:35 | |
| 75 | | | |
| 76 | LL | reuse Trait::<'static, i32, 123>::static_method as error2; | |
| 77 | | ^^^^^^^^^^^^^ cannot infer type | |
| 78 | | | |
| 79 | note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found | |
| 80 | --> $DIR/free-to-trait-static-reuse.rs:14:1 | |
| 81 | | | |
| 82 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} | |
| 83 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 84 | ... | |
| 85 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} | |
| 86 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 87 | ||
| 88 | error[E0283]: type annotations needed | |
| 89 | --> $DIR/free-to-trait-static-reuse.rs:28:35 | |
| 90 | | | |
| 91 | LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; | |
| 92 | | ^^^^^^^^^^^^^ cannot infer type | |
| 93 | | | |
| 94 | note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found | |
| 95 | --> $DIR/free-to-trait-static-reuse.rs:14:1 | |
| 96 | | | |
| 97 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} | |
| 98 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 99 | ... | |
| 100 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} | |
| 101 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 102 | ||
| 103 | error[E0283]: type annotations needed | |
| 104 | --> $DIR/free-to-trait-static-reuse.rs:31:14 | |
| 105 | | | |
| 106 | LL | reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 } | |
| 107 | | ^^^^^^^^^^^^^ cannot infer type | |
| 108 | | | |
| 109 | note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found | |
| 110 | --> $DIR/free-to-trait-static-reuse.rs:14:1 | |
| 111 | | | |
| 112 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} | |
| 113 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 114 | ... | |
| 115 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} | |
| 116 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 117 | ||
| 118 | 26 | error[E0277]: the trait bound `String: Trait<'a, T, X>` is not satisfied |
| 119 | --> $DIR/free-to-trait-static-reuse.rs:35:8 | |
| 27 | --> $DIR/free-to-trait-static-reuse.rs:27:8 | |
| 120 | 28 | | |
| 121 | 29 | LL | reuse <String as Trait>::static_method as error5; |
| 122 | 30 | | ^^^^^^ the trait `Trait<'a, T, X>` is not implemented for `String` |
| ... | ... | @@ -131,13 +39,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} |
| 131 | 39 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Struct` |
| 132 | 40 | |
| 133 | 41 | error[E0277]: the trait bound `Struct: Bound<T>` is not satisfied |
| 134 | --> $DIR/free-to-trait-static-reuse.rs:42:8 | |
| 42 | --> $DIR/free-to-trait-static-reuse.rs:34:8 | |
| 135 | 43 | | |
| 136 | 44 | LL | reuse <Struct as Trait>::static_method as error6; |
| 137 | 45 | | ^^^^^^ unsatisfied trait bound |
| 138 | 46 | | |
| 139 | 47 | help: the trait `Bound<T>` is not implemented for `Struct` |
| 140 | --> $DIR/free-to-trait-static-reuse.rs:38:1 | |
| 48 | --> $DIR/free-to-trait-static-reuse.rs:30:1 | |
| 141 | 49 | | |
| 142 | 50 | LL | struct Struct; |
| 143 | 51 | | ^^^^^^^^^^^^^ |
| ... | ... | @@ -155,7 +63,6 @@ LL | { |
| 155 | 63 | LL | fn static_method<'c: 'c, U, const B: bool>(x: usize) {} |
| 156 | 64 | | ------------- required by a bound in this associated function |
| 157 | 65 | |
| 158 | error: aborting due to 11 previous errors | |
| 66 | error: aborting due to 3 previous errors | |
| 159 | 67 | |
| 160 | Some errors have detailed explanations: E0277, E0283. | |
| 161 | For more information about an error, try `rustc --explain E0277`. | |
| 68 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/delegation/generics/generics-gen-args-errors.rs+6-7| ... | ... | @@ -44,8 +44,6 @@ mod test_2 { |
| 44 | 44 | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} |
| 45 | 45 | |
| 46 | 46 | reuse foo::<> as bar1; |
| 47 | //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions | |
| 48 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 49 | 47 | |
| 50 | 48 | reuse foo::<String, String> as bar2; |
| 51 | 49 | //~^ ERROR: function takes 3 generic arguments but 2 generic arguments were supplied |
| ... | ... | @@ -54,9 +52,9 @@ mod test_2 { |
| 54 | 52 | |
| 55 | 53 | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; |
| 56 | 54 | //~^ ERROR: use of undeclared lifetime name `'asdasd` |
| 57 | //~| ERROR: function takes 2 lifetime arguments but 5 lifetime arguments were supplied | |
| 58 | //~| ERROR: function takes 3 generic arguments but 2 generic arguments were supplied | |
| 59 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 55 | //~| ERROR: function takes 2 lifetime arguments but 6 lifetime arguments were supplied | |
| 56 | //~| ERROR: function takes 3 generic arguments but 1 generic argument was supplied | |
| 57 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 60 | 58 | |
| 61 | 59 | reuse foo::<String, 'static, 123, asdasd> as bar4; |
| 62 | 60 | //~^ ERROR: cannot find type `asdasd` in this scope |
| ... | ... | @@ -131,12 +129,13 @@ mod test_3 { |
| 131 | 129 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 132 | 130 | |
| 133 | 131 | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; |
| 134 | //~^ ERROR: trait takes 3 lifetime arguments but 1 lifetime argument was supplied | |
| 135 | //~| ERROR: trait takes 2 generic arguments but 5 generic arguments were supplied | |
| 132 | //~^ ERROR: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied | |
| 133 | //~| ERROR: trait takes 2 generic arguments but 4 generic arguments were supplied | |
| 136 | 134 | //~| ERROR: method takes 2 generic arguments but 5 generic arguments were supplied |
| 137 | 135 | //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied |
| 138 | 136 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 139 | 137 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 138 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 140 | 139 | } |
| 141 | 140 | |
| 142 | 141 | fn main() {} |
tests/ui/delegation/generics/generics-gen-args-errors.stderr+102-108| ... | ... | @@ -38,7 +38,7 @@ LL | reuse foo::<A, B, C> as xd; |
| 38 | 38 | = note: nested items are independent from their parent item for everything except for privacy and name resolution |
| 39 | 39 | |
| 40 | 40 | error[E0261]: use of undeclared lifetime name `'asdasd` |
| 41 | --> $DIR/generics-gen-args-errors.rs:55:29 | |
| 41 | --> $DIR/generics-gen-args-errors.rs:53:29 | |
| 42 | 42 | | |
| 43 | 43 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; |
| 44 | 44 | | ^^^^^^^ undeclared lifetime |
| ... | ... | @@ -49,7 +49,7 @@ LL | reuse foo'asdasd, ::<'static, _, 'asdasd, 'static, 'static, 'static, _> |
| 49 | 49 | | ++++++++ |
| 50 | 50 | |
| 51 | 51 | error[E0261]: use of undeclared lifetime name `'a` |
| 52 | --> $DIR/generics-gen-args-errors.rs:77:50 | |
| 52 | --> $DIR/generics-gen-args-errors.rs:75:50 | |
| 53 | 53 | | |
| 54 | 54 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; |
| 55 | 55 | | ^^ undeclared lifetime |
| ... | ... | @@ -103,65 +103,77 @@ LL | fn check<A, B, C, asd>() { |
| 103 | 103 | | +++++ |
| 104 | 104 | |
| 105 | 105 | error[E0425]: cannot find type `asdasd` in this scope |
| 106 | --> $DIR/generics-gen-args-errors.rs:61:39 | |
| 106 | --> $DIR/generics-gen-args-errors.rs:59:39 | |
| 107 | 107 | | |
| 108 | 108 | LL | reuse foo::<String, 'static, 123, asdasd> as bar4; |
| 109 | 109 | | ^^^^^^ not found in this scope |
| 110 | 110 | |
| 111 | 111 | error[E0425]: cannot find type `asd` in this scope |
| 112 | --> $DIR/generics-gen-args-errors.rs:71:22 | |
| 112 | --> $DIR/generics-gen-args-errors.rs:69:22 | |
| 113 | 113 | | |
| 114 | 114 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; |
| 115 | 115 | | ^^^ not found in this scope |
| 116 | 116 | |
| 117 | 117 | error[E0425]: cannot find type `asd` in this scope |
| 118 | --> $DIR/generics-gen-args-errors.rs:77:27 | |
| 118 | --> $DIR/generics-gen-args-errors.rs:75:27 | |
| 119 | 119 | | |
| 120 | 120 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; |
| 121 | 121 | | ^^^ not found in this scope |
| 122 | 122 | |
| 123 | 123 | error[E0425]: cannot find type `asd` in this scope |
| 124 | --> $DIR/generics-gen-args-errors.rs:94:19 | |
| 124 | --> $DIR/generics-gen-args-errors.rs:92:19 | |
| 125 | 125 | | |
| 126 | 126 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 127 | 127 | | ^^^ not found in this scope |
| 128 | 128 | |
| 129 | 129 | error[E0425]: cannot find type `asd` in this scope |
| 130 | --> $DIR/generics-gen-args-errors.rs:94:24 | |
| 130 | --> $DIR/generics-gen-args-errors.rs:92:24 | |
| 131 | 131 | | |
| 132 | 132 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 133 | 133 | | ^^^ not found in this scope |
| 134 | 134 | |
| 135 | 135 | error[E0425]: cannot find type `asd` in this scope |
| 136 | --> $DIR/generics-gen-args-errors.rs:94:29 | |
| 136 | --> $DIR/generics-gen-args-errors.rs:92:29 | |
| 137 | 137 | | |
| 138 | 138 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 139 | 139 | | ^^^ not found in this scope |
| 140 | 140 | |
| 141 | 141 | error[E0425]: cannot find type `asd` in this scope |
| 142 | --> $DIR/generics-gen-args-errors.rs:94:34 | |
| 142 | --> $DIR/generics-gen-args-errors.rs:92:34 | |
| 143 | 143 | | |
| 144 | 144 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 145 | 145 | | ^^^ not found in this scope |
| 146 | 146 | |
| 147 | 147 | error[E0425]: cannot find type `asd` in this scope |
| 148 | --> $DIR/generics-gen-args-errors.rs:94:39 | |
| 148 | --> $DIR/generics-gen-args-errors.rs:92:39 | |
| 149 | 149 | | |
| 150 | 150 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 151 | 151 | | ^^^ not found in this scope |
| 152 | 152 | |
| 153 | 153 | error[E0425]: cannot find type `asdasa` in this scope |
| 154 | --> $DIR/generics-gen-args-errors.rs:94:44 | |
| 154 | --> $DIR/generics-gen-args-errors.rs:92:44 | |
| 155 | 155 | | |
| 156 | 156 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 157 | 157 | | ^^^^^^ not found in this scope |
| 158 | 158 | |
| 159 | 159 | error[E0425]: cannot find type `DDDD` in this scope |
| 160 | --> $DIR/generics-gen-args-errors.rs:124:34 | |
| 160 | --> $DIR/generics-gen-args-errors.rs:122:34 | |
| 161 | 161 | | |
| 162 | 162 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 163 | 163 | | ^^^^ not found in this scope |
| 164 | 164 | |
| 165 | error: wrong infer used: expected '_, found: _ | |
| 166 | --> $DIR/generics-gen-args-errors.rs:53:26 | |
| 167 | | | |
| 168 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | |
| 169 | | ^ | |
| 170 | ||
| 171 | error: wrong infer used: expected '_, found: _ | |
| 172 | --> $DIR/generics-gen-args-errors.rs:131:33 | |
| 173 | | | |
| 174 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; | |
| 175 | | ^ | |
| 176 | ||
| 165 | 177 | error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied |
| 166 | 178 | --> $DIR/generics-gen-args-errors.rs:33:15 |
| 167 | 179 | | |
| ... | ... | @@ -184,20 +196,8 @@ error: inferred lifetimes are not allowed in delegations as we need to inherit s |
| 184 | 196 | LL | reuse foo::<A, B, C> as xd; |
| 185 | 197 | | ^^^ |
| 186 | 198 | |
| 187 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 188 | --> $DIR/generics-gen-args-errors.rs:46:11 | |
| 189 | | | |
| 190 | LL | reuse foo::<> as bar1; | |
| 191 | | ^^^ | |
| 192 | ||
| 193 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 194 | --> $DIR/generics-gen-args-errors.rs:46:11 | |
| 195 | | | |
| 196 | LL | reuse foo::<> as bar1; | |
| 197 | | ^^^ not allowed in type signatures | |
| 198 | ||
| 199 | 199 | error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied |
| 200 | --> $DIR/generics-gen-args-errors.rs:50:11 | |
| 200 | --> $DIR/generics-gen-args-errors.rs:48:11 | |
| 201 | 201 | | |
| 202 | 202 | LL | reuse foo::<String, String> as bar2; |
| 203 | 203 | | ^^^ expected 2 lifetime arguments |
| ... | ... | @@ -213,7 +213,7 @@ LL | reuse foo::<'a, 'b, String, String> as bar2; |
| 213 | 213 | | +++++++ |
| 214 | 214 | |
| 215 | 215 | error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied |
| 216 | --> $DIR/generics-gen-args-errors.rs:50:11 | |
| 216 | --> $DIR/generics-gen-args-errors.rs:48:11 | |
| 217 | 217 | | |
| 218 | 218 | LL | reuse foo::<String, String> as bar2; |
| 219 | 219 | | ^^^ ------ ------ supplied 2 generic arguments |
| ... | ... | @@ -231,16 +231,16 @@ LL | reuse foo::<String, String, N> as bar2; |
| 231 | 231 | | +++ |
| 232 | 232 | |
| 233 | 233 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 234 | --> $DIR/generics-gen-args-errors.rs:50:11 | |
| 234 | --> $DIR/generics-gen-args-errors.rs:48:11 | |
| 235 | 235 | | |
| 236 | 236 | LL | reuse foo::<String, String> as bar2; |
| 237 | 237 | | ^^^ |
| 238 | 238 | |
| 239 | error[E0107]: function takes 2 lifetime arguments but 5 lifetime arguments were supplied | |
| 240 | --> $DIR/generics-gen-args-errors.rs:55:11 | |
| 239 | error[E0107]: function takes 2 lifetime arguments but 6 lifetime arguments were supplied | |
| 240 | --> $DIR/generics-gen-args-errors.rs:53:11 | |
| 241 | 241 | | |
| 242 | 242 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; |
| 243 | | ^^^ --------------------------- help: remove the lifetime arguments | |
| 243 | | ^^^------------------------------------------------- help: remove the lifetime arguments | |
| 244 | 244 | | | |
| 245 | 245 | | expected 2 lifetime arguments |
| 246 | 246 | | |
| ... | ... | @@ -250,30 +250,24 @@ note: function defined here, with 2 lifetime parameters: `'a`, `'b` |
| 250 | 250 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} |
| 251 | 251 | | ^^^ -- -- |
| 252 | 252 | |
| 253 | error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied | |
| 254 | --> $DIR/generics-gen-args-errors.rs:55:11 | |
| 253 | error[E0107]: function takes 3 generic arguments but 1 generic argument was supplied | |
| 254 | --> $DIR/generics-gen-args-errors.rs:53:11 | |
| 255 | 255 | | |
| 256 | 256 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; |
| 257 | | ^^^ expected 3 generic arguments ------- - supplied 2 generic arguments | |
| 257 | | ^^^ expected 3 generic arguments - supplied 1 generic argument | |
| 258 | 258 | | |
| 259 | 259 | note: function defined here, with 3 generic parameters: `T`, `U`, `N` |
| 260 | 260 | --> $DIR/generics-gen-args-errors.rs:44:8 |
| 261 | 261 | | |
| 262 | 262 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} |
| 263 | 263 | | ^^^ - - -------------- |
| 264 | help: add missing generic argument | |
| 264 | help: add missing generic arguments | |
| 265 | 265 | | |
| 266 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, N> as bar3; | |
| 267 | | +++ | |
| 268 | ||
| 269 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 270 | --> $DIR/generics-gen-args-errors.rs:55:11 | |
| 271 | | | |
| 272 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | |
| 273 | | ^^^ | |
| 266 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, U, N> as bar3; | |
| 267 | | ++++++ | |
| 274 | 268 | |
| 275 | 269 | error[E0107]: function takes 2 lifetime arguments but 1 lifetime argument was supplied |
| 276 | --> $DIR/generics-gen-args-errors.rs:61:11 | |
| 270 | --> $DIR/generics-gen-args-errors.rs:59:11 | |
| 277 | 271 | | |
| 278 | 272 | LL | reuse foo::<String, 'static, 123, asdasd> as bar4; |
| 279 | 273 | | ^^^ ------ supplied 1 lifetime argument |
| ... | ... | @@ -291,13 +285,13 @@ LL | reuse foo::<String, 'static, 'static, 123, asdasd> as bar4; |
| 291 | 285 | | +++++++++ |
| 292 | 286 | |
| 293 | 287 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 294 | --> $DIR/generics-gen-args-errors.rs:61:11 | |
| 288 | --> $DIR/generics-gen-args-errors.rs:59:11 | |
| 295 | 289 | | |
| 296 | 290 | LL | reuse foo::<String, 'static, 123, asdasd> as bar4; |
| 297 | 291 | | ^^^ |
| 298 | 292 | |
| 299 | 293 | error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied |
| 300 | --> $DIR/generics-gen-args-errors.rs:66:11 | |
| 294 | --> $DIR/generics-gen-args-errors.rs:64:11 | |
| 301 | 295 | | |
| 302 | 296 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; |
| 303 | 297 | | ^^^ expected 2 lifetime arguments |
| ... | ... | @@ -313,10 +307,10 @@ LL | reuse foo::<'a, 'b, 1, 2, _, 4, 5, _> as bar5; |
| 313 | 307 | | +++++++ |
| 314 | 308 | |
| 315 | 309 | error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied |
| 316 | --> $DIR/generics-gen-args-errors.rs:66:11 | |
| 310 | --> $DIR/generics-gen-args-errors.rs:64:11 | |
| 317 | 311 | | |
| 318 | 312 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; |
| 319 | | ^^^ --------- help: remove the unnecessary generic arguments | |
| 313 | | ^^^------------------- help: remove the unnecessary generic arguments | |
| 320 | 314 | | | |
| 321 | 315 | | expected 3 generic arguments |
| 322 | 316 | | |
| ... | ... | @@ -327,13 +321,13 @@ LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} |
| 327 | 321 | | ^^^ - - -------------- |
| 328 | 322 | |
| 329 | 323 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 330 | --> $DIR/generics-gen-args-errors.rs:66:11 | |
| 324 | --> $DIR/generics-gen-args-errors.rs:64:11 | |
| 331 | 325 | | |
| 332 | 326 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; |
| 333 | 327 | | ^^^ |
| 334 | 328 | |
| 335 | 329 | error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied |
| 336 | --> $DIR/generics-gen-args-errors.rs:71:11 | |
| 330 | --> $DIR/generics-gen-args-errors.rs:69:11 | |
| 337 | 331 | | |
| 338 | 332 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; |
| 339 | 333 | | ^^^ expected 2 lifetime arguments |
| ... | ... | @@ -349,7 +343,7 @@ LL | reuse foo::<'a, 'b, 1, 2,asd,String, { let x = 0; }> as bar6; |
| 349 | 343 | | +++++++ |
| 350 | 344 | |
| 351 | 345 | error[E0107]: function takes 3 generic arguments but 5 generic arguments were supplied |
| 352 | --> $DIR/generics-gen-args-errors.rs:71:11 | |
| 346 | --> $DIR/generics-gen-args-errors.rs:69:11 | |
| 353 | 347 | | |
| 354 | 348 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; |
| 355 | 349 | | ^^^ ----------------------- help: remove the unnecessary generic arguments |
| ... | ... | @@ -363,25 +357,25 @@ LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} |
| 363 | 357 | | ^^^ - - -------------- |
| 364 | 358 | |
| 365 | 359 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 366 | --> $DIR/generics-gen-args-errors.rs:71:11 | |
| 360 | --> $DIR/generics-gen-args-errors.rs:69:11 | |
| 367 | 361 | | |
| 368 | 362 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; |
| 369 | 363 | | ^^^ |
| 370 | 364 | |
| 371 | 365 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 372 | --> $DIR/generics-gen-args-errors.rs:77:11 | |
| 366 | --> $DIR/generics-gen-args-errors.rs:75:11 | |
| 373 | 367 | | |
| 374 | 368 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; |
| 375 | 369 | | ^^^ |
| 376 | 370 | |
| 377 | 371 | error[E0747]: constant provided when a type was expected |
| 378 | --> $DIR/generics-gen-args-errors.rs:77:17 | |
| 372 | --> $DIR/generics-gen-args-errors.rs:75:17 | |
| 379 | 373 | | |
| 380 | 374 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; |
| 381 | 375 | | ^^^^^^^^ |
| 382 | 376 | |
| 383 | 377 | error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied |
| 384 | --> $DIR/generics-gen-args-errors.rs:83:11 | |
| 378 | --> $DIR/generics-gen-args-errors.rs:81:11 | |
| 385 | 379 | | |
| 386 | 380 | LL | reuse foo::<{}, {}, {}> as bar8; |
| 387 | 381 | | ^^^ expected 2 lifetime arguments |
| ... | ... | @@ -397,19 +391,19 @@ LL | reuse foo::<'a, 'b, {}, {}, {}> as bar8; |
| 397 | 391 | | +++++++ |
| 398 | 392 | |
| 399 | 393 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 400 | --> $DIR/generics-gen-args-errors.rs:83:11 | |
| 394 | --> $DIR/generics-gen-args-errors.rs:81:11 | |
| 401 | 395 | | |
| 402 | 396 | LL | reuse foo::<{}, {}, {}> as bar8; |
| 403 | 397 | | ^^^ |
| 404 | 398 | |
| 405 | 399 | error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied |
| 406 | --> $DIR/generics-gen-args-errors.rs:94:11 | |
| 400 | --> $DIR/generics-gen-args-errors.rs:92:11 | |
| 407 | 401 | | |
| 408 | 402 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 409 | 403 | | ^^^^^ expected 3 lifetime arguments |
| 410 | 404 | | |
| 411 | 405 | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` |
| 412 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 406 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 413 | 407 | | |
| 414 | 408 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 415 | 409 | | ^^^^^ -- -- -- |
| ... | ... | @@ -419,7 +413,7 @@ LL | reuse Trait::<'b, 'c, 'a, asd, asd, asd, asd, asd, asdasa>::foo as bar1 |
| 419 | 413 | | +++++++++++ |
| 420 | 414 | |
| 421 | 415 | error[E0107]: trait takes 2 generic arguments but 6 generic arguments were supplied |
| 422 | --> $DIR/generics-gen-args-errors.rs:94:11 | |
| 416 | --> $DIR/generics-gen-args-errors.rs:92:11 | |
| 423 | 417 | | |
| 424 | 418 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 425 | 419 | | ^^^^^ ----------------------- help: remove the unnecessary generic arguments |
| ... | ... | @@ -427,19 +421,19 @@ LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 427 | 421 | | expected 2 generic arguments |
| 428 | 422 | | |
| 429 | 423 | note: trait defined here, with 2 generic parameters: `T`, `N` |
| 430 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 424 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 431 | 425 | | |
| 432 | 426 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 433 | 427 | | ^^^^^ - -------------- |
| 434 | 428 | |
| 435 | 429 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 436 | --> $DIR/generics-gen-args-errors.rs:94:11 | |
| 430 | --> $DIR/generics-gen-args-errors.rs:92:11 | |
| 437 | 431 | | |
| 438 | 432 | LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1; |
| 439 | 433 | | ^^^^^ |
| 440 | 434 | |
| 441 | 435 | error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied |
| 442 | --> $DIR/generics-gen-args-errors.rs:105:11 | |
| 436 | --> $DIR/generics-gen-args-errors.rs:103:11 | |
| 443 | 437 | | |
| 444 | 438 | LL | reuse Trait::<'static, 'static>::foo as bar2; |
| 445 | 439 | | ^^^^^ ------- ------- supplied 2 lifetime arguments |
| ... | ... | @@ -447,7 +441,7 @@ LL | reuse Trait::<'static, 'static>::foo as bar2; |
| 447 | 441 | | expected 3 lifetime arguments |
| 448 | 442 | | |
| 449 | 443 | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` |
| 450 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 444 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 451 | 445 | | |
| 452 | 446 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 453 | 447 | | ^^^^^ -- -- -- |
| ... | ... | @@ -457,25 +451,25 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar2; |
| 457 | 451 | | +++++++++ |
| 458 | 452 | |
| 459 | 453 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 460 | --> $DIR/generics-gen-args-errors.rs:105:11 | |
| 454 | --> $DIR/generics-gen-args-errors.rs:103:11 | |
| 461 | 455 | | |
| 462 | 456 | LL | reuse Trait::<'static, 'static>::foo as bar2; |
| 463 | 457 | | ^^^^^ |
| 464 | 458 | |
| 465 | 459 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions |
| 466 | --> $DIR/generics-gen-args-errors.rs:105:11 | |
| 460 | --> $DIR/generics-gen-args-errors.rs:103:11 | |
| 467 | 461 | | |
| 468 | 462 | LL | reuse Trait::<'static, 'static>::foo as bar2; |
| 469 | 463 | | ^^^^^ not allowed in type signatures |
| 470 | 464 | |
| 471 | 465 | error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied |
| 472 | --> $DIR/generics-gen-args-errors.rs:109:11 | |
| 466 | --> $DIR/generics-gen-args-errors.rs:107:11 | |
| 473 | 467 | | |
| 474 | 468 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; |
| 475 | 469 | | ^^^^^ expected 3 lifetime arguments |
| 476 | 470 | | |
| 477 | 471 | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` |
| 478 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 472 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 479 | 473 | | |
| 480 | 474 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 481 | 475 | | ^^^^^ -- -- -- |
| ... | ... | @@ -485,7 +479,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, 3, 4, 5>::foo as bar3; |
| 485 | 479 | | +++++++++++ |
| 486 | 480 | |
| 487 | 481 | error[E0107]: trait takes 2 generic arguments but 5 generic arguments were supplied |
| 488 | --> $DIR/generics-gen-args-errors.rs:109:11 | |
| 482 | --> $DIR/generics-gen-args-errors.rs:107:11 | |
| 489 | 483 | | |
| 490 | 484 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; |
| 491 | 485 | | ^^^^^ --------- help: remove the unnecessary generic arguments |
| ... | ... | @@ -493,25 +487,25 @@ LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; |
| 493 | 487 | | expected 2 generic arguments |
| 494 | 488 | | |
| 495 | 489 | note: trait defined here, with 2 generic parameters: `T`, `N` |
| 496 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 490 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 497 | 491 | | |
| 498 | 492 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 499 | 493 | | ^^^^^ - -------------- |
| 500 | 494 | |
| 501 | 495 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 502 | --> $DIR/generics-gen-args-errors.rs:109:11 | |
| 496 | --> $DIR/generics-gen-args-errors.rs:107:11 | |
| 503 | 497 | | |
| 504 | 498 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; |
| 505 | 499 | | ^^^^^ |
| 506 | 500 | |
| 507 | 501 | error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied |
| 508 | --> $DIR/generics-gen-args-errors.rs:114:11 | |
| 502 | --> $DIR/generics-gen-args-errors.rs:112:11 | |
| 509 | 503 | | |
| 510 | 504 | LL | reuse Trait::<1, 2, true>::foo as bar4; |
| 511 | 505 | | ^^^^^ expected 3 lifetime arguments |
| 512 | 506 | | |
| 513 | 507 | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` |
| 514 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 508 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 515 | 509 | | |
| 516 | 510 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 517 | 511 | | ^^^^^ -- -- -- |
| ... | ... | @@ -521,7 +515,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, true>::foo as bar4; |
| 521 | 515 | | +++++++++++ |
| 522 | 516 | |
| 523 | 517 | error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied |
| 524 | --> $DIR/generics-gen-args-errors.rs:114:11 | |
| 518 | --> $DIR/generics-gen-args-errors.rs:112:11 | |
| 525 | 519 | | |
| 526 | 520 | LL | reuse Trait::<1, 2, true>::foo as bar4; |
| 527 | 521 | | ^^^^^ ------ help: remove the unnecessary generic argument |
| ... | ... | @@ -529,19 +523,19 @@ LL | reuse Trait::<1, 2, true>::foo as bar4; |
| 529 | 523 | | expected 2 generic arguments |
| 530 | 524 | | |
| 531 | 525 | note: trait defined here, with 2 generic parameters: `T`, `N` |
| 532 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 526 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 533 | 527 | | |
| 534 | 528 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 535 | 529 | | ^^^^^ - -------------- |
| 536 | 530 | |
| 537 | 531 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 538 | --> $DIR/generics-gen-args-errors.rs:114:11 | |
| 532 | --> $DIR/generics-gen-args-errors.rs:112:11 | |
| 539 | 533 | | |
| 540 | 534 | LL | reuse Trait::<1, 2, true>::foo as bar4; |
| 541 | 535 | | ^^^^^ |
| 542 | 536 | |
| 543 | 537 | error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied |
| 544 | --> $DIR/generics-gen-args-errors.rs:119:11 | |
| 538 | --> $DIR/generics-gen-args-errors.rs:117:11 | |
| 545 | 539 | | |
| 546 | 540 | LL | reuse Trait::<'static>::foo as bar5; |
| 547 | 541 | | ^^^^^ ------- supplied 1 lifetime argument |
| ... | ... | @@ -549,7 +543,7 @@ LL | reuse Trait::<'static>::foo as bar5; |
| 549 | 543 | | expected 3 lifetime arguments |
| 550 | 544 | | |
| 551 | 545 | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` |
| 552 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 546 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 553 | 547 | | |
| 554 | 548 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 555 | 549 | | ^^^^^ -- -- -- |
| ... | ... | @@ -559,19 +553,19 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar5; |
| 559 | 553 | | ++++++++++++++++++ |
| 560 | 554 | |
| 561 | 555 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 562 | --> $DIR/generics-gen-args-errors.rs:119:11 | |
| 556 | --> $DIR/generics-gen-args-errors.rs:117:11 | |
| 563 | 557 | | |
| 564 | 558 | LL | reuse Trait::<'static>::foo as bar5; |
| 565 | 559 | | ^^^^^ |
| 566 | 560 | |
| 567 | 561 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions |
| 568 | --> $DIR/generics-gen-args-errors.rs:119:11 | |
| 562 | --> $DIR/generics-gen-args-errors.rs:117:11 | |
| 569 | 563 | | |
| 570 | 564 | LL | reuse Trait::<'static>::foo as bar5; |
| 571 | 565 | | ^^^^^ not allowed in type signatures |
| 572 | 566 | |
| 573 | 567 | error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied |
| 574 | --> $DIR/generics-gen-args-errors.rs:124:11 | |
| 568 | --> $DIR/generics-gen-args-errors.rs:122:11 | |
| 575 | 569 | | |
| 576 | 570 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 577 | 571 | | ^^^^^ - supplied 1 lifetime argument |
| ... | ... | @@ -579,7 +573,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 579 | 573 | | expected 3 lifetime arguments |
| 580 | 574 | | |
| 581 | 575 | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` |
| 582 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 576 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 583 | 577 | | |
| 584 | 578 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 585 | 579 | | ^^^^^ -- -- -- |
| ... | ... | @@ -589,7 +583,7 @@ LL | reuse Trait::<1, 'static, 'static, 2, 'static, DDDD>::foo::<1, 2, 3, 4, |
| 589 | 583 | | ++++++++++++++++++ |
| 590 | 584 | |
| 591 | 585 | error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied |
| 592 | --> $DIR/generics-gen-args-errors.rs:124:11 | |
| 586 | --> $DIR/generics-gen-args-errors.rs:122:11 | |
| 593 | 587 | | |
| 594 | 588 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 595 | 589 | | ^^^^^ --------------- help: remove the unnecessary generic argument |
| ... | ... | @@ -597,25 +591,25 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 597 | 591 | | expected 2 generic arguments |
| 598 | 592 | | |
| 599 | 593 | note: trait defined here, with 2 generic parameters: `T`, `N` |
| 600 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 594 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 601 | 595 | | |
| 602 | 596 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 603 | 597 | | ^^^^^ - -------------- |
| 604 | 598 | |
| 605 | 599 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 606 | --> $DIR/generics-gen-args-errors.rs:124:11 | |
| 600 | --> $DIR/generics-gen-args-errors.rs:122:11 | |
| 607 | 601 | | |
| 608 | 602 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 609 | 603 | | ^^^^^ |
| 610 | 604 | |
| 611 | 605 | error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied |
| 612 | --> $DIR/generics-gen-args-errors.rs:124:41 | |
| 606 | --> $DIR/generics-gen-args-errors.rs:122:41 | |
| 613 | 607 | | |
| 614 | 608 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 615 | 609 | | ^^^ expected 1 lifetime argument |
| 616 | 610 | | |
| 617 | 611 | note: method defined here, with 1 lifetime parameter: `'d` |
| 618 | --> $DIR/generics-gen-args-errors.rs:91:12 | |
| 612 | --> $DIR/generics-gen-args-errors.rs:89:12 | |
| 619 | 613 | | |
| 620 | 614 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} |
| 621 | 615 | | ^^^ -- |
| ... | ... | @@ -625,7 +619,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<'d, 1, 2, 3, 4, 5, 6> as bar6 |
| 625 | 619 | | +++ |
| 626 | 620 | |
| 627 | 621 | error[E0107]: method takes 2 generic arguments but 6 generic arguments were supplied |
| 628 | --> $DIR/generics-gen-args-errors.rs:124:41 | |
| 622 | --> $DIR/generics-gen-args-errors.rs:122:41 | |
| 629 | 623 | | |
| 630 | 624 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 631 | 625 | | ^^^ ------------ help: remove the unnecessary generic arguments |
| ... | ... | @@ -633,73 +627,73 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 633 | 627 | | expected 2 generic arguments |
| 634 | 628 | | |
| 635 | 629 | note: method defined here, with 2 generic parameters: `U`, `M` |
| 636 | --> $DIR/generics-gen-args-errors.rs:91:12 | |
| 630 | --> $DIR/generics-gen-args-errors.rs:89:12 | |
| 637 | 631 | | |
| 638 | 632 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} |
| 639 | 633 | | ^^^ - ------------- |
| 640 | 634 | |
| 641 | 635 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 642 | --> $DIR/generics-gen-args-errors.rs:124:41 | |
| 636 | --> $DIR/generics-gen-args-errors.rs:122:41 | |
| 643 | 637 | | |
| 644 | 638 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; |
| 645 | 639 | | ^^^ |
| 646 | 640 | |
| 647 | error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied | |
| 648 | --> $DIR/generics-gen-args-errors.rs:133:11 | |
| 641 | error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied | |
| 642 | --> $DIR/generics-gen-args-errors.rs:131:11 | |
| 649 | 643 | | |
| 650 | 644 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; |
| 651 | | ^^^^^ ----- supplied 1 lifetime argument | |
| 645 | | ^^^^^ ----- ----- supplied 2 lifetime arguments | |
| 652 | 646 | | | |
| 653 | 647 | | expected 3 lifetime arguments |
| 654 | 648 | | |
| 655 | 649 | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` |
| 656 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 650 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 657 | 651 | | |
| 658 | 652 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 659 | 653 | | ^^^^^ -- -- -- |
| 660 | help: add missing lifetime arguments | |
| 654 | help: add missing lifetime argument | |
| 661 | 655 | | |
| 662 | LL | reuse Trait::<Trait, 'static, 'static, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; | |
| 663 | | ++++++++++++++++++ | |
| 656 | LL | reuse Trait::<Trait, Clone, 'a, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; | |
| 657 | | ++++ | |
| 664 | 658 | |
| 665 | error[E0107]: trait takes 2 generic arguments but 5 generic arguments were supplied | |
| 666 | --> $DIR/generics-gen-args-errors.rs:133:11 | |
| 659 | error[E0107]: trait takes 2 generic arguments but 4 generic arguments were supplied | |
| 660 | --> $DIR/generics-gen-args-errors.rs:131:11 | |
| 667 | 661 | | |
| 668 | 662 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; |
| 669 | | ^^^^^ --- help: remove the unnecessary generic argument | |
| 663 | | ^^^^^ ------------------------- help: remove the unnecessary generic arguments | |
| 670 | 664 | | | |
| 671 | 665 | | expected 2 generic arguments |
| 672 | 666 | | |
| 673 | 667 | note: trait defined here, with 2 generic parameters: `T`, `N` |
| 674 | --> $DIR/generics-gen-args-errors.rs:90:11 | |
| 668 | --> $DIR/generics-gen-args-errors.rs:88:11 | |
| 675 | 669 | | |
| 676 | 670 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { |
| 677 | 671 | | ^^^^^ - -------------- |
| 678 | 672 | |
| 679 | 673 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 680 | --> $DIR/generics-gen-args-errors.rs:133:11 | |
| 674 | --> $DIR/generics-gen-args-errors.rs:131:11 | |
| 681 | 675 | | |
| 682 | 676 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; |
| 683 | 677 | | ^^^^^ |
| 684 | 678 | |
| 685 | 679 | error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied |
| 686 | --> $DIR/generics-gen-args-errors.rs:133:59 | |
| 680 | --> $DIR/generics-gen-args-errors.rs:131:59 | |
| 687 | 681 | | |
| 688 | 682 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; |
| 689 | 683 | | ^^^ expected 1 lifetime argument |
| 690 | 684 | | |
| 691 | 685 | note: method defined here, with 1 lifetime parameter: `'d` |
| 692 | --> $DIR/generics-gen-args-errors.rs:91:12 | |
| 686 | --> $DIR/generics-gen-args-errors.rs:89:12 | |
| 693 | 687 | | |
| 694 | 688 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} |
| 695 | 689 | | ^^^ -- |
| 696 | 690 | help: add missing lifetime argument |
| 697 | 691 | | |
| 698 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<'d, 1, 2, 3, _, 6> as bar7; | |
| 692 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<'a, 1, 2, 3, _, 6> as bar7; | |
| 699 | 693 | | +++ |
| 700 | 694 | |
| 701 | 695 | error[E0107]: method takes 2 generic arguments but 5 generic arguments were supplied |
| 702 | --> $DIR/generics-gen-args-errors.rs:133:59 | |
| 696 | --> $DIR/generics-gen-args-errors.rs:131:59 | |
| 703 | 697 | | |
| 704 | 698 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; |
| 705 | 699 | | ^^^ --------- help: remove the unnecessary generic arguments |
| ... | ... | @@ -707,13 +701,13 @@ LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, |
| 707 | 701 | | expected 2 generic arguments |
| 708 | 702 | | |
| 709 | 703 | note: method defined here, with 2 generic parameters: `U`, `M` |
| 710 | --> $DIR/generics-gen-args-errors.rs:91:12 | |
| 704 | --> $DIR/generics-gen-args-errors.rs:89:12 | |
| 711 | 705 | | |
| 712 | 706 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} |
| 713 | 707 | | ^^^ - ------------- |
| 714 | 708 | |
| 715 | 709 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature |
| 716 | --> $DIR/generics-gen-args-errors.rs:133:59 | |
| 710 | --> $DIR/generics-gen-args-errors.rs:131:59 | |
| 717 | 711 | | |
| 718 | 712 | LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7; |
| 719 | 713 | | ^^^ |
| ... | ... | @@ -789,12 +783,12 @@ LL | reuse foo::<A, B, { C }> as xd; |
| 789 | 783 | | + + |
| 790 | 784 | |
| 791 | 785 | error[E0747]: constant provided when a type was expected |
| 792 | --> $DIR/generics-gen-args-errors.rs:83:17 | |
| 786 | --> $DIR/generics-gen-args-errors.rs:81:17 | |
| 793 | 787 | | |
| 794 | 788 | LL | reuse foo::<{}, {}, {}> as bar8; |
| 795 | 789 | | ^^ |
| 796 | 790 | |
| 797 | error: aborting due to 75 previous errors | |
| 791 | error: aborting due to 74 previous errors | |
| 798 | 792 | |
| 799 | 793 | Some errors have detailed explanations: E0107, E0121, E0261, E0401, E0423, E0425, E0747. |
| 800 | 794 | For more information about an error, try `rustc --explain E0107`. |
tests/ui/delegation/generics/infers.rs created+356| ... | ... | @@ -0,0 +1,356 @@ |
| 1 | //@ compile-flags: -Z deduplicate-diagnostics=yes | |
| 2 | ||
| 3 | #![feature(fn_delegation)] | |
| 4 | ||
| 5 | // Some interesting cases: | |
| 6 | mod selected_tests { | |
| 7 | mod different_infers { | |
| 8 | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 9 | ||
| 10 | // Should differentiate between lifetime and types/consts infers. | |
| 11 | reuse foo::<_, '_, '_, '_> as bar; | |
| 12 | //~^ ERROR: wrong infer used: expected '_, found: _ | |
| 13 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 14 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 15 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 16 | } | |
| 17 | ||
| 18 | mod self_type { | |
| 19 | trait Trait<'a, X> { | |
| 20 | fn method<'b: 'b, const M: usize>(&self) {} | |
| 21 | fn r#static<'b, Y, const B: bool>() {} | |
| 22 | } | |
| 23 | ||
| 24 | impl<'a, X> Trait<'a, X> for () {} | |
| 25 | ||
| 26 | reuse Trait::<'_, _>::method::<'_, _> as foo; | |
| 27 | ||
| 28 | reuse <_ as Trait<'_, _>>::method::<'_, _> as foo1; | |
| 29 | reuse <() as Trait<'_, _>>::method::<'_, _> as foo2; | |
| 30 | ||
| 31 | reuse <_ as Trait<'_, _>>::r#static::<_, _> as foo3; | |
| 32 | reuse <() as Trait<'_, _>>::r#static::<_, _> as foo4; | |
| 33 | ||
| 34 | reuse Trait::<'_, _>::r#static::<_, _> as foo5; | |
| 35 | } | |
| 36 | ||
| 37 | mod late_bound_lifetimes { | |
| 38 | fn foo<'a, 'b, 'c: 'c, 'd>(_: &'a &'b &'c &'d ()) {} | |
| 39 | ||
| 40 | // 'c corresponds to infer. | |
| 41 | reuse foo::<'_> as foo1; | |
| 42 | ||
| 43 | // Only 'c is generated in desugaring, second infer remains just infer in call path. | |
| 44 | reuse foo::<'_, '_> as foo2; | |
| 45 | //~^ ERROR: function takes 1 lifetime argument but 2 lifetime arguments were supplied | |
| 46 | ||
| 47 | reuse foo as foo3; | |
| 48 | reuse foo::<'static> as foo4; | |
| 49 | } | |
| 50 | ||
| 51 | mod non_angle_bracketed_args { | |
| 52 | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 53 | ||
| 54 | reuse foo::('_, _, _, _) as bar; | |
| 55 | //~^ ERROR: lifetimes must be followed by `+` to form a trait object type | |
| 56 | //~| ERROR: at least one trait is required for an object type | |
| 57 | //~| ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214] | |
| 58 | //~| ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] | |
| 59 | //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 60 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 61 | //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 62 | } | |
| 63 | } | |
| 64 | ||
| 65 | // All other stuff: | |
| 66 | mod legacy_tests { | |
| 67 | trait Trait<T> { | |
| 68 | fn foo<U>(&self, _: U, _: T) {} | |
| 69 | } | |
| 70 | ||
| 71 | impl<T> Trait<T> for u8 {} | |
| 72 | ||
| 73 | reuse Trait::<_>::foo::<i32> as generic_arguments1; | |
| 74 | reuse <u8 as Trait<_>>::foo as generic_arguments2; | |
| 75 | reuse <_ as Trait<_>>::foo as generic_arguments3; | |
| 76 | } | |
| 77 | ||
| 78 | mod free_to_free { | |
| 79 | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 80 | ||
| 81 | reuse foo::<> as foo1; | |
| 82 | reuse foo::<'_, _, _, _> as foo2; | |
| 83 | reuse foo::<'static, String, _, _> as foo3; | |
| 84 | reuse foo::<'_, _, 123, _> as foo4; | |
| 85 | ||
| 86 | reuse foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 87 | //~^ ERROR: function takes 3 generic arguments but 5 generic arguments were supplied | |
| 88 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 89 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 90 | ||
| 91 | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 92 | //~^ ERROR: function takes 3 generic arguments but 6 generic arguments were supplied [E0107] | |
| 93 | //~| ERROR: function takes 1 lifetime argument but 3 lifetime arguments were supplied | |
| 94 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 95 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 96 | ||
| 97 | reuse foo::<_, '_, _, _> as foo7; | |
| 98 | //~^ ERROR: wrong infer used: expected '_, found: _ | |
| 99 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 100 | ||
| 101 | reuse foo::<'_, '_, '_, '_> as foo8; | |
| 102 | //~^ ERROR: wrong infer used: expected _, found: '_ | |
| 103 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 104 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 105 | ||
| 106 | reuse foo::<_> as foo9; | |
| 107 | //~^ ERROR: function takes 3 generic arguments but 0 generic arguments were supplied | |
| 108 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 109 | ||
| 110 | reuse foo::<Vec<'_>, _, _, ()> as foo10; | |
| 111 | //~^ ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] | |
| 112 | //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 113 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 114 | //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] | |
| 115 | //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] | |
| 116 | ||
| 117 | reuse foo::<Vec<_>, _, _, ()> as foo11; | |
| 118 | //~^ ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] | |
| 119 | //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 120 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 121 | //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 122 | ||
| 123 | reuse foo::<'____, ___, _, ___> as foo12; | |
| 124 | //~^ ERROR: use of undeclared lifetime name `'____` [E0261] | |
| 125 | //~| ERROR: cannot find type `___` in this scope [E0425] | |
| 126 | //~| ERROR: cannot find type `___` in this scope [E0425] | |
| 127 | ||
| 128 | reuse foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13; | |
| 129 | //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 130 | //~| ERROR: type provided when a constant was expected [E0747] | |
| 131 | ||
| 132 | reuse foo::<'_, unresolved_, _, _> as foo14; | |
| 133 | //~^ ERROR: cannot find type `unresolved_` in this scope | |
| 134 | ||
| 135 | reuse foo::<_, _, _> as foo15; | |
| 136 | //~^ ERROR: function takes 3 generic arguments but 2 generic arguments were supplied | |
| 137 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 138 | } | |
| 139 | ||
| 140 | mod free_to_trait { | |
| 141 | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 142 | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 143 | } | |
| 144 | ||
| 145 | struct X; | |
| 146 | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} | |
| 147 | //~^ ERROR: the type parameter `Some` is not constrained by the impl trait, self type, or predicates [E0207] | |
| 148 | //~| ERROR: the type parameter `Params` is not constrained by the impl trait, self type, or predicates [E0207] | |
| 149 | ||
| 150 | mod child_only { | |
| 151 | use super::*; | |
| 152 | ||
| 153 | reuse Trait::foo::<> as foo1; | |
| 154 | reuse Trait::foo::<'_, _, _, _> as foo2; | |
| 155 | reuse Trait::foo::<'static, String, _, _> as foo3; | |
| 156 | reuse Trait::foo::<'_, _, 123, _> as foo4; | |
| 157 | ||
| 158 | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 159 | //~^ ERROR: method takes 3 generic arguments but 5 generic arguments were supplied | |
| 160 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 161 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 162 | ||
| 163 | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 164 | //~^ ERROR: method takes 3 generic arguments but 6 generic arguments were supplied [E0107] | |
| 165 | //~| ERROR: method takes 1 lifetime argument but 3 lifetime arguments were supplied | |
| 166 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 167 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 168 | ||
| 169 | reuse Trait::foo::<_, '_, _, _> as foo7; | |
| 170 | //~^ ERROR: wrong infer used: expected '_, found: _ | |
| 171 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 172 | ||
| 173 | reuse Trait::foo::<'_, '_, '_, '_> as foo8; | |
| 174 | //~^ ERROR: wrong infer used: expected _, found: '_ | |
| 175 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 176 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 177 | ||
| 178 | reuse Trait::foo::<_> as foo9; | |
| 179 | //~^ ERROR: method takes 3 generic arguments but 0 generic arguments were supplied | |
| 180 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 181 | ||
| 182 | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 183 | //~^ ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 184 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 185 | //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] | |
| 186 | //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] | |
| 187 | //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied | |
| 188 | ||
| 189 | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11; | |
| 190 | //~^ ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] | |
| 191 | //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 192 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 193 | //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 194 | ||
| 195 | reuse Trait::foo::<'____, ___, _, ___> as foo12; | |
| 196 | //~^ ERROR: use of undeclared lifetime name `'____` [E0261] | |
| 197 | //~| ERROR: cannot find type `___` in this scope [E0425] | |
| 198 | //~| ERROR: cannot find type `___` in this scope [E0425] | |
| 199 | ||
| 200 | reuse Trait::foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13; | |
| 201 | //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 202 | //~| ERROR: type provided when a constant was expected [E0747] | |
| 203 | ||
| 204 | reuse Trait::foo::<'_, unresolved_, _, _> as foo14; | |
| 205 | //~^ ERROR: cannot find type `unresolved_` in this scope | |
| 206 | ||
| 207 | reuse Trait::foo::<_, _, _> as foo15; | |
| 208 | //~^ ERROR: method takes 3 generic arguments but 2 generic arguments were supplied | |
| 209 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 210 | } | |
| 211 | ||
| 212 | mod parent_only { | |
| 213 | use super::*; | |
| 214 | ||
| 215 | reuse Trait::<'_, 'static, _, _, _>::foo as foo1; | |
| 216 | reuse Trait::<'_, '_, _, _, _>::foo as foo2; | |
| 217 | ||
| 218 | reuse Trait::<'_, (), _, '_, _>::foo as foo3; | |
| 219 | //~^ ERROR: trait takes 2 lifetime arguments but 1 lifetime argument was supplied [E0107] | |
| 220 | //~| ERROR: trait takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 221 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 222 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 223 | ||
| 224 | reuse Trait::<>::foo as foo4; | |
| 225 | ||
| 226 | reuse Trait::<_, _>::foo as foo5; | |
| 227 | //~^ ERROR: trait takes 3 generic arguments but 0 generic arguments were supplied | |
| 228 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 229 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 230 | ||
| 231 | reuse Trait::<'_, '_>::foo as foo6; | |
| 232 | //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions | |
| 233 | ||
| 234 | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo as foo7; | |
| 235 | //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 236 | //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 237 | ||
| 238 | reuse Trait::<'static, 'static, (), 123, ()>::foo as foo8; | |
| 239 | reuse Trait::<'static, 'static, _, _, _>::foo as foo9; | |
| 240 | ||
| 241 | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo as foo10; | |
| 242 | //~^ ERROR: trait takes 3 generic arguments but 7 generic arguments were supplied | |
| 243 | ||
| 244 | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; | |
| 245 | //~^ ERROR: trait takes 2 lifetime arguments but 6 lifetime arguments were supplied | |
| 246 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 247 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 248 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 249 | ||
| 250 | reuse Trait::<'static, 'static, _>::foo as foo12; | |
| 251 | //~^ ERROR: trait takes 3 generic arguments but 1 generic argument was supplied | |
| 252 | } | |
| 253 | ||
| 254 | mod parent_and_child_random { | |
| 255 | use super::*; | |
| 256 | ||
| 257 | reuse Trait::<'_, 'static, _, _, _>::foo::<> as foo1; | |
| 258 | reuse Trait::<'_, '_, _, _, _>::foo::<'_, _, _, _> as foo2; | |
| 259 | ||
| 260 | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; | |
| 261 | //~^ ERROR: trait takes 2 lifetime arguments but 1 lifetime argument was supplied [E0107] | |
| 262 | //~| ERROR: trait takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 263 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 264 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 265 | ||
| 266 | reuse Trait::<>::foo::<'_, _, 123, _> as foo4; | |
| 267 | ||
| 268 | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 269 | //~^ ERROR: trait takes 3 generic arguments but 0 generic arguments were supplied | |
| 270 | //~| ERROR: method takes 3 generic arguments but 5 generic arguments were supplied | |
| 271 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 272 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 273 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 274 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 275 | ||
| 276 | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 277 | //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 278 | //~| ERROR: method takes 3 generic arguments but 6 generic arguments were supplied [E0107] | |
| 279 | //~| ERROR: method takes 1 lifetime argument but 3 lifetime arguments were supplied | |
| 280 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 281 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 282 | ||
| 283 | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7; | |
| 284 | //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 285 | //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 286 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 287 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 288 | ||
| 289 | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; | |
| 290 | //~^ ERROR: wrong infer used: expected _, found: '_ | |
| 291 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 292 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 293 | ||
| 294 | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; | |
| 295 | //~^ ERROR: method takes 3 generic arguments but 0 generic arguments were supplied | |
| 296 | //~| ERROR: wrong infer used: expected '_, found: _ | |
| 297 | ||
| 298 | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 299 | //~^ ERROR: trait takes 3 generic arguments but 7 generic arguments were supplied [E0107] | |
| 300 | //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] | |
| 301 | //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 302 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 303 | //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] | |
| 304 | //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] | |
| 305 | ||
| 306 | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 307 | //~^ ERROR: trait takes 2 lifetime arguments but 5 lifetime arguments were supplied [E0107] | |
| 308 | //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] | |
| 309 | //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] | |
| 310 | //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 311 | //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] | |
| 312 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 313 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 314 | //~| ERROR: wrong infer used: expected _, found: '_ | |
| 315 | ||
| 316 | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; | |
| 317 | //~^ ERROR: cannot find type `___` in this scope | |
| 318 | //~| ERROR: cannot find type `___` in this scope | |
| 319 | //~| ERROR: use of undeclared lifetime name `'____` | |
| 320 | //~| ERROR: trait takes 3 generic arguments but 1 generic argument was supplied | |
| 321 | } | |
| 322 | } | |
| 323 | ||
| 324 | mod trait_impl_to_free { | |
| 325 | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 326 | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self) {} | |
| 327 | } | |
| 328 | ||
| 329 | struct S; | |
| 330 | impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for S {} | |
| 331 | ||
| 332 | mod to_reuse { | |
| 333 | pub fn foo<X, const M: usize, Y>(_: ()) {} | |
| 334 | } | |
| 335 | ||
| 336 | struct F1(S); | |
| 337 | impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F1 { | |
| 338 | reuse to_reuse::foo::<_, _, _> { self.0 } | |
| 339 | //~^ ERROR: mismatched types | |
| 340 | } | |
| 341 | ||
| 342 | struct F2(S); | |
| 343 | impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F2 { | |
| 344 | reuse to_reuse::foo { self.0 } | |
| 345 | //~^ ERROR: mismatched types | |
| 346 | //~| ERROR: function takes 0 lifetime arguments but 1 lifetime argument was supplied | |
| 347 | } | |
| 348 | ||
| 349 | struct F3(S); | |
| 350 | impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F3 { | |
| 351 | reuse to_reuse::foo::<(), 123, ()> { self.0 } | |
| 352 | //~^ ERROR: mismatched types | |
| 353 | } | |
| 354 | } | |
| 355 | ||
| 356 | fn main() {} |
tests/ui/delegation/generics/infers.stderr created+1296| ... | ... | @@ -0,0 +1,1296 @@ |
| 1 | error: lifetimes must be followed by `+` to form a trait object type | |
| 2 | --> $DIR/infers.rs:54:21 | |
| 3 | | | |
| 4 | LL | reuse foo::('_, _, _, _) as bar; | |
| 5 | | ^^ | |
| 6 | | | |
| 7 | help: consider adding a trait bound after the potential lifetime bound | |
| 8 | | | |
| 9 | LL | reuse foo::('_ + /* Trait */, _, _, _) as bar; | |
| 10 | | +++++++++++++ | |
| 11 | ||
| 12 | error[E0261]: use of undeclared lifetime name `'____` | |
| 13 | --> $DIR/infers.rs:123:17 | |
| 14 | | | |
| 15 | LL | reuse foo::<'____, ___, _, ___> as foo12; | |
| 16 | | ^^^^^ undeclared lifetime | |
| 17 | | | |
| 18 | help: consider introducing lifetime `'____` here | |
| 19 | | | |
| 20 | LL | reuse foo'____, ::<'____, ___, _, ___> as foo12; | |
| 21 | | ++++++ | |
| 22 | ||
| 23 | error[E0261]: use of undeclared lifetime name `'____` | |
| 24 | --> $DIR/infers.rs:195:28 | |
| 25 | | | |
| 26 | LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; | |
| 27 | | ^^^^^ undeclared lifetime | |
| 28 | | | |
| 29 | help: consider introducing lifetime `'____` here | |
| 30 | | | |
| 31 | LL | reuse Trait::foo'____, ::<'____, ___, _, ___> as foo12; | |
| 32 | | ++++++ | |
| 33 | ||
| 34 | error[E0261]: use of undeclared lifetime name `'____` | |
| 35 | --> $DIR/infers.rs:316:51 | |
| 36 | | | |
| 37 | LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; | |
| 38 | | ^^^^^ undeclared lifetime | |
| 39 | | | |
| 40 | help: consider introducing lifetime `'____` here | |
| 41 | | | |
| 42 | LL | reuse Trait::<'static, 'static, _>::foo'____, ::<'____, ___, _, ___> as foo12; | |
| 43 | | ++++++ | |
| 44 | ||
| 45 | error[E0425]: cannot find type `___` in this scope | |
| 46 | --> $DIR/infers.rs:123:24 | |
| 47 | | | |
| 48 | LL | reuse foo::<'____, ___, _, ___> as foo12; | |
| 49 | | ^^^ not found in this scope | |
| 50 | ||
| 51 | error[E0425]: cannot find type `___` in this scope | |
| 52 | --> $DIR/infers.rs:123:32 | |
| 53 | | | |
| 54 | LL | reuse foo::<'____, ___, _, ___> as foo12; | |
| 55 | | ^^^ not found in this scope | |
| 56 | ||
| 57 | error[E0425]: cannot find type `unresolved_` in this scope | |
| 58 | --> $DIR/infers.rs:132:21 | |
| 59 | | | |
| 60 | LL | reuse foo::<'_, unresolved_, _, _> as foo14; | |
| 61 | | ^^^^^^^^^^^ not found in this scope | |
| 62 | ||
| 63 | error[E0425]: cannot find type `___` in this scope | |
| 64 | --> $DIR/infers.rs:195:35 | |
| 65 | | | |
| 66 | LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; | |
| 67 | | ^^^ not found in this scope | |
| 68 | ||
| 69 | error[E0425]: cannot find type `___` in this scope | |
| 70 | --> $DIR/infers.rs:195:43 | |
| 71 | | | |
| 72 | LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; | |
| 73 | | ^^^ not found in this scope | |
| 74 | ||
| 75 | error[E0425]: cannot find type `unresolved_` in this scope | |
| 76 | --> $DIR/infers.rs:204:32 | |
| 77 | | | |
| 78 | LL | reuse Trait::foo::<'_, unresolved_, _, _> as foo14; | |
| 79 | | ^^^^^^^^^^^ not found in this scope | |
| 80 | ||
| 81 | error[E0425]: cannot find type `___` in this scope | |
| 82 | --> $DIR/infers.rs:316:58 | |
| 83 | | | |
| 84 | LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; | |
| 85 | | ^^^ not found in this scope | |
| 86 | ||
| 87 | error[E0425]: cannot find type `___` in this scope | |
| 88 | --> $DIR/infers.rs:316:66 | |
| 89 | | | |
| 90 | LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; | |
| 91 | | ^^^ not found in this scope | |
| 92 | ||
| 93 | error: wrong infer used: expected '_, found: _ | |
| 94 | --> $DIR/infers.rs:11:21 | |
| 95 | | | |
| 96 | LL | reuse foo::<_, '_, '_, '_> as bar; | |
| 97 | | ^ | |
| 98 | ||
| 99 | error: wrong infer used: expected _, found: '_ | |
| 100 | --> $DIR/infers.rs:11:24 | |
| 101 | | | |
| 102 | LL | reuse foo::<_, '_, '_, '_> as bar; | |
| 103 | | ^^ | |
| 104 | ||
| 105 | error: wrong infer used: expected _, found: '_ | |
| 106 | --> $DIR/infers.rs:11:28 | |
| 107 | | | |
| 108 | LL | reuse foo::<_, '_, '_, '_> as bar; | |
| 109 | | ^^ | |
| 110 | ||
| 111 | error: wrong infer used: expected _, found: '_ | |
| 112 | --> $DIR/infers.rs:11:32 | |
| 113 | | | |
| 114 | LL | reuse foo::<_, '_, '_, '_> as bar; | |
| 115 | | ^^ | |
| 116 | ||
| 117 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 118 | --> $DIR/infers.rs:54:15 | |
| 119 | | | |
| 120 | LL | reuse foo::('_, _, _, _) as bar; | |
| 121 | | ^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses | |
| 122 | | | |
| 123 | help: use angle brackets instead | |
| 124 | | | |
| 125 | LL - reuse foo::('_, _, _, _) as bar; | |
| 126 | LL + reuse foo::<'_, _, _, _> as bar; | |
| 127 | | | |
| 128 | ||
| 129 | error: wrong infer used: expected _, found: '_ | |
| 130 | --> $DIR/infers.rs:86:21 | |
| 131 | | | |
| 132 | LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 133 | | ^^ | |
| 134 | ||
| 135 | error: wrong infer used: expected _, found: '_ | |
| 136 | --> $DIR/infers.rs:86:25 | |
| 137 | | | |
| 138 | LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 139 | | ^^ | |
| 140 | ||
| 141 | error: wrong infer used: expected '_, found: _ | |
| 142 | --> $DIR/infers.rs:91:17 | |
| 143 | | | |
| 144 | LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 145 | | ^ | |
| 146 | ||
| 147 | error: wrong infer used: expected _, found: '_ | |
| 148 | --> $DIR/infers.rs:91:26 | |
| 149 | | | |
| 150 | LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 151 | | ^^ | |
| 152 | ||
| 153 | error: wrong infer used: expected '_, found: _ | |
| 154 | --> $DIR/infers.rs:97:17 | |
| 155 | | | |
| 156 | LL | reuse foo::<_, '_, _, _> as foo7; | |
| 157 | | ^ | |
| 158 | ||
| 159 | error: wrong infer used: expected _, found: '_ | |
| 160 | --> $DIR/infers.rs:97:20 | |
| 161 | | | |
| 162 | LL | reuse foo::<_, '_, _, _> as foo7; | |
| 163 | | ^^ | |
| 164 | ||
| 165 | error: wrong infer used: expected _, found: '_ | |
| 166 | --> $DIR/infers.rs:101:21 | |
| 167 | | | |
| 168 | LL | reuse foo::<'_, '_, '_, '_> as foo8; | |
| 169 | | ^^ | |
| 170 | ||
| 171 | error: wrong infer used: expected _, found: '_ | |
| 172 | --> $DIR/infers.rs:101:25 | |
| 173 | | | |
| 174 | LL | reuse foo::<'_, '_, '_, '_> as foo8; | |
| 175 | | ^^ | |
| 176 | ||
| 177 | error: wrong infer used: expected _, found: '_ | |
| 178 | --> $DIR/infers.rs:101:29 | |
| 179 | | | |
| 180 | LL | reuse foo::<'_, '_, '_, '_> as foo8; | |
| 181 | | ^^ | |
| 182 | ||
| 183 | error: wrong infer used: expected '_, found: _ | |
| 184 | --> $DIR/infers.rs:106:17 | |
| 185 | | | |
| 186 | LL | reuse foo::<_> as foo9; | |
| 187 | | ^ | |
| 188 | ||
| 189 | error: wrong infer used: expected '_, found: _ | |
| 190 | --> $DIR/infers.rs:135:17 | |
| 191 | | | |
| 192 | LL | reuse foo::<_, _, _> as foo15; | |
| 193 | | ^ | |
| 194 | ||
| 195 | error: wrong infer used: expected _, found: '_ | |
| 196 | --> $DIR/infers.rs:158:32 | |
| 197 | | | |
| 198 | LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 199 | | ^^ | |
| 200 | ||
| 201 | error: wrong infer used: expected _, found: '_ | |
| 202 | --> $DIR/infers.rs:158:36 | |
| 203 | | | |
| 204 | LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 205 | | ^^ | |
| 206 | ||
| 207 | error: wrong infer used: expected '_, found: _ | |
| 208 | --> $DIR/infers.rs:163:28 | |
| 209 | | | |
| 210 | LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 211 | | ^ | |
| 212 | ||
| 213 | error: wrong infer used: expected _, found: '_ | |
| 214 | --> $DIR/infers.rs:163:37 | |
| 215 | | | |
| 216 | LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 217 | | ^^ | |
| 218 | ||
| 219 | error: wrong infer used: expected '_, found: _ | |
| 220 | --> $DIR/infers.rs:169:28 | |
| 221 | | | |
| 222 | LL | reuse Trait::foo::<_, '_, _, _> as foo7; | |
| 223 | | ^ | |
| 224 | ||
| 225 | error: wrong infer used: expected _, found: '_ | |
| 226 | --> $DIR/infers.rs:169:31 | |
| 227 | | | |
| 228 | LL | reuse Trait::foo::<_, '_, _, _> as foo7; | |
| 229 | | ^^ | |
| 230 | ||
| 231 | error: wrong infer used: expected _, found: '_ | |
| 232 | --> $DIR/infers.rs:173:32 | |
| 233 | | | |
| 234 | LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; | |
| 235 | | ^^ | |
| 236 | ||
| 237 | error: wrong infer used: expected _, found: '_ | |
| 238 | --> $DIR/infers.rs:173:36 | |
| 239 | | | |
| 240 | LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; | |
| 241 | | ^^ | |
| 242 | ||
| 243 | error: wrong infer used: expected _, found: '_ | |
| 244 | --> $DIR/infers.rs:173:40 | |
| 245 | | | |
| 246 | LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; | |
| 247 | | ^^ | |
| 248 | ||
| 249 | error: wrong infer used: expected '_, found: _ | |
| 250 | --> $DIR/infers.rs:178:28 | |
| 251 | | | |
| 252 | LL | reuse Trait::foo::<_> as foo9; | |
| 253 | | ^ | |
| 254 | ||
| 255 | error: wrong infer used: expected '_, found: _ | |
| 256 | --> $DIR/infers.rs:207:28 | |
| 257 | | | |
| 258 | LL | reuse Trait::foo::<_, _, _> as foo15; | |
| 259 | | ^ | |
| 260 | ||
| 261 | error: wrong infer used: expected _, found: '_ | |
| 262 | --> $DIR/infers.rs:218:34 | |
| 263 | | | |
| 264 | LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; | |
| 265 | | ^^ | |
| 266 | ||
| 267 | error: wrong infer used: expected '_, found: _ | |
| 268 | --> $DIR/infers.rs:226:23 | |
| 269 | | | |
| 270 | LL | reuse Trait::<_, _>::foo as foo5; | |
| 271 | | ^ | |
| 272 | ||
| 273 | error: wrong infer used: expected '_, found: _ | |
| 274 | --> $DIR/infers.rs:226:26 | |
| 275 | | | |
| 276 | LL | reuse Trait::<_, _>::foo as foo5; | |
| 277 | | ^ | |
| 278 | ||
| 279 | error: wrong infer used: expected _, found: '_ | |
| 280 | --> $DIR/infers.rs:244:41 | |
| 281 | | | |
| 282 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; | |
| 283 | | ^^ | |
| 284 | ||
| 285 | error: wrong infer used: expected _, found: '_ | |
| 286 | --> $DIR/infers.rs:244:44 | |
| 287 | | | |
| 288 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; | |
| 289 | | ^^ | |
| 290 | ||
| 291 | error: wrong infer used: expected _, found: '_ | |
| 292 | --> $DIR/infers.rs:244:48 | |
| 293 | | | |
| 294 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; | |
| 295 | | ^^ | |
| 296 | ||
| 297 | error: wrong infer used: expected _, found: '_ | |
| 298 | --> $DIR/infers.rs:260:34 | |
| 299 | | | |
| 300 | LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; | |
| 301 | | ^^ | |
| 302 | ||
| 303 | error: wrong infer used: expected '_, found: _ | |
| 304 | --> $DIR/infers.rs:268:23 | |
| 305 | | | |
| 306 | LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 307 | | ^ | |
| 308 | ||
| 309 | error: wrong infer used: expected '_, found: _ | |
| 310 | --> $DIR/infers.rs:268:26 | |
| 311 | | | |
| 312 | LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 313 | | ^ | |
| 314 | ||
| 315 | error: wrong infer used: expected _, found: '_ | |
| 316 | --> $DIR/infers.rs:268:40 | |
| 317 | | | |
| 318 | LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 319 | | ^^ | |
| 320 | ||
| 321 | error: wrong infer used: expected _, found: '_ | |
| 322 | --> $DIR/infers.rs:268:44 | |
| 323 | | | |
| 324 | LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 325 | | ^^ | |
| 326 | ||
| 327 | error: wrong infer used: expected '_, found: _ | |
| 328 | --> $DIR/infers.rs:276:38 | |
| 329 | | | |
| 330 | LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 331 | | ^ | |
| 332 | ||
| 333 | error: wrong infer used: expected _, found: '_ | |
| 334 | --> $DIR/infers.rs:276:47 | |
| 335 | | | |
| 336 | LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 337 | | ^^ | |
| 338 | ||
| 339 | error: wrong infer used: expected '_, found: _ | |
| 340 | --> $DIR/infers.rs:283:64 | |
| 341 | | | |
| 342 | LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7; | |
| 343 | | ^ | |
| 344 | ||
| 345 | error: wrong infer used: expected _, found: '_ | |
| 346 | --> $DIR/infers.rs:283:67 | |
| 347 | | | |
| 348 | LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7; | |
| 349 | | ^^ | |
| 350 | ||
| 351 | error: wrong infer used: expected _, found: '_ | |
| 352 | --> $DIR/infers.rs:289:65 | |
| 353 | | | |
| 354 | LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; | |
| 355 | | ^^ | |
| 356 | ||
| 357 | error: wrong infer used: expected _, found: '_ | |
| 358 | --> $DIR/infers.rs:289:69 | |
| 359 | | | |
| 360 | LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; | |
| 361 | | ^^ | |
| 362 | ||
| 363 | error: wrong infer used: expected _, found: '_ | |
| 364 | --> $DIR/infers.rs:289:73 | |
| 365 | | | |
| 366 | LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; | |
| 367 | | ^^ | |
| 368 | ||
| 369 | error: wrong infer used: expected '_, found: _ | |
| 370 | --> $DIR/infers.rs:294:57 | |
| 371 | | | |
| 372 | LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; | |
| 373 | | ^ | |
| 374 | ||
| 375 | error: wrong infer used: expected _, found: '_ | |
| 376 | --> $DIR/infers.rs:306:41 | |
| 377 | | | |
| 378 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 379 | | ^^ | |
| 380 | ||
| 381 | error: wrong infer used: expected _, found: '_ | |
| 382 | --> $DIR/infers.rs:306:44 | |
| 383 | | | |
| 384 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 385 | | ^^ | |
| 386 | ||
| 387 | error: wrong infer used: expected _, found: '_ | |
| 388 | --> $DIR/infers.rs:306:48 | |
| 389 | | | |
| 390 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 391 | | ^^ | |
| 392 | ||
| 393 | error[E0107]: function takes 1 lifetime argument but 2 lifetime arguments were supplied | |
| 394 | --> $DIR/infers.rs:44:15 | |
| 395 | | | |
| 396 | LL | reuse foo::<'_, '_> as foo2; | |
| 397 | | ^^^--------- help: remove the lifetime argument | |
| 398 | | | | |
| 399 | | expected 1 lifetime argument | |
| 400 | | | |
| 401 | note: function defined here, with 1 lifetime parameter: `'c` | |
| 402 | --> $DIR/infers.rs:38:12 | |
| 403 | | | |
| 404 | LL | fn foo<'a, 'b, 'c: 'c, 'd>(_: &'a &'b &'c &'d ()) {} | |
| 405 | | ^^^ -- | |
| 406 | ||
| 407 | error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied | |
| 408 | --> $DIR/infers.rs:54:15 | |
| 409 | | | |
| 410 | LL | reuse foo::('_, _, _, _) as bar; | |
| 411 | | ^^^ expected 1 lifetime argument | |
| 412 | | | |
| 413 | note: function defined here, with 1 lifetime parameter: `'b` | |
| 414 | --> $DIR/infers.rs:52:12 | |
| 415 | | | |
| 416 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 417 | | ^^^ -- | |
| 418 | help: add missing lifetime argument | |
| 419 | | | |
| 420 | LL | reuse foo::('b, '_, _, _, _) as bar; | |
| 421 | | +++ | |
| 422 | ||
| 423 | error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied | |
| 424 | --> $DIR/infers.rs:54:15 | |
| 425 | | | |
| 426 | LL | reuse foo::('_, _, _, _) as bar; | |
| 427 | | ^^^ --- help: remove the unnecessary generic argument | |
| 428 | | | | |
| 429 | | expected 3 generic arguments | |
| 430 | | | |
| 431 | note: function defined here, with 3 generic parameters: `X`, `M`, `Y` | |
| 432 | --> $DIR/infers.rs:52:12 | |
| 433 | | | |
| 434 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 435 | | ^^^ - -------------- - | |
| 436 | ||
| 437 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 438 | --> $DIR/infers.rs:54:15 | |
| 439 | | | |
| 440 | LL | reuse foo::('_, _, _, _) as bar; | |
| 441 | | ^^^ | |
| 442 | ||
| 443 | error[E0224]: at least one trait is required for an object type | |
| 444 | --> $DIR/infers.rs:54:21 | |
| 445 | | | |
| 446 | LL | reuse foo::('_, _, _, _) as bar; | |
| 447 | | ^^ | |
| 448 | ||
| 449 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 450 | --> $DIR/infers.rs:54:25 | |
| 451 | | | |
| 452 | LL | reuse foo::('_, _, _, _) as bar; | |
| 453 | | ^ not allowed in type signatures | |
| 454 | ||
| 455 | error[E0107]: function takes 3 generic arguments but 5 generic arguments were supplied | |
| 456 | --> $DIR/infers.rs:86:11 | |
| 457 | | | |
| 458 | LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 459 | | ^^^---------------------- help: remove the unnecessary generic arguments | |
| 460 | | | | |
| 461 | | expected 3 generic arguments | |
| 462 | | | |
| 463 | note: function defined here, with 3 generic parameters: `X`, `M`, `Y` | |
| 464 | --> $DIR/infers.rs:79:8 | |
| 465 | | | |
| 466 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 467 | | ^^^ - -------------- - | |
| 468 | ||
| 469 | error[E0107]: function takes 1 lifetime argument but 3 lifetime arguments were supplied | |
| 470 | --> $DIR/infers.rs:91:11 | |
| 471 | | | |
| 472 | LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 473 | | ^^^---------------------- help: remove the lifetime arguments | |
| 474 | | | | |
| 475 | | expected 1 lifetime argument | |
| 476 | | | |
| 477 | note: function defined here, with 1 lifetime parameter: `'b` | |
| 478 | --> $DIR/infers.rs:79:8 | |
| 479 | | | |
| 480 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 481 | | ^^^ -- | |
| 482 | ||
| 483 | error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied | |
| 484 | --> $DIR/infers.rs:91:11 | |
| 485 | | | |
| 486 | LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 487 | | ^^^------------------------------- help: remove the unnecessary generic arguments | |
| 488 | | | | |
| 489 | | expected 3 generic arguments | |
| 490 | | | |
| 491 | note: function defined here, with 3 generic parameters: `X`, `M`, `Y` | |
| 492 | --> $DIR/infers.rs:79:8 | |
| 493 | | | |
| 494 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 495 | | ^^^ - -------------- - | |
| 496 | ||
| 497 | error[E0107]: function takes 3 generic arguments but 0 generic arguments were supplied | |
| 498 | --> $DIR/infers.rs:106:11 | |
| 499 | | | |
| 500 | LL | reuse foo::<_> as foo9; | |
| 501 | | ^^^ expected 3 generic arguments | |
| 502 | | | |
| 503 | note: function defined here, with 3 generic parameters: `X`, `M`, `Y` | |
| 504 | --> $DIR/infers.rs:79:8 | |
| 505 | | | |
| 506 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 507 | | ^^^ - -------------- - | |
| 508 | help: add missing generic arguments | |
| 509 | | | |
| 510 | LL | reuse fooX, M, Y::<_> as foo9; | |
| 511 | | +++++++ | |
| 512 | ||
| 513 | error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied | |
| 514 | --> $DIR/infers.rs:110:11 | |
| 515 | | | |
| 516 | LL | reuse foo::<Vec<'_>, _, _, ()> as foo10; | |
| 517 | | ^^^ expected 1 lifetime argument | |
| 518 | | | |
| 519 | note: function defined here, with 1 lifetime parameter: `'b` | |
| 520 | --> $DIR/infers.rs:79:8 | |
| 521 | | | |
| 522 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 523 | | ^^^ -- | |
| 524 | help: add missing lifetime argument | |
| 525 | | | |
| 526 | LL | reuse foo::<'b, Vec<'_>, _, _, ()> as foo10; | |
| 527 | | +++ | |
| 528 | ||
| 529 | error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied | |
| 530 | --> $DIR/infers.rs:110:11 | |
| 531 | | | |
| 532 | LL | reuse foo::<Vec<'_>, _, _, ()> as foo10; | |
| 533 | | ^^^-------------------- help: remove the unnecessary generic argument | |
| 534 | | | | |
| 535 | | expected 3 generic arguments | |
| 536 | | | |
| 537 | note: function defined here, with 3 generic parameters: `X`, `M`, `Y` | |
| 538 | --> $DIR/infers.rs:79:8 | |
| 539 | | | |
| 540 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 541 | | ^^^ - -------------- - | |
| 542 | ||
| 543 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 544 | --> $DIR/infers.rs:110:11 | |
| 545 | | | |
| 546 | LL | reuse foo::<Vec<'_>, _, _, ()> as foo10; | |
| 547 | | ^^^ | |
| 548 | ||
| 549 | error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied | |
| 550 | --> $DIR/infers.rs:110:17 | |
| 551 | | | |
| 552 | LL | reuse foo::<Vec<'_>, _, _, ()> as foo10; | |
| 553 | | ^^^---- help: remove the unnecessary generics | |
| 554 | | | | |
| 555 | | expected 0 lifetime arguments | |
| 556 | ||
| 557 | error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied | |
| 558 | --> $DIR/infers.rs:110:17 | |
| 559 | | | |
| 560 | LL | reuse foo::<Vec<'_>, _, _, ()> as foo10; | |
| 561 | | ^^^ expected at least 1 generic argument | |
| 562 | | | |
| 563 | help: add missing generic argument | |
| 564 | | | |
| 565 | LL | reuse foo::<Vec<'_, T>, _, _, ()> as foo10; | |
| 566 | | +++ | |
| 567 | ||
| 568 | error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied | |
| 569 | --> $DIR/infers.rs:117:11 | |
| 570 | | | |
| 571 | LL | reuse foo::<Vec<_>, _, _, ()> as foo11; | |
| 572 | | ^^^ expected 1 lifetime argument | |
| 573 | | | |
| 574 | note: function defined here, with 1 lifetime parameter: `'b` | |
| 575 | --> $DIR/infers.rs:79:8 | |
| 576 | | | |
| 577 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 578 | | ^^^ -- | |
| 579 | help: add missing lifetime argument | |
| 580 | | | |
| 581 | LL | reuse foo::<'b, Vec<_>, _, _, ()> as foo11; | |
| 582 | | +++ | |
| 583 | ||
| 584 | error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied | |
| 585 | --> $DIR/infers.rs:117:11 | |
| 586 | | | |
| 587 | LL | reuse foo::<Vec<_>, _, _, ()> as foo11; | |
| 588 | | ^^^------------------- help: remove the unnecessary generic argument | |
| 589 | | | | |
| 590 | | expected 3 generic arguments | |
| 591 | | | |
| 592 | note: function defined here, with 3 generic parameters: `X`, `M`, `Y` | |
| 593 | --> $DIR/infers.rs:79:8 | |
| 594 | | | |
| 595 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 596 | | ^^^ - -------------- - | |
| 597 | ||
| 598 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 599 | --> $DIR/infers.rs:117:11 | |
| 600 | | | |
| 601 | LL | reuse foo::<Vec<_>, _, _, ()> as foo11; | |
| 602 | | ^^^ | |
| 603 | ||
| 604 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 605 | --> $DIR/infers.rs:117:21 | |
| 606 | | | |
| 607 | LL | reuse foo::<Vec<_>, _, _, ()> as foo11; | |
| 608 | | ^ not allowed in type signatures | |
| 609 | ||
| 610 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 611 | --> $DIR/infers.rs:128:25 | |
| 612 | | | |
| 613 | LL | reuse foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13; | |
| 614 | | ^ not allowed in type signatures | |
| 615 | ||
| 616 | error[E0747]: type provided when a constant was expected | |
| 617 | --> $DIR/infers.rs:128:29 | |
| 618 | | | |
| 619 | LL | reuse foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13; | |
| 620 | | ^^^^^^^^^^^ | |
| 621 | | | |
| 622 | help: if this generic argument was intended as a const parameter, surround it with braces | |
| 623 | | | |
| 624 | LL | reuse foo::<'_, Vec<_>, { Vec<Vec<_>> }, _> as foo13; | |
| 625 | | + + | |
| 626 | ||
| 627 | error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied | |
| 628 | --> $DIR/infers.rs:135:11 | |
| 629 | | | |
| 630 | LL | reuse foo::<_, _, _> as foo15; | |
| 631 | | ^^^ | |
| 632 | | | | |
| 633 | | expected 3 generic arguments | |
| 634 | | supplied 2 generic arguments | |
| 635 | | | |
| 636 | note: function defined here, with 3 generic parameters: `X`, `M`, `Y` | |
| 637 | --> $DIR/infers.rs:79:8 | |
| 638 | | | |
| 639 | LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} | |
| 640 | | ^^^ - -------------- - | |
| 641 | help: add missing generic argument | |
| 642 | | | |
| 643 | LL | reuse fooY::<_, _, _> as foo15; | |
| 644 | | + | |
| 645 | ||
| 646 | error[E0207]: the type parameter `Some` is not constrained by the impl trait, self type, or predicates | |
| 647 | --> $DIR/infers.rs:146:18 | |
| 648 | | | |
| 649 | LL | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} | |
| 650 | | ^^^^ unconstrained type parameter | |
| 651 | ||
| 652 | error[E0207]: the type parameter `Params` is not constrained by the impl trait, self type, or predicates | |
| 653 | --> $DIR/infers.rs:146:24 | |
| 654 | | | |
| 655 | LL | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} | |
| 656 | | ^^^^^^ unconstrained type parameter | |
| 657 | ||
| 658 | error[E0107]: method takes 3 generic arguments but 5 generic arguments were supplied | |
| 659 | --> $DIR/infers.rs:158:22 | |
| 660 | | | |
| 661 | LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 662 | | ^^^---------------------- help: remove the unnecessary generic arguments | |
| 663 | | | | |
| 664 | | expected 3 generic arguments | |
| 665 | | | |
| 666 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 667 | --> $DIR/infers.rs:142:12 | |
| 668 | | | |
| 669 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 670 | | ^^^ -- -------------- -- | |
| 671 | ||
| 672 | error[E0107]: method takes 1 lifetime argument but 3 lifetime arguments were supplied | |
| 673 | --> $DIR/infers.rs:163:22 | |
| 674 | | | |
| 675 | LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 676 | | ^^^---------------------- help: remove the lifetime arguments | |
| 677 | | | | |
| 678 | | expected 1 lifetime argument | |
| 679 | | | |
| 680 | note: method defined here, with 1 lifetime parameter: `'bb` | |
| 681 | --> $DIR/infers.rs:142:12 | |
| 682 | | | |
| 683 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 684 | | ^^^ --- | |
| 685 | ||
| 686 | error[E0107]: method takes 3 generic arguments but 6 generic arguments were supplied | |
| 687 | --> $DIR/infers.rs:163:22 | |
| 688 | | | |
| 689 | LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 690 | | ^^^------------------------------- help: remove the unnecessary generic arguments | |
| 691 | | | | |
| 692 | | expected 3 generic arguments | |
| 693 | | | |
| 694 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 695 | --> $DIR/infers.rs:142:12 | |
| 696 | | | |
| 697 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 698 | | ^^^ -- -------------- -- | |
| 699 | ||
| 700 | error[E0107]: method takes 3 generic arguments but 0 generic arguments were supplied | |
| 701 | --> $DIR/infers.rs:178:22 | |
| 702 | | | |
| 703 | LL | reuse Trait::foo::<_> as foo9; | |
| 704 | | ^^^ expected 3 generic arguments | |
| 705 | | | |
| 706 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 707 | --> $DIR/infers.rs:142:12 | |
| 708 | | | |
| 709 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 710 | | ^^^ -- -------------- -- | |
| 711 | help: add missing generic arguments | |
| 712 | | | |
| 713 | LL | reuse Trait::fooXX, M, YY::<_> as foo9; | |
| 714 | | +++++++++ | |
| 715 | ||
| 716 | error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied | |
| 717 | --> $DIR/infers.rs:182:22 | |
| 718 | | | |
| 719 | LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 720 | | ^^^ expected 1 lifetime argument | |
| 721 | | | |
| 722 | note: method defined here, with 1 lifetime parameter: `'bb` | |
| 723 | --> $DIR/infers.rs:142:12 | |
| 724 | | | |
| 725 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 726 | | ^^^ --- | |
| 727 | help: add missing lifetime argument | |
| 728 | | | |
| 729 | LL | reuse Trait::foo::<'a, Vec<'_>, _, _, ()> as foo10; | |
| 730 | | +++ | |
| 731 | ||
| 732 | error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied | |
| 733 | --> $DIR/infers.rs:182:22 | |
| 734 | | | |
| 735 | LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 736 | | ^^^-------------------- help: remove the unnecessary generic argument | |
| 737 | | | | |
| 738 | | expected 3 generic arguments | |
| 739 | | | |
| 740 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 741 | --> $DIR/infers.rs:142:12 | |
| 742 | | | |
| 743 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 744 | | ^^^ -- -------------- -- | |
| 745 | ||
| 746 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 747 | --> $DIR/infers.rs:182:22 | |
| 748 | | | |
| 749 | LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 750 | | ^^^ | |
| 751 | ||
| 752 | error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied | |
| 753 | --> $DIR/infers.rs:182:28 | |
| 754 | | | |
| 755 | LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 756 | | ^^^---- help: remove the unnecessary generics | |
| 757 | | | | |
| 758 | | expected 0 lifetime arguments | |
| 759 | ||
| 760 | error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied | |
| 761 | --> $DIR/infers.rs:182:28 | |
| 762 | | | |
| 763 | LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 764 | | ^^^ expected at least 1 generic argument | |
| 765 | | | |
| 766 | help: add missing generic argument | |
| 767 | | | |
| 768 | LL | reuse Trait::foo::<Vec<'_, T>, _, _, ()> as foo10; | |
| 769 | | +++ | |
| 770 | ||
| 771 | error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied | |
| 772 | --> $DIR/infers.rs:189:22 | |
| 773 | | | |
| 774 | LL | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11; | |
| 775 | | ^^^ expected 1 lifetime argument | |
| 776 | | | |
| 777 | note: method defined here, with 1 lifetime parameter: `'bb` | |
| 778 | --> $DIR/infers.rs:142:12 | |
| 779 | | | |
| 780 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 781 | | ^^^ --- | |
| 782 | help: add missing lifetime argument | |
| 783 | | | |
| 784 | LL | reuse Trait::foo::<'a, Vec<_>, _, _, ()> as foo11; | |
| 785 | | +++ | |
| 786 | ||
| 787 | error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied | |
| 788 | --> $DIR/infers.rs:189:22 | |
| 789 | | | |
| 790 | LL | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11; | |
| 791 | | ^^^------------------- help: remove the unnecessary generic argument | |
| 792 | | | | |
| 793 | | expected 3 generic arguments | |
| 794 | | | |
| 795 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 796 | --> $DIR/infers.rs:142:12 | |
| 797 | | | |
| 798 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 799 | | ^^^ -- -------------- -- | |
| 800 | ||
| 801 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 802 | --> $DIR/infers.rs:189:22 | |
| 803 | | | |
| 804 | LL | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11; | |
| 805 | | ^^^ | |
| 806 | ||
| 807 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 808 | --> $DIR/infers.rs:189:32 | |
| 809 | | | |
| 810 | LL | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11; | |
| 811 | | ^ not allowed in type signatures | |
| 812 | ||
| 813 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 814 | --> $DIR/infers.rs:200:36 | |
| 815 | | | |
| 816 | LL | reuse Trait::foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13; | |
| 817 | | ^ not allowed in type signatures | |
| 818 | ||
| 819 | error[E0747]: type provided when a constant was expected | |
| 820 | --> $DIR/infers.rs:200:40 | |
| 821 | | | |
| 822 | LL | reuse Trait::foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13; | |
| 823 | | ^^^^^^^^^^^ | |
| 824 | | | |
| 825 | help: if this generic argument was intended as a const parameter, surround it with braces | |
| 826 | | | |
| 827 | LL | reuse Trait::foo::<'_, Vec<_>, { Vec<Vec<_>> }, _> as foo13; | |
| 828 | | + + | |
| 829 | ||
| 830 | error[E0107]: method takes 3 generic arguments but 2 generic arguments were supplied | |
| 831 | --> $DIR/infers.rs:207:22 | |
| 832 | | | |
| 833 | LL | reuse Trait::foo::<_, _, _> as foo15; | |
| 834 | | ^^^ | |
| 835 | | | | |
| 836 | | expected 3 generic arguments | |
| 837 | | supplied 2 generic arguments | |
| 838 | | | |
| 839 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 840 | --> $DIR/infers.rs:142:12 | |
| 841 | | | |
| 842 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 843 | | ^^^ -- -------------- -- | |
| 844 | help: add missing generic argument | |
| 845 | | | |
| 846 | LL | reuse Trait::fooYY::<_, _, _> as foo15; | |
| 847 | | ++ | |
| 848 | ||
| 849 | error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied | |
| 850 | --> $DIR/infers.rs:218:15 | |
| 851 | | | |
| 852 | LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; | |
| 853 | | ^^^^^ --- supplied 1 lifetime argument | |
| 854 | | | | |
| 855 | | expected 2 lifetime arguments | |
| 856 | | | |
| 857 | note: trait defined here, with 2 lifetime parameters: `'a`, `'b` | |
| 858 | --> $DIR/infers.rs:141:15 | |
| 859 | | | |
| 860 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 861 | | ^^^^^ -- -- | |
| 862 | help: add missing lifetime argument | |
| 863 | | | |
| 864 | LL | reuse Trait::<'_, (), _, '_, _>::foo, 'a as foo3; | |
| 865 | | ++++ | |
| 866 | ||
| 867 | error[E0107]: trait takes 3 generic arguments but 4 generic arguments were supplied | |
| 868 | --> $DIR/infers.rs:218:15 | |
| 869 | | | |
| 870 | LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; | |
| 871 | | ^^^^^ --- help: remove the unnecessary generic argument | |
| 872 | | | | |
| 873 | | expected 3 generic arguments | |
| 874 | | | |
| 875 | note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` | |
| 876 | --> $DIR/infers.rs:141:15 | |
| 877 | | | |
| 878 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 879 | | ^^^^^ - -------------- - | |
| 880 | ||
| 881 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 882 | --> $DIR/infers.rs:218:15 | |
| 883 | | | |
| 884 | LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; | |
| 885 | | ^^^^^ | |
| 886 | ||
| 887 | error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied | |
| 888 | --> $DIR/infers.rs:226:15 | |
| 889 | | | |
| 890 | LL | reuse Trait::<_, _>::foo as foo5; | |
| 891 | | ^^^^^ expected 3 generic arguments | |
| 892 | | | |
| 893 | note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` | |
| 894 | --> $DIR/infers.rs:141:15 | |
| 895 | | | |
| 896 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 897 | | ^^^^^ - -------------- - | |
| 898 | help: add missing generic arguments | |
| 899 | | | |
| 900 | LL | reuse Trait::<_, _>::foo, X, C, Y as foo5; | |
| 901 | | +++++++++ | |
| 902 | ||
| 903 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 904 | --> $DIR/infers.rs:231:15 | |
| 905 | | | |
| 906 | LL | reuse Trait::<'_, '_>::foo as foo6; | |
| 907 | | ^^^^^ not allowed in type signatures | |
| 908 | ||
| 909 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 910 | --> $DIR/infers.rs:234:35 | |
| 911 | | | |
| 912 | LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo as foo7; | |
| 913 | | ^ not allowed in type signatures | |
| 914 | ||
| 915 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 916 | --> $DIR/infers.rs:234:52 | |
| 917 | | | |
| 918 | LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo as foo7; | |
| 919 | | ^ not allowed in type signatures | |
| 920 | ||
| 921 | error[E0107]: trait takes 3 generic arguments but 7 generic arguments were supplied | |
| 922 | --> $DIR/infers.rs:241:15 | |
| 923 | | | |
| 924 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo as foo10; | |
| 925 | | ^^^^^ expected 3 generic arguments ------- help: remove the unnecessary generic arguments | |
| 926 | | | |
| 927 | note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` | |
| 928 | --> $DIR/infers.rs:141:15 | |
| 929 | | | |
| 930 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 931 | | ^^^^^ - -------------- - | |
| 932 | ||
| 933 | error[E0107]: trait takes 2 lifetime arguments but 6 lifetime arguments were supplied | |
| 934 | --> $DIR/infers.rs:244:15 | |
| 935 | | | |
| 936 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; | |
| 937 | | ^^^^^ --------------------------- help: remove the lifetime arguments | |
| 938 | | | | |
| 939 | | expected 2 lifetime arguments | |
| 940 | | | |
| 941 | note: trait defined here, with 2 lifetime parameters: `'a`, `'b` | |
| 942 | --> $DIR/infers.rs:141:15 | |
| 943 | | | |
| 944 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 945 | | ^^^^^ -- -- | |
| 946 | ||
| 947 | error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied | |
| 948 | --> $DIR/infers.rs:250:15 | |
| 949 | | | |
| 950 | LL | reuse Trait::<'static, 'static, _>::foo as foo12; | |
| 951 | | ^^^^^ --- supplied 1 generic argument | |
| 952 | | | | |
| 953 | | expected 3 generic arguments | |
| 954 | | | |
| 955 | note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` | |
| 956 | --> $DIR/infers.rs:141:15 | |
| 957 | | | |
| 958 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 959 | | ^^^^^ - -------------- - | |
| 960 | help: add missing generic arguments | |
| 961 | | | |
| 962 | LL | reuse Trait::<'static, 'static, _>::foo, C, Y as foo12; | |
| 963 | | ++++++ | |
| 964 | ||
| 965 | error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied | |
| 966 | --> $DIR/infers.rs:260:15 | |
| 967 | | | |
| 968 | LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; | |
| 969 | | ^^^^^ --- supplied 1 lifetime argument | |
| 970 | | | | |
| 971 | | expected 2 lifetime arguments | |
| 972 | | | |
| 973 | note: trait defined here, with 2 lifetime parameters: `'a`, `'b` | |
| 974 | --> $DIR/infers.rs:141:15 | |
| 975 | | | |
| 976 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 977 | | ^^^^^ -- -- | |
| 978 | help: add missing lifetime argument | |
| 979 | | | |
| 980 | LL | reuse Trait::<'_, (), _, '_, _>::foo, 'a::<'static, String, _, _> as foo3; | |
| 981 | | ++++ | |
| 982 | ||
| 983 | error[E0107]: trait takes 3 generic arguments but 4 generic arguments were supplied | |
| 984 | --> $DIR/infers.rs:260:15 | |
| 985 | | | |
| 986 | LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; | |
| 987 | | ^^^^^ --- help: remove the unnecessary generic argument | |
| 988 | | | | |
| 989 | | expected 3 generic arguments | |
| 990 | | | |
| 991 | note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` | |
| 992 | --> $DIR/infers.rs:141:15 | |
| 993 | | | |
| 994 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 995 | | ^^^^^ - -------------- - | |
| 996 | ||
| 997 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 998 | --> $DIR/infers.rs:260:15 | |
| 999 | | | |
| 1000 | LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; | |
| 1001 | | ^^^^^ | |
| 1002 | ||
| 1003 | error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied | |
| 1004 | --> $DIR/infers.rs:268:15 | |
| 1005 | | | |
| 1006 | LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 1007 | | ^^^^^ expected 3 generic arguments | |
| 1008 | | | |
| 1009 | note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` | |
| 1010 | --> $DIR/infers.rs:141:15 | |
| 1011 | | | |
| 1012 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 1013 | | ^^^^^ - -------------- - | |
| 1014 | help: add missing generic arguments | |
| 1015 | | | |
| 1016 | LL | reuse Trait::<_, _>::foo, X, C, Y::<'_, '_, '_, _, _, _,> as foo5; | |
| 1017 | | +++++++++ | |
| 1018 | ||
| 1019 | error[E0107]: method takes 3 generic arguments but 5 generic arguments were supplied | |
| 1020 | --> $DIR/infers.rs:268:30 | |
| 1021 | | | |
| 1022 | LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; | |
| 1023 | | ^^^---------------------- help: remove the unnecessary generic arguments | |
| 1024 | | | | |
| 1025 | | expected 3 generic arguments | |
| 1026 | | | |
| 1027 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 1028 | --> $DIR/infers.rs:142:12 | |
| 1029 | | | |
| 1030 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 1031 | | ^^^ -- -------------- -- | |
| 1032 | ||
| 1033 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 1034 | --> $DIR/infers.rs:276:15 | |
| 1035 | | | |
| 1036 | LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 1037 | | ^^^^^ not allowed in type signatures | |
| 1038 | ||
| 1039 | error[E0107]: method takes 1 lifetime argument but 3 lifetime arguments were supplied | |
| 1040 | --> $DIR/infers.rs:276:32 | |
| 1041 | | | |
| 1042 | LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 1043 | | ^^^---------------------- help: remove the lifetime arguments | |
| 1044 | | | | |
| 1045 | | expected 1 lifetime argument | |
| 1046 | | | |
| 1047 | note: method defined here, with 1 lifetime parameter: `'bb` | |
| 1048 | --> $DIR/infers.rs:142:12 | |
| 1049 | | | |
| 1050 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 1051 | | ^^^ --- | |
| 1052 | ||
| 1053 | error[E0107]: method takes 3 generic arguments but 6 generic arguments were supplied | |
| 1054 | --> $DIR/infers.rs:276:32 | |
| 1055 | | | |
| 1056 | LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; | |
| 1057 | | ^^^------------------------------- help: remove the unnecessary generic arguments | |
| 1058 | | | | |
| 1059 | | expected 3 generic arguments | |
| 1060 | | | |
| 1061 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 1062 | --> $DIR/infers.rs:142:12 | |
| 1063 | | | |
| 1064 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 1065 | | ^^^ -- -------------- -- | |
| 1066 | ||
| 1067 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 1068 | --> $DIR/infers.rs:283:35 | |
| 1069 | | | |
| 1070 | LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7; | |
| 1071 | | ^ not allowed in type signatures | |
| 1072 | ||
| 1073 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 1074 | --> $DIR/infers.rs:283:52 | |
| 1075 | | | |
| 1076 | LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7; | |
| 1077 | | ^ not allowed in type signatures | |
| 1078 | ||
| 1079 | error[E0107]: method takes 3 generic arguments but 0 generic arguments were supplied | |
| 1080 | --> $DIR/infers.rs:294:51 | |
| 1081 | | | |
| 1082 | LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; | |
| 1083 | | ^^^ expected 3 generic arguments | |
| 1084 | | | |
| 1085 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 1086 | --> $DIR/infers.rs:142:12 | |
| 1087 | | | |
| 1088 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 1089 | | ^^^ -- -------------- -- | |
| 1090 | help: add missing generic arguments | |
| 1091 | | | |
| 1092 | LL | reuse Trait::<'static, 'static, _, _, _>::fooXX, M, YY::<_> as foo9; | |
| 1093 | | +++++++++ | |
| 1094 | ||
| 1095 | error[E0107]: trait takes 3 generic arguments but 7 generic arguments were supplied | |
| 1096 | --> $DIR/infers.rs:298:15 | |
| 1097 | | | |
| 1098 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 1099 | | ^^^^^ expected 3 generic arguments ------- help: remove the unnecessary generic arguments | |
| 1100 | | | |
| 1101 | note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` | |
| 1102 | --> $DIR/infers.rs:141:15 | |
| 1103 | | | |
| 1104 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 1105 | | ^^^^^ - -------------- - | |
| 1106 | ||
| 1107 | error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied | |
| 1108 | --> $DIR/infers.rs:298:63 | |
| 1109 | | | |
| 1110 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 1111 | | ^^^ expected 1 lifetime argument | |
| 1112 | | | |
| 1113 | note: method defined here, with 1 lifetime parameter: `'bb` | |
| 1114 | --> $DIR/infers.rs:142:12 | |
| 1115 | | | |
| 1116 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 1117 | | ^^^ --- | |
| 1118 | help: add missing lifetime argument | |
| 1119 | | | |
| 1120 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<'bb, Vec<'_>, _, _, ()> as foo10; | |
| 1121 | | ++++ | |
| 1122 | ||
| 1123 | error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied | |
| 1124 | --> $DIR/infers.rs:298:63 | |
| 1125 | | | |
| 1126 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 1127 | | ^^^-------------------- help: remove the unnecessary generic argument | |
| 1128 | | | | |
| 1129 | | expected 3 generic arguments | |
| 1130 | | | |
| 1131 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 1132 | --> $DIR/infers.rs:142:12 | |
| 1133 | | | |
| 1134 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 1135 | | ^^^ -- -------------- -- | |
| 1136 | ||
| 1137 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 1138 | --> $DIR/infers.rs:298:63 | |
| 1139 | | | |
| 1140 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 1141 | | ^^^ | |
| 1142 | ||
| 1143 | error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied | |
| 1144 | --> $DIR/infers.rs:298:69 | |
| 1145 | | | |
| 1146 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 1147 | | ^^^---- help: remove the unnecessary generics | |
| 1148 | | | | |
| 1149 | | expected 0 lifetime arguments | |
| 1150 | ||
| 1151 | error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied | |
| 1152 | --> $DIR/infers.rs:298:69 | |
| 1153 | | | |
| 1154 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10; | |
| 1155 | | ^^^ expected at least 1 generic argument | |
| 1156 | | | |
| 1157 | help: add missing generic argument | |
| 1158 | | | |
| 1159 | LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_, T>, _, _, ()> as foo10; | |
| 1160 | | +++ | |
| 1161 | ||
| 1162 | error[E0107]: trait takes 2 lifetime arguments but 5 lifetime arguments were supplied | |
| 1163 | --> $DIR/infers.rs:306:15 | |
| 1164 | | | |
| 1165 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 1166 | | ^^^^^ ----------------------- help: remove the lifetime arguments | |
| 1167 | | | | |
| 1168 | | expected 2 lifetime arguments | |
| 1169 | | | |
| 1170 | note: trait defined here, with 2 lifetime parameters: `'a`, `'b` | |
| 1171 | --> $DIR/infers.rs:141:15 | |
| 1172 | | | |
| 1173 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 1174 | | ^^^^^ -- -- | |
| 1175 | ||
| 1176 | error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied | |
| 1177 | --> $DIR/infers.rs:306:65 | |
| 1178 | | | |
| 1179 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 1180 | | ^^^ expected 1 lifetime argument | |
| 1181 | | | |
| 1182 | note: method defined here, with 1 lifetime parameter: `'bb` | |
| 1183 | --> $DIR/infers.rs:142:12 | |
| 1184 | | | |
| 1185 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 1186 | | ^^^ --- | |
| 1187 | help: add missing lifetime argument | |
| 1188 | | | |
| 1189 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<'bb, Vec<_>, _, _, ()> as foo11; | |
| 1190 | | ++++ | |
| 1191 | ||
| 1192 | error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied | |
| 1193 | --> $DIR/infers.rs:306:65 | |
| 1194 | | | |
| 1195 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 1196 | | ^^^------------------- help: remove the unnecessary generic argument | |
| 1197 | | | | |
| 1198 | | expected 3 generic arguments | |
| 1199 | | | |
| 1200 | note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` | |
| 1201 | --> $DIR/infers.rs:142:12 | |
| 1202 | | | |
| 1203 | LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | |
| 1204 | | ^^^ -- -------------- -- | |
| 1205 | ||
| 1206 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 1207 | --> $DIR/infers.rs:306:65 | |
| 1208 | | | |
| 1209 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 1210 | | ^^^ | |
| 1211 | ||
| 1212 | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions | |
| 1213 | --> $DIR/infers.rs:306:75 | |
| 1214 | | | |
| 1215 | LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11; | |
| 1216 | | ^ not allowed in type signatures | |
| 1217 | ||
| 1218 | error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied | |
| 1219 | --> $DIR/infers.rs:316:15 | |
| 1220 | | | |
| 1221 | LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; | |
| 1222 | | ^^^^^ --- supplied 1 generic argument | |
| 1223 | | | | |
| 1224 | | expected 3 generic arguments | |
| 1225 | | | |
| 1226 | note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` | |
| 1227 | --> $DIR/infers.rs:141:15 | |
| 1228 | | | |
| 1229 | LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { | |
| 1230 | | ^^^^^ - -------------- - | |
| 1231 | help: add missing generic arguments | |
| 1232 | | | |
| 1233 | LL | reuse Trait::<'static, 'static, _>::foo, C, Y::<'____, ___, _, ___> as foo12; | |
| 1234 | | ++++++ | |
| 1235 | ||
| 1236 | error[E0308]: mismatched types | |
| 1237 | --> $DIR/infers.rs:338:42 | |
| 1238 | | | |
| 1239 | LL | reuse to_reuse::foo::<_, _, _> { self.0 } | |
| 1240 | | --- ^^^^^^ expected `()`, found `S` | |
| 1241 | | | | |
| 1242 | | arguments to this function are incorrect | |
| 1243 | | | |
| 1244 | note: function defined here | |
| 1245 | --> $DIR/infers.rs:333:16 | |
| 1246 | | | |
| 1247 | LL | pub fn foo<X, const M: usize, Y>(_: ()) {} | |
| 1248 | | ^^^ ----- | |
| 1249 | ||
| 1250 | error[E0107]: function takes 0 lifetime arguments but 1 lifetime argument was supplied | |
| 1251 | --> $DIR/infers.rs:344:25 | |
| 1252 | | | |
| 1253 | LL | reuse to_reuse::foo { self.0 } | |
| 1254 | | ^^^ | |
| 1255 | | | | |
| 1256 | | expected 0 lifetime arguments | |
| 1257 | | help: remove the lifetime argument | |
| 1258 | | | |
| 1259 | note: function defined here, with 0 lifetime parameters | |
| 1260 | --> $DIR/infers.rs:333:16 | |
| 1261 | | | |
| 1262 | LL | pub fn foo<X, const M: usize, Y>(_: ()) {} | |
| 1263 | | ^^^ | |
| 1264 | ||
| 1265 | error[E0308]: mismatched types | |
| 1266 | --> $DIR/infers.rs:344:31 | |
| 1267 | | | |
| 1268 | LL | reuse to_reuse::foo { self.0 } | |
| 1269 | | --- ^^^^^^ expected `()`, found `S` | |
| 1270 | | | | |
| 1271 | | arguments to this function are incorrect | |
| 1272 | | | |
| 1273 | note: function defined here | |
| 1274 | --> $DIR/infers.rs:333:16 | |
| 1275 | | | |
| 1276 | LL | pub fn foo<X, const M: usize, Y>(_: ()) {} | |
| 1277 | | ^^^ ----- | |
| 1278 | ||
| 1279 | error[E0308]: mismatched types | |
| 1280 | --> $DIR/infers.rs:351:46 | |
| 1281 | | | |
| 1282 | LL | reuse to_reuse::foo::<(), 123, ()> { self.0 } | |
| 1283 | | --- ^^^^^^ expected `()`, found `S` | |
| 1284 | | | | |
| 1285 | | arguments to this function are incorrect | |
| 1286 | | | |
| 1287 | note: function defined here | |
| 1288 | --> $DIR/infers.rs:333:16 | |
| 1289 | | | |
| 1290 | LL | pub fn foo<X, const M: usize, Y>(_: ()) {} | |
| 1291 | | ^^^ ----- | |
| 1292 | ||
| 1293 | error: aborting due to 138 previous errors | |
| 1294 | ||
| 1295 | Some errors have detailed explanations: E0107, E0121, E0207, E0214, E0224, E0261, E0308, E0425, E0747. | |
| 1296 | For more information about an error, try `rustc --explain E0107`. |
tests/ui/delegation/generics/trait-impl-wrong-args-count.rs+5| ... | ... | @@ -26,6 +26,7 @@ mod test_1 { |
| 26 | 26 | |
| 27 | 27 | reuse to_reuse::bar1; |
| 28 | 28 | //~^ ERROR: function takes 0 generic arguments but 3 generic arguments were supplied |
| 29 | //~| ERROR: function takes 0 lifetime arguments but 2 lifetime arguments were supplied | |
| 29 | 30 | |
| 30 | 31 | reuse to_reuse::bar2; |
| 31 | 32 | //~^ ERROR: type annotations needed |
| ... | ... | @@ -59,8 +60,10 @@ mod test_2 { |
| 59 | 60 | impl Trait<String, 1> for X { |
| 60 | 61 | reuse <X as Trait1>::bar; |
| 61 | 62 | //~^ ERROR: missing generics for trait |
| 63 | //~| ERROR: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied | |
| 62 | 64 | |
| 63 | 65 | reuse <X as Trait1::<bool, bool>>::bar as bar1; |
| 66 | //~^ ERROR: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied | |
| 64 | 67 | |
| 65 | 68 | reuse <X as Trait1::<bool, bool>>::bar::<'static, u32, u32, 1> as bar2; |
| 66 | 69 | |
| ... | ... | @@ -94,9 +97,11 @@ mod test_3 { |
| 94 | 97 | impl Trait<String, 1> for X { |
| 95 | 98 | reuse <X as Trait1::<(), ()>>::bar; |
| 96 | 99 | //~^ ERROR: associated function takes 0 generic arguments but 3 generic arguments were supplied |
| 100 | //~| ERROR: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied | |
| 97 | 101 | |
| 98 | 102 | reuse <X as Trait1::<(), ()>>::bar as bar1; |
| 99 | 103 | //~^ ERROR: associated function takes 0 generic arguments but 3 generic arguments were supplied |
| 104 | //~| ERROR: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied | |
| 100 | 105 | |
| 101 | 106 | reuse <X as Trait1::<(), ()>>::foo as bar2; |
| 102 | 107 | //~^ ERROR: type annotations needed |
tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr+103-19| ... | ... | @@ -13,11 +13,29 @@ note: function defined here, with at most 2 generic parameters: `A`, `B` |
| 13 | 13 | LL | pub fn bar<'a: 'a, 'b: 'b, A, B>(x: &super::XX) {} |
| 14 | 14 | | ^^^ - - |
| 15 | 15 | |
| 16 | error[E0107]: function takes 0 lifetime arguments but 2 lifetime arguments were supplied | |
| 17 | --> $DIR/trait-impl-wrong-args-count.rs:27:25 | |
| 18 | | | |
| 19 | LL | reuse to_reuse::bar1; | |
| 20 | | ^^^^ | |
| 21 | | | | |
| 22 | | expected 0 lifetime arguments | |
| 23 | | help: remove the lifetime arguments | |
| 24 | | | |
| 25 | note: function defined here, with 0 lifetime parameters | |
| 26 | --> $DIR/trait-impl-wrong-args-count.rs:7:16 | |
| 27 | | | |
| 28 | LL | pub fn bar1(x: &super::XX) {} | |
| 29 | | ^^^^ | |
| 30 | ||
| 16 | 31 | error[E0107]: function takes 0 generic arguments but 3 generic arguments were supplied |
| 17 | 32 | --> $DIR/trait-impl-wrong-args-count.rs:27:25 |
| 18 | 33 | | |
| 19 | 34 | LL | reuse to_reuse::bar1; |
| 20 | | ^^^^ expected 0 generic arguments | |
| 35 | | ^^^^ | |
| 36 | | | | |
| 37 | | expected 0 generic arguments | |
| 38 | | help: remove the unnecessary generic arguments | |
| 21 | 39 | | |
| 22 | 40 | note: function defined here, with 0 generic parameters |
| 23 | 41 | --> $DIR/trait-impl-wrong-args-count.rs:7:16 |
| ... | ... | @@ -26,7 +44,7 @@ LL | pub fn bar1(x: &super::XX) {} |
| 26 | 44 | | ^^^^ |
| 27 | 45 | |
| 28 | 46 | error[E0284]: type annotations needed |
| 29 | --> $DIR/trait-impl-wrong-args-count.rs:30:25 | |
| 47 | --> $DIR/trait-impl-wrong-args-count.rs:31:25 | |
| 30 | 48 | | |
| 31 | 49 | LL | reuse to_reuse::bar2; |
| 32 | 50 | | ^^^^ cannot infer the value of the const parameter `X` declared on the function `bar2` |
| ... | ... | @@ -42,7 +60,7 @@ LL | reuse to_reuse::bar2::<A, B, C, D, E, F, X, Y>; |
| 42 | 60 | | ++++++++++++++++++++++++++ |
| 43 | 61 | |
| 44 | 62 | error[E0284]: type annotations needed |
| 45 | --> $DIR/trait-impl-wrong-args-count.rs:30:25 | |
| 63 | --> $DIR/trait-impl-wrong-args-count.rs:31:25 | |
| 46 | 64 | | |
| 47 | 65 | LL | reuse to_reuse::bar2; |
| 48 | 66 | | ^^^^ cannot infer the value of the const parameter `Y` declared on the function `bar2` |
| ... | ... | @@ -58,13 +76,13 @@ LL | reuse to_reuse::bar2::<A, B, C, D, E, F, X, Y>; |
| 58 | 76 | | ++++++++++++++++++++++++++ |
| 59 | 77 | |
| 60 | 78 | error[E0107]: missing generics for trait `test_2::Trait1` |
| 61 | --> $DIR/trait-impl-wrong-args-count.rs:60:21 | |
| 79 | --> $DIR/trait-impl-wrong-args-count.rs:61:21 | |
| 62 | 80 | | |
| 63 | 81 | LL | reuse <X as Trait1>::bar; |
| 64 | 82 | | ^^^^^^ expected 2 generic arguments |
| 65 | 83 | | |
| 66 | 84 | note: trait defined here, with 2 generic parameters: `A`, `B` |
| 67 | --> $DIR/trait-impl-wrong-args-count.rs:51:11 | |
| 85 | --> $DIR/trait-impl-wrong-args-count.rs:52:11 | |
| 68 | 86 | | |
| 69 | 87 | LL | trait Trait1<A, B> { |
| 70 | 88 | | ^^^^^^ - - |
| ... | ... | @@ -73,14 +91,44 @@ help: add missing generic arguments |
| 73 | 91 | LL | reuse <X as Trait1<A, B>>::bar; |
| 74 | 92 | | ++++++ |
| 75 | 93 | |
| 94 | error[E0107]: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied | |
| 95 | --> $DIR/trait-impl-wrong-args-count.rs:61:30 | |
| 96 | | | |
| 97 | LL | reuse <X as Trait1>::bar; | |
| 98 | | ^^^ | |
| 99 | | | | |
| 100 | | expected 1 lifetime argument | |
| 101 | | help: remove the lifetime argument | |
| 102 | | | |
| 103 | note: associated function defined here, with 1 lifetime parameter: `'x` | |
| 104 | --> $DIR/trait-impl-wrong-args-count.rs:53:12 | |
| 105 | | | |
| 106 | LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {} | |
| 107 | | ^^^ -- | |
| 108 | ||
| 109 | error[E0107]: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied | |
| 110 | --> $DIR/trait-impl-wrong-args-count.rs:65:44 | |
| 111 | | | |
| 112 | LL | reuse <X as Trait1::<bool, bool>>::bar as bar1; | |
| 113 | | ^^^ | |
| 114 | | | | |
| 115 | | expected 1 lifetime argument | |
| 116 | | help: remove the lifetime argument | |
| 117 | | | |
| 118 | note: associated function defined here, with 1 lifetime parameter: `'x` | |
| 119 | --> $DIR/trait-impl-wrong-args-count.rs:53:12 | |
| 120 | | | |
| 121 | LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {} | |
| 122 | | ^^^ -- | |
| 123 | ||
| 76 | 124 | error[E0107]: missing generics for trait `test_2::Trait1` |
| 77 | --> $DIR/trait-impl-wrong-args-count.rs:67:21 | |
| 125 | --> $DIR/trait-impl-wrong-args-count.rs:70:21 | |
| 78 | 126 | | |
| 79 | 127 | LL | reuse <X as Trait1>::bar::<'static, u32, u32, 1> as bar3; |
| 80 | 128 | | ^^^^^^ expected 2 generic arguments |
| 81 | 129 | | |
| 82 | 130 | note: trait defined here, with 2 generic parameters: `A`, `B` |
| 83 | --> $DIR/trait-impl-wrong-args-count.rs:51:11 | |
| 131 | --> $DIR/trait-impl-wrong-args-count.rs:52:11 | |
| 84 | 132 | | |
| 85 | 133 | LL | trait Trait1<A, B> { |
| 86 | 134 | | ^^^^^^ - - |
| ... | ... | @@ -90,13 +138,13 @@ LL | reuse <X as Trait1<A, B>>::bar::<'static, u32, u32, 1> as bar3; |
| 90 | 138 | | ++++++ |
| 91 | 139 | |
| 92 | 140 | error[E0107]: missing generics for trait `test_2::Trait1` |
| 93 | --> $DIR/trait-impl-wrong-args-count.rs:70:21 | |
| 141 | --> $DIR/trait-impl-wrong-args-count.rs:73:21 | |
| 94 | 142 | | |
| 95 | 143 | LL | reuse <X as Trait1>::bar as bar4; |
| 96 | 144 | | ^^^^^^ expected 2 generic arguments |
| 97 | 145 | | |
| 98 | 146 | note: trait defined here, with 2 generic parameters: `A`, `B` |
| 99 | --> $DIR/trait-impl-wrong-args-count.rs:51:11 | |
| 147 | --> $DIR/trait-impl-wrong-args-count.rs:52:11 | |
| 100 | 148 | | |
| 101 | 149 | LL | trait Trait1<A, B> { |
| 102 | 150 | | ^^^^^^ - - |
| ... | ... | @@ -105,38 +153,74 @@ help: add missing generic arguments |
| 105 | 153 | LL | reuse <X as Trait1<A, B>>::bar as bar4; |
| 106 | 154 | | ++++++ |
| 107 | 155 | |
| 156 | error[E0107]: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied | |
| 157 | --> $DIR/trait-impl-wrong-args-count.rs:98:40 | |
| 158 | | | |
| 159 | LL | reuse <X as Trait1::<(), ()>>::bar; | |
| 160 | | ^^^ | |
| 161 | | | | |
| 162 | | expected 0 lifetime arguments | |
| 163 | | help: remove the lifetime arguments | |
| 164 | | | |
| 165 | note: associated function defined here, with 0 lifetime parameters | |
| 166 | --> $DIR/trait-impl-wrong-args-count.rs:89:12 | |
| 167 | | | |
| 168 | LL | fn bar() {} | |
| 169 | | ^^^ | |
| 170 | ||
| 108 | 171 | error[E0107]: associated function takes 0 generic arguments but 3 generic arguments were supplied |
| 109 | --> $DIR/trait-impl-wrong-args-count.rs:95:40 | |
| 172 | --> $DIR/trait-impl-wrong-args-count.rs:98:40 | |
| 110 | 173 | | |
| 111 | 174 | LL | reuse <X as Trait1::<(), ()>>::bar; |
| 112 | | ^^^ expected 0 generic arguments | |
| 175 | | ^^^ | |
| 176 | | | | |
| 177 | | expected 0 generic arguments | |
| 178 | | help: remove the unnecessary generic arguments | |
| 113 | 179 | | |
| 114 | 180 | note: associated function defined here, with 0 generic parameters |
| 115 | --> $DIR/trait-impl-wrong-args-count.rs:86:12 | |
| 181 | --> $DIR/trait-impl-wrong-args-count.rs:89:12 | |
| 182 | | | |
| 183 | LL | fn bar() {} | |
| 184 | | ^^^ | |
| 185 | ||
| 186 | error[E0107]: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied | |
| 187 | --> $DIR/trait-impl-wrong-args-count.rs:102:40 | |
| 188 | | | |
| 189 | LL | reuse <X as Trait1::<(), ()>>::bar as bar1; | |
| 190 | | ^^^ | |
| 191 | | | | |
| 192 | | expected 0 lifetime arguments | |
| 193 | | help: remove the lifetime arguments | |
| 194 | | | |
| 195 | note: associated function defined here, with 0 lifetime parameters | |
| 196 | --> $DIR/trait-impl-wrong-args-count.rs:89:12 | |
| 116 | 197 | | |
| 117 | 198 | LL | fn bar() {} |
| 118 | 199 | | ^^^ |
| 119 | 200 | |
| 120 | 201 | error[E0107]: associated function takes 0 generic arguments but 3 generic arguments were supplied |
| 121 | --> $DIR/trait-impl-wrong-args-count.rs:98:40 | |
| 202 | --> $DIR/trait-impl-wrong-args-count.rs:102:40 | |
| 122 | 203 | | |
| 123 | 204 | LL | reuse <X as Trait1::<(), ()>>::bar as bar1; |
| 124 | | ^^^ expected 0 generic arguments | |
| 205 | | ^^^ | |
| 206 | | | | |
| 207 | | expected 0 generic arguments | |
| 208 | | help: remove the unnecessary generic arguments | |
| 125 | 209 | | |
| 126 | 210 | note: associated function defined here, with 0 generic parameters |
| 127 | --> $DIR/trait-impl-wrong-args-count.rs:86:12 | |
| 211 | --> $DIR/trait-impl-wrong-args-count.rs:89:12 | |
| 128 | 212 | | |
| 129 | 213 | LL | fn bar() {} |
| 130 | 214 | | ^^^ |
| 131 | 215 | |
| 132 | 216 | error[E0282]: type annotations needed |
| 133 | --> $DIR/trait-impl-wrong-args-count.rs:101:40 | |
| 217 | --> $DIR/trait-impl-wrong-args-count.rs:106:40 | |
| 134 | 218 | | |
| 135 | 219 | LL | reuse <X as Trait1::<(), ()>>::foo as bar2; |
| 136 | 220 | | ^^^ cannot infer type of the type parameter `X` declared on the associated function `foo` |
| 137 | 221 | |
| 138 | 222 | error[E0107]: associated function takes at most 2 generic arguments but 3 generic arguments were supplied |
| 139 | --> $DIR/trait-impl-wrong-args-count.rs:104:40 | |
| 223 | --> $DIR/trait-impl-wrong-args-count.rs:109:40 | |
| 140 | 224 | | |
| 141 | 225 | LL | reuse <X as Trait1::<(), ()>>::foo as bar3; |
| 142 | 226 | | ^^^ |
| ... | ... | @@ -145,12 +229,12 @@ LL | reuse <X as Trait1::<(), ()>>::foo as bar3; |
| 145 | 229 | | help: remove the unnecessary generic argument |
| 146 | 230 | | |
| 147 | 231 | note: associated function defined here, with at most 2 generic parameters: `X`, `Y` |
| 148 | --> $DIR/trait-impl-wrong-args-count.rs:87:12 | |
| 232 | --> $DIR/trait-impl-wrong-args-count.rs:90:12 | |
| 149 | 233 | | |
| 150 | 234 | LL | fn foo<X, Y>() {} |
| 151 | 235 | | ^^^ - - |
| 152 | 236 | |
| 153 | error: aborting due to 11 previous errors | |
| 237 | error: aborting due to 16 previous errors | |
| 154 | 238 | |
| 155 | 239 | Some errors have detailed explanations: E0107, E0282, E0284. |
| 156 | 240 | For more information about an error, try `rustc --explain E0107`. |
tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs+2-4| ... | ... | @@ -1,3 +1,4 @@ |
| 1 | //@ check-pass | |
| 1 | 2 | //@ compile-flags: -Z deduplicate-diagnostics=yes |
| 2 | 3 | |
| 3 | 4 | #![feature(fn_delegation)] |
| ... | ... | @@ -12,11 +13,8 @@ impl Trait for F {} |
| 12 | 13 | struct S(F); |
| 13 | 14 | impl S { |
| 14 | 15 | reuse Trait::foo::<> { self.0 } |
| 15 | //~^ ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 16 | ||
| 16 | 17 | reuse Trait::foo::<'_> as bar { self.0 } |
| 17 | //~^ ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 18 | //~| WARN: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present | |
| 19 | //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 20 | 18 | } |
| 21 | 19 | |
| 22 | 20 | fn main() {} |
tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr deleted-27| ... | ... | @@ -1,27 +0,0 @@ |
| 1 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 2 | --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:14:18 | |
| 3 | | | |
| 4 | LL | reuse Trait::foo::<> { self.0 } | |
| 5 | | ^^^ | |
| 6 | ||
| 7 | warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present | |
| 8 | --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:16:24 | |
| 9 | | | |
| 10 | LL | fn foo<'a: 'a>(&self) {} | |
| 11 | | - the late bound lifetime parameter is introduced here | |
| 12 | ... | |
| 13 | LL | reuse Trait::foo::<'_> as bar { self.0 } | |
| 14 | | ^^ | |
| 15 | | | |
| 16 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 17 | = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> | |
| 18 | = note: `#[warn(late_bound_lifetime_arguments)]` (part of `#[warn(future_incompatible)]`) on by default | |
| 19 | ||
| 20 | error: inferred lifetimes are not allowed in delegations as we need to inherit signature | |
| 21 | --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:16:24 | |
| 22 | | | |
| 23 | LL | reuse Trait::foo::<'_> as bar { self.0 } | |
| 24 | | ^^ | |
| 25 | ||
| 26 | error: aborting due to 2 previous errors; 1 warning emitted | |
| 27 |
tests/ui/delegation/self-ty-ice-156388.rs+2-1| ... | ... | @@ -1,8 +1,9 @@ |
| 1 | 1 | //@ compile-flags: -Z deduplicate-diagnostics=yes |
| 2 | 2 | |
| 3 | #![feature(const_trait_impl)] | |
| 3 | 4 | #![feature(fn_delegation)] |
| 4 | 5 | |
| 5 | 6 | reuse Default::default; |
| 6 | //~^ ERROR: delegation self type is not specified | |
| 7 | //~^ ERROR: the trait bound `Self: [const] Default` is not satisfied | |
| 7 | 8 | |
| 8 | 9 | fn main() {} |
tests/ui/delegation/self-ty-ice-156388.stderr+7-3| ... | ... | @@ -1,10 +1,14 @@ |
| 1 | error: delegation self type is not specified | |
| 2 | --> $DIR/self-ty-ice-156388.rs:5:16 | |
| 1 | error[E0277]: the trait bound `Self: [const] Default` is not satisfied | |
| 2 | --> $DIR/self-ty-ice-156388.rs:6:16 | |
| 3 | 3 | | |
| 4 | 4 | LL | reuse Default::default; |
| 5 | 5 | | ^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function` | |
| 7 | help: consider restricting type parameter `Self` with trait `Default` | |
| 8 | | | |
| 9 | LL | reuse Default::default [const] std::default::Default; | |
| 10 | | +++++++++++++++++++++++++++++ | |
| 8 | 11 | |
| 9 | 12 | error: aborting due to 1 previous error |
| 10 | 13 | |
| 14 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/delegation/target-expr.rs-1| ... | ... | @@ -15,7 +15,6 @@ fn foo(x: i32) -> i32 { x } |
| 15 | 15 | |
| 16 | 16 | fn bar<T: Default>(_: T) { |
| 17 | 17 | reuse Trait::static_method { |
| 18 | //~^ ERROR: delegation self type is not specified | |
| 19 | 18 | let _ = T::Default(); |
| 20 | 19 | //~^ ERROR can't use generic parameters from outer item |
| 21 | 20 | } |
tests/ui/delegation/target-expr.stderr+6-15| ... | ... | @@ -1,18 +1,17 @@ |
| 1 | 1 | error[E0401]: can't use generic parameters from outer item |
| 2 | --> $DIR/target-expr.rs:19:17 | |
| 2 | --> $DIR/target-expr.rs:18:17 | |
| 3 | 3 | | |
| 4 | 4 | LL | fn bar<T: Default>(_: T) { |
| 5 | 5 | | - type parameter from outer item |
| 6 | 6 | LL | reuse Trait::static_method { |
| 7 | 7 | | ------------- generic parameter used in this inner delegated function |
| 8 | LL | | |
| 9 | 8 | LL | let _ = T::Default(); |
| 10 | 9 | | ^ use of generic parameter from outer item |
| 11 | 10 | | |
| 12 | 11 | = note: nested items are independent from their parent item for everything except for privacy and name resolution |
| 13 | 12 | |
| 14 | 13 | error[E0434]: can't capture dynamic environment in a fn item |
| 15 | --> $DIR/target-expr.rs:27:17 | |
| 14 | --> $DIR/target-expr.rs:26:17 | |
| 16 | 15 | | |
| 17 | 16 | LL | let x = y; |
| 18 | 17 | | ^ |
| ... | ... | @@ -20,7 +19,7 @@ LL | let x = y; |
| 20 | 19 | = help: use the `|| { ... }` closure form instead |
| 21 | 20 | |
| 22 | 21 | error[E0424]: expected value, found module `self` |
| 23 | --> $DIR/target-expr.rs:34:5 | |
| 22 | --> $DIR/target-expr.rs:33:5 | |
| 24 | 23 | | |
| 25 | 24 | LL | fn main() { |
| 26 | 25 | | ---- this function can't have a `self` parameter |
| ... | ... | @@ -29,26 +28,18 @@ LL | self.0; |
| 29 | 28 | | ^^^^ `self` value is a keyword only available in methods with a `self` parameter |
| 30 | 29 | |
| 31 | 30 | error[E0425]: cannot find value `x` in this scope |
| 32 | --> $DIR/target-expr.rs:36:13 | |
| 31 | --> $DIR/target-expr.rs:35:13 | |
| 33 | 32 | | |
| 34 | 33 | LL | let z = x; |
| 35 | 34 | | ^ |
| 36 | 35 | | |
| 37 | 36 | help: the binding `x` is available in a different scope in the same function |
| 38 | --> $DIR/target-expr.rs:27:13 | |
| 37 | --> $DIR/target-expr.rs:26:13 | |
| 39 | 38 | | |
| 40 | 39 | LL | let x = y; |
| 41 | 40 | | ^ |
| 42 | 41 | |
| 43 | error: delegation self type is not specified | |
| 44 | --> $DIR/target-expr.rs:17:18 | |
| 45 | | | |
| 46 | LL | reuse Trait::static_method { | |
| 47 | | ^^^^^^^^^^^^^ | |
| 48 | | | |
| 49 | = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function` | |
| 50 | ||
| 51 | error: aborting due to 5 previous errors | |
| 42 | error: aborting due to 4 previous errors | |
| 52 | 43 | |
| 53 | 44 | Some errors have detailed explanations: E0401, E0424, E0425, E0434. |
| 54 | 45 | For more information about an error, try `rustc --explain E0401`. |
tests/ui/delegation/unsupported.current.stderr+1-9| ... | ... | @@ -20,14 +20,6 @@ LL | reuse ToReuse::opaque_ret; |
| 20 | 20 | = note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret` is compatible with trait definition |
| 21 | 21 | = note: for more information, see <https://rustc-dev-guide.rust-lang.org/overview.html#queries> and <https://rustc-dev-guide.rust-lang.org/query.html> |
| 22 | 22 | |
| 23 | error: delegation self type is not specified | |
| 24 | --> $DIR/unsupported.rs:54:18 | |
| 25 | | | |
| 26 | LL | reuse Trait::foo; | |
| 27 | | ^^^ | |
| 28 | | | |
| 29 | = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function` | |
| 30 | ||
| 31 | error: aborting due to 3 previous errors | |
| 23 | error: aborting due to 2 previous errors | |
| 32 | 24 | |
| 33 | 25 | For more information about this error, try `rustc --explain E0391`. |
tests/ui/delegation/unsupported.next.stderr+1-9| ... | ... | @@ -20,14 +20,6 @@ LL | reuse ToReuse::opaque_ret; |
| 20 | 20 | = note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret` is compatible with trait definition |
| 21 | 21 | = note: for more information, see <https://rustc-dev-guide.rust-lang.org/overview.html#queries> and <https://rustc-dev-guide.rust-lang.org/query.html> |
| 22 | 22 | |
| 23 | error: delegation self type is not specified | |
| 24 | --> $DIR/unsupported.rs:54:18 | |
| 25 | | | |
| 26 | LL | reuse Trait::foo; | |
| 27 | | ^^^ | |
| 28 | | | |
| 29 | = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function` | |
| 30 | ||
| 31 | error: aborting due to 3 previous errors | |
| 23 | error: aborting due to 2 previous errors | |
| 32 | 24 | |
| 33 | 25 | For more information about this error, try `rustc --explain E0391`. |
tests/ui/delegation/unsupported.rs-1| ... | ... | @@ -52,7 +52,6 @@ mod effects { |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | reuse Trait::foo; |
| 55 | //~^ ERROR: delegation self type is not specified | |
| 56 | 55 | } |
| 57 | 56 | |
| 58 | 57 | fn main() {} |
tests/ui/derives/derive-compound-arities.rs created+75| ... | ... | @@ -0,0 +1,75 @@ |
| 1 | //! Regression test for https://github.com/rust-lang/rust/issues/28561 | |
| 2 | //@ check-pass | |
| 3 | #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Clone, Copy)] | |
| 4 | struct Array<T> { | |
| 5 | f00: [T; 00], | |
| 6 | f01: [T; 01], | |
| 7 | f02: [T; 02], | |
| 8 | f03: [T; 03], | |
| 9 | f04: [T; 04], | |
| 10 | f05: [T; 05], | |
| 11 | f06: [T; 06], | |
| 12 | f07: [T; 07], | |
| 13 | f08: [T; 08], | |
| 14 | f09: [T; 09], | |
| 15 | f10: [T; 10], | |
| 16 | f11: [T; 11], | |
| 17 | f12: [T; 12], | |
| 18 | f13: [T; 13], | |
| 19 | f14: [T; 14], | |
| 20 | f15: [T; 15], | |
| 21 | f16: [T; 16], | |
| 22 | f17: [T; 17], | |
| 23 | f18: [T; 18], | |
| 24 | f19: [T; 19], | |
| 25 | f20: [T; 20], | |
| 26 | f21: [T; 21], | |
| 27 | f22: [T; 22], | |
| 28 | f23: [T; 23], | |
| 29 | f24: [T; 24], | |
| 30 | f25: [T; 25], | |
| 31 | f26: [T; 26], | |
| 32 | f27: [T; 27], | |
| 33 | f28: [T; 28], | |
| 34 | f29: [T; 29], | |
| 35 | f30: [T; 30], | |
| 36 | f31: [T; 31], | |
| 37 | f32: [T; 32], | |
| 38 | } | |
| 39 | ||
| 40 | #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] | |
| 41 | #[allow(unpredictable_function_pointer_comparisons)] | |
| 42 | struct Fn<A, B, C, D, E, F, G, H, I, J, K, L> { | |
| 43 | f00: fn(), | |
| 44 | f01: fn(A), | |
| 45 | f02: fn(A, B), | |
| 46 | f03: fn(A, B, C), | |
| 47 | f04: fn(A, B, C, D), | |
| 48 | f05: fn(A, B, C, D, E), | |
| 49 | f06: fn(A, B, C, D, E, F), | |
| 50 | f07: fn(A, B, C, D, E, F, G), | |
| 51 | f08: fn(A, B, C, D, E, F, G, H), | |
| 52 | f09: fn(A, B, C, D, E, F, G, H, I), | |
| 53 | f10: fn(A, B, C, D, E, F, G, H, I, J), | |
| 54 | f11: fn(A, B, C, D, E, F, G, H, I, J, K), | |
| 55 | f12: fn(A, B, C, D, E, F, G, H, I, J, K, L), | |
| 56 | } | |
| 57 | ||
| 58 | #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] | |
| 59 | struct Tuple<A, B, C, D, E, F, G, H, I, J, K, L> { | |
| 60 | f00: (), | |
| 61 | f01: (A), | |
| 62 | f02: (A, B), | |
| 63 | f03: (A, B, C), | |
| 64 | f04: (A, B, C, D), | |
| 65 | f05: (A, B, C, D, E), | |
| 66 | f06: (A, B, C, D, E, F), | |
| 67 | f07: (A, B, C, D, E, F, G), | |
| 68 | f08: (A, B, C, D, E, F, G, H), | |
| 69 | f09: (A, B, C, D, E, F, G, H, I), | |
| 70 | f10: (A, B, C, D, E, F, G, H, I, J), | |
| 71 | f11: (A, B, C, D, E, F, G, H, I, J, K), | |
| 72 | f12: (A, B, C, D, E, F, G, H, I, J, K, L), | |
| 73 | } | |
| 74 | ||
| 75 | fn main() {} |
tests/ui/derives/derive-error-identifies-unsafe-trait-name.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | //! Regression test for https://github.com/rust-lang/rust/issues/33571 | |
| 2 | #[derive(Clone, | |
| 3 | Sync, //~ ERROR cannot find derive macro `Sync` in this scope | |
| 4 | //~| ERROR cannot find derive macro `Sync` in this scope | |
| 5 | Copy)] | |
| 6 | enum Foo {} | |
| 7 | ||
| 8 | fn main() {} |
tests/ui/derives/derive-error-identifies-unsafe-trait-name.stderr created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | error: cannot find derive macro `Sync` in this scope | |
| 2 | --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10 | |
| 3 | | | |
| 4 | LL | Sync, | |
| 5 | | ^^^^ | |
| 6 | | | |
| 7 | note: unsafe traits like `Sync` should be implemented explicitly | |
| 8 | --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10 | |
| 9 | | | |
| 10 | LL | Sync, | |
| 11 | | ^^^^ | |
| 12 | ||
| 13 | error: cannot find derive macro `Sync` in this scope | |
| 14 | --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10 | |
| 15 | | | |
| 16 | LL | Sync, | |
| 17 | | ^^^^ | |
| 18 | | | |
| 19 | note: unsafe traits like `Sync` should be implemented explicitly | |
| 20 | --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10 | |
| 21 | | | |
| 22 | LL | Sync, | |
| 23 | | ^^^^ | |
| 24 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 25 | ||
| 26 | error: aborting due to 2 previous errors | |
| 27 |
tests/ui/derives/derived-trait-requires-field-impl.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | //! Regression test for https://github.com/rust-lang/rust/issues/27340 | |
| 2 | struct Foo; | |
| 3 | #[derive(Copy, Clone)] | |
| 4 | struct Bar(Foo); | |
| 5 | //~^ ERROR: the trait `Copy` cannot be implemented for this type | |
| 6 | //~| ERROR: `Foo: Clone` is not satisfied | |
| 7 | ||
| 8 | fn main() {} |
tests/ui/derives/derived-trait-requires-field-impl.stderr created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | error[E0204]: the trait `Copy` cannot be implemented for this type | |
| 2 | --> $DIR/derived-trait-requires-field-impl.rs:4:8 | |
| 3 | | | |
| 4 | LL | #[derive(Copy, Clone)] | |
| 5 | | ---- in this derive macro expansion | |
| 6 | LL | struct Bar(Foo); | |
| 7 | | ^^^ --- this field does not implement `Copy` | |
| 8 | ||
| 9 | error[E0277]: the trait bound `Foo: Clone` is not satisfied | |
| 10 | --> $DIR/derived-trait-requires-field-impl.rs:4:12 | |
| 11 | | | |
| 12 | LL | #[derive(Copy, Clone)] | |
| 13 | | ----- in this derive macro expansion | |
| 14 | LL | struct Bar(Foo); | |
| 15 | | ^^^ the trait `Clone` is not implemented for `Foo` | |
| 16 | | | |
| 17 | note: required by a bound in `std::clone::AssertParamIsClone` | |
| 18 | --> $SRC_DIR/core/src/clone.rs:LL:COL | |
| 19 | help: consider annotating `Foo` with `#[derive(Clone)]` | |
| 20 | | | |
| 21 | LL + #[derive(Clone)] | |
| 22 | LL | struct Foo; | |
| 23 | | | |
| 24 | ||
| 25 | error: aborting due to 2 previous errors | |
| 26 | ||
| 27 | Some errors have detailed explanations: E0204, E0277. | |
| 28 | For more information about an error, try `rustc --explain E0204`. |
tests/ui/derives/hash-on-compound-types.rs+1-2| ... | ... | @@ -1,5 +1,4 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/21402>. | |
| 2 | ||
| 1 | //! Regression test for https://github.com/rust-lang/rust/issues/21402 | |
| 3 | 2 | //@ check-pass |
| 4 | 3 | #![allow(dead_code)] |
| 5 | 4 |
tests/ui/derives/no-ice-on-derived-copy-with-associated-type-field.rs created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | //! Regression test for https://github.com/rust-lang/rust/issues/32324 | |
| 2 | //@ check-pass | |
| 3 | #![allow(dead_code)] | |
| 4 | ||
| 5 | trait Resources { | |
| 6 | type Buffer: Copy; | |
| 7 | } | |
| 8 | ||
| 9 | #[derive(Copy, Clone)] | |
| 10 | struct ConstantBufferSet<R: Resources>( | |
| 11 | pub R::Buffer | |
| 12 | ); | |
| 13 | ||
| 14 | #[derive(Copy, Clone)] | |
| 15 | enum It {} | |
| 16 | impl Resources for It { | |
| 17 | type Buffer = u8; | |
| 18 | } | |
| 19 | ||
| 20 | #[derive(Copy, Clone)] | |
| 21 | enum Command { | |
| 22 | BindConstantBuffers(ConstantBufferSet<It>) | |
| 23 | } | |
| 24 | ||
| 25 | fn main() {} |
tests/ui/derives/no-ice-on-path-style-derive-macro.rs created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | //! Regression test for https://github.com/rust-lang/rust/issues/46101 | |
| 2 | trait Foo {} | |
| 3 | #[derive(Foo::Anything)] //~ ERROR cannot find | |
| 4 | //~| ERROR cannot find | |
| 5 | struct S; | |
| 6 | ||
| 7 | fn main() {} |
tests/ui/derives/no-ice-on-path-style-derive-macro.stderr created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | error[E0433]: cannot find derive macro `Anything` in trait `Foo` | |
| 2 | --> $DIR/no-ice-on-path-style-derive-macro.rs:3:10 | |
| 3 | | | |
| 4 | LL | #[derive(Foo::Anything)] | |
| 5 | | ^^^^^^^^^^^^^ a derive macro can't exist within a trait | |
| 6 | ||
| 7 | error[E0433]: cannot find derive macro `Anything` in trait `Foo` | |
| 8 | --> $DIR/no-ice-on-path-style-derive-macro.rs:3:10 | |
| 9 | | | |
| 10 | LL | #[derive(Foo::Anything)] | |
| 11 | | ^^^^^^^^^^^^^ a derive macro can't exist within a trait | |
| 12 | | | |
| 13 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 14 | ||
| 15 | error: aborting due to 2 previous errors | |
| 16 | ||
| 17 | For more information about this error, try `rustc --explain E0433`. |
tests/ui/derives/no-spurious-unused-variable-warning-on-derive-hash.rs created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | //! Regression test for https://github.com/rust-lang/rust/issues/32292 | |
| 2 | //@ run-pass | |
| 3 | #![deny(warnings)] | |
| 4 | ||
| 5 | #[derive(Hash, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Copy)] | |
| 6 | struct Foo; | |
| 7 | ||
| 8 | fn main() { | |
| 9 | let _ = Foo; | |
| 10 | } |
tests/ui/drop/rc-trait-object-double-drop.rs created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/25515>. | |
| 2 | //! Test we don't drop twice when we take a reference through other | |
| 3 | //! object like `Rc<dyn Trait>`. | |
| 4 | //! | |
| 5 | //! This used to drop Foo twice while coerced to a trait object. | |
| 6 | //! `&T`, `Rc` and `&mut` dropped any unsized item each time | |
| 7 | //! reference was taken. | |
| 8 | //! | |
| 9 | //! Value was being dropped when taking the address of an unsized field. | |
| 10 | //@ run-pass | |
| 11 | ||
| 12 | use std::rc::Rc; | |
| 13 | ||
| 14 | struct Foo<'r>(&'r mut i32); | |
| 15 | ||
| 16 | impl<'r> Drop for Foo<'r> { | |
| 17 | fn drop(&mut self) { | |
| 18 | *self.0 += 1; | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn main() { | |
| 23 | let mut drops = 0; | |
| 24 | ||
| 25 | { | |
| 26 | let _: Rc<dyn Send> = Rc::new(Foo(&mut drops)); | |
| 27 | } | |
| 28 | ||
| 29 | assert_eq!(1, drops); | |
| 30 | } |
tests/ui/dropck/no-dropck-overflow-on-deep-nesting.rs created+50| ... | ... | @@ -0,0 +1,50 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22443>. | |
| 2 | //! | |
| 3 | //! This test is reduced from librustc_ast. It is just checking that we | |
| 4 | //! can successfully deal with a "deep" structure, which the drop-check | |
| 5 | //! was hitting a recursion limit on at one point. | |
| 6 | ||
| 7 | //@ check-pass | |
| 8 | ||
| 9 | ||
| 10 | #![allow(non_camel_case_types)] | |
| 11 | ||
| 12 | pub fn noop_fold_impl_item() -> SmallVector<ImplItem> { | |
| 13 | loop { } | |
| 14 | } | |
| 15 | ||
| 16 | pub struct SmallVector<T>(P<T>); | |
| 17 | pub struct ImplItem(P<S01_Method>); | |
| 18 | ||
| 19 | struct P<T>(Box<T>); | |
| 20 | ||
| 21 | struct S01_Method(P<S02_Generics>); | |
| 22 | struct S02_Generics(P<S03_TyParam>); | |
| 23 | struct S03_TyParam(P<S04_TyParamBound>); | |
| 24 | struct S04_TyParamBound(S05_PolyTraitRef); | |
| 25 | struct S05_PolyTraitRef(S06_TraitRef); | |
| 26 | struct S06_TraitRef(S07_Path); | |
| 27 | struct S07_Path(Vec<S08_PathSegment>); | |
| 28 | struct S08_PathSegment(S09_GenericArgs); | |
| 29 | struct S09_GenericArgs(P<S10_ParenthesizedParameterData>); | |
| 30 | struct S10_ParenthesizedParameterData(Option<P<S11_Ty>>); | |
| 31 | struct S11_Ty(P<S12_Expr>); | |
| 32 | struct S12_Expr(P<S13_Block>); | |
| 33 | struct S13_Block(Vec<P<S14_Stmt>>); | |
| 34 | struct S14_Stmt(P<S15_Decl>); | |
| 35 | struct S15_Decl(P<S16_Local>); | |
| 36 | struct S16_Local(P<S17_Pat>); | |
| 37 | struct S17_Pat(P<S18_Mac>); | |
| 38 | struct S18_Mac(Vec<P<S19_TokenTree>>); | |
| 39 | struct S19_TokenTree(P<S20_Token>); | |
| 40 | struct S20_Token(P<S21_Nonterminal>); | |
| 41 | struct S21_Nonterminal(P<S22_Item>); | |
| 42 | struct S22_Item(P<S23_EnumDef>); | |
| 43 | struct S23_EnumDef(Vec<P<S24_Variant>>); | |
| 44 | struct S24_Variant(P<S25_VariantKind>); | |
| 45 | struct S25_VariantKind(P<S26_StructDef>); | |
| 46 | struct S26_StructDef(Vec<P<S27_StructField>>); | |
| 47 | struct S27_StructField(P<S28_StructFieldKind>); | |
| 48 | struct S28_StructFieldKind; | |
| 49 | ||
| 50 | pub fn main() {} |
tests/ui/dst/match-dst-struct.rs created+62| ... | ... | @@ -0,0 +1,62 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/23261>. | |
| 2 | //! Matching on a DST struct should not trigger an LLVM assertion. | |
| 3 | //@ run-pass | |
| 4 | ||
| 5 | struct Foo<T: ?Sized> { | |
| 6 | a: i32, | |
| 7 | inner: T | |
| 8 | } | |
| 9 | ||
| 10 | trait Get { | |
| 11 | fn get(&self) -> i32; | |
| 12 | } | |
| 13 | ||
| 14 | impl Get for i32 { | |
| 15 | fn get(&self) -> i32 { | |
| 16 | *self | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | fn check_val(val: &Foo<[u8]>) { | |
| 21 | match *val { | |
| 22 | Foo { a, .. } => { | |
| 23 | assert_eq!(a, 32); | |
| 24 | } | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | fn check_dst_val(val: &Foo<[u8]>) { | |
| 29 | match *val { | |
| 30 | Foo { ref inner, .. } => { | |
| 31 | assert_eq!(inner, [1, 2, 3]); | |
| 32 | } | |
| 33 | } | |
| 34 | } | |
| 35 | ||
| 36 | fn check_both(val: &Foo<[u8]>) { | |
| 37 | match *val { | |
| 38 | Foo { a, ref inner } => { | |
| 39 | assert_eq!(a, 32); | |
| 40 | assert_eq!(inner, [1, 2, 3]); | |
| 41 | } | |
| 42 | } | |
| 43 | } | |
| 44 | ||
| 45 | fn check_trait_obj(val: &Foo<dyn Get>) { | |
| 46 | match *val { | |
| 47 | Foo { a, ref inner } => { | |
| 48 | assert_eq!(a, 32); | |
| 49 | assert_eq!(inner.get(), 32); | |
| 50 | } | |
| 51 | } | |
| 52 | } | |
| 53 | ||
| 54 | fn main() { | |
| 55 | let foo: &Foo<[u8]> = &Foo { a: 32, inner: [1, 2, 3] }; | |
| 56 | check_val(foo); | |
| 57 | check_dst_val(foo); | |
| 58 | check_both(foo); | |
| 59 | ||
| 60 | let foo: &Foo<dyn Get> = &Foo { a: 32, inner: 32 }; | |
| 61 | check_trait_obj(foo); | |
| 62 | } |
tests/ui/dyn-compatibility/supertrait-with-self-in-type-arg.rs created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/26056>. | |
| 2 | ||
| 3 | trait MapLookup<Q> { | |
| 4 | type MapValue; | |
| 5 | } | |
| 6 | ||
| 7 | impl<K> MapLookup<K> for K { | |
| 8 | type MapValue = K; | |
| 9 | } | |
| 10 | ||
| 11 | trait Map: MapLookup<<Self as Map>::Key> { | |
| 12 | type Key; | |
| 13 | } | |
| 14 | ||
| 15 | impl<K> Map for K { | |
| 16 | type Key = K; | |
| 17 | } | |
| 18 | ||
| 19 | ||
| 20 | fn main() { | |
| 21 | let _ = &() | |
| 22 | as &dyn Map<Key=u32,MapValue=u32>; | |
| 23 | //~^ ERROR E0038 | |
| 24 | } |
tests/ui/dyn-compatibility/supertrait-with-self-in-type-arg.stderr created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | error[E0038]: the trait `Map` is not dyn compatible | |
| 2 | --> $DIR/supertrait-with-self-in-type-arg.rs:22:17 | |
| 3 | | | |
| 4 | LL | as &dyn Map<Key=u32,MapValue=u32>; | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` is not dyn compatible | |
| 6 | | | |
| 7 | note: for a trait to be dyn compatible it needs to allow building a vtable | |
| 8 | for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> | |
| 9 | --> $DIR/supertrait-with-self-in-type-arg.rs:11:12 | |
| 10 | | | |
| 11 | LL | trait Map: MapLookup<<Self as Map>::Key> { | |
| 12 | | --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter | |
| 13 | | | | |
| 14 | | this trait is not dyn compatible... | |
| 15 | ||
| 16 | error: aborting due to 1 previous error | |
| 17 | ||
| 18 | For more information about this error, try `rustc --explain E0038`. |
tests/ui/error-codes/E0264.rs+2-2| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | #![feature(lang_items)] |
| 2 | 2 | |
| 3 | 3 | extern "C" { |
| 4 | #[lang = "copy"] | |
| 5 | fn copy(); //~ ERROR E0264 | |
| 4 | #[lang = "copy"] //~ ERROR E0264 | |
| 5 | fn copy(); | |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | fn main() {} |
tests/ui/error-codes/E0264.stderr+3-3| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | error[E0264]: unknown external lang item: `copy` |
| 2 | --> $DIR/E0264.rs:5:5 | |
| 2 | --> $DIR/E0264.rs:4:5 | |
| 3 | 3 | | |
| 4 | LL | fn copy(); | |
| 5 | | ^^^^^^^^^^ | |
| 4 | LL | #[lang = "copy"] | |
| 5 | | ^^^^^^^^^^^^^^^^ | |
| 6 | 6 | |
| 7 | 7 | error: aborting due to 1 previous error |
| 8 | 8 |
tests/ui/error-codes/E0718.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | #![feature(lang_items)] |
| 2 | 2 | |
| 3 | 3 | // Box is expected to be a struct, so this will error. |
| 4 | #[lang = "owned_box"] //~ ERROR lang item must be applied to a struct | |
| 4 | #[lang = "owned_box"] //~ ERROR `#[lang = "owned_box"]` attribute cannot be used on statics | |
| 5 | 5 | static X: u32 = 42; |
| 6 | 6 | |
| 7 | 7 | fn main() {} |
tests/ui/error-codes/E0718.stderr+4-3| ... | ... | @@ -1,9 +1,10 @@ |
| 1 | error[E0718]: `owned_box` lang item must be applied to a struct | |
| 1 | error: `#[lang = "owned_box"]` attribute cannot be used on statics | |
| 2 | 2 | --> $DIR/E0718.rs:4:1 |
| 3 | 3 | | |
| 4 | 4 | LL | #[lang = "owned_box"] |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^ attribute should be applied to a struct, not a static | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = help: `#[lang = "owned_box"]` can only be applied to structs | |
| 6 | 8 | |
| 7 | 9 | error: aborting due to 1 previous error |
| 8 | 10 | |
| 9 | For more information about this error, try `rustc --explain E0718`. |
tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time | |
| 2 | --> $DIR/no-unsized-arguments.rs:40:42 | |
| 3 | | | |
| 4 | LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { | |
| 5 | | ^^^^ doesn't have a size known at compile-time | |
| 6 | | | |
| 7 | = help: the trait `Sized` is not implemented for `[u8]` | |
| 8 | help: function arguments must have a statically known size, borrowed slices always have a known size | |
| 9 | | | |
| 10 | LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { | |
| 11 | | + | |
| 12 | ||
| 13 | error: unsized arguments cannot be used in a tail call | |
| 14 | --> $DIR/no-unsized-arguments.rs:33:5 | |
| 15 | | | |
| 16 | LL | become unsized_argument(b); | |
| 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 18 | | | |
| 19 | = note: unsized argument of type `[u8]` | |
| 20 | ||
| 21 | error: unsized arguments cannot be used in a tail call | |
| 22 | --> $DIR/no-unsized-arguments.rs:48:5 | |
| 23 | | | |
| 24 | LL | become unsized_argument(*b); | |
| 25 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 26 | | | |
| 27 | = note: unsized argument of type `[u8]` | |
| 28 | ||
| 29 | error: aborting due to 3 previous errors | |
| 30 | ||
| 31 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/explicit-tail-calls/no-unsized-arguments.rs created+50| ... | ... | @@ -0,0 +1,50 @@ |
| 1 | //@ add-minicore | |
| 2 | //@ ignore-backends: gcc | |
| 3 | //@ min-llvm-version: 22 | |
| 4 | // | |
| 5 | //@ revisions: x86 x86_64 aarch64 | |
| 6 | // | |
| 7 | //@ [x86] compile-flags: --target=i686-unknown-linux-gnu | |
| 8 | //@ [x86] needs-llvm-components: x86 | |
| 9 | //@ [x86_64] compile-flags: --target=x86_64-unknown-linux-gnu | |
| 10 | //@ [x86_64] needs-llvm-components: x86 | |
| 11 | //@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu | |
| 12 | //@ [aarch64] needs-llvm-components: aarch64 | |
| 13 | #![feature(explicit_tail_calls, rust_tail_cc, unsized_fn_params, no_core)] | |
| 14 | #![allow(incomplete_features, internal_features)] | |
| 15 | #![no_core] | |
| 16 | #![crate_type = "lib"] | |
| 17 | ||
| 18 | extern crate minicore; | |
| 19 | use minicore::*; | |
| 20 | ||
| 21 | extern "C" { | |
| 22 | fn extract(_: [u8]) -> u8; | |
| 23 | } | |
| 24 | ||
| 25 | fn vanilla(b: [u8]) -> u8 { | |
| 26 | fn unsized_argument(x: [u8]) -> u8 { | |
| 27 | unsafe { extract(x) } | |
| 28 | } | |
| 29 | ||
| 30 | // Non-tail call. | |
| 31 | let _ = unsized_argument(b); | |
| 32 | ||
| 33 | become unsized_argument(b); | |
| 34 | //~^ ERROR unsized arguments cannot be used in a tail call | |
| 35 | } | |
| 36 | ||
| 37 | extern "tail" fn tailcc(b: &[u8]) -> u8 { | |
| 38 | // `extern "tail"` is special because we also can't unsized parameters in standard definitions | |
| 39 | // and calls. | |
| 40 | extern "tail" fn unsized_argument(x: [u8]) -> u8 { | |
| 41 | //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time | |
| 42 | unsafe { extract(x) } | |
| 43 | } | |
| 44 | ||
| 45 | // Vanilla call. | |
| 46 | let _ = unsized_argument(*b); | |
| 47 | ||
| 48 | become unsized_argument(*b); | |
| 49 | //~^ ERROR unsized arguments cannot be used in a tail call | |
| 50 | } |
tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time | |
| 2 | --> $DIR/no-unsized-arguments.rs:40:42 | |
| 3 | | | |
| 4 | LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { | |
| 5 | | ^^^^ doesn't have a size known at compile-time | |
| 6 | | | |
| 7 | = help: the trait `Sized` is not implemented for `[u8]` | |
| 8 | help: function arguments must have a statically known size, borrowed slices always have a known size | |
| 9 | | | |
| 10 | LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { | |
| 11 | | + | |
| 12 | ||
| 13 | error: unsized arguments cannot be used in a tail call | |
| 14 | --> $DIR/no-unsized-arguments.rs:33:5 | |
| 15 | | | |
| 16 | LL | become unsized_argument(b); | |
| 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 18 | | | |
| 19 | = note: unsized argument of type `[u8]` | |
| 20 | ||
| 21 | error: unsized arguments cannot be used in a tail call | |
| 22 | --> $DIR/no-unsized-arguments.rs:48:5 | |
| 23 | | | |
| 24 | LL | become unsized_argument(*b); | |
| 25 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 26 | | | |
| 27 | = note: unsized argument of type `[u8]` | |
| 28 | ||
| 29 | error: aborting due to 3 previous errors | |
| 30 | ||
| 31 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time | |
| 2 | --> $DIR/no-unsized-arguments.rs:40:42 | |
| 3 | | | |
| 4 | LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { | |
| 5 | | ^^^^ doesn't have a size known at compile-time | |
| 6 | | | |
| 7 | = help: the trait `Sized` is not implemented for `[u8]` | |
| 8 | help: function arguments must have a statically known size, borrowed slices always have a known size | |
| 9 | | | |
| 10 | LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { | |
| 11 | | + | |
| 12 | ||
| 13 | error: unsized arguments cannot be used in a tail call | |
| 14 | --> $DIR/no-unsized-arguments.rs:33:5 | |
| 15 | | | |
| 16 | LL | become unsized_argument(b); | |
| 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 18 | | | |
| 19 | = note: unsized argument of type `[u8]` | |
| 20 | ||
| 21 | error: unsized arguments cannot be used in a tail call | |
| 22 | --> $DIR/no-unsized-arguments.rs:48:5 | |
| 23 | | | |
| 24 | LL | become unsized_argument(*b); | |
| 25 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 26 | | | |
| 27 | = note: unsized argument of type `[u8]` | |
| 28 | ||
| 29 | error: aborting due to 3 previous errors | |
| 30 | ||
| 31 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/explicit-tail-calls/signature-mismatch.rs+8-4| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | #![expect(incomplete_features)] |
| 2 | #![feature(explicit_tail_calls)] | |
| 2 | #![feature(explicit_tail_calls, rust_tail_cc)] | |
| 3 | 3 | #![feature(c_variadic)] |
| 4 | 4 | |
| 5 | 5 | fn _f0((): ()) { |
| ... | ... | @@ -8,26 +8,30 @@ fn _f0((): ()) { |
| 8 | 8 | |
| 9 | 9 | fn _g0() {} |
| 10 | 10 | |
| 11 | ||
| 12 | 11 | fn _f1() { |
| 13 | 12 | become _g1(()); //~ error: mismatched signatures |
| 14 | 13 | } |
| 15 | 14 | |
| 16 | 15 | fn _g1((): ()) {} |
| 17 | 16 | |
| 18 | ||
| 19 | 17 | extern "C" fn _f2() { |
| 20 | 18 | become _g2(); //~ error: mismatched function ABIs |
| 21 | 19 | } |
| 22 | 20 | |
| 23 | 21 | fn _g2() {} |
| 24 | 22 | |
| 25 | ||
| 26 | 23 | fn _f3() { |
| 27 | 24 | become _g3(); //~ error: mismatched function ABIs |
| 28 | 25 | } |
| 29 | 26 | |
| 30 | 27 | extern "C" fn _g3() {} |
| 31 | 28 | |
| 29 | extern "tail" fn _tailcc() {} | |
| 30 | ||
| 31 | fn _f4() { | |
| 32 | // tailcc does not need the signatures to match, | |
| 33 | // but only tailcc can tail call tailcc. | |
| 34 | become _tailcc(); //~ error: mismatched function ABIs | |
| 35 | } | |
| 32 | 36 | |
| 33 | 37 | fn main() {} |
tests/ui/explicit-tail-calls/signature-mismatch.stderr+13-4| ... | ... | @@ -9,7 +9,7 @@ LL | become _g0(); |
| 9 | 9 | = note: callee signature: `fn()` |
| 10 | 10 | |
| 11 | 11 | error: mismatched signatures |
| 12 | --> $DIR/signature-mismatch.rs:13:5 | |
| 12 | --> $DIR/signature-mismatch.rs:12:5 | |
| 13 | 13 | | |
| 14 | 14 | LL | become _g1(()); |
| 15 | 15 | | ^^^^^^^^^^^^^^ |
| ... | ... | @@ -19,7 +19,7 @@ LL | become _g1(()); |
| 19 | 19 | = note: callee signature: `fn(())` |
| 20 | 20 | |
| 21 | 21 | error: mismatched function ABIs |
| 22 | --> $DIR/signature-mismatch.rs:20:5 | |
| 22 | --> $DIR/signature-mismatch.rs:18:5 | |
| 23 | 23 | | |
| 24 | 24 | LL | become _g2(); |
| 25 | 25 | | ^^^^^^^^^^^^ |
| ... | ... | @@ -28,7 +28,7 @@ LL | become _g2(); |
| 28 | 28 | = note: caller ABI is `"C"`, while callee ABI is `"Rust"` |
| 29 | 29 | |
| 30 | 30 | error: mismatched function ABIs |
| 31 | --> $DIR/signature-mismatch.rs:27:5 | |
| 31 | --> $DIR/signature-mismatch.rs:24:5 | |
| 32 | 32 | | |
| 33 | 33 | LL | become _g3(); |
| 34 | 34 | | ^^^^^^^^^^^^ |
| ... | ... | @@ -36,5 +36,14 @@ LL | become _g3(); |
| 36 | 36 | = note: `become` requires caller and callee to have the same ABI |
| 37 | 37 | = note: caller ABI is `"Rust"`, while callee ABI is `"C"` |
| 38 | 38 | |
| 39 | error: aborting due to 4 previous errors | |
| 39 | error: mismatched function ABIs | |
| 40 | --> $DIR/signature-mismatch.rs:34:5 | |
| 41 | | | |
| 42 | LL | become _tailcc(); | |
| 43 | | ^^^^^^^^^^^^^^^^ | |
| 44 | | | |
| 45 | = note: `become` requires caller and callee to have the same ABI | |
| 46 | = note: caller ABI is `"Rust"`, while callee ABI is `"tail"` | |
| 47 | ||
| 48 | error: aborting due to 5 previous errors | |
| 40 | 49 |
tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs created+49| ... | ... | @@ -0,0 +1,49 @@ |
| 1 | //@ run-pass | |
| 2 | //@ ignore-backends: gcc | |
| 3 | //@ min-llvm-version: 22 | |
| 4 | //@ revisions: x86_64 aarch64 | |
| 5 | // | |
| 6 | // FIXME: enable x86 on LLVM 23. | |
| 7 | //@ [x86_64] only-x86_64 | |
| 8 | //@ [aarch64] only-aarch64 | |
| 9 | #![feature(explicit_tail_calls, rust_tail_cc)] | |
| 10 | ||
| 11 | #[inline(never)] | |
| 12 | pub extern "tail" fn add() -> u64 { | |
| 13 | #[inline(never)] | |
| 14 | extern "tail" fn add(a: u64, b: u64) -> u64 { | |
| 15 | a.wrapping_add(b) | |
| 16 | } | |
| 17 | ||
| 18 | become add(1, 2); | |
| 19 | } | |
| 20 | ||
| 21 | #[inline(never)] | |
| 22 | pub extern "tail" fn pass_struct(a: u64, d: u64) -> u64 { | |
| 23 | #[derive(Clone, Copy)] | |
| 24 | pub struct Large { | |
| 25 | pub a: u64, | |
| 26 | pub b: u64, | |
| 27 | pub c: u64, | |
| 28 | pub d: u64, | |
| 29 | } | |
| 30 | ||
| 31 | #[inline(never)] | |
| 32 | extern "tail" fn add(large: Large) -> u64 { | |
| 33 | let _ = large.b; | |
| 34 | let _ = large.c; | |
| 35 | large.a.wrapping_add(large.d) | |
| 36 | } | |
| 37 | ||
| 38 | let large = Large { a, b: 0xBBBB_BBBB_BBBB_BBBB, c: 0xCCCC_CCCC_CCCC_CCCC, d }; | |
| 39 | become add(large); | |
| 40 | } | |
| 41 | ||
| 42 | fn main() { | |
| 43 | assert_eq!(add(), 3); | |
| 44 | ||
| 45 | // FIXME: LLVM 22 has a bug which makes this miscompile. | |
| 46 | if false { | |
| 47 | assert_eq!(pass_struct(5, 6), 5 + 6); | |
| 48 | } | |
| 49 | } |
tests/ui/higher-ranked/forall-implies-static.rs created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/26217>. | |
| 2 | ||
| 3 | fn foo<T>() where for<'a> T: 'a {} | |
| 4 | ||
| 5 | fn bar<'a>() { | |
| 6 | foo::<&'a i32>(); | |
| 7 | //~^ ERROR lifetime may not live long enough | |
| 8 | } | |
| 9 | ||
| 10 | fn main() { | |
| 11 | bar(); | |
| 12 | } |
tests/ui/higher-ranked/forall-implies-static.stderr created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | error: lifetime may not live long enough | |
| 2 | --> $DIR/forall-implies-static.rs:6:5 | |
| 3 | | | |
| 4 | LL | fn bar<'a>() { | |
| 5 | | -- lifetime `'a` defined here | |
| 6 | LL | foo::<&'a i32>(); | |
| 7 | | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` | |
| 8 | | | |
| 9 | note: due to a current limitation of the type system, this implies a `'static` lifetime | |
| 10 | --> $DIR/forall-implies-static.rs:3:19 | |
| 11 | | | |
| 12 | LL | fn foo<T>() where for<'a> T: 'a {} | |
| 13 | | ^^^^^^^^^^^^^ | |
| 14 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 |
tests/ui/higher-ranked/leak-check/trait-object-assoc-type-bound-unsatisfied.rs created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22872>. | |
| 2 | ||
| 3 | trait Wrap<'b> { | |
| 4 | fn foo(&'b mut self); | |
| 5 | } | |
| 6 | ||
| 7 | struct Wrapper<P>(P); | |
| 8 | ||
| 9 | impl<'b, P> Wrap<'b> for Wrapper<P> | |
| 10 | where P: Process<'b>, | |
| 11 | <P as Process<'b>>::Item: Iterator { | |
| 12 | fn foo(&mut self) {} | |
| 13 | } | |
| 14 | ||
| 15 | ||
| 16 | pub trait Process<'a> { | |
| 17 | type Item; | |
| 18 | fn bar(&'a self); | |
| 19 | } | |
| 20 | ||
| 21 | fn push_process<P>(process: P) where P: Process<'static> { | |
| 22 | let _: Box<dyn for<'b> Wrap<'b>> = Box::new(Wrapper(process)); | |
| 23 | //~^ ERROR is not an iterator | |
| 24 | } | |
| 25 | ||
| 26 | fn main() {} |
tests/ui/higher-ranked/leak-check/trait-object-assoc-type-bound-unsatisfied.stderr created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | error[E0277]: `<P as Process<'_>>::Item` is not an iterator | |
| 2 | --> $DIR/trait-object-assoc-type-bound-unsatisfied.rs:22:40 | |
| 3 | | | |
| 4 | LL | let _: Box<dyn for<'b> Wrap<'b>> = Box::new(Wrapper(process)); | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `<P as Process<'_>>::Item` is not an iterator | |
| 6 | | | |
| 7 | = help: the trait `Iterator` is not implemented for `<P as Process<'_>>::Item` | |
| 8 | note: required for `Wrapper<P>` to implement `for<'b> Wrap<'b>` | |
| 9 | --> $DIR/trait-object-assoc-type-bound-unsatisfied.rs:9:13 | |
| 10 | | | |
| 11 | LL | impl<'b, P> Wrap<'b> for Wrapper<P> | |
| 12 | | ^^^^^^^^ ^^^^^^^^^^ | |
| 13 | LL | where P: Process<'b>, | |
| 14 | LL | <P as Process<'b>>::Item: Iterator { | |
| 15 | | -------- unsatisfied trait bound introduced here | |
| 16 | = note: required for the cast from `Box<Wrapper<P>>` to `Box<dyn for<'b> Wrap<'b>>` | |
| 17 | help: consider further restricting the associated type | |
| 18 | | | |
| 19 | LL | fn push_process<P>(process: P) where P: Process<'static>, <P as Process<'_>>::Item: Iterator { | |
| 20 | | ++++++++++++++++++++++++++++++++++++ | |
| 21 | ||
| 22 | error: aborting due to 1 previous error | |
| 23 | ||
| 24 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/higher-ranked/trait-bounds/infer-assoc-type-projection-type.rs created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/25810>. | |
| 2 | //@ run-pass | |
| 3 | ||
| 4 | fn main() { | |
| 5 | let x = X(15); | |
| 6 | let y = x.foo(); | |
| 7 | println!("{:?}",y); | |
| 8 | } | |
| 9 | ||
| 10 | trait Foo | |
| 11 | where for<'a> &'a Self: Bar | |
| 12 | { | |
| 13 | fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output; | |
| 14 | } | |
| 15 | ||
| 16 | trait Bar { | |
| 17 | type Output; | |
| 18 | } | |
| 19 | ||
| 20 | struct X(i32); | |
| 21 | ||
| 22 | impl<'a> Bar for &'a X { | |
| 23 | type Output = &'a i32; | |
| 24 | } | |
| 25 | ||
| 26 | impl Foo for X { | |
| 27 | fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output { | |
| 28 | &self.0 | |
| 29 | } | |
| 30 | } |
tests/ui/inference/downcast-fn-ptr-placeholder.rs created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/23041>. | |
| 2 | //! Previously ICEd with cat_expr error, fixed by delaying bug. | |
| 3 | ||
| 4 | use std::any::Any; | |
| 5 | fn main() | |
| 6 | { | |
| 7 | fn bar(x:i32) ->i32 { 3*x }; | |
| 8 | let b:Box<dyn Any> = Box::new(bar as fn(_)->_); | |
| 9 | b.downcast_ref::<fn(_)->_>(); //~ ERROR E0282 | |
| 10 | } |
tests/ui/inference/downcast-fn-ptr-placeholder.stderr created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | error[E0282]: type annotations needed | |
| 2 | --> $DIR/downcast-fn-ptr-placeholder.rs:9:22 | |
| 3 | | | |
| 4 | LL | b.downcast_ref::<fn(_)->_>(); | |
| 5 | | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref` | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For more information about this error, try `rustc --explain E0282`. |
tests/ui/issues/issue-2150.rs deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | #![deny(unreachable_code)] | |
| 2 | #![allow(unused_variables)] | |
| 3 | #![allow(dead_code)] | |
| 4 | ||
| 5 | fn fail_len(v: Vec<isize> ) -> usize { | |
| 6 | let mut i = 3; | |
| 7 | panic!(); | |
| 8 | for x in &v { i += 1; } | |
| 9 | //~^ ERROR: unreachable statement | |
| 10 | return i; | |
| 11 | } | |
| 12 | fn main() {} |
tests/ui/issues/issue-2150.stderr deleted-16| ... | ... | @@ -1,16 +0,0 @@ |
| 1 | error: unreachable statement | |
| 2 | --> $DIR/issue-2150.rs:8:5 | |
| 3 | | | |
| 4 | LL | panic!(); | |
| 5 | | -------- any code following this expression is unreachable | |
| 6 | LL | for x in &v { i += 1; } | |
| 7 | | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | |
| 8 | | | |
| 9 | note: the lint level is defined here | |
| 10 | --> $DIR/issue-2150.rs:1:9 | |
| 11 | | | |
| 12 | LL | #![deny(unreachable_code)] | |
| 13 | | ^^^^^^^^^^^^^^^^ | |
| 14 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 |
tests/ui/issues/issue-21546.rs deleted-49| ... | ... | @@ -1,49 +0,0 @@ |
| 1 | // Also works as a test for #14564 | |
| 2 | ||
| 3 | #[allow(non_snake_case)] | |
| 4 | mod Foo { } | |
| 5 | ||
| 6 | #[allow(dead_code)] | |
| 7 | struct Foo; | |
| 8 | //~^ ERROR the name `Foo` is defined multiple times | |
| 9 | ||
| 10 | #[allow(non_snake_case)] | |
| 11 | mod Bar { } | |
| 12 | ||
| 13 | #[allow(dead_code)] | |
| 14 | struct Bar(i32); | |
| 15 | //~^ ERROR the name `Bar` is defined multiple times | |
| 16 | ||
| 17 | ||
| 18 | #[allow(dead_code)] | |
| 19 | struct Baz(i32); | |
| 20 | ||
| 21 | #[allow(non_snake_case)] | |
| 22 | mod Baz { } | |
| 23 | //~^ ERROR the name `Baz` is defined multiple times | |
| 24 | ||
| 25 | ||
| 26 | #[allow(dead_code)] | |
| 27 | struct Qux { x: bool } | |
| 28 | ||
| 29 | #[allow(non_snake_case)] | |
| 30 | mod Qux { } | |
| 31 | //~^ ERROR the name `Qux` is defined multiple times | |
| 32 | ||
| 33 | ||
| 34 | #[allow(dead_code)] | |
| 35 | struct Quux; | |
| 36 | ||
| 37 | #[allow(non_snake_case)] | |
| 38 | mod Quux { } | |
| 39 | //~^ ERROR the name `Quux` is defined multiple times | |
| 40 | ||
| 41 | ||
| 42 | #[allow(dead_code)] | |
| 43 | enum Corge { A, B } | |
| 44 | ||
| 45 | #[allow(non_snake_case)] | |
| 46 | mod Corge { } | |
| 47 | //~^ ERROR the name `Corge` is defined multiple times | |
| 48 | ||
| 49 | fn main() { } |
tests/ui/issues/issue-21546.stderr deleted-69| ... | ... | @@ -1,69 +0,0 @@ |
| 1 | error[E0428]: the name `Foo` is defined multiple times | |
| 2 | --> $DIR/issue-21546.rs:7:1 | |
| 3 | | | |
| 4 | LL | mod Foo { } | |
| 5 | | ------- previous definition of the module `Foo` here | |
| 6 | ... | |
| 7 | LL | struct Foo; | |
| 8 | | ^^^^^^^^^^^ `Foo` redefined here | |
| 9 | | | |
| 10 | = note: `Foo` must be defined only once in the type namespace of this module | |
| 11 | ||
| 12 | error[E0428]: the name `Bar` is defined multiple times | |
| 13 | --> $DIR/issue-21546.rs:14:1 | |
| 14 | | | |
| 15 | LL | mod Bar { } | |
| 16 | | ------- previous definition of the module `Bar` here | |
| 17 | ... | |
| 18 | LL | struct Bar(i32); | |
| 19 | | ^^^^^^^^^^^^^^^^ `Bar` redefined here | |
| 20 | | | |
| 21 | = note: `Bar` must be defined only once in the type namespace of this module | |
| 22 | ||
| 23 | error[E0428]: the name `Baz` is defined multiple times | |
| 24 | --> $DIR/issue-21546.rs:22:1 | |
| 25 | | | |
| 26 | LL | struct Baz(i32); | |
| 27 | | ---------------- previous definition of the type `Baz` here | |
| 28 | ... | |
| 29 | LL | mod Baz { } | |
| 30 | | ^^^^^^^ `Baz` redefined here | |
| 31 | | | |
| 32 | = note: `Baz` must be defined only once in the type namespace of this module | |
| 33 | ||
| 34 | error[E0428]: the name `Qux` is defined multiple times | |
| 35 | --> $DIR/issue-21546.rs:30:1 | |
| 36 | | | |
| 37 | LL | struct Qux { x: bool } | |
| 38 | | ---------- previous definition of the type `Qux` here | |
| 39 | ... | |
| 40 | LL | mod Qux { } | |
| 41 | | ^^^^^^^ `Qux` redefined here | |
| 42 | | | |
| 43 | = note: `Qux` must be defined only once in the type namespace of this module | |
| 44 | ||
| 45 | error[E0428]: the name `Quux` is defined multiple times | |
| 46 | --> $DIR/issue-21546.rs:38:1 | |
| 47 | | | |
| 48 | LL | struct Quux; | |
| 49 | | ------------ previous definition of the type `Quux` here | |
| 50 | ... | |
| 51 | LL | mod Quux { } | |
| 52 | | ^^^^^^^^ `Quux` redefined here | |
| 53 | | | |
| 54 | = note: `Quux` must be defined only once in the type namespace of this module | |
| 55 | ||
| 56 | error[E0428]: the name `Corge` is defined multiple times | |
| 57 | --> $DIR/issue-21546.rs:46:1 | |
| 58 | | | |
| 59 | LL | enum Corge { A, B } | |
| 60 | | ---------- previous definition of the type `Corge` here | |
| 61 | ... | |
| 62 | LL | mod Corge { } | |
| 63 | | ^^^^^^^^^ `Corge` redefined here | |
| 64 | | | |
| 65 | = note: `Corge` must be defined only once in the type namespace of this module | |
| 66 | ||
| 67 | error: aborting due to 6 previous errors | |
| 68 | ||
| 69 | For more information about this error, try `rustc --explain E0428`. |
tests/ui/issues/issue-21622.rs deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | #![allow(dead_code)] | |
| 3 | #![allow(unused_variables)] | |
| 4 | ||
| 5 | struct Index; | |
| 6 | ||
| 7 | impl Index { | |
| 8 | fn new() -> Self { Index } | |
| 9 | } | |
| 10 | ||
| 11 | fn user() { | |
| 12 | let new = Index::new; | |
| 13 | ||
| 14 | fn inner() { | |
| 15 | let index = Index::new(); | |
| 16 | } | |
| 17 | ||
| 18 | let index2 = new(); | |
| 19 | } | |
| 20 | ||
| 21 | fn main() {} |
tests/ui/issues/issue-21634.rs deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | ||
| 3 | #[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))] | |
| 4 | fn main() { | |
| 5 | if let Ok(x) = "3.1415".parse::<f64>() { | |
| 6 | assert_eq!(false, x <= 0.0); | |
| 7 | } | |
| 8 | if let Ok(x) = "3.1415".parse::<f64>() { | |
| 9 | assert_eq!(3.1415, x + 0.0); | |
| 10 | } | |
| 11 | if let Ok(mut x) = "3.1415".parse::<f64>() { | |
| 12 | assert_eq!(8.1415, { x += 5.0; x }); | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] | |
| 17 | fn main() {} |
tests/ui/issues/issue-21701.rs deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | fn foo<U>(t: U) { | |
| 2 | let y = t(); | |
| 3 | //~^ ERROR: expected function, found `U` | |
| 4 | } | |
| 5 | ||
| 6 | struct Bar; | |
| 7 | ||
| 8 | pub fn some_func() { | |
| 9 | let f = Bar(); | |
| 10 | //~^ ERROR: expected function, found struct `Bar` | |
| 11 | } | |
| 12 | ||
| 13 | fn main() { | |
| 14 | foo(|| { 1 }); | |
| 15 | } |
tests/ui/issues/issue-21701.stderr deleted-30| ... | ... | @@ -1,30 +0,0 @@ |
| 1 | error[E0618]: expected function, found `U` | |
| 2 | --> $DIR/issue-21701.rs:2:13 | |
| 3 | | | |
| 4 | LL | fn foo<U>(t: U) { | |
| 5 | | - `t` has type `U` | |
| 6 | LL | let y = t(); | |
| 7 | | ^-- | |
| 8 | | | | |
| 9 | | call expression requires function | |
| 10 | ||
| 11 | error[E0618]: expected function, found struct `Bar` | |
| 12 | --> $DIR/issue-21701.rs:9:13 | |
| 13 | | | |
| 14 | LL | struct Bar; | |
| 15 | | ---------- struct `Bar` defined here | |
| 16 | ... | |
| 17 | LL | let f = Bar(); | |
| 18 | | ^^^-- | |
| 19 | | | | |
| 20 | | call expression requires function | |
| 21 | | | |
| 22 | help: `Bar` is a unit struct, and does not take parentheses to be constructed | |
| 23 | | | |
| 24 | LL - let f = Bar(); | |
| 25 | LL + let f = Bar; | |
| 26 | | | |
| 27 | ||
| 28 | error: aborting due to 2 previous errors | |
| 29 | ||
| 30 | For more information about this error, try `rustc --explain E0618`. |
tests/ui/issues/issue-21763.rs deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | // Regression test for HashMap only impl'ing Send/Sync if its contents do | |
| 2 | ||
| 3 | //@ normalize-stderr: "(?:[A-Za-z]:[/\\]|/).*[\\/]hashbrown\S+" -> "$$HASHBROWN_SRC_LOCATION" | |
| 4 | ||
| 5 | use std::collections::HashMap; | |
| 6 | use std::rc::Rc; | |
| 7 | ||
| 8 | fn foo<T: Send>() {} | |
| 9 | ||
| 10 | fn main() { | |
| 11 | foo::<HashMap<Rc<()>, Rc<()>>>(); | |
| 12 | //~^ ERROR `Rc<()>` cannot be sent between threads safely | |
| 13 | } |
tests/ui/issues/issue-21763.stderr deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | error[E0277]: `Rc<()>` cannot be sent between threads safely | |
| 2 | --> $DIR/issue-21763.rs:11:11 | |
| 3 | | | |
| 4 | LL | foo::<HashMap<Rc<()>, Rc<()>>>(); | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely | |
| 6 | | | |
| 7 | = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>` | |
| 8 | = note: required because it appears within the type `(Rc<()>, Rc<()>)` | |
| 9 | = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send` | |
| 10 | note: required because it appears within the type `hashbrown::map::HashMap<Rc<()>, Rc<()>, RandomState>` | |
| 11 | --> $HASHBROWN_SRC_LOCATION | |
| 12 | note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>` | |
| 13 | --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL | |
| 14 | note: required by a bound in `foo` | |
| 15 | --> $DIR/issue-21763.rs:8:11 | |
| 16 | | | |
| 17 | LL | fn foo<T: Send>() {} | |
| 18 | | ^^^^ required by this bound in `foo` | |
| 19 | ||
| 20 | error: aborting due to 1 previous error | |
| 21 | ||
| 22 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/issues/issue-21922.rs deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | use std::ops::Add; | |
| 3 | fn show(z: i32) { | |
| 4 | println!("{}", z) | |
| 5 | } | |
| 6 | fn main() { | |
| 7 | let x = 23; | |
| 8 | let y = 42; | |
| 9 | show(Add::add( x, y)); | |
| 10 | show(Add::add( x, &y)); | |
| 11 | show(Add::add(&x, y)); | |
| 12 | show(Add::add(&x, &y)); | |
| 13 | show( x + y); | |
| 14 | show( x + &y); | |
| 15 | show(&x + y); | |
| 16 | show(&x + &y); | |
| 17 | } |
tests/ui/issues/issue-21974.rs deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | // Test that (for now) we report an ambiguity error here, because | |
| 2 | // specific trait relationships are ignored for the purposes of trait | |
| 3 | // matching. This behavior should likely be improved such that this | |
| 4 | // test passes. See #21974 for more details. | |
| 5 | ||
| 6 | trait Foo { | |
| 7 | fn foo(self); | |
| 8 | } | |
| 9 | ||
| 10 | fn foo<'a,'b,T>(x: &'a T, y: &'b T) | |
| 11 | where &'a T : Foo, //~ ERROR type annotations needed | |
| 12 | &'b T : Foo | |
| 13 | { | |
| 14 | x.foo(); //~ ERROR type annotations needed | |
| 15 | y.foo(); | |
| 16 | } | |
| 17 | ||
| 18 | fn main() { } |
tests/ui/issues/issue-21974.stderr deleted-31| ... | ... | @@ -1,31 +0,0 @@ |
| 1 | error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo` | |
| 2 | --> $DIR/issue-21974.rs:11:19 | |
| 3 | | | |
| 4 | LL | where &'a T : Foo, | |
| 5 | | ^^^ | |
| 6 | | | |
| 7 | note: multiple `impl`s or `where` clauses satisfying `&'a T: Foo` found | |
| 8 | --> $DIR/issue-21974.rs:11:19 | |
| 9 | | | |
| 10 | LL | where &'a T : Foo, | |
| 11 | | ^^^ | |
| 12 | LL | &'b T : Foo | |
| 13 | | ^^^ | |
| 14 | ||
| 15 | error[E0283]: type annotations needed: cannot satisfy `&T: Foo` | |
| 16 | --> $DIR/issue-21974.rs:14:7 | |
| 17 | | | |
| 18 | LL | x.foo(); | |
| 19 | | ^^^ | |
| 20 | | | |
| 21 | note: multiple `impl`s or `where` clauses satisfying `&T: Foo` found | |
| 22 | --> $DIR/issue-21974.rs:11:19 | |
| 23 | | | |
| 24 | LL | where &'a T : Foo, | |
| 25 | | ^^^ | |
| 26 | LL | &'b T : Foo | |
| 27 | | ^^^ | |
| 28 | ||
| 29 | error: aborting due to 2 previous errors | |
| 30 | ||
| 31 | For more information about this error, try `rustc --explain E0283`. |
tests/ui/issues/issue-22008.rs deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | pub fn main() { | |
| 3 | let command = "a"; | |
| 4 | ||
| 5 | match command { | |
| 6 | "foo" => println!("foo"), | |
| 7 | _ => println!("{}", command), | |
| 8 | } | |
| 9 | } |
tests/ui/issues/issue-22034.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | fn main() { | |
| 2 | let ptr: *mut () = core::ptr::null_mut(); | |
| 3 | let _: &mut dyn Fn() = unsafe { | |
| 4 | &mut *(ptr as *mut dyn Fn()) | |
| 5 | //~^ ERROR expected a `Fn()` closure, found `()` | |
| 6 | }; | |
| 7 | } |
tests/ui/issues/issue-22034.stderr deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | error[E0277]: expected a `Fn()` closure, found `()` | |
| 2 | --> $DIR/issue-22034.rs:4:16 | |
| 3 | | | |
| 4 | LL | &mut *(ptr as *mut dyn Fn()) | |
| 5 | | ^^^ expected an `Fn()` closure, found `()` | |
| 6 | | | |
| 7 | = help: the trait `Fn()` is not implemented for `()` | |
| 8 | = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` | |
| 9 | = note: required for the cast from `*mut ()` to `*mut dyn Fn()` | |
| 10 | ||
| 11 | error: aborting due to 1 previous error | |
| 12 | ||
| 13 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/issues/issue-22036.rs deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | ||
| 3 | trait DigitCollection: Sized { | |
| 4 | type Iter: Iterator<Item = u8>; | |
| 5 | fn digit_iter(self) -> Self::Iter; | |
| 6 | ||
| 7 | fn digit_sum(self) -> u32 { | |
| 8 | self.digit_iter() | |
| 9 | .map(|digit: u8| digit as u32) | |
| 10 | .fold(0, |sum, digit| sum + digit) | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | impl<I> DigitCollection for I where I: Iterator<Item=u8> { | |
| 15 | type Iter = I; | |
| 16 | ||
| 17 | fn digit_iter(self) -> I { | |
| 18 | self | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn main() { | |
| 23 | let xs = vec![1, 2, 3, 4, 5]; | |
| 24 | assert_eq!(xs.into_iter().digit_sum(), 15); | |
| 25 | } |
tests/ui/issues/issue-22258.rs deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | use std::ops::Add; | |
| 3 | ||
| 4 | fn f<T: Add>(a: T, b: T) -> <T as Add>::Output { | |
| 5 | a + b | |
| 6 | } | |
| 7 | ||
| 8 | fn main() { | |
| 9 | println!("a + b is {}", f::<f32>(100f32, 200f32)); | |
| 10 | } |
tests/ui/issues/issue-22356.rs deleted-33| ... | ... | @@ -1,33 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | #![allow(type_alias_bounds)] | |
| 3 | ||
| 4 | ||
| 5 | use std::marker::PhantomData; | |
| 6 | ||
| 7 | pub struct Handle<T, I>(T, I); | |
| 8 | ||
| 9 | impl<T, I> Handle<T, I> { | |
| 10 | pub fn get_info(&self) -> &I { | |
| 11 | let Handle(_, ref info) = *self; | |
| 12 | info | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | pub struct BufferHandle<D: Device, T> { | |
| 17 | raw: RawBufferHandle<D>, | |
| 18 | _marker: PhantomData<T>, | |
| 19 | } | |
| 20 | ||
| 21 | impl<D: Device, T> BufferHandle<D, T> { | |
| 22 | pub fn get_info(&self) -> &String { | |
| 23 | self.raw.get_info() | |
| 24 | } | |
| 25 | } | |
| 26 | ||
| 27 | pub type RawBufferHandle<D: Device> = Handle<<D as Device>::Buffer, String>; | |
| 28 | ||
| 29 | pub trait Device { | |
| 30 | type Buffer; | |
| 31 | } | |
| 32 | ||
| 33 | fn main() {} |
tests/ui/issues/issue-22370.rs deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | trait A<T=Self> {} | |
| 2 | ||
| 3 | fn f(a: &dyn A) {} | |
| 4 | //~^ ERROR E0393 | |
| 5 | ||
| 6 | fn main() {} |
tests/ui/issues/issue-22370.stderr deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | error[E0393]: the type parameter `T` must be explicitly specified | |
| 2 | --> $DIR/issue-22370.rs:3:14 | |
| 3 | | | |
| 4 | LL | trait A<T=Self> {} | |
| 5 | | --------------- type parameter `T` must be specified for this | |
| 6 | LL | | |
| 7 | LL | fn f(a: &dyn A) {} | |
| 8 | | ^ | |
| 9 | | | |
| 10 | = note: because the parameter default references `Self`, the parameter must be specified on the trait object type | |
| 11 | help: explicitly specify the type parameter | |
| 12 | | | |
| 13 | LL | fn f(a: &dyn A</* T */>) {} | |
| 14 | | +++++++++ | |
| 15 | ||
| 16 | error: aborting due to 1 previous error | |
| 17 | ||
| 18 | For more information about this error, try `rustc --explain E0393`. |
tests/ui/issues/issue-22471.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | #![allow(dead_code)] | |
| 3 | #![allow(type_alias_bounds)] | |
| 4 | ||
| 5 | type Foo<T> where T: Copy = Box<T>; | |
| 6 | ||
| 7 | fn main(){} |
tests/ui/issues/issue-22603.rs deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | ||
| 3 | #![feature(unboxed_closures, fn_traits)] | |
| 4 | ||
| 5 | struct Foo; | |
| 6 | ||
| 7 | impl<A> FnOnce<(A,)> for Foo { | |
| 8 | type Output = (); | |
| 9 | extern "rust-call" fn call_once(self, (_,): (A,)) { | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | fn main() { | |
| 14 | println!("{:?}", Foo("bar")); | |
| 15 | } |
tests/ui/issues/issue-22629.rs deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(unused_imports)] | |
| 3 | // Test transitive analysis for associated types. Collected types | |
| 4 | // should be normalized and new obligations generated. | |
| 5 | ||
| 6 | ||
| 7 | use std::borrow::{ToOwned, Cow}; | |
| 8 | ||
| 9 | fn assert_send<T: Send>(_: T) {} | |
| 10 | ||
| 11 | fn main() { | |
| 12 | assert_send(Cow::Borrowed("foo")); | |
| 13 | } |
tests/ui/issues/issue-22638.rs deleted-61| ... | ... | @@ -1,61 +0,0 @@ |
| 1 | //@ build-fail | |
| 2 | ||
| 3 | #![allow(unused)] | |
| 4 | ||
| 5 | #![recursion_limit = "20"] | |
| 6 | #![type_length_limit = "20000000"] | |
| 7 | #![crate_type = "rlib"] | |
| 8 | ||
| 9 | #[derive(Clone)] | |
| 10 | struct A (B); | |
| 11 | ||
| 12 | impl A { | |
| 13 | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 14 | let &A(ref term) = self; | |
| 15 | term.matches(f); | |
| 16 | } | |
| 17 | } | |
| 18 | ||
| 19 | #[derive(Clone)] | |
| 20 | enum B { | |
| 21 | Variant1, | |
| 22 | Variant2(C), | |
| 23 | } | |
| 24 | ||
| 25 | impl B { | |
| 26 | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 27 | match self { | |
| 28 | &B::Variant2(ref factor) => { | |
| 29 | factor.matches(&|| ()) | |
| 30 | } | |
| 31 | _ => unreachable!("") | |
| 32 | } | |
| 33 | } | |
| 34 | } | |
| 35 | ||
| 36 | #[derive(Clone)] | |
| 37 | struct C (D); | |
| 38 | ||
| 39 | impl C { | |
| 40 | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 41 | let &C(ref base) = self; | |
| 42 | base.matches(&|| { | |
| 43 | C(base.clone()).matches(f) | |
| 44 | }) | |
| 45 | } | |
| 46 | } | |
| 47 | ||
| 48 | #[derive(Clone)] | |
| 49 | struct D (Box<A>); | |
| 50 | ||
| 51 | impl D { | |
| 52 | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 53 | let &D(ref a) = self; | |
| 54 | a.matches(f) | |
| 55 | //~^ ERROR reached the recursion limit while instantiating | |
| 56 | } | |
| 57 | } | |
| 58 | ||
| 59 | pub fn matches() { | |
| 60 | A(B::Variant1).matches(&(|| ())) | |
| 61 | } |
tests/ui/issues/issue-22638.stderr deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | error: reached the recursion limit while instantiating `A::matches::<{closure@$DIR/issue-22638.rs:42:23: 42:25}>` | |
| 2 | --> $DIR/issue-22638.rs:54:9 | |
| 3 | | | |
| 4 | LL | a.matches(f) | |
| 5 | | ^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: `A::matches` defined here | |
| 8 | --> $DIR/issue-22638.rs:13:5 | |
| 9 | | | |
| 10 | LL | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | ||
| 13 | error: aborting due to 1 previous error | |
| 14 |
tests/ui/issues/issue-22673.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | ||
| 3 | trait Expr: PartialEq<Self::Item> { | |
| 4 | type Item; | |
| 5 | } | |
| 6 | ||
| 7 | fn main() {} |
tests/ui/issues/issue-22777.rs deleted-47| ... | ... | @@ -1,47 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | // This test is reduced from librustc_ast. It is just checking that we | |
| 3 | // can successfully deal with a "deep" structure, which the drop-check | |
| 4 | // was hitting a recursion limit on at one point. | |
| 5 | ||
| 6 | ||
| 7 | #![allow(non_camel_case_types)] | |
| 8 | ||
| 9 | pub fn noop_fold_impl_item() -> SmallVector<ImplItem> { | |
| 10 | loop { } | |
| 11 | } | |
| 12 | ||
| 13 | pub struct SmallVector<T>(P<T>); | |
| 14 | pub struct ImplItem(P<S01_Method>); | |
| 15 | ||
| 16 | struct P<T>(Box<T>); | |
| 17 | ||
| 18 | struct S01_Method(P<S02_Generics>); | |
| 19 | struct S02_Generics(P<S03_TyParam>); | |
| 20 | struct S03_TyParam(P<S04_TyParamBound>); | |
| 21 | struct S04_TyParamBound(S05_PolyTraitRef); | |
| 22 | struct S05_PolyTraitRef(S06_TraitRef); | |
| 23 | struct S06_TraitRef(S07_Path); | |
| 24 | struct S07_Path(Vec<S08_PathSegment>); | |
| 25 | struct S08_PathSegment(S09_GenericArgs); | |
| 26 | struct S09_GenericArgs(P<S10_ParenthesizedParameterData>); | |
| 27 | struct S10_ParenthesizedParameterData(Option<P<S11_Ty>>); | |
| 28 | struct S11_Ty(P<S12_Expr>); | |
| 29 | struct S12_Expr(P<S13_Block>); | |
| 30 | struct S13_Block(Vec<P<S14_Stmt>>); | |
| 31 | struct S14_Stmt(P<S15_Decl>); | |
| 32 | struct S15_Decl(P<S16_Local>); | |
| 33 | struct S16_Local(P<S17_Pat>); | |
| 34 | struct S17_Pat(P<S18_Mac>); | |
| 35 | struct S18_Mac(Vec<P<S19_TokenTree>>); | |
| 36 | struct S19_TokenTree(P<S20_Token>); | |
| 37 | struct S20_Token(P<S21_Nonterminal>); | |
| 38 | struct S21_Nonterminal(P<S22_Item>); | |
| 39 | struct S22_Item(P<S23_EnumDef>); | |
| 40 | struct S23_EnumDef(Vec<P<S24_Variant>>); | |
| 41 | struct S24_Variant(P<S25_VariantKind>); | |
| 42 | struct S25_VariantKind(P<S26_StructDef>); | |
| 43 | struct S26_StructDef(Vec<P<S27_StructField>>); | |
| 44 | struct S27_StructField(P<S28_StructFieldKind>); | |
| 45 | struct S28_StructFieldKind; | |
| 46 | ||
| 47 | pub fn main() {} |
tests/ui/issues/issue-22781.rs deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | #![allow(unused_variables)] | |
| 3 | use std::collections::HashMap; | |
| 4 | use std::collections::hash_map::Entry::Vacant; | |
| 5 | ||
| 6 | pub fn foo() { | |
| 7 | type F = Box<dyn Fn(&()) + 'static>; | |
| 8 | let mut map: HashMap<(), F> = HashMap::new(); | |
| 9 | let x: &mut F = match map.entry(()) { | |
| 10 | Vacant(_) => unimplemented!(), | |
| 11 | _ => unimplemented!() | |
| 12 | }; | |
| 13 | } | |
| 14 | ||
| 15 | fn main() {} |
tests/ui/issues/issue-22814.rs deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | trait Test {} | |
| 3 | ||
| 4 | macro_rules! test { | |
| 5 | ( $($name:ident)+) => ( | |
| 6 | impl<$($name: Test),+> Test for ($($name,)+) { | |
| 7 | } | |
| 8 | ) | |
| 9 | } | |
| 10 | ||
| 11 | test!(A B C); | |
| 12 | ||
| 13 | fn main() {} |
tests/ui/issues/issue-22872.rs deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | trait Wrap<'b> { | |
| 2 | fn foo(&'b mut self); | |
| 3 | } | |
| 4 | ||
| 5 | struct Wrapper<P>(P); | |
| 6 | ||
| 7 | impl<'b, P> Wrap<'b> for Wrapper<P> | |
| 8 | where P: Process<'b>, | |
| 9 | <P as Process<'b>>::Item: Iterator { | |
| 10 | fn foo(&mut self) {} | |
| 11 | } | |
| 12 | ||
| 13 | ||
| 14 | pub trait Process<'a> { | |
| 15 | type Item; | |
| 16 | fn bar(&'a self); | |
| 17 | } | |
| 18 | ||
| 19 | fn push_process<P>(process: P) where P: Process<'static> { | |
| 20 | let _: Box<dyn for<'b> Wrap<'b>> = Box::new(Wrapper(process)); | |
| 21 | //~^ ERROR is not an iterator | |
| 22 | } | |
| 23 | ||
| 24 | fn main() {} |
tests/ui/issues/issue-22872.stderr deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | error[E0277]: `<P as Process<'_>>::Item` is not an iterator | |
| 2 | --> $DIR/issue-22872.rs:20:40 | |
| 3 | | | |
| 4 | LL | let _: Box<dyn for<'b> Wrap<'b>> = Box::new(Wrapper(process)); | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `<P as Process<'_>>::Item` is not an iterator | |
| 6 | | | |
| 7 | = help: the trait `Iterator` is not implemented for `<P as Process<'_>>::Item` | |
| 8 | note: required for `Wrapper<P>` to implement `for<'b> Wrap<'b>` | |
| 9 | --> $DIR/issue-22872.rs:7:13 | |
| 10 | | | |
| 11 | LL | impl<'b, P> Wrap<'b> for Wrapper<P> | |
| 12 | | ^^^^^^^^ ^^^^^^^^^^ | |
| 13 | LL | where P: Process<'b>, | |
| 14 | LL | <P as Process<'b>>::Item: Iterator { | |
| 15 | | -------- unsatisfied trait bound introduced here | |
| 16 | = note: required for the cast from `Box<Wrapper<P>>` to `Box<dyn for<'b> Wrap<'b>>` | |
| 17 | help: consider further restricting the associated type | |
| 18 | | | |
| 19 | LL | fn push_process<P>(process: P) where P: Process<'static>, <P as Process<'_>>::Item: Iterator { | |
| 20 | | ++++++++++++++++++++++++++++++++++++ | |
| 21 | ||
| 22 | error: aborting due to 1 previous error | |
| 23 | ||
| 24 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/issues/issue-22874.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | struct Table { | |
| 2 | rows: [[String]], | |
| 3 | //~^ ERROR the size for values of type | |
| 4 | } | |
| 5 | ||
| 6 | fn f(table: &Table) -> &[String] { | |
| 7 | &table.rows[0] | |
| 8 | //~^ ERROR the size for values of type | |
| 9 | } | |
| 10 | ||
| 11 | fn main() {} |
tests/ui/issues/issue-22874.stderr deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | error[E0277]: the size for values of type `[String]` cannot be known at compilation time | |
| 2 | --> $DIR/issue-22874.rs:2:11 | |
| 3 | | | |
| 4 | LL | rows: [[String]], | |
| 5 | | ^^^^^^^^^^ doesn't have a size known at compile-time | |
| 6 | | | |
| 7 | = help: the trait `Sized` is not implemented for `[String]` | |
| 8 | = note: slice and array elements must have `Sized` type | |
| 9 | ||
| 10 | error[E0277]: the size for values of type `[String]` cannot be known at compilation time | |
| 11 | --> $DIR/issue-22874.rs:7:6 | |
| 12 | | | |
| 13 | LL | &table.rows[0] | |
| 14 | | ^^^^^^^^^^ doesn't have a size known at compile-time | |
| 15 | | | |
| 16 | = help: the trait `Sized` is not implemented for `[String]` | |
| 17 | = note: required for `[[String]]` to implement `Index<_>` | |
| 18 | ||
| 19 | error: aborting due to 2 previous errors | |
| 20 | ||
| 21 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/issues/issue-22886.rs deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | // Regression test for #22886. | |
| 2 | ||
| 3 | fn crash_please() { | |
| 4 | let mut iter = Newtype(Some(Box::new(0))); | |
| 5 | let saved = iter.next().unwrap(); | |
| 6 | println!("{}", saved); | |
| 7 | iter.0 = None; | |
| 8 | println!("{}", saved); | |
| 9 | } | |
| 10 | ||
| 11 | struct Newtype(Option<Box<usize>>); | |
| 12 | ||
| 13 | impl<'a> Iterator for Newtype { //~ ERROR E0207 | |
| 14 | type Item = &'a Box<usize>; | |
| 15 | ||
| 16 | fn next(&mut self) -> Option<&Box<usize>> { | |
| 17 | self.0.as_ref() | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | fn main() { } |
tests/ui/issues/issue-22886.stderr deleted-16| ... | ... | @@ -1,16 +0,0 @@ |
| 1 | error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates | |
| 2 | --> $DIR/issue-22886.rs:13:6 | |
| 3 | | | |
| 4 | LL | impl<'a> Iterator for Newtype { | |
| 5 | | ^^ unconstrained lifetime parameter | |
| 6 | | | |
| 7 | help: use the lifetime parameter `'a` in the `Newtype` type and use it in the type definition | |
| 8 | | | |
| 9 | LL ~ struct Newtype<'a>(Option<Box<usize>>); | |
| 10 | LL | | |
| 11 | LL ~ impl<'a> Iterator for Newtype<'a> { | |
| 12 | | | |
| 13 | ||
| 14 | error: aborting due to 1 previous error | |
| 15 | ||
| 16 | For more information about this error, try `rustc --explain E0207`. |
tests/ui/issues/issue-23024.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | use std::any::Any; | |
| 2 | ||
| 3 | fn main() | |
| 4 | { | |
| 5 | fn h(x:i32) -> i32 {3*x} | |
| 6 | let mut vfnfer:Vec<Box<dyn Any>> = vec![]; | |
| 7 | vfnfer.push(Box::new(h)); | |
| 8 | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); | |
| 9 | //~^ ERROR the precise format of `Fn`-family traits' | |
| 10 | //~| ERROR missing generics for trait `Fn` | |
| 11 | } |
tests/ui/issues/issue-23024.stderr deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change | |
| 2 | --> $DIR/issue-23024.rs:8:39 | |
| 3 | | | |
| 4 | LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); | |
| 5 | | ^^ help: use parenthetical notation instead: `Fn() -> ()` | |
| 6 | | | |
| 7 | = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information | |
| 8 | = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable | |
| 9 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 10 | ||
| 11 | error[E0107]: missing generics for trait `Fn` | |
| 12 | --> $DIR/issue-23024.rs:8:39 | |
| 13 | | | |
| 14 | LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); | |
| 15 | | ^^ expected 1 generic argument | |
| 16 | | | |
| 17 | help: add missing generic argument | |
| 18 | | | |
| 19 | LL | println!("{:?}",(vfnfer[0] as dyn Fn<Args>)(3)); | |
| 20 | | ++++++ | |
| 21 | ||
| 22 | error: aborting due to 2 previous errors | |
| 23 | ||
| 24 | Some errors have detailed explanations: E0107, E0658. | |
| 25 | For more information about an error, try `rustc --explain E0107`. |
tests/ui/issues/issue-23041.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | use std::any::Any; | |
| 2 | fn main() | |
| 3 | { | |
| 4 | fn bar(x:i32) ->i32 { 3*x }; | |
| 5 | let b:Box<dyn Any> = Box::new(bar as fn(_)->_); | |
| 6 | b.downcast_ref::<fn(_)->_>(); //~ ERROR E0282 | |
| 7 | } |
tests/ui/issues/issue-23041.stderr deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | error[E0282]: type annotations needed | |
| 2 | --> $DIR/issue-23041.rs:6:22 | |
| 3 | | | |
| 4 | LL | b.downcast_ref::<fn(_)->_>(); | |
| 5 | | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref` | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For more information about this error, try `rustc --explain E0282`. |
tests/ui/issues/issue-23261.rs deleted-61| ... | ... | @@ -1,61 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | // Matching on a DST struct should not trigger an LLVM assertion. | |
| 3 | ||
| 4 | struct Foo<T: ?Sized> { | |
| 5 | a: i32, | |
| 6 | inner: T | |
| 7 | } | |
| 8 | ||
| 9 | trait Get { | |
| 10 | fn get(&self) -> i32; | |
| 11 | } | |
| 12 | ||
| 13 | impl Get for i32 { | |
| 14 | fn get(&self) -> i32 { | |
| 15 | *self | |
| 16 | } | |
| 17 | } | |
| 18 | ||
| 19 | fn check_val(val: &Foo<[u8]>) { | |
| 20 | match *val { | |
| 21 | Foo { a, .. } => { | |
| 22 | assert_eq!(a, 32); | |
| 23 | } | |
| 24 | } | |
| 25 | } | |
| 26 | ||
| 27 | fn check_dst_val(val: &Foo<[u8]>) { | |
| 28 | match *val { | |
| 29 | Foo { ref inner, .. } => { | |
| 30 | assert_eq!(inner, [1, 2, 3]); | |
| 31 | } | |
| 32 | } | |
| 33 | } | |
| 34 | ||
| 35 | fn check_both(val: &Foo<[u8]>) { | |
| 36 | match *val { | |
| 37 | Foo { a, ref inner } => { | |
| 38 | assert_eq!(a, 32); | |
| 39 | assert_eq!(inner, [1, 2, 3]); | |
| 40 | } | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | fn check_trait_obj(val: &Foo<dyn Get>) { | |
| 45 | match *val { | |
| 46 | Foo { a, ref inner } => { | |
| 47 | assert_eq!(a, 32); | |
| 48 | assert_eq!(inner.get(), 32); | |
| 49 | } | |
| 50 | } | |
| 51 | } | |
| 52 | ||
| 53 | fn main() { | |
| 54 | let foo: &Foo<[u8]> = &Foo { a: 32, inner: [1, 2, 3] }; | |
| 55 | check_val(foo); | |
| 56 | check_dst_val(foo); | |
| 57 | check_both(foo); | |
| 58 | ||
| 59 | let foo: &Foo<dyn Get> = &Foo { a: 32, inner: 32 }; | |
| 60 | check_trait_obj(foo); | |
| 61 | } |
tests/ui/issues/issue-23311.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | ||
| 3 | // Test that we do not ICE when pattern matching an array against a slice. | |
| 4 | ||
| 5 | fn main() { | |
| 6 | match "foo".as_bytes() { | |
| 7 | b"food" => (), | |
| 8 | &[b'f', ..] => (), | |
| 9 | _ => () | |
| 10 | } | |
| 11 | } |
tests/ui/issues/issue-23354-2.rs deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | //@ run-fail | |
| 2 | //@ error-pattern:panic evaluated | |
| 3 | //@ needs-subprocess | |
| 4 | ||
| 5 | #[allow(unused_variables)] | |
| 6 | fn main() { | |
| 7 | // This used to trigger an LLVM assertion during compilation | |
| 8 | let x = [panic!("panic evaluated"); 2]; | |
| 9 | } |
tests/ui/issues/issue-23354.rs deleted-8| ... | ... | @@ -1,8 +0,0 @@ |
| 1 | //@ run-fail | |
| 2 | //@ error-pattern:panic evaluated | |
| 3 | //@ needs-subprocess | |
| 4 | ||
| 5 | #[allow(unused_variables)] | |
| 6 | fn main() { | |
| 7 | let x = [panic!("panic evaluated"); 0]; | |
| 8 | } |
tests/ui/issues/issue-25343.rs deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #[allow(unused)] | |
| 3 | fn main() { | |
| 4 | || { | |
| 5 | 'label: loop { | |
| 6 | } | |
| 7 | }; | |
| 8 | ||
| 9 | // More cases added from issue 31754 | |
| 10 | ||
| 11 | 'label2: loop { | |
| 12 | break; | |
| 13 | } | |
| 14 | ||
| 15 | let closure = || { | |
| 16 | 'label2: loop {} | |
| 17 | }; | |
| 18 | ||
| 19 | fn inner_fn() { | |
| 20 | 'label2: loop {} | |
| 21 | } | |
| 22 | } |
tests/ui/issues/issue-25497.rs deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #[derive(Clone, Debug, PartialEq)] | |
| 3 | enum Expression { | |
| 4 | Dummy, | |
| 5 | Add(Box<Expression>), | |
| 6 | } | |
| 7 | ||
| 8 | use Expression::*; | |
| 9 | ||
| 10 | fn simplify(exp: Expression) -> Expression { | |
| 11 | match exp { | |
| 12 | Add(n) => *n.clone(), | |
| 13 | _ => Dummy | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | fn main() { | |
| 18 | assert_eq!(simplify(Add(Box::new(Dummy))), Dummy); | |
| 19 | } |
tests/ui/issues/issue-25515.rs deleted-20| ... | ... | @@ -1,20 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | use std::rc::Rc; | |
| 3 | ||
| 4 | struct Foo<'r>(&'r mut i32); | |
| 5 | ||
| 6 | impl<'r> Drop for Foo<'r> { | |
| 7 | fn drop(&mut self) { | |
| 8 | *self.0 += 1; | |
| 9 | } | |
| 10 | } | |
| 11 | ||
| 12 | fn main() { | |
| 13 | let mut drops = 0; | |
| 14 | ||
| 15 | { | |
| 16 | let _: Rc<dyn Send> = Rc::new(Foo(&mut drops)); | |
| 17 | } | |
| 18 | ||
| 19 | assert_eq!(1, drops); | |
| 20 | } |
tests/ui/issues/issue-25810.rs deleted-28| ... | ... | @@ -1,28 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | fn main() { | |
| 3 | let x = X(15); | |
| 4 | let y = x.foo(); | |
| 5 | println!("{:?}",y); | |
| 6 | } | |
| 7 | ||
| 8 | trait Foo | |
| 9 | where for<'a> &'a Self: Bar | |
| 10 | { | |
| 11 | fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output; | |
| 12 | } | |
| 13 | ||
| 14 | trait Bar { | |
| 15 | type Output; | |
| 16 | } | |
| 17 | ||
| 18 | struct X(i32); | |
| 19 | ||
| 20 | impl<'a> Bar for &'a X { | |
| 21 | type Output = &'a i32; | |
| 22 | } | |
| 23 | ||
| 24 | impl Foo for X { | |
| 25 | fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output { | |
| 26 | &self.0 | |
| 27 | } | |
| 28 | } |
tests/ui/issues/issue-2590.rs deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | struct Parser { | |
| 2 | tokens: Vec<isize> , | |
| 3 | } | |
| 4 | ||
| 5 | trait Parse { | |
| 6 | fn parse(&self) -> Vec<isize> ; | |
| 7 | } | |
| 8 | ||
| 9 | impl Parse for Parser { | |
| 10 | fn parse(&self) -> Vec<isize> { | |
| 11 | self.tokens //~ ERROR cannot move out | |
| 12 | } | |
| 13 | } | |
| 14 | ||
| 15 | fn main() {} |
tests/ui/issues/issue-2590.stderr deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | error[E0507]: cannot move out of `self.tokens` which is behind a shared reference | |
| 2 | --> $DIR/issue-2590.rs:11:9 | |
| 3 | | | |
| 4 | LL | self.tokens | |
| 5 | | ^^^^^^^^^^^ move occurs because `self.tokens` has type `Vec<isize>`, which does not implement the `Copy` trait | |
| 6 | | | |
| 7 | help: consider cloning the value if the performance cost is acceptable | |
| 8 | | | |
| 9 | LL | self.tokens.clone() | |
| 10 | | ++++++++ | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 | ||
| 14 | For more information about this error, try `rustc --explain E0507`. |
tests/ui/issues/issue-26056.rs deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | trait MapLookup<Q> { | |
| 2 | type MapValue; | |
| 3 | } | |
| 4 | ||
| 5 | impl<K> MapLookup<K> for K { | |
| 6 | type MapValue = K; | |
| 7 | } | |
| 8 | ||
| 9 | trait Map: MapLookup<<Self as Map>::Key> { | |
| 10 | type Key; | |
| 11 | } | |
| 12 | ||
| 13 | impl<K> Map for K { | |
| 14 | type Key = K; | |
| 15 | } | |
| 16 | ||
| 17 | ||
| 18 | fn main() { | |
| 19 | let _ = &() | |
| 20 | as &dyn Map<Key=u32,MapValue=u32>; | |
| 21 | //~^ ERROR E0038 | |
| 22 | } |
tests/ui/issues/issue-26056.stderr deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | error[E0038]: the trait `Map` is not dyn compatible | |
| 2 | --> $DIR/issue-26056.rs:20:17 | |
| 3 | | | |
| 4 | LL | as &dyn Map<Key=u32,MapValue=u32>; | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` is not dyn compatible | |
| 6 | | | |
| 7 | note: for a trait to be dyn compatible it needs to allow building a vtable | |
| 8 | for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> | |
| 9 | --> $DIR/issue-26056.rs:9:12 | |
| 10 | | | |
| 11 | LL | trait Map: MapLookup<<Self as Map>::Key> { | |
| 12 | | --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter | |
| 13 | | | | |
| 14 | | this trait is not dyn compatible... | |
| 15 | ||
| 16 | error: aborting due to 1 previous error | |
| 17 | ||
| 18 | For more information about this error, try `rustc --explain E0038`. |
tests/ui/issues/issue-26217.rs deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | fn foo<T>() where for<'a> T: 'a {} | |
| 2 | ||
| 3 | fn bar<'a>() { | |
| 4 | foo::<&'a i32>(); | |
| 5 | //~^ ERROR lifetime may not live long enough | |
| 6 | } | |
| 7 | ||
| 8 | fn main() { | |
| 9 | bar(); | |
| 10 | } |
tests/ui/issues/issue-26217.stderr deleted-16| ... | ... | @@ -1,16 +0,0 @@ |
| 1 | error: lifetime may not live long enough | |
| 2 | --> $DIR/issue-26217.rs:4:5 | |
| 3 | | | |
| 4 | LL | fn bar<'a>() { | |
| 5 | | -- lifetime `'a` defined here | |
| 6 | LL | foo::<&'a i32>(); | |
| 7 | | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` | |
| 8 | | | |
| 9 | note: due to a current limitation of the type system, this implies a `'static` lifetime | |
| 10 | --> $DIR/issue-26217.rs:1:19 | |
| 11 | | | |
| 12 | LL | fn foo<T>() where for<'a> T: 'a {} | |
| 13 | | ^^^^^^^^^^^^^ | |
| 14 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 |
tests/ui/issues/issue-26237.rs deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | macro_rules! macro_panic { | |
| 2 | ($not_a_function:expr, $some_argument:ident) => { | |
| 3 | $not_a_function($some_argument) | |
| 4 | } | |
| 5 | } | |
| 6 | ||
| 7 | fn main() { | |
| 8 | let mut value_a = 0; | |
| 9 | let mut value_b = 0; | |
| 10 | macro_panic!(value_a, value_b); | |
| 11 | //~^ ERROR expected function, found `{integer}` | |
| 12 | } |
tests/ui/issues/issue-26237.stderr deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | error[E0618]: expected function, found `{integer}` | |
| 2 | --> $DIR/issue-26237.rs:10:18 | |
| 3 | | | |
| 4 | LL | $not_a_function($some_argument) | |
| 5 | | ------------------------------- call expression requires function | |
| 6 | ... | |
| 7 | LL | let mut value_a = 0; | |
| 8 | | ----------- `value_a` has type `{integer}` | |
| 9 | LL | let mut value_b = 0; | |
| 10 | LL | macro_panic!(value_a, value_b); | |
| 11 | | ^^^^^^^ | |
| 12 | ||
| 13 | error: aborting due to 1 previous error | |
| 14 | ||
| 15 | For more information about this error, try `rustc --explain E0618`. |
tests/ui/issues/issue-26468.rs deleted-29| ... | ... | @@ -1,29 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(dead_code)] | |
| 3 | ||
| 4 | enum FooMode { | |
| 5 | Check = 0x1001, | |
| 6 | } | |
| 7 | ||
| 8 | enum BarMode { | |
| 9 | Check = 0x2001, | |
| 10 | } | |
| 11 | ||
| 12 | enum Mode { | |
| 13 | Foo(FooMode), | |
| 14 | Bar(BarMode), | |
| 15 | } | |
| 16 | ||
| 17 | #[inline(never)] | |
| 18 | fn broken(mode: &Mode) -> u32 { | |
| 19 | for _ in 0..1 { | |
| 20 | if let Mode::Foo(FooMode::Check) = *mode { return 17 } | |
| 21 | if let Mode::Bar(BarMode::Check) = *mode { return 19 } | |
| 22 | } | |
| 23 | return 42; | |
| 24 | } | |
| 25 | ||
| 26 | fn main() { | |
| 27 | let mode = Mode::Bar(BarMode::Check); | |
| 28 | assert_eq!(broken(&mode), 19); | |
| 29 | } |
tests/ui/issues/issue-27340.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | struct Foo; | |
| 2 | #[derive(Copy, Clone)] | |
| 3 | struct Bar(Foo); | |
| 4 | //~^ ERROR: the trait `Copy` cannot be implemented for this type | |
| 5 | //~| ERROR: `Foo: Clone` is not satisfied | |
| 6 | ||
| 7 | fn main() {} |
tests/ui/issues/issue-27340.stderr deleted-28| ... | ... | @@ -1,28 +0,0 @@ |
| 1 | error[E0204]: the trait `Copy` cannot be implemented for this type | |
| 2 | --> $DIR/issue-27340.rs:3:8 | |
| 3 | | | |
| 4 | LL | #[derive(Copy, Clone)] | |
| 5 | | ---- in this derive macro expansion | |
| 6 | LL | struct Bar(Foo); | |
| 7 | | ^^^ --- this field does not implement `Copy` | |
| 8 | ||
| 9 | error[E0277]: the trait bound `Foo: Clone` is not satisfied | |
| 10 | --> $DIR/issue-27340.rs:3:12 | |
| 11 | | | |
| 12 | LL | #[derive(Copy, Clone)] | |
| 13 | | ----- in this derive macro expansion | |
| 14 | LL | struct Bar(Foo); | |
| 15 | | ^^^ the trait `Clone` is not implemented for `Foo` | |
| 16 | | | |
| 17 | note: required by a bound in `std::clone::AssertParamIsClone` | |
| 18 | --> $SRC_DIR/core/src/clone.rs:LL:COL | |
| 19 | help: consider annotating `Foo` with `#[derive(Clone)]` | |
| 20 | | | |
| 21 | LL + #[derive(Clone)] | |
| 22 | LL | struct Foo; | |
| 23 | | | |
| 24 | ||
| 25 | error: aborting due to 2 previous errors | |
| 26 | ||
| 27 | Some errors have detailed explanations: E0204, E0277. | |
| 28 | For more information about an error, try `rustc --explain E0204`. |
tests/ui/issues/issue-28561.rs deleted-74| ... | ... | @@ -1,74 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Clone, Copy)] | |
| 3 | struct Array<T> { | |
| 4 | f00: [T; 00], | |
| 5 | f01: [T; 01], | |
| 6 | f02: [T; 02], | |
| 7 | f03: [T; 03], | |
| 8 | f04: [T; 04], | |
| 9 | f05: [T; 05], | |
| 10 | f06: [T; 06], | |
| 11 | f07: [T; 07], | |
| 12 | f08: [T; 08], | |
| 13 | f09: [T; 09], | |
| 14 | f10: [T; 10], | |
| 15 | f11: [T; 11], | |
| 16 | f12: [T; 12], | |
| 17 | f13: [T; 13], | |
| 18 | f14: [T; 14], | |
| 19 | f15: [T; 15], | |
| 20 | f16: [T; 16], | |
| 21 | f17: [T; 17], | |
| 22 | f18: [T; 18], | |
| 23 | f19: [T; 19], | |
| 24 | f20: [T; 20], | |
| 25 | f21: [T; 21], | |
| 26 | f22: [T; 22], | |
| 27 | f23: [T; 23], | |
| 28 | f24: [T; 24], | |
| 29 | f25: [T; 25], | |
| 30 | f26: [T; 26], | |
| 31 | f27: [T; 27], | |
| 32 | f28: [T; 28], | |
| 33 | f29: [T; 29], | |
| 34 | f30: [T; 30], | |
| 35 | f31: [T; 31], | |
| 36 | f32: [T; 32], | |
| 37 | } | |
| 38 | ||
| 39 | #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] | |
| 40 | #[allow(unpredictable_function_pointer_comparisons)] | |
| 41 | struct Fn<A, B, C, D, E, F, G, H, I, J, K, L> { | |
| 42 | f00: fn(), | |
| 43 | f01: fn(A), | |
| 44 | f02: fn(A, B), | |
| 45 | f03: fn(A, B, C), | |
| 46 | f04: fn(A, B, C, D), | |
| 47 | f05: fn(A, B, C, D, E), | |
| 48 | f06: fn(A, B, C, D, E, F), | |
| 49 | f07: fn(A, B, C, D, E, F, G), | |
| 50 | f08: fn(A, B, C, D, E, F, G, H), | |
| 51 | f09: fn(A, B, C, D, E, F, G, H, I), | |
| 52 | f10: fn(A, B, C, D, E, F, G, H, I, J), | |
| 53 | f11: fn(A, B, C, D, E, F, G, H, I, J, K), | |
| 54 | f12: fn(A, B, C, D, E, F, G, H, I, J, K, L), | |
| 55 | } | |
| 56 | ||
| 57 | #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] | |
| 58 | struct Tuple<A, B, C, D, E, F, G, H, I, J, K, L> { | |
| 59 | f00: (), | |
| 60 | f01: (A), | |
| 61 | f02: (A, B), | |
| 62 | f03: (A, B, C), | |
| 63 | f04: (A, B, C, D), | |
| 64 | f05: (A, B, C, D, E), | |
| 65 | f06: (A, B, C, D, E, F), | |
| 66 | f07: (A, B, C, D, E, F, G), | |
| 67 | f08: (A, B, C, D, E, F, G, H), | |
| 68 | f09: (A, B, C, D, E, F, G, H, I), | |
| 69 | f10: (A, B, C, D, E, F, G, H, I, J), | |
| 70 | f11: (A, B, C, D, E, F, G, H, I, J, K), | |
| 71 | f12: (A, B, C, D, E, F, G, H, I, J, K, L), | |
| 72 | } | |
| 73 | ||
| 74 | fn main() {} |
tests/ui/issues/issue-32292.rs deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![deny(warnings)] | |
| 3 | ||
| 4 | #[derive(Hash, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Copy)] | |
| 5 | struct Foo; | |
| 6 | ||
| 7 | fn main() { | |
| 8 | let _ = Foo; | |
| 9 | } |
tests/ui/issues/issue-32324.rs deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | #![allow(dead_code)] | |
| 3 | ||
| 4 | trait Resources { | |
| 5 | type Buffer: Copy; | |
| 6 | } | |
| 7 | ||
| 8 | #[derive(Copy, Clone)] | |
| 9 | struct ConstantBufferSet<R: Resources>( | |
| 10 | pub R::Buffer | |
| 11 | ); | |
| 12 | ||
| 13 | #[derive(Copy, Clone)] | |
| 14 | enum It {} | |
| 15 | impl Resources for It { | |
| 16 | type Buffer = u8; | |
| 17 | } | |
| 18 | ||
| 19 | #[derive(Copy, Clone)] | |
| 20 | enum Command { | |
| 21 | BindConstantBuffers(ConstantBufferSet<It>) | |
| 22 | } | |
| 23 | ||
| 24 | fn main() {} |
tests/ui/issues/issue-33571.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | #[derive(Clone, | |
| 2 | Sync, //~ ERROR cannot find derive macro `Sync` in this scope | |
| 3 | //~| ERROR cannot find derive macro `Sync` in this scope | |
| 4 | Copy)] | |
| 5 | enum Foo {} | |
| 6 | ||
| 7 | fn main() {} |
tests/ui/issues/issue-33571.stderr deleted-27| ... | ... | @@ -1,27 +0,0 @@ |
| 1 | error: cannot find derive macro `Sync` in this scope | |
| 2 | --> $DIR/issue-33571.rs:2:10 | |
| 3 | | | |
| 4 | LL | Sync, | |
| 5 | | ^^^^ | |
| 6 | | | |
| 7 | note: unsafe traits like `Sync` should be implemented explicitly | |
| 8 | --> $DIR/issue-33571.rs:2:10 | |
| 9 | | | |
| 10 | LL | Sync, | |
| 11 | | ^^^^ | |
| 12 | ||
| 13 | error: cannot find derive macro `Sync` in this scope | |
| 14 | --> $DIR/issue-33571.rs:2:10 | |
| 15 | | | |
| 16 | LL | Sync, | |
| 17 | | ^^^^ | |
| 18 | | | |
| 19 | note: unsafe traits like `Sync` should be implemented explicitly | |
| 20 | --> $DIR/issue-33571.rs:2:10 | |
| 21 | | | |
| 22 | LL | Sync, | |
| 23 | | ^^^^ | |
| 24 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 25 | ||
| 26 | error: aborting due to 2 previous errors | |
| 27 |
tests/ui/issues/issue-46101.rs deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | trait Foo {} | |
| 2 | #[derive(Foo::Anything)] //~ ERROR cannot find | |
| 3 | //~| ERROR cannot find | |
| 4 | struct S; | |
| 5 | ||
| 6 | fn main() {} |
tests/ui/issues/issue-46101.stderr deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | error[E0433]: cannot find derive macro `Anything` in trait `Foo` | |
| 2 | --> $DIR/issue-46101.rs:2:10 | |
| 3 | | | |
| 4 | LL | #[derive(Foo::Anything)] | |
| 5 | | ^^^^^^^^^^^^^ a derive macro can't exist within a trait | |
| 6 | ||
| 7 | error[E0433]: cannot find derive macro `Anything` in trait `Foo` | |
| 8 | --> $DIR/issue-46101.rs:2:10 | |
| 9 | | | |
| 10 | LL | #[derive(Foo::Anything)] | |
| 11 | | ^^^^^^^^^^^^^ a derive macro can't exist within a trait | |
| 12 | | | |
| 13 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 14 | ||
| 15 | error: aborting due to 2 previous errors | |
| 16 | ||
| 17 | For more information about this error, try `rustc --explain E0433`. |
tests/ui/label/label-in-closure-no-self-shadow.rs created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/25343>. | |
| 2 | //! Ensure we're not wrongly producing shadowing label warning. | |
| 3 | //! More cases added from issue <https://github.com/rust-lang/rust/issues/31754>. | |
| 4 | //@ run-pass | |
| 5 | ||
| 6 | #[allow(unused)] | |
| 7 | fn main() { | |
| 8 | || { | |
| 9 | 'label: loop { | |
| 10 | } | |
| 11 | }; | |
| 12 | ||
| 13 | 'label2: loop { | |
| 14 | break; | |
| 15 | } | |
| 16 | ||
| 17 | let closure = || { | |
| 18 | 'label2: loop {} | |
| 19 | }; | |
| 20 | ||
| 21 | fn inner_fn() { | |
| 22 | 'label2: loop {} | |
| 23 | } | |
| 24 | } |
tests/ui/macros/format-foreign-dollar-without-spec.stderr+6-7| ... | ... | @@ -2,15 +2,14 @@ error: argument never used |
| 2 | 2 | --> $DIR/format-foreign-dollar-without-spec.rs:3:25 |
| 3 | 3 | | |
| 4 | 4 | LL | println!("%65536$", 1); |
| 5 | | ^ argument never used | |
| 5 | | --------- ^ argument never used | |
| 6 | | | | |
| 7 | | formatting specifier missing | |
| 6 | 8 | | |
| 7 | note: format specifiers use curly braces, and the conversion specifier ` | |
| 8 | ` is unknown or unsupported | |
| 9 | --> $DIR/format-foreign-dollar-without-spec.rs:3:15 | |
| 9 | help: format specifiers use curly braces, consider adding a format specifier | |
| 10 | 10 | | |
| 11 | LL | println!("%65536$", 1); | |
| 12 | | ^^^^^^^^ | |
| 13 | = note: printf formatting is not supported; see the documentation for `std::fmt` | |
| 11 | LL | println!("%65536${}", 1); | |
| 12 | | ++ | |
| 14 | 13 | |
| 15 | 14 | error: aborting due to 1 previous error |
| 16 | 15 |
tests/ui/macros/issue-92267.stderr+6-7| ... | ... | @@ -2,15 +2,14 @@ error: argument never used |
| 2 | 2 | --> $DIR/issue-92267.rs:3:34 |
| 3 | 3 | | |
| 4 | 4 | LL | pub fn main() { println!("🦀%%%", 0) } |
| 5 | | ^ argument never used | |
| 5 | | ------- ^ argument never used | |
| 6 | | | | |
| 7 | | formatting specifier missing | |
| 6 | 8 | | |
| 7 | note: format specifiers use curly braces, and the conversion specifier ` | |
| 8 | ` is unknown or unsupported | |
| 9 | --> $DIR/issue-92267.rs:3:30 | |
| 9 | help: format specifiers use curly braces, consider adding a format specifier | |
| 10 | 10 | | |
| 11 | LL | pub fn main() { println!("🦀%%%", 0) } | |
| 12 | | ^^ | |
| 13 | = note: printf formatting is not supported; see the documentation for `std::fmt` | |
| 11 | LL | pub fn main() { println!("🦀%%%{}", 0) } | |
| 12 | | ++ | |
| 14 | 13 | |
| 15 | 14 | error: aborting due to 1 previous error |
| 16 | 15 |
tests/ui/macros/non-function-call-in-macro.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/26237>. | |
| 2 | ||
| 3 | macro_rules! macro_panic { | |
| 4 | ($not_a_function:expr, $some_argument:ident) => { | |
| 5 | $not_a_function($some_argument) | |
| 6 | } | |
| 7 | } | |
| 8 | ||
| 9 | fn main() { | |
| 10 | let mut value_a = 0; | |
| 11 | let mut value_b = 0; | |
| 12 | macro_panic!(value_a, value_b); | |
| 13 | //~^ ERROR expected function, found `{integer}` | |
| 14 | } |
tests/ui/macros/non-function-call-in-macro.stderr created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | error[E0618]: expected function, found `{integer}` | |
| 2 | --> $DIR/non-function-call-in-macro.rs:12:18 | |
| 3 | | | |
| 4 | LL | $not_a_function($some_argument) | |
| 5 | | ------------------------------- call expression requires function | |
| 6 | ... | |
| 7 | LL | let mut value_a = 0; | |
| 8 | | ----------- `value_a` has type `{integer}` | |
| 9 | LL | let mut value_b = 0; | |
| 10 | LL | macro_panic!(value_a, value_b); | |
| 11 | | ^^^^^^^ | |
| 12 | ||
| 13 | error: aborting due to 1 previous error | |
| 14 | ||
| 15 | For more information about this error, try `rustc --explain E0618`. |
tests/ui/macros/trailing-percent-format-hint-issue-158216.rs created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | //@ check-fail | |
| 2 | //@ compile-flags: --crate-type=lib | |
| 3 | ||
| 4 | pub fn f(x: f64) { | |
| 5 | println!("{x:>8.2}%", "foo"); | |
| 6 | //~^ ERROR argument never used | |
| 7 | } |
tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | error: argument never used | |
| 2 | --> $DIR/trailing-percent-format-hint-issue-158216.rs:5:27 | |
| 3 | | | |
| 4 | LL | println!("{x:>8.2}%", "foo"); | |
| 5 | | ----------- ^^^^^ argument never used | |
| 6 | | | | |
| 7 | | formatting specifier missing | |
| 8 | | | |
| 9 | help: format specifiers use curly braces, consider adding a format specifier | |
| 10 | | | |
| 11 | LL | println!("{x:>8.2}%{}", "foo"); | |
| 12 | | ++ | |
| 13 | ||
| 14 | error: aborting due to 1 previous error | |
| 15 |
tests/ui/macros/trait-bound-not-parsed-as-matcher.rs created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22814>. | |
| 2 | ||
| 3 | //@ check-pass | |
| 4 | trait Test {} | |
| 5 | ||
| 6 | macro_rules! test { | |
| 7 | ( $($name:ident)+) => ( | |
| 8 | impl<$($name: Test),+> Test for ($($name,)+) { | |
| 9 | } | |
| 10 | ) | |
| 11 | } | |
| 12 | ||
| 13 | test!(A B C); | |
| 14 | ||
| 15 | fn main() {} |
tests/ui/match/match-str-proper-optimization.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22008>. | |
| 2 | //! Ensure matching against `str` doesn't cause segfault when compiled | |
| 3 | //! with `opt-level` >= 2. | |
| 4 | // | |
| 5 | //@ compile-flags: -C opt-level=2 | |
| 6 | //@ run-pass | |
| 7 | pub fn main() { | |
| 8 | let command = "a"; | |
| 9 | ||
| 10 | match command { | |
| 11 | "foo" => println!("foo"), | |
| 12 | _ => println!("{}", command), | |
| 13 | } | |
| 14 | } |
tests/ui/methods/nested-fn-call-shadowed-assoc-fn-variable.rs created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/21622>. | |
| 2 | ||
| 3 | //@ check-pass | |
| 4 | #![allow(dead_code)] | |
| 5 | #![allow(unused_variables)] | |
| 6 | ||
| 7 | struct Index; | |
| 8 | ||
| 9 | impl Index { | |
| 10 | fn new() -> Self { Index } | |
| 11 | } | |
| 12 | ||
| 13 | fn user() { | |
| 14 | let new = Index::new; | |
| 15 | ||
| 16 | fn inner() { | |
| 17 | let index = Index::new(); | |
| 18 | } | |
| 19 | ||
| 20 | let index2 = new(); | |
| 21 | } | |
| 22 | ||
| 23 | fn main() {} |
tests/ui/moves/move-field-out-of-shared-self.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/2590>. | |
| 2 | ||
| 3 | struct Parser { | |
| 4 | tokens: Vec<isize> , | |
| 5 | } | |
| 6 | ||
| 7 | trait Parse { | |
| 8 | fn parse(&self) -> Vec<isize> ; | |
| 9 | } | |
| 10 | ||
| 11 | impl Parse for Parser { | |
| 12 | fn parse(&self) -> Vec<isize> { | |
| 13 | self.tokens //~ ERROR cannot move out | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | fn main() {} |
tests/ui/moves/move-field-out-of-shared-self.stderr created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | error[E0507]: cannot move out of `self.tokens` which is behind a shared reference | |
| 2 | --> $DIR/move-field-out-of-shared-self.rs:13:9 | |
| 3 | | | |
| 4 | LL | self.tokens | |
| 5 | | ^^^^^^^^^^^ move occurs because `self.tokens` has type `Vec<isize>`, which does not implement the `Copy` trait | |
| 6 | | | |
| 7 | help: consider cloning the value if the performance cost is acceptable | |
| 8 | | | |
| 9 | LL | self.tokens.clone() | |
| 10 | | ++++++++ | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 | ||
| 14 | For more information about this error, try `rustc --explain E0507`. |
tests/ui/panic-handler/panic-handler-wrong-location.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | #![no_std] |
| 4 | 4 | #![no_main] |
| 5 | 5 | |
| 6 | #[panic_handler] //~ ERROR `panic_impl` lang item must be applied to a function | |
| 6 | #[panic_handler] //~ ERROR attribute cannot be used on statics | |
| 7 | 7 | static X: u32 = 42; |
| 8 | 8 | |
| 9 | 9 | //~? ERROR `#[panic_handler]` function required, but not found |
tests/ui/panic-handler/panic-handler-wrong-location.stderr+6-5| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | error[E0718]: `panic_impl` lang item must be applied to a function | |
| 1 | error: `#[panic_handler]` function required, but not found | |
| 2 | ||
| 3 | error: `#[panic_handler]` attribute cannot be used on statics | |
| 2 | 4 | --> $DIR/panic-handler-wrong-location.rs:6:1 |
| 3 | 5 | | |
| 4 | 6 | LL | #[panic_handler] |
| 5 | | ^^^^^^^^^^^^^^^^ attribute should be applied to a function, not a static | |
| 6 | ||
| 7 | error: `#[panic_handler]` function required, but not found | |
| 7 | | ^^^^^^^^^^^^^^^^ | |
| 8 | | | |
| 9 | = help: `#[panic_handler]` can only be applied to functions | |
| 8 | 10 | |
| 9 | 11 | error: aborting due to 2 previous errors |
| 10 | 12 | |
| 11 | For more information about this error, try `rustc --explain E0718`. |
tests/ui/pattern/match-array-against-slice.rs created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/23311>. | |
| 2 | //! Test that we do not ICE when pattern matching an array against a slice. | |
| 3 | //@ run-pass | |
| 4 | ||
| 5 | fn main() { | |
| 6 | match "foo".as_bytes() { | |
| 7 | b"food" => (), | |
| 8 | &[b'f', ..] => (), | |
| 9 | _ => () | |
| 10 | } | |
| 11 | } |
tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs+27-6| ... | ... | @@ -15,26 +15,38 @@ enum Mode { |
| 15 | 15 | OtherWithPanic, |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | fn print_unspanned<T>(s: &str) -> Result<T, LexError> | |
| 19 | where | |
| 20 | T: FromStr<Err = LexError> + Debug, | |
| 21 | { | |
| 22 | let t = T::from_str(s); | |
| 23 | let mut s = format!("{t:?}"); | |
| 24 | while let Some((l, r)) = s.split_once("span: #") { | |
| 25 | let (_, r) = r.split_once(")").unwrap(); | |
| 26 | s = format!("{l}span: Span{r}"); | |
| 27 | } | |
| 28 | println!("{s}"); | |
| 29 | t | |
| 30 | } | |
| 31 | ||
| 18 | 32 | fn parse<T>(s: &str, mode: Mode) |
| 19 | 33 | where |
| 20 | 34 | T: FromStr<Err = LexError> + Debug, |
| 21 | 35 | { |
| 22 | 36 | match mode { |
| 23 | 37 | NormalOk => { |
| 24 | let t = T::from_str(s); | |
| 25 | println!("{:?}", t); | |
| 38 | let t = print_unspanned::<T>(s); | |
| 26 | 39 | assert!(t.is_ok()); |
| 27 | 40 | } |
| 28 | 41 | NormalErr => { |
| 29 | let t = T::from_str(s); | |
| 30 | println!("{:?}", t); | |
| 42 | let t = print_unspanned::<T>(s); | |
| 31 | 43 | assert!(t.is_err()); |
| 32 | 44 | } |
| 33 | 45 | OtherError => { |
| 34 | println!("{:?}", T::from_str(s)); | |
| 46 | print_unspanned::<T>(s); | |
| 35 | 47 | } |
| 36 | 48 | OtherWithPanic => { |
| 37 | if catch_unwind(|| println!("{:?}", T::from_str(s))).is_ok() { | |
| 49 | if catch_unwind(|| print_unspanned::<T>(s)).is_ok() { | |
| 38 | 50 | eprintln!("{s} did not panic"); |
| 39 | 51 | } |
| 40 | 52 | } |
| ... | ... | @@ -64,7 +76,10 @@ fn lit(s: &str, mode: Mode) { |
| 64 | 76 | } |
| 65 | 77 | |
| 66 | 78 | pub fn run() { |
| 79 | assert_eq!("\'", "'"); | |
| 67 | 80 | // returns Ok(valid instance) |
| 81 | lit("r\"g\"", NormalOk); | |
| 82 | lit("r#\"g\"#", NormalOk); | |
| 68 | 83 | lit("123", NormalOk); |
| 69 | 84 | lit("\"ab\"", NormalOk); |
| 70 | 85 | lit("\'b\'", NormalOk); |
| ... | ... | @@ -72,6 +87,7 @@ pub fn run() { |
| 72 | 87 | lit("b\"b\"", NormalOk); |
| 73 | 88 | lit("c\"b\"", NormalOk); |
| 74 | 89 | lit("cr\"b\"", NormalOk); |
| 90 | lit("'\\''", NormalOk); | |
| 75 | 91 | lit("b'b'", NormalOk); |
| 76 | 92 | lit("256u8", NormalOk); |
| 77 | 93 | lit("-256u8", NormalOk); |
| ... | ... | @@ -99,10 +115,13 @@ pub fn run() { |
| 99 | 115 | NormalOk, |
| 100 | 116 | ); |
| 101 | 117 | stream("/*a*/ //", NormalOk); |
| 118 | lit("\"\"", NormalOk); | |
| 119 | stream("", NormalOk); | |
| 102 | 120 | |
| 103 | 121 | println!("### ERRORS"); |
| 104 | 122 | |
| 105 | 123 | // returns Err(LexError) |
| 124 | lit("", NormalErr); | |
| 106 | 125 | lit("\'c\'/**/", NormalErr); |
| 107 | 126 | lit(" 0", NormalErr); |
| 108 | 127 | lit("0 ", NormalErr); |
| ... | ... | @@ -119,10 +138,12 @@ pub fn run() { |
| 119 | 138 | // emits diagnostics and returns LexError |
| 120 | 139 | lit("r'r'", OtherError); |
| 121 | 140 | lit("c'r'", OtherError); |
| 141 | lit("\u{2000}", OtherError); | |
| 122 | 142 | |
| 123 | 143 | // emits diagnostic and returns a seemingly valid tokenstream |
| 124 | 144 | stream("r'r'", OtherError); |
| 125 | 145 | stream("c'r'", OtherError); |
| 146 | stream("\u{2000}", OtherError); | |
| 126 | 147 | |
| 127 | 148 | for parse in [stream as fn(&str, Mode), lit] { |
| 128 | 149 | // emits diagnostic(s), then panics |
tests/ui/proc-macro/nonfatal-parsing.stderr+25-1| ... | ... | @@ -22,6 +22,17 @@ help: consider inserting whitespace here |
| 22 | 22 | LL | c 'r' |
| 23 | 23 | | + |
| 24 | 24 | |
| 25 | error: unknown start of token: \u{2000} | |
| 26 | --> <proc-macro source code>:1:1 | |
| 27 | | | |
| 28 | LL |   | |
| 29 | | ^ | |
| 30 | | | |
| 31 | help: Unicode character ' ' (En Quad) looks like ' ' (Space), but it is not | |
| 32 | | | |
| 33 | LL | | |
| 34 | | | |
| 35 | ||
| 25 | 36 | error: prefix `r` is unknown |
| 26 | 37 | --> $DIR/nonfatal-parsing.rs:15:5 |
| 27 | 38 | | |
| ... | ... | @@ -40,6 +51,19 @@ LL | nonfatal_parsing::run!(); |
| 40 | 51 | = note: prefixed identifiers and literals are reserved since Rust 2021 |
| 41 | 52 | = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) |
| 42 | 53 | |
| 54 | error: unknown start of token: \u{2000} | |
| 55 | --> $DIR/nonfatal-parsing.rs:15:5 | |
| 56 | | | |
| 57 | LL | nonfatal_parsing::run!(); | |
| 58 | | ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 59 | | | |
| 60 | = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) | |
| 61 | help: Unicode character ' ' (En Quad) looks like ' ' (Space), but it is not | |
| 62 | --> <proc-macro source code>:1:1 | |
| 63 | | | |
| 64 | LL | | |
| 65 | | | |
| 66 | ||
| 43 | 67 | error: found invalid character; only `#` is allowed in raw string delimitation: \u{0} |
| 44 | 68 | --> $DIR/nonfatal-parsing.rs:15:5 |
| 45 | 69 | | |
| ... | ... | @@ -175,6 +199,6 @@ error: invalid digit for a base 2 literal |
| 175 | 199 | LL | /*a*/ 0b2 // |
| 176 | 200 | | ^ |
| 177 | 201 | |
| 178 | error: aborting due to 20 previous errors | |
| 202 | error: aborting due to 22 previous errors | |
| 179 | 203 | |
| 180 | 204 | For more information about this error, try `rustc --explain E0768`. |
tests/ui/proc-macro/nonfatal-parsing.stdout+50-42| ... | ... | @@ -1,34 +1,40 @@ |
| 1 | Ok(Literal { kind: Integer, symbol: "123", suffix: None, span: #44 bytes(361..385) }) | |
| 2 | Ok(Literal { kind: Str, symbol: "ab", suffix: None, span: #44 bytes(361..385) }) | |
| 3 | Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #44 bytes(361..385) }) | |
| 4 | Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #44 bytes(361..385) }) | |
| 5 | Ok(Literal { kind: ByteStr, symbol: "b", suffix: None, span: #44 bytes(361..385) }) | |
| 6 | Ok(Literal { kind: CStr, symbol: "b", suffix: None, span: #44 bytes(361..385) }) | |
| 7 | Ok(Literal { kind: CStrRaw(0), symbol: "b", suffix: None, span: #44 bytes(361..385) }) | |
| 8 | Ok(Literal { kind: Byte, symbol: "b", suffix: None, span: #44 bytes(361..385) }) | |
| 9 | Ok(Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #44 bytes(361..385) }) | |
| 10 | Ok(Literal { kind: Integer, symbol: "-256", suffix: Some("u8"), span: #44 bytes(361..385) }) | |
| 11 | Ok(TokenStream [Punct { ch: '-', spacing: Alone, span: #44 bytes(361..385) }, Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #44 bytes(361..385) }]) | |
| 12 | Ok(Literal { kind: Integer, symbol: "0b11111000000001111", suffix: Some("i16"), span: #44 bytes(361..385) }) | |
| 13 | Ok(Literal { kind: Integer, symbol: "0xf32", suffix: None, span: #44 bytes(361..385) }) | |
| 14 | Ok(Literal { kind: Integer, symbol: "0b0", suffix: Some("f32"), span: #44 bytes(361..385) }) | |
| 15 | Ok(Literal { kind: Float, symbol: "2E4", suffix: None, span: #44 bytes(361..385) }) | |
| 16 | Ok(Literal { kind: Float, symbol: "2.2E-4", suffix: Some("f64"), span: #44 bytes(361..385) }) | |
| 17 | Ok(Literal { kind: Integer, symbol: "18", suffix: Some("u8E"), span: #44 bytes(361..385) }) | |
| 18 | Ok(Literal { kind: Float, symbol: "18.0", suffix: Some("u8E"), span: #44 bytes(361..385) }) | |
| 19 | Ok(Literal { kind: CStrRaw(1), symbol: "// /* // \n */", suffix: None, span: #44 bytes(361..385) }) | |
| 20 | Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #44 bytes(361..385) }) | |
| 21 | Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #44 bytes(361..385) }) | |
| 22 | Ok(Literal { kind: StrRaw(255), symbol: "a", suffix: None, span: #44 bytes(361..385) }) | |
| 23 | Ok(TokenStream [Ident { ident: "fn", span: #44 bytes(361..385) }, Ident { ident: "main", span: #44 bytes(361..385) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #44 bytes(361..385) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "println", span: #44 bytes(361..385) }, Punct { ch: '!', spacing: Alone, span: #44 bytes(361..385) }, Group { delimiter: Parenthesis, stream: TokenStream [Literal { kind: Str, symbol: "Hello, world!", suffix: None, span: #44 bytes(361..385) }], span: #44 bytes(361..385) }], span: #44 bytes(361..385) }]) | |
| 24 | Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: #44 bytes(361..385) }, Punct { ch: '.', spacing: Alone, span: #44 bytes(361..385) }, Ident { ident: "u8E", span: #44 bytes(361..385) }]) | |
| 25 | Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f32"), span: #44 bytes(361..385) }]) | |
| 26 | Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f34"), span: #44 bytes(361..385) }]) | |
| 27 | Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: #44 bytes(361..385) }, Punct { ch: '.', spacing: Alone, span: #44 bytes(361..385) }, Ident { ident: "bu8", span: #44 bytes(361..385) }]) | |
| 28 | Ok(TokenStream [Literal { kind: Integer, symbol: "3", suffix: None, span: #44 bytes(361..385) }, Literal { kind: Integer, symbol: "4", suffix: None, span: #44 bytes(361..385) }]) | |
| 29 | Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: #44 bytes(361..385) }]) | |
| 1 | Ok(Literal { kind: StrRaw(0), symbol: "g", suffix: None, span: Span }) | |
| 2 | Ok(Literal { kind: StrRaw(1), symbol: "g", suffix: None, span: Span }) | |
| 3 | Ok(Literal { kind: Integer, symbol: "123", suffix: None, span: Span }) | |
| 4 | Ok(Literal { kind: Str, symbol: "ab", suffix: None, span: Span }) | |
| 5 | Ok(Literal { kind: Char, symbol: "b", suffix: None, span: Span }) | |
| 6 | Ok(Literal { kind: Char, symbol: "b", suffix: None, span: Span }) | |
| 7 | Ok(Literal { kind: ByteStr, symbol: "b", suffix: None, span: Span }) | |
| 8 | Ok(Literal { kind: CStr, symbol: "b", suffix: None, span: Span }) | |
| 9 | Ok(Literal { kind: CStrRaw(0), symbol: "b", suffix: None, span: Span }) | |
| 10 | Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span }) | |
| 11 | Ok(Literal { kind: Byte, symbol: "b", suffix: None, span: Span }) | |
| 12 | Ok(Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: Span }) | |
| 13 | Ok(Literal { kind: Integer, symbol: "-256", suffix: Some("u8"), span: Span }) | |
| 14 | Ok(TokenStream [Punct { ch: '-', spacing: Alone, span: Span }, Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: Span }]) | |
| 15 | Ok(Literal { kind: Integer, symbol: "0b11111000000001111", suffix: Some("i16"), span: Span }) | |
| 16 | Ok(Literal { kind: Integer, symbol: "0xf32", suffix: None, span: Span }) | |
| 17 | Ok(Literal { kind: Integer, symbol: "0b0", suffix: Some("f32"), span: Span }) | |
| 18 | Ok(Literal { kind: Float, symbol: "2E4", suffix: None, span: Span }) | |
| 19 | Ok(Literal { kind: Float, symbol: "2.2E-4", suffix: Some("f64"), span: Span }) | |
| 20 | Ok(Literal { kind: Integer, symbol: "18", suffix: Some("u8E"), span: Span }) | |
| 21 | Ok(Literal { kind: Float, symbol: "18.0", suffix: Some("u8E"), span: Span }) | |
| 22 | Ok(Literal { kind: CStrRaw(1), symbol: "// /* // \n */", suffix: None, span: Span }) | |
| 23 | Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span }) | |
| 24 | Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span }) | |
| 25 | Ok(Literal { kind: StrRaw(255), symbol: "a", suffix: None, span: Span }) | |
| 26 | Ok(TokenStream [Ident { ident: "fn", span: Span }, Ident { ident: "main", span: Span }, Group { delimiter: Parenthesis, stream: TokenStream [], span: Span }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "println", span: Span }, Punct { ch: '!', spacing: Alone, span: Span }, Group { delimiter: Parenthesis, stream: TokenStream [Literal { kind: Str, symbol: "Hello, world!", suffix: None, span: Span }], span: Span }], span: Span }]) | |
| 27 | Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: Span }, Punct { ch: '.', spacing: Alone, span: Span }, Ident { ident: "u8E", span: Span }]) | |
| 28 | Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f32"), span: Span }]) | |
| 29 | Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f34"), span: Span }]) | |
| 30 | Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: Span }, Punct { ch: '.', spacing: Alone, span: Span }, Ident { ident: "bu8", span: Span }]) | |
| 31 | Ok(TokenStream [Literal { kind: Integer, symbol: "3", suffix: None, span: Span }, Literal { kind: Integer, symbol: "4", suffix: None, span: Span }]) | |
| 32 | Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: Span }]) | |
| 33 | Ok(TokenStream []) | |
| 34 | Ok(Literal { kind: Str, symbol: "", suffix: None, span: Span }) | |
| 30 | 35 | Ok(TokenStream []) |
| 31 | 36 | ### ERRORS |
| 37 | Err(LexError("not a literal")) | |
| 32 | 38 | Err(LexError("comment or whitespace around literal")) |
| 33 | 39 | Err(LexError("comment or whitespace around literal")) |
| 34 | 40 | Err(LexError("comment or whitespace around literal")) |
| ... | ... | @@ -42,17 +48,19 @@ Err(LexError("unexpected closing delimiter: `)`")) |
| 42 | 48 | Err(LexError("unexpected closing delimiter: `]`")) |
| 43 | 49 | Err(LexError("not a literal")) |
| 44 | 50 | Err(LexError("not a literal")) |
| 45 | Ok(TokenStream [Ident { ident: "r", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }]) | |
| 46 | Ok(TokenStream [Ident { ident: "c", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }]) | |
| 47 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }]) | |
| 48 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 bytes(361..385) }]) | |
| 49 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) }]) | |
| 50 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) }]) | |
| 51 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) }]) | |
| 52 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }]) | |
| 53 | Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }) | |
| 54 | Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 bytes(361..385) }) | |
| 55 | Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) }) | |
| 56 | Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) }) | |
| 57 | Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) }) | |
| 51 | Err(LexError("not a literal")) | |
| 52 | Ok(TokenStream [Ident { ident: "r", span: Span }, Literal { kind: Char, symbol: "r", suffix: None, span: Span }]) | |
| 53 | Ok(TokenStream [Ident { ident: "c", span: Span }, Literal { kind: Char, symbol: "r", suffix: None, span: Span }]) | |
| 54 | Ok(TokenStream []) | |
| 55 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }]) | |
| 56 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: Span }]) | |
| 57 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: Span }]) | |
| 58 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: Span }]) | |
| 59 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: Span }]) | |
| 60 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }]) | |
| 61 | Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }) | |
| 62 | Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: Span }) | |
| 63 | Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: Span }) | |
| 64 | Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: Span }) | |
| 65 | Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: Span }) | |
| 58 | 66 | Err(LexError("comment or whitespace around literal")) |
tests/ui/reachable/unreachable-ret-after-panic.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/2150>. | |
| 2 | ||
| 3 | #![deny(unreachable_code)] | |
| 4 | #![allow(unused_variables)] | |
| 5 | #![allow(dead_code)] | |
| 6 | ||
| 7 | fn fail_len(v: Vec<isize> ) -> usize { | |
| 8 | let mut i = 3; | |
| 9 | panic!(); | |
| 10 | for x in &v { i += 1; } | |
| 11 | //~^ ERROR: unreachable statement | |
| 12 | return i; | |
| 13 | } | |
| 14 | fn main() {} |
tests/ui/reachable/unreachable-ret-after-panic.stderr created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | error: unreachable statement | |
| 2 | --> $DIR/unreachable-ret-after-panic.rs:10:5 | |
| 3 | | | |
| 4 | LL | panic!(); | |
| 5 | | -------- any code following this expression is unreachable | |
| 6 | LL | for x in &v { i += 1; } | |
| 7 | | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | |
| 8 | | | |
| 9 | note: the lint level is defined here | |
| 10 | --> $DIR/unreachable-ret-after-panic.rs:3:9 | |
| 11 | | | |
| 12 | LL | #![deny(unreachable_code)] | |
| 13 | | ^^^^^^^^^^^^^^^^ | |
| 14 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 |
tests/ui/recursion/infinite-instantiation-via-nested-closures.rs created+62| ... | ... | @@ -0,0 +1,62 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22638>. | |
| 2 | //@ build-fail | |
| 3 | ||
| 4 | #![allow(unused)] | |
| 5 | ||
| 6 | #![recursion_limit = "20"] | |
| 7 | #![type_length_limit = "20000000"] | |
| 8 | #![crate_type = "rlib"] | |
| 9 | ||
| 10 | #[derive(Clone)] | |
| 11 | struct A (B); | |
| 12 | ||
| 13 | impl A { | |
| 14 | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 15 | let &A(ref term) = self; | |
| 16 | term.matches(f); | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | #[derive(Clone)] | |
| 21 | enum B { | |
| 22 | Variant1, | |
| 23 | Variant2(C), | |
| 24 | } | |
| 25 | ||
| 26 | impl B { | |
| 27 | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 28 | match self { | |
| 29 | &B::Variant2(ref factor) => { | |
| 30 | factor.matches(&|| ()) | |
| 31 | } | |
| 32 | _ => unreachable!("") | |
| 33 | } | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | #[derive(Clone)] | |
| 38 | struct C (D); | |
| 39 | ||
| 40 | impl C { | |
| 41 | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 42 | let &C(ref base) = self; | |
| 43 | base.matches(&|| { | |
| 44 | C(base.clone()).matches(f) | |
| 45 | }) | |
| 46 | } | |
| 47 | } | |
| 48 | ||
| 49 | #[derive(Clone)] | |
| 50 | struct D (Box<A>); | |
| 51 | ||
| 52 | impl D { | |
| 53 | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 54 | let &D(ref a) = self; | |
| 55 | a.matches(f) | |
| 56 | //~^ ERROR reached the recursion limit while instantiating | |
| 57 | } | |
| 58 | } | |
| 59 | ||
| 60 | pub fn matches() { | |
| 61 | A(B::Variant1).matches(&(|| ())) | |
| 62 | } |
tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | error: reached the recursion limit while instantiating `A::matches::<{closure@$DIR/infinite-instantiation-via-nested-closures.rs:43:23: 43:25}>` | |
| 2 | --> $DIR/infinite-instantiation-via-nested-closures.rs:55:9 | |
| 3 | | | |
| 4 | LL | a.matches(f) | |
| 5 | | ^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: `A::matches` defined here | |
| 8 | --> $DIR/infinite-instantiation-via-nested-closures.rs:14:5 | |
| 9 | | | |
| 10 | LL | pub fn matches<F: Fn()>(&self, f: &F) { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | ||
| 13 | error: aborting due to 1 previous error | |
| 14 |
tests/ui/resolve/module-type-name-conflict.rs created+52| ... | ... | @@ -0,0 +1,52 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/21546>. | |
| 2 | //! Ensure structs, enums and modules cannot share name in namespace. | |
| 3 | //! | |
| 4 | //! Also works as a test for <https://github.com/rust-lang/rust/issues/14564>. | |
| 5 | ||
| 6 | #[allow(non_snake_case)] | |
| 7 | mod Foo { } | |
| 8 | ||
| 9 | #[allow(dead_code)] | |
| 10 | struct Foo; | |
| 11 | //~^ ERROR the name `Foo` is defined multiple times | |
| 12 | ||
| 13 | #[allow(non_snake_case)] | |
| 14 | mod Bar { } | |
| 15 | ||
| 16 | #[allow(dead_code)] | |
| 17 | struct Bar(i32); | |
| 18 | //~^ ERROR the name `Bar` is defined multiple times | |
| 19 | ||
| 20 | ||
| 21 | #[allow(dead_code)] | |
| 22 | struct Baz(i32); | |
| 23 | ||
| 24 | #[allow(non_snake_case)] | |
| 25 | mod Baz { } | |
| 26 | //~^ ERROR the name `Baz` is defined multiple times | |
| 27 | ||
| 28 | ||
| 29 | #[allow(dead_code)] | |
| 30 | struct Qux { x: bool } | |
| 31 | ||
| 32 | #[allow(non_snake_case)] | |
| 33 | mod Qux { } | |
| 34 | //~^ ERROR the name `Qux` is defined multiple times | |
| 35 | ||
| 36 | ||
| 37 | #[allow(dead_code)] | |
| 38 | struct Quux; | |
| 39 | ||
| 40 | #[allow(non_snake_case)] | |
| 41 | mod Quux { } | |
| 42 | //~^ ERROR the name `Quux` is defined multiple times | |
| 43 | ||
| 44 | ||
| 45 | #[allow(dead_code)] | |
| 46 | enum Corge { A, B } | |
| 47 | ||
| 48 | #[allow(non_snake_case)] | |
| 49 | mod Corge { } | |
| 50 | //~^ ERROR the name `Corge` is defined multiple times | |
| 51 | ||
| 52 | fn main() { } |
tests/ui/resolve/module-type-name-conflict.stderr created+69| ... | ... | @@ -0,0 +1,69 @@ |
| 1 | error[E0428]: the name `Foo` is defined multiple times | |
| 2 | --> $DIR/module-type-name-conflict.rs:10:1 | |
| 3 | | | |
| 4 | LL | mod Foo { } | |
| 5 | | ------- previous definition of the module `Foo` here | |
| 6 | ... | |
| 7 | LL | struct Foo; | |
| 8 | | ^^^^^^^^^^^ `Foo` redefined here | |
| 9 | | | |
| 10 | = note: `Foo` must be defined only once in the type namespace of this module | |
| 11 | ||
| 12 | error[E0428]: the name `Bar` is defined multiple times | |
| 13 | --> $DIR/module-type-name-conflict.rs:17:1 | |
| 14 | | | |
| 15 | LL | mod Bar { } | |
| 16 | | ------- previous definition of the module `Bar` here | |
| 17 | ... | |
| 18 | LL | struct Bar(i32); | |
| 19 | | ^^^^^^^^^^^^^^^^ `Bar` redefined here | |
| 20 | | | |
| 21 | = note: `Bar` must be defined only once in the type namespace of this module | |
| 22 | ||
| 23 | error[E0428]: the name `Baz` is defined multiple times | |
| 24 | --> $DIR/module-type-name-conflict.rs:25:1 | |
| 25 | | | |
| 26 | LL | struct Baz(i32); | |
| 27 | | ---------------- previous definition of the type `Baz` here | |
| 28 | ... | |
| 29 | LL | mod Baz { } | |
| 30 | | ^^^^^^^ `Baz` redefined here | |
| 31 | | | |
| 32 | = note: `Baz` must be defined only once in the type namespace of this module | |
| 33 | ||
| 34 | error[E0428]: the name `Qux` is defined multiple times | |
| 35 | --> $DIR/module-type-name-conflict.rs:33:1 | |
| 36 | | | |
| 37 | LL | struct Qux { x: bool } | |
| 38 | | ---------- previous definition of the type `Qux` here | |
| 39 | ... | |
| 40 | LL | mod Qux { } | |
| 41 | | ^^^^^^^ `Qux` redefined here | |
| 42 | | | |
| 43 | = note: `Qux` must be defined only once in the type namespace of this module | |
| 44 | ||
| 45 | error[E0428]: the name `Quux` is defined multiple times | |
| 46 | --> $DIR/module-type-name-conflict.rs:41:1 | |
| 47 | | | |
| 48 | LL | struct Quux; | |
| 49 | | ------------ previous definition of the type `Quux` here | |
| 50 | ... | |
| 51 | LL | mod Quux { } | |
| 52 | | ^^^^^^^^ `Quux` redefined here | |
| 53 | | | |
| 54 | = note: `Quux` must be defined only once in the type namespace of this module | |
| 55 | ||
| 56 | error[E0428]: the name `Corge` is defined multiple times | |
| 57 | --> $DIR/module-type-name-conflict.rs:49:1 | |
| 58 | | | |
| 59 | LL | enum Corge { A, B } | |
| 60 | | ---------- previous definition of the type `Corge` here | |
| 61 | ... | |
| 62 | LL | mod Corge { } | |
| 63 | | ^^^^^^^^^ `Corge` redefined here | |
| 64 | | | |
| 65 | = note: `Corge` must be defined only once in the type namespace of this module | |
| 66 | ||
| 67 | error: aborting due to 6 previous errors | |
| 68 | ||
| 69 | For more information about this error, try `rustc --explain E0428`. |
tests/ui/traits/ambiguous-trait-matching-distinct-lifetimes.rs created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | //! <https://github.com/rust-lang/rust/issues/21974>. | |
| 2 | //! | |
| 3 | //! Test that (for now) we report an ambiguity error here, because | |
| 4 | //! specific trait relationships are ignored for the purposes of trait | |
| 5 | //! matching. This behavior should likely be improved such that this | |
| 6 | //! test passes. | |
| 7 | ||
| 8 | trait Foo { | |
| 9 | fn foo(self); | |
| 10 | } | |
| 11 | ||
| 12 | fn foo<'a,'b,T>(x: &'a T, y: &'b T) | |
| 13 | where &'a T : Foo, //~ ERROR type annotations needed | |
| 14 | &'b T : Foo | |
| 15 | { | |
| 16 | x.foo(); //~ ERROR type annotations needed | |
| 17 | y.foo(); | |
| 18 | } | |
| 19 | ||
| 20 | fn main() { } |
tests/ui/traits/ambiguous-trait-matching-distinct-lifetimes.stderr created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo` | |
| 2 | --> $DIR/ambiguous-trait-matching-distinct-lifetimes.rs:13:19 | |
| 3 | | | |
| 4 | LL | where &'a T : Foo, | |
| 5 | | ^^^ | |
| 6 | | | |
| 7 | note: multiple `impl`s or `where` clauses satisfying `&'a T: Foo` found | |
| 8 | --> $DIR/ambiguous-trait-matching-distinct-lifetimes.rs:13:19 | |
| 9 | | | |
| 10 | LL | where &'a T : Foo, | |
| 11 | | ^^^ | |
| 12 | LL | &'b T : Foo | |
| 13 | | ^^^ | |
| 14 | ||
| 15 | error[E0283]: type annotations needed: cannot satisfy `&T: Foo` | |
| 16 | --> $DIR/ambiguous-trait-matching-distinct-lifetimes.rs:16:7 | |
| 17 | | | |
| 18 | LL | x.foo(); | |
| 19 | | ^^^ | |
| 20 | | | |
| 21 | note: multiple `impl`s or `where` clauses satisfying `&T: Foo` found | |
| 22 | --> $DIR/ambiguous-trait-matching-distinct-lifetimes.rs:13:19 | |
| 23 | | | |
| 24 | LL | where &'a T : Foo, | |
| 25 | | ^^^ | |
| 26 | LL | &'b T : Foo | |
| 27 | | ^^^ | |
| 28 | ||
| 29 | error: aborting due to 2 previous errors | |
| 30 | ||
| 31 | For more information about this error, try `rustc --explain E0283`. |
tests/ui/type-alias/where-clause-on-generic-type-alias.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22471>. | |
| 2 | ||
| 3 | //@ check-pass | |
| 4 | #![allow(type_alias_bounds)] | |
| 5 | ||
| 6 | type Foo<T> where T: Copy = Box<T>; | |
| 7 | ||
| 8 | fn main(){} |
tests/ui/type-inference/index-expr-ambiguous-type.rs created+54| ... | ... | @@ -0,0 +1,54 @@ |
| 1 | // Regression test for #156738 | |
| 2 | // | |
| 3 | // When the index type in `arr[idx]` is ambiguous, the error should point | |
| 4 | // at the index sub-expression, not the whole indexing expression or | |
| 5 | // surrounding operators. | |
| 6 | ||
| 7 | fn with_cast() { | |
| 8 | let bad_idx = 0u8; | |
| 9 | let _foo = [1, 2, 3][bad_idx.into()] as i32; | |
| 10 | //~^ ERROR type annotations needed | |
| 11 | } | |
| 12 | ||
| 13 | fn with_binop() { | |
| 14 | let bad_idx = 0u8; | |
| 15 | let _foo = 0 + [1, 2, 3][bad_idx.into()]; | |
| 16 | //~^ ERROR type annotations needed | |
| 17 | } | |
| 18 | ||
| 19 | fn standalone() { | |
| 20 | let bad_idx = 0u8; | |
| 21 | let _foo = [1, 2, 3][bad_idx.into()]; | |
| 22 | //~^ ERROR type annotations needed | |
| 23 | } | |
| 24 | ||
| 25 | fn with_known_index_type() { | |
| 26 | let bad_idx = 0u8; | |
| 27 | let _foo = [1, 2, 3][Into::<usize>::into(bad_idx)] as i32; | |
| 28 | } | |
| 29 | ||
| 30 | fn invalid_operator_with_ambiguous_index() { | |
| 31 | let bad_idx = 0u8; | |
| 32 | let _foo = true + [1, 2, 3][bad_idx.into()]; | |
| 33 | //~^ ERROR cannot add | |
| 34 | } | |
| 35 | ||
| 36 | fn mismatched_numeric_binop_with_ambiguous_index() { | |
| 37 | let bad_idx = 0u8; | |
| 38 | let _foo = 0u64 + [1i32, 2, 3][bad_idx.into()]; | |
| 39 | //~^ ERROR type annotations needed | |
| 40 | } | |
| 41 | ||
| 42 | fn shift_with_ambiguous_index() { | |
| 43 | let bad_idx = 0u8; | |
| 44 | let _foo = 1u32 << [0u8][bad_idx.into()]; | |
| 45 | //~^ ERROR type annotations needed | |
| 46 | } | |
| 47 | ||
| 48 | fn string_add_with_ambiguous_index() { | |
| 49 | let bad_idx = 0u8; | |
| 50 | let _foo = String::new() + [""][bad_idx.into()]; | |
| 51 | //~^ ERROR type annotations needed | |
| 52 | } | |
| 53 | ||
| 54 | fn main() {} |
tests/ui/type-inference/index-expr-ambiguous-type.stderr created+70| ... | ... | @@ -0,0 +1,70 @@ |
| 1 | error[E0282]: type annotations needed | |
| 2 | --> $DIR/index-expr-ambiguous-type.rs:9:34 | |
| 3 | | | |
| 4 | LL | let _foo = [1, 2, 3][bad_idx.into()] as i32; | |
| 5 | | ^^^^ cannot infer type | |
| 6 | ||
| 7 | error[E0284]: type annotations needed | |
| 8 | --> $DIR/index-expr-ambiguous-type.rs:15:38 | |
| 9 | | | |
| 10 | LL | let _foo = 0 + [1, 2, 3][bad_idx.into()]; | |
| 11 | | ^^^^ cannot infer type | |
| 12 | | | |
| 13 | = note: cannot satisfy `<i32 as Add<_>>::Output == _` | |
| 14 | ||
| 15 | error[E0283]: type annotations needed | |
| 16 | --> $DIR/index-expr-ambiguous-type.rs:21:34 | |
| 17 | | | |
| 18 | LL | let _foo = [1, 2, 3][bad_idx.into()]; | |
| 19 | | ^^^^ | |
| 20 | | | |
| 21 | = note: the type must implement `From<u8>` | |
| 22 | = note: required for `u8` to implement `Into<_>` | |
| 23 | help: try using a fully qualified path to specify the expected types | |
| 24 | | | |
| 25 | LL - let _foo = [1, 2, 3][bad_idx.into()]; | |
| 26 | LL + let _foo = [1, 2, 3][<u8 as Into<T>>::into(bad_idx)]; | |
| 27 | | | |
| 28 | ||
| 29 | error[E0369]: cannot add `_` to `bool` | |
| 30 | --> $DIR/index-expr-ambiguous-type.rs:32:21 | |
| 31 | | | |
| 32 | LL | let _foo = true + [1, 2, 3][bad_idx.into()]; | |
| 33 | | ---- ^ ------------------------- _ | |
| 34 | | | | |
| 35 | | bool | |
| 36 | ||
| 37 | error[E0284]: type annotations needed | |
| 38 | --> $DIR/index-expr-ambiguous-type.rs:38:21 | |
| 39 | | | |
| 40 | LL | let _foo = 0u64 + [1i32, 2, 3][bad_idx.into()]; | |
| 41 | | ^ cannot infer type | |
| 42 | | | |
| 43 | = note: cannot satisfy `<u64 as Add<_>>::Output == _` | |
| 44 | ||
| 45 | error[E0284]: type annotations needed | |
| 46 | --> $DIR/index-expr-ambiguous-type.rs:44:38 | |
| 47 | | | |
| 48 | LL | let _foo = 1u32 << [0u8][bad_idx.into()]; | |
| 49 | | ^^^^ cannot infer type | |
| 50 | | | |
| 51 | = note: cannot satisfy `<u32 as Shl<_>>::Output == _` | |
| 52 | ||
| 53 | error[E0283]: type annotations needed | |
| 54 | --> $DIR/index-expr-ambiguous-type.rs:50:45 | |
| 55 | | | |
| 56 | LL | let _foo = String::new() + [""][bad_idx.into()]; | |
| 57 | | ^^^^ | |
| 58 | | | |
| 59 | = note: the type must implement `From<u8>` | |
| 60 | = note: required for `u8` to implement `Into<_>` | |
| 61 | help: try using a fully qualified path to specify the expected types | |
| 62 | | | |
| 63 | LL - let _foo = String::new() + [""][bad_idx.into()]; | |
| 64 | LL + let _foo = String::new() + [""][<u8 as Into<T>>::into(bad_idx)]; | |
| 65 | | | |
| 66 | ||
| 67 | error: aborting due to 7 previous errors | |
| 68 | ||
| 69 | Some errors have detailed explanations: E0282, E0283, E0284, E0369. | |
| 70 | For more information about an error, try `rustc --explain E0282`. |
tests/ui/typeck/call-non-fn-type-param.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/21701>. | |
| 2 | ||
| 3 | fn foo<U>(t: U) { | |
| 4 | let y = t(); | |
| 5 | //~^ ERROR: expected function, found `U` | |
| 6 | } | |
| 7 | ||
| 8 | struct Bar; | |
| 9 | ||
| 10 | pub fn some_func() { | |
| 11 | let f = Bar(); | |
| 12 | //~^ ERROR: expected function, found struct `Bar` | |
| 13 | } | |
| 14 | ||
| 15 | fn main() { | |
| 16 | foo(|| { 1 }); | |
| 17 | } |
tests/ui/typeck/call-non-fn-type-param.stderr created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | error[E0618]: expected function, found `U` | |
| 2 | --> $DIR/call-non-fn-type-param.rs:4:13 | |
| 3 | | | |
| 4 | LL | fn foo<U>(t: U) { | |
| 5 | | - `t` has type `U` | |
| 6 | LL | let y = t(); | |
| 7 | | ^-- | |
| 8 | | | | |
| 9 | | call expression requires function | |
| 10 | ||
| 11 | error[E0618]: expected function, found struct `Bar` | |
| 12 | --> $DIR/call-non-fn-type-param.rs:11:13 | |
| 13 | | | |
| 14 | LL | struct Bar; | |
| 15 | | ---------- struct `Bar` defined here | |
| 16 | ... | |
| 17 | LL | let f = Bar(); | |
| 18 | | ^^^-- | |
| 19 | | | | |
| 20 | | call expression requires function | |
| 21 | | | |
| 22 | help: `Bar` is a unit struct, and does not take parentheses to be constructed | |
| 23 | | | |
| 24 | LL - let f = Bar(); | |
| 25 | LL + let f = Bar; | |
| 26 | | | |
| 27 | ||
| 28 | error: aborting due to 2 previous errors | |
| 29 | ||
| 30 | For more information about this error, try `rustc --explain E0618`. |
tests/ui/typeck/match-boxed-fn-entry-type-inference.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22781>. | |
| 2 | ||
| 3 | //@ check-pass | |
| 4 | #![allow(unused_variables)] | |
| 5 | use std::collections::HashMap; | |
| 6 | use std::collections::hash_map::Entry::Vacant; | |
| 7 | ||
| 8 | pub fn foo() { | |
| 9 | type F = Box<dyn Fn(&()) + 'static>; | |
| 10 | let mut map: HashMap<(), F> = HashMap::new(); | |
| 11 | let x: &mut F = match map.entry(()) { | |
| 12 | Vacant(_) => unimplemented!(), | |
| 13 | _ => unimplemented!() | |
| 14 | }; | |
| 15 | } | |
| 16 | ||
| 17 | fn main() {} |
tests/ui/unboxed-closures/fnonce-impl-on-unit-struct.rs created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22603>. | |
| 2 | //@ check-pass | |
| 3 | ||
| 4 | #![feature(unboxed_closures, fn_traits)] | |
| 5 | ||
| 6 | struct Foo; | |
| 7 | ||
| 8 | impl<A> FnOnce<(A,)> for Foo { | |
| 9 | type Output = (); | |
| 10 | extern "rust-call" fn call_once(self, (_,): (A,)) { | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | fn main() { | |
| 15 | println!("{:?}", Foo("bar")); | |
| 16 | } |
tests/ui/uninhabited/void-branch.rs+9| ... | ... | @@ -29,4 +29,13 @@ fn with_infallible() { |
| 29 | 29 | println!() |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | fn infallible_with_arg<T>(x: T) -> (T, std::convert::Infallible) { | |
| 33 | (x, loop {}) | |
| 34 | //~^ ERROR unreachable expression | |
| 35 | } | |
| 36 | ||
| 37 | fn in_if_else(x: String) -> Result<String, (String, std::convert::Infallible)> { | |
| 38 | if x.len() > 0 { Err(infallible_with_arg(x)) } else { Ok(x) } | |
| 39 | } | |
| 40 | ||
| 32 | 41 | fn main() {} |
tests/ui/uninhabited/void-branch.stderr+16-6| ... | ... | @@ -1,3 +1,18 @@ |
| 1 | error: unreachable expression | |
| 2 | --> $DIR/void-branch.rs:33:5 | |
| 3 | | | |
| 4 | LL | (x, loop {}) | |
| 5 | | ^^^^-------^ | |
| 6 | | | | | |
| 7 | | | any code following this expression is unreachable | |
| 8 | | unreachable expression | |
| 9 | | | |
| 10 | note: the lint level is defined here | |
| 11 | --> $DIR/void-branch.rs:1:9 | |
| 12 | | | |
| 13 | LL | #![deny(unreachable_code)] | |
| 14 | | ^^^^^^^^^^^^^^^^ | |
| 15 | ||
| 1 | 16 | error: unreachable expression |
| 2 | 17 | --> $DIR/void-branch.rs:10:13 |
| 3 | 18 | | |
| ... | ... | @@ -11,11 +26,6 @@ note: this expression has type `Void`, which is uninhabited |
| 11 | 26 | | |
| 12 | 27 | LL | std::mem::uninitialized::<Void>(); |
| 13 | 28 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 14 | note: the lint level is defined here | |
| 15 | --> $DIR/void-branch.rs:1:9 | |
| 16 | | | |
| 17 | LL | #![deny(unreachable_code)] | |
| 18 | | ^^^^^^^^^^^^^^^^ | |
| 19 | 29 | |
| 20 | 30 | error: unreachable expression |
| 21 | 31 | --> $DIR/void-branch.rs:25:9 |
| ... | ... | @@ -31,5 +41,5 @@ note: this expression has type `Infallible`, which is uninhabited |
| 31 | 41 | LL | infallible(); |
| 32 | 42 | | ^^^^^^^^^^^^ |
| 33 | 43 | |
| 34 | error: aborting due to 2 previous errors | |
| 44 | error: aborting due to 3 previous errors | |
| 35 | 45 |
tests/ui/unsized/unsized-slice-element.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/22874>. | |
| 2 | ||
| 3 | struct Table { | |
| 4 | rows: [[String]], | |
| 5 | //~^ ERROR the size for values of type | |
| 6 | } | |
| 7 | ||
| 8 | fn f(table: &Table) -> &[String] { | |
| 9 | &table.rows[0] | |
| 10 | //~^ ERROR the size for values of type | |
| 11 | } | |
| 12 | ||
| 13 | fn main() {} |
tests/ui/unsized/unsized-slice-element.stderr created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | error[E0277]: the size for values of type `[String]` cannot be known at compilation time | |
| 2 | --> $DIR/unsized-slice-element.rs:4:11 | |
| 3 | | | |
| 4 | LL | rows: [[String]], | |
| 5 | | ^^^^^^^^^^ doesn't have a size known at compile-time | |
| 6 | | | |
| 7 | = help: the trait `Sized` is not implemented for `[String]` | |
| 8 | = note: slice and array elements must have `Sized` type | |
| 9 | ||
| 10 | error[E0277]: the size for values of type `[String]` cannot be known at compilation time | |
| 11 | --> $DIR/unsized-slice-element.rs:9:6 | |
| 12 | | | |
| 13 | LL | &table.rows[0] | |
| 14 | | ^^^^^^^^^^ doesn't have a size known at compile-time | |
| 15 | | | |
| 16 | = help: the trait `Sized` is not implemented for `[String]` | |
| 17 | = note: required for `[[String]]` to implement `Index<_>` | |
| 18 | ||
| 19 | error: aborting due to 2 previous errors | |
| 20 | ||
| 21 | For more information about this error, try `rustc --explain E0277`. |
triagebot.toml+2-3| ... | ... | @@ -1155,7 +1155,6 @@ otherwise, make sure you bump the `FORMAT_VERSION` constant. |
| 1155 | 1155 | """ |
| 1156 | 1156 | cc = [ |
| 1157 | 1157 | "@CraftSpider", |
| 1158 | "@aDotInTheVoid", | |
| 1159 | 1158 | "@Enselic", |
| 1160 | 1159 | "@obi1kenobi", |
| 1161 | 1160 | ] |
| ... | ... | @@ -1313,7 +1312,7 @@ Please ensure that if you've changed the output: |
| 1313 | 1312 | - It's intentional. |
| 1314 | 1313 | - The `FORMAT_VERSION` in `src/librustdoc-json-types` is bumped if necessary. |
| 1315 | 1314 | """ |
| 1316 | cc = ["@aDotInTheVoid", "@obi1kenobi"] | |
| 1315 | cc = ["@obi1kenobi"] | |
| 1317 | 1316 | |
| 1318 | 1317 | [mentions."tests/ui/derives/deriving-all-codegen.stdout"] |
| 1319 | 1318 | message = "Changes to the code generated for builtin derived traits." |
| ... | ... | @@ -1698,7 +1697,7 @@ dep-bumps = [ |
| 1698 | 1697 | "/tests/rustdoc-gui" = ["rustdoc"] |
| 1699 | 1698 | "/tests/rustdoc-js-std" = ["rustdoc"] |
| 1700 | 1699 | "/tests/rustdoc-js/" = ["rustdoc"] |
| 1701 | "/tests/rustdoc-json" = ["@aDotInTheVoid"] | |
| 1700 | "/tests/rustdoc-json" = ["rustdoc"] | |
| 1702 | 1701 | "/tests/rustdoc-ui" = ["rustdoc"] |
| 1703 | 1702 | "/tests/ui" = ["compiler"] |
| 1704 | 1703 | "/tests/ui-fulldeps" = ["compiler"] |