authorbors <bors@rust-lang.org> 2026-06-25 04:45:47 UTC
committerbors <bors@rust-lang.org> 2026-06-25 04:45:47 UTC
log73100eefe2afb831c4964f579c95beeb27b86e28
treeef221079b923742506992b2931ec16c0d55fc053
parent8e25b4121d5ea29bef166b86173fb043782ffbff
parent81526af38549605c9656264e012af035d7fd60aa

Auto merge of #158342 - jhpratt:rollup-TaDKE5Z, r=jhpratt

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>
491491mjptree <michael.prantl@hotmail.de>
492492Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com>
493493msizanoen1 <qtmlabs@protonmail.com>
494mu001999 <mu001999@outlook.com> <rcu@live.com>
495494Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
496495Nadrieril Feneanar <Nadrieril@users.noreply.github.com>
497496Nadrieril Feneanar <Nadrieril@users.noreply.github.com> <nadrieril+rust@gmail.com>
......@@ -603,6 +602,7 @@ Robert Habermeier <rphmeier@gmail.com>
603602Robert Millar <robert.millar@cantab.net>
604603Roc Yu <rocyu@protonmail.com>
605604Rohit Joshi <rohitjoshi@users.noreply.github.com> Rohit Joshi <rohit.joshi@capitalone.com>
605Roland Xu <rcu@live.com> <mu001999@outlook.com>
606606Ross Smyth <18294397+RossSmyth@users.noreply.github.com>
607607Ross Smyth <18294397+RossSmyth@users.noreply.github.com> <crs2017@gmail.com>
608608Ross Smyth <18294397+RossSmyth@users.noreply.github.com> <rsmyth@electrocraft.com>
Cargo.lock+2-2
......@@ -3554,9 +3554,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
35543554
35553555[[package]]
35563556name = "rustc-literal-escaper"
3557version = "0.0.7"
3557version = "0.0.8"
35583558source = "registry+https://github.com/rust-lang/crates.io-index"
3559checksum = "8be87abb9e40db7466e0681dc8ecd9dcfd40360cb10b4c8fe24a7c4c3669b198"
3559checksum = "bfe6f213fb658c8fb95baabd5420393438cf5a98d707f5dd701d9197c705f71e"
35603560
35613561[[package]]
35623562name = "rustc-main"
compiler/rustc_ast/Cargo.toml+1-1
......@@ -7,7 +7,7 @@ edition = "2024"
77# tidy-alphabetical-start
88bitflags = "2.4.1"
99memchr = "2.7.6"
10rustc-literal-escaper = "0.0.7"
10rustc-literal-escaper = "0.0.8"
1111rustc_ast_ir = { path = "../rustc_ast_ir" }
1212rustc_data_structures = { path = "../rustc_data_structures" }
1313rustc_index = { path = "../rustc_index" }
compiler/rustc_ast_lowering/src/delegation.rs+65-32
......@@ -194,7 +194,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
194194 return self.generate_delegation_error(span, delegation);
195195 }
196196
197 let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method);
197 let mut generics = self.uplift_delegation_generics(delegation, sig_id);
198198
199199 let (body_id, call_expr_id, unused_target_expr) = self.lower_delegation_body(
200200 delegation,
......@@ -404,10 +404,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
404404 hir::InferDelegationSig::Output(self.arena.alloc(hir::DelegationInfo {
405405 call_expr_id,
406406 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,
411411 group_id: {
412412 let id = match source {
413413 DelegationSource::Single => None,
......@@ -625,20 +625,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
625625 }),
626626 );
627627
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 };
632645
633 hir::QPath::TypeRelative(ty, self.arena.alloc(segment))
646 hir::QPath::Resolved(ty, self.arena.alloc(new_path))
634647 }
648 hir::QPath::TypeRelative(..) => unreachable!("until inherent methods are supported"),
635649 };
636650
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;
640661 }
641 .map(|ty| ty.hir_id);
642662
643663 let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span));
644664 let args = self.arena.alloc_from_iter(args);
......@@ -662,25 +682,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
662682 segment: &hir::PathSegment<'hir>,
663683 result: &mut GenericsGenerationResult<'hir>,
664684 ) -> 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 });
680714
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();
684717
685718 segment
686719 }
compiler/rustc_ast_lowering/src/delegation/generics.rs+304-194
......@@ -1,6 +1,7 @@
11use hir::HirId;
22use hir::def::{DefKind, Res};
33use rustc_ast::*;
4use rustc_data_structures::fx::FxHashSet;
45use rustc_hir as hir;
56use rustc_hir::def_id::DefId;
67use rustc_middle::ty::GenericParamDefKind;
......@@ -9,21 +10,7 @@ use rustc_span::symbol::kw;
910use rustc_span::{Ident, Span, sym};
1011
1112use crate::LoweringContext;
12
13#[derive(Clone, Copy)]
14pub(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}
13use crate::diagnostics::DelegationInfersMismatch;
2714
2815#[derive(Debug, Clone, Copy)]
2916pub(super) enum GenericsPosition {
......@@ -31,30 +18,30 @@ pub(super) enum GenericsPosition {
3118 Child,
3219}
3320
21#[derive(Debug)]
22pub(super) enum GenericArgSlot<T> {
23 UserSpecified,
24 Generate(T, Option<usize> /* Infer arg index from AST */),
25}
26
3427pub(super) struct DelegationGenerics<T> {
35 generics: T,
36 kind: DelegationGenericsKind,
28 data: T,
3729 pos: GenericsPosition,
30 trait_impl: bool,
3831}
3932
40impl<'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 }
33type TyGenerics<'hir> = Vec<GenericArgSlot<&'hir ty::GenericParamDef>>;
4834
49 fn trait_impl(
50 generics: &'hir [ty::GenericParamDef],
51 user_specified: bool,
35impl<'hir> DelegationGenerics<TyGenerics<'hir>> {
36 fn generate_all(
37 params: &'hir [ty::GenericParamDef],
5238 pos: GenericsPosition,
39 trait_impl: bool,
5340 ) -> Self {
5441 DelegationGenerics {
55 generics,
42 data: params.iter().map(|p| GenericArgSlot::Generate(p, None)).collect(),
5643 pos,
57 kind: DelegationGenericsKind::TraitImpl(user_specified),
44 trait_impl,
5845 }
5946 }
6047}
......@@ -70,103 +57,176 @@ impl<'hir> DelegationGenerics<&'hir [ty::GenericParamDef]> {
7057/// (i.e., method call scenarios), in such a case this approach helps
7158/// a lot as if `into_hir_generics` will not be called then uplifting will not happen.
7259pub(super) enum HirOrTyGenerics<'hir> {
73 Ty(DelegationGenerics<&'hir [ty::GenericParamDef]>),
60 Ty(DelegationGenerics<TyGenerics<'hir>>),
7461 Hir(DelegationGenerics<&'hir hir::Generics<'hir>>),
7562}
7663
7764pub(super) struct GenericsGenerationResult<'hir> {
7865 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
70impl GenericsGenerationResult<'_> {
71 pub(super) fn segment_id_for_sig(&self) -> Option<HirId> {
72 self.use_for_sig_inheritance.then(|| self.args_segment_id)
73 }
8074}
8175
8276pub(super) struct GenericsGenerationResults<'hir> {
8377 pub(super) parent: GenericsGenerationResult<'hir>,
8478 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>,
8780}
8881
89pub(super) struct GenericArgsPropagationDetails {
90 pub(super) should_propagate: bool,
91 pub(super) use_args_in_sig_inheritance: bool,
82pub(super) struct DelegationGenericArgsIterator<'hir> {
83 index: usize = Default::default(),
84 params: &'hir [hir::GenericParam<'hir>],
9285}
9386
94impl 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.
93impl<'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);
110149 }
150
151 args
111152 }
112153}
113154
114155impl<'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) {
120157 if let HirOrTyGenerics::Ty(ty) = self {
121158 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);
123160
124161 *self = HirOrTyGenerics::Hir(DelegationGenerics {
125 generics: params,
126 kind: ty.kind,
162 data: params,
127163 pos: ty.pos,
164 trait_impl: ty.trait_impl,
128165 });
129166 }
130
131 self
132167 }
133168
134169 fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> {
135170 match self {
136171 HirOrTyGenerics::Ty(_) => hir::Generics::empty(),
137 HirOrTyGenerics::Hir(hir) => hir.generics,
172 HirOrTyGenerics::Hir(hir) => hir.data,
138173 }
139174 }
140175
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> {
146177 match self {
147178 HirOrTyGenerics::Ty(_) => {
148 bug!("Attempting to get generic args before uplifting to HIR")
179 bug!("attempting to get generic args before uplifting to HIR")
149180 }
150181 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, .. }
153183 }
154184 }
155185 }
156186
157 pub(super) fn args_propagation_details(&self) -> GenericArgsPropagationDetails {
187 pub(super) fn infer_indices(&self) -> FxHashSet<usize> {
158188 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"),
161219 }
162220 }
163221}
164222
165223impl<'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 }
170230 }
171231}
172232
......@@ -208,13 +268,30 @@ impl<'hir> LoweringContext<'_, 'hir> {
208268 &mut self,
209269 delegation: &Delegation,
210270 sig_id: DefId,
211 is_method: bool,
212271 ) -> GenericsGenerationResults<'hir> {
213272 let delegation_parent_kind = self.tcx.def_kind(self.tcx.local_parent(self.owner.def_id));
214273
215274 let segments = &delegation.path.segments;
216275 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 };
218295
219296 let sig_params = &self.tcx.generics_of(sig_id).own_params[..];
220297
......@@ -223,23 +300,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
223300 if matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }) {
224301 // Considering parent generics, during signature inheritance
225302 // 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 };
228305
229 let child = DelegationGenerics::trait_impl(
230 sig_params,
231 child_user_specified,
232 GenericsPosition::Child,
233 );
306 let parent = GenericsGenerationResult::new(parent);
234307
308 let child = DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, true);
235309 let child = GenericsGenerationResult::new(child);
236310
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 };
243312 }
244313
245314 let delegation_in_free_ctx =
......@@ -248,7 +317,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
248317 let sig_parent = self.tcx.parent(sig_id);
249318 let sig_in_trait = matches!(self.tcx.def_kind(sig_parent), DefKind::Trait);
250319 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);
252327
253328 let can_add_generics_to_parent = len >= 2
254329 && self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| {
......@@ -256,57 +331,137 @@ impl<'hir> LoweringContext<'_, 'hir> {
256331 });
257332
258333 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,
271345 }
272346 } 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)..],
276349 GenericsPosition::Parent,
350 false,
277351 )
278352 }
279353 } else {
280 DelegationGenerics::default(&[], GenericsPosition::Parent)
354 DelegationGenerics { data: vec![], pos: GenericsPosition::Parent, trait_impl: false }
281355 };
282356
283 let child_generics = if child_user_specified {
357 let child_generics = if let Some(args) = get_user_args(len - 1) {
284358 let synth_params_index =
285359 sig_params.iter().position(|p| p.kind.is_synthetic()).unwrap_or(sig_params.len());
286360
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 }
291369 } else {
292 DelegationGenerics::default(sig_params, GenericsPosition::Child)
370 DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, false)
293371 };
294372
295373 GenericsGenerationResults {
296374 parent: GenericsGenerationResult::new(parent_generics),
297375 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 });
300451 }
452
453 slots
301454 }
302455
303456 fn uplift_delegation_generic_params(
304457 &mut self,
305458 span: Span,
306 params: &'hir [ty::GenericParamDef],
459 params: &[GenericArgSlot<&ty::GenericParamDef>],
307460 rename_self: bool,
308461 ) -> &'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
310465 let def_kind = match p.kind {
311466 GenericParamDefKind::Lifetime => DefKind::LifetimeParam,
312467 GenericParamDefKind::Type { .. } => DefKind::TyParam,
......@@ -354,7 +509,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
354509 // `lower_node_id` routine so param's id is added to `self.children`.
355510 let hir_id = self.lower_node_id(node_id);
356511
357 hir::GenericParam {
512 Some(hir::GenericParam {
358513 hir_id,
359514 colon_span: Some(span),
360515 def_id,
......@@ -363,7 +518,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
363518 pure_wrt_drop: p.pure_wrt_drop,
364519 source: hir::GenericParamSource::Generics,
365520 span,
366 }
521 })
367522 }));
368523
369524 // HACK: for now we generate predicates such that all lifetimes are early bound,
......@@ -413,77 +568,32 @@ impl<'hir> LoweringContext<'_, 'hir> {
413568 }
414569 }
415570
416 fn create_generics_args_from_params(
571 pub(super) fn create_generic_arg_path(
417572 &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 )
488598 }
489599}
compiler/rustc_ast_lowering/src/diagnostics.rs+9
......@@ -560,3 +560,12 @@ pub(crate) struct DelegationAttemptedBlockWithDefsDeletion {
560560 #[primary_span]
561561 pub span: Span,
562562}
563
564#[derive(Diagnostic)]
565#[diag("wrong infer used: expected {$expected}, found: {$actual}")]
566pub(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 @@
3131//! in the HIR, especially for multiple identifiers.
3232
3333// tidy-alphabetical-start
34#![feature(const_default)]
35#![feature(const_trait_impl)]
36#![feature(default_field_values)]
3437#![feature(deref_patterns)]
3538#![recursion_limit = "256"]
3639// tidy-alphabetical-end
compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs+3-3
......@@ -11,7 +11,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser {
1111 type Item = (Symbol, Span);
1212 const CONVERT: ConvertFn<Self::Item> =
1313 |items, span| AttributeKind::AllowInternalUnstable(items, span);
14 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
14 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1515 Allow(Target::MacroDef),
1616 Allow(Target::Fn),
1717 Warn(Target::Field),
......@@ -36,7 +36,7 @@ impl CombineAttributeParser for UnstableFeatureBoundParser {
3636 type Item = (Symbol, Span);
3737 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::UnstableFeatureBound(items);
3838 const STABILITY: AttributeStability = unstable!(staged_api);
39 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
39 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
4040 Allow(Target::Fn),
4141 Allow(Target::Impl { of_trait: true }),
4242 Allow(Target::Trait),
......@@ -59,7 +59,7 @@ impl CombineAttributeParser for RustcAllowConstFnUnstableParser {
5959 type Item = Symbol;
6060 const CONVERT: ConvertFn<Self::Item> =
6161 |items, first_span| AttributeKind::RustcAllowConstFnUnstable(items, first_span);
62 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
62 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
6363 Allow(Target::Fn),
6464 Allow(Target::Method(MethodKind::Inherent)),
6565 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;
1919
2020impl SingleAttributeParser for RustcAutodiffParser {
2121 const PATH: &[Symbol] = &[sym::rustc_autodiff];
22 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
22 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
2323 Allow(Target::Fn),
2424 Allow(Target::Method(MethodKind::Inherent)),
2525 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;
88
99impl NoArgsAttributeParser for CoroutineParser {
1010 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)]);
1213 const STABILITY: AttributeStability = unstable!(coroutines);
1314 const CREATE: fn(rustc_span::Span) -> AttributeKind = |_| AttributeKind::Coroutine;
1415}
compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs+1-1
......@@ -4,7 +4,7 @@ use super::prelude::*;
44pub(crate) struct CfiEncodingParser;
55impl SingleAttributeParser for CfiEncodingParser {
66 const PATH: &[Symbol] = &[sym::cfi_encoding];
7 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
7 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
88 Allow(Target::Struct),
99 Allow(Target::ForeignTy),
1010 Allow(Target::Enum),
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs+18-18
......@@ -18,7 +18,7 @@ pub(crate) struct OptimizeParser;
1818
1919impl SingleAttributeParser for OptimizeParser {
2020 const PATH: &[Symbol] = &[sym::optimize];
21 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
21 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
2222 Allow(Target::Fn),
2323 Allow(Target::Closure),
2424 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -51,7 +51,7 @@ pub(crate) struct ColdParser;
5151impl NoArgsAttributeParser for ColdParser {
5252 const PATH: &[Symbol] = &[sym::cold];
5353 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
54 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
54 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
5555 Allow(Target::Fn),
5656 Allow(Target::Method(MethodKind::Trait { body: true })),
5757 Allow(Target::Method(MethodKind::TraitImpl)),
......@@ -67,7 +67,7 @@ pub(crate) struct CoverageParser;
6767
6868impl SingleAttributeParser for CoverageParser {
6969 const PATH: &[Symbol] = &[sym::coverage];
70 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
70 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
7171 Allow(Target::Fn),
7272 Allow(Target::Closure),
7373 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -114,7 +114,7 @@ impl SingleAttributeParser for ExportNameParser {
114114 note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them",
115115 unsafe_since: Some(Edition2024),
116116 };
117 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
117 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
118118 Allow(Target::Static),
119119 Allow(Target::Fn),
120120 Allow(Target::Method(MethodKind::Inherent)),
......@@ -151,7 +151,7 @@ pub(crate) struct RustcObjcClassParser;
151151
152152impl SingleAttributeParser for RustcObjcClassParser {
153153 const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_class];
154 const ALLOWED_TARGETS: AllowedTargets =
154 const ALLOWED_TARGETS: AllowedTargets<'_> =
155155 AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]);
156156 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName");
157157 const STABILITY: AttributeStability = unstable!(rustc_attrs);
......@@ -179,7 +179,7 @@ pub(crate) struct RustcObjcSelectorParser;
179179
180180impl SingleAttributeParser for RustcObjcSelectorParser {
181181 const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_selector];
182 const ALLOWED_TARGETS: AllowedTargets =
182 const ALLOWED_TARGETS: AllowedTargets<'_> =
183183 AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]);
184184 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName");
185185 const STABILITY: AttributeStability = unstable!(rustc_attrs);
......@@ -226,7 +226,7 @@ impl AttributeParser for NakedParser {
226226 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).",
227227 unsafe_since: None,
228228 };
229 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
229 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
230230 Allow(Target::Fn),
231231 Allow(Target::Method(MethodKind::Inherent)),
232232 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -334,7 +334,7 @@ pub(crate) struct TrackCallerParser;
334334impl NoArgsAttributeParser for TrackCallerParser {
335335 const PATH: &[Symbol] = &[sym::track_caller];
336336 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
337 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
337 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
338338 Allow(Target::Fn),
339339 Allow(Target::Method(MethodKind::Inherent)),
340340 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -359,7 +359,7 @@ impl NoArgsAttributeParser for NoMangleParser {
359359 note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them",
360360 unsafe_since: Some(Edition2024),
361361 };
362 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
362 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
363363 Allow(Target::Fn),
364364 Allow(Target::Static),
365365 Allow(Target::Method(MethodKind::Inherent)),
......@@ -462,7 +462,7 @@ impl AttributeParser for UsedParser {
462462 }
463463 },
464464 )];
465 const ALLOWED_TARGETS: AllowedTargets =
465 const ALLOWED_TARGETS: AllowedTargets<'_> =
466466 AllowedTargets::AllowList(&[Allow(Target::Static), Warn(Target::MacroCall)]);
467467
468468 fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
......@@ -533,7 +533,7 @@ impl CombineAttributeParser for TargetFeatureParser {
533533 parse_tf_attribute(cx, args)
534534 }
535535
536 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
536 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
537537 Allow(Target::Fn),
538538 Allow(Target::Method(MethodKind::Inherent)),
539539 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -561,7 +561,7 @@ impl CombineAttributeParser for ForceTargetFeatureParser {
561561 was_forced: true,
562562 };
563563 const TEMPLATE: AttributeTemplate = template!(List: &["enable = \"feat1, feat2\""]);
564 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
564 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
565565 Allow(Target::Fn),
566566 Allow(Target::Method(MethodKind::Inherent)),
567567 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -581,7 +581,7 @@ pub(crate) struct InstrumentFnParser;
581581
582582impl SingleAttributeParser for InstrumentFnParser {
583583 const PATH: &[Symbol] = &[sym::instrument_fn];
584 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
584 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
585585 Allow(Target::Fn),
586586 Allow(Target::Method(MethodKind::Inherent)),
587587 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -619,7 +619,7 @@ pub(crate) struct SanitizeParser;
619619
620620impl SingleAttributeParser for SanitizeParser {
621621 const PATH: &[Symbol] = &[sym::sanitize];
622 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
622 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
623623 Allow(Target::Fn),
624624 Allow(Target::Closure),
625625 Allow(Target::Method(MethodKind::Inherent)),
......@@ -751,7 +751,7 @@ pub(crate) struct ThreadLocalParser;
751751
752752impl NoArgsAttributeParser for ThreadLocalParser {
753753 const PATH: &[Symbol] = &[sym::thread_local];
754 const ALLOWED_TARGETS: AllowedTargets =
754 const ALLOWED_TARGETS: AllowedTargets<'_> =
755755 AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]);
756756 const STABILITY: AttributeStability = unstable!(thread_local);
757757 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal;
......@@ -761,7 +761,7 @@ pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser;
761761
762762impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisParser {
763763 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)]);
765765 const STABILITY: AttributeStability = unstable!(rustc_attrs);
766766 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis;
767767}
......@@ -770,7 +770,7 @@ pub(crate) struct RustcEiiForeignItemParser;
770770
771771impl NoArgsAttributeParser for RustcEiiForeignItemParser {
772772 const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item];
773 const ALLOWED_TARGETS: AllowedTargets =
773 const ALLOWED_TARGETS: AllowedTargets<'_> =
774774 AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]);
775775 const STABILITY: AttributeStability = unstable!(eii_internals);
776776 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem;
......@@ -780,7 +780,7 @@ pub(crate) struct PatchableFunctionEntryParser;
780780
781781impl SingleAttributeParser for PatchableFunctionEntryParser {
782782 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)]);
784784 const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]);
785785 const STABILITY: AttributeStability = unstable!(patchable_function_entry);
786786
compiler/rustc_attr_parsing/src/attributes/confusables.rs+1-1
......@@ -32,7 +32,7 @@ impl AttributeParser for ConfusablesParser {
3232 this.first_span.get_or_insert(cx.attr_span);
3333 },
3434 )];
35 const ALLOWED_TARGETS: AllowedTargets =
35 const ALLOWED_TARGETS: AllowedTargets<'_> =
3636 AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
3737
3838 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;
22use rustc_hir::attrs::{CrateType, WindowsSubsystemKind};
33use rustc_session::lint::builtin::UNKNOWN_CRATE_TYPES;
44use rustc_span::Symbol;
5use rustc_span::edit_distance::find_best_match_for_name;
5use rustc_span::edit_distance::find_best_match_for_name_with_substrings;
66
77use super::prelude::*;
88use crate::diagnostics::{UnknownCrateTypes, UnknownCrateTypesSuggestion};
......@@ -13,7 +13,7 @@ impl SingleAttributeParser for CrateNameParser {
1313 const PATH: &[Symbol] = &[sym::crate_name];
1414 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
1515 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
16 const ALLOWED_TARGETS: AllowedTargets =
16 const ALLOWED_TARGETS: AllowedTargets<'_> =
1717 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
1818 const STABILITY: AttributeStability = AttributeStability::Stable;
1919
......@@ -32,7 +32,7 @@ impl CombineAttributeParser for CrateTypeParser {
3232 const PATH: &[Symbol] = &[sym::crate_type];
3333 type Item = CrateType;
3434 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::CrateType(items);
35 const ALLOWED_TARGETS: AllowedTargets =
35 const ALLOWED_TARGETS: AllowedTargets<'_> =
3636 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
3737 const TEMPLATE: AttributeTemplate =
3838 template!(NameValueStr: "crate type", "https://doc.rust-lang.org/reference/linkage.html");
......@@ -49,10 +49,10 @@ impl CombineAttributeParser for CrateTypeParser {
4949 let Ok(crate_type) = crate_type.try_into() else {
5050 // We don't error on invalid `#![crate_type]` when not applied to a crate
5151 if cx.shared.target == Target::Crate {
52 let candidate = find_best_match_for_name(
52 let candidate = find_best_match_for_name_with_substrings(
5353 &CrateType::all_stable().iter().map(|(name, _)| *name).collect::<Vec<_>>(),
5454 crate_type,
55 None,
55 Some(5),
5656 );
5757 let span = n.value_span;
5858 cx.emit_lint(
......@@ -76,7 +76,7 @@ impl SingleAttributeParser for RecursionLimitParser {
7676 const PATH: &[Symbol] = &[sym::recursion_limit];
7777 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
7878 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<'_> =
8080 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
8181 const STABILITY: AttributeStability = AttributeStability::Stable;
8282
......@@ -92,7 +92,7 @@ pub(crate) struct MoveSizeLimitParser;
9292impl SingleAttributeParser for MoveSizeLimitParser {
9393 const PATH: &[Symbol] = &[sym::move_size_limit];
9494 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)]);
9696 const STABILITY: AttributeStability = unstable!(large_assignments);
9797
9898 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
......@@ -108,7 +108,7 @@ impl SingleAttributeParser for TypeLengthLimitParser {
108108 const PATH: &[Symbol] = &[sym::type_length_limit];
109109 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
110110 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
111 const ALLOWED_TARGETS: AllowedTargets =
111 const ALLOWED_TARGETS: AllowedTargets<'_> =
112112 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
113113 const STABILITY: AttributeStability = AttributeStability::Stable;
114114
......@@ -124,7 +124,7 @@ pub(crate) struct PatternComplexityLimitParser;
124124impl SingleAttributeParser for PatternComplexityLimitParser {
125125 const PATH: &[Symbol] = &[sym::pattern_complexity_limit];
126126 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)]);
128128 const STABILITY: AttributeStability = unstable!(
129129 rustc_attrs,
130130 "the `#[pattern_complexity_limit]` attribute is used for rustc unit tests"
......@@ -141,7 +141,7 @@ pub(crate) struct NoCoreParser;
141141
142142impl NoArgsAttributeParser for NoCoreParser {
143143 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)]);
145145 const STABILITY: AttributeStability = unstable!(no_core);
146146 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoCore;
147147}
......@@ -151,7 +151,7 @@ pub(crate) struct NoStdParser;
151151impl NoArgsAttributeParser for NoStdParser {
152152 const PATH: &[Symbol] = &[sym::no_std];
153153 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
154 const ALLOWED_TARGETS: AllowedTargets =
154 const ALLOWED_TARGETS: AllowedTargets<'_> =
155155 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
156156 const STABILITY: AttributeStability = AttributeStability::Stable;
157157 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoStd;
......@@ -162,7 +162,7 @@ pub(crate) struct NoMainParser;
162162impl NoArgsAttributeParser for NoMainParser {
163163 const PATH: &[Symbol] = &[sym::no_main];
164164 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
165 const ALLOWED_TARGETS: AllowedTargets =
165 const ALLOWED_TARGETS: AllowedTargets<'_> =
166166 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
167167 const STABILITY: AttributeStability = AttributeStability::Stable;
168168 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain;
......@@ -172,7 +172,7 @@ pub(crate) struct RustcCoherenceIsCoreParser;
172172
173173impl NoArgsAttributeParser for RustcCoherenceIsCoreParser {
174174 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)]);
176176 const STABILITY: AttributeStability = unstable!(rustc_attrs);
177177 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoherenceIsCore;
178178}
......@@ -182,7 +182,7 @@ pub(crate) struct WindowsSubsystemParser;
182182impl SingleAttributeParser for WindowsSubsystemParser {
183183 const PATH: &[Symbol] = &[sym::windows_subsystem];
184184 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
185 const ALLOWED_TARGETS: AllowedTargets =
185 const ALLOWED_TARGETS: AllowedTargets<'_> =
186186 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
187187 const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute");
188188 const STABILITY: AttributeStability = AttributeStability::Stable;
......@@ -210,7 +210,7 @@ pub(crate) struct PanicRuntimeParser;
210210
211211impl NoArgsAttributeParser for PanicRuntimeParser {
212212 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)]);
214214 const STABILITY: AttributeStability = unstable!(panic_runtime);
215215 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PanicRuntime;
216216}
......@@ -219,7 +219,7 @@ pub(crate) struct NeedsPanicRuntimeParser;
219219
220220impl NoArgsAttributeParser for NeedsPanicRuntimeParser {
221221 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)]);
223223 const STABILITY: AttributeStability = unstable!(needs_panic_runtime);
224224 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsPanicRuntime;
225225}
......@@ -228,7 +228,7 @@ pub(crate) struct ProfilerRuntimeParser;
228228
229229impl NoArgsAttributeParser for ProfilerRuntimeParser {
230230 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)]);
232232 const STABILITY: AttributeStability = unstable!(profiler_runtime);
233233 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProfilerRuntime;
234234}
......@@ -238,7 +238,7 @@ pub(crate) struct NoBuiltinsParser;
238238impl NoArgsAttributeParser for NoBuiltinsParser {
239239 const PATH: &[Symbol] = &[sym::no_builtins];
240240 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
241 const ALLOWED_TARGETS: AllowedTargets =
241 const ALLOWED_TARGETS: AllowedTargets<'_> =
242242 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
243243 const STABILITY: AttributeStability = AttributeStability::Stable;
244244 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoBuiltins;
......@@ -248,7 +248,7 @@ pub(crate) struct RustcPreserveUbChecksParser;
248248
249249impl NoArgsAttributeParser for RustcPreserveUbChecksParser {
250250 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)]);
252252 const STABILITY: AttributeStability = unstable!(rustc_attrs);
253253 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPreserveUbChecks;
254254}
......@@ -257,7 +257,7 @@ pub(crate) struct RustcNoImplicitBoundsParser;
257257
258258impl NoArgsAttributeParser for RustcNoImplicitBoundsParser {
259259 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)]);
261261 const STABILITY: AttributeStability = unstable!(rustc_attrs);
262262 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitBounds;
263263}
......@@ -266,7 +266,7 @@ pub(crate) struct DefaultLibAllocatorParser;
266266
267267impl NoArgsAttributeParser for DefaultLibAllocatorParser {
268268 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)]);
270270 const STABILITY: AttributeStability = unstable!(allocator_internals);
271271 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::DefaultLibAllocator;
272272}
......@@ -277,7 +277,7 @@ impl CombineAttributeParser for FeatureParser {
277277 const PATH: &[Symbol] = &[sym::feature];
278278 type Item = Ident;
279279 const CONVERT: ConvertFn<Self::Item> = AttributeKind::Feature;
280 const ALLOWED_TARGETS: AllowedTargets =
280 const ALLOWED_TARGETS: AllowedTargets<'_> =
281281 AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate)]);
282282 const TEMPLATE: AttributeTemplate = template!(List: &["feature1, feature2, ..."]);
283283 const STABILITY: AttributeStability = AttributeStability::Stable;
......@@ -323,7 +323,7 @@ impl CombineAttributeParser for RegisterToolParser {
323323 const PATH: &[Symbol] = &[sym::register_tool];
324324 type Item = Ident;
325325 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)]);
327327 const TEMPLATE: AttributeTemplate = template!(List: &["tool1, tool2, ..."]);
328328 const STABILITY: AttributeStability = unstable!(register_tool);
329329
compiler/rustc_attr_parsing/src/attributes/debugger.rs+1-1
......@@ -7,7 +7,7 @@ pub(crate) struct DebuggerVisualizerParser;
77
88impl CombineAttributeParser for DebuggerVisualizerParser {
99 const PATH: &[Symbol] = &[sym::debugger_visualizer];
10 const ALLOWED_TARGETS: AllowedTargets =
10 const ALLOWED_TARGETS: AllowedTargets<'_> =
1111 AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]);
1212 const TEMPLATE: AttributeTemplate = template!(
1313 List: &[r#"natvis_file = "...", gdb_script_file = "...""#],
compiler/rustc_attr_parsing/src/attributes/deprecation.rs+1-1
......@@ -32,7 +32,7 @@ fn get(
3232pub(crate) struct DeprecatedParser;
3333impl SingleAttributeParser for DeprecatedParser {
3434 const PATH: &[Symbol] = &[sym::deprecated];
35 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
35 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
3636 Allow(Target::Fn),
3737 Allow(Target::Mod),
3838 Allow(Target::Struct),
compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs+1-1
......@@ -16,7 +16,7 @@ impl SingleAttributeParser for DoNotRecommendParser {
1616 const PATH: &[Symbol] = &[sym::diagnostic, sym::do_not_recommend];
1717 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
1818 // "Allowed" on any target, noop on all but trait impls
19 const ALLOWED_TARGETS: AllowedTargets =
19 const ALLOWED_TARGETS: AllowedTargets<'_> =
2020 AllowedTargets::AllowListWarnRest(&[Allow(Target::Impl { of_trait: true })]);
2121 const TEMPLATE: AttributeTemplate = template!(Word /*doesn't matter */);
2222 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 {
3737
3838 // "Allowed" on all targets; noop on anything but non-const trait impls;
3939 // this linted on in parser.
40 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
40 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
4141 // FIXME(mejrs) no constness field on `Target`,
4242 // so non-constness is still checked in check_attr.rs
4343 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 {
4343 },
4444 )];
4545
46 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
46 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
4747 Allow(Target::Enum),
4848 Allow(Target::Struct),
4949 Allow(Target::Union),
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_type_error.rs+1-1
......@@ -42,7 +42,7 @@ impl AttributeParser for OnTypeErrorParser {
4242 },
4343 )];
4444
45 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
45 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
4646 Allow(Target::Enum),
4747 Allow(Target::Struct),
4848 Allow(Target::Union),
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs+1-1
......@@ -45,7 +45,7 @@ impl AttributeParser for OnUnimplementedParser {
4545 },
4646 ),
4747 ];
48 const ALLOWED_TARGETS: AllowedTargets =
48 const ALLOWED_TARGETS: AllowedTargets<'_> =
4949 AllowedTargets::AllowListWarnRest(&[Allow(Target::Trait)]);
5050
5151 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 {
4040 },
4141 )];
4242 // "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(&[
4444 Allow(Target::Use),
4545 Allow(Target::Mod),
4646 Allow(Target::Crate),
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unmatched_args.rs+1-1
......@@ -33,7 +33,7 @@ impl AttributeParser for OnUnmatchedArgsParser {
3333 },
3434 )];
3535
36 const ALLOWED_TARGETS: AllowedTargets =
36 const ALLOWED_TARGETS: AllowedTargets<'_> =
3737 AllowedTargets::AllowListWarnRest(&[Allow(Target::MacroDef)]);
3838
3939 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 {
706706 },
707707 )];
708708 // 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(&[
711711 // Allow(Target::ExternCrate),
712712 // Allow(Target::Use),
713713 // Allow(Target::Static),
compiler/rustc_attr_parsing/src/attributes/dummy.rs+1-1
......@@ -12,7 +12,7 @@ pub(crate) struct RustcDummyParser;
1212impl SingleAttributeParser for RustcDummyParser {
1313 const PATH: &[Symbol] = &[sym::rustc_dummy];
1414 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore;
15 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::ManuallyChecked;
15 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked;
1616 const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really
1717 const STABILITY: AttributeStability =
1818 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;
1313impl SingleAttributeParser for InlineParser {
1414 const PATH: &[Symbol] = &[sym::inline];
1515 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
16 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
16 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1717 Allow(Target::Fn),
1818 Allow(Target::Method(MethodKind::Inherent)),
1919 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -66,7 +66,7 @@ pub(crate) struct RustcForceInlineParser;
6666
6767impl SingleAttributeParser for RustcForceInlineParser {
6868 const PATH: &[Symbol] = &[sym::rustc_force_inline];
69 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
69 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
7070 Allow(Target::Fn),
7171 Allow(Target::Method(MethodKind::Inherent)),
7272 ]);
compiler/rustc_attr_parsing/src/attributes/instruction_set.rs+1-1
......@@ -8,7 +8,7 @@ pub(crate) struct InstructionSetParser;
88
99impl SingleAttributeParser for InstructionSetParser {
1010 const PATH: &[Symbol] = &[sym::instruction_set];
11 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
11 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
1212 Allow(Target::Fn),
1313 Allow(Target::Closure),
1414 Allow(Target::Method(MethodKind::Inherent)),
compiler/rustc_attr_parsing/src/attributes/link_attrs.rs+13-11
......@@ -26,7 +26,7 @@ pub(crate) struct LinkNameParser;
2626impl SingleAttributeParser for LinkNameParser {
2727 const PATH: &[Symbol] = &[sym::link_name];
2828 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
29 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
29 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
3030 Allow(Target::ForeignFn),
3131 Allow(Target::ForeignStatic),
3232 ]);
......@@ -70,7 +70,7 @@ impl CombineAttributeParser for LinkParser {
7070 r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#,
7171 r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#,
7272 ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute");
73 const ALLOWED_TARGETS: AllowedTargets =
73 const ALLOWED_TARGETS: AllowedTargets<'_> =
7474 AllowedTargets::AllowListWarnRest(&[Allow(Target::ForeignMod)]);
7575 const STABILITY: AttributeStability = AttributeStability::Stable;
7676
......@@ -494,7 +494,7 @@ impl SingleAttributeParser for LinkSectionParser {
494494 unsafe_since: Some(Edition2024),
495495 };
496496 const STABILITY: AttributeStability = AttributeStability::Stable;
497 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
497 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
498498 Allow(Target::Static),
499499 Allow(Target::Fn),
500500 Allow(Target::Method(MethodKind::Inherent)),
......@@ -535,7 +535,7 @@ impl SingleAttributeParser for LinkSectionParser {
535535pub(crate) struct ExportStableParser;
536536impl NoArgsAttributeParser for ExportStableParser {
537537 const PATH: &[Symbol] = &[sym::export_stable];
538 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
538 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
539539 Allow(Target::Fn),
540540 Allow(Target::Method(MethodKind::Inherent)),
541541 Allow(Target::Struct),
......@@ -558,7 +558,8 @@ impl NoArgsAttributeParser for FfiConstParser {
558558 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.",
559559 unsafe_since: None,
560560 };
561 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
561 const ALLOWED_TARGETS: AllowedTargets<'_> =
562 AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
562563 const STABILITY: AttributeStability = unstable!(ffi_const);
563564 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::FfiConst;
564565}
......@@ -570,7 +571,8 @@ impl NoArgsAttributeParser for FfiPureParser {
570571 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.",
571572 unsafe_since: None,
572573 };
573 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
574 const ALLOWED_TARGETS: AllowedTargets<'_> =
575 AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
574576 const STABILITY: AttributeStability = unstable!(ffi_pure);
575577 const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure;
576578}
......@@ -578,7 +580,7 @@ impl NoArgsAttributeParser for FfiPureParser {
578580pub(crate) struct RustcStdInternalSymbolParser;
579581impl NoArgsAttributeParser for RustcStdInternalSymbolParser {
580582 const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol];
581 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
583 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
582584 Allow(Target::Fn),
583585 Allow(Target::ForeignFn),
584586 Allow(Target::Static),
......@@ -592,7 +594,7 @@ pub(crate) struct LinkOrdinalParser;
592594
593595impl SingleAttributeParser for LinkOrdinalParser {
594596 const PATH: &[Symbol] = &[sym::link_ordinal];
595 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
597 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
596598 Allow(Target::ForeignFn),
597599 Allow(Target::ForeignStatic),
598600 Warn(Target::MacroCall),
......@@ -632,7 +634,7 @@ pub(crate) struct LinkageParser;
632634
633635impl SingleAttributeParser for LinkageParser {
634636 const PATH: &[Symbol] = &[sym::linkage];
635 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
637 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
636638 Allow(Target::Fn),
637639 Allow(Target::Method(MethodKind::Inherent)),
638640 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -708,7 +710,7 @@ pub(crate) struct NeedsAllocatorParser;
708710
709711impl NoArgsAttributeParser for NeedsAllocatorParser {
710712 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)]);
712714 const STABILITY: AttributeStability = unstable!(allocator_internals);
713715 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsAllocator;
714716}
......@@ -717,7 +719,7 @@ pub(crate) struct CompilerBuiltinsParser;
717719
718720impl NoArgsAttributeParser for CompilerBuiltinsParser {
719721 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)]);
721723 const STABILITY: AttributeStability = unstable!(compiler_builtins);
722724 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CompilerBuiltins;
723725}
compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs+5-5
......@@ -5,7 +5,7 @@ use super::prelude::*;
55pub(crate) struct RustcAsPtrParser;
66impl NoArgsAttributeParser for RustcAsPtrParser {
77 const PATH: &[Symbol] = &[sym::rustc_as_ptr];
8 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
8 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
99 Allow(Target::Fn),
1010 Allow(Target::Method(MethodKind::Inherent)),
1111 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -19,7 +19,7 @@ impl NoArgsAttributeParser for RustcAsPtrParser {
1919pub(crate) struct RustcPubTransparentParser;
2020impl NoArgsAttributeParser for RustcPubTransparentParser {
2121 const PATH: &[Symbol] = &[sym::rustc_pub_transparent];
22 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
22 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
2323 Allow(Target::Struct),
2424 Allow(Target::Enum),
2525 Allow(Target::Union),
......@@ -31,7 +31,7 @@ impl NoArgsAttributeParser for RustcPubTransparentParser {
3131pub(crate) struct RustcPassByValueParser;
3232impl NoArgsAttributeParser for RustcPassByValueParser {
3333 const PATH: &[Symbol] = &[sym::rustc_pass_by_value];
34 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
34 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
3535 Allow(Target::Struct),
3636 Allow(Target::Enum),
3737 Allow(Target::TyAlias),
......@@ -43,7 +43,7 @@ impl NoArgsAttributeParser for RustcPassByValueParser {
4343pub(crate) struct RustcShouldNotBeCalledOnConstItemsParser;
4444impl NoArgsAttributeParser for RustcShouldNotBeCalledOnConstItemsParser {
4545 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(&[
4747 Allow(Target::Method(MethodKind::Inherent)),
4848 Allow(Target::Method(MethodKind::TraitImpl)),
4949 ]);
......@@ -55,7 +55,7 @@ pub(crate) struct AutomaticallyDerivedParser;
5555impl NoArgsAttributeParser for AutomaticallyDerivedParser {
5656 const PATH: &[Symbol] = &[sym::automatically_derived];
5757 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
58 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
58 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
5959 Allow(Target::Impl { of_trait: true }),
6060 Error(Target::Crate),
6161 Error(Target::WherePredicate),
compiler/rustc_attr_parsing/src/attributes/loop_match.rs+2-2
......@@ -5,7 +5,7 @@ use super::prelude::*;
55pub(crate) struct LoopMatchParser;
66impl NoArgsAttributeParser for LoopMatchParser {
77 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)]);
99 const STABILITY: AttributeStability = unstable!(loop_match);
1010 const CREATE: fn(Span) -> AttributeKind = AttributeKind::LoopMatch;
1111}
......@@ -13,7 +13,7 @@ impl NoArgsAttributeParser for LoopMatchParser {
1313pub(crate) struct ConstContinueParser;
1414impl NoArgsAttributeParser for ConstContinueParser {
1515 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)]);
1717 const STABILITY: AttributeStability = unstable!(loop_match);
1818 const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstContinue;
1919}
compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs+8-7
......@@ -8,7 +8,7 @@ pub(crate) struct MacroEscapeParser;
88impl NoArgsAttributeParser for MacroEscapeParser {
99 const PATH: &[Symbol] = &[sym::macro_escape];
1010 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
11 const ALLOWED_TARGETS: AllowedTargets = MACRO_USE_ALLOWED_TARGETS;
11 const ALLOWED_TARGETS: AllowedTargets<'_> = MACRO_USE_ALLOWED_TARGETS;
1212 const STABILITY: AttributeStability = AttributeStability::Stable;
1313 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::MacroEscape;
1414}
......@@ -32,7 +32,7 @@ const MACRO_USE_TEMPLATE: AttributeTemplate = template!(
3232 Word, List: &["name1, name2, ..."],
3333 "https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute"
3434);
35const MACRO_USE_ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
35const MACRO_USE_ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
3636 Allow(Target::Mod),
3737 Allow(Target::ExternCrate),
3838 Error(Target::WherePredicate),
......@@ -106,7 +106,7 @@ impl AttributeParser for MacroUseParser {
106106 }
107107 },
108108 )];
109 const ALLOWED_TARGETS: AllowedTargets = MACRO_USE_ALLOWED_TARGETS;
109 const ALLOWED_TARGETS: AllowedTargets<'_> = MACRO_USE_ALLOWED_TARGETS;
110110
111111 fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
112112 Some(AttributeKind::MacroUse { span: self.first_span?, arguments: self.state })
......@@ -118,7 +118,7 @@ pub(crate) struct AllowInternalUnsafeParser;
118118impl NoArgsAttributeParser for AllowInternalUnsafeParser {
119119 const PATH: &[Symbol] = &[sym::allow_internal_unsafe];
120120 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore;
121 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
121 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
122122 Allow(Target::Fn),
123123 Allow(Target::MacroDef),
124124 Warn(Target::Field),
......@@ -134,7 +134,7 @@ impl SingleAttributeParser for MacroExportParser {
134134 const PATH: &[Symbol] = &[sym::macro_export];
135135 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
136136 const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]);
137 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
137 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
138138 Allow(Target::MacroDef),
139139 Error(Target::WherePredicate),
140140 Error(Target::Crate),
......@@ -174,7 +174,8 @@ impl SingleAttributeParser for CollapseDebugInfoParser {
174174 List: &["no", "external", "yes"],
175175 "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute"
176176 );
177 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
177 const ALLOWED_TARGETS: AllowedTargets<'_> =
178 AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
178179 const STABILITY: AttributeStability = AttributeStability::Stable;
179180
180181 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
......@@ -204,7 +205,7 @@ pub(crate) struct RustcProcMacroDeclsParser;
204205
205206impl NoArgsAttributeParser for RustcProcMacroDeclsParser {
206207 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)]);
208209 const STABILITY: AttributeStability = unstable!(rustc_attrs);
209210 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcProcMacroDecls;
210211}
compiler/rustc_attr_parsing/src/attributes/mod.rs+7-7
......@@ -105,7 +105,7 @@ pub(crate) trait AttributeParser: Default + 'static {
105105 ///
106106 /// If an attribute has this symbol, the `accept` function will be called on it.
107107 const ATTRIBUTES: AcceptMapping<Self>;
108 const ALLOWED_TARGETS: AllowedTargets;
108 const ALLOWED_TARGETS: AllowedTargets<'_>;
109109 const SAFETY: AttributeSafety = AttributeSafety::Normal;
110110
111111 /// The parser has gotten a chance to accept the attributes on an item,
......@@ -140,7 +140,7 @@ pub(crate) trait SingleAttributeParser: 'static {
140140 const SAFETY: AttributeSafety = AttributeSafety::Normal;
141141 const STABILITY: AttributeStability;
142142
143 const ALLOWED_TARGETS: AllowedTargets;
143 const ALLOWED_TARGETS: AllowedTargets<'_>;
144144
145145 /// The template this attribute parser should implement. Used for diagnostics.
146146 const TEMPLATE: AttributeTemplate;
......@@ -174,7 +174,7 @@ impl<T: SingleAttributeParser> AttributeParser for Single<T> {
174174 }
175175 },
176176 )];
177 const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
177 const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS;
178178 const SAFETY: AttributeSafety = T::SAFETY;
179179
180180 fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
......@@ -252,7 +252,7 @@ pub enum AttributeSafety {
252252pub(crate) trait NoArgsAttributeParser: 'static {
253253 const PATH: &[Symbol];
254254 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
255 const ALLOWED_TARGETS: AllowedTargets;
255 const ALLOWED_TARGETS: AllowedTargets<'_>;
256256 const SAFETY: AttributeSafety = AttributeSafety::Normal;
257257 const STABILITY: AttributeStability;
258258
......@@ -273,7 +273,7 @@ impl<T: NoArgsAttributeParser> SingleAttributeParser for WithoutArgs<T> {
273273 const ON_DUPLICATE: OnDuplicate = T::ON_DUPLICATE;
274274 const SAFETY: AttributeSafety = T::SAFETY;
275275 const STABILITY: AttributeStability = T::STABILITY;
276 const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
276 const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS;
277277 const TEMPLATE: AttributeTemplate = template!(Word);
278278
279279 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
......@@ -303,7 +303,7 @@ pub(crate) trait CombineAttributeParser: 'static {
303303 const SAFETY: AttributeSafety = AttributeSafety::Normal;
304304 const STABILITY: AttributeStability;
305305
306 const ALLOWED_TARGETS: AllowedTargets;
306 const ALLOWED_TARGETS: AllowedTargets<'_>;
307307
308308 /// The template this attribute parser should implement. Used for diagnostics.
309309 const TEMPLATE: AttributeTemplate;
......@@ -342,7 +342,7 @@ impl<T: CombineAttributeParser> AttributeParser for Combine<T> {
342342 group.first_span.get_or_insert(cx.attr_span);
343343 group.items.extend(T::extend(cx, args))
344344 })];
345 const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
345 const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS;
346346 const SAFETY: AttributeSafety = T::SAFETY;
347347
348348 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;
66
77impl SingleAttributeParser for MustNotSuspendParser {
88 const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend];
9 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
9 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1010 Allow(Target::Struct),
1111 Allow(Target::Enum),
1212 Allow(Target::Union),
compiler/rustc_attr_parsing/src/attributes/must_use.rs+1-1
......@@ -7,7 +7,7 @@ pub(crate) struct MustUseParser;
77impl SingleAttributeParser for MustUseParser {
88 const PATH: &[Symbol] = &[sym::must_use];
99 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
10 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
10 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[
1111 Allow(Target::Fn),
1212 Allow(Target::Enum),
1313 Allow(Target::Struct),
compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs+1-1
......@@ -7,7 +7,7 @@ pub(crate) struct NoImplicitPreludeParser;
77impl NoArgsAttributeParser for NoImplicitPreludeParser {
88 const PATH: &[rustc_span::Symbol] = &[sym::no_implicit_prelude];
99 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
10 const ALLOWED_TARGETS: AllowedTargets =
10 const ALLOWED_TARGETS: AllowedTargets<'_> =
1111 AllowedTargets::AllowListWarnRest(&[Allow(Target::Mod), Allow(Target::Crate)]);
1212 const STABILITY: AttributeStability = AttributeStability::Stable;
1313 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;
66impl NoArgsAttributeParser for NoLinkParser {
77 const PATH: &[Symbol] = &[sym::no_link];
88 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
9 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
9 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1010 Allow(Target::ExternCrate),
1111 Warn(Target::Field),
1212 Warn(Target::Arm),
compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs+1-1
......@@ -12,7 +12,7 @@ pub(crate) struct NonExhaustiveParser;
1212impl NoArgsAttributeParser for NonExhaustiveParser {
1313 const PATH: &[Symbol] = &[sym::non_exhaustive];
1414 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
15 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
15 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1616 Allow(Target::Enum),
1717 Allow(Target::Struct),
1818 Allow(Target::Variant),
compiler/rustc_attr_parsing/src/attributes/path.rs+1-1
......@@ -7,7 +7,7 @@ pub(crate) struct PathParser;
77impl SingleAttributeParser for PathParser {
88 const PATH: &[Symbol] = &[sym::path];
99 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
10 const ALLOWED_TARGETS: AllowedTargets =
10 const ALLOWED_TARGETS: AllowedTargets<'_> =
1111 AllowedTargets::AllowListWarnRest(&[Allow(Target::Mod), Error(Target::Crate)]);
1212 const TEMPLATE: AttributeTemplate = template!(
1313 NameValueStr: "file",
compiler/rustc_attr_parsing/src/attributes/pin_v2.rs+1-1
......@@ -12,7 +12,7 @@ pub(crate) struct PinV2Parser;
1212
1313impl NoArgsAttributeParser for PinV2Parser {
1414 const PATH: &[Symbol] = &[sym::pin_v2];
15 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
15 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1616 Allow(Target::Enum),
1717 Allow(Target::Struct),
1818 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;
33
44use super::prelude::*;
55
6const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets =
6const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets<'_> =
77 AllowedTargets::AllowList(&[Allow(Target::Fn), Warn(Target::Crate), Warn(Target::MacroCall)]);
88
99pub(crate) struct ProcMacroParser;
1010impl NoArgsAttributeParser for ProcMacroParser {
1111 const PATH: &[Symbol] = &[sym::proc_macro];
12 const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS;
12 const ALLOWED_TARGETS: AllowedTargets<'_> = PROC_MACRO_ALLOWED_TARGETS;
1313 const STABILITY: AttributeStability = AttributeStability::Stable;
1414 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProcMacro;
1515}
......@@ -17,7 +17,7 @@ impl NoArgsAttributeParser for ProcMacroParser {
1717pub(crate) struct ProcMacroAttributeParser;
1818impl NoArgsAttributeParser for ProcMacroAttributeParser {
1919 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;
2121 const STABILITY: AttributeStability = AttributeStability::Stable;
2222 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProcMacroAttribute;
2323}
......@@ -25,7 +25,7 @@ impl NoArgsAttributeParser for ProcMacroAttributeParser {
2525pub(crate) struct ProcMacroDeriveParser;
2626impl SingleAttributeParser for ProcMacroDeriveParser {
2727 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;
2929 const TEMPLATE: AttributeTemplate = template!(
3030 List: &["TraitName", "TraitName, attributes(name1, name2, ...)"],
3131 "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros"
......@@ -44,7 +44,8 @@ impl SingleAttributeParser for ProcMacroDeriveParser {
4444pub(crate) struct RustcBuiltinMacroParser;
4545impl SingleAttributeParser for RustcBuiltinMacroParser {
4646 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)]);
4849 const TEMPLATE: AttributeTemplate =
4950 template!(List: &["TraitName", "TraitName, attributes(name1, name2, ...)"]);
5051 const STABILITY: AttributeStability = unstable!(rustc_attrs);
compiler/rustc_attr_parsing/src/attributes/prototype.rs+1-1
......@@ -18,7 +18,7 @@ impl SingleAttributeParser for CustomMirParser {
1818 const PATH: &[rustc_span::Symbol] = &[sym::custom_mir];
1919 const STABILITY: AttributeStability = unstable!(custom_mir);
2020
21 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
21 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
2222
2323 const TEMPLATE: AttributeTemplate = template!(List: &[r#"dialect = "...", phase = "...""#]);
2424
compiler/rustc_attr_parsing/src/attributes/repr.rs+3-3
......@@ -63,7 +63,7 @@ impl CombineAttributeParser for ReprParser {
6363 reprs
6464 }
6565
66 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::ManuallyChecked;
66 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked;
6767 const STABILITY: AttributeStability = AttributeStability::Stable;
6868}
6969
......@@ -306,7 +306,7 @@ impl RustcAlignParser {
306306impl AttributeParser for RustcAlignParser {
307307 const ATTRIBUTES: AcceptMapping<Self> =
308308 &[(Self::PATH, Self::TEMPLATE, unstable!(fn_align), Self::parse)];
309 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
309 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
310310 Allow(Target::Fn),
311311 Allow(Target::Method(MethodKind::Inherent)),
312312 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -336,7 +336,7 @@ impl RustcAlignStaticParser {
336336impl AttributeParser for RustcAlignStaticParser {
337337 const ATTRIBUTES: AcceptMapping<Self> =
338338 &[(Self::PATH, Self::TEMPLATE, unstable!(static_align), Self::parse)];
339 const ALLOWED_TARGETS: AllowedTargets =
339 const ALLOWED_TARGETS: AllowedTargets<'_> =
340340 AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]);
341341
342342 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;
66
77impl NoArgsAttributeParser for RustcAllocatorParser {
88 const PATH: &[Symbol] = &[sym::rustc_allocator];
9 const ALLOWED_TARGETS: AllowedTargets =
9 const ALLOWED_TARGETS: AllowedTargets<'_> =
1010 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
1111 const STABILITY: AttributeStability = unstable!(rustc_attrs);
1212 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator;
......@@ -16,7 +16,7 @@ pub(crate) struct RustcAllocatorZeroedParser;
1616
1717impl NoArgsAttributeParser for RustcAllocatorZeroedParser {
1818 const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed];
19 const ALLOWED_TARGETS: AllowedTargets =
19 const ALLOWED_TARGETS: AllowedTargets<'_> =
2020 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
2121 const STABILITY: AttributeStability = unstable!(rustc_attrs);
2222 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocatorZeroed;
......@@ -26,7 +26,7 @@ pub(crate) struct RustcAllocatorZeroedVariantParser;
2626
2727impl SingleAttributeParser for RustcAllocatorZeroedVariantParser {
2828 const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed_variant];
29 const ALLOWED_TARGETS: AllowedTargets =
29 const ALLOWED_TARGETS: AllowedTargets<'_> =
3030 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
3131 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function");
3232 const STABILITY: AttributeStability = unstable!(rustc_attrs);
......@@ -42,7 +42,7 @@ pub(crate) struct RustcDeallocatorParser;
4242
4343impl NoArgsAttributeParser for RustcDeallocatorParser {
4444 const PATH: &[Symbol] = &[sym::rustc_deallocator];
45 const ALLOWED_TARGETS: AllowedTargets =
45 const ALLOWED_TARGETS: AllowedTargets<'_> =
4646 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
4747 const STABILITY: AttributeStability = unstable!(rustc_attrs);
4848 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDeallocator;
......@@ -52,7 +52,7 @@ pub(crate) struct RustcReallocatorParser;
5252
5353impl NoArgsAttributeParser for RustcReallocatorParser {
5454 const PATH: &[Symbol] = &[sym::rustc_reallocator];
55 const ALLOWED_TARGETS: AllowedTargets =
55 const ALLOWED_TARGETS: AllowedTargets<'_> =
5656 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
5757 const STABILITY: AttributeStability = unstable!(rustc_attrs);
5858 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;
1010
1111impl NoArgsAttributeParser for RustcDumpUserArgsParser {
1212 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)]);
1414 const STABILITY: AttributeStability = unstable!(rustc_attrs);
1515 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs;
1616}
......@@ -19,7 +19,7 @@ pub(crate) struct RustcDumpDefParentsParser;
1919
2020impl NoArgsAttributeParser for RustcDumpDefParentsParser {
2121 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)]);
2323 const STABILITY: AttributeStability = unstable!(rustc_attrs);
2424 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents;
2525}
......@@ -28,7 +28,7 @@ pub(crate) struct RustcDumpDefPathParser;
2828
2929impl SingleAttributeParser for RustcDumpDefPathParser {
3030 const PATH: &[Symbol] = &[sym::rustc_dump_def_path];
31 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
31 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
3232 Allow(Target::Fn),
3333 Allow(Target::Method(MethodKind::TraitImpl)),
3434 Allow(Target::Method(MethodKind::Inherent)),
......@@ -49,7 +49,7 @@ pub(crate) struct RustcDumpGenericsParser;
4949
5050impl NoArgsAttributeParser for RustcDumpGenericsParser {
5151 const PATH: &[Symbol] = &[sym::rustc_dump_generics];
52 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
52 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
5353 Allow(Target::Struct),
5454 Allow(Target::Enum),
5555 Allow(Target::Union),
......@@ -78,7 +78,7 @@ pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser;
7878
7979impl NoArgsAttributeParser for RustcDumpHiddenTypeOfOpaquesParser {
8080 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)]);
8282 const STABILITY: AttributeStability = unstable!(rustc_attrs);
8383 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques;
8484}
......@@ -87,7 +87,7 @@ pub(crate) struct RustcDumpInferredOutlivesParser;
8787
8888impl NoArgsAttributeParser for RustcDumpInferredOutlivesParser {
8989 const PATH: &[Symbol] = &[sym::rustc_dump_inferred_outlives];
90 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
90 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
9191 Allow(Target::Struct),
9292 Allow(Target::Enum),
9393 Allow(Target::Union),
......@@ -101,7 +101,8 @@ pub(crate) struct RustcDumpItemBoundsParser;
101101
102102impl NoArgsAttributeParser for RustcDumpItemBoundsParser {
103103 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)]);
105106 const STABILITY: AttributeStability = unstable!(rustc_attrs);
106107 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
107108}
......@@ -115,7 +116,7 @@ impl CombineAttributeParser for RustcDumpLayoutParser {
115116
116117 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcDumpLayout(items);
117118
118 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
119 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
119120 Allow(Target::Struct),
120121 Allow(Target::Enum),
121122 Allow(Target::Union),
......@@ -174,7 +175,7 @@ pub(crate) struct RustcDumpObjectLifetimeDefaultsParser;
174175
175176impl NoArgsAttributeParser for RustcDumpObjectLifetimeDefaultsParser {
176177 const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults];
177 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
178 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
178179 Allow(Target::AssocConst),
179180 Allow(Target::AssocTy),
180181 Allow(Target::Const),
......@@ -201,7 +202,7 @@ pub(crate) struct RustcDumpPredicatesParser;
201202
202203impl NoArgsAttributeParser for RustcDumpPredicatesParser {
203204 const PATH: &[Symbol] = &[sym::rustc_dump_predicates];
204 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
205 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
205206 Allow(Target::AssocConst),
206207 Allow(Target::AssocTy),
207208 Allow(Target::Const),
......@@ -229,7 +230,7 @@ pub(crate) struct RustcDumpSymbolNameParser;
229230
230231impl SingleAttributeParser for RustcDumpSymbolNameParser {
231232 const PATH: &[Symbol] = &[sym::rustc_dump_symbol_name];
232 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
233 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
233234 Allow(Target::Fn),
234235 Allow(Target::Method(MethodKind::TraitImpl)),
235236 Allow(Target::Method(MethodKind::Inherent)),
......@@ -250,7 +251,7 @@ pub(crate) struct RustcDumpVariancesParser;
250251
251252impl NoArgsAttributeParser for RustcDumpVariancesParser {
252253 const PATH: &[Symbol] = &[sym::rustc_dump_variances];
253 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
254 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
254255 Allow(Target::Enum),
255256 Allow(Target::Fn),
256257 Allow(Target::Method(MethodKind::Inherent)),
......@@ -271,7 +272,7 @@ pub(crate) struct RustcDumpVariancesOfOpaquesParser;
271272
272273impl NoArgsAttributeParser for RustcDumpVariancesOfOpaquesParser {
273274 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)]);
275276 const STABILITY: AttributeStability = unstable!(rustc_attrs);
276277 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques;
277278}
......@@ -280,7 +281,7 @@ pub(crate) struct RustcDumpVtableParser;
280281
281282impl NoArgsAttributeParser for RustcDumpVtableParser {
282283 const PATH: &[Symbol] = &[sym::rustc_dump_vtable];
283 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
284 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
284285 Allow(Target::Impl { of_trait: true }),
285286 Allow(Target::TyAlias),
286287 ]);
compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs+63-43
......@@ -12,6 +12,7 @@ use rustc_span::Symbol;
1212use super::prelude::*;
1313use super::util::parse_single_integer;
1414use crate::diagnostics;
15use crate::diagnostics::UnknownExternLangItem;
1516use crate::session_diagnostics::{
1617 AttributeRequiresOpt, CguFieldsMissing, RustcScalableVectorCountOutOfRange, UnknownLangItem,
1718};
......@@ -20,7 +21,7 @@ pub(crate) struct RustcMainParser;
2021
2122impl NoArgsAttributeParser for RustcMainParser {
2223 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)]);
2425 const STABILITY: AttributeStability = unstable!(
2526 rustc_attrs,
2627 "the `#[rustc_main]` attribute is used internally to specify test entry point function"
......@@ -32,7 +33,7 @@ pub(crate) struct RustcMustImplementOneOfParser;
3233
3334impl SingleAttributeParser for RustcMustImplementOneOfParser {
3435 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)]);
3637 const STABILITY: AttributeStability = unstable!(
3738 rustc_attrs,
3839 "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;
7879
7980impl NoArgsAttributeParser for RustcNeverReturnsNullPtrParser {
8081 const PATH: &[Symbol] = &[sym::rustc_never_returns_null_ptr];
81 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
82 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
8283 Allow(Target::Fn),
8384 Allow(Target::Method(MethodKind::Inherent)),
8485 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -93,7 +94,7 @@ pub(crate) struct RustcNoImplicitAutorefsParser;
9394
9495impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser {
9596 const PATH: &[Symbol] = &[sym::rustc_no_implicit_autorefs];
96 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
97 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
9798 Allow(Target::Fn),
9899 Allow(Target::Method(MethodKind::Inherent)),
99100 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -109,7 +110,7 @@ pub(crate) struct RustcLegacyConstGenericsParser;
109110
110111impl SingleAttributeParser for RustcLegacyConstGenericsParser {
111112 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)]);
113114 const TEMPLATE: AttributeTemplate = template!(List: &["N"]);
114115 const STABILITY: AttributeStability = unstable!(rustc_attrs);
115116
......@@ -149,7 +150,7 @@ pub(crate) struct RustcInheritOverflowChecksParser;
149150
150151impl NoArgsAttributeParser for RustcInheritOverflowChecksParser {
151152 const PATH: &[Symbol] = &[sym::rustc_inherit_overflow_checks];
152 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
153 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
153154 Allow(Target::Fn),
154155 Allow(Target::Method(MethodKind::Inherent)),
155156 Allow(Target::Method(MethodKind::TraitImpl)),
......@@ -163,7 +164,7 @@ pub(crate) struct RustcLintOptDenyFieldAccessParser;
163164
164165impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser {
165166 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)]);
167168 const TEMPLATE: AttributeTemplate = template!(Word);
168169 const STABILITY: AttributeStability = unstable!(rustc_attrs);
169170 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
......@@ -178,7 +179,7 @@ pub(crate) struct RustcLintOptTyParser;
178179
179180impl NoArgsAttributeParser for RustcLintOptTyParser {
180181 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)]);
182183 const STABILITY: AttributeStability = unstable!(rustc_attrs);
183184 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy;
184185}
......@@ -305,7 +306,7 @@ impl AttributeParser for RustcCguTestAttributeParser {
305306 ),
306307 ];
307308
308 const ALLOWED_TARGETS: AllowedTargets =
309 const ALLOWED_TARGETS: AllowedTargets<'_> =
309310 AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]);
310311
311312 fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
......@@ -317,7 +318,7 @@ pub(crate) struct RustcDeprecatedSafe2024Parser;
317318
318319impl SingleAttributeParser for RustcDeprecatedSafe2024Parser {
319320 const PATH: &[Symbol] = &[sym::rustc_deprecated_safe_2024];
320 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
321 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
321322 Allow(Target::Fn),
322323 Allow(Target::Method(MethodKind::Inherent)),
323324 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -347,7 +348,7 @@ pub(crate) struct RustcConversionSuggestionParser;
347348
348349impl NoArgsAttributeParser for RustcConversionSuggestionParser {
349350 const PATH: &[Symbol] = &[sym::rustc_conversion_suggestion];
350 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
351 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
351352 Allow(Target::Fn),
352353 Allow(Target::Method(MethodKind::Inherent)),
353354 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -362,7 +363,8 @@ pub(crate) struct RustcCaptureAnalysisParser;
362363
363364impl NoArgsAttributeParser for RustcCaptureAnalysisParser {
364365 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)]);
366368 const STABILITY: AttributeStability = unstable!(rustc_attrs);
367369 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis;
368370}
......@@ -371,7 +373,7 @@ pub(crate) struct RustcNeverTypeOptionsParser;
371373
372374impl SingleAttributeParser for RustcNeverTypeOptionsParser {
373375 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)]);
375377 const TEMPLATE: AttributeTemplate = template!(List: &[
376378 r#"fallback = "unit", "never", "no""#,
377379 r#"diverging_block_default = "unit", "never""#,
......@@ -444,7 +446,7 @@ pub(crate) struct RustcTrivialFieldReadsParser;
444446
445447impl NoArgsAttributeParser for RustcTrivialFieldReadsParser {
446448 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)]);
448450 const STABILITY: AttributeStability = unstable!(rustc_attrs);
449451 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads;
450452}
......@@ -453,7 +455,7 @@ pub(crate) struct RustcNoMirInlineParser;
453455
454456impl NoArgsAttributeParser for RustcNoMirInlineParser {
455457 const PATH: &[Symbol] = &[sym::rustc_no_mir_inline];
456 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
458 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
457459 Allow(Target::Fn),
458460 Allow(Target::Method(MethodKind::Inherent)),
459461 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -469,7 +471,7 @@ pub(crate) struct RustcNoWritableParser;
469471impl NoArgsAttributeParser for RustcNoWritableParser {
470472 const PATH: &[Symbol] = &[sym::rustc_no_writable];
471473 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
472 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
474 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
473475 Allow(Target::Fn),
474476 Allow(Target::Closure),
475477 Allow(Target::Method(MethodKind::Inherent)),
......@@ -484,7 +486,7 @@ pub(crate) struct RustcLintQueryInstabilityParser;
484486
485487impl NoArgsAttributeParser for RustcLintQueryInstabilityParser {
486488 const PATH: &[Symbol] = &[sym::rustc_lint_query_instability];
487 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
489 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
488490 Allow(Target::Fn),
489491 Allow(Target::Method(MethodKind::Inherent)),
490492 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -499,7 +501,7 @@ pub(crate) struct RustcRegionsParser;
499501
500502impl NoArgsAttributeParser for RustcRegionsParser {
501503 const PATH: &[Symbol] = &[sym::rustc_regions];
502 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
504 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
503505 Allow(Target::Fn),
504506 Allow(Target::Method(MethodKind::Inherent)),
505507 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -514,7 +516,7 @@ pub(crate) struct RustcLintUntrackedQueryInformationParser;
514516
515517impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser {
516518 const PATH: &[Symbol] = &[sym::rustc_lint_untracked_query_information];
517 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
519 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
518520 Allow(Target::Fn),
519521 Allow(Target::Method(MethodKind::Inherent)),
520522 Allow(Target::Method(MethodKind::Trait { body: false })),
......@@ -529,7 +531,7 @@ pub(crate) struct RustcSimdMonomorphizeLaneLimitParser;
529531
530532impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser {
531533 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)]);
533535 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
534536 const STABILITY: AttributeStability = unstable!(rustc_attrs);
535537
......@@ -543,7 +545,7 @@ pub(crate) struct RustcScalableVectorParser;
543545
544546impl SingleAttributeParser for RustcScalableVectorParser {
545547 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)]);
547549 const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]);
548550 const STABILITY: AttributeStability = unstable!(rustc_attrs);
549551
......@@ -565,7 +567,7 @@ pub(crate) struct LangParser;
565567
566568impl SingleAttributeParser for LangParser {
567569 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;
569571 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
570572 const STABILITY: AttributeStability = unstable!(lang_items);
571573
......@@ -576,6 +578,24 @@ impl SingleAttributeParser for LangParser {
576578 cx.emit_err(UnknownLangItem { span: cx.attr_span, name });
577579 return None;
578580 };
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
579599 Some(AttributeKind::Lang(lang_item))
580600 }
581601}
......@@ -584,7 +604,7 @@ pub(crate) struct RustcHasIncoherentInherentImplsParser;
584604
585605impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParser {
586606 const PATH: &[Symbol] = &[sym::rustc_has_incoherent_inherent_impls];
587 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
607 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
588608 Allow(Target::Trait),
589609 Allow(Target::Struct),
590610 Allow(Target::Enum),
......@@ -599,7 +619,7 @@ pub(crate) struct PanicHandlerParser;
599619
600620impl NoArgsAttributeParser for PanicHandlerParser {
601621 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)]);
603623 const STABILITY: AttributeStability = AttributeStability::Stable;
604624 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Lang(LangItem::PanicImpl);
605625}
......@@ -608,7 +628,7 @@ pub(crate) struct RustcNounwindParser;
608628
609629impl NoArgsAttributeParser for RustcNounwindParser {
610630 const PATH: &[Symbol] = &[sym::rustc_nounwind];
611 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
631 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
612632 Allow(Target::Fn),
613633 Allow(Target::ForeignFn),
614634 Allow(Target::Method(MethodKind::Inherent)),
......@@ -623,7 +643,7 @@ pub(crate) struct RustcOffloadKernelParser;
623643
624644impl NoArgsAttributeParser for RustcOffloadKernelParser {
625645 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)]);
627647 const STABILITY: AttributeStability = unstable!(rustc_attrs);
628648 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel;
629649}
......@@ -636,7 +656,7 @@ impl CombineAttributeParser for RustcMirParser {
636656 type Item = RustcMirKind;
637657
638658 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcMir(items);
639 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
659 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
640660 Allow(Target::Fn),
641661 Allow(Target::Method(MethodKind::Inherent)),
642662 Allow(Target::Method(MethodKind::TraitImpl)),
......@@ -712,7 +732,7 @@ pub(crate) struct RustcNonConstTraitMethodParser;
712732
713733impl NoArgsAttributeParser for RustcNonConstTraitMethodParser {
714734 const PATH: &[Symbol] = &[sym::rustc_non_const_trait_method];
715 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
735 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
716736 Allow(Target::Method(MethodKind::Trait { body: true })),
717737 Allow(Target::Method(MethodKind::Trait { body: false })),
718738 ]);
......@@ -731,7 +751,7 @@ impl CombineAttributeParser for RustcCleanParser {
731751 type Item = RustcCleanAttribute;
732752
733753 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcClean(items);
734 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
754 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
735755 // tidy-alphabetical-start
736756 Allow(Target::AssocConst),
737757 Allow(Target::AssocTy),
......@@ -824,7 +844,7 @@ pub(crate) struct RustcIfThisChangedParser;
824844
825845impl SingleAttributeParser for RustcIfThisChangedParser {
826846 const PATH: &[Symbol] = &[sym::rustc_if_this_changed];
827 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
847 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
828848 // tidy-alphabetical-start
829849 Allow(Target::AssocConst),
830850 Allow(Target::AssocTy),
......@@ -882,7 +902,7 @@ impl CombineAttributeParser for RustcThenThisWouldNeedParser {
882902
883903 const CONVERT: ConvertFn<Self::Item> =
884904 |items, _span| AttributeKind::RustcThenThisWouldNeed(items);
885 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
905 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
886906 // tidy-alphabetical-start
887907 Allow(Target::AssocConst),
888908 Allow(Target::AssocTy),
......@@ -929,7 +949,7 @@ pub(crate) struct RustcInsignificantDtorParser;
929949
930950impl NoArgsAttributeParser for RustcInsignificantDtorParser {
931951 const PATH: &[Symbol] = &[sym::rustc_insignificant_dtor];
932 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
952 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
933953 Allow(Target::Enum),
934954 Allow(Target::Struct),
935955 Allow(Target::ForeignTy),
......@@ -942,7 +962,7 @@ pub(crate) struct RustcEffectiveVisibilityParser;
942962
943963impl NoArgsAttributeParser for RustcEffectiveVisibilityParser {
944964 const PATH: &[Symbol] = &[sym::rustc_effective_visibility];
945 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
965 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
946966 Allow(Target::Use),
947967 Allow(Target::Static),
948968 Allow(Target::Const),
......@@ -981,7 +1001,7 @@ pub(crate) struct RustcDiagnosticItemParser;
9811001
9821002impl SingleAttributeParser for RustcDiagnosticItemParser {
9831003 const PATH: &[Symbol] = &[sym::rustc_diagnostic_item];
984 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
1004 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
9851005 Allow(Target::Trait),
9861006 Allow(Target::Struct),
9871007 Allow(Target::Enum),
......@@ -1016,7 +1036,7 @@ pub(crate) struct RustcDoNotConstCheckParser;
10161036
10171037impl NoArgsAttributeParser for RustcDoNotConstCheckParser {
10181038 const PATH: &[Symbol] = &[sym::rustc_do_not_const_check];
1019 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
1039 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
10201040 Allow(Target::Fn),
10211041 Allow(Target::Method(MethodKind::Inherent)),
10221042 Allow(Target::Method(MethodKind::TraitImpl)),
......@@ -1034,7 +1054,7 @@ pub(crate) struct RustcNonnullOptimizationGuaranteedParser;
10341054
10351055impl NoArgsAttributeParser for RustcNonnullOptimizationGuaranteedParser {
10361056 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)]);
10381058 const STABILITY: AttributeStability = unstable!(
10391059 rustc_attrs,
10401060 "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;
10471067
10481068impl NoArgsAttributeParser for RustcStrictCoherenceParser {
10491069 const PATH: &[Symbol] = &[sym::rustc_strict_coherence];
1050 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
1070 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
10511071 Allow(Target::Trait),
10521072 Allow(Target::Struct),
10531073 Allow(Target::Enum),
......@@ -1062,7 +1082,7 @@ pub(crate) struct RustcReservationImplParser;
10621082
10631083impl SingleAttributeParser for RustcReservationImplParser {
10641084 const PATH: &[Symbol] = &[sym::rustc_reservation_impl];
1065 const ALLOWED_TARGETS: AllowedTargets =
1085 const ALLOWED_TARGETS: AllowedTargets<'_> =
10661086 AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]);
10671087 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "reservation message");
10681088 const STABILITY: AttributeStability = unstable!(rustc_attrs);
......@@ -1079,7 +1099,7 @@ pub(crate) struct PreludeImportParser;
10791099
10801100impl NoArgsAttributeParser for PreludeImportParser {
10811101 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)]);
10831103 const STABILITY: AttributeStability = unstable!(prelude_import);
10841104 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PreludeImport;
10851105}
......@@ -1088,7 +1108,7 @@ pub(crate) struct RustcDocPrimitiveParser;
10881108
10891109impl SingleAttributeParser for RustcDocPrimitiveParser {
10901110 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)]);
10921112 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name");
10931113 const STABILITY: AttributeStability = unstable!(
10941114 rustc_attrs,
......@@ -1107,7 +1127,7 @@ pub(crate) struct RustcIntrinsicParser;
11071127
11081128impl NoArgsAttributeParser for RustcIntrinsicParser {
11091129 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)]);
11111131 const STABILITY: AttributeStability = unstable!(intrinsics);
11121132 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsic;
11131133}
......@@ -1116,7 +1136,7 @@ pub(crate) struct RustcIntrinsicConstStableIndirectParser;
11161136
11171137impl NoArgsAttributeParser for RustcIntrinsicConstStableIndirectParser {
11181138 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)]);
11201140 const STABILITY: AttributeStability = unstable!(rustc_attrs);
11211141 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect;
11221142}
......@@ -1125,7 +1145,7 @@ pub(crate) struct RustcExhaustiveParser;
11251145
11261146impl NoArgsAttributeParser for RustcExhaustiveParser {
11271147 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)]);
11291149 const STABILITY: AttributeStability = unstable!(rustc_attrs);
11301150 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcMustMatchExhaustively;
11311151}
compiler/rustc_attr_parsing/src/attributes/semantics.rs+2-2
......@@ -5,7 +5,7 @@ use super::prelude::*;
55pub(crate) struct MayDangleParser;
66impl NoArgsAttributeParser for MayDangleParser {
77 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`
99 const STABILITY: AttributeStability = unstable!(dropck_eyepatch);
1010 const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle;
1111}
......@@ -14,7 +14,7 @@ pub(crate) struct ComptimeParser;
1414impl NoArgsAttributeParser for ComptimeParser {
1515 const PATH: &[Symbol] = &[sym::rustc_comptime];
1616 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
17 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
17 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1818 Allow(Target::Method(MethodKind::Inherent)),
1919 Allow(Target::Fn),
2020 ]);
compiler/rustc_attr_parsing/src/attributes/splat.rs+1-1
......@@ -9,7 +9,7 @@ pub(crate) struct SplatParser;
99
1010impl NoArgsAttributeParser for SplatParser {
1111 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)]);
1313 const STABILITY: AttributeStability =
1414 unstable!(splat, "the `#[splat]` attribute is experimental");
1515 const CREATE: fn(Span) -> AttributeKind = AttributeKind::Splat;
compiler/rustc_attr_parsing/src/attributes/stability.rs+6-6
......@@ -13,7 +13,7 @@ use super::prelude::*;
1313use super::util::parse_version;
1414use crate::session_diagnostics;
1515
16const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
16const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1717 Allow(Target::Fn),
1818 Allow(Target::Struct),
1919 Allow(Target::Enum),
......@@ -102,7 +102,7 @@ impl AttributeParser for StabilityParser {
102102 },
103103 ),
104104 ];
105 const ALLOWED_TARGETS: AllowedTargets = ALLOWED_TARGETS;
105 const ALLOWED_TARGETS: AllowedTargets<'_> = ALLOWED_TARGETS;
106106
107107 fn finalize(mut self, cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
108108 if let Some(atum) = self.allowed_through_unstable_modules {
......@@ -158,7 +158,7 @@ impl AttributeParser for BodyStabilityParser {
158158 }
159159 },
160160 )];
161 const ALLOWED_TARGETS: AllowedTargets = ALLOWED_TARGETS;
161 const ALLOWED_TARGETS: AllowedTargets<'_> = ALLOWED_TARGETS;
162162
163163 fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
164164 let (stability, span) = self.stability?;
......@@ -171,7 +171,7 @@ pub(crate) struct RustcConstStableIndirectParser;
171171impl NoArgsAttributeParser for RustcConstStableIndirectParser {
172172 const PATH: &[Symbol] = &[sym::rustc_const_stable_indirect];
173173 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore;
174 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
174 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
175175 Allow(Target::Fn),
176176 Allow(Target::Method(MethodKind::Inherent)),
177177 ]);
......@@ -233,7 +233,7 @@ impl AttributeParser for ConstStabilityParser {
233233 this.promotable = true;
234234 }),
235235 ];
236 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
236 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
237237 Allow(Target::Fn),
238238 Allow(Target::Method(MethodKind::Inherent)),
239239 Allow(Target::Method(MethodKind::TraitImpl)),
......@@ -460,7 +460,7 @@ pub(crate) struct UnstableRemovedParser;
460460impl CombineAttributeParser for UnstableRemovedParser {
461461 type Item = UnstableRemovedFeature;
462462 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)]);
464464 const TEMPLATE: AttributeTemplate =
465465 template!(List: &[r#"feature = "name", reason = "...", link = "...", since = "version""#]);
466466 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;
99impl SingleAttributeParser for IgnoreParser {
1010 const PATH: &[Symbol] = &[sym::ignore];
1111 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
12 const ALLOWED_TARGETS: AllowedTargets =
12 const ALLOWED_TARGETS: AllowedTargets<'_> =
1313 AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]);
1414 const TEMPLATE: AttributeTemplate = template!(
1515 Word, NameValueStr: "reason",
......@@ -51,7 +51,7 @@ pub(crate) struct ShouldPanicParser;
5151impl SingleAttributeParser for ShouldPanicParser {
5252 const PATH: &[Symbol] = &[sym::should_panic];
5353 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
54 const ALLOWED_TARGETS: AllowedTargets =
54 const ALLOWED_TARGETS: AllowedTargets<'_> =
5555 AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]);
5656 const TEMPLATE: AttributeTemplate = template!(
5757 Word, List: &[r#"expected = "reason""#], NameValueStr: "reason",
......@@ -83,7 +83,7 @@ pub(crate) struct ReexportTestHarnessMainParser;
8383
8484impl SingleAttributeParser for ReexportTestHarnessMainParser {
8585 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)]);
8787 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
8888 const STABILITY: AttributeStability = unstable!(custom_test_frameworks);
8989
......@@ -105,7 +105,7 @@ pub(crate) struct RustcAbiParser;
105105impl SingleAttributeParser for RustcAbiParser {
106106 const PATH: &[Symbol] = &[sym::rustc_abi];
107107 const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::debug, sym::assert_eq]);
108 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
108 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
109109 Allow(Target::TyAlias),
110110 Allow(Target::Fn),
111111 Allow(Target::ForeignFn),
......@@ -150,7 +150,7 @@ pub(crate) struct RustcDelayedBugFromInsideQueryParser;
150150
151151impl NoArgsAttributeParser for RustcDelayedBugFromInsideQueryParser {
152152 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)]);
154154 const STABILITY: AttributeStability = unstable!(rustc_attrs);
155155 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDelayedBugFromInsideQuery;
156156}
......@@ -159,7 +159,7 @@ pub(crate) struct RustcEvaluateWhereClausesParser;
159159
160160impl NoArgsAttributeParser for RustcEvaluateWhereClausesParser {
161161 const PATH: &[Symbol] = &[sym::rustc_evaluate_where_clauses];
162 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
162 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
163163 Allow(Target::Fn),
164164 Allow(Target::Method(MethodKind::Inherent)),
165165 Allow(Target::Method(MethodKind::Trait { body: true })),
......@@ -174,7 +174,7 @@ pub(crate) struct TestRunnerParser;
174174
175175impl SingleAttributeParser for TestRunnerParser {
176176 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)]);
178178 const TEMPLATE: AttributeTemplate = template!(List: &["path"]);
179179 const STABILITY: AttributeStability = unstable!(custom_test_frameworks);
180180
......@@ -194,7 +194,7 @@ pub(crate) struct RustcTestMarkerParser;
194194
195195impl SingleAttributeParser for RustcTestMarkerParser {
196196 const PATH: &[Symbol] = &[sym::rustc_test_marker];
197 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
197 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
198198 Allow(Target::Const),
199199 Allow(Target::Fn),
200200 Allow(Target::Static),
compiler/rustc_attr_parsing/src/attributes/traits.rs+10-10
......@@ -12,7 +12,7 @@ use crate::target_checking::Policy::{Allow, Warn};
1212pub(crate) struct RustcSkipDuringMethodDispatchParser;
1313impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser {
1414 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)]);
1616
1717 const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]);
1818 const STABILITY: AttributeStability = unstable!(rustc_attrs);
......@@ -52,7 +52,7 @@ impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser {
5252pub(crate) struct RustcParenSugarParser;
5353impl NoArgsAttributeParser for RustcParenSugarParser {
5454 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)]);
5656 const STABILITY: AttributeStability = unstable!(rustc_attrs);
5757 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcParenSugar;
5858}
......@@ -62,7 +62,7 @@ impl NoArgsAttributeParser for RustcParenSugarParser {
6262pub(crate) struct MarkerParser;
6363impl NoArgsAttributeParser for MarkerParser {
6464 const PATH: &[Symbol] = &[sym::marker];
65 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
65 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
6666 Allow(Target::Trait),
6767 Warn(Target::Field),
6868 Warn(Target::Arm),
......@@ -75,7 +75,7 @@ impl NoArgsAttributeParser for MarkerParser {
7575pub(crate) struct RustcDenyExplicitImplParser;
7676impl NoArgsAttributeParser for RustcDenyExplicitImplParser {
7777 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)]);
7979 const STABILITY: AttributeStability = unstable!(rustc_attrs);
8080 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDenyExplicitImpl;
8181}
......@@ -83,7 +83,7 @@ impl NoArgsAttributeParser for RustcDenyExplicitImplParser {
8383pub(crate) struct RustcDynIncompatibleTraitParser;
8484impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser {
8585 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)]);
8787 const STABILITY: AttributeStability = unstable!(rustc_attrs);
8888 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait;
8989}
......@@ -93,7 +93,7 @@ impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser {
9393pub(crate) struct RustcSpecializationTraitParser;
9494impl NoArgsAttributeParser for RustcSpecializationTraitParser {
9595 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)]);
9797 const STABILITY: AttributeStability = unstable!(rustc_attrs);
9898 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcSpecializationTrait;
9999}
......@@ -101,7 +101,7 @@ impl NoArgsAttributeParser for RustcSpecializationTraitParser {
101101pub(crate) struct RustcUnsafeSpecializationMarkerParser;
102102impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser {
103103 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)]);
105105 const STABILITY: AttributeStability = unstable!(rustc_attrs);
106106 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcUnsafeSpecializationMarker;
107107}
......@@ -111,7 +111,7 @@ impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser {
111111pub(crate) struct RustcCoinductiveParser;
112112impl NoArgsAttributeParser for RustcCoinductiveParser {
113113 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)]);
115115 const STABILITY: AttributeStability = unstable!(rustc_attrs);
116116 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoinductive;
117117}
......@@ -119,7 +119,7 @@ impl NoArgsAttributeParser for RustcCoinductiveParser {
119119pub(crate) struct RustcAllowIncoherentImplParser;
120120impl NoArgsAttributeParser for RustcAllowIncoherentImplParser {
121121 const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
122 const ALLOWED_TARGETS: AllowedTargets =
122 const ALLOWED_TARGETS: AllowedTargets<'_> =
123123 AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
124124 const STABILITY: AttributeStability = unstable!(rustc_attrs);
125125 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl;
......@@ -128,7 +128,7 @@ impl NoArgsAttributeParser for RustcAllowIncoherentImplParser {
128128pub(crate) struct FundamentalParser;
129129impl NoArgsAttributeParser for FundamentalParser {
130130 const PATH: &[Symbol] = &[sym::fundamental];
131 const ALLOWED_TARGETS: AllowedTargets =
131 const ALLOWED_TARGETS: AllowedTargets<'_> =
132132 AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]);
133133 const STABILITY: AttributeStability = unstable!(fundamental);
134134 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 {
1111 cx.dcx().span_err(vec![used, unused], "multiple macro transparency attributes");
1212 });
1313 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)]);
1516 const TEMPLATE: AttributeTemplate =
1617 template!(NameValueStr: ["transparent", "semiopaque", "opaque"]);
1718
compiler/rustc_attr_parsing/src/attributes/unroll.rs+1-1
......@@ -7,7 +7,7 @@ use super::prelude::*;
77pub(crate) struct UnrollParser;
88impl SingleAttributeParser for UnrollParser {
99 const PATH: &[Symbol] = &[sym::unroll];
10 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
10 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1111 Allow(Target::Loop),
1212 Allow(Target::ForLoop),
1313 Allow(Target::While),
compiler/rustc_attr_parsing/src/context.rs+1-1
......@@ -85,7 +85,7 @@ pub(super) struct GroupTypeInner {
8585pub(super) struct GroupTypeInnerAccept {
8686 pub(super) template: AttributeTemplate,
8787 pub(super) accept_fn: AcceptFn,
88 pub(super) allowed_targets: AllowedTargets,
88 pub(super) allowed_targets: AllowedTargets<'static>,
8989 pub(super) safety: AttributeSafety,
9090 pub(super) stability: AttributeStability,
9191 pub(super) finalizer: FinalizeFn,
compiler/rustc_attr_parsing/src/diagnostics.rs+9-1
......@@ -1,4 +1,4 @@
1use rustc_errors::{Applicability, DiagArgValue, E0232, MultiSpan};
1use rustc_errors::{Applicability, DiagArgValue, E0232, E0264, MultiSpan};
22use rustc_hir::AttrPath;
33use rustc_macros::{Diagnostic, Subdiagnostic};
44use rustc_span::{Span, Symbol};
......@@ -801,3 +801,11 @@ pub(crate) struct UnsafeAttribute {
801801 pub attr_path: AttrPath,
802802 pub note: &'static str,
803803}
804
805#[derive(Diagnostic)]
806#[diag("unknown external lang item: `{$lang_item}`", code = E0264)]
807pub(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 {
337337 pub target: &'static str,
338338 pub applied: DiagArgValue,
339339 pub only: &'static str,
340 pub attribute_args: &'static str,
340 pub attribute_args: String,
341341 #[subdiagnostic]
342342 pub help: Option<InvalidTargetHelp>,
343343 #[warning(
compiler/rustc_attr_parsing/src/target_checking.rs+10-10
......@@ -16,9 +16,9 @@ use crate::target_checking::Policy::Allow;
1616use crate::{AttributeParser, ShouldEmit};
1717
1818#[derive(Debug)]
19pub(crate) enum AllowedTargets {
20 AllowList(&'static [Policy]),
21 AllowListWarnRest(&'static [Policy]),
19pub(crate) enum AllowedTargets<'a> {
20 AllowList(&'a [Policy]),
21 AllowListWarnRest(&'a [Policy]),
2222 /// This is useful for argument-dependent target checking.
2323 /// If debug assertions are enabled,
2424 /// 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 {
3131 Error,
3232}
3333
34impl AllowedTargets {
34impl AllowedTargets<'_> {
3535 pub(crate) fn is_allowed(&self, target: Target) -> AllowedResult {
3636 match self {
3737 AllowedTargets::AllowList(list) => {
......@@ -94,8 +94,8 @@ pub(crate) enum Policy {
9494
9595impl<'sess> AttributeParser<'sess> {
9696 pub(crate) fn check_target(
97 allowed_targets: &AllowedTargets,
98 attribute_args: &'static str,
97 allowed_targets: &AllowedTargets<'_>,
98 attribute_args: &str,
9999 cx: &mut AcceptContext<'_, 'sess>,
100100 ) {
101101 if matches!(cx.should_emit, ShouldEmit::Nothing) {
......@@ -137,7 +137,7 @@ impl<'sess> AttributeParser<'sess> {
137137 target: cx.target.plural_name(),
138138 only: if only { "only " } else { "" },
139139 applied: DiagArgValue::StrListSepByAnd(applied.into_iter().map(Cow::Owned).collect()),
140 attribute_args,
140 attribute_args: attribute_args.to_string(),
141141 help: Self::target_checking_help(attribute_args, cx),
142142 previously_accepted: matches!(result, AllowedResult::Warn) && !is_diagnostic_attr,
143143 on_macro_call: matches!(cx.target, Target::MacroCall),
......@@ -173,7 +173,7 @@ impl<'sess> AttributeParser<'sess> {
173173 }
174174
175175 fn target_checking_help(
176 attribute_args: &'static str,
176 attribute_args: &str,
177177 cx: &AcceptContext<'_, '_>,
178178 ) -> Option<InvalidTargetHelp> {
179179 match &*cx.attr_path.segments {
......@@ -443,8 +443,8 @@ fn filter_targets(
443443impl<'f, 'sess> AcceptContext<'f, 'sess> {
444444 pub(crate) fn check_target(
445445 &mut self,
446 attribute_args: &'static str,
447 allowed_targets: &AllowedTargets,
446 attribute_args: &str,
447 allowed_targets: &AllowedTargets<'_>,
448448 ) {
449449 self.ignore_target_checks();
450450 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(
607607 // If there's a lot of unused arguments,
608608 // let's check if this format arguments looks like another syntax (printf / shell).
609609 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 };
610612 report_missing_placeholders(
611613 ecx,
612614 unused,
......@@ -616,7 +618,7 @@ fn make_format_args(
616618 &invalid_refs,
617619 detect_foreign_fmt,
618620 str_style,
619 fmt_str,
621 foreign_fmt_str,
620622 uncooked_fmt_str.1.as_str(),
621623 fmt_span,
622624 );
compiler/rustc_codegen_cranelift/src/abi/mod.rs+3-3
......@@ -16,9 +16,9 @@ use rustc_abi::{CanonAbi, ExternAbi, X86Call};
1616use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization;
1717use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall;
1818use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
19use rustc_middle::ty::TypeVisitableExt;
2019use rustc_middle::ty::layout::FnAbiOf;
2120use rustc_middle::ty::print::with_no_trimmed_paths;
21use rustc_middle::ty::{ShimKind, TypeVisitableExt};
2222use rustc_session::Session;
2323use rustc_span::Spanned;
2424use rustc_target::callconv::{FnAbi, PassMode};
......@@ -467,7 +467,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
467467 }
468468 // We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
469469 // it is `func returning noop future`
470 InstanceKind::DropGlue(_, None) => {
470 InstanceKind::Shim(ShimKind::DropGlue(_, None)) => {
471471 // empty drop glue - a nop.
472472 let dest = target.expect("Non terminating drop_in_place_real???");
473473 let ret_block = fx.get_block(dest);
......@@ -725,7 +725,7 @@ pub(crate) fn codegen_drop<'tcx>(
725725 let ret_block = fx.get_block(target);
726726
727727 // 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 {
729729 // we don't actually need to drop anything
730730 fx.bcx.ins().jump(ret_block, &[]);
731731 } else {
compiler/rustc_codegen_cranelift/src/constant.rs+1-1
......@@ -53,7 +53,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
5353) -> CValue<'tcx> {
5454 let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) {
5555 let instance = ty::Instance {
56 def: ty::InstanceKind::ThreadLocalShim(def_id),
56 def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)),
5757 args: ty::GenericArgs::empty(),
5858 };
5959 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::{
1111 ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
1212};
1313use rustc_middle::query::LocalCrate;
14use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt};
14use rustc_middle::ty::{
15 self, GenericArgKind, GenericArgsRef, Instance, ShimKind, SymbolName, Ty, TyCtxt,
16};
1517use rustc_middle::util::Providers;
1618use rustc_session::config::CrateType;
1719use rustc_span::Span;
......@@ -332,7 +334,10 @@ fn exported_generic_symbols_provider_local<'tcx>(
332334 ));
333335 }
334336 }
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 }) => {
336341 // A little sanity-check
337342 assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty)));
338343
......@@ -356,7 +361,7 @@ fn exported_generic_symbols_provider_local<'tcx>(
356361 }
357362 }
358363 MonoItem::Fn(Instance {
359 def: InstanceKind::AsyncDropGlueCtorShim(_, ty),
364 def: InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, ty)),
360365 args,
361366 }) => {
362367 // A little sanity-check
......@@ -371,7 +376,10 @@ fn exported_generic_symbols_provider_local<'tcx>(
371376 },
372377 ));
373378 }
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 }) => {
375383 symbols.push((
376384 ExportedSymbol::AsyncDropGlue(def, ty),
377385 SymbolExportInfo {
......@@ -578,7 +586,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
578586 rustc_symbol_mangling::symbol_name_for_instance_in_crate(
579587 tcx,
580588 ty::Instance {
581 def: ty::InstanceKind::ThreadLocalShim(def_id),
589 def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)),
582590 args: ty::GenericArgs::empty(),
583591 },
584592 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> {
618618 let ty = self.monomorphize(ty);
619619 let drop_fn = Instance::resolve_drop_glue(bx.tcx(), ty);
620620
621 if let ty::InstanceKind::DropGlue(_, None) = drop_fn.def {
621 if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_fn.def {
622622 // we don't actually need to drop anything.
623623 return helper.funclet_br(self, bx, target, mergeable_succ, &[]);
624624 }
......@@ -934,7 +934,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
934934 match instance.def {
935935 // We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
936936 // it is `func returning noop future`
937 ty::InstanceKind::DropGlue(_, None) => {
937 ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => {
938938 // Empty drop glue; a no-op.
939939 let target = target.unwrap();
940940 return helper.funclet_br(self, bx, target, mergeable_succ, &[]);
......@@ -1317,7 +1317,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13171317 }
13181318 LocalRef::Operand(arg) => {
13191319 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 );
13211324 };
13221325 bx.typed_place_copy(place_value, tmp.val, fn_abi.args[i].layout);
13231326 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> {
665665 let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id)
666666 {
667667 let instance = ty::Instance {
668 def: ty::InstanceKind::ThreadLocalShim(def_id),
668 def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)),
669669 args: ty::GenericArgs::empty(),
670670 };
671671 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> {
428428 // Determine whether this is a non-capturing closure. That's relevant as their first
429429 // argument can be skipped (and that's the only kind of argument skipping we allow).
430430 let is_non_capturing_closure =
431 (matches!(instance.def, ty::InstanceKind::ClosureOnceShim { .. })
431 (matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }))
432432 || self.tcx.is_closure_like(def_id))
433433 && {
434434 let arg = &callee_fn_abi.args[0];
......@@ -652,18 +652,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
652652 interp_ok(())
653653 }
654654 }
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(..))
667667 | ty::InstanceKind::Item(_) => {
668668 // We need MIR for this fn.
669669 // 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> {
607607 enter_trace_span!(M, resolve::resolve_drop_glue, ty = ?place.layout.ty);
608608 Instance::resolve_drop_glue(*self.tcx, place.layout.ty)
609609 };
610 if let ty::InstanceKind::DropGlue(_, None) = instance.def {
610 if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = instance.def {
611611 // This is the branch we enter if and only if the dropped type has no drop glue
612612 // whatsoever. This can happen as a result of monomorphizing a drop of a
613613 // 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
13A `#[lang = ".."]` attribute was placed on the wrong item type.
24
35Erroneous code example:
46
5```compile_fail,E0718
7```compile_fail
68#![feature(lang_items)]
79
810#[lang = "owned_box"]
compiler/rustc_hir/src/hir.rs+24-4
......@@ -3852,14 +3852,34 @@ pub enum OpaqueTyOrigin<D> {
38523852 },
38533853}
38543854
3855#[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)]
3856pub 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
38553865#[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)]
38563866pub struct DelegationInfo {
38573867 pub call_expr_id: HirId,
38583868 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>,
38633883 pub group_id: Option<(LocalExpnId, bool /* unused_target_expr */)>,
38643884}
38653885
compiler/rustc_hir_analysis/src/delegation.rs+83-157
......@@ -5,16 +5,15 @@
55use std::debug_assert_matches;
66
77use rustc_data_structures::fx::FxHashMap;
8use rustc_hir::PathSegment;
98use rustc_hir::def::DefKind;
109use rustc_hir::def_id::{DefId, LocalDefId};
10use rustc_hir::{DelegationSelfTyPropagationKind, PathSegment};
1111use rustc_middle::ty::{
1212 self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
1313};
1414use rustc_span::{ErrorGuaranteed, Span, kw};
1515
1616use crate::collect::ItemCtxt;
17use crate::diagnostics::DelegationSelfTypeNotSpecified;
1817use crate::hir_ty_lowering::HirTyLowerer;
1918
2019type RemapTable = FxHashMap<u32, u32>;
......@@ -65,8 +64,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamIndexRemapper<'tcx> {
6564 }
6665}
6766
67#[derive(Debug)]
6868enum SelfPositionKind {
69 AfterLifetimes(bool /* Should propagate self ty */),
69 AfterLifetimes(Option<DelegationSelfTyPropagationKind>),
7070 Zero,
7171 None,
7272}
......@@ -83,8 +83,8 @@ fn create_self_position_kind(
8383 | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero,
8484
8585 (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)
8888 }
8989
9090 _ => SelfPositionKind::None,
......@@ -268,28 +268,6 @@ fn get_parent_and_inheritance_kind<'tcx>(
268268 }
269269}
270270
271fn 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
293271fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option<Ty<'tcx>> {
294272 let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id");
295273 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) ->
302280 | (FnKind::AssocTrait, FnKind::AssocTrait) => {
303281 match create_self_position_kind(tcx, delegation_id, sig_id) {
304282 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 })
313301 }
314302 SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)),
315303 }
......@@ -348,137 +336,69 @@ fn create_generic_args<'tcx>(
348336 sig_id: DefId,
349337 delegation_id: LocalDefId,
350338 mut parent_args: &[ty::GenericArg<'tcx>],
351 child_args: &[ty::GenericArg<'tcx>],
339 mut child_args: &[ty::GenericArg<'tcx>],
352340) -> 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);
355342 let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id);
356343
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);
361344 let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count();
362345 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,
371346
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];
388349
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..];
394351
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);
401358
402 let mut new_args = vec![];
359 parent_args =
360 tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args;
403361
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()..];
406364
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 }
414367
415 lifetimes_end_pos = parent_args_lifetimes_count;
368 let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into());
416369
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 }
418375
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)
420381 }
421382 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)
430385 }
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),
433387 };
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 }
462388
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<_>>()
482402}
483403
484404pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
......@@ -541,7 +461,10 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
541461 let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
542462 let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
543463 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 );
545468
546469 let collector = PredicatesCollector { tcx, preds: vec![], args, folder, filter_self_preds };
547470 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>(
640563
641564 let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id);
642565 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);
643572
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 });
652578
653579 let child_args = info
654 .child_args_segment_id
580 .child_seg_id_for_sig
655581 .and_then(get_segment)
656582 .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Fn | DefKind::AssocFn))
657583 .map(|(segment, def_id)| {
compiler/rustc_hir_analysis/src/diagnostics.rs-8
......@@ -1582,14 +1582,6 @@ pub(crate) struct UnsupportedDelegation<'a> {
15821582 pub callee_span: Span,
15831583}
15841584
1585#[derive(Diagnostic)]
1586#[diag("delegation self type is not specified")]
1587#[help("consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`")]
1588pub(crate) struct DelegationSelfTypeNotSpecified {
1589 #[primary_span]
1590 pub span: Span,
1591}
1592
15931585#[derive(Diagnostic)]
15941586#[diag("inferred lifetimes are not allowed in delegations as we need to inherit signature")]
15951587pub(crate) struct ElidedLifetimesAreNotAllowedInDelegations {
compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs+26-18
......@@ -6,7 +6,7 @@ use rustc_errors::{
66};
77use rustc_hir::def::{DefKind, Res};
88use rustc_hir::def_id::DefId;
9use rustc_hir::{self as hir, GenericArg};
9use rustc_hir::{self as hir, DelegationInfo, GenericArg};
1010use rustc_middle::ty::{
1111 self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty,
1212};
......@@ -430,8 +430,17 @@ pub(crate) fn check_generic_arg_count(
430430 prohibit_assoc_item_constraint(cx, c, None);
431431 }
432432
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 };
435444
436445 let mut invalid_args = vec![];
437446
......@@ -458,7 +467,7 @@ pub(crate) fn check_generic_arg_count(
458467 };
459468
460469 let reported = cx.dcx().emit_err(WrongNumberOfGenericArgs::new(
461 cx.tcx(),
470 tcx,
462471 gen_args_info,
463472 seg,
464473 gen_params,
......@@ -536,20 +545,19 @@ pub(crate) fn check_generic_arg_count(
536545 .map(|param| param.name)
537546 .collect();
538547 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 )
549556 })
550 } else {
551 false
552 };
557 })
558 } else {
559 false
560 };
553561 // We set this to true and delay emitting `WrongNumberOfGenericArgs`
554562 // to provide a succinct error for cases like issue #113073,
555563 // 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(
573581 let reported = gen_args.has_err().unwrap_or_else(|| {
574582 cx.dcx()
575583 .create_err(WrongNumberOfGenericArgs::new(
576 cx.tcx(),
584 tcx,
577585 gen_args_info,
578586 seg,
579587 gen_params,
compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs+15-1
......@@ -2522,15 +2522,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25222522 ) -> Const<'tcx> {
25232523 let tcx = self.tcx();
25242524
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
25252533 let tys = match ty.kind() {
25262534 ty::Tuple(tys) => tys,
25272535 ty::Error(e) => return Const::new_error(tcx, *e),
25282536 _ => {
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()));
25302539 return Const::new_error(tcx, e);
25312540 }
25322541 };
25332542
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
25342548 let exprs = exprs
25352549 .iter()
25362550 .zip(tys.iter())
compiler/rustc_hir_typeck/src/cast.rs+20-1
......@@ -739,9 +739,21 @@ impl<'a, 'tcx> CastCheck<'tcx> {
739739 );
740740 }
741741
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
742753 #[instrument(skip(fcx), level = "debug")]
743754 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);
745757 self.cast_ty = fcx.structurally_resolve_type(self.cast_span, self.cast_ty);
746758
747759 debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty);
......@@ -1169,3 +1181,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
11691181 }
11701182 }
11711183}
1184
1185fn 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>(
9090 }
9191
9292 // Check that argument is Sized.
93 if !params_can_be_unsized {
93 if !params_can_be_unsized || fn_sig.abi() == rustc_abi::ExternAbi::RustTail {
9494 fcx.require_type_is_sized(
9595 param_ty,
9696 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;
44use rustc_hir::def::{DefKind, Res};
55use rustc_hir::def_id::DefId;
66use rustc_infer::traits::ObligationCauseCode;
7use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
7use rustc_middle::ty::{
8 self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
9};
810use rustc_span::{Span, kw};
11use rustc_trait_selection::infer::InferCtxtExt;
912use rustc_trait_selection::traits;
1013
1114use crate::FnCtxt;
......@@ -37,6 +40,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3740 &self,
3841 error: &mut traits::FulfillmentError<'tcx>,
3942 ) -> bool {
43 if self.adjust_binop_index_operand(error) {
44 return true;
45 }
46
4047 let (def_id, hir_id, idx, flavor) = match *error.obligation.cause.code().peel_derives() {
4148 ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) => {
4249 (def_id, hir_id, idx, ClauseFlavor::Where)
......@@ -165,6 +172,119 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
165172 }
166173 }
167174
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
168288 fn point_at_expr_if_possible(
169289 &self,
170290 error: &mut traits::FulfillmentError<'tcx>,
compiler/rustc_hir_typeck/src/op.rs+1
......@@ -313,6 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
313313 }
314314
315315 self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
316
316317 method.sig.output()
317318 }
318319 // 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> {
348348 fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
349349 intravisit::walk_ty(self, hir_ty);
350350 // 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
352352 if let Some(ty) = self.fcx.node_ty_opt(hir_ty.hir_id) {
353353 let ty = self.resolve(ty, &hir_ty.span);
354354 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;
88use rustc_target::spec::SanitizerSet;
99
1010use crate::mono::Visibility;
11use crate::ty::{InstanceKind, TyCtxt};
11use crate::ty::{InstanceKind, ShimKind, TyCtxt};
1212
1313impl<'tcx> TyCtxt<'tcx> {
1414 pub fn codegen_instance_attrs(
......@@ -33,7 +33,7 @@ impl<'tcx> TyCtxt<'tcx> {
3333 //
3434 // A `ClosureOnceShim` with the track_caller attribute does not have a symbol,
3535 // and therefore can be skipped here.
36 if let InstanceKind::ReifyShim(_, _) = instance_kind
36 if let InstanceKind::Shim(ShimKind::Reify(_, _)) = instance_kind
3737 && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
3838 {
3939 if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
......@@ -54,8 +54,11 @@ impl<'tcx> TyCtxt<'tcx> {
5454 }
5555
5656 // 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
5962 {
6063 let closure_attrs = self.codegen_fn_attrs(closure);
6164 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> {
7575 tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty))
7676 }
7777 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)),
7979 args: ty::GenericArgs::empty(),
8080 }),
8181 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};
3232use crate::ty::codec::{TyDecoder, TyEncoder};
3333use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
3434use 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,
3737};
3838
3939mod basic_blocks;
......@@ -127,8 +127,8 @@ impl<'tcx> MirSource<'tcx> {
127127 MirSource { instance: InstanceKind::Item(def_id), promoted: None }
128128 }
129129
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 }
132132 }
133133
134134 #[inline]
compiler/rustc_middle/src/mir/pretty.rs+4-4
......@@ -218,7 +218,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> {
218218 // All drop shims have the same DefId, so we have to add the type
219219 // to get unique file names.
220220 let shim_disambiguator = match source.instance {
221 ty::InstanceKind::DropGlue(_, Some(ty)) => {
221 ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) => {
222222 // Unfortunately, pretty-printed types are not very filename-friendly.
223223 // We do some filtering.
224224 let mut s = ".".to_owned();
......@@ -229,7 +229,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> {
229229 }));
230230 s
231231 }
232 ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => {
232 ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, ty)) => {
233233 let mut s = ".".to_owned();
234234 s.extend(ty.to_string().chars().filter_map(|c| match c {
235235 ' ' => None,
......@@ -238,7 +238,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> {
238238 }));
239239 s
240240 }
241 ty::InstanceKind::AsyncDropGlue(_, ty) => {
241 ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) => {
242242 let ty::Coroutine(_, args) = ty.kind() else {
243243 bug!();
244244 };
......@@ -251,7 +251,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> {
251251 }));
252252 s
253253 }
254 ty::InstanceKind::FutureDropPollShim(_, proxy_cor, impl_cor) => {
254 ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, proxy_cor, impl_cor)) => {
255255 let mut s = ".".to_owned();
256256 s.extend(proxy_cor.to_string().chars().filter_map(|c| match c {
257257 ' ' => None,
compiler/rustc_middle/src/mir/visit.rs+15-15
......@@ -347,27 +347,27 @@ macro_rules! make_mir_visitor {
347347 ty::InstanceKind::Item(_def_id) => {}
348348
349349 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, _))
352352 | 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 {
356356 coroutine_closure_def_id: _def_id,
357357 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)) => {
367367 // FIXME(eddyb) use a better `TyContext` here.
368368 self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
369369 }
370 ty::InstanceKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty) => {
370 ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_def_id, proxy_ty, impl_ty)) => {
371371 self.visit_ty($(& $mutability)? *proxy_ty, TyContext::Location(location));
372372 self.visit_ty($(& $mutability)? *impl_ty, TyContext::Location(location));
373373 }
compiler/rustc_middle/src/mono.rs+15-15
......@@ -22,7 +22,7 @@ use tracing::debug;
2222use crate::dep_graph::dep_node::{make_compile_codegen_unit, make_compile_mono_item};
2323use crate::dep_graph::{DepNode, WorkProduct, WorkProductId};
2424use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
25use crate::ty::{self, GenericArgs, Instance, InstanceKind, SymbolName, Ty, TyCtxt};
25use crate::ty::{self, GenericArgs, Instance, InstanceKind, ShimKind, SymbolName, Ty, TyCtxt};
2626
2727/// Describes how a monomorphization will be instantiated in object files.
2828#[derive(PartialEq)]
......@@ -173,7 +173,7 @@ impl<'tcx> MonoItem<'tcx> {
173173 // incrementality (which wants small CGUs with as many things GloballyShared as possible).
174174 // The heuristics implemented here do better than a completely naive approach in the
175175 // 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 {
177177 if tcx.sess.opts.optimize == OptLevel::No {
178178 return InstantiationMode::GloballyShared { may_conflict: false };
179179 }
......@@ -523,20 +523,20 @@ impl<'tcx> CodegenUnit<'tcx> {
523523 match item {
524524 MonoItem::Fn(ref instance) => match instance.def {
525525 InstanceKind::Item(def) => def.as_local().map(|_| def),
526 InstanceKind::VTableShim(..)
527 | InstanceKind::ReifyShim(..)
528 | InstanceKind::Intrinsic(..)
529 | InstanceKind::FnPtrShim(..)
526 InstanceKind::Intrinsic(..)
530527 | 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,
540540 },
541541 MonoItem::Static(def_id) => def_id.as_local().map(|_| def_id),
542542 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! {
14001400 }
14011401
14021402 /// 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> {
14041404 arena_cache
14051405 desc {
1406 "generating MIR shim for `{}`, instance={:?}",
1406 "generating MIR shim for `{}`, kind={:?}",
14071407 tcx.def_path_str(key.def_id()),
14081408 key
14091409 }
compiler/rustc_middle/src/query/keys.rs+6
......@@ -63,6 +63,12 @@ impl QueryKey for () {
6363 }
6464}
6565
66impl<'tcx> QueryKey for ty::ShimKind<'tcx> {
67 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
68 tcx.def_span(self.def_id())
69 }
70}
71
6672impl<'tcx> QueryKey for ty::InstanceKind<'tcx> {
6773 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
6874 tcx.def_span(self.def_id())
compiler/rustc_middle/src/ty/instance.rs+155-102
......@@ -75,12 +75,28 @@ pub enum InstanceKind<'tcx> {
7575 /// caller.
7676 Intrinsic(DefId),
7777
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)]
93pub enum ShimKind<'tcx> {
7894 /// `<T as Trait>::method` where `method` receives unsizeable `self: Self` (part of the
7995 /// `unsized_fn_params` feature).
8096 ///
8197 /// The generated shim will take `Self` via `*mut Self` - conceptually this is `&owned Self` -
8298 /// and dereference the argument to call the original function.
83 VTableShim(DefId),
99 VTable(DefId),
84100
85101 /// `fn()` pointer where the function itself cannot be turned into a pointer.
86102 ///
......@@ -99,22 +115,12 @@ pub enum InstanceKind<'tcx> {
99115 ///
100116 /// This field will only be populated if we are compiling in a mode that needs these shims
101117 /// to be separable, currently only when KCFI is enabled.
102 ReifyShim(DefId, Option<ReifyReason>),
118 Reify(DefId, Option<ReifyReason>),
103119
104120 /// `<fn() as FnTrait>::call_*` (generated `FnTrait` implementation for `fn()` pointers).
105121 ///
106122 /// `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>),
118124
119125 /// `<[FnMut/Fn closure] as FnOnce>::call_once`.
120126 ///
......@@ -122,14 +128,14 @@ pub enum InstanceKind<'tcx> {
122128 ///
123129 /// This generates a body that will just borrow the (owned) self type,
124130 /// 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 },
126132
127133 /// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once`
128134 ///
129135 /// The body generated here differs significantly from the `ClosureOnceShim`,
130136 /// since we need to generate a distinct coroutine type that will move the
131137 /// closure's upvars *out* of the closure.
132 ConstructCoroutineInClosureShim {
138 ConstructCoroutineInClosure {
133139 coroutine_closure_def_id: DefId,
134140 // Whether the generated MIR body takes the coroutine by-ref. This is
135141 // because the signature of `<{async fn} as FnMut>::call_mut` is:
......@@ -142,10 +148,10 @@ pub enum InstanceKind<'tcx> {
142148 /// Compiler-generated accessor for thread locals which returns a reference to the thread local
143149 /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking
144150 /// native support.
145 ThreadLocalShim(DefId),
151 ThreadLocal(DefId),
146152
147153 /// 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>),
149155
150156 /// `core::ptr::drop_glue::<T>`.
151157 ///
......@@ -162,20 +168,20 @@ pub enum InstanceKind<'tcx> {
162168 /// Additionally, arrays, tuples, and closures get a `Clone` shim even if they aren't `Copy`.
163169 ///
164170 /// 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>),
166172
167173 /// Compiler-generated `<T as FnPtr>::addr` implementation.
168174 ///
169175 /// Automatically generated for all potentially higher-ranked `fn(I) -> R` types.
170176 ///
171177 /// The `DefId` is for `FnPtr::addr`, the `Ty` is the type `T`.
172 FnPtrAddrShim(DefId, Ty<'tcx>),
178 FnPtrAddr(DefId, Ty<'tcx>),
173179
174180 /// `core::future::async_drop::async_drop_in_place::<'_, T>`.
175181 ///
176182 /// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty`
177183 /// is the type `T`.
178 AsyncDropGlueCtorShim(DefId, Ty<'tcx>),
184 AsyncDropGlueCtor(DefId, Ty<'tcx>),
179185
180186 /// `core::future::async_drop::async_drop_in_place::<'_, T>::{closure}`.
181187 ///
......@@ -228,10 +234,12 @@ impl<'tcx> Instance<'tcx> {
228234 InstanceKind::Item(def) => tcx
229235 .upstream_monomorphizations_for(def)
230236 .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(_, _)) => {
235243 tcx.upstream_async_drop_glue_for(self.args)
236244 }
237245 _ => None,
......@@ -244,45 +252,18 @@ impl<'tcx> InstanceKind<'tcx> {
244252 pub fn def_id(self) -> DefId {
245253 match self {
246254 InstanceKind::Item(def_id)
247 | InstanceKind::VTableShim(def_id)
248 | InstanceKind::ReifyShim(def_id, _)
249 | InstanceKind::FnPtrShim(def_id, _)
250255 | 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(),
264258 }
265259 }
266260
267261 /// Returns the `DefId` of instances which might not require codegen locally.
268262 pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
269263 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(),
286267 }
287268 }
288269
......@@ -293,31 +274,28 @@ impl<'tcx> InstanceKind<'tcx> {
293274 /// `generates_cgu_internal_copy` for more information.
294275 pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool {
295276 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 }
309285 }
310286
311287 pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
312288 match *self {
313289 InstanceKind::Item(def_id)
314290 | InstanceKind::Virtual(def_id, _)
315 | InstanceKind::VTableShim(def_id) => {
291 | InstanceKind::Shim(ShimKind::VTable(def_id)) => {
316292 tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
317293 }
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,
321299 _ => false,
322300 }
323301 }
......@@ -330,22 +308,79 @@ impl<'tcx> InstanceKind<'tcx> {
330308 /// body should perform necessary instantiations.
331309 pub fn has_polymorphic_mir_body(&self) -> bool {
332310 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
317impl<'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,
349384 }
350385 }
351386}
......@@ -416,7 +451,11 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> {
416451 continue;
417452 } else {
418453 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 )),
420459 args: proxy_args,
421460 };
422461 }
......@@ -426,12 +465,16 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> {
426465 };
427466 if first_cor != cor_ty {
428467 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 )),
430473 args: proxy_args,
431474 };
432475 } else {
433476 return Instance {
434 def: ty::InstanceKind::AsyncDropGlue(poll_def_id, cor_ty),
477 def: ty::InstanceKind::Shim(ShimKind::AsyncDropGlue(poll_def_id, cor_ty)),
435478 args: child_args,
436479 };
437480 }
......@@ -599,11 +642,11 @@ impl<'tcx> Instance<'tcx> {
599642 match resolved.def {
600643 InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => {
601644 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));
603646 }
604647 InstanceKind::Virtual(def_id, _) => {
605648 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));
607650 }
608651 _ if tcx.sess.is_sanitizer_kcfi_enabled() => {
609652 // Reify `::call`-like method implementations
......@@ -611,7 +654,10 @@ impl<'tcx> Instance<'tcx> {
611654 // Reroute through a reify via the *unresolved* instance. The resolved one can't
612655 // be directly reified because it's closure-like. The reify can handle the
613656 // 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 }
615661 // Reify `Trait::method` implementations if the trait is dyn-compatible.
616662 } else if let Some(assoc) = tcx.opt_associated_item(def_id)
617663 && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) =
......@@ -620,7 +666,8 @@ impl<'tcx> Instance<'tcx> {
620666 {
621667 // If this function could also go in a vtable, we need to `ReifyShim` it with
622668 // 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))
624671 }
625672 }
626673 _ => {}
......@@ -645,7 +692,7 @@ impl<'tcx> Instance<'tcx> {
645692
646693 if is_vtable_shim {
647694 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 };
649696 }
650697
651698 let mut resolved = Instance::expect_resolve(tcx, typing_env, def_id, args, span);
......@@ -688,19 +735,22 @@ impl<'tcx> Instance<'tcx> {
688735 // Create a shim for the `FnOnce/FnMut/Fn` method we are calling
689736 // - unlike functions, invoking a closure always goes through a
690737 // 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 };
692742 } else {
693743 debug!(
694744 " => vtable fn pointer created for function with #[track_caller]: {:?}",
695745 def
696746 );
697 resolved.def = InstanceKind::ReifyShim(def, reason);
747 resolved.def = InstanceKind::Shim(ShimKind::Reify(def, reason));
698748 }
699749 }
700750 }
701751 InstanceKind::Virtual(def_id, _) => {
702752 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))
704754 }
705755 _ => {}
706756 }
......@@ -770,8 +820,11 @@ impl<'tcx> Instance<'tcx> {
770820 .def_id;
771821 let track_caller =
772822 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 });
775828
776829 let self_ty = Ty::new_closure(tcx, closure_did, args);
777830
compiler/rustc_middle/src/ty/mod.rs+5-16
......@@ -85,7 +85,7 @@ pub use self::context::{
8585 CtxtInterners, CurrentGcx, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls,
8686};
8787pub use self::fold::*;
88pub use self::instance::{Instance, InstanceKind, ReifyReason};
88pub use self::instance::{Instance, InstanceKind, ReifyReason, ShimKind};
8989pub(crate) use self::list::RawList;
9090pub use self::list::{List, ListWithCachedTypeInfo};
9191pub use self::opaque_types::OpaqueTypeKey;
......@@ -1803,20 +1803,9 @@ impl<'tcx> TyCtxt<'tcx> {
18031803 _ => self.optimized_mir(def),
18041804 }
18051805 }
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),
18201809 };
18211810
18221811 assert!(
......@@ -1942,7 +1931,7 @@ impl<'tcx> TyCtxt<'tcx> {
19421931 if args[0].has_placeholders() || args[0].has_non_region_param() {
19431932 return Err(self.layout_error(LayoutError::TooGeneric(ty())));
19441933 }
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));
19461935 self.mir_shims(instance)
19471936 .coroutine_layout_raw()
19481937 .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> {
367367 cx.print_def_path(self.def_id(), self.args)?;
368368 match self.def {
369369 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)")?,
379370 ty::InstanceKind::Intrinsic(_) => cx.write_str(" - intrinsic")?,
380371 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
381impl<'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)")
387388 }
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)")
392391 }
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})"))
396402 }
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 }
399406 }
400407}
401408
compiler/rustc_mir_build/src/check_tail_calls.rs+20-1
......@@ -147,7 +147,9 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
147147 // ```
148148 // we should think what is the expected behavior here.
149149 // (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 {
151153 let caller_ty = self.tcx.type_of(self.caller_def_id).skip_binder();
152154
153155 self.report_signature_mismatch(
......@@ -189,6 +191,12 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
189191 if callee_sig.c_variadic() {
190192 self.report_c_variadic_callee(expr.span);
191193 }
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 }
192200 }
193201
194202 /// Returns true if the caller function needs a location argument
......@@ -417,6 +425,17 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
417425
418426 self.found_errors = Err(err);
419427 }
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 }
420439}
421440
422441impl<'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>(
223223 None,
224224 &mut PerParentDisambiguatorState::new(parent_def_id),
225225 );
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 };
228230
229231 if let Some(dumper) = MirDumper::new(tcx, "built", &by_move_body) {
230232 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>(
206206 // Update the body's def to become the drop glue.
207207 let coroutine_instance = body.source.instance;
208208 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)));
210210
211211 // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible
212212 // filename.
compiler/rustc_mir_transform/src/coroutine/mod.rs+1-1
......@@ -71,7 +71,7 @@ use rustc_index::{Idx, IndexVec, indexvec};
7171use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
7272use rustc_middle::mir::*;
7373use rustc_middle::ty::{
74 self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt,
74 self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, ShimKind, Ty, TyCtxt,
7575};
7676use rustc_middle::{bug, span_bug};
7777use 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;
1515use rustc_middle::mir::visit::*;
1616use rustc_middle::mir::*;
1717use rustc_middle::ty::{
18 self, Instance, InstanceKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized,
18 self, Instance, InstanceKind, ShimKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized,
1919};
2020use rustc_session::config::{DebugInfo, OptLevel};
2121use rustc_span::Spanned;
......@@ -739,18 +739,21 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
739739 // the correct param-env for types being dropped. Stall resolving
740740 // the MIR for this instance until all of its const params are
741741 // 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 {
743745 debug!("still needs substitution");
744746 return Err("implementation limitation -- HACK for dropping polymorphic type");
745747 }
746 InstanceKind::AsyncDropGlue(_, ty) | InstanceKind::AsyncDropGlueCtorShim(_, ty) => {
748 InstanceKind::Shim(ShimKind::AsyncDropGlue(_, ty))
749 | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, ty)) => {
747750 return if ty.still_further_specializable() {
748751 Err("still needs substitution")
749752 } else {
750753 Ok(())
751754 };
752755 }
753 InstanceKind::FutureDropPollShim(_, ty, ty2) => {
756 InstanceKind::Shim(ShimKind::FutureDropPoll(_, ty, ty2)) => {
754757 return if ty.still_further_specializable() || ty2.still_further_specializable() {
755758 Err("still needs substitution")
756759 } else {
......@@ -762,15 +765,15 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
762765 // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we
763766 // do not need to catch this here, we can wait until the inliner decides to continue
764767 // 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(()),
774777 }
775778
776779 if inliner.tcx().is_constructor(callee_def_id) {
......@@ -1370,8 +1373,8 @@ fn try_instance_mir<'tcx>(
13701373 tcx: TyCtxt<'tcx>,
13711374 instance: InstanceKind<'tcx>,
13721375) -> 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
13751378 && let ty::Adt(def, args) = ty.kind()
13761379 {
13771380 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;
44use rustc_hir::def_id::{DefId, LocalDefId};
55use rustc_hir::limit::Limit;
66use rustc_middle::mir::TerminatorKind;
7use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, TyCtxt, TypeVisitableExt};
7use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, ShimKind, TyCtxt, TypeVisitableExt};
88use rustc_span::sym;
99use tracing::{instrument, trace};
1010
......@@ -26,24 +26,24 @@ fn should_recurse<'tcx>(tcx: TyCtxt<'tcx>, callee: ty::Instance<'tcx>) -> bool {
2626 // These have MIR and if that MIR is inlined, instantiated and then inlining is run
2727 // again, a function item can end up getting inlined. Thus we'll be able to cause
2828 // 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(..)) => {}
3636
3737 // 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,
3939
4040 // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to
4141 // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this
4242 // 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(..)) => {
4747 if callee.has_param() {
4848 return false;
4949 }
compiler/rustc_mir_transform/src/lint_and_remove_uninhabited.rs+17-6
......@@ -93,8 +93,8 @@ fn find_unreachable_code_from<'tcx>(
9393 bb: BasicBlock,
9494 body: &Body<'tcx>,
9595) -> 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 {
9898 match &stmt.kind {
9999 // Ignore the implicit `()` return place assignment for unit functions/blocks
100100 StatementKind::Assign((_, Rvalue::Use(Operand::Constant(const_), _)))
......@@ -108,7 +108,10 @@ fn find_unreachable_code_from<'tcx>(
108108 StatementKind::Assign((place, _)) if place.as_local() == Some(RETURN_PLACE) => {
109109 continue;
110110 }
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 { .. } => {
112115 continue;
113116 }
114117 StatementKind::FakeRead(..) => return Some((stmt.source_info, "definition")),
......@@ -116,10 +119,18 @@ fn find_unreachable_code_from<'tcx>(
116119 }
117120 }
118121
119 let term = bb.terminator();
122 let term = bbdata.terminator();
120123 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,
123134 _ => Some((term.source_info, "expression")),
124135 }
125136}
compiler/rustc_mir_transform/src/shim.rs+42-55
......@@ -31,16 +31,15 @@ pub(super) fn provide(providers: &mut Providers) {
3131 providers.mir_shims = make_shim;
3232}
3333
34fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<'tcx> {
35 debug!("make_shim({:?})", instance);
34fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> {
35 debug!("make_shim({:?})", shim);
3636
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) => {
4039 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))
4241 }
43 ty::InstanceKind::FnPtrShim(def_id, ty) => {
42 ty::ShimKind::FnPtr(def_id, ty) => {
4443 let trait_ = tcx.parent(def_id);
4544 // Supports `Fn` or `async Fn` traits.
4645 let adjustment = match tcx
......@@ -53,17 +52,17 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
5352 None => bug!("fn pointer {:?} is not an fn", ty),
5453 };
5554
56 build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect(ty))
55 build_call_shim(tcx, shim, Some(adjustment), CallKind::Indirect(ty))
5756 }
5857 // We are generating a call back to our def-id, which the
5958 // codegen backend knows to turn to an actual call, be it
6059 // a virtual call, or a direct call to a function for which
6160 // indirect calls must be codegen'd differently than direct ones
6261 // (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))
6564 }
66 ty::InstanceKind::ClosureOnceShim { call_once: _, closure: _, track_caller: _ } => {
65 ty::ShimKind::ClosureOnce { call_once: _, closure: _, track_caller: _ } => {
6766 let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP);
6867 let call_mut = tcx
6968 .associated_items(fn_mut)
......@@ -72,15 +71,14 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
7271 .unwrap()
7372 .def_id;
7473
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))
7675 }
7776
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 }
8280
83 ty::InstanceKind::DropGlue(def_id, ty) => {
81 ty::ShimKind::DropGlue(def_id, ty) => {
8482 // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end
8583 // of this function. Is this intentional?
8684 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<
110108
111109 let mut body =
112110 EarlyBinder::bind(body.clone()).instantiate(tcx, args).skip_norm_wip();
113 debug!("make_shim({:?}) = {:?}", instance, body);
111 debug!("make_shim({:?}) = {:?}", shim, body);
114112
115113 pm::run_passes(
116114 tcx,
......@@ -129,10 +127,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
129127
130128 build_drop_shim(tcx, def_id, ty, ty::TypingEnv::post_analysis(tcx, def_id))
131129 }
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) => {
136134 let mut body =
137135 async_destructor_ctor::build_future_drop_poll_shim(tcx, def_id, proxy_ty, impl_ty);
138136
......@@ -148,10 +146,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
148146 pm::Optimizations::Allowed,
149147 );
150148 run_optimization_passes(tcx, &mut body);
151 debug!("make_shim({:?}) = {:?}", instance, body);
149 debug!("make_shim({:?}) = {:?}", shim, body);
152150 return body;
153151 }
154 ty::InstanceKind::AsyncDropGlue(def_id, ty) => {
152 ty::ShimKind::AsyncDropGlue(def_id, ty) => {
155153 let mut body = async_destructor_ctor::build_async_drop_shim(tcx, def_id, ty);
156154
157155 // 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<
170168 Some(MirPhase::Runtime(RuntimePhase::PostCleanup)),
171169 );
172170 run_optimization_passes(tcx, &mut body);
173 debug!("make_shim({:?}) = {:?}", instance, body);
171 debug!("make_shim({:?}) = {:?}", shim, body);
174172 return body;
175173 }
176174
177 ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) => {
175 ty::ShimKind::AsyncDropGlueCtor(def_id, ty) => {
178176 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);
180178 return body;
181179 }
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 }
188180 };
189 debug!("make_shim({:?}) = untransformed {:?}", instance, result);
181 debug!("make_shim({:?}) = untransformed {:?}", shim, result);
190182
191183 deref_finder(tcx, &mut result, false);
192184
......@@ -211,7 +203,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
211203 Some(MirPhase::Runtime(RuntimePhase::Optimized)),
212204 );
213205
214 debug!("make_shim({:?}) = {:?}", instance, result);
206 debug!("make_shim({:?}) = {:?}", shim, result);
215207
216208 result
217209}
......@@ -300,7 +292,7 @@ pub fn build_drop_shim<'tcx>(
300292 }
301293 block(&mut blocks, TerminatorKind::Return);
302294
303 let source = MirSource::from_instance(ty::InstanceKind::DropGlue(def_id, ty));
295 let source = MirSource::from_shim(ty::ShimKind::DropGlue(def_id, ty));
304296 let mut body =
305297 new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
306298
......@@ -480,11 +472,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
480472 }
481473}
482474
483fn build_thread_local_shim<'tcx>(
484 tcx: TyCtxt<'tcx>,
485 instance: ty::InstanceKind<'tcx>,
486) -> Body<'tcx> {
487 let def_id = instance.def_id();
475fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> {
476 let def_id = shim.def_id();
488477
489478 let span = tcx.def_span(def_id);
490479 let source_info = SourceInfo::outermost(span);
......@@ -502,7 +491,7 @@ fn build_thread_local_shim<'tcx>(
502491 )]);
503492
504493 new_body(
505 MirSource::from_instance(instance),
494 MirSource::from_shim(shim),
506495 blocks,
507496 IndexVec::from_raw(vec![LocalDecl::new(tcx.thread_local_ptr_ty(def_id), span)]),
508497 0,
......@@ -565,10 +554,8 @@ impl<'tcx> CloneShimBuilder<'tcx> {
565554 }
566555
567556 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]));
572559 new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span)
573560 }
574561
......@@ -776,14 +763,14 @@ impl<'tcx> CloneShimBuilder<'tcx> {
776763#[instrument(level = "debug", skip(tcx), ret)]
777764fn build_call_shim<'tcx>(
778765 tcx: TyCtxt<'tcx>,
779 instance: ty::InstanceKind<'tcx>,
766 shim: ty::ShimKind<'tcx>,
780767 rcvr_adjustment: Option<Adjustment>,
781768 call_kind: CallKind<'tcx>,
782769) -> Body<'tcx> {
783770 // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used
784771 // to instantiate into the signature of the shim. It is not necessary for users of this
785772 // 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 {
787774 let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx));
788775
789776 let untuple_args = sig.inputs();
......@@ -796,12 +783,12 @@ fn build_call_shim<'tcx>(
796783 (None, None)
797784 };
798785
799 let def_id = instance.def_id();
786 let def_id = shim.def_id();
800787
801788 let sig = tcx.fn_sig(def_id);
802789 let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig));
803790
804 assert_eq!(sig_args.is_some(), !instance.has_polymorphic_mir_body());
791 assert_eq!(sig_args.is_some(), !shim.has_polymorphic_mir_body());
805792 let mut sig = if let Some(sig_args) = sig_args {
806793 sig.instantiate(tcx, &sig_args).skip_norm_wip()
807794 } else {
......@@ -830,14 +817,14 @@ fn build_call_shim<'tcx>(
830817 DerefSource::MutRef => Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fnty),
831818 DerefSource::MutPtr => Ty::new_mut_ptr(tcx, fnty),
832819 },
833 Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {instance:?}"),
820 Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {shim:?}"),
834821 };
835822 sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
836823 }
837824
838825 // FIXME: Avoid having to adjust the signature both here and in
839826 // `fn_sig_for_fn_abi`.
840 if let ty::InstanceKind::VTableShim(..) = instance {
827 if let ty::ShimKind::VTable(..) = shim {
841828 // Modify fn(self, ...) to fn(self: *mut Self, ...)
842829 let mut inputs_and_output = sig.inputs_and_output.to_vec();
843830 let self_arg = &mut inputs_and_output[0];
......@@ -995,7 +982,7 @@ fn build_call_shim<'tcx>(
995982 }
996983
997984 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);
999986
1000987 if let ExternAbi::RustCall = sig.abi() {
1001988 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
11191106 Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }),
11201107 false,
11211108 );
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));
11231110 new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span)
11241111}
11251112
......@@ -1218,7 +1205,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
12181205 false,
12191206 );
12201207
1221 let source = MirSource::from_instance(ty::InstanceKind::ConstructCoroutineInClosureShim {
1208 let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosure {
12221209 coroutine_closure_def_id,
12231210 receiver_by_ref,
12241211 });
compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs+10-10
......@@ -106,7 +106,7 @@ pub(super) fn build_async_drop_shim<'tcx>(
106106 );
107107 block(&mut blocks, TerminatorKind::Return);
108108
109 let source = MirSource::from_instance(ty::InstanceKind::AsyncDropGlue(def_id, ty));
109 let source = MirSource::from_shim(ty::ShimKind::AsyncDropGlue(def_id, ty));
110110 let mut body =
111111 new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
112112
......@@ -175,17 +175,17 @@ pub(super) fn build_future_drop_poll_shim<'tcx>(
175175 proxy_ty: Ty<'tcx>,
176176 impl_ty: Ty<'tcx>,
177177) -> 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);
179179 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);
181181 };
182182
183183 let span = tcx.def_span(def_id);
184184
185185 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)
187187 } 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)
189189 }
190190}
191191
......@@ -198,16 +198,16 @@ fn build_adrop_for_coroutine_shim<'tcx>(
198198 proxy_ty: Ty<'tcx>,
199199 impl_ty: Ty<'tcx>,
200200 span: Span,
201 instance: ty::InstanceKind<'tcx>,
201 shim: ty::ShimKind<'tcx>,
202202) -> Body<'tcx> {
203203 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);
205205 };
206206 let source_info = SourceInfo::outermost(span);
207207 let body = tcx.optimized_mir(*coroutine_def_id).future_drop_poll().unwrap();
208208 let mut body: Body<'tcx> =
209209 EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args).skip_norm_wip();
210 body.source.instance = instance;
210 body.source.instance = ty::InstanceKind::Shim(shim);
211211 body.phase = MirPhase::Runtime(RuntimePhase::Initial);
212212 body.var_debug_info.clear();
213213
......@@ -291,7 +291,7 @@ fn build_adrop_for_adrop_shim<'tcx>(
291291 proxy_ty: Ty<'tcx>,
292292 impl_ty: Ty<'tcx>,
293293 span: Span,
294 instance: ty::InstanceKind<'tcx>,
294 shim: ty::ShimKind<'tcx>,
295295) -> Body<'tcx> {
296296 let source_info = SourceInfo::outermost(span);
297297 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>(
413413 false,
414414 ));
415415
416 let source = MirSource::from_instance(instance);
416 let source = MirSource::from_shim(shim);
417417 let mut body = new_body(source, blocks, locals, sig.inputs().len(), span);
418418 body.phase = MirPhase::Runtime(RuntimePhase::Initial);
419419 return body;
compiler/rustc_monomorphize/src/collector.rs+17-17
......@@ -226,8 +226,8 @@ use rustc_middle::query::TyCtxtAt;
226226use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
227227use rustc_middle::ty::layout::ValidityRequirement;
228228use 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,
231231};
232232use rustc_middle::util::Providers;
233233use rustc_middle::{bug, span_bug};
......@@ -447,7 +447,7 @@ fn collect_items_rec<'tcx>(
447447 used_items.push(respan(
448448 starting_item.span,
449449 MonoItem::Fn(Instance {
450 def: InstanceKind::ThreadLocalShim(def_id),
450 def: InstanceKind::Shim(ShimKind::ThreadLocal(def_id)),
451451 args: GenericArgs::empty(),
452452 }),
453453 ));
......@@ -1013,10 +1013,10 @@ fn visit_instance_use<'tcx>(
10131013 bug!("{:?} being reified", instance);
10141014 }
10151015 }
1016 ty::InstanceKind::ThreadLocalShim(..) => {
1016 ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => {
10171017 bug!("{:?} being reified", instance);
10181018 }
1019 ty::InstanceKind::DropGlue(_, None) => {
1019 ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => {
10201020 // Don't need to emit noop drop glue if we are calling directly.
10211021 //
10221022 // Note that we also optimize away the call to visit_instance_use in vtable construction
......@@ -1025,18 +1025,18 @@ fn visit_instance_use<'tcx>(
10251025 output.push(create_fn_mono_item(tcx, instance, source));
10261026 }
10271027 }
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(..)) => {
10401040 output.push(create_fn_mono_item(tcx, instance, source));
10411041 }
10421042 }
compiler/rustc_monomorphize/src/partitioning.rs+29-29
......@@ -115,7 +115,7 @@ use rustc_middle::mono::{
115115 MonoItemPartitions, Visibility,
116116};
117117use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths};
118use rustc_middle::ty::{self, InstanceKind, TyCtxt};
118use rustc_middle::ty::{self, InstanceKind, ShimKind, TyCtxt};
119119use rustc_middle::util::Providers;
120120use rustc_session::CodegenUnits;
121121use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
......@@ -630,20 +630,20 @@ fn characteristic_def_id_of_mono_item<'tcx>(
630630 MonoItem::Fn(instance) => {
631631 let def_id = match instance.def {
632632 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(..)
640634 | 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,
647647 };
648648
649649 // If this is a method, we want to put it into the same module as
......@@ -794,27 +794,27 @@ fn mono_item_visibility<'tcx>(
794794
795795 let def_id = match instance.def {
796796 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,
801801
802802 // We match the visibility of statics here
803 InstanceKind::ThreadLocalShim(def_id) => {
803 InstanceKind::Shim(ShimKind::ThreadLocal(def_id)) => {
804804 return static_visibility(tcx, can_be_internalized, def_id);
805805 }
806806
807807 // 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(..))
811811 | InstanceKind::Virtual(..)
812812 | 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,
818818 };
819819
820820 // Both the `start_fn` lang item and `main` itself should not be exported,
......@@ -1331,8 +1331,8 @@ pub(crate) fn provide(providers: &mut Providers) {
13311331 // "Normal" functions size estimate: the number of
13321332 // statements, plus one for the terminator.
13331333 InstanceKind::Item(..)
1334 | InstanceKind::DropGlue(..)
1335 | InstanceKind::AsyncDropGlueCtorShim(..) => {
1334 | InstanceKind::Shim(ShimKind::DropGlue(..))
1335 | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => {
13361336 let mir = tcx.instance_mir(instance.def);
13371337 mir.basic_blocks
13381338 .iter()
compiler/rustc_parse/Cargo.toml+1-1
......@@ -6,7 +6,7 @@ edition = "2024"
66[dependencies]
77# tidy-alphabetical-start
88bitflags = "2.4.1"
9rustc-literal-escaper = "0.0.7"
9rustc-literal-escaper = "0.0.8"
1010rustc_ast = { path = "../rustc_ast" }
1111rustc_ast_pretty = { path = "../rustc_ast_pretty" }
1212rustc_data_structures = { path = "../rustc_data_structures" }
compiler/rustc_parse_format/Cargo.toml+1-1
......@@ -5,7 +5,7 @@ edition = "2024"
55
66[dependencies]
77# tidy-alphabetical-start
8rustc-literal-escaper = "0.0.7"
8rustc-literal-escaper = "0.0.8"
99rustc_lexer = { path = "../rustc_lexer" }
1010# tidy-alphabetical-end
1111
compiler/rustc_passes/src/diagnostics.rs-20
......@@ -5,7 +5,6 @@ use rustc_errors::codes::*;
55use rustc_errors::{
66 Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, msg,
77};
8use rustc_hir::Target;
98use rustc_macros::{Diagnostic, Subdiagnostic};
109use rustc_middle::ty::{MainDefinition, Ty};
1110use rustc_span::{DUMMY_SP, Ident, Span, Symbol};
......@@ -326,14 +325,6 @@ pub(crate) struct DeprecatedAnnotationHasNoEffect {
326325 pub span: Span,
327326}
328327
329#[derive(Diagnostic)]
330#[diag("unknown external lang item: `{$lang_item}`", code = E0264)]
331pub(crate) struct UnknownExternLangItem {
332 #[primary_span]
333 pub span: Span,
334 pub lang_item: Symbol,
335}
336
337328#[derive(Diagnostic)]
338329#[diag("`#[panic_handler]` function required, but not found")]
339330pub(crate) struct MissingPanicHandler;
......@@ -398,17 +389,6 @@ pub(crate) struct LangItemWithTargetFeature {
398389 pub sig_span: Span,
399390}
400391
401#[derive(Diagnostic)]
402#[diag("`{$name}` lang item must be applied to a {$expected_target}", code = E0718)]
403pub(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
412392#[derive(Diagnostic)]
413393#[diag("duplicate diagnostic item in crate `{$crate_name}`: `{$name}`")]
414394pub(crate) struct DuplicateDiagnosticItemInCrate {
compiler/rustc_passes/src/lang_items.rs+9-14
......@@ -18,9 +18,7 @@ use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
1818use rustc_session::cstore::ExternCrate;
1919use rustc_span::{Span, Symbol, sym};
2020
21use crate::diagnostics::{
22 DuplicateLangItem, IncorrectCrateType, IncorrectTarget, LangItemOnIncorrectTarget,
23};
21use crate::diagnostics::{DuplicateLangItem, IncorrectCrateType, IncorrectTarget};
2422use crate::weak_lang_items;
2523
2624pub(crate) enum Duplicate {
......@@ -63,8 +61,14 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
6361 ) {
6462 if let Some((name, attr_span)) = extract_ast(attrs) {
6563 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 }
6872 self.collect_item_extended(
6973 lang_item,
7074 def_id,
......@@ -74,15 +78,6 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
7478 actual_target,
7579 );
7680 }
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 }
8681 // Unknown lang item.
8782 _ => {
8883 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;
99use rustc_middle::ty::TyCtxt;
1010use rustc_session::config::CrateType;
1111
12use crate::diagnostics::{
13 MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd, UnknownExternLangItem,
14};
12use crate::diagnostics::{MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd};
1513use crate::lang_items::extract_ast;
1614
1715/// Checks the crate for usage of weak lang items, returning a vector of all the
......@@ -28,27 +26,23 @@ pub(crate) fn check_crate(
2826 items.missing.push(LangItem::EhPersonality);
2927 }
3028
31 visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate);
29 visit::Visitor::visit_crate(&mut WeakLangItemVisitor { items }, krate);
3230
3331 verify(tcx, items);
3432}
3533
36struct WeakLangItemVisitor<'a, 'tcx> {
37 tcx: TyCtxt<'tcx>,
34struct WeakLangItemVisitor<'a> {
3835 items: &'a mut lang_items::LanguageItems,
3936}
4037
41impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> {
38impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_> {
4239 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);
5246 }
5347 }
5448 }
compiler/rustc_proc_macro/Cargo.toml+1-1
......@@ -16,7 +16,7 @@ doctest = false
1616
1717[dependencies]
1818# tidy-alphabetical-start
19rustc-literal-escaper = "0.0.7"
19rustc-literal-escaper = "0.0.8"
2020# tidy-alphabetical-end
2121
2222[features]
compiler/rustc_public/src/unstable/convert/stable/ty.rs+1-12
......@@ -994,18 +994,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
994994 ty::InstanceKind::Virtual(_def_id, idx) => {
995995 crate::mir::mono::InstanceKind::Virtual { idx }
996996 }
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,
1009998 };
1010999 crate::mir::mono::Instance { def, kind }
10111000 }
compiler/rustc_public_bridge/src/context/impls.rs+1-1
......@@ -645,7 +645,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> {
645645
646646 /// Check if this is an empty DropGlue shim.
647647 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)))
649649 }
650650
651651 /// 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> {
548548 root_id,
549549 vis,
550550 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),
552552 });
553553
554554 self.r.indeterminate_imports.push(import);
......@@ -863,7 +863,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
863863 || ast::attr::contains_name(&item.attrs, sym::no_implicit_prelude),
864864 );
865865 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) {
867867 self.r.on_unknown_data.insert(local_def_id, directive);
868868 }
869869 }
......@@ -1040,7 +1040,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
10401040 module_path: Vec::new(),
10411041 vis,
10421042 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),
10441044 });
10451045 if used {
10461046 self.r.import_use_map.insert(import, Used::Other);
......@@ -1172,7 +1172,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
11721172 module_path: Vec::new(),
11731173 vis: Visibility::Restricted(CRATE_DEF_ID),
11741174 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),
11761176 })
11771177 };
11781178
......@@ -1353,7 +1353,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
13531353 module_path: Vec::new(),
13541354 vis,
13551355 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),
13571357 });
13581358 self.r.import_use_map.insert(import, Used::Other);
13591359 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> {
186186 // Does that prevents errors from happening? maybe
187187 let mut parser = AttributeParser::new(
188188 &self.r.tcx.sess,
189 self.r.tcx.features(),
189 self.r.features,
190190 self.r.tcx().registered_tools(()),
191191 ShouldEmit::Nothing,
192192 );
......@@ -433,7 +433,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
433433 // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so
434434 // to avoid affecting stable we have to feature gate the not creating
435435 // anon consts
436 if !self.r.tcx.features().min_generic_const_args() {
436 if !self.r.features.min_generic_const_args() {
437437 let parent = self
438438 .create_def(constant.id, None, DefKind::AnonConst, constant.value.span)
439439 .def_id();
compiler/rustc_resolve/src/error_helper.rs+11-7
......@@ -1628,7 +1628,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
16281628 in_module.for_each_child(self, |this, ident, orig_ident_span, ns, name_binding| {
16291629 // Avoid non-importable candidates.
16301630 if name_binding.is_assoc_item()
1631 && !this.tcx.features().import_trait_associated_functions()
1631 && !this.features.import_trait_associated_functions()
16321632 {
16331633 return;
16341634 }
......@@ -1809,10 +1809,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18091809 }) => {
18101810 if span.allows_unstable(feature) {
18111811 true
1812 } else if self.tcx.features().enabled(feature) {
1812 } else if self.features.enabled(feature) {
18131813 true
18141814 } else if let Some(implied_by) = implied_by
1815 && self.tcx.features().enabled(implied_by)
1815 && self.features.enabled(implied_by)
18161816 {
18171817 true
18181818 } else {
......@@ -4144,13 +4144,17 @@ pub(crate) struct OnUnknownData {
41444144}
41454145
41464146impl OnUnknownData {
4147 pub(crate) fn from_attrs<'tcx>(
4148 tcx: TyCtxt<'tcx>,
4147 pub(crate) fn from_attrs(
4148 r: &Resolver<'_, '_>,
41494149 attrs: &[ast::Attribute],
41504150 ) -> Option<OnUnknownData> {
4151 if tcx.features().diagnostic_on_unknown()
4151 if r.features.diagnostic_on_unknown()
41524152 && 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 )
41544158 {
41554159 Some(Self { directive: directive? })
41564160 } else {
compiler/rustc_resolve/src/ident.rs+83-34
......@@ -23,9 +23,9 @@ use crate::late::{
2323use crate::macros::{MacroRulesScope, sub_namespace_match};
2424use crate::{
2525 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,
2929};
3030
3131#[derive(Copy, Clone)]
......@@ -608,21 +608,36 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
608608 finalize.map(|f| Finalize { used: Used::Scope, ..f }),
609609 )
610610 };
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
626641 match decl {
627642 Ok(decl) => {
628643 if let Some(lint_id) = derive_fallback_lint_id {
......@@ -746,7 +761,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
746761 Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) {
747762 Some(decl) => {
748763 if matches!(ident.name, sym::f16)
749 && !self.tcx.features().f16()
764 && !self.features.f16()
750765 && !orig_ident_span.allows_unstable(sym::f16)
751766 && finalize.is_some()
752767 {
......@@ -759,7 +774,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
759774 .emit();
760775 }
761776 if matches!(ident.name, sym::f128)
762 && !self.tcx.features().f128()
777 && !self.features.f128()
763778 && !orig_ident_span.allows_unstable(sym::f128)
764779 && finalize.is_some()
765780 {
......@@ -1078,10 +1093,49 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10781093 }
10791094 }
10801095
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>(
10831098 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>,
10851139 ident: IdentKey,
10861140 orig_ident_span: Span,
10871141 ns: Namespace,
......@@ -1098,7 +1152,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10981152 // doesn't need to be mutable. It will fail when there is a cycle of imports, and without
10991153 // the exclusive access infinite recursion will crash the compiler with stack overflow.
11001154 let resolution = &*self
1101 .resolution_or_default(module, key, orig_ident_span)
1155 .resolution_or_default(module.to_module(), key, orig_ident_span)
11021156 .try_borrow_mut_unchecked()
11031157 .map_err(|_| ControlFlow::Continue(Determined))?;
11041158
......@@ -1121,11 +1175,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11211175 return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) };
11221176 }
11231177
1124 // In extern modules everything is determined from the start.
1125 if !module.is_local() {
1126 return Err(ControlFlow::Continue(Determined));
1127 };
1128
11291178 // Check if one of single imports can still define the name, block if it can.
11301179 if self.reborrow().single_import_can_define_name(
11311180 &resolution,
......@@ -1535,7 +1584,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15351584 }
15361585
15371586 RibKind::ConstParamTy => {
1538 if !self.tcx.features().generic_const_parameter_types() {
1587 if !self.features.generic_const_parameter_types() {
15391588 if let Some(span) = finalize {
15401589 self.report_error(
15411590 span,
......@@ -1564,7 +1613,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15641613 }
15651614 NoConstantGenericsReason::NonTrivialConstArg => {
15661615 ResolutionError::ParamInNonTrivialAnonConst {
1567 is_gca: self.tcx.features().generic_const_args(),
1616 is_gca: self.features.generic_const_args(),
15681617 name: rib_ident.name,
15691618 param_kind: ParamKindInNonTrivialAnonConst::Type,
15701619 }
......@@ -1629,7 +1678,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
16291678 | RibKind::ForwardGenericParamBan(_) => continue,
16301679
16311680 RibKind::ConstParamTy => {
1632 if !self.tcx.features().generic_const_parameter_types() {
1681 if !self.features.generic_const_parameter_types() {
16331682 if let Some(span) = finalize {
16341683 self.report_error(
16351684 span,
......@@ -1656,7 +1705,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
16561705 }
16571706 NoConstantGenericsReason::NonTrivialConstArg => {
16581707 ResolutionError::ParamInNonTrivialAnonConst {
1659 is_gca: self.tcx.features().generic_const_args(),
1708 is_gca: self.features.generic_const_args(),
16601709 name: rib_ident.name,
16611710 param_kind: ParamKindInNonTrivialAnonConst::Const {
16621711 name: rib_ident.name,
......@@ -2019,7 +2068,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20192068 module,
20202069 || {
20212070 let import_inherent_item_error_flag =
2022 self.tcx.features().import_trait_associated_functions()
2071 self.features.import_trait_associated_functions()
20232072 && matches!(
20242073 res,
20252074 Res::Def(
compiler/rustc_resolve/src/imports.rs+3-4
......@@ -779,7 +779,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
779779 match import_decls[ns] {
780780 PendingDecl::Ready(Some(import_decl)) => {
781781 if import_decl.is_assoc_item()
782 && !this.tcx.features().import_trait_associated_functions()
782 && !this.features.import_trait_associated_functions()
783783 {
784784 feature_err(
785785 this.tcx.sess,
......@@ -822,8 +822,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
822822 continue;
823823 };
824824
825 if module.is_trait() && !self.tcx.features().import_trait_associated_functions()
826 {
825 if module.is_trait() && !self.features.import_trait_associated_functions() {
827826 feature_err(
828827 self.tcx.sess,
829828 sym::import_trait_associated_functions,
......@@ -1487,7 +1486,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14871486
14881487 // If importing of trait asscoiated items is enabled, an also find an
14891488 // `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()
14911490 && let PathResult::Module(ModuleOrUniformRoot::Module(m)) = path_res
14921491 && let Some(Res::Def(DefKind::Enum, _)) = m.res()
14931492 {
compiler/rustc_resolve/src/late.rs+11-12
......@@ -1664,7 +1664,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
16641664 };
16651665 // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better
16661666 // 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() {
16681668 forward_ty_ban_rib_const_param_ty.bindings.clear();
16691669 forward_const_ban_rib_const_param_ty.bindings.clear();
16701670 }
......@@ -1701,7 +1701,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
17011701
17021702 this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty);
17031703 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() {
17051705 this.visit_ty(ty)
17061706 } else {
17071707 this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
......@@ -1812,8 +1812,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18121812 }
18131813
18141814 LifetimeRibKind::ImplTrait => {
1815 if self.r.tcx.features().anonymous_lifetime_in_impl_trait()
1816 {
1815 if self.r.features.anonymous_lifetime_in_impl_trait() {
18171816 None
18181817 } else {
18191818 Some(LifetimeUseSet::Many)
......@@ -2991,7 +2990,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
29912990 self.with_generic_param_rib(
29922991 &generics.params,
29932992 RibKind::Item(
2994 if self.r.tcx.features().generic_const_items() {
2993 if self.r.features.generic_const_items() {
29952994 HasGenericParams::Yes(generics.span)
29962995 } else {
29972996 HasGenericParams::No
......@@ -3008,7 +3007,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
30083007 LifetimeRibKind::Elided(LifetimeRes::Static),
30093008 |this| {
30103009 if rhs_kind.is_type_const()
3011 && !this.r.tcx.features().generic_const_parameter_types()
3010 && !this.r.features.generic_const_parameter_types()
30123011 {
30133012 this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
30143013 this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
......@@ -3255,7 +3254,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
32553254 RibKind::Normal => {
32563255 // FIXME(non_lifetime_binders): Stop special-casing
32573256 // const params to error out here.
3258 if self.r.tcx.features().non_lifetime_binders()
3257 if self.r.features.non_lifetime_binders()
32593258 && matches!(param.kind, GenericParamKind::Type { .. })
32603259 {
32613260 Res::Def(def_kind, def_id.to_def_id())
......@@ -3409,7 +3408,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
34093408 |this| {
34103409 this.visit_generics(generics);
34113410 if rhs_kind.is_type_const()
3412 && !this.r.tcx.features().generic_const_parameter_types()
3411 && !this.r.features.generic_const_parameter_types()
34133412 {
34143413 this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
34153414 this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
......@@ -5038,10 +5037,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
50385037 let tcx = self.r.tcx();
50395038
50405039 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() => {
50425041 Some((sym::f16, "the type `f16` is unstable"))
50435042 }
5044 PrimTy::Float(FloatTy::F128) if !tcx.features().f128() => {
5043 PrimTy::Float(FloatTy::F128) if !self.r.features.f128() => {
50455044 Some((sym::f128, "the type `f128` is unstable"))
50465045 }
50475046 _ => None,
......@@ -5196,8 +5195,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
51965195 AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes,
51975196 AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
51985197 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()
52015200 || is_trivial_const_arg
52025201 {
52035202 ConstantHasGenerics::Yes
compiler/rustc_resolve/src/late/diagnostics.rs+4-5
......@@ -1775,8 +1775,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
17751775 // const generics. Of course, `Struct` and `Enum` may contain ty params, too, but the
17761776 // benefits of including them here outweighs the small number of false positives.
17771777 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() =>
17801779 {
17811780 Applicability::MaybeIncorrect
17821781 }
......@@ -3977,7 +3976,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
39773976 })
39783977 .emit(),
39793978 NoConstantGenericsReason::NonTrivialConstArg => {
3980 assert!(!self.r.tcx.features().generic_const_exprs());
3979 assert!(!self.r.features.generic_const_exprs());
39813980 self.r
39823981 .dcx()
39833982 .create_err(diagnostics::ParamInNonTrivialAnonConst {
......@@ -3985,8 +3984,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
39853984 name: lifetime_ref.ident.name,
39863985 param_kind: diagnostics::ParamKindInNonTrivialAnonConst::Lifetime,
39873986 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(),
39903989 })
39913990 .emit()
39923991 }
compiler/rustc_resolve/src/lib.rs+8-8
......@@ -50,7 +50,7 @@ use rustc_data_structures::sync::{FreezeReadGuard, FreezeWriteGuard};
5050use rustc_data_structures::unord::{UnordItems, UnordMap, UnordSet};
5151use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed, LintBuffer};
5252use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind};
53use rustc_feature::BUILTIN_ATTRIBUTES;
53use rustc_feature::{BUILTIN_ATTRIBUTES, Features};
5454use rustc_hir::attrs::StrippedCfgItem;
5555use rustc_hir::def::Namespace::{self, *};
5656use rustc_hir::def::{
......@@ -1550,7 +1550,8 @@ pub struct Resolver<'ra, 'tcx> {
15501550 impl_trait_names: FxHashMap<NodeId, Symbol> = default::fx_hash_map(),
15511551
15521552 /// 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,
15541555}
15551556
15561557/// This provides memory for the rest of the crate. The `'ra` lifetime that is
......@@ -1808,11 +1809,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18081809 let registered_tools = tcx.registered_tools(());
18091810 let edition = tcx.sess.edition();
18101811
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
18161812 let mut resolver = Resolver {
18171813 tcx,
18181814
......@@ -1880,10 +1876,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18801876 current_crate_outer_attr_insert_span,
18811877 disambiguators: Default::default(),
18821878 delegation_infos: Default::default(),
1883 on_unknown_data,
1879 features: tcx.features(),
18841880 ..
18851881 };
18861882
1883 if let Some(directive) = OnUnknownData::from_attrs(&resolver, attrs) {
1884 resolver.on_unknown_data.insert(CRATE_DEF_ID, directive);
1885 }
1886
18871887 let root_parent_scope = ParentScope::module(graph_root, resolver.arenas);
18881888 resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope);
18891889 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> {
699699 }
700700
701701 // 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() {
703703 let is_macro = match res {
704704 Res::Def(..) => true,
705705 Res::NonMacroAttr(..) => false,
......@@ -727,8 +727,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
727727 && let [namespace, attribute, ..] = &*path.segments
728728 && namespace.ident.name == sym::diagnostic
729729 && !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))
732731 })
733732 {
734733 let name = attribute.ident.name;
......@@ -750,7 +749,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
750749 let candidates = DIAGNOSTIC_ATTRIBUTES
751750 .iter()
752751 .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)
754753 })
755754 .collect::<Vec<_>>();
756755
......@@ -1112,7 +1111,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11121111 let feature = stability.feature;
11131112
11141113 let is_allowed =
1115 |feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature);
1114 |feature| self.features.enabled(feature) || span.allows_unstable(feature);
11161115 let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
11171116 if !is_allowed(feature) && !allowed_by_implication {
11181117 stability::report_unstable(
......@@ -1242,7 +1241,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12421241 ) -> SyntaxExtension {
12431242 let mut ext = compile_declarative_macro(
12441243 self.tcx.sess,
1245 self.tcx.features(),
1244 self.features,
12461245 macro_def,
12471246 ident,
12481247 attrs,
compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs+3-3
......@@ -310,7 +310,7 @@ pub(crate) fn transform_instance<'tcx>(
310310 // FIXME: account for async-drop-glue
311311 if (matches!(instance.def, ty::InstanceKind::Virtual(..))
312312 && 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(..)))
314314 {
315315 // Adjust the type ids of DropGlues
316316 //
......@@ -364,7 +364,7 @@ pub(crate) fn transform_instance<'tcx>(
364364 tcx.types.unit
365365 };
366366 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
368368 && let Some(trait_id) = tcx.trait_of_assoc(def_id)
369369 {
370370 // 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>(
461461
462462fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option<DefId> {
463463 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, _)) => {
465465 tcx.opt_associated_item(def_id).map(|item| item.def_id)
466466 }
467467 _ => None,
compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs+2-2
......@@ -6,7 +6,7 @@
66
77use std::hash::Hasher;
88
9use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, Ty, TyCtxt};
9use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, ShimKind, Ty, TyCtxt};
1010use rustc_target::callconv::FnAbi;
1111use twox_hash::XxHash64;
1212
......@@ -46,7 +46,7 @@ pub fn typeid_for_instance<'tcx>(
4646 //
4747 // This was implemented for KCFI support in #123106 and #123052 (which introduced the
4848 // 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)))) {
5050 options.insert(TypeIdOptions::USE_CONCRETE_SELF);
5151 }
5252 // 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>(
6262 let mut p = LegacySymbolMangler { tcx, path: SymbolPath::new(), keep_within_component: false };
6363 p.print_def_path(
6464 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
6868 {
6969 // Add the name of the dropped type to the symbol name
7070 &*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 {
7272 let ty::Coroutine(_, cor_args) = ty.kind() else {
7373 bug!();
7474 };
......@@ -81,13 +81,13 @@ pub(super) fn mangle<'tcx>(
8181 .unwrap();
8282
8383 match instance.def {
84 ty::InstanceKind::ThreadLocalShim(..) => {
84 ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => {
8585 p.write_str("{{tls-shim}}").unwrap();
8686 }
87 ty::InstanceKind::VTableShim(..) => {
87 ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) => {
8888 p.write_str("{{vtable-shim}}").unwrap();
8989 }
90 ty::InstanceKind::ReifyShim(_, reason) => {
90 ty::InstanceKind::Shim(ty::ShimKind::Reify(_, reason)) => {
9191 p.write_str("{{reify-shim").unwrap();
9292 match reason {
9393 Some(ReifyReason::FnPtr) => p.write_str("-fnptr").unwrap(),
......@@ -98,14 +98,17 @@ pub(super) fn mangle<'tcx>(
9898 }
9999 // FIXME(async_closures): This shouldn't be needed when we fix
100100 // `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 }) => {
102105 p.write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" })
103106 .unwrap();
104107 }
105108 _ => {}
106109 }
107110
108 if let ty::InstanceKind::FutureDropPollShim(..) = instance.def {
111 if let ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) = instance.def {
109112 let _ = p.write_str("{{drop-shim}}");
110113 }
111114
compiler/rustc_symbol_mangling/src/v0.rs+19-13
......@@ -49,25 +49,31 @@ pub(super) fn mangle<'tcx>(
4949
5050 // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance.
5151 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 }
5761
5862 // FIXME(async_closures): This shouldn't be needed when we fix
5963 // `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"),
6773 _ => None,
6874 };
6975
70 if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def {
76 if let ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) = instance.def {
7177 let ty::Coroutine(_, cor_args) = ty.kind() else {
7278 bug!();
7379 };
compiler/rustc_target/src/callconv/mod.rs+3
......@@ -827,6 +827,9 @@ impl<'a, Ty> FnAbi<'a, Ty> {
827827 ArgAttribute::default()
828828 };
829829 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);
830833 }
831834 }
832835
compiler/rustc_ty_utils/src/abi.rs+25-21
......@@ -10,7 +10,7 @@ use rustc_middle::query::Providers;
1010use rustc_middle::ty::layout::{
1111 FnAbiError, HasTyCtxt, HasTypingEnv, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind,
1212};
13use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, Unnormalized};
13use rustc_middle::ty::{self, InstanceKind, ShimKind, Ty, TyCtxt, Unnormalized};
1414use rustc_span::DUMMY_SP;
1515use rustc_span::def_id::DefId;
1616use rustc_target::callconv::{
......@@ -38,7 +38,7 @@ fn fn_sig_for_fn_abi<'tcx>(
3838 instance: ty::Instance<'tcx>,
3939 typing_env: ty::TypingEnv<'tcx>,
4040) -> ty::FnSig<'tcx> {
41 if let InstanceKind::ThreadLocalShim(..) = instance.def {
41 if let InstanceKind::Shim(ShimKind::ThreadLocal(..)) = instance.def {
4242 return tcx.mk_fn_sig_safe_rust_abi([], tcx.thread_local_ptr_ty(instance.def_id()));
4343 }
4444
......@@ -50,7 +50,7 @@ fn fn_sig_for_fn_abi<'tcx>(
5050 );
5151
5252 // 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 {
5454 let mut inputs_and_output = sig.inputs_and_output.to_vec();
5555 inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]);
5656 sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
......@@ -82,22 +82,23 @@ fn fn_sig_for_fn_abi<'tcx>(
8282 // a separate def-id for these bodies.
8383 let mut coroutine_kind = args.as_coroutine_closure().kind();
8484
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)
9896 } 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 };
101102
102103 let sig = tcx.instantiate_bound_regions_with_erased(sig);
103104
......@@ -264,7 +265,8 @@ impl<'tcx> FnAbiDesc<'tcx> {
264265 ) -> Self {
265266 let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query;
266267 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(_)));
268270 Self {
269271 layout_cx: LayoutCx::new(tcx, typing_env),
270272 sig: tcx.normalize_erasing_regions(
......@@ -458,8 +460,10 @@ fn fn_abi_sanity_check<'tcx>(
458460 // omitted entirely in the calling convention.
459461 assert!(arg.is_ignore());
460462 }
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");
463467 }
464468 } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
465469 assert_matches!(
compiler/rustc_ty_utils/src/instance.rs+35-21
......@@ -38,16 +38,16 @@ fn resolve_instance_raw<'tcx>(
3838 } else if tcx.is_lang_item(def_id, LangItem::DropGlue) {
3939 let ty = args.type_at(0);
4040
41 if ty.needs_drop(tcx, typing_env) {
41 let shim = if ty.needs_drop(tcx, typing_env) {
4242 debug!(" => nontrivial drop glue");
4343 match *ty.kind() {
4444 ty::Coroutine(coroutine_def_id, ..) => {
4545 // FIXME: sync drop of coroutine with async drop (generate both versions?)
4646 // Currently just ignored
4747 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)
4949 } else {
50 ty::InstanceKind::DropGlue(def_id, Some(ty))
50 ty::ShimKind::DropGlue(def_id, Some(ty))
5151 }
5252 }
5353 ty::Closure(..)
......@@ -57,14 +57,15 @@ fn resolve_instance_raw<'tcx>(
5757 | ty::Dynamic(..)
5858 | ty::Array(..)
5959 | ty::Slice(..)
60 | ty::UnsafeBinder(..) => ty::InstanceKind::DropGlue(def_id, Some(ty)),
60 | ty::UnsafeBinder(..) => ty::ShimKind::DropGlue(def_id, Some(ty)),
6161 // Drop shims can only be built from ADTs.
6262 _ => return Ok(None),
6363 }
6464 } else {
6565 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)
6869 } else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) {
6970 let ty = args.type_at(0);
7071
......@@ -82,14 +83,14 @@ fn resolve_instance_raw<'tcx>(
8283 _ => return Ok(None),
8384 }
8485 debug!(" => nontrivial async drop glue ctor");
85 ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty)
86 ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(def_id, ty))
8687 } else {
8788 debug!(" => trivial async drop glue ctor");
88 ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty)
89 ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(def_id, ty))
8990 }
9091 } else if tcx.is_async_drop_in_place_coroutine(def_id) {
9192 let ty = args.type_at(0);
92 ty::InstanceKind::AsyncDropGlue(def_id, ty)
93 ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(def_id, ty))
9394 } else {
9495 debug!(" => free item");
9596 ty::InstanceKind::Item(def_id)
......@@ -279,7 +280,7 @@ fn resolve_associated_item<'tcx>(
279280 };
280281
281282 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)),
283284 args: rcvr_args,
284285 })
285286 } else {
......@@ -296,7 +297,10 @@ fn resolve_associated_item<'tcx>(
296297 return Ok(None);
297298 }
298299 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 )),
300304 args: rcvr_args,
301305 })
302306 } else {
......@@ -326,7 +330,10 @@ fn resolve_associated_item<'tcx>(
326330 Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind))
327331 }
328332 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 )),
330337 args: rcvr_args,
331338 }),
332339 ty::CoroutineClosure(coroutine_closure_def_id, args) => {
......@@ -339,10 +346,12 @@ fn resolve_associated_item<'tcx>(
339346 Some(Instance::new_raw(coroutine_closure_def_id, args))
340347 } else {
341348 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 ),
346355 args,
347356 })
348357 }
......@@ -362,10 +371,12 @@ fn resolve_associated_item<'tcx>(
362371 // If we're computing `AsyncFnOnce` for a by-ref closure then
363372 // construct a new body that has the right return types.
364373 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 ),
369380 args,
370381 })
371382 } else {
......@@ -376,7 +387,10 @@ fn resolve_associated_item<'tcx>(
376387 Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind))
377388 }
378389 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 )),
380394 args: rcvr_args,
381395 }),
382396 _ => bug!(
compiler/rustc_type_ir/src/generic_arg.rs-13
......@@ -18,16 +18,3 @@ pub enum GenericArgKind<I: Interner> {
1818}
1919
2020impl<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)]
28pub enum TermKind<I: Interner> {
29 Ty(I::Ty),
30 Const(I::Const),
31}
32
33impl<I: Interner> Eq for TermKind<I> {}
compiler/rustc_type_ir/src/lib.rs+2
......@@ -52,6 +52,7 @@ mod pattern;
5252mod predicate;
5353mod predicate_kind;
5454mod region_kind;
55mod term_kind;
5556mod ty;
5657mod ty_info;
5758mod ty_kind;
......@@ -81,6 +82,7 @@ pub use predicate_kind::*;
8182pub use region_kind::*;
8283pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
8384use rustc_type_ir_macros::GenericTypeVisitable;
85pub use term_kind::*;
8486pub use ty::{Alias, *};
8587pub use ty_info::*;
8688pub use ty_kind::*;
compiler/rustc_type_ir/src/predicate.rs+4-353
......@@ -9,10 +9,9 @@ use rustc_type_ir_macros::{
99};
1010
1111use crate::inherent::*;
12use crate::ty::AliasTerm;
1312use crate::upcast::{Upcast, UpcastFrom};
1413use crate::visit::TypeVisitableExt as _;
15use crate::{self as ty, Alias, AliasTyKind, Interner, UnevaluatedConstKind};
14use crate::{self as ty, Alias, Interner};
1615
1716/// `A: 'region`
1817#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)]
......@@ -505,7 +504,7 @@ impl<I: Interner> ExistentialProjection<I> {
505504 debug_assert!(!self_ty.has_escaping_bound_vars());
506505
507506 ProjectionPredicate {
508 projection_term: AliasTerm::new(
507 projection_term: ty::AliasTerm::new(
509508 interner,
510509 interner.alias_term_kind_from_def_id(self.def_id.into()),
511510 [self_ty.into()].iter().chain(self.args.iter()),
......@@ -537,354 +536,6 @@ impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> {
537536 }
538537}
539538
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)]
546pub 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
589impl<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
630impl<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
641impl<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
656impl<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>
778impl<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>
832impl<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>
866impl<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
876impl<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
882impl<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
888539/// This kind of predicate has no *direct* correspondent in the
889540/// syntax, but it roughly corresponds to the syntactic forms:
890541///
......@@ -904,7 +555,7 @@ impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
904555 derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext)
905556)]
906557pub struct ProjectionPredicate<I: Interner> {
907 pub projection_term: AliasTerm<I>,
558 pub projection_term: ty::AliasTerm<I>,
908559 pub term: I::Term,
909560}
910561
......@@ -966,7 +617,7 @@ impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
966617 feature = "nightly",
967618 derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext)
968619)]
969pub struct NormalizesTo<I: Interner, K = AliasTermKind<I>> {
620pub struct NormalizesTo<I: Interner, K = ty::AliasTermKind<I>> {
970621 pub alias: Alias<I, K>,
971622 pub term: I::Term,
972623}
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<
840840 escaping_outlives,
841841 I::BoundVarKinds::from_vars(infcx.cx(), bound_vars),
842842 );
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 }
844852 }
845853
846854 let assumptions = match assumptions {
......@@ -885,12 +893,17 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling<
885893
886894 // while we did skip the binder, bound vars aren't in any universe so
887895 // 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 }
894907 }
895908
896909 // I'm not convinced our handling here is *complete* so for now
......@@ -978,11 +991,14 @@ pub fn regions_outlived_by_placeholder<I: Interner>(
978991}
979992
980993/// The largest universe a variable or placeholder was from in `t`
981pub fn max_universe<Infcx: InferCtxtLike<Interner = I>, I: Interner, T: TypeVisitable<I>>(
994pub fn max_universe<Infcx: InferCtxtLike<Interner = I>, I: Interner, T: TypeFoldable<I>>(
982995 infcx: &Infcx,
983996 t: T,
984997) -> UniverseIndex {
985998 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);
9861002 t.visit_with(&mut visitor);
9871003 visitor.max_universe()
9881004}
......@@ -1036,11 +1052,17 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeVisitor<I>
10361052 fn visit_region(&mut self, r: I::Region) {
10371053 match r.kind() {
10381054 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 },
10441066 _ => (),
10451067 }
10461068 }
compiler/rustc_type_ir/src/term_kind.rs created+372
......@@ -0,0 +1,372 @@
1use derive_where::derive_where;
2#[cfg(feature = "nightly")]
3use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
4use rustc_type_ir_macros::{
5 GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
6};
7
8use crate::inherent::*;
9use 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)]
17pub enum TermKind<I: Interner> {
18 Ty(I::Ty),
19 Const(I::Const),
20}
21
22impl<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)]
30pub 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
73impl<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
114impl<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
125impl<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
140impl<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>
264impl<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>
318impl<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>
352impl<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
362impl<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
368impl<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::{
55 GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
66};
77
8use crate::predicate::AliasTermKind;
9use crate::ty_kind::AliasTyKind;
10use crate::{Interner, UnevaluatedConstKind};
8use crate::{AliasTermKind, AliasTyKind, Interner, UnevaluatedConstKind};
119
1210/// Represents an alias of a type, constant, or other term-like item.
1311///
library/Cargo.lock+2-2
......@@ -283,9 +283,9 @@ dependencies = [
283283
284284[[package]]
285285name = "rustc-literal-escaper"
286version = "0.0.7"
286version = "0.0.8"
287287source = "registry+https://github.com/rust-lang/crates.io-index"
288checksum = "8be87abb9e40db7466e0681dc8ecd9dcfd40360cb10b4c8fe24a7c4c3669b198"
288checksum = "bfe6f213fb658c8fb95baabd5420393438cf5a98d707f5dd701d9197c705f71e"
289289dependencies = [
290290 "rustc-std-workspace-core",
291291]
library/alloc/src/string.rs+19-1
......@@ -2239,15 +2239,33 @@ impl FromUtf8Error {
22392239 /// invalid sequences, and [`String::from_utf8_lossy_owned`] for the
22402240 /// `String` function which corresponds to this function.
22412241 ///
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 ///
22422252 /// # Examples
22432253 ///
22442254 /// ```
22452255 /// #![feature(string_from_utf8_lossy_owned)]
22462256 /// // some invalid bytes
22472257 /// 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 /// };
22492266 ///
22502267 /// assert_eq!(String::from("Hello �World"), output);
2268 /// assert!(had_invalid_utf8);
22512269 /// ```
22522270 #[must_use]
22532271 #[cfg(not(no_global_oom_handling))]
library/core/src/char/methods.rs+27-24
......@@ -495,7 +495,7 @@ impl char {
495495 || args.escape_grapheme_extender && self.is_grapheme_extender()
496496 || self.is_default_ignorable()
497497 || self.is_format_control()
498 || self.is_unassigned() =>
498 || !self.is_assigned() =>
499499 {
500500 EscapeDebug::unicode(self)
501501 }
......@@ -1139,8 +1139,9 @@ impl char {
11391139 /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
11401140 ///
11411141 #[must_use]
1142 #[unstable(feature = "char_unassigned_private_use", issue = "158322")]
11421143 #[inline]
1143 const fn is_private_use(self) -> bool {
1144 pub const fn is_private_use(self) -> bool {
11441145 // According to
11451146 // https://www.unicode.org/policies/stability_policy.html#Property_Value,
11461147 // the set of codepoints in `Co` will never change.
......@@ -1176,54 +1177,56 @@ impl char {
11761177 self > '\u{AC}' && unicode::Cf(self)
11771178 }
11781179
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
11801181 /// [`UNICODE_VERSION`].
11811182 ///
11821183 /// [`UNICODE_VERSION`]: Self::UNICODE_VERSION
11831184 ///
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 ///
11891185 /// Many of Unicode's [stability policies] apply only to assigned characters.
11901186 ///
11911187 /// [stability policies]: https://www.unicode.org/policies/stability_policy.html
11921188 ///
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.
11961198 ///
1197 /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
1198 /// [specified]: https://www.unicode.org/reports/tr44/#GC_Values_Table
11991199 /// [`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
12001201 ///
12011202 /// # Examples
12021203 ///
12031204 /// Basic usage:
12041205 ///
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
12101210 ///
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()); */
12121214 /// ```
12131215 #[must_use]
1216 #[unstable(feature = "char_unassigned_private_use", issue = "158322")]
12141217 #[inline]
1215 fn is_unassigned(self) -> bool {
1218 pub fn is_assigned(self) -> bool {
12161219 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),
12191222 // Assigned character ranges in planes 4 and above.
12201223 // `src/tools/unicode-table-generator/src/main.rs` asserts that this is correct
12211224 '\u{E0001}'
12221225 | '\u{E0020}'..='\u{E007F}'
12231226 | '\u{E0100}'..='\u{E01EF}'
12241227 | '\u{F0000}'..='\u{FFFFD}'
1225 | '\u{100000}'..='\u{10FFFD}' => false,
1226 _ => true,
1228 | '\u{100000}'..='\u{10FFFD}' => true,
1229 _ => false,
12271230 }
12281231 }
12291232
library/core/src/io/error.rs+7
......@@ -238,6 +238,11 @@ pub enum ErrorKind {
238238 #[unstable(feature = "io_error_inprogress", issue = "130840")]
239239 InProgress,
240240
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
241246 // "Unusual" error kinds which do not correspond simply to (sets
242247 // of) OS error codes, should be added just above this comment.
243248 // `Other` and `Uncategorized` should remain at the end:
......@@ -309,6 +314,7 @@ impl ErrorKind {
309314 StorageFull => "no storage space",
310315 TimedOut => "timed out",
311316 TooManyLinks => "too many links",
317 TooManyOpenFiles => "too many open files",
312318 Uncategorized => "uncategorized error",
313319 UnexpectedEof => "unexpected end of file",
314320 Unsupported => "unsupported",
......@@ -379,6 +385,7 @@ impl ErrorKind {
379385 Unsupported,
380386 OutOfMemory,
381387 InProgress,
388 TooManyOpenFiles,
382389 Uncategorized,
383390 })
384391 }
library/core/src/macros/mod.rs+8-8
......@@ -40,7 +40,7 @@ macro_rules! panic {
4040#[rustc_diagnostic_item = "assert_eq_macro"]
4141#[allow_internal_unstable(panic_internals)]
4242macro_rules! assert_eq {
43 ($left:expr, $right:expr $(,)?) => {
43 ($left:expr, $right:expr $(,)?) => {{
4444 match (&$left, &$right) {
4545 (left_val, right_val) => {
4646 if !(*left_val == *right_val) {
......@@ -52,8 +52,8 @@ macro_rules! assert_eq {
5252 }
5353 }
5454 }
55 };
56 ($left:expr, $right:expr, $($arg:tt)+) => {
55 }};
56 ($left:expr, $right:expr, $($arg:tt)+) => {{
5757 match (&$left, &$right) {
5858 (left_val, right_val) => {
5959 if !(*left_val == *right_val) {
......@@ -65,7 +65,7 @@ macro_rules! assert_eq {
6565 }
6666 }
6767 }
68 };
68 }};
6969}
7070
7171/// Asserts that two expressions are not equal to each other (using [`PartialEq`]).
......@@ -96,7 +96,7 @@ macro_rules! assert_eq {
9696#[rustc_diagnostic_item = "assert_ne_macro"]
9797#[allow_internal_unstable(panic_internals)]
9898macro_rules! assert_ne {
99 ($left:expr, $right:expr $(,)?) => {
99 ($left:expr, $right:expr $(,)?) => {{
100100 match (&$left, &$right) {
101101 (left_val, right_val) => {
102102 if *left_val == *right_val {
......@@ -108,8 +108,8 @@ macro_rules! assert_ne {
108108 }
109109 }
110110 }
111 };
112 ($left:expr, $right:expr, $($arg:tt)+) => {
111 }};
112 ($left:expr, $right:expr, $($arg:tt)+) => {{
113113 match (&($left), &($right)) {
114114 (left_val, right_val) => {
115115 if *left_val == *right_val {
......@@ -121,7 +121,7 @@ macro_rules! assert_ne {
121121 }
122122 }
123123 }
124 };
124 }};
125125}
126126
127127/// Asserts that an expression matches the provided pattern.
library/core/src/net/parser.rs+44-53
......@@ -63,11 +63,6 @@ impl<'a> Parser<'a> {
6363 if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(kind))
6464 }
6565
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
7166 /// Reads the next character from the input
7267 fn read_char(&mut self) -> Option<char> {
7368 self.state.split_first().map(|(&b, tail)| {
......@@ -100,60 +95,56 @@ impl<'a> Parser<'a> {
10095 })
10196 }
10297
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>>(
110105 &mut self,
111106 radix: u32,
112 max_digits: Option<usize>,
107 max_digits: u32,
113108 allow_zero_prefix: bool,
114109 ) -> 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;
140116
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;
145120 }
121 result *= radix;
122 result += digit;
123 digit_count += 1;
124 }
146125
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 {
153127 None
154128 } 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)?;
156145 }
146
147 Some(result)
157148 })
158149 }
159150
......@@ -166,7 +157,7 @@ impl<'a> Parser<'a> {
166157 *slot = p.read_separator('.', i, |p| {
167158 // Disallow octal number in IP string.
168159 // 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)
170161 })?;
171162 }
172163
......@@ -198,7 +189,7 @@ impl<'a> Parser<'a> {
198189 }
199190 }
200191
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));
202193
203194 match group {
204195 Some(g) => *slot = g,
......@@ -250,7 +241,7 @@ impl<'a> Parser<'a> {
250241 fn read_port(&mut self) -> Option<u16> {
251242 self.read_atomically(|p| {
252243 p.read_given_char(':')?;
253 p.read_number(10, None, true)
244 p.read_decimal()
254245 })
255246 }
256247
......@@ -258,7 +249,7 @@ impl<'a> Parser<'a> {
258249 fn read_scope_id(&mut self) -> Option<u32> {
259250 self.read_atomically(|p| {
260251 p.read_given_char('%')?;
261 p.read_number(10, None, true)
252 p.read_decimal()
262253 })
263254 }
264255
library/core/src/num/int_macros.rs+1-1
......@@ -1181,7 +1181,7 @@ macro_rules! int_impl {
11811181 (
11821182 lhs: $SelfT = self,
11831183 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),
11851185 );
11861186 // SAFETY: Same precondition
11871187 unsafe { intrinsics::exact_div(self, rhs) }
library/core/src/slice/mod.rs+2
......@@ -2530,6 +2530,7 @@ impl<T> [T] {
25302530 F: FnMut(&T) -> bool,
25312531 {
25322532 let index = self.iter().position(pred)?;
2533 // Slice bounds checks optimized are away (as of June 2026)
25332534 Some((&self[..index], &self[index + 1..]))
25342535 }
25352536
......@@ -2558,6 +2559,7 @@ impl<T> [T] {
25582559 F: FnMut(&T) -> bool,
25592560 {
25602561 let index = self.iter().rposition(pred)?;
2562 // Slice bounds checks optimized are away (as of June 2026)
25612563 Some((&self[..index], &self[index + 1..]))
25622564 }
25632565
library/coretests/benches/net/addr_parser.rs+155-21
......@@ -3,76 +3,210 @@ use core::str::FromStr;
33
44use test::{Bencher, black_box};
55
6const IPV4_STR: &str = "192.168.0.1";
7const IPV4_STR_PORT: &str = "192.168.0.1:8080";
8
9const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1";
10const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1";
11const IPV6_STR_V4: &str = "2001:db8::192.168.0.1";
12const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080";
13const IPV6_STR_PORT_SCOPE_ID: &str = "[2001:db8::c0a8:1%1337]:8080";
6const 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
19const 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
32const 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
45const 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
58const 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
71const 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
84const 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];
1496
1597#[bench]
1698fn 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 });
18104}
19105
20106#[bench]
21107fn 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 });
23113}
24114
25115#[bench]
26116fn 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 });
28122}
29123
30124#[bench]
31125fn 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 });
33131}
34132
35133#[bench]
36134fn 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 });
38140}
39141
40142#[bench]
41143fn 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 });
43149}
44150
45151#[bench]
46152fn 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 });
48158}
49159
50160#[bench]
51161fn 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 });
53167}
54168
55169#[bench]
56170fn 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 });
58176}
59177
60178#[bench]
61179fn 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 });
63185}
64186
65187#[bench]
66188fn 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 });
68194}
69195
70196#[bench]
71197fn 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 });
73203}
74204
75205#[bench]
76206fn 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 });
78212}
library/coretests/tests/macros.rs+13-1
......@@ -241,7 +241,19 @@ fn temporary_scope_introduction() {
241241
242242 (assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val));
243243 (assert_matches!(*MutRefWithDrop(&mut val).0, 0, "msg"), std::mem::take(&mut val));
244
245244 (debug_assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val));
246245 (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));
247259}
library/proc_macro/Cargo.toml+1-1
......@@ -9,7 +9,7 @@ std = { path = "../std" }
99# `core` when resolving doc links. Without this line a different `core` will be
1010# loaded from sysroot causing duplicate lang items and other similar errors.
1111core = { path = "../core" }
12rustc-literal-escaper = { version = "0.0.7", features = ["rustc-dep-of-std"] }
12rustc-literal-escaper = { version = "0.0.8", features = ["rustc-dep-of-std"] }
1313
1414[features]
1515default = ["rustc-dep-of-std"]
library/proc_macro/src/bridge/buffer.rs+2-30
......@@ -1,8 +1,7 @@
11//! Buffer management for same-process client<->server communication.
22
3use std::io::{self, Write};
43use std::mem::{self, ManuallyDrop};
5use std::ops::{Deref, DerefMut};
4use std::ops::Deref;
65use std::slice;
76
87#[repr(C)]
......@@ -32,13 +31,6 @@ impl Deref for Buffer {
3231 }
3332}
3433
35impl 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
4234impl Buffer {
4335 #[inline]
4436 pub(super) fn new() -> Self {
......@@ -99,25 +91,6 @@ impl Buffer {
9991 }
10092}
10193
102impl 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
12194impl Drop for Buffer {
12295 #[inline]
12396 fn drop(&mut self) {
......@@ -128,8 +101,7 @@ impl Drop for Buffer {
128101
129102impl From<Vec<u8>> for Buffer {
130103 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();
133105
134106 // This utility function is nested in here because it can *only*
135107 // 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 {
282282 pub const fn expand1(f: impl Fn(crate::TokenStream) -> crate::TokenStream + Copy) -> Self {
283283 Client {
284284 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)
286286 }),
287287 }
288288 }
library/proc_macro/src/bridge/rpc.rs+1-2
......@@ -1,6 +1,5 @@
11//! Serialization for client-server communication.
22
3use std::io::Write;
43use std::num::NonZero;
54
65use super::buffer::Buffer;
......@@ -209,7 +208,7 @@ impl<S> Encode<S> for &str {
209208 fn encode(self, w: &mut Buffer, s: &mut S) {
210209 let bytes = self.as_bytes();
211210 bytes.len().encode(w, s);
212 w.write_all(bytes).unwrap();
211 w.extend_from_slice(bytes);
213212 }
214213}
215214
library/proc_macro/src/lib.rs+11-13
......@@ -37,7 +37,7 @@
3737#![warn(unreachable_pub)]
3838#![deny(unsafe_op_in_unsafe_fn)]
3939
40#[unstable(feature = "proc_macro_internals", issue = "27812")]
40#[unstable(feature = "proc_macro_internals", issue = "none")]
4141#[doc(hidden)]
4242pub mod bridge;
4343
......@@ -296,7 +296,7 @@ impl TokenStream {
296296 /// Checks if this `TokenStream` is empty.
297297 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
298298 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)
300300 }
301301
302302 /// Parses this `TokenStream` as an expression and attempts to expand any
......@@ -575,9 +575,7 @@ pub mod token_stream {
575575 type IntoIter = IntoIter;
576576
577577 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())
581579 }
582580 }
583581}
......@@ -595,7 +593,7 @@ pub macro quote($($t:tt)*) {
595593 /* compiler built-in */
596594}
597595
598#[unstable(feature = "proc_macro_internals", issue = "27812")]
596#[unstable(feature = "proc_macro_internals", issue = "none")]
599597#[doc(hidden)]
600598mod quote;
601599
......@@ -755,14 +753,14 @@ impl Span {
755753
756754 // Used by the implementation of `Span::quote`
757755 #[doc(hidden)]
758 #[unstable(feature = "proc_macro_internals", issue = "27812")]
756 #[unstable(feature = "proc_macro_internals", issue = "none")]
759757 pub fn save_span(&self) -> usize {
760758 BridgeMethods::span_save_span(self.0)
761759 }
762760
763761 // Used by the implementation of `Span::quote`
764762 #[doc(hidden)]
765 #[unstable(feature = "proc_macro_internals", issue = "27812")]
763 #[unstable(feature = "proc_macro_internals", issue = "none")]
766764 pub fn recover_proc_macro_span(id: usize) -> Span {
767765 Span(BridgeMethods::span_recover_proc_macro_span(id))
768766 }
......@@ -1296,7 +1294,7 @@ macro_rules! unsuffixed_int_literals {
12961294 /// specified on this token, meaning that invocations like
12971295 /// `Literal::i8_unsuffixed(1)` are equivalent to
12981296 /// `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
13001298 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
13011299 ///
13021300 /// Literals created through this method have the `Span::call_site()`
......@@ -1416,7 +1414,7 @@ impl Literal {
14161414 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
14171415 /// the float's value is emitted directly into the token but no suffix is
14181416 /// 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
14201418 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
14211419 ///
14221420 /// # Panics
......@@ -1441,7 +1439,7 @@ impl Literal {
14411439 /// specified is the preceding part of the token and `f32` is the suffix of
14421440 /// the token. This token will always be inferred to be an `f32` in the
14431441 /// compiler.
1444 /// Literals created from negative numbers might not survive rountrips through
1442 /// Literals created from negative numbers might not survive roundtrips through
14451443 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
14461444 ///
14471445 /// # Panics
......@@ -1461,7 +1459,7 @@ impl Literal {
14611459 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
14621460 /// the float's value is emitted directly into the token but no suffix is
14631461 /// 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
14651463 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
14661464 ///
14671465 /// # Panics
......@@ -1486,7 +1484,7 @@ impl Literal {
14861484 /// specified is the preceding part of the token and `f64` is the suffix of
14871485 /// the token. This token will always be inferred to be an `f64` in the
14881486 /// compiler.
1489 /// Literals created from negative numbers might not survive rountrips through
1487 /// Literals created from negative numbers might not survive roundtrips through
14901488 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
14911489 ///
14921490 /// # Panics
library/std/src/lib.rs+1
......@@ -355,6 +355,7 @@
355355#![feature(int_from_ascii)]
356356#![feature(io_error_inprogress)]
357357#![feature(io_error_more)]
358#![feature(io_error_too_many_open_files)]
358359#![feature(io_error_uncategorized)]
359360#![feature(io_slice_as_bytes)]
360361#![feature(ip)]
library/std/src/os/mod.rs+66-117
......@@ -6,121 +6,83 @@
66
77pub mod raw;
88
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
1310
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")]
27pub 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")]
36pub 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")]
45pub 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")]
54pub 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)]
17cfg_select! {
5718 any(
5819 all(target_arch = "wasm32", not(target_os = "wasi")),
5920 all(target_vendor = "fortanix", target_env = "sgx")
60 )
61))]
62#[unstable(issue = "none", feature = "std_internals")]
63pub mod windows {}
21 ) => {
22 #[unstable(issue = "none", feature = "std_internals")]
23 pub mod darwin {}
6424
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))]
74pub mod darwin;
25 #[unstable(issue = "none", feature = "std_internals")]
26 pub mod unix {}
7527
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)))]
85pub mod unix;
28 #[unstable(issue = "none", feature = "std_internals")]
29 pub mod linux {}
8630
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))]
96pub mod linux;
31 #[unstable(issue = "none", feature = "std_internals")]
32 pub mod wasi {}
9733
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))]
107pub 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
48cfg_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}
10867
109#[cfg(any(all(target_os = "wasi", target_env = "p2"), doc))]
110pub mod wasip2;
68// # Special modules
11169
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))]
121pub 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))]
78pub mod fd;
79
80#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))]
81mod net;
82
83// # Ordinary platforms
84// `cfg(doc)` not handled specially
12285
123// Others.
12486#[cfg(target_os = "aix")]
12587pub mod aix;
12688#[cfg(target_os = "android")]
......@@ -183,16 +145,3 @@ pub mod vita;
183145pub mod vxworks;
184146#[cfg(target_os = "xous")]
185147pub 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))]
195pub mod fd;
196
197#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))]
198mod net;
library/std/src/sync/poison.rs-3
......@@ -57,9 +57,6 @@
5757//!
5858//! [`Once`]: crate::sync::Once
5959
60// If we are not unwinding, `PoisonError` is uninhabited.
61#![cfg_attr(not(panic = "unwind"), expect(unreachable_code))]
62
6360#[stable(feature = "rust1", since = "1.0.0")]
6461pub use self::condvar::Condvar;
6562#[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<()> {
612612 Err(io::const_error!(io::ErrorKind::OutOfMemory, "not enough memory for the operation"))
613613 }
614614 vex_sdk::FRESULT::FR_TOO_MANY_OPEN_FILES => Err(io::const_error!(
615 io::ErrorKind::Uncategorized,
615 io::ErrorKind::TooManyOpenFiles,
616616 "maximum number of open files has been reached",
617617 )),
618618 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 {
137137 libc::ETXTBSY => ExecutableFileBusy,
138138 libc::EXDEV => CrossesDevices,
139139 libc::EINPROGRESS => InProgress,
140 libc::EMFILE | libc::ENFILE => TooManyOpenFiles,
140141 libc::EOPNOTSUPP => Unsupported,
141142
142143 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 {
5959 libc::ETXTBSY => ExecutableFileBusy,
6060 libc::EXDEV => CrossesDevices,
6161 libc::EINPROGRESS => InProgress,
62 libc::EMFILE | libc::ENFILE => TooManyOpenFiles,
6263 libc::EOPNOTSUPP => Unsupported,
6364 libc::EACCES | libc::EPERM => PermissionDenied,
6465 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 {
6161 c::ERROR_POSSIBLE_DEADLOCK => return Deadlock,
6262 c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
6363 c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
64 c::ERROR_TOO_MANY_OPEN_FILES => return TooManyOpenFiles,
6465 c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
6566 c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop,
6667 _ => {}
......@@ -81,6 +82,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
8182 c::WSAENETDOWN => NetworkDown,
8283 c::WSAENETUNREACH => NetworkUnreachable,
8384 c::WSAEDQUOT => QuotaExceeded,
85 c::WSAEMFILE => TooManyOpenFiles,
8486 // Not a perfect mapping but this error is only returned when writing to
8587 // a socket after shutting down the write-end. On Unix targets, EPIPE is
8688 // returned in those cases.
src/bootstrap/src/core/build_steps/dist.rs-5
......@@ -1201,11 +1201,6 @@ impl Step for Src {
12011201 // not needed and contains symlinks which rustup currently
12021202 // chokes on when unpacking.
12031203 "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",
12091204 ],
12101205 &dst_src,
12111206 );
src/ci/scripts/install-mingw.sh+2-2
......@@ -6,8 +6,8 @@ IFS=$'\n\t'
66
77source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
88
9MINGW_ARCHIVE_32="i686-14.1.0-release-posix-dwarf-msvcrt-rt_v12-rev0.7z"
10MINGW_ARCHIVE_64="x86_64-14.1.0-release-posix-seh-msvcrt-rt_v12-rev0.7z"
9MINGW_ARCHIVE_32="i686-14.2.0-release-posix-dwarf-msvcrt-rt_v12-rev2.7z"
10MINGW_ARCHIVE_64="x86_64-14.2.0-release-posix-seh-msvcrt-rt_v12-rev2.7z"
1111LLVM_MINGW_ARCHIVE_AARCH64="llvm-mingw-20251104-ucrt-aarch64.zip"
1212LLVM_MINGW_ARCHIVE_X86_64="llvm-mingw-20251104-ucrt-x86_64.zip"
1313
src/doc/rustc/src/platform-support/windows-gnu.md+12
......@@ -26,6 +26,18 @@ They follow Windows calling convention for `extern "C"`.
2626
2727Like with any other Windows target, created binaries are in PE format.
2828
29### C toolchain
30
31The 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
38Using older tools (especially Binutils) may not work properly, due to the number of issues plaguing older versions of Binutils.
39The supported toolchain versions are subject to change.
40
2941## Building Rust programs
3042
3143Rust 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"] }
1010indoc = "1.0"
1111itertools = "0.12"
1212opener = "0.8"
13rustc-literal-escaper = "0.0.7"
13rustc-literal-escaper = "0.0.8"
1414walkdir = "2.3"
1515
1616[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."
77# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88
99[dependencies]
10rustc-literal-escaper = "0.0.7"
10rustc-literal-escaper = "0.0.8"
1111serde_json = "1.0.57"
1212tempfile = "3.1.0"
1313walkdir = "2.3.1"
src/tools/miri/tests/pass/c-variadic.rs+15
......@@ -106,6 +106,20 @@ fn various_types() {
106106 }
107107}
108108
109fn 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
109123fn clone() {
110124 if cfg!(force_intrinsic_fallback) {
111125 // Skip this test when we use the fallback bodies. The fallback body does
......@@ -170,6 +184,7 @@ fn main() {
170184 forward_by_ref();
171185 nested();
172186 various_types();
187 equal_up_to_free_lifetime();
173188 clone();
174189 clone_and_advance();
175190}
src/tools/rust-analyzer/.github/FUNDING.yml created+2
......@@ -0,0 +1,2 @@
1github: rustfoundation
2custom: ["rust-lang.org/funding"]
src/tools/rust-analyzer/.github/actions/github-release/Dockerfile+1-1
......@@ -1,4 +1,4 @@
1FROM node:slim
1FROM node:24.16-slim@sha256:ca520832af80fa37a57c14077ed0fcdd83b5aefccc356059fdc3a9a05b78ae1f
22
33COPY . /action
44WORKDIR /action
src/tools/rust-analyzer/.gitignore+1
......@@ -7,6 +7,7 @@ vendor/
77*.log
88*.iml
99.vscode/settings.json
10.vim/coc-settings.json
1011.DS_Store
1112/out/
1213/dump.lsif
src/tools/rust-analyzer/Cargo.lock-10
......@@ -1002,15 +1002,6 @@ dependencies = [
10021002 "typed-arena",
10031003]
10041004
1005[[package]]
1006name = "home"
1007version = "0.5.12"
1008source = "registry+https://github.com/rust-lang/crates.io-index"
1009checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
1010dependencies = [
1011 "windows-sys 0.61.2",
1012]
1013
10141005[[package]]
10151006name = "icu_collections"
10161007version = "2.2.0"
......@@ -3116,7 +3107,6 @@ name = "toolchain"
31163107version = "0.0.0"
31173108dependencies = [
31183109 "camino",
3119 "home",
31203110]
31213111
31223112[[package]]
src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs+5-4
......@@ -671,6 +671,7 @@ impl<'db> ExprCollector<'db> {
671671 }
672672
673673 pl.params()
674 .filter(|it| it.dotdotdot_token().is_none())
674675 .map(|it| {
675676 let type_ref = self.lower_type_ref_opt(it.ty(), impl_trait_lower_fn);
676677 let name = match it.pat() {
......@@ -2403,6 +2404,10 @@ impl<'db> ExprCollector<'db> {
24032404 statements: &mut Vec<Statement>,
24042405 mac: ast::MacroExpr,
24052406 ) -> Option<ExprId> {
2407 if !self.check_cfg(&ast::Expr::MacroExpr(mac.clone())) {
2408 return None;
2409 }
2410
24062411 let mac_call = mac.macro_call()?;
24072412 let syntax_ptr = AstPtr::new(&ast::Expr::from(mac));
24082413 let macro_ptr = AstPtr::new(&mac_call);
......@@ -2446,10 +2451,6 @@ impl<'db> ExprCollector<'db> {
24462451 }
24472452 ast::Stmt::ExprStmt(stmt) => {
24482453 let expr = stmt.expr();
2449 match &expr {
2450 Some(expr) if !self.check_cfg(expr) => return,
2451 _ => (),
2452 }
24532454 let has_semi = stmt.semicolon_token().is_some();
24542455 // Note that macro could be expanded to multiple statements
24552456 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() {
688688 }"#]],
689689 );
690690}
691
692#[test]
693fn foo() {
694 pretty_print(
695 r#"
696macro_rules! foo {
697 () => {
698 1
699 };
700}
701
702fn 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 {
141141 fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContext;
142142}
143143
144#[salsa_macros::interned(no_lifetime, id = span::SyntaxContext, revisions = usize::MAX)]
145pub struct SyntaxContextWrapper {
146 pub data: SyntaxContext,
147}
148
149144fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId, edition: Edition) -> SyntaxContext {
150145 match file {
151146 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>(
8787 let valtree = match (ty.kind(), value) {
8888 (TyKind::Uint(uint), Literal::Uint(value, _)) => {
8989 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 };
9193 ValTreeKind::Leaf(scalar)
9294 }
9395 (TyKind::Uint(uint), Literal::Int(value, _)) => {
9496 // `Literal::Int` is the default, so we also need to account for the type being uint.
9597 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 };
97101 ValTreeKind::Leaf(scalar)
98102 }
99103 (TyKind::Int(int), Literal::Int(value, _)) => {
100104 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 };
102108 ValTreeKind::Leaf(scalar)
103109 }
104110 (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
219225 return Const::error(interner);
220226 };
221227 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 };
223231 Const::new_valtree(interner, usize_ty, ValTreeKind::Leaf(scalar))
224232}
225233
src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs+13
......@@ -2633,6 +2633,19 @@ fn const_generic_subst_fn() {
26332633 );
26342634}
26352635
2636#[test]
2637fn 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
26362649#[test]
26372650fn layout_of_type_with_associated_type_field_defined_inside_body() {
26382651 check_number(
src/tools/rust-analyzer/crates/hir-ty/src/db.rs+2-15
......@@ -6,8 +6,8 @@ use base_db::{Crate, target::TargetLoadError};
66use either::Either;
77use hir_def::{
88 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,
1111 builtin_derive::BuiltinDeriveImplMethod,
1212 db::DefDatabase,
1313 expr_store::ExpressionStore,
......@@ -294,19 +294,6 @@ fn hir_database_is_dyn_compatible() {
294294 fn _assert_dyn_compatible(_: &dyn HirDatabase) {}
295295}
296296
297#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
298#[derive(PartialOrd, Ord)]
299pub 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)]
306pub struct InternedConstParamId {
307 pub loc: ConstParamId,
308}
309
310297#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
311298#[derive(PartialOrd, Ord)]
312299pub 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> {
10161016 }
10171017 }
10181018 Pat::Expr(expr) => {
1019 // Destructuring assignment.
10201019 this.mutate_expr(expr)?;
1020 // Destructuring assignment moves
1021 this.consume_or_copy(place);
10211022 }
10221023 Pat::Or(_)
10231024 | 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> {
19351935 Ok(Interval::new(addr, 4))
19361936 }
19371937 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))
19431948 }
19441949 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))
19501960 }
19511961 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))
19571969 }
19581970 TyKind::RawPtr(..) => {
19591971 let size = self.ptr_size();
......@@ -1995,15 +2007,13 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
19952007 _ => not_supported!("unsupported const"),
19962008 })
19972009 .collect::<Result<'_, Vec<_>>>()?;
2010 let item_size = item_layout.size.bytes_usize();
19982011 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,
20012014 )?;
20022015 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)?;
20072017 }
20082018 let ref_addr = self.heap_allocate(self.ptr_size() * 2, self.ptr_size())?;
20092019 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> {
843843 GenericArgs::for_item(self.interner, def_id, |_index, kind, _| self.var_for_def(kind, span))
844844 }
845845
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`.
847847 pub fn fill_rest_fresh_args(
848848 &self,
849849 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> {
11281128 SolverDefId::ConstId(def_id) => {
11291129 AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
11301130 }
1131 SolverDefId::StaticId(def_id) => {
1132 AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1133 }
11311134 SolverDefId::AnonConstId(def_id) => {
11321135 AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
11331136 }
......@@ -2626,8 +2629,8 @@ macro_rules! impl_gc_visit_slice {
26262629 }
26272630
26282631 #[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);
26312634 }
26322635 }
26332636 )*
src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs+37
......@@ -617,3 +617,40 @@ fn foo(foo: &Foo) {
617617 expect!["102..126;85..88;114..117 ByRef(Immutable) *foo &'<erased> Foo"],
618618 );
619619}
620
621#[test]
622fn method_call_field_access_regression() {
623 check_closure_captures(
624 r#"
625//- minicore:copy, fn
626struct NonCopy;
627
628struct Wrapper {
629 field: NonCopy,
630}
631
632impl Wrapper {
633 fn wrapped(&self) -> NonCopy {
634 NonCopy
635 }
636}
637
638pub struct Wrapper2 {
639 field1: NonCopy,
640 field2: NonCopy,
641}
642
643fn 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() {
394394 );
395395}
396396
397#[test]
398fn static_as_array_len_does_not_panic() {
399 check_no_mismatches(
400 r#"
401static S: usize = 8;
402const A: [u8; S] = [0; 8];
403 "#,
404 );
405}
406
407#[test]
408fn 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#"
412fn f(_: [u8; 18446744073709551616]) {}
413 "#,
414 );
415}
416
397417#[test]
398418fn another_20654_case() {
399419 check_no_mismatches(
src/tools/rust-analyzer/crates/hir-ty/src/traits.rs+4-1
......@@ -20,7 +20,7 @@ use hir_expand::name::Name;
2020use intern::sym;
2121use rustc_type_ir::{
2222 TypeVisitableExt, TypingMode,
23 inherent::{BoundExistentialPredicates, IntoKind},
23 inherent::{BoundExistentialPredicates, IntoKind, Ty as _},
2424};
2525
2626use crate::{
......@@ -154,6 +154,9 @@ pub fn implements_trait_unique_with_infcx<'db>(
154154
155155 let args = create_args(&infcx);
156156 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 }
157160
158161 let obligation = Obligation::new(interner, ObligationCause::dummy(), env.param_env, trait_ref);
159162 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 {
12361236 fn destructure_in_sub_pattern() {
12371237 check_sub_pattern_assist(
12381238 r#"
1239#![feature(bindings_after_at)]
1240
12411239fn main() {
12421240 let $0t = (1,2);
12431241}
12441242 "#,
12451243 r#"
1246#![feature(bindings_after_at)]
1247
12481244fn main() {
12491245 let t @ ($0_0, _1) = (1,2);
12501246}
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs+107-70
......@@ -17,9 +17,10 @@ use syntax::{
1717 ast::{
1818 self, HasVisibility,
1919 edit::{AstNodeEdit, IndentLevel},
20 make,
20 syntax_factory::SyntaxFactory,
2121 },
22 match_ast, ted,
22 match_ast,
23 syntax_editor::{Position, SyntaxEditor},
2324};
2425
2526use crate::{AssistContext, Assists};
......@@ -121,15 +122,18 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_, '_>) ->
121122 let (usages_to_be_processed, record_fields, use_stmts_to_be_inserted) =
122123 module.get_usages_and_record_fields(ctx, module_text_range);
123124
125 let make = SyntaxFactory::without_mappings();
126
124127 builder.edit_file(ctx.vfs_file_id());
125128 use_stmts_to_be_inserted.into_iter().for_each(|(_, use_stmt)| {
126129 builder.insert(ctx.selection_trimmed().end(), format!("\n{use_stmt}"));
127130 });
128131
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);
131134
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);
133137
134138 let mut usages_to_be_processed_for_cur_file = vec![];
135139 for (file_id, usages) in usages_to_be_processed {
......@@ -185,6 +189,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_, '_>) ->
185189fn generate_module_def(
186190 parent_impl: &Option<ast::Impl>,
187191 Module { name, body_items, use_items }: &Module,
192 make: &SyntaxFactory,
188193) -> ast::Module {
189194 let items: Vec<_> = if let Some(impl_) = parent_impl.as_ref()
190195 && let Some(self_ty) = impl_.self_ty()
......@@ -195,11 +200,15 @@ fn generate_module_def(
195200 .filter_map(ast::AssocItem::cast)
196201 .map(|it| it.indent(IndentLevel(1)))
197202 .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();
201210 // 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);
203212 once(use_impl)
204213 .chain(use_items.iter().cloned())
205214 .chain(once(ast::Item::Impl(impl_)))
......@@ -209,19 +218,18 @@ fn generate_module_def(
209218 };
210219
211220 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))
216224}
217225
218fn 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_(
226fn 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 [],
222231 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),
225233 );
226234
227235 ast::Item::from(use_)
......@@ -385,18 +393,30 @@ impl Module {
385393 if use_.syntax().parent().is_some_and(|parent| parent == covering_node)
386394 && use_stmts_set.insert(use_.syntax().text_range().start())
387395 {
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();
400420 }
401421 }
402422 }
......@@ -407,18 +427,23 @@ impl Module {
407427 }
408428 }
409429
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
411436 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);
413438
414 let mut impl_items = impls
439 let impl_items = impls
415440 .into_iter()
416441 .flat_map(|impl_| impl_.syntax().descendants())
417442 .filter_map(ast::Item::cast)
418443 .collect_vec();
419444
420445 let (mut impl_item_replacements, _, _) =
421 get_replacements_for_visibility_change(&mut impl_items, true);
446 get_replacements_for_visibility_change(&impl_items);
422447
423448 replacements.append(&mut impl_item_replacements);
424449
......@@ -432,17 +457,39 @@ impl Module {
432457 }
433458 }
434459
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();
444477
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();
446493 }
447494 }
448495
......@@ -450,6 +497,7 @@ impl Module {
450497 &mut self,
451498 module: Option<ast::Module>,
452499 ctx: &AssistContext<'_, '_>,
500 make: &SyntaxFactory,
453501 ) -> Vec<TextRange> {
454502 let mut imports_to_remove = vec![];
455503 let mut node_set = FxHashSet::default();
......@@ -476,7 +524,8 @@ impl Module {
476524 })
477525 .for_each(|(node, def)| {
478526 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)
480529 {
481530 check_intersection_and_push(&mut imports_to_remove, import);
482531 }
......@@ -492,6 +541,7 @@ impl Module {
492541 use_node: &SyntaxNode,
493542 curr_parent_module: &Option<ast::Module>,
494543 ctx: &AssistContext<'_, '_>,
544 make: &SyntaxFactory,
495545 ) -> Option<TextRange> {
496546 //We only need to find in the current file
497547 let selection_range = ctx.selection_trimmed();
......@@ -567,7 +617,7 @@ impl Module {
567617 // mod -> ust_stmt transversal
568618 // true | false -> super import insertion
569619 // 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);
571621 self.use_items.insert(0, super_use_node);
572622 }
573623 None => {}
......@@ -590,14 +640,14 @@ impl Module {
590640 if !first_path_in_use_tree_str.contains("super")
591641 && !first_path_in_use_tree_str.contains("crate")
592642 {
593 let super_path = make::ext::ident_path("super");
643 let super_path = make.ident_path("super");
594644 use_tree_str.push(super_path);
595645 }
596646 }
597647
598648 use_tree_paths = Some(use_tree_str);
599649 } 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);
601651 self.use_items.insert(0, super_use_node);
602652 }
603653 }
......@@ -609,7 +659,7 @@ impl Module {
609659 && let Some(first_path_in_use_tree) = use_tree_paths.first()
610660 && first_path_in_use_tree.to_string().contains("super")
611661 {
612 use_tree_paths.insert(0, make::ext::ident_path("super"));
662 use_tree_paths.insert(0, make.ident_path("super"));
613663 }
614664
615665 let is_item = matches!(
......@@ -624,12 +674,12 @@ impl Module {
624674 | Definition::TypeAlias(_)
625675 );
626676
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));
633683 self.use_items.insert(0, ast::Item::from(use_));
634684 }
635685 }
......@@ -741,8 +791,7 @@ fn check_def_in_mod_and_out_sel(
741791}
742792
743793fn get_replacements_for_visibility_change(
744 items: &mut [ast::Item],
745 is_clone_for_updated: bool,
794 items: &[ast::Item],
746795) -> (
747796 Vec<(Option<ast::Visibility>, SyntaxNode)>,
748797 Vec<(Option<ast::Visibility>, SyntaxNode)>,
......@@ -753,9 +802,6 @@ fn get_replacements_for_visibility_change(
753802 let mut impls = Vec::new();
754803
755804 for item in items {
756 if !is_clone_for_updated {
757 *item = item.clone_for_update();
758 }
759805 //Use stmts are ignored
760806 macro_rules! push_to_replacement {
761807 ($it:ident) => {
......@@ -812,15 +858,6 @@ fn get_use_tree_paths_from_path(
812858 Some(use_tree_str)
813859}
814860
815fn 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
824861fn indent_range_before_given_node(node: &SyntaxNode) -> Option<TextRange> {
825862 node.siblings_with_tokens(syntax::Direction::Prev)
826863 .find(|x| x.kind() == WHITESPACE)
src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs+148-68
......@@ -1,19 +1,20 @@
11use either::{Either, for_both};
2use hir::{PathResolution, Semantics};
2use hir::{EditionedFileId, PathResolution, Semantics};
33use ide_db::{
4 EditionedFileId, RootDatabase,
4 RootDatabase,
55 defs::Definition,
6 search::{FileReference, FileReferenceNode, UsageSearchResult},
6 search::{FileReference, UsageSearchResult},
77};
88use syntax::{
9 Direction, TextRange,
9 Direction, T, TextRange,
1010 ast::{self, AstNode, AstToken, HasName},
11 syntax_editor::{Element, SyntaxEditor},
11 syntax_editor::{Element, Position, SyntaxEditor},
1212};
1313
1414use crate::{
1515 AssistId,
1616 assist_context::{AssistContext, Assists},
17 utils::{cover_edit_range, original_range_in},
1718};
1819
1920// Assist: inline_local_variable
......@@ -34,11 +35,12 @@ use crate::{
3435// ```
3536pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
3637 let file_id = ctx.file_id();
38 let source = ctx.source_file().syntax();
3739 let range = ctx.selection_trimmed();
3840 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>() {
4042 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() {
4244 inline_let(&ctx.sema, let_stmt, range, file_id)
4345 } else {
4446 None
......@@ -47,71 +49,65 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_, '
4749 either::Either::Left(it) => it.initializer()?,
4850 either::Either::Right(it) => it.expr()?,
4951 };
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)
6259 }
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 }
7962 };
8063
8164 acc.add(
8265 AssistId::refactor_inline("inline_local_variable"),
8366 "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);
8770 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
9179 if let Some(bin_expr) = let_stmt.syntax().parent().and_then(ast::BinExpr::cast)
9280 && let Some(op_token) = bin_expr.op_token()
9381 {
9482 editor.delete(&op_token);
9583 remove_whitespace(op_token, Direction::Prev, &editor);
96 remove_whitespace(let_stmt.syntax(), Direction::Prev, &editor);
84 remove_whitespace(place.start(), Direction::Prev, &editor);
9785 } else {
98 remove_whitespace(let_stmt.syntax(), Direction::Next, &editor);
86 remove_whitespace(place.end(), Direction::Next, &editor);
9987 }
10088 }
10189
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) {
10493 make.expr_paren(initializer_expr.clone()).into()
10594 } else {
10695 initializer_expr.clone()
10796 };
10897
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() {
110100 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 );
113109 } else {
114 editor.replace(name.syntax(), replacement.syntax());
110 editor.replace_all(place, vec![replacement.syntax().clone().into()]);
115111 }
116112 }
117113 builder.add_file_edits(ctx.vfs_file_id(), editor);
......@@ -122,7 +118,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_, '
122118struct InlineData {
123119 let_stmt: Either<ast::LetStmt, ast::LetExpr>,
124120 delete_let: bool,
125 target: ast::NameOrNameRef,
121 target: TextRange,
126122 references: Vec<FileReference>,
127123}
128124
......@@ -140,20 +136,18 @@ fn inline_let(
140136 cov_mark::hit!(test_not_inline_mut_variable);
141137 return None;
142138 }
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) {
144141 cov_mark::hit!(not_applicable_outside_of_bind_pat);
145142 return None;
146143 }
147144
148145 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 }),
157151 None => {
158152 cov_mark::hit!(test_not_applicable_if_variable_unused);
159153 None
......@@ -169,7 +163,8 @@ fn inline_usage(
169163) -> Option<InlineData> {
170164 let path = path_expr.path()?;
171165 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) {
173168 cov_mark::hit!(test_not_inline_selection_too_broad);
174169 return None;
175170 }
......@@ -193,12 +188,12 @@ fn inline_usage(
193188
194189 let let_stmt = AstNode::cast(bind_pat.syntax().parent()?)?;
195190
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<_>>();
198193 let delete_let = references.len() == 1;
199194 references.retain(|fref| fref.name.as_name_ref() == Some(&name));
200195
201 Some(InlineData { let_stmt, delete_let, target: ast::NameOrNameRef::NameRef(name), references })
196 Some(InlineData { let_stmt, delete_let, target, references })
202197}
203198
204199fn remove_whitespace(elem: impl Element, dir: Direction, editor: &SyntaxEditor) {
......@@ -969,8 +964,8 @@ fn main() {
969964 }
970965
971966 #[test]
972 fn not_applicable_on_local_usage_in_macro() {
973 check_assist_not_applicable(
967 fn local_usage_in_macro() {
968 check_assist(
974969 inline_local_variable,
975970 r#"
976971macro_rules! m {
......@@ -978,11 +973,19 @@ macro_rules! m {
978973}
979974fn f() {
980975 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#"
980macro_rules! m {
981 ($i:ident) => { $i }
982}
983fn f() {
984 m!(0); // some macros may break, but it's best to support them
982985}
983986"#,
984987 );
985 check_assist_not_applicable(
988 check_assist(
986989 inline_local_variable,
987990 r#"
988991macro_rules! m {
......@@ -990,7 +993,84 @@ macro_rules! m {
990993}
991994fn f() {
992995 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#"
1000macro_rules! m {
1001 ($i:ident) => { $i }
1002}
1003fn 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#"
1015macro_rules! i {
1016 ($($t:tt)*) => { $($t)* }
1017}
1018fn f() {
1019 i!(let xyz = 0;);
1020 _ = xyz$0;
1021}
1022"#,
1023 r#"
1024macro_rules! i {
1025 ($($t:tt)*) => { $($t)* }
1026}
1027fn f() {
1028 i!();
1029 _ = 0;
1030}
1031"#,
1032 );
1033 check_assist(
1034 inline_local_variable,
1035 r#"
1036macro_rules! i {
1037 ($($t:tt)*) => { $($t)* }
1038}
1039fn f() {
1040 i!(let xyz = 0;);
1041 _ = xyz$0;
1042 _ = xyz;
1043}
1044"#,
1045 r#"
1046macro_rules! i {
1047 ($($t:tt)*) => { $($t)* }
1048}
1049fn f() {
1050 i!(let xyz = 0;);
1051 _ = 0;
1052 _ = xyz;
1053}
1054"#,
1055 );
1056 check_assist(
1057 inline_local_variable,
1058 r#"
1059macro_rules! i {
1060 ($($t:tt)*) => { $($t)* }
1061}
1062fn f() {
1063 i!(let $0xyz = 0;);
1064 _ = xyz;
1065}
1066"#,
1067 r#"
1068macro_rules! i {
1069 ($($t:tt)*) => { $($t)* }
1070}
1071fn f() {
1072 i!();
1073 _ = 0;
9941074}
9951075"#,
9961076 );
src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_macro.rs+59-8
......@@ -1,8 +1,11 @@
11use hir::db::ExpandDatabase;
22use ide_db::syntax_helpers::prettify_macro_expansion;
3use syntax::ast::{self, AstNode, edit::AstNodeEdit};
3use syntax::ast::{self, AstNode, edit::IndentLevel};
44
5use crate::{AssistContext, AssistId, Assists};
5use crate::{
6 AssistContext, AssistId, Assists,
7 utils::{cover_edit_range, original_range_in},
8};
69
710// Assist: inline_macro
811//
......@@ -36,24 +39,40 @@ use crate::{AssistContext, AssistId, Assists};
3639// }
3740// ```
3841pub(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 })?;
4153 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();
4354
4455 acc.add(
4556 AssistId::refactor_inline("inline_macro"),
4657 "Inline macro".to_owned(),
4758 text_range,
4859 |builder| {
49 let editor = builder.make_editor(unexpanded.syntax());
5060 let expanded = ctx.sema.parse_or_expand(macro_call.into());
5161 let span_map = ctx.sema.db.expansion_span_map(macro_call);
5262 // Don't call `prettify_macro_expansion()` outside the actual assist action; it does some heavy rowan tree manipulation,
5363 // which can be very costly for big macros when it is done *even without the assist being invoked*.
5464 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()]);
5776 builder.add_file_edits(ctx.vfs_file_id(), editor);
5877 },
5978 )
......@@ -103,6 +122,7 @@ macro_rules! num {
103122"#
104123 };
105124 }
125
106126 #[test]
107127 fn inline_macro_target() {
108128 check_assist_target(
......@@ -376,6 +396,37 @@ fn bar() {
376396fn bar() {
377397 a::Foo;
378398}
399"#,
400 );
401 }
402
403 #[test]
404 fn inline_macro_in_macro() {
405 check_assist(
406 inline_macro,
407 r#"
408macro_rules! foo { () => { 2 }; }
409macro_rules! m { ($($tt:tt)*) => { $($tt)* }; }
410fn f() { m! { $0foo!(); } }
411"#,
412 r#"
413macro_rules! foo { () => { 2 }; }
414macro_rules! m { ($($tt:tt)*) => { $($tt)* }; }
415fn f() { m! { 2; } }
416"#,
417 );
418 check_assist(
419 inline_macro,
420 r#"
421//- proc_macros: identity
422macro_rules! foo { () => { 2 }; }
423#[proc_macros::identity]
424fn f() { $0foo!(); }
425"#,
426 r#"
427macro_rules! foo { () => { 2 }; }
428#[proc_macros::identity]
429fn f() { 2; }
379430"#,
380431 );
381432 }
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<'_, '_>)
135135 PathResolution::SelfType(imp) => {
136136 concrete_type = imp.source(ctx.db())?.value.self_ty()?;
137137 }
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 }
139152 _ => return None,
140153 }
141154
......@@ -996,6 +1009,68 @@ trait Tr {
9961009 );
9971010 }
9981011
1012 #[test]
1013 fn inline_self_type_in_adt_definition() {
1014 check_assist(
1015 inline_type_alias,
1016 r#"
1017enum Foo {
1018 A(i32),
1019 B(Box<Self$0>),
1020}
1021"#,
1022 r#"
1023enum Foo {
1024 A(i32),
1025 B(Box<Foo>),
1026}
1027"#,
1028 );
1029 check_assist(
1030 inline_type_alias,
1031 r#"
1032struct Foo {
1033 a: Box<Self$0>,
1034}
1035"#,
1036 r#"
1037struct Foo {
1038 a: Box<Foo>,
1039}
1040"#,
1041 );
1042 check_assist(
1043 inline_type_alias,
1044 r#"
1045struct Foo<T> {
1046 a: T,
1047 b: Box<Self$0>,
1048}
1049"#,
1050 r#"
1051struct Foo<T> {
1052 a: T,
1053 b: Box<Foo<T>>,
1054}
1055"#,
1056 );
1057 check_assist(
1058 inline_type_alias,
1059 r#"
1060union Foo {
1061 a: u32,
1062 b: std::mem::ManuallyDrop<Box<Self$0>>,
1063}
1064"#,
1065 r#"
1066union Foo {
1067 a: u32,
1068 b: std::mem::ManuallyDrop<Box<Foo>>,
1069}
1070"#,
1071 );
1072 }
1073
9991074 #[test]
10001075 fn inline_types_with_lifetime() {
10011076 check_assist(
src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs+114-81
......@@ -1,10 +1,12 @@
1use either::Either;
21use ide_db::imports::{
32 insert_use::{ImportGranularity, InsertUseConfig},
43 merge_imports::{MergeBehavior, try_merge_imports, try_merge_trees},
54};
65use 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},
810};
911
1012use crate::{
......@@ -13,8 +15,6 @@ use crate::{
1315 utils::next_prev,
1416};
1517
16use Edit::*;
17
1818// Assist: merge_imports
1919//
2020// Merges neighbor imports with a common prefix.
......@@ -28,16 +28,17 @@ use Edit::*;
2828// use std::{fmt::Formatter, io};
2929// ```
3030pub(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() {
3232 // Merge a neighbor
3333 cov_mark::hit!(merge_with_use_item_neighbors);
3434 let tree = ctx.find_node_at_offset::<ast::UseTree>()?.top_use_tree();
3535 let target = tree.syntax().text_range();
3636
3737 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)
4142 } else {
4243 // Merge selected
4344 let selection_range = ctx.selection_trimmed();
......@@ -50,104 +51,80 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> O
5051 });
5152
5253 let first_selected = selected_nodes.next()?;
53 let edits = match_ast! {
54 let (editor, _) = SyntaxEditor::new(parent_node.ancestors().last().unwrap());
55 match_ast! {
5456 match first_selected {
5557 ast::Use(use_item) => {
5658 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 )?;
5865 },
5966 ast::UseTree(use_tree) => {
6067 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 )?;
6273 },
6374 _ => return None,
6475 }
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)
7278 };
7379
7480 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 }
9281 builder.add_file_edits(ctx.vfs_file_id(), editor);
9382 })
9483}
9584
96trait 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 }
85fn 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;
11493 }
115 fn try_merge(&self, other: &Self, cfg: &InsertUseConfig) -> Option<Self>;
116 fn into_either(self) -> Either<ast::Use, ast::UseTree>;
117}
11894
119impl 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)?;
126102 }
127 fn into_either(self) -> Either<ast::Use, ast::UseTree> {
128 Either::Left(self)
103 for item in rest {
104 item.remove(editor);
129105 }
106 editor.replace(first.syntax(), merged.syntax());
107 Some(())
130108}
131109
132impl Merge for ast::UseTree {
133 fn try_merge(&self, other: &Self, _: &InsertUseConfig) -> Option<Self> {
134 try_merge_trees(self, other, MergeBehavior::Crate)
110fn 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;
135117 }
136 fn into_either(self) -> Either<ast::Use, ast::UseTree> {
137 Either::Right(self)
138 }
139}
140118
141#[derive(Debug)]
142enum Edit {
143 Remove(Either<ast::Use, ast::UseTree>),
144 Replace(SyntaxNode, SyntaxNode),
145}
146
147impl 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);
150125 }
126 editor.replace(first.syntax(), merged.syntax());
127 Some(())
151128}
152129
153130#[cfg(test)]
......@@ -558,6 +535,62 @@ use foo::{bar, baz};
558535 );
559536 }
560537
538 #[test]
539 fn mod_indent_whitespace() {
540 check_assist(
541 merge_imports,
542 r"
543mod tests {
544 use foo$0::bar;
545 use foo::baz;
546 fn feature() {}
547}
548",
549 r"
550mod tests {
551 use foo::{bar, baz};
552 fn feature() {}
553}
554",
555 );
556 check_assist(
557 merge_imports,
558 r"
559mod tests {
560 use foo$0::bar;
561 use foo::baz;
562
563 fn feature() {}
564}
565",
566 r"
567mod tests {
568 use foo::{bar, baz};
569
570 fn feature() {}
571}
572",
573 );
574 check_assist(
575 merge_imports,
576 r"
577mod tests {
578 use foo::bar;
579 use foo$0::baz;
580
581 fn feature() {}
582}
583",
584 r"
585mod tests {
586 use foo::{bar, baz};
587
588 fn feature() {}
589}
590",
591 );
592 }
593
561594 #[test]
562595 fn works_with_trailing_comma() {
563596 check_assist(
src/tools/rust-analyzer/crates/ide-assists/src/handlers/normalize_import.rs+5-3
......@@ -1,5 +1,5 @@
11use ide_db::imports::merge_imports::try_normalize_import;
2use syntax::{AstNode, ast};
2use syntax::{AstNode, ast, syntax_editor::SyntaxEditor};
33
44use crate::{
55 AssistId,
......@@ -25,11 +25,13 @@ pub(crate) fn normalize_import(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -
2525 };
2626
2727 let target = use_item.syntax().text_range();
28 let (editor, _) = SyntaxEditor::new(use_item.syntax().ancestors().last().unwrap());
2829 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());
3032
3133 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);
3335 })
3436}
3537
src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs+70-9
......@@ -17,7 +17,7 @@ use crate::{
1717 AssistContext, AssistId, Assists,
1818 utils::{
1919 does_pat_match_variant, does_pat_variant_nested_or_literal, unwrap_trivial_block,
20 wrap_paren,
20 wrap_paren_in_guard_chain,
2121 },
2222};
2323
......@@ -303,7 +303,7 @@ pub(crate) fn replace_match_with_if_let(
303303 _ => make.expr_let(if_let_pat, scrutinee).into(),
304304 };
305305 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);
307307 make.expr_bin(condition, ast::BinaryOp::LogicOp(ast::LogicOp::And), guard).into()
308308 } else {
309309 condition
......@@ -712,13 +712,11 @@ impl VariantData {
712712 check_assist(
713713 replace_if_let_with_match,
714714 r#"
715#![feature(if_let_guard)]
716715fn main() {
717716 if $0let true = true && let Some(1) = None {} else { other() }
718717}
719718"#,
720719 r#"
721#![feature(if_let_guard)]
722720fn main() {
723721 match true {
724722 true if let Some(1) = None => {}
......@@ -731,7 +729,6 @@ fn main() {
731729 check_assist(
732730 replace_if_let_with_match,
733731 r#"
734#![feature(if_let_guard)]
735732fn main() {
736733 if true {
737734 $0if let ParenExpr(expr) = cond
......@@ -758,7 +755,6 @@ fn main() {
758755}
759756"#,
760757 r#"
761#![feature(if_let_guard)]
762758fn main() {
763759 if true {
764760 match cond {
......@@ -816,13 +812,11 @@ fn main() {
816812 check_assist(
817813 replace_if_let_with_match,
818814 r#"
819#![feature(if_let_guard)]
820815fn main() {
821816 if $0let true = true && let Some(1) = None {}
822817}
823818"#,
824819 r#"
825#![feature(if_let_guard)]
826820fn main() {
827821 match true {
828822 true if let Some(1) = None => {}
......@@ -2460,7 +2454,7 @@ fn main() {
24602454 }
24612455
24622456 #[test]
2463 fn test_replace_match_with_if_let_chain() {
2457 fn test_replace_match_with_if_let_with_simple_guard() {
24642458 check_assist(
24652459 replace_match_with_if_let,
24662460 r#"
......@@ -2504,6 +2498,73 @@ fn main() {
25042498 );
25052499 }
25062500
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#"
2506fn main() {
2507 match$0 Some(0) {
2508 Some(n) if let Some(m) = n.checked_add(1) => (),
2509 _ => code(),
2510 }
2511}
2512"#,
2513 r#"
2514fn 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#"
2527fn 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#"
2535fn 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#"
2549fn 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#"
2557fn 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
25072568 #[test]
25082569 fn test_replace_match_with_if_let_not_applicable_pat2_is_ident_pat() {
25092570 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 {
110110 param.needs_parens_in_place_of(call.syntax(), callable.syntax())
111111}
112112
113pub(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
117fn 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
113133/// This is a method with a heuristics to support test methods annotated with custom test annotations, such as
114134/// `#[test_case(...)]`, `#[tokio::test]` and similar.
115135/// Also a regular `#[test]` annotation is supported.
......@@ -1177,6 +1197,15 @@ pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bo
11771197 is_const
11781198}
11791199
1200pub(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
11801209// FIXME: #20460 When hir-ty can analyze the `never` statement at the end of block, remove it
11811210pub(crate) fn is_never_block(
11821211 sema: &Semantics<'_, RootDatabase>,
src/tools/rust-analyzer/crates/ide-completion/src/config.rs+1
......@@ -45,6 +45,7 @@ pub enum AutoImportExclusionType {
4545 Always,
4646 Methods,
4747 SubItems,
48 Variants,
4849}
4950
5051#[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> {
868868 _ => None,
869869 })
870870 .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<_>>();
871880 exclude_flyimport
872881 .extend(exclude_traits.iter().map(|&t| (t.into(), AutoImportExclusionType::Always)));
873882 exclude_flyimport
874883 .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 );
875887
876888 // FIXME: This should be part of `CompletionAnalysis` / `expand_and_analyze`
877889 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 {
23722372}
23732373fn foo(s: S) { s.$0 }
23742374"#,
2375 CompletionItemKind::SymbolKind(SymbolKind::Method),
2375 SymbolKind::Method,
23762376 expect![[r#"
23772377 [
23782378 CompletionItem {
src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs+98
......@@ -3041,6 +3041,76 @@ fn foo() {
30413041 );
30423042}
30433043
3044#[test]
3045fn 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#"
3055enum Foo {
3056 Variant1,
3057 Variant2,
3058}
3059fn 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
30443114#[test]
30453115fn excluded_trait_method_is_excluded_from_path_completion() {
30463116 check_with_config(
......@@ -4109,3 +4179,31 @@ fn main() {
41094179 "#]],
41104180 );
41114181}
4182
4183#[test]
4184fn no_await_on_error_type() {
4185 check(
4186 r#"
4187//- minicore: future
4188fn 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 @@
11//! Applies changes to the IDE state transactionally.
22
3use std::time::{Duration, Instant};
4
35use profile::Bytes;
46use salsa::Database as _;
57
68use crate::{ChangeWithProcMacros, RootDatabase};
79
810impl RootDatabase {
9 pub fn apply_change(&mut self, change: ChangeWithProcMacros) {
11 pub fn apply_change(&mut self, change: ChangeWithProcMacros) -> Duration {
1012 let _p = tracing::info_span!("RootDatabase::apply_change").entered();
13 let now = Instant::now();
1114 self.trigger_cancellation();
15 let elapsed = now.elapsed();
1216 tracing::trace!("apply_change {:?}", change);
1317 change.apply(self);
18 elapsed
1419 }
1520
1621 // Feature: Memory Usage
src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs+5-3
......@@ -17,7 +17,7 @@ use crate::{
1717 RootDatabase,
1818 imports::merge_imports::{
1919 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,
2121 },
2222};
2323
......@@ -251,7 +251,7 @@ fn insert_use_with_alias_option_with_editor(
251251 let mut use_tree = make.use_tree(path, None, alias, false);
252252 if mb == Some(MergeBehavior::One)
253253 && 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)
255255 {
256256 use_tree = wrapped;
257257 }
......@@ -263,7 +263,9 @@ fn insert_use_with_alias_option_with_editor(
263263 for existing_use in
264264 scope.as_syntax_node().children().filter_map(ast::Use::cast).filter(filter)
265265 {
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 {
267269 syntax_editor.replace(existing_use.syntax(), merged.syntax());
268270 return;
269271 }
src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs+7-3
......@@ -1,4 +1,5 @@
11use stdx::trim_indent;
2use syntax::ast::syntax_factory::SyntaxFactory;
23use test_fixture::WithFixture;
34use test_utils::{CURSOR_MARKER, assert_eq_text};
45
......@@ -1430,7 +1431,8 @@ fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior
14301431 .find_map(ast::Use::cast)
14311432 .unwrap();
14321433
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);
14341436 assert_eq!(result.map(|u| u.to_string()), None);
14351437}
14361438
......@@ -1495,7 +1497,8 @@ fn check_merge(ra_fixture0: &str, ra_fixture1: &str, last: &str, mb: MergeBehavi
14951497 .find_map(ast::Use::cast)
14961498 .unwrap();
14971499
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);
14991502 assert_eq!(result.map(|u| u.to_string().trim().to_owned()), Some(last.trim().to_owned()));
15001503}
15011504
......@@ -1525,7 +1528,8 @@ fn merge_gated_imports_with_different_values() {
15251528 .find_map(ast::Use::cast)
15261529 .unwrap();
15271530
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);
15291533 assert_eq!(result, None);
15301534}
15311535
src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs+397-267
......@@ -4,12 +4,12 @@ use std::cmp::Ordering;
44use itertools::{EitherOrBoth, Itertools};
55use parser::T;
66use syntax::{
7 Direction, SyntaxElement, ToSmolStr, algo,
7 ToSmolStr,
88 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,
1111 },
12 ted::{self, Position},
12 syntax_editor::{Position, SyntaxEditor},
1313};
1414
1515use crate::syntax_helpers::node_ext::vis_eq;
......@@ -39,8 +39,8 @@ impl MergeBehavior {
3939}
4040
4141/// Merge `rhs` into `lhs` keeping both intact.
42/// Returned AST is mutable.
4342pub fn try_merge_imports(
43 make: &SyntaxFactory,
4444 lhs: &ast::Use,
4545 rhs: &ast::Use,
4646 merge_behavior: MergeBehavior,
......@@ -53,39 +53,39 @@ pub fn try_merge_imports(
5353 return None;
5454 }
5555
56 let lhs = lhs.clone_subtree().clone_for_update();
57 let rhs = rhs.clone_subtree().clone_for_update();
5856 let lhs_tree = lhs.use_tree()?;
5957 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)?;
6159
6260 // 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);
6463
65 Some(lhs)
64 make_use_with_tree(lhs, use_tree)
6665}
6766
6867/// Merge `rhs` into `lhs` keeping both intact.
69/// Returned AST is mutable.
7068pub fn try_merge_trees(
69 make: &SyntaxFactory,
7170 lhs: &ast::UseTree,
7271 rhs: &ast::UseTree,
7372 merge: MergeBehavior,
7473) -> 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)?;
7875
7976 // 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))
8378}
8479
85fn try_merge_trees_mut(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior) -> Option<()> {
80fn 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> {
8686 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);
8989 } else {
9090 let lhs_path = lhs.path()?;
9191 let rhs_path = rhs.path()?;
......@@ -100,46 +100,53 @@ fn try_merge_trees_mut(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehav
100100 // and we can safely return here
101101 let lhs_name = lhs.rename().and_then(|lhs_name| lhs_name.name());
102102 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 {
104106 return None;
105107 }
106108
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);
110110 } 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)?;
113113 }
114114 }
115 recursive_merge(lhs, rhs, merge)
115 recursive_merge(lhs, rhs, merge, make)
116116}
117117
118118/// Recursively merges rhs to lhs
119119#[must_use]
120fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior) -> Option<()> {
120fn recursive_merge(
121 lhs: ast::UseTree,
122 rhs: ast::UseTree,
123 merge: MergeBehavior,
124 make: &SyntaxFactory,
125) -> Option<ast::UseTree> {
121126 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.
127131 .map(|tree| merge.is_tree_allowed(&tree).then_some(tree))
128132 .collect::<Option<_>>()?;
133
129134 // Sorts the use trees similar to rustfmt's algorithm for ordering imports
130135 // (see `use_tree_cmp` doc).
131136 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() {
133139 if !merge.is_tree_allowed(&rhs_t) {
134140 return None;
135141 }
136142
137143 match use_trees.binary_search_by(|lhs_t| use_tree_cmp_bin_search(lhs_t, &rhs_t)) {
138144 Ok(idx) => {
139 let lhs_t = &mut use_trees[idx];
145 let mut lhs_t = use_trees[idx].clone();
140146 let lhs_path = lhs_t.path()?;
141147 let rhs_path = rhs_t.path()?;
142148 let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?;
149
143150 if lhs_prefix == lhs_path && rhs_prefix == rhs_path {
144151 let tree_is_self = |tree: &ast::UseTree| {
145152 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)
157164 };
158165
159166 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;
162168 continue;
163169 }
164170
165 match (tree_contains_self(lhs_t), tree_contains_self(&rhs_t)) {
171 match (tree_contains_self(&lhs_t), tree_contains_self(&rhs_t)) {
166172 (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;
168175 continue;
169176 }
170177 (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;
174181 continue;
175182 }
176183 _ => (),
......@@ -180,9 +187,11 @@ fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior)
180187 continue;
181188 }
182189 }
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;
186195 }
187196 Err(_)
188197 if merge == MergeBehavior::Module
......@@ -192,15 +201,12 @@ fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior)
192201 return None;
193202 }
194203 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);
200205 }
201206 }
202207 }
203 Some(())
208
209 with_use_tree_list(&lhs, use_trees, make)
204210}
205211
206212/// Style to follow when normalizing a use tree.
......@@ -250,241 +256,216 @@ impl From<MergeBehavior> for NormalizationStyle {
250256/// - `foo::{bar::Qux, bar::{self}}` -> `{foo::bar::{self, Qux}}`
251257/// - `foo::bar::{self}` -> `{foo::bar}`
252258/// - `foo::bar` -> `{foo::bar}`
253pub 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)
259pub 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)
257267}
258268
259fn try_normalize_use_tree_mut(use_tree: &ast::UseTree, style: NormalizationStyle) -> Option<()> {
269fn try_normalize_use_tree(
270 use_tree: ast::UseTree,
271 style: NormalizationStyle,
272 make: &SyntaxFactory,
273) -> Option<ast::UseTree> {
260274 if style == NormalizationStyle::One {
275 let mut use_tree = use_tree;
261276 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;
267280 }
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);
270286 }
271 Some(())
287
288 recursive_normalize(use_tree, NormalizationStyle::Default, make)
272289}
273290
274291/// Recursively normalizes a use tree and its subtrees (if any).
275fn recursive_normalize(use_tree: &ast::UseTree, style: NormalizationStyle) -> Option<()> {
292fn recursive_normalize(
293 use_tree: ast::UseTree,
294 style: NormalizationStyle,
295 make: &SyntaxFactory,
296) -> Option<ast::UseTree> {
276297 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)
295320 {
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)
300345 {
301 ted::insert_raw(
302 Position::last_child_of(use_tree.syntax()),
303 make::token(T![::]),
304 );
346 merged = normalized;
305347 }
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;
306354 }
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
325355 }
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;
338371 }
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;
350383 }
351 } else {
352 // Tracks whether any changes have been made to the use tree.
353 let mut modified = false;
384 }
354385
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}
380388
381 if curr_skipped.is_empty() {
382 // Un-nesting is complete.
383 break;
384 }
385 prev_skipped = curr_skipped;
386 }
389fn 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();
387401
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);
398412 } else {
399 modified |= recursive_normalize(&subtree, NormalizationStyle::Default).is_some();
413 elements.push(sub_sub_tree);
400414 }
401415 }
402416
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}
431423
432 let (Some(next_anchor), true) = (next_anchor, !curr_skipped.is_empty()) else {
433 // Merging is complete.
434 break;
435 };
424fn 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 };
436438
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}
441449
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 }
450fn 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}
481455
482 if !modified {
483 // Either the use tree was already normalized or its semantically empty.
484 return None;
456fn 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))
485466 }
467 _ => Some(use_tree),
486468 }
487 Some(())
488469}
489470
490471/// 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
513494fn use_tree_cmp_bin_search(lhs: &ast::UseTree, rhs: &ast::UseTree) -> Ordering {
514495 let lhs_is_simple_path = lhs.is_simple_path() && lhs.rename().is_none();
515496 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) {
520500 (None, None) => match (lhs_is_simple_path, rhs_is_simple_path) {
521501 (true, true) => Ordering::Equal,
522502 (true, false) => Ordering::Less,
......@@ -701,14 +681,164 @@ fn get_single_subtree(use_tree: &ast::UseTree) -> Option<ast::UseTree> {
701681 .map(|(single_subtree,)| single_subtree)
702682}
703683
704fn 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 _ => (),
684fn 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
692fn 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
755fn 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
765fn 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
781fn 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
796pub(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;
711806 }
807
808 let list = make_use_tree_list(make, vec![use_tree.clone()], None)?;
809 make_use_tree_from_list(make, list)
810}
811
812fn 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))
712842}
713843
714844// 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 {
10251025 check_diagnostics(
10261026 r#"
10271027//- minicore: coerce_unsized, dispatch_from_dyn
1028#![feature(trait_upcasting)]
10291028trait Foo {}
10301029trait Bar: Foo {}
10311030
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs+24
......@@ -354,6 +354,30 @@ fn f() {
354354 )
355355 }
356356
357 #[test]
358 fn varargs_fn_pointer() {
359 check_diagnostics(
360 r#"
361struct Funcs {
362 f: unsafe extern "C" fn(u8, u8, ...) -> i32,
363 g: unsafe extern "C" fn(...) -> i32,
364}
365
366fn 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
357381 #[test]
358382 fn arg_count_lambda() {
359383 check_diagnostics(
src/tools/rust-analyzer/crates/ide/src/lib.rs+3-2
......@@ -60,6 +60,7 @@ mod view_mir;
6060mod view_syntax_tree;
6161
6262use std::panic::{AssertUnwindSafe, UnwindSafe};
63use std::time::Duration;
6364
6465use cfg::CfgOptions;
6566use fetch_crates::CrateInfo;
......@@ -197,8 +198,8 @@ impl AnalysisHost {
197198
198199 /// Applies changes to the current state of the world. If there are
199200 /// 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)
202203 }
203204
204205 /// NB: this clears the database
src/tools/rust-analyzer/crates/ide/src/navigation_target.rs-1
......@@ -50,7 +50,6 @@ pub struct NavigationTarget {
5050 pub kind: Option<SymbolKind>,
5151 pub container_name: Option<Symbol>,
5252 pub description: Option<String>,
53 // FIXME: Use the database lifetime here.
5453 pub docs: Option<Documentation<'static>>,
5554 /// In addition to a `name` field, a `NavigationTarget` may also be aliased
5655 /// 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
128128 <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>
129129 <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>
130130
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>
132132
133 <span class="variable callable">y</span><span class="semicolon">;</span>
133 <span class="variable">y</span><span class="semicolon">;</span>
134134
135135 <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>
136136 <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
143143 <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>
144144 <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>
145145
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>
147147 <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>
148148
149149 <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
173173<span class="brace">}</span>
174174
175175<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>
178178<span class="brace">}</span>
179179
180180<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>
181181 <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>
183183 <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>
184184<span class="brace">}</span>
185185
src/tools/rust-analyzer/crates/intern/Cargo.toml-1
......@@ -12,7 +12,6 @@ rust-version.workspace = true
1212[lib]
1313doctest = false
1414
15
1615[dependencies]
1716dashmap.workspace = true
1817# 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> {
3434 for item in storage {
3535 let item = item.key();
3636 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) {
4038 item.visit_with(gc);
4139 }
4240 }
......@@ -60,9 +58,7 @@ impl<T: SliceInternable + GcInternedSliceVisit> Storage for InternedSliceStorage
6058 for item in storage {
6159 let item = item.key();
6260 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) {
6662 T::visit_header(&item.header.header, gc);
6763 T::visit_slice(&item.slice, gc);
6864 }
......@@ -81,7 +77,7 @@ pub trait GcInternedVisit {
8177
8278pub trait GcInternedSliceVisit: SliceInternable {
8379 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);
8581}
8682
8783#[derive(Default)]
......@@ -103,11 +99,13 @@ impl GarbageCollector {
10399 self.storages.push(&InternedSliceStorage::<T>(PhantomData));
104100 }
105101
102 /// Collects unreachable GC-managed interned values.
103 ///
106104 /// # Safety
107105 ///
108106 /// - 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.
111109 /// - [`GcInternedVisit`] and [`GcInternedSliceVisit`] must mark all values reachable from the node.
112110 pub unsafe fn collect(mut self) {
113111 if cfg!(feature = "prevent-gc") {
......@@ -136,8 +134,9 @@ impl GarbageCollector {
136134 &mut self,
137135 interned: InternedRef<'_, T>,
138136 ) -> ControlFlow<()> {
137 const { assert!(T::USE_GC) };
138
139139 if interned.strong_count() > 1 {
140 // It will be visited anyway, so short-circuit
141140 return ControlFlow::Break(());
142141 }
143142 let addr = interned.as_raw().addr();
......@@ -148,8 +147,9 @@ impl GarbageCollector {
148147 &mut self,
149148 interned: InternedSliceRef<'_, T>,
150149 ) -> ControlFlow<()> {
150 const { assert!(T::USE_GC) };
151
151152 if interned.strong_count() > 1 {
152 // It will be visited anyway, so short-circuit
153153 return ControlFlow::Break(());
154154 }
155155 let addr = interned.as_raw().addr();
......@@ -240,7 +240,7 @@ mod tests {
240240 impl GcInternedSliceVisit for StringSlice {
241241 fn visit_header(_header: &Self::Header, _gc: &mut GarbageCollector) {}
242242
243 fn visit_slice(_header: &[Self::SliceType], _gc: &mut GarbageCollector) {}
243 fn visit_slice(_slice: &[Self::SliceType], _gc: &mut GarbageCollector) {}
244244 }
245245
246246 let (a, d) = {
......@@ -276,6 +276,10 @@ mod tests {
276276 gc.add_storage::<GcString>();
277277 unsafe { gc.collect() };
278278
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 }
279283 assert_eq!(a.0, "abc");
280284 assert_eq!(d.header.length, 2);
281285 assert_eq!(d.header.header, "abc");
......@@ -288,6 +292,11 @@ mod tests {
288292 gc.add_slice_storage::<StringSlice>();
289293 gc.add_storage::<GcString>();
290294 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 }
291300 }
292301
293302 #[test]
......@@ -309,7 +318,7 @@ mod tests {
309318 impl GcInternedSliceVisit for StringSlice {
310319 fn visit_header(_header: &Self::Header, _gc: &mut GarbageCollector) {}
311320
312 fn visit_slice(_header: &[Self::SliceType], _gc: &mut GarbageCollector) {}
321 fn visit_slice(_slice: &[Self::SliceType], _gc: &mut GarbageCollector) {}
313322 }
314323
315324 let outer = {
......@@ -322,6 +331,10 @@ mod tests {
322331 gc.add_storage::<GcInterned>();
323332 unsafe { gc.collect() };
324333
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 }
325338 assert_eq!(outer.0.header.header, "abc");
326339 assert_eq!(outer.0.slice, [123, 456, 789]);
327340
......@@ -331,5 +344,10 @@ mod tests {
331344 gc.add_slice_storage::<StringSlice>();
332345 gc.add_storage::<GcInterned>();
333346 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 }
334352 }
335353}
src/tools/rust-analyzer/crates/parser/src/output.rs+1-1
......@@ -18,7 +18,7 @@ pub struct Output {
1818 ///
1919 /// ```text
2020 /// |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover|
21 /// ``````
21 /// ```
2222 event: Vec<u32>,
2323 error: Vec<String>,
2424}
src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml+1-1
......@@ -29,7 +29,7 @@ line-index.workspace = true
2929proc-macro-test.path = "./proc-macro-test"
3030
3131[features]
32default = ["in-rust-tree"]
32default = []
3333in-rust-tree = []
3434
3535[lints]
src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs+1-1
......@@ -560,7 +560,7 @@ impl WorkspaceBuildScripts {
560560
561561// FIXME: Find a better way to know if it is a dylib.
562562fn 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()) {
564564 None => false,
565565 Some(ext) => matches!(ext.as_str(), "dll" | "dylib" | "so"),
566566 }
src/tools/rust-analyzer/crates/project-model/src/workspace.rs+10-3
......@@ -811,6 +811,7 @@ impl ProjectWorkspace {
811811 .packages()
812812 .map(|pkg| {
813813 let is_local = cargo[pkg].is_local;
814 let is_member = cargo[pkg].is_member;
814815 let pkg_root = cargo[pkg].manifest.parent().to_path_buf();
815816
816817 let mut include = vec![pkg_root.clone()];
......@@ -844,9 +845,11 @@ impl ProjectWorkspace {
844845 let mut exclude = vec![pkg_root.join(".git")];
845846 if is_local {
846847 include.extend(self.extra_includes.iter().cloned());
847
848848 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.
850853 exclude.push(pkg_root.join("tests"));
851854 exclude.push(pkg_root.join("examples"));
852855 exclude.push(pkg_root.join("benches"));
......@@ -874,6 +877,7 @@ impl ProjectWorkspace {
874877 .chain(cargo_script.iter().flat_map(|(cargo, build_scripts, _)| {
875878 cargo.packages().map(|pkg| {
876879 let is_local = cargo[pkg].is_local;
880 let is_member = cargo[pkg].is_member;
877881 let pkg_root = cargo[pkg].manifest.parent().to_path_buf();
878882
879883 let mut include = vec![pkg_root.clone()];
......@@ -909,7 +913,10 @@ impl ProjectWorkspace {
909913 include.extend(self.extra_includes.iter().cloned());
910914
911915 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.
913920 exclude.push(pkg_root.join("tests"));
914921 exclude.push(pkg_root.join("examples"));
915922 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 {
6464 fn new() -> Result<Self> {
6565 let mut path = AbsPathBuf::assert_utf8(std::env::temp_dir());
6666 path.push("ra-rustc-test");
67 std::fs::create_dir_all(&path)?;
6768 let tmp_file = path.join("ra-rustc-test.rs");
6869 std::fs::write(&tmp_file, "")?;
6970 let cargo_config = CargoConfig {
src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs+1-1
......@@ -237,7 +237,7 @@ impl flags::Scip {
237237 let token = si.tokens.get(id).unwrap();
238238
239239 let Some(definition) = token.definition else {
240 break;
240 continue;
241241 };
242242
243243 let file_id = definition.file_id;
src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs+9-2
......@@ -662,9 +662,12 @@ config_data! {
662662 /// For traits the type "methods" can be used to only exclude the methods but not the trait
663663 /// itself.
664664 ///
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
666666 /// itself. This does not include items defined in nested modules.
667667 ///
668 /// For enums the type "variants" can be used to only exclude the all variants in it but not the enum
669 /// itself.
670 ///
668671 /// This setting also inherits `#rust-analyzer.completion.excludeTraits#`.
669672 completion_autoimport_exclude: Vec<AutoImportExclusion> = vec![
670673 AutoImportExclusion::Verbose { path: "core::borrow::Borrow".to_owned(), r#type: AutoImportExclusionType::Methods },
......@@ -1944,6 +1947,9 @@ impl Config {
19441947 AutoImportExclusionType::SubItems => {
19451948 ide_completion::AutoImportExclusionType::SubItems
19461949 }
1950 AutoImportExclusionType::Variants => {
1951 ide_completion::AutoImportExclusionType::Variants
1952 }
19471953 },
19481954 ),
19491955 })
......@@ -3004,6 +3010,7 @@ pub enum AutoImportExclusionType {
30043010 Always,
30053011 Methods,
30063012 SubItems,
3013 Variants,
30073014}
30083015
30093016#[derive(Serialize, Deserialize, Debug, Clone)]
......@@ -4135,7 +4142,7 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
41354142 },
41364143 "type": {
41374144 "type": "string",
4138 "enum": ["always", "methods", "subItems"],
4145 "enum": ["always", "methods", "sub_items", "variants"],
41394146 "enumDescriptions": [
41404147 "Do not show this item or its methods (if it is a trait) in auto-import completions.",
41414148 "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 {
330330 this
331331 }
332332
333 pub(crate) fn process_changes(&mut self) -> bool {
333 pub(crate) fn process_changes(&mut self) -> (bool, Option<Duration>) {
334334 let _p = span!(Level::INFO, "GlobalState::process_changes").entered();
335335 // We cannot directly resolve a change in a ratoml file to a format
336336 // that can be used by the config module because config talks
......@@ -343,7 +343,7 @@ impl GlobalState {
343343 let mut guard = self.vfs.write();
344344 let changed_files = guard.0.take_changes();
345345 if changed_files.is_empty() {
346 return false;
346 return (false, None);
347347 }
348348
349349 let (change, modified_rust_files, workspace_structure_change) =
......@@ -439,7 +439,7 @@ impl GlobalState {
439439 (change, modified_rust_files, workspace_structure_change)
440440 });
441441
442 self.analysis_host.apply_change(change);
442 let cancellation_time = self.analysis_host.apply_change(change);
443443
444444 if !modified_ratoml_files.is_empty()
445445 || !self.config.same_source_root_parent_map(&self.local_roots_parent_map)
......@@ -561,7 +561,7 @@ impl GlobalState {
561561 }
562562 }
563563
564 true
564 (true, Some(cancellation_time))
565565 }
566566
567567 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 {
307307 let _p = tracing::info_span!("GlobalState::handle_event", event = %event).entered();
308308
309309 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");
317311
318312 let was_quiescent = self.is_quiescent();
313
314 let mut cancellation_time = None;
319315 match event {
320316 Event::Lsp(msg) => match msg {
321317 lsp_server::Message::Request(req) => self.on_new_request(loop_start, req),
......@@ -326,7 +322,9 @@ impl GlobalState {
326322 let _p = tracing::info_span!("GlobalState::handle_event/queued_task").entered();
327323 self.handle_deferred_task(task);
328324 // 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 {
330328 self.handle_deferred_task(task);
331329 }
332330 }
......@@ -334,14 +332,16 @@ impl GlobalState {
334332 let _p = tracing::info_span!("GlobalState::handle_event/task").entered();
335333 let mut prime_caches_progress = Vec::new();
336334
337 self.handle_task(&mut prime_caches_progress, task);
335 cancellation_time = self.handle_task(&mut prime_caches_progress, task);
338336 // 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 {
340340 self.handle_task(&mut prime_caches_progress, task);
341341 }
342342
343343 let title = "Indexing";
344 let cancel_token = Some("rustAnalyzer/cachePriming".to_owned());
344 let cancel_token = || Some("rustAnalyzer/cachePriming".to_owned());
345345
346346 let mut last_report = None;
347347 for progress in prime_caches_progress {
......@@ -352,7 +352,7 @@ impl GlobalState {
352352 Progress::Begin,
353353 None,
354354 Some(0.0),
355 cancel_token.clone(),
355 cancel_token(),
356356 );
357357 }
358358 PrimeCachesProgress::Report(report) => {
......@@ -387,6 +387,16 @@ impl GlobalState {
387387 if cancelled {
388388 self.prime_caches_queue
389389 .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));
390400 }
391401 if let Some((message, fraction, title)) = last_report.take() {
392402 self.report_progress(
......@@ -394,7 +404,7 @@ impl GlobalState {
394404 Progress::Report,
395405 message,
396406 Some(fraction),
397 cancel_token.clone(),
407 cancel_token(),
398408 );
399409 }
400410 self.report_progress(
......@@ -402,7 +412,7 @@ impl GlobalState {
402412 Progress::End,
403413 None,
404414 Some(1.0),
405 cancel_token.clone(),
415 cancel_token(),
406416 );
407417 }
408418 };
......@@ -413,7 +423,7 @@ impl GlobalState {
413423 Progress::Report,
414424 message,
415425 Some(fraction),
416 cancel_token.clone(),
426 cancel_token(),
417427 );
418428 }
419429 }
......@@ -422,7 +432,9 @@ impl GlobalState {
422432 let mut last_progress_report = None;
423433 self.handle_vfs_msg(message, &mut last_progress_report);
424434 // 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 {
426438 self.handle_vfs_msg(message, &mut last_progress_report);
427439 }
428440 if let Some((message, fraction)) = last_progress_report {
......@@ -439,7 +451,9 @@ impl GlobalState {
439451 let mut cargo_finished = false;
440452 self.handle_flycheck_msg(message, &mut cargo_finished);
441453 // 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 {
443457 self.handle_flycheck_msg(message, &mut cargo_finished);
444458 }
445459 if cargo_finished {
......@@ -453,14 +467,18 @@ impl GlobalState {
453467 let _p = tracing::info_span!("GlobalState::handle_event/test_result").entered();
454468 self.handle_cargo_test_msg(message);
455469 // 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 {
457473 self.handle_cargo_test_msg(message);
458474 }
459475 }
460476 Event::DiscoverProject(message) => {
461477 self.handle_discover_msg(message);
462478 // 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 {
464482 self.handle_discover_msg(message);
465483 }
466484 }
......@@ -469,26 +487,29 @@ impl GlobalState {
469487 }
470488 }
471489 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,
479507 };
480508
481509 let mut gc_elapsed = None;
482510 if self.is_quiescent() {
483511 let became_quiescent = !was_quiescent;
484512 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 }
492513 // delay initial cache priming until proc macros are loaded, or we will load up a bunch of garbage into salsa
493514 let proc_macros_loaded = self.config.prefill_caches()
494515 && (!self.config.expand_proc_macros()
......@@ -496,6 +517,19 @@ impl GlobalState {
496517 if proc_macros_loaded {
497518 self.prime_caches_queue.request_op("became quiescent".to_owned(), ());
498519 }
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 }
499533 }
500534
501535 let client_refresh = became_quiescent || state_changed;
......@@ -593,11 +627,13 @@ impl GlobalState {
593627 tracing::warn!(
594628 "overly long loop turn took {loop_duration:?}:\n\
595629 (event handling took {event_handling_duration:?}): {event_dbg_msg}\n\
630 (cancellation took {cancellation_time:?})
596631 (garbage collection took {gc_elapsed:?})"
597632 );
598633 self.poke_rust_analyzer_developer(format!(
599634 "overly long loop turn took {loop_duration:?}:\n\
600635 (event handling took {event_handling_duration:?}): {event_dbg_msg}\n\
636 (cancellation took {cancellation_time:?})
601637 (garbage collection took {gc_elapsed:?})"
602638 ));
603639 }
......@@ -803,7 +839,12 @@ impl GlobalState {
803839 }
804840 }
805841
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;
807848 match task {
808849 Task::Response(response) => self.respond(response),
809850 // Only retry requests that haven't been cancelled. Otherwise we do unnecessary work.
......@@ -906,8 +947,9 @@ impl GlobalState {
906947 ProcMacroProgress::Report(msg) => (Some(Progress::Report), Some(msg)),
907948 ProcMacroProgress::End(change) => {
908949 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();
911953 (Some(Progress::End), None)
912954 }
913955 };
......@@ -921,6 +963,7 @@ impl GlobalState {
921963 self.send_notification::<lsp_ext::DiscoveredTests>(tests);
922964 }
923965 }
966 cancellation_time
924967 }
925968
926969 fn handle_vfs_msg(
src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs+22-22
......@@ -13,7 +13,7 @@
1313//! project is currently loading and we don't have a full project model, we
1414//! still want to respond to various requests.
1515// FIXME: This is a mess that needs some untangling work
16use std::{iter, mem, sync::atomic::AtomicUsize};
16use std::{iter, mem, sync::atomic::AtomicUsize, time::Duration};
1717
1818use hir::{ChangeWithProcMacros, ProcMacrosBuilder, db::DefDatabase};
1919use ide_db::{
......@@ -468,25 +468,22 @@ impl GlobalState {
468468 });
469469 }
470470
471 pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
471 pub(crate) fn switch_workspaces(&mut self, cause: Cause) -> Option<Duration> {
472472 let _p = tracing::info_span!("GlobalState::switch_workspaces").entered();
473473 tracing::info!(%cause, "will switch workspaces");
474474
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()?;
480477 let switching_from_empty_workspace = self.workspaces.is_empty();
481478
482479 info!(%cause, ?force_crate_graph_reload, %switching_from_empty_workspace);
483480 if self.fetch_workspace_error().is_err() && !switching_from_empty_workspace {
484481 if *force_crate_graph_reload {
485 self.recreate_crate_graph(cause, false);
482 return self.recreate_crate_graph(cause, false);
486483 }
487484 // It only makes sense to switch to a partially broken workspace
488485 // if we don't have any workspace at all yet.
489 return;
486 return None;
490487 }
491488
492489 let workspaces =
......@@ -501,7 +498,7 @@ impl GlobalState {
501498 if same_workspaces {
502499 if switching_from_empty_workspace {
503500 // Switching from empty to empty is a no-op
504 return;
501 return None;
505502 }
506503 if let Some(FetchBuildDataResponse { workspaces, build_scripts }) =
507504 self.fetch_build_data_queue.last_op_result()
......@@ -524,20 +521,20 @@ impl GlobalState {
524521 } else {
525522 info!("build scripts do not match the version of the active workspace");
526523 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);
528525 }
529526
530527 // Current build scripts do not match the version of the active
531528 // workspace, so there's nothing for us to update.
532 return;
529 return None;
533530 }
534531 } else {
535532 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);
537534 }
538535
539536 // No build scripts but unchanged workspaces, nothing to do here
540 return;
537 return None;
541538 }
542539 } else {
543540 info!("abandon build scripts for workspaces");
......@@ -560,7 +557,7 @@ impl GlobalState {
560557 // `switch_workspaces()` will be called again when build scripts already run, which should
561558 // take a short time. If we update the workspace now we will invalidate proc macros and cfgs,
562559 // and then when build scripts complete we will invalidate them again.
563 return;
560 return None;
564561 }
565562 }
566563 }
......@@ -733,13 +730,15 @@ impl GlobalState {
733730 self.local_roots_parent_map = Arc::new(self.source_root_config.source_root_parent_map());
734731
735732 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);
737734
738735 info!("did switch workspaces");
736 cancellation_time
739737 }
740738
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> {
742740 info!(?cause, "Building Crate Graph");
741 let mut cancellation_time = None;
743742 self.report_progress(
744743 "Building CrateGraph",
745744 crate::lsp::utils::Progress::Begin,
......@@ -795,9 +794,8 @@ impl GlobalState {
795794 }
796795
797796 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();
801799 } else {
802800 change.set_crate_graph(crate_graph);
803801 self.fetch_proc_macros_queue.request_op(cause, (change, proc_macro_paths));
......@@ -810,11 +808,13 @@ impl GlobalState {
810808 None,
811809 None,
812810 );
811 cancellation_time
813812 }
814813
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();
817816 self.reload_flycheck();
817 cancellation_time
818818 }
819819
820820 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 {
153153 Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => {
154154 config.test_command
155155 }
156 Some(CargoTargetSpec { target_kind: TargetKind::Bench, .. }) => {
157 config.bench_command
158 }
156159 _ => "run".to_owned(),
157160 };
158161 cargo_args.push(subcommand);
......@@ -225,6 +228,9 @@ impl CargoTargetSpec {
225228 Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => {
226229 (config.test_override_command, None)
227230 }
231 Some(CargoTargetSpec { target_kind: TargetKind::Bench, .. }) => {
232 (config.bench_override_command, None)
233 }
228234 _ => (None, None),
229235 },
230236 };
......@@ -319,7 +325,11 @@ impl CargoTargetSpec {
319325
320326 pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) {
321327 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 }
323333
324334 // Can't mix --doc with other target flags
325335 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> {
4040 })
4141 }
4242
43 pub(crate) fn len(&self) -> usize {
44 self.pool.len()
45 }
46
4743 pub(crate) fn is_empty(&self) -> bool {
4844 self.pool.is_empty()
4945 }
src/tools/rust-analyzer/crates/syntax/src/ast.rs-1
......@@ -1,7 +1,6 @@
11//! Abstract Syntax Tree, layered on top of untyped `SyntaxNode`s
22
33pub mod edit;
4pub mod edit_in_place;
54mod expr_ext;
65mod generated;
76pub mod make;
src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs+130-1
......@@ -13,7 +13,7 @@ use crate::{
1313 SyntaxKind::{ATTR, COMMENT, WHITESPACE},
1414 SyntaxNode, SyntaxToken,
1515 ast::{self, AstNode, HasName, make},
16 syntax_editor::{Position, SyntaxEditor, SyntaxMappingBuilder},
16 syntax_editor::{Position, Removable, SyntaxEditor, SyntaxMappingBuilder},
1717};
1818
1919use super::syntax_factory::SyntaxFactory;
......@@ -263,6 +263,109 @@ pub fn indent(node: &SyntaxNode, level: IndentLevel) -> SyntaxNode {
263263 level.clone_increase_indent(node)
264264}
265265
266impl 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
286impl 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
348impl 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
266369#[test]
267370fn test_increase_indent() {
268371 let arm_list = {
......@@ -285,3 +388,29 @@ fn test_increase_indent() {
285388 }"
286389 );
287390}
391
392#[test]
393fn split_prefix_inserts_self() {
394 check_split_prefix("use foo;", "foo::{self}");
395}
396
397#[test]
398fn split_prefix_preserves_rename() {
399 check_split_prefix("use foo as bar;", "foo::{self as bar}");
400}
401
402#[test]
403fn split_prefix_wraps_glob() {
404 check_split_prefix("use foo::*;", "foo::{*}");
405}
406
407#[cfg(test)]
408fn 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
3use std::iter::{empty, once, successors};
4
5use parser::T;
6
7use crate::{
8 AstNode, AstToken, Direction,
9 algo::{self, neighbor},
10 ast::{self, make, syntax_factory::SyntaxFactory},
11 syntax_editor::SyntaxEditor,
12 ted,
13};
14
15use super::HasName;
16
17impl 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
37pub trait Removable: AstNode {
38 fn remove(&self);
39}
40
41impl 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
58impl 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
221impl 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
244impl 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
289impl 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
299impl 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 {
264264 return false;
265265 }
266266
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
267275 let (left, right, inv) = match self.is_ordered_before_parent_in_place_of(parent, place_of) {
268276 true => (self, parent, false),
269277 false => (parent, self, true),
......@@ -551,4 +559,19 @@ impl Expr {
551559 ForExpr(_) | IfExpr(_) | MatchExpr(_) | WhileExpr(_) | IncludeBytesExpr(_) => true,
552560 }
553561 }
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 }
554577}
src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs+31-2
......@@ -4,8 +4,8 @@ use either::Either;
44use crate::{
55 AstNode, Edition, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken,
66 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,
99 },
1010 syntax_editor::SyntaxMappingBuilder,
1111};
......@@ -2015,6 +2015,35 @@ impl SyntaxFactory {
20152015 make::assoc_item_list(None).clone_for_update()
20162016 }
20172017
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
20182047 pub fn attr_outer(&self, meta: ast::Meta) -> ast::Attr {
20192048 let ast = make::attr_outer(meta.clone()).clone_for_update();
20202049
src/tools/rust-analyzer/crates/syntax/src/lib.rs-1
......@@ -39,7 +39,6 @@ pub mod ast;
3939pub mod fuzz;
4040pub mod hacks;
4141pub mod syntax_editor;
42pub mod ted;
4342pub mod utils;
4443
4544use 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 {
459459 if let Some(next_ws) = next_ws {
460460 let ws_text = next_ws.syntax().text();
461461 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 {
463470 editor.delete(next_ws.syntax());
464471 } else {
465472 editor.replace(next_ws.syntax(), make.whitespace(rest));
466473 }
467474 }
468475 }
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 }
469491
470492 editor.delete(self.syntax());
471493 }
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.
5use std::{mem, ops::RangeInclusive};
6
7use parser::T;
8use rowan::TextSize;
9
10use 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.
17pub trait Element {
18 fn syntax_element(self) -> SyntaxElement;
19}
20
21impl<E: Element + Clone> Element for &'_ E {
22 fn syntax_element(self) -> SyntaxElement {
23 self.clone().syntax_element()
24 }
25}
26impl Element for SyntaxElement {
27 fn syntax_element(self) -> SyntaxElement {
28 self
29 }
30}
31impl Element for SyntaxNode {
32 fn syntax_element(self) -> SyntaxElement {
33 self.into()
34 }
35}
36impl Element for SyntaxToken {
37 fn syntax_element(self) -> SyntaxElement {
38 self.into()
39 }
40}
41
42#[derive(Debug)]
43pub struct Position {
44 repr: PositionRepr,
45}
46
47#[derive(Debug)]
48enum PositionRepr {
49 FirstChild(SyntaxNode),
50 After(SyntaxElement),
51}
52
53impl 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
86pub fn insert(position: Position, elem: impl Element) {
87 insert_all(position, vec![elem.syntax_element()]);
88}
89pub fn insert_raw(position: Position, elem: impl Element) {
90 insert_all_raw(position, vec![elem.syntax_element()]);
91}
92pub 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}
105pub 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
113pub fn remove(elem: impl Element) {
114 elem.syntax_element().detach();
115}
116pub fn remove_all(range: RangeInclusive<SyntaxElement>) {
117 replace_all(range, Vec::new());
118}
119pub 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
134pub fn replace(old: impl Element, new: impl Element) {
135 replace_with_many(old, vec![new.syntax_element()]);
136}
137pub fn replace_with_many(old: impl Element, new: Vec<SyntaxElement>) {
138 let old = old.syntax_element();
139 replace_all(old.clone()..=old, new);
140}
141pub 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
148pub fn append_child(node: &(impl Into<SyntaxNode> + Clone), child: impl Element) {
149 let position = Position::last_child_of(node);
150 insert(position, child);
151}
152pub 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
157pub 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
162fn 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}
188fn 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}
195fn 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
1313doctest = false
1414
1515[dependencies]
16home = "0.5.11"
1716camino.workspace = true
1817
1918[lints]
src/tools/rust-analyzer/crates/toolchain/src/lib.rs+1-1
......@@ -119,7 +119,7 @@ fn get_cargo_home() -> Option<Utf8PathBuf> {
119119 return Utf8PathBuf::try_from(PathBuf::from(path)).ok();
120120 }
121121
122 if let Some(mut path) = home::home_dir() {
122 if let Some(mut path) = env::home_dir() {
123123 path.push(".cargo");
124124 return Utf8PathBuf::try_from(path).ok();
125125 }
src/tools/rust-analyzer/docs/book/src/configuration_generated.md+4-1
......@@ -446,9 +446,12 @@ verbose form `{ "path": "path::to::item", type: "always" }`.
446446For traits the type "methods" can be used to only exclude the methods but not the trait
447447itself.
448448
449For modules the type "subItems" can be used to only exclude the all items in it but not the module
449For modules the type "sub_items" can be used to only exclude the all items in it but not the module
450450itself. This does not include items defined in nested modules.
451451
452For enums the type "variants" can be used to only exclude the all variants in it but not the enum
453itself.
454
452455This setting also inherits `#rust-analyzer.completion.excludeTraits#`.
453456
454457
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:
206206cargo run --release -p rust-analyzer -- analysis-stats ../chalk/
207207```
208208
209For measuring time of incremental analysis, use either of these:
210
211```bash
212cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --highlight ../chalk/chalk-engine/src/logic.rs
213cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --complete ../chalk/chalk-engine/src/logic.rs:94:0
214```
215
216209Look for `fn benchmark_xxx` tests for a quick way to reproduce performance problems.
217210
218211## Release Process
src/tools/rust-analyzer/editors/code/package.json+43-2
......@@ -214,6 +214,11 @@
214214 "title": "Reload workspace",
215215 "category": "rust-analyzer"
216216 },
217 {
218 "command": "rust-analyzer.newProject",
219 "title": "Create New Project...",
220 "category": "rust-analyzer"
221 },
217222 {
218223 "command": "rust-analyzer.rebuildProcMacros",
219224 "title": "Rebuild proc macros and build scripts",
......@@ -491,6 +496,23 @@
491496 "markdownDescription": "Do not start rust-analyzer server when the extension is activated.",
492497 "default": false,
493498 "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"
494516 }
495517 }
496518 },
......@@ -1333,7 +1355,7 @@
13331355 "title": "Completion",
13341356 "properties": {
13351357 "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#`.",
13371359 "default": [
13381360 {
13391361 "path": "core::borrow::Borrow",
......@@ -1361,7 +1383,8 @@
13611383 "enum": [
13621384 "always",
13631385 "methods",
1364 "subItems"
1386 "sub_items",
1387 "variants"
13651388 ],
13661389 "enumDescriptions": [
13671390 "Do not show this item or its methods (if it is a trait) in auto-import completions.",
......@@ -3811,6 +3834,9 @@
38113834 "command": "rust-analyzer.memoryUsage",
38123835 "when": "inRustProject"
38133836 },
3837 {
3838 "command": "rust-analyzer.newProject"
3839 },
38143840 {
38153841 "command": "rust-analyzer.reloadWorkspace",
38163842 "when": "inRustProject"
......@@ -3930,6 +3956,13 @@
39303956 }
39313957 ]
39323958 },
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 ],
39333966 "viewsContainers": {
39343967 "activitybar": [
39353968 {
......@@ -3955,6 +3988,14 @@
39553988 "title": "Learn about rust-analyzer",
39563989 "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.",
39573990 "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 },
39583999 {
39594000 "id": "setup",
39604001 "title": "Useful Setup Tips",
src/tools/rust-analyzer/editors/code/src/commands.ts+1
......@@ -33,6 +33,7 @@ import { log } from "./util";
3333import type { SyntaxElement } from "./syntax_tree_provider";
3434
3535export * from "./run";
36export { newProject } from "./new_project";
3637
3738export function analyzerStatus(ctx: CtxInit): Cmd {
3839 const tdcp = new (class implements vscode.TextDocumentContentProvider {
src/tools/rust-analyzer/editors/code/src/config.ts+4
......@@ -447,6 +447,10 @@ export class Config {
447447 return this.get<boolean>("initializeStopped");
448448 }
449449
450 get projectCreationOpenAfterCreate() {
451 return this.get<string>("projectCreation.openAfterCreate");
452 }
453
450454 get askBeforeUpdateTest() {
451455 return this.get<boolean>("runnables.askBeforeUpdateTest");
452456 }
src/tools/rust-analyzer/editors/code/src/main.ts+6
......@@ -161,6 +161,12 @@ function createCommands(): Record<string, CommandFactory> {
161161 memoryUsage: { enabled: commands.memoryUsage },
162162 reloadWorkspace: { enabled: commands.reloadWorkspace },
163163 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 },
164170 matchingBrace: { enabled: commands.matchingBrace },
165171 joinLines: { enabled: commands.joinLines },
166172 parentModule: { enabled: commands.parentModule },
src/tools/rust-analyzer/editors/code/src/new_project.ts created+311
......@@ -0,0 +1,311 @@
1import * as vscode from "vscode";
2
3import type { Ctx, Cmd } from "./ctx";
4import * as ra from "./lsp_ext";
5import { cargoPath } from "./toolchain";
6import { log, spawnAsync } from "./util";
7
8type NewProjectKind = "bin" | "lib";
9type NewProjectOpenAction = "open" | "openNewWindow" | "addToWorkspace";
10
11type NewProjectTemplate = {
12 detail: string;
13 id: NewProjectKind;
14 label: string;
15};
16
17type NewProjectCargo = {
18 cargo: string;
19 cargoEnv: NodeJS.ProcessEnv;
20};
21
22const 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
35export 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
77async 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
84async 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
91async 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
105const 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.
109export 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
132async 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
150export function cargoNewArgs(kind: NewProjectKind, name: string): string[] {
151 return ["new", kind === "bin" ? "--bin" : "--lib", name];
152}
153
154async 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
190function 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
197async 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
238export 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
255async 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
284async 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";
33import * as path from "path";
44import * as readline from "readline";
55import * as vscode from "vscode";
6import { Env, log, memoizeAsync, unwrapUndefinable } from "./util";
6import { Env, isWindows, log, memoizeAsync, unwrapUndefinable } from "./util";
77import type { CargoRunnableArgs } from "./lsp_ext";
88
99interface CompilationArtifact {
......@@ -160,9 +160,46 @@ export function cargoPath(env?: Env): Promise<string> {
160160 if (env?.["RUSTC_TOOLCHAIN"]) {
161161 return Promise.resolve("cargo");
162162 }
163 if (env) {
164 return getPathForExecutableWithEnv("cargo", env);
165 }
163166 return getPathForExecutable("cargo");
164167}
165168
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 */
177async 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
166203/** Mirrors `toolchain::get_path_for_executable()` implementation */
167204const getPathForExecutable = memoizeAsync(
168205 // We apply caching to decrease file-system interactions
......@@ -172,23 +209,22 @@ const getPathForExecutable = memoizeAsync(
172209 if (envVar) return envVar;
173210 }
174211
175 if (await lookupInPath(executableName)) return executableName;
212 if (await lookupInPath(executableName, process.env["PATH"] ?? "")) return executableName;
176213
177214 const cargoHome = getCargoHome();
178215 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 }
181220 }
182221 return executableName;
183222 },
184223);
185224
186async function lookupInPath(exec: string): Promise<boolean> {
187 const paths = process.env["PATH"] ?? "";
188
225async function lookupInPath(exec: string, paths: string): Promise<boolean> {
189226 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));
192228 });
193229
194230 for await (const isFile of candidates.map(isFileAtPath)) {
......@@ -199,8 +235,28 @@ async function lookupInPath(exec: string): Promise<boolean> {
199235 return false;
200236}
201237
238function 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
245function 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
202254function getCargoHome(): vscode.Uri | null {
203255 const envVar = process.env["CARGO_HOME"];
256 return getCargoHomeFromPath(envVar);
257}
258
259function getCargoHomeFromPath(envVar: string | undefined): vscode.Uri | null {
204260 if (envVar) return vscode.Uri.file(envVar);
205261
206262 try {
src/tools/rust-analyzer/editors/code/src/util.ts+5-1
......@@ -22,6 +22,10 @@ class Log {
2222 log: true,
2323 });
2424
25 show(): void {
26 this.output.show(true);
27 }
28
2529 trace(...messages: [unknown, ...unknown[]]): void {
2630 this.output.trace(this.stringify(messages));
2731 }
......@@ -40,7 +44,7 @@ class Log {
4044
4145 error(...messages: [unknown, ...unknown[]]): void {
4246 this.output.error(this.stringify(messages));
43 this.output.show(true);
47 this.show();
4448 }
4549
4650 private stringify(messages: unknown[]): string {
src/tools/rust-analyzer/editors/code/tests/unit/commands.test.ts created+80
......@@ -0,0 +1,80 @@
1import * as assert from "node:assert/strict";
2
3import {
4 cargoNewArgs,
5 determineNewProjectOpenAction,
6 validateNewProjectName,
7} from "../../src/new_project";
8import type { Context } from ".";
9
10export 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 @@
11import * as assert from "assert";
2import { Cargo } from "../../src/toolchain";
2import * as os from "os";
3import * as path from "path";
4import { mkdtemp, mkdir, rm, writeFile } from "fs/promises";
5import { Cargo, cargoPath } from "../../src/toolchain";
6import { isWindows, normalizeDriveLetter } from "../../src/util";
37import type { Context } from ".";
48
59export async function getTests(ctx: Context) {
......@@ -96,4 +100,47 @@ export async function getTests(ctx: Context) {
96100 assert.notDeepStrictEqual(args.filter, undefined);
97101 });
98102 });
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
142function 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);
99146}
src/tools/rust-analyzer/editors/code/walkthrough-create-project.md created+9
......@@ -0,0 +1,9 @@
1# Create a New Cargo Project
2
3Create a new Cargo project without leaving VS Code.
4
5The command lets you choose the package kind, parent folder, project name, and
6how the new project should be opened afterward.
7
8The project is created with Cargo, so the generated files and defaults match
9the normal `cargo new` experience.
src/tools/rust-analyzer/rust-version+1-1
......@@ -1 +1 @@
1029c9e18dd1f4668e1d42bb187c1c263dfe20093
1942ac9ce4116d4ea784c9882659372b34978b1f8
tests/pretty/delegation-self-rename.pp+8-5
......@@ -19,15 +19,18 @@ impl <'a, A, const B: bool> Trait<'a, A, B> for X { }
1919#[attr = Inline(Hint)]
2020fn foo<'a, Self, A, const B: _, const B2: _, T, U,
2121 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) }
2323#[attr = Inline(Hint)]
2424fn 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}
2629
2730#[attr = Inline(Hint)]
2831fn foo2<'a, This, A, const B: _, const B2: _, T, U,
2932 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) }
3134#[attr = Inline(Hint)]
3235fn bar2<This, impl FnOnce() -> usize>(arg0: _, arg1: _)
3336 -> _ { bar::<This>(arg0, arg1) }
......@@ -36,7 +39,7 @@ trait Trait2 {
3639 #[attr = Inline(Hint)]
3740 fn foo3<'a, This, A, const B: _, const B2: _, T, U,
3841 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) }
4043 #[attr = Inline(Hint)]
4144 fn bar3<This, impl FnOnce() -> usize>(arg0: _, arg1: _)
4245 -> _ { bar2::<This>(arg0, arg1) }
......@@ -47,7 +50,7 @@ impl Trait2 for () { }
4750#[attr = Inline(Hint)]
4851fn foo4<'a, This, A, const B: _, const B2: _, T, U,
4952 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) }
5154#[attr = Inline(Hint)]
5255fn bar4<This, impl FnOnce() -> usize>(arg0: _, arg1: _)
5356 -> _ { <() 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)]
10fn 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)]
8fn 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
4trait 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
15impl<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
23fn 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
7use std::marker::PhantomData;
8
9pub struct Handle<T, I>(T, I);
10
11impl<T, I> Handle<T, I> {
12 pub fn get_info(&self) -> &I {
13 let Handle(_, ref info) = *self;
14 info
15 }
16}
17
18pub struct BufferHandle<D: Device, T> {
19 raw: RawBufferHandle<D>,
20 _marker: PhantomData<T>,
21}
22
23impl<D: Device, T> BufferHandle<D, T> {
24 pub fn get_info(&self) -> &String {
25 self.raw.get_info()
26 }
27}
28
29pub type RawBufferHandle<D: Device> = Handle<<D as Device>::Buffer, String>;
30
31pub trait Device {
32 type Buffer;
33}
34
35fn 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
14fn 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
22struct Newtype(Option<Box<usize>>);
23
24impl<'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
32fn main() { }
tests/ui/associated-types/associated-type-unconstrained-lifetime.stderr created+16
......@@ -0,0 +1,16 @@
1error[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 |
4LL | impl<'a> Iterator for Newtype {
5 | ^^ unconstrained lifetime parameter
6 |
7help: use the lifetime parameter `'a` in the `Newtype` type and use it in the type definition
8 |
9LL ~ struct Newtype<'a>(Option<Box<usize>>);
10LL |
11LL ~ impl<'a> Iterator for Newtype<'a> {
12 |
13
14error: aborting due to 1 previous error
15
16For 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
8use std::borrow::{ToOwned, Cow};
9
10fn assert_send<T: Send>(_: T) {}
11
12fn 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
4use std::ops::Add;
5
6fn f<T: Add>(a: T, b: T) -> <T as Add>::Output {
7 a + b
8}
9
10fn 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
4trait Expr: PartialEq<Self::Item> {
5 type Item;
6}
7
8fn 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
14trait 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
21fn main() {}
tests/ui/assumptions_on_binders/non_lifetime_binder_alias_outlives.stderr created+20
......@@ -0,0 +1,20 @@
1error[E0284]: type annotations needed: cannot satisfy `<T as Trait>::Assoc: 'static`
2 --> $DIR/non_lifetime_binder_alias_outlives.rs:16:5
3 |
4LL | / type Ref
5LL | | where
6LL | | for<T> T: Trait<Assoc: 'static>;
7 | |________________________________________^ cannot satisfy `<T as Trait>::Assoc: 'static`
8 |
9note: required by a bound in `Trait::Ref`
10 --> $DIR/non_lifetime_binder_alias_outlives.rs:18:32
11 |
12LL | type Ref
13 | --- required by a bound in this associated type
14LL | where
15LL | for<T> T: Trait<Assoc: 'static>;
16 | ^^^^^^^ required by this bound in `Trait::Ref`
17
18error: aborting due to 1 previous error
19
20For 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
13struct Parent<'a> {
14 a: &'a str,
15}
16
17impl<'a> Parent<'a> {
18 type const CT<T: 'a>: usize = 0;
19}
20
21fn check()
22where
23 [(); Parent::CT::<T>]:,
24 //~^ ERROR cannot find type `T` in this scope
25{
26}
27
28fn main() {}
tests/ui/assumptions_on_binders/resolved-region-var-max-universe.stderr created+14
......@@ -0,0 +1,14 @@
1error[E0425]: cannot find type `T` in this scope
2 --> $DIR/resolved-region-var-max-universe.rs:23:23
3 |
4LL | [(); Parent::CT::<T>]:,
5 | ^ not found in this scope
6 |
7help: you might be missing a type parameter
8 |
9LL | fn check<T>()
10 | +++
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0425`.
tests/ui/attributes/invalid-crate-type.rs+49
......@@ -1,5 +1,8 @@
11// regression test for issue 11256
22#![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
36
47// Tests for suggestions (#53958)
58
......@@ -43,6 +46,52 @@
4346//~| HELP did you mean
4447//~| SUGGESTION cdylib
4548
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
4695fn main() {
4796 return
4897}
tests/ui/attributes/invalid-crate-type.stderr+64-10
......@@ -2,57 +2,111 @@ error: invalid `crate_type` value
22 --> $DIR/invalid-crate-type.rs:2:15
33 |
44LL | #![crate_type="foo"]
5 | ^^^^^
5 | ^^^^^ help: did you mean: `"lib"`
66 |
77 = note: `#[deny(unknown_crate_types)]` on by default
88
99error: invalid `crate_type` value
10 --> $DIR/invalid-crate-type.rs:6:15
10 --> $DIR/invalid-crate-type.rs:9:15
1111 |
1212LL | #![crate_type="statoclib"]
1313 | ^^^^^^^^^^^ help: did you mean: `"staticlib"`
1414
1515error: invalid `crate_type` value
16 --> $DIR/invalid-crate-type.rs:11:15
16 --> $DIR/invalid-crate-type.rs:14:15
1717 |
1818LL | #![crate_type="procmacro"]
1919 | ^^^^^^^^^^^ help: did you mean: `"proc-macro"`
2020
2121error: invalid `crate_type` value
22 --> $DIR/invalid-crate-type.rs:16:15
22 --> $DIR/invalid-crate-type.rs:19:15
2323 |
2424LL | #![crate_type="static-lib"]
2525 | ^^^^^^^^^^^^ help: did you mean: `"staticlib"`
2626
2727error: invalid `crate_type` value
28 --> $DIR/invalid-crate-type.rs:21:15
28 --> $DIR/invalid-crate-type.rs:24:15
2929 |
3030LL | #![crate_type="drylib"]
3131 | ^^^^^^^^ help: did you mean: `"dylib"`
3232
3333error: invalid `crate_type` value
34 --> $DIR/invalid-crate-type.rs:26:15
34 --> $DIR/invalid-crate-type.rs:29:15
3535 |
3636LL | #![crate_type="dlib"]
3737 | ^^^^^^ help: did you mean: `"lib"`
3838
3939error: invalid `crate_type` value
40 --> $DIR/invalid-crate-type.rs:31:15
40 --> $DIR/invalid-crate-type.rs:34:15
4141 |
4242LL | #![crate_type="lob"]
4343 | ^^^^^ help: did you mean: `"lib"`
4444
4545error: invalid `crate_type` value
46 --> $DIR/invalid-crate-type.rs:36:15
46 --> $DIR/invalid-crate-type.rs:39:15
4747 |
4848LL | #![crate_type="bon"]
4949 | ^^^^^ help: did you mean: `"bin"`
5050
5151error: invalid `crate_type` value
52 --> $DIR/invalid-crate-type.rs:41:15
52 --> $DIR/invalid-crate-type.rs:44:15
5353 |
5454LL | #![crate_type="cdalib"]
5555 | ^^^^^^^^ help: did you mean: `"cdylib"`
5656
57error: aborting due to 9 previous errors
57error: invalid `crate_type` value
58 --> $DIR/invalid-crate-type.rs:50:15
59 |
60LL | #![crate_type="binary"]
61 | ^^^^^^^^ help: did you mean: `"bin"`
62
63error: invalid `crate_type` value
64 --> $DIR/invalid-crate-type.rs:55:15
65 |
66LL | #![crate_type="library"]
67 | ^^^^^^^^^ help: did you mean: `"lib"`
68
69error: invalid `crate_type` value
70 --> $DIR/invalid-crate-type.rs:60:15
71 |
72LL | #![crate_type="rustlib"]
73 | ^^^^^^^^^ help: did you mean: `"rlib"`
74
75error: invalid `crate_type` value
76 --> $DIR/invalid-crate-type.rs:65:15
77 |
78LL | #![crate_type="dynamiclib"]
79 | ^^^^^^^^^^^^ help: did you mean: `"dylib"`
80
81error: invalid `crate_type` value
82 --> $DIR/invalid-crate-type.rs:70:15
83 |
84LL | #![crate_type="dylibrary"]
85 | ^^^^^^^^^^^ help: did you mean: `"dylib"`
86
87error: invalid `crate_type` value
88 --> $DIR/invalid-crate-type.rs:75:15
89 |
90LL | #![crate_type="cdynamiclib"]
91 | ^^^^^^^^^^^^^ help: did you mean: `"cdylib"`
92
93error: invalid `crate_type` value
94 --> $DIR/invalid-crate-type.rs:80:15
95 |
96LL | #![crate_type="cdylibrary"]
97 | ^^^^^^^^^^^^ help: did you mean: `"cdylib"`
98
99error: invalid `crate_type` value
100 --> $DIR/invalid-crate-type.rs:85:15
101 |
102LL | #![crate_type="staticlibrary"]
103 | ^^^^^^^^^^^^^^^ help: did you mean: `"staticlib"`
104
105error: invalid `crate_type` value
106 --> $DIR/invalid-crate-type.rs:90:15
107 |
108LL | #![crate_type="procedural-macro"]
109 | ^^^^^^^^^^^^^^^^^^ help: did you mean: `"proc-macro"`
110
111error: aborting due to 18 previous errors
58112
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
6use std::collections::HashMap;
7use std::rc::Rc;
8
9fn foo<T: Send>() {}
10
11fn 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 @@
1error[E0277]: `Rc<()>` cannot be sent between threads safely
2 --> $DIR/hashmap-send-requires-send-contents.rs:12:11
3 |
4LL | 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`
10note: required because it appears within the type `hashbrown::map::HashMap<Rc<()>, Rc<()>, RandomState>`
11 --> $HASHBROWN_SRC_LOCATION
12note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>`
13 --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
14note: required by a bound in `foo`
15 --> $DIR/hashmap-send-requires-send-contents.rs:9:11
16 |
17LL | fn foo<T: Send>() {}
18 | ^^^^ required by this bound in `foo`
19
20error: aborting due to 1 previous error
21
22For 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
9use std::ops::Add;
10fn show(z: i32) {
11 println!("{}", z)
12}
13fn 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"))]
5fn 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")))]
18fn 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)]
7enum Expression {
8 Dummy,
9 Add(Box<Expression>),
10}
11
12use Expression::*;
13
14fn simplify(exp: Expression) -> Expression {
15 match exp {
16 Add(n) => *n.clone(),
17 _ => Dummy
18 }
19}
20
21fn 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>.
2use std::any::Any;
3
4fn 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 @@
1error[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 |
4LL | 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
11error[E0107]: missing generics for trait `Fn`
12 --> $DIR/dyn-any-to-fn-with-missing-generics.rs:9:39
13 |
14LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
15 | ^^ expected 1 generic argument
16 |
17help: add missing generic argument
18 |
19LL | println!("{:?}",(vfnfer[0] as dyn Fn<Args>)(3));
20 | ++++++
21
22error: aborting due to 2 previous errors
23
24Some errors have detailed explanations: E0107, E0658.
25For 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
3fn 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 @@
1error[E0277]: expected a `Fn()` closure, found `()`
2 --> $DIR/raw-ptr-to-dyn-fn-raw-ptr.rs:6:16
3 |
4LL | &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
11error: aborting due to 1 previous error
12
13For 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
7enum FooMode {
8 Check = 0x1001,
9}
10
11enum BarMode {
12 Check = 0x2001,
13}
14
15enum Mode {
16 Foo(FooMode),
17 Bar(BarMode),
18}
19
20#[inline(never)]
21fn 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
29fn 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 @@
22#![expect(incomplete_features)]
33
44struct 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])`
66}
77
88fn main() {}
tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr+1-1
......@@ -1,4 +1,4 @@
1error: expected `usize`, found const tuple
1error: expected `usize`, found `([1, 2], 3, [4, 5])`
22 --> $DIR/tuple_expr_arg_bad-issue-151048.rs:5:19
33 |
44LL | stuff: [u8; { ([1, 2], 3, [4, 5]) }],
tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs+1-1
......@@ -2,7 +2,7 @@
22#![expect(incomplete_features)]
33
44pub 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 `()`
66}
77
88fn main() {}
tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr+1-1
......@@ -1,4 +1,4 @@
1error: expected `u32`, found const tuple
1error: expected `u32`, found `()`
22 --> $DIR/tuple_expr_arg_mismatch_type.rs:5:28
33 |
44LL | 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
6fn takes_tuple<const N: ()>() {}
7
8fn generic_caller<T, const N: u32>() {
9 takes_tuple::<{ (N, T::ASSOC) }>;
10 //~^ ERROR expected `()`, found `(N, T::ASSOC)`
11}
12
13fn main() {}
tests/ui/const-generics/mgca/tuple_expr_arg_unbounded_assoc_const.stderr created+8
......@@ -0,0 +1,8 @@
1error: expected `()`, found `(N, T::ASSOC)`
2 --> $DIR/tuple_expr_arg_unbounded_assoc_const.rs:9:21
3 |
4LL | takes_tuple::<{ (N, T::ASSOC) }>;
5 | ^^^^^^^^^^^^^
6
7error: 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() {
119119 //~^ ERROR requested `*const u8` is incompatible with next argument of type `usize`
120120}
121121
122unsafe 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
122131fn use_after_free() {
123132 const unsafe extern "C" fn helper(ap: ...) -> [u8; size_of::<VaList>()] {
124133 unsafe { std::mem::transmute(ap) }
......@@ -196,6 +205,7 @@ fn main() {
196205 read_too_many();
197206 read_cast_numeric();
198207 read_cast_pointer();
208 read_cast_lifetime();
199209 manual_copy_read();
200210 manual_copy_drop();
201211 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) };
390390 |
391391 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
392392
393error[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 |
396LL | 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 |
399note: inside `read_as::<*const fn(&())>`
400 --> $DIR/c-variadic-fail.rs:37:5
401 |
402LL | ap.next_arg::<T>()
403 | ^^^^^^^^^^^^^^^^^^
404note: inside `VaList::<'_>::next_arg::<*const fn(&())>`
405 --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL
406
407note: erroneous constant encountered
408 --> $DIR/c-variadic-fail.rs:127:5
409 |
410LL | const { read_as::<*const fn(&'static ())>(std::ptr::dangling::<for<'a> fn(&'a ())>()) };
411 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
412
413note: erroneous constant encountered
414 --> $DIR/c-variadic-fail.rs:127:5
415 |
416LL | 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
393421error[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
395423 |
396424LL | ap.next_arg::<i32>();
397425 | ^^^^^^^^^^^^^^^^^^^^ evaluation of `use_after_free::{constant#0}` failed inside this call
......@@ -400,7 +428,7 @@ note: inside `VaList::<'_>::next_arg::<i32>`
400428 --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL
401429
402430note: erroneous constant encountered
403 --> $DIR/c-variadic-fail.rs:127:5
431 --> $DIR/c-variadic-fail.rs:136:5
404432 |
405433LL | / const {
406434LL | | unsafe {
......@@ -411,7 +439,7 @@ LL | | };
411439 | |_____^
412440
413441note: erroneous constant encountered
414 --> $DIR/c-variadic-fail.rs:127:5
442 --> $DIR/c-variadic-fail.rs:136:5
415443 |
416444LL | / const {
417445LL | | unsafe {
......@@ -424,13 +452,13 @@ LL | | };
424452 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
425453
426454error[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
428456 |
429457LL | const { unsafe { helper(1, 2, 3) } };
430458 | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_drop::{constant#0}` failed inside this call
431459 |
432460note: inside `manual_copy_drop::helper`
433 --> $DIR/c-variadic-fail.rs:150:9
461 --> $DIR/c-variadic-fail.rs:159:9
434462 |
435463LL | drop(ap);
436464 | ^^^^^^^^
......@@ -442,13 +470,13 @@ note: inside `<VaList<'_> as Drop>::drop`
442470 --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL
443471
444472note: erroneous constant encountered
445 --> $DIR/c-variadic-fail.rs:153:5
473 --> $DIR/c-variadic-fail.rs:162:5
446474 |
447475LL | const { unsafe { helper(1, 2, 3) } };
448476 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
449477
450478note: erroneous constant encountered
451 --> $DIR/c-variadic-fail.rs:153:5
479 --> $DIR/c-variadic-fail.rs:162:5
452480 |
453481LL | const { unsafe { helper(1, 2, 3) } };
454482 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -456,13 +484,13 @@ LL | const { unsafe { helper(1, 2, 3) } };
456484 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
457485
458486error[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
460488 |
461489LL | const { unsafe { helper(1, 2, 3) } };
462490 | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_forget::{constant#0}` failed inside this call
463491 |
464492note: inside `manual_copy_forget::helper`
465 --> $DIR/c-variadic-fail.rs:166:9
493 --> $DIR/c-variadic-fail.rs:175:9
466494 |
467495LL | drop(ap);
468496 | ^^^^^^^^
......@@ -474,13 +502,13 @@ note: inside `<VaList<'_> as Drop>::drop`
474502 --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL
475503
476504note: erroneous constant encountered
477 --> $DIR/c-variadic-fail.rs:169:5
505 --> $DIR/c-variadic-fail.rs:178:5
478506 |
479507LL | const { unsafe { helper(1, 2, 3) } };
480508 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
481509
482510note: erroneous constant encountered
483 --> $DIR/c-variadic-fail.rs:169:5
511 --> $DIR/c-variadic-fail.rs:178:5
484512 |
485513LL | const { unsafe { helper(1, 2, 3) } };
486514 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -488,13 +516,13 @@ LL | const { unsafe { helper(1, 2, 3) } };
488516 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
489517
490518error[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
492520 |
493521LL | const { unsafe { helper(1, 2, 3) } };
494522 | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_read::{constant#0}` failed inside this call
495523 |
496524note: inside `manual_copy_read::helper`
497 --> $DIR/c-variadic-fail.rs:179:17
525 --> $DIR/c-variadic-fail.rs:188:17
498526 |
499527LL | let _ = ap.next_arg::<i32>();
500528 | ^^^^^^^^^^^^^^^^^^^^
......@@ -502,13 +530,13 @@ note: inside `VaList::<'_>::next_arg::<i32>`
502530 --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL
503531
504532note: erroneous constant encountered
505 --> $DIR/c-variadic-fail.rs:182:5
533 --> $DIR/c-variadic-fail.rs:191:5
506534 |
507535LL | const { unsafe { helper(1, 2, 3) } };
508536 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
509537
510538note: erroneous constant encountered
511 --> $DIR/c-variadic-fail.rs:182:5
539 --> $DIR/c-variadic-fail.rs:191:5
512540 |
513541LL | const { unsafe { helper(1, 2, 3) } };
514542 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -516,7 +544,7 @@ LL | const { unsafe { helper(1, 2, 3) } };
516544 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
517545
518546error[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
520548 |
521549LL | }
522550 | ^ evaluation of `drop_of_invalid::{constant#0}` failed inside this call
......@@ -527,7 +555,7 @@ note: inside `<VaList<'_> as Drop>::drop`
527555 --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL
528556
529557note: erroneous constant encountered
530 --> $DIR/c-variadic-fail.rs:187:5
558 --> $DIR/c-variadic-fail.rs:196:5
531559 |
532560LL | / const {
533561LL | | let mut invalid: MaybeUninit<VaList> = MaybeUninit::zeroed();
......@@ -536,7 +564,7 @@ LL | | }
536564 | |_____^
537565
538566note: erroneous constant encountered
539 --> $DIR/c-variadic-fail.rs:187:5
567 --> $DIR/c-variadic-fail.rs:196:5
540568 |
541569LL | / const {
542570LL | | let mut invalid: MaybeUninit<VaList> = MaybeUninit::zeroed();
......@@ -546,6 +574,6 @@ LL | | }
546574 |
547575 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
548576
549error: aborting due to 19 previous errors
577error: aborting due to 20 previous errors
550578
551579For 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
5trait Trait<T> {
6 fn foo<U>(&self, _: U, _: T) {}
7}
8
9impl<T> Trait<T> for u8 {}
10
11reuse Trait::<_>::foo::<i32> as generic_arguments1;
12//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
13reuse <u8 as Trait<_>>::foo as generic_arguments2;
14//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
15reuse <_ 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
19fn main() {}
tests/ui/delegation/generics/free-fn-to-trait-infer.stderr deleted-27
......@@ -1,27 +0,0 @@
1error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
2 --> $DIR/free-fn-to-trait-infer.rs:11:15
3 |
4LL | reuse Trait::<_>::foo::<i32> as generic_arguments1;
5 | ^ not allowed in type signatures
6
7error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
8 --> $DIR/free-fn-to-trait-infer.rs:13:20
9 |
10LL | reuse <u8 as Trait<_>>::foo as generic_arguments2;
11 | ^ not allowed in type signatures
12
13error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
14 --> $DIR/free-fn-to-trait-infer.rs:15:8
15 |
16LL | reuse <_ as Trait<_>>::foo as generic_arguments3;
17 | ^ not allowed in type signatures
18
19error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
20 --> $DIR/free-fn-to-trait-infer.rs:15:19
21 |
22LL | reuse <_ as Trait<_>>::foo as generic_arguments3;
23 | ^ not allowed in type signatures
24
25error: aborting due to 4 previous errors
26
27For 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 }
2020reuse <usize as Trait>::static_method::<'static, Vec<i32>, false> as bar2;
2121
2222reuse Trait::static_method as error { self - 123 }
23//~^ ERROR: type annotations needed
24//~| ERROR: delegation self type is not specified
2523reuse Trait::<'static, i32, 123>::static_method as error2;
26//~^ ERROR: type annotations needed
27//~| ERROR: delegation self type is not specified
2824reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3;
29//~^ ERROR: type annotations needed
30//~| ERROR: delegation self type is not specified
3125reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 }
32//~^ ERROR: type annotations needed
33//~| ERROR: delegation self type is not specified
3426
3527reuse <String as Trait>::static_method as error5;
3628//~^ 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 @@
1error: delegation self type is not specified
2 --> $DIR/free-to-trait-static-reuse.rs:22:14
3 |
4LL | reuse Trait::static_method as error { self - 123 }
5 | ^^^^^^^^^^^^^
6 |
7 = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
8
9error: delegation self type is not specified
10 --> $DIR/free-to-trait-static-reuse.rs:25:35
11 |
12LL | reuse Trait::<'static, i32, 123>::static_method as error2;
13 | ^^^^^^^^^^^^^
14 |
15 = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
16
17error: delegation self type is not specified
18 --> $DIR/free-to-trait-static-reuse.rs:28:35
19 |
20LL | 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
25error: delegation self type is not specified
26 --> $DIR/free-to-trait-static-reuse.rs:31:14
27 |
28LL | 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
331error[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
353 |
364LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
375 | ^^^^^^ unsatisfied trait bound
386 |
397help: 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
419 |
4210LL | struct Struct;
4311 | ^^^^^^^^^^^^^
......@@ -55,68 +23,8 @@ LL | where
5523LL | Self: Bound<T>,
5624 | ^^^^^^^^ required by this bound in `Trait`
5725
58error[E0283]: type annotations needed
59 --> $DIR/free-to-trait-static-reuse.rs:22:14
60 |
61LL | reuse Trait::static_method as error { self - 123 }
62 | ^^^^^^^^^^^^^ cannot infer type
63 |
64note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found
65 --> $DIR/free-to-trait-static-reuse.rs:14:1
66 |
67LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
68 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
69...
70LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
71 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
72
73error[E0283]: type annotations needed
74 --> $DIR/free-to-trait-static-reuse.rs:25:35
75 |
76LL | reuse Trait::<'static, i32, 123>::static_method as error2;
77 | ^^^^^^^^^^^^^ cannot infer type
78 |
79note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found
80 --> $DIR/free-to-trait-static-reuse.rs:14:1
81 |
82LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
83 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
84...
85LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
86 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
87
88error[E0283]: type annotations needed
89 --> $DIR/free-to-trait-static-reuse.rs:28:35
90 |
91LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3;
92 | ^^^^^^^^^^^^^ cannot infer type
93 |
94note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found
95 --> $DIR/free-to-trait-static-reuse.rs:14:1
96 |
97LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
98 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
99...
100LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
101 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
102
103error[E0283]: type annotations needed
104 --> $DIR/free-to-trait-static-reuse.rs:31:14
105 |
106LL | reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 }
107 | ^^^^^^^^^^^^^ cannot infer type
108 |
109note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found
110 --> $DIR/free-to-trait-static-reuse.rs:14:1
111 |
112LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
113 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114...
115LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
116 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
117
11826error[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
12028 |
12129LL | reuse <String as Trait>::static_method as error5;
12230 | ^^^^^^ 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 {}
13139 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Struct`
13240
13341error[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
13543 |
13644LL | reuse <Struct as Trait>::static_method as error6;
13745 | ^^^^^^ unsatisfied trait bound
13846 |
13947help: 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
14149 |
14250LL | struct Struct;
14351 | ^^^^^^^^^^^^^
......@@ -155,7 +63,6 @@ LL | {
15563LL | fn static_method<'c: 'c, U, const B: bool>(x: usize) {}
15664 | ------------- required by a bound in this associated function
15765
158error: aborting due to 11 previous errors
66error: aborting due to 3 previous errors
15967
160Some errors have detailed explanations: E0277, E0283.
161For more information about an error, try `rustc --explain E0277`.
68For 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 {
4444 fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {}
4545
4646 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
4947
5048 reuse foo::<String, String> as bar2;
5149 //~^ ERROR: function takes 3 generic arguments but 2 generic arguments were supplied
......@@ -54,9 +52,9 @@ mod test_2 {
5452
5553 reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3;
5654 //~^ 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: _
6058
6159 reuse foo::<String, 'static, 123, asdasd> as bar4;
6260 //~^ ERROR: cannot find type `asdasd` in this scope
......@@ -131,12 +129,13 @@ mod test_3 {
131129 //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
132130
133131 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
136134 //~| ERROR: method takes 2 generic arguments but 5 generic arguments were supplied
137135 //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied
138136 //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
139137 //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
138 //~| ERROR: wrong infer used: expected '_, found: _
140139}
141140
142141fn main() {}
tests/ui/delegation/generics/generics-gen-args-errors.stderr+102-108
......@@ -38,7 +38,7 @@ LL | reuse foo::<A, B, C> as xd;
3838 = note: nested items are independent from their parent item for everything except for privacy and name resolution
3939
4040error[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
4242 |
4343LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3;
4444 | ^^^^^^^ undeclared lifetime
......@@ -49,7 +49,7 @@ LL | reuse foo'asdasd, ::<'static, _, 'asdasd, 'static, 'static, 'static, _>
4949 | ++++++++
5050
5151error[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
5353 |
5454LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7;
5555 | ^^ undeclared lifetime
......@@ -103,65 +103,77 @@ LL | fn check<A, B, C, asd>() {
103103 | +++++
104104
105105error[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
107107 |
108108LL | reuse foo::<String, 'static, 123, asdasd> as bar4;
109109 | ^^^^^^ not found in this scope
110110
111111error[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
113113 |
114114LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6;
115115 | ^^^ not found in this scope
116116
117117error[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
119119 |
120120LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7;
121121 | ^^^ not found in this scope
122122
123123error[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
125125 |
126126LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
127127 | ^^^ not found in this scope
128128
129129error[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
131131 |
132132LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
133133 | ^^^ not found in this scope
134134
135135error[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
137137 |
138138LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
139139 | ^^^ not found in this scope
140140
141141error[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
143143 |
144144LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
145145 | ^^^ not found in this scope
146146
147147error[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
149149 |
150150LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
151151 | ^^^ not found in this scope
152152
153153error[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
155155 |
156156LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
157157 | ^^^^^^ not found in this scope
158158
159159error[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
161161 |
162162LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
163163 | ^^^^ not found in this scope
164164
165error: wrong infer used: expected '_, found: _
166 --> $DIR/generics-gen-args-errors.rs:53:26
167 |
168LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3;
169 | ^
170
171error: wrong infer used: expected '_, found: _
172 --> $DIR/generics-gen-args-errors.rs:131:33
173 |
174LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
175 | ^
176
165177error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied
166178 --> $DIR/generics-gen-args-errors.rs:33:15
167179 |
......@@ -184,20 +196,8 @@ error: inferred lifetimes are not allowed in delegations as we need to inherit s
184196LL | reuse foo::<A, B, C> as xd;
185197 | ^^^
186198
187error: inferred lifetimes are not allowed in delegations as we need to inherit signature
188 --> $DIR/generics-gen-args-errors.rs:46:11
189 |
190LL | reuse foo::<> as bar1;
191 | ^^^
192
193error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
194 --> $DIR/generics-gen-args-errors.rs:46:11
195 |
196LL | reuse foo::<> as bar1;
197 | ^^^ not allowed in type signatures
198
199199error[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
201201 |
202202LL | reuse foo::<String, String> as bar2;
203203 | ^^^ expected 2 lifetime arguments
......@@ -213,7 +213,7 @@ LL | reuse foo::<'a, 'b, String, String> as bar2;
213213 | +++++++
214214
215215error[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
217217 |
218218LL | reuse foo::<String, String> as bar2;
219219 | ^^^ ------ ------ supplied 2 generic arguments
......@@ -231,16 +231,16 @@ LL | reuse foo::<String, String, N> as bar2;
231231 | +++
232232
233233error: 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
235235 |
236236LL | reuse foo::<String, String> as bar2;
237237 | ^^^
238238
239error[E0107]: function takes 2 lifetime arguments but 5 lifetime arguments were supplied
240 --> $DIR/generics-gen-args-errors.rs:55:11
239error[E0107]: function takes 2 lifetime arguments but 6 lifetime arguments were supplied
240 --> $DIR/generics-gen-args-errors.rs:53:11
241241 |
242242LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3;
243 | ^^^ --------------------------- help: remove the lifetime arguments
243 | ^^^------------------------------------------------- help: remove the lifetime arguments
244244 | |
245245 | expected 2 lifetime arguments
246246 |
......@@ -250,30 +250,24 @@ note: function defined here, with 2 lifetime parameters: `'a`, `'b`
250250LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {}
251251 | ^^^ -- --
252252
253error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied
254 --> $DIR/generics-gen-args-errors.rs:55:11
253error[E0107]: function takes 3 generic arguments but 1 generic argument was supplied
254 --> $DIR/generics-gen-args-errors.rs:53:11
255255 |
256256LL | 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
258258 |
259259note: function defined here, with 3 generic parameters: `T`, `U`, `N`
260260 --> $DIR/generics-gen-args-errors.rs:44:8
261261 |
262262LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {}
263263 | ^^^ - - --------------
264help: add missing generic argument
264help: add missing generic arguments
265265 |
266LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, N> as bar3;
267 | +++
268
269error: inferred lifetimes are not allowed in delegations as we need to inherit signature
270 --> $DIR/generics-gen-args-errors.rs:55:11
271 |
272LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3;
273 | ^^^
266LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, U, N> as bar3;
267 | ++++++
274268
275269error[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
277271 |
278272LL | reuse foo::<String, 'static, 123, asdasd> as bar4;
279273 | ^^^ ------ supplied 1 lifetime argument
......@@ -291,13 +285,13 @@ LL | reuse foo::<String, 'static, 'static, 123, asdasd> as bar4;
291285 | +++++++++
292286
293287error: 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
295289 |
296290LL | reuse foo::<String, 'static, 123, asdasd> as bar4;
297291 | ^^^
298292
299293error[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
301295 |
302296LL | reuse foo::<1, 2, _, 4, 5, _> as bar5;
303297 | ^^^ expected 2 lifetime arguments
......@@ -313,10 +307,10 @@ LL | reuse foo::<'a, 'b, 1, 2, _, 4, 5, _> as bar5;
313307 | +++++++
314308
315309error[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
317311 |
318312LL | reuse foo::<1, 2, _, 4, 5, _> as bar5;
319 | ^^^ --------- help: remove the unnecessary generic arguments
313 | ^^^------------------- help: remove the unnecessary generic arguments
320314 | |
321315 | expected 3 generic arguments
322316 |
......@@ -327,13 +321,13 @@ LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {}
327321 | ^^^ - - --------------
328322
329323error: 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
331325 |
332326LL | reuse foo::<1, 2, _, 4, 5, _> as bar5;
333327 | ^^^
334328
335329error[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
337331 |
338332LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6;
339333 | ^^^ expected 2 lifetime arguments
......@@ -349,7 +343,7 @@ LL | reuse foo::<'a, 'b, 1, 2,asd,String, { let x = 0; }> as bar6;
349343 | +++++++
350344
351345error[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
353347 |
354348LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6;
355349 | ^^^ ----------------------- help: remove the unnecessary generic arguments
......@@ -363,25 +357,25 @@ LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {}
363357 | ^^^ - - --------------
364358
365359error: 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
367361 |
368362LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6;
369363 | ^^^
370364
371365error: 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
373367 |
374368LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7;
375369 | ^^^
376370
377371error[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
379373 |
380374LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7;
381375 | ^^^^^^^^
382376
383377error[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
385379 |
386380LL | reuse foo::<{}, {}, {}> as bar8;
387381 | ^^^ expected 2 lifetime arguments
......@@ -397,19 +391,19 @@ LL | reuse foo::<'a, 'b, {}, {}, {}> as bar8;
397391 | +++++++
398392
399393error: 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
401395 |
402396LL | reuse foo::<{}, {}, {}> as bar8;
403397 | ^^^
404398
405399error[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
407401 |
408402LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
409403 | ^^^^^ expected 3 lifetime arguments
410404 |
411405note: 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
413407 |
414408LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
415409 | ^^^^^ -- -- --
......@@ -419,7 +413,7 @@ LL | reuse Trait::<'b, 'c, 'a, asd, asd, asd, asd, asd, asdasa>::foo as bar1
419413 | +++++++++++
420414
421415error[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
423417 |
424418LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
425419 | ^^^^^ ----------------------- help: remove the unnecessary generic arguments
......@@ -427,19 +421,19 @@ LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
427421 | expected 2 generic arguments
428422 |
429423note: 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
431425 |
432426LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
433427 | ^^^^^ - --------------
434428
435429error: 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
437431 |
438432LL | reuse Trait::<asd, asd, asd, asd, asd, asdasa>::foo as bar1;
439433 | ^^^^^
440434
441435error[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
443437 |
444438LL | reuse Trait::<'static, 'static>::foo as bar2;
445439 | ^^^^^ ------- ------- supplied 2 lifetime arguments
......@@ -447,7 +441,7 @@ LL | reuse Trait::<'static, 'static>::foo as bar2;
447441 | expected 3 lifetime arguments
448442 |
449443note: 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
451445 |
452446LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
453447 | ^^^^^ -- -- --
......@@ -457,25 +451,25 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar2;
457451 | +++++++++
458452
459453error: 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
461455 |
462456LL | reuse Trait::<'static, 'static>::foo as bar2;
463457 | ^^^^^
464458
465459error[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
467461 |
468462LL | reuse Trait::<'static, 'static>::foo as bar2;
469463 | ^^^^^ not allowed in type signatures
470464
471465error[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
473467 |
474468LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3;
475469 | ^^^^^ expected 3 lifetime arguments
476470 |
477471note: 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
479473 |
480474LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
481475 | ^^^^^ -- -- --
......@@ -485,7 +479,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, 3, 4, 5>::foo as bar3;
485479 | +++++++++++
486480
487481error[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
489483 |
490484LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3;
491485 | ^^^^^ --------- help: remove the unnecessary generic arguments
......@@ -493,25 +487,25 @@ LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3;
493487 | expected 2 generic arguments
494488 |
495489note: 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
497491 |
498492LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
499493 | ^^^^^ - --------------
500494
501495error: 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
503497 |
504498LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3;
505499 | ^^^^^
506500
507501error[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
509503 |
510504LL | reuse Trait::<1, 2, true>::foo as bar4;
511505 | ^^^^^ expected 3 lifetime arguments
512506 |
513507note: 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
515509 |
516510LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
517511 | ^^^^^ -- -- --
......@@ -521,7 +515,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, true>::foo as bar4;
521515 | +++++++++++
522516
523517error[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
525519 |
526520LL | reuse Trait::<1, 2, true>::foo as bar4;
527521 | ^^^^^ ------ help: remove the unnecessary generic argument
......@@ -529,19 +523,19 @@ LL | reuse Trait::<1, 2, true>::foo as bar4;
529523 | expected 2 generic arguments
530524 |
531525note: 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
533527 |
534528LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
535529 | ^^^^^ - --------------
536530
537531error: 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
539533 |
540534LL | reuse Trait::<1, 2, true>::foo as bar4;
541535 | ^^^^^
542536
543537error[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
545539 |
546540LL | reuse Trait::<'static>::foo as bar5;
547541 | ^^^^^ ------- supplied 1 lifetime argument
......@@ -549,7 +543,7 @@ LL | reuse Trait::<'static>::foo as bar5;
549543 | expected 3 lifetime arguments
550544 |
551545note: 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
553547 |
554548LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
555549 | ^^^^^ -- -- --
......@@ -559,19 +553,19 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar5;
559553 | ++++++++++++++++++
560554
561555error: 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
563557 |
564558LL | reuse Trait::<'static>::foo as bar5;
565559 | ^^^^^
566560
567561error[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
569563 |
570564LL | reuse Trait::<'static>::foo as bar5;
571565 | ^^^^^ not allowed in type signatures
572566
573567error[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
575569 |
576570LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
577571 | ^^^^^ - supplied 1 lifetime argument
......@@ -579,7 +573,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
579573 | expected 3 lifetime arguments
580574 |
581575note: 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
583577 |
584578LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
585579 | ^^^^^ -- -- --
......@@ -589,7 +583,7 @@ LL | reuse Trait::<1, 'static, 'static, 2, 'static, DDDD>::foo::<1, 2, 3, 4,
589583 | ++++++++++++++++++
590584
591585error[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
593587 |
594588LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
595589 | ^^^^^ --------------- 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;
597591 | expected 2 generic arguments
598592 |
599593note: 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
601595 |
602596LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
603597 | ^^^^^ - --------------
604598
605599error: 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
607601 |
608602LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
609603 | ^^^^^
610604
611605error[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
613607 |
614608LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
615609 | ^^^ expected 1 lifetime argument
616610 |
617611note: 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
619613 |
620614LL | fn foo<'d: 'd, U, const M: bool>(self) {}
621615 | ^^^ --
......@@ -625,7 +619,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<'d, 1, 2, 3, 4, 5, 6> as bar6
625619 | +++
626620
627621error[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
629623 |
630624LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
631625 | ^^^ ------------ 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;
633627 | expected 2 generic arguments
634628 |
635629note: 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
637631 |
638632LL | fn foo<'d: 'd, U, const M: bool>(self) {}
639633 | ^^^ - -------------
640634
641635error: 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
643637 |
644638LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
645639 | ^^^
646640
647error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied
648 --> $DIR/generics-gen-args-errors.rs:133:11
641error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied
642 --> $DIR/generics-gen-args-errors.rs:131:11
649643 |
650644LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
651 | ^^^^^ ----- supplied 1 lifetime argument
645 | ^^^^^ ----- ----- supplied 2 lifetime arguments
652646 | |
653647 | expected 3 lifetime arguments
654648 |
655649note: 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
657651 |
658652LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
659653 | ^^^^^ -- -- --
660help: add missing lifetime arguments
654help: add missing lifetime argument
661655 |
662LL | reuse Trait::<Trait, 'static, 'static, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
663 | ++++++++++++++++++
656LL | reuse Trait::<Trait, Clone, 'a, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
657 | ++++
664658
665error[E0107]: trait takes 2 generic arguments but 5 generic arguments were supplied
666 --> $DIR/generics-gen-args-errors.rs:133:11
659error[E0107]: trait takes 2 generic arguments but 4 generic arguments were supplied
660 --> $DIR/generics-gen-args-errors.rs:131:11
667661 |
668662LL | 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
670664 | |
671665 | expected 2 generic arguments
672666 |
673667note: 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
675669 |
676670LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized {
677671 | ^^^^^ - --------------
678672
679673error: 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
681675 |
682676LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
683677 | ^^^^^
684678
685679error[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
687681 |
688682LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
689683 | ^^^ expected 1 lifetime argument
690684 |
691685note: 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
693687 |
694688LL | fn foo<'d: 'd, U, const M: bool>(self) {}
695689 | ^^^ --
696690help: add missing lifetime argument
697691 |
698LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<'d, 1, 2, 3, _, 6> as bar7;
692LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<'a, 1, 2, 3, _, 6> as bar7;
699693 | +++
700694
701695error[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
703697 |
704698LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
705699 | ^^^ --------- help: remove the unnecessary generic arguments
......@@ -707,13 +701,13 @@ LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _,
707701 | expected 2 generic arguments
708702 |
709703note: 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
711705 |
712706LL | fn foo<'d: 'd, U, const M: bool>(self) {}
713707 | ^^^ - -------------
714708
715709error: 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
717711 |
718712LL | reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
719713 | ^^^
......@@ -789,12 +783,12 @@ LL | reuse foo::<A, B, { C }> as xd;
789783 | + +
790784
791785error[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
793787 |
794788LL | reuse foo::<{}, {}, {}> as bar8;
795789 | ^^
796790
797error: aborting due to 75 previous errors
791error: aborting due to 74 previous errors
798792
799793Some errors have detailed explanations: E0107, E0121, E0261, E0401, E0423, E0425, E0747.
800794For 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:
6mod 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:
66mod 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
78mod 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
140mod 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
324mod 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
356fn main() {}
tests/ui/delegation/generics/infers.stderr created+1296
......@@ -0,0 +1,1296 @@
1error: lifetimes must be followed by `+` to form a trait object type
2 --> $DIR/infers.rs:54:21
3 |
4LL | reuse foo::('_, _, _, _) as bar;
5 | ^^
6 |
7help: consider adding a trait bound after the potential lifetime bound
8 |
9LL | reuse foo::('_ + /* Trait */, _, _, _) as bar;
10 | +++++++++++++
11
12error[E0261]: use of undeclared lifetime name `'____`
13 --> $DIR/infers.rs:123:17
14 |
15LL | reuse foo::<'____, ___, _, ___> as foo12;
16 | ^^^^^ undeclared lifetime
17 |
18help: consider introducing lifetime `'____` here
19 |
20LL | reuse foo'____, ::<'____, ___, _, ___> as foo12;
21 | ++++++
22
23error[E0261]: use of undeclared lifetime name `'____`
24 --> $DIR/infers.rs:195:28
25 |
26LL | reuse Trait::foo::<'____, ___, _, ___> as foo12;
27 | ^^^^^ undeclared lifetime
28 |
29help: consider introducing lifetime `'____` here
30 |
31LL | reuse Trait::foo'____, ::<'____, ___, _, ___> as foo12;
32 | ++++++
33
34error[E0261]: use of undeclared lifetime name `'____`
35 --> $DIR/infers.rs:316:51
36 |
37LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12;
38 | ^^^^^ undeclared lifetime
39 |
40help: consider introducing lifetime `'____` here
41 |
42LL | reuse Trait::<'static, 'static, _>::foo'____, ::<'____, ___, _, ___> as foo12;
43 | ++++++
44
45error[E0425]: cannot find type `___` in this scope
46 --> $DIR/infers.rs:123:24
47 |
48LL | reuse foo::<'____, ___, _, ___> as foo12;
49 | ^^^ not found in this scope
50
51error[E0425]: cannot find type `___` in this scope
52 --> $DIR/infers.rs:123:32
53 |
54LL | reuse foo::<'____, ___, _, ___> as foo12;
55 | ^^^ not found in this scope
56
57error[E0425]: cannot find type `unresolved_` in this scope
58 --> $DIR/infers.rs:132:21
59 |
60LL | reuse foo::<'_, unresolved_, _, _> as foo14;
61 | ^^^^^^^^^^^ not found in this scope
62
63error[E0425]: cannot find type `___` in this scope
64 --> $DIR/infers.rs:195:35
65 |
66LL | reuse Trait::foo::<'____, ___, _, ___> as foo12;
67 | ^^^ not found in this scope
68
69error[E0425]: cannot find type `___` in this scope
70 --> $DIR/infers.rs:195:43
71 |
72LL | reuse Trait::foo::<'____, ___, _, ___> as foo12;
73 | ^^^ not found in this scope
74
75error[E0425]: cannot find type `unresolved_` in this scope
76 --> $DIR/infers.rs:204:32
77 |
78LL | reuse Trait::foo::<'_, unresolved_, _, _> as foo14;
79 | ^^^^^^^^^^^ not found in this scope
80
81error[E0425]: cannot find type `___` in this scope
82 --> $DIR/infers.rs:316:58
83 |
84LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12;
85 | ^^^ not found in this scope
86
87error[E0425]: cannot find type `___` in this scope
88 --> $DIR/infers.rs:316:66
89 |
90LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12;
91 | ^^^ not found in this scope
92
93error: wrong infer used: expected '_, found: _
94 --> $DIR/infers.rs:11:21
95 |
96LL | reuse foo::<_, '_, '_, '_> as bar;
97 | ^
98
99error: wrong infer used: expected _, found: '_
100 --> $DIR/infers.rs:11:24
101 |
102LL | reuse foo::<_, '_, '_, '_> as bar;
103 | ^^
104
105error: wrong infer used: expected _, found: '_
106 --> $DIR/infers.rs:11:28
107 |
108LL | reuse foo::<_, '_, '_, '_> as bar;
109 | ^^
110
111error: wrong infer used: expected _, found: '_
112 --> $DIR/infers.rs:11:32
113 |
114LL | reuse foo::<_, '_, '_, '_> as bar;
115 | ^^
116
117error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
118 --> $DIR/infers.rs:54:15
119 |
120LL | reuse foo::('_, _, _, _) as bar;
121 | ^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
122 |
123help: use angle brackets instead
124 |
125LL - reuse foo::('_, _, _, _) as bar;
126LL + reuse foo::<'_, _, _, _> as bar;
127 |
128
129error: wrong infer used: expected _, found: '_
130 --> $DIR/infers.rs:86:21
131 |
132LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5;
133 | ^^
134
135error: wrong infer used: expected _, found: '_
136 --> $DIR/infers.rs:86:25
137 |
138LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5;
139 | ^^
140
141error: wrong infer used: expected '_, found: _
142 --> $DIR/infers.rs:91:17
143 |
144LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
145 | ^
146
147error: wrong infer used: expected _, found: '_
148 --> $DIR/infers.rs:91:26
149 |
150LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
151 | ^^
152
153error: wrong infer used: expected '_, found: _
154 --> $DIR/infers.rs:97:17
155 |
156LL | reuse foo::<_, '_, _, _> as foo7;
157 | ^
158
159error: wrong infer used: expected _, found: '_
160 --> $DIR/infers.rs:97:20
161 |
162LL | reuse foo::<_, '_, _, _> as foo7;
163 | ^^
164
165error: wrong infer used: expected _, found: '_
166 --> $DIR/infers.rs:101:21
167 |
168LL | reuse foo::<'_, '_, '_, '_> as foo8;
169 | ^^
170
171error: wrong infer used: expected _, found: '_
172 --> $DIR/infers.rs:101:25
173 |
174LL | reuse foo::<'_, '_, '_, '_> as foo8;
175 | ^^
176
177error: wrong infer used: expected _, found: '_
178 --> $DIR/infers.rs:101:29
179 |
180LL | reuse foo::<'_, '_, '_, '_> as foo8;
181 | ^^
182
183error: wrong infer used: expected '_, found: _
184 --> $DIR/infers.rs:106:17
185 |
186LL | reuse foo::<_> as foo9;
187 | ^
188
189error: wrong infer used: expected '_, found: _
190 --> $DIR/infers.rs:135:17
191 |
192LL | reuse foo::<_, _, _> as foo15;
193 | ^
194
195error: wrong infer used: expected _, found: '_
196 --> $DIR/infers.rs:158:32
197 |
198LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5;
199 | ^^
200
201error: wrong infer used: expected _, found: '_
202 --> $DIR/infers.rs:158:36
203 |
204LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5;
205 | ^^
206
207error: wrong infer used: expected '_, found: _
208 --> $DIR/infers.rs:163:28
209 |
210LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
211 | ^
212
213error: wrong infer used: expected _, found: '_
214 --> $DIR/infers.rs:163:37
215 |
216LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
217 | ^^
218
219error: wrong infer used: expected '_, found: _
220 --> $DIR/infers.rs:169:28
221 |
222LL | reuse Trait::foo::<_, '_, _, _> as foo7;
223 | ^
224
225error: wrong infer used: expected _, found: '_
226 --> $DIR/infers.rs:169:31
227 |
228LL | reuse Trait::foo::<_, '_, _, _> as foo7;
229 | ^^
230
231error: wrong infer used: expected _, found: '_
232 --> $DIR/infers.rs:173:32
233 |
234LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8;
235 | ^^
236
237error: wrong infer used: expected _, found: '_
238 --> $DIR/infers.rs:173:36
239 |
240LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8;
241 | ^^
242
243error: wrong infer used: expected _, found: '_
244 --> $DIR/infers.rs:173:40
245 |
246LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8;
247 | ^^
248
249error: wrong infer used: expected '_, found: _
250 --> $DIR/infers.rs:178:28
251 |
252LL | reuse Trait::foo::<_> as foo9;
253 | ^
254
255error: wrong infer used: expected '_, found: _
256 --> $DIR/infers.rs:207:28
257 |
258LL | reuse Trait::foo::<_, _, _> as foo15;
259 | ^
260
261error: wrong infer used: expected _, found: '_
262 --> $DIR/infers.rs:218:34
263 |
264LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3;
265 | ^^
266
267error: wrong infer used: expected '_, found: _
268 --> $DIR/infers.rs:226:23
269 |
270LL | reuse Trait::<_, _>::foo as foo5;
271 | ^
272
273error: wrong infer used: expected '_, found: _
274 --> $DIR/infers.rs:226:26
275 |
276LL | reuse Trait::<_, _>::foo as foo5;
277 | ^
278
279error: wrong infer used: expected _, found: '_
280 --> $DIR/infers.rs:244:41
281 |
282LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11;
283 | ^^
284
285error: wrong infer used: expected _, found: '_
286 --> $DIR/infers.rs:244:44
287 |
288LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11;
289 | ^^
290
291error: wrong infer used: expected _, found: '_
292 --> $DIR/infers.rs:244:48
293 |
294LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11;
295 | ^^
296
297error: wrong infer used: expected _, found: '_
298 --> $DIR/infers.rs:260:34
299 |
300LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3;
301 | ^^
302
303error: wrong infer used: expected '_, found: _
304 --> $DIR/infers.rs:268:23
305 |
306LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5;
307 | ^
308
309error: wrong infer used: expected '_, found: _
310 --> $DIR/infers.rs:268:26
311 |
312LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5;
313 | ^
314
315error: wrong infer used: expected _, found: '_
316 --> $DIR/infers.rs:268:40
317 |
318LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5;
319 | ^^
320
321error: wrong infer used: expected _, found: '_
322 --> $DIR/infers.rs:268:44
323 |
324LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5;
325 | ^^
326
327error: wrong infer used: expected '_, found: _
328 --> $DIR/infers.rs:276:38
329 |
330LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
331 | ^
332
333error: wrong infer used: expected _, found: '_
334 --> $DIR/infers.rs:276:47
335 |
336LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
337 | ^^
338
339error: wrong infer used: expected '_, found: _
340 --> $DIR/infers.rs:283:64
341 |
342LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7;
343 | ^
344
345error: wrong infer used: expected _, found: '_
346 --> $DIR/infers.rs:283:67
347 |
348LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7;
349 | ^^
350
351error: wrong infer used: expected _, found: '_
352 --> $DIR/infers.rs:289:65
353 |
354LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8;
355 | ^^
356
357error: wrong infer used: expected _, found: '_
358 --> $DIR/infers.rs:289:69
359 |
360LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8;
361 | ^^
362
363error: wrong infer used: expected _, found: '_
364 --> $DIR/infers.rs:289:73
365 |
366LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8;
367 | ^^
368
369error: wrong infer used: expected '_, found: _
370 --> $DIR/infers.rs:294:57
371 |
372LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9;
373 | ^
374
375error: wrong infer used: expected _, found: '_
376 --> $DIR/infers.rs:306:41
377 |
378LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11;
379 | ^^
380
381error: wrong infer used: expected _, found: '_
382 --> $DIR/infers.rs:306:44
383 |
384LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11;
385 | ^^
386
387error: wrong infer used: expected _, found: '_
388 --> $DIR/infers.rs:306:48
389 |
390LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11;
391 | ^^
392
393error[E0107]: function takes 1 lifetime argument but 2 lifetime arguments were supplied
394 --> $DIR/infers.rs:44:15
395 |
396LL | reuse foo::<'_, '_> as foo2;
397 | ^^^--------- help: remove the lifetime argument
398 | |
399 | expected 1 lifetime argument
400 |
401note: function defined here, with 1 lifetime parameter: `'c`
402 --> $DIR/infers.rs:38:12
403 |
404LL | fn foo<'a, 'b, 'c: 'c, 'd>(_: &'a &'b &'c &'d ()) {}
405 | ^^^ --
406
407error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied
408 --> $DIR/infers.rs:54:15
409 |
410LL | reuse foo::('_, _, _, _) as bar;
411 | ^^^ expected 1 lifetime argument
412 |
413note: function defined here, with 1 lifetime parameter: `'b`
414 --> $DIR/infers.rs:52:12
415 |
416LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
417 | ^^^ --
418help: add missing lifetime argument
419 |
420LL | reuse foo::('b, '_, _, _, _) as bar;
421 | +++
422
423error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied
424 --> $DIR/infers.rs:54:15
425 |
426LL | reuse foo::('_, _, _, _) as bar;
427 | ^^^ --- help: remove the unnecessary generic argument
428 | |
429 | expected 3 generic arguments
430 |
431note: function defined here, with 3 generic parameters: `X`, `M`, `Y`
432 --> $DIR/infers.rs:52:12
433 |
434LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
435 | ^^^ - -------------- -
436
437error: inferred lifetimes are not allowed in delegations as we need to inherit signature
438 --> $DIR/infers.rs:54:15
439 |
440LL | reuse foo::('_, _, _, _) as bar;
441 | ^^^
442
443error[E0224]: at least one trait is required for an object type
444 --> $DIR/infers.rs:54:21
445 |
446LL | reuse foo::('_, _, _, _) as bar;
447 | ^^
448
449error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
450 --> $DIR/infers.rs:54:25
451 |
452LL | reuse foo::('_, _, _, _) as bar;
453 | ^ not allowed in type signatures
454
455error[E0107]: function takes 3 generic arguments but 5 generic arguments were supplied
456 --> $DIR/infers.rs:86:11
457 |
458LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5;
459 | ^^^---------------------- help: remove the unnecessary generic arguments
460 | |
461 | expected 3 generic arguments
462 |
463note: function defined here, with 3 generic parameters: `X`, `M`, `Y`
464 --> $DIR/infers.rs:79:8
465 |
466LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
467 | ^^^ - -------------- -
468
469error[E0107]: function takes 1 lifetime argument but 3 lifetime arguments were supplied
470 --> $DIR/infers.rs:91:11
471 |
472LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
473 | ^^^---------------------- help: remove the lifetime arguments
474 | |
475 | expected 1 lifetime argument
476 |
477note: function defined here, with 1 lifetime parameter: `'b`
478 --> $DIR/infers.rs:79:8
479 |
480LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
481 | ^^^ --
482
483error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied
484 --> $DIR/infers.rs:91:11
485 |
486LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
487 | ^^^------------------------------- help: remove the unnecessary generic arguments
488 | |
489 | expected 3 generic arguments
490 |
491note: function defined here, with 3 generic parameters: `X`, `M`, `Y`
492 --> $DIR/infers.rs:79:8
493 |
494LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
495 | ^^^ - -------------- -
496
497error[E0107]: function takes 3 generic arguments but 0 generic arguments were supplied
498 --> $DIR/infers.rs:106:11
499 |
500LL | reuse foo::<_> as foo9;
501 | ^^^ expected 3 generic arguments
502 |
503note: function defined here, with 3 generic parameters: `X`, `M`, `Y`
504 --> $DIR/infers.rs:79:8
505 |
506LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
507 | ^^^ - -------------- -
508help: add missing generic arguments
509 |
510LL | reuse fooX, M, Y::<_> as foo9;
511 | +++++++
512
513error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied
514 --> $DIR/infers.rs:110:11
515 |
516LL | reuse foo::<Vec<'_>, _, _, ()> as foo10;
517 | ^^^ expected 1 lifetime argument
518 |
519note: function defined here, with 1 lifetime parameter: `'b`
520 --> $DIR/infers.rs:79:8
521 |
522LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
523 | ^^^ --
524help: add missing lifetime argument
525 |
526LL | reuse foo::<'b, Vec<'_>, _, _, ()> as foo10;
527 | +++
528
529error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied
530 --> $DIR/infers.rs:110:11
531 |
532LL | reuse foo::<Vec<'_>, _, _, ()> as foo10;
533 | ^^^-------------------- help: remove the unnecessary generic argument
534 | |
535 | expected 3 generic arguments
536 |
537note: function defined here, with 3 generic parameters: `X`, `M`, `Y`
538 --> $DIR/infers.rs:79:8
539 |
540LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
541 | ^^^ - -------------- -
542
543error: inferred lifetimes are not allowed in delegations as we need to inherit signature
544 --> $DIR/infers.rs:110:11
545 |
546LL | reuse foo::<Vec<'_>, _, _, ()> as foo10;
547 | ^^^
548
549error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
550 --> $DIR/infers.rs:110:17
551 |
552LL | reuse foo::<Vec<'_>, _, _, ()> as foo10;
553 | ^^^---- help: remove the unnecessary generics
554 | |
555 | expected 0 lifetime arguments
556
557error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied
558 --> $DIR/infers.rs:110:17
559 |
560LL | reuse foo::<Vec<'_>, _, _, ()> as foo10;
561 | ^^^ expected at least 1 generic argument
562 |
563help: add missing generic argument
564 |
565LL | reuse foo::<Vec<'_, T>, _, _, ()> as foo10;
566 | +++
567
568error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied
569 --> $DIR/infers.rs:117:11
570 |
571LL | reuse foo::<Vec<_>, _, _, ()> as foo11;
572 | ^^^ expected 1 lifetime argument
573 |
574note: function defined here, with 1 lifetime parameter: `'b`
575 --> $DIR/infers.rs:79:8
576 |
577LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
578 | ^^^ --
579help: add missing lifetime argument
580 |
581LL | reuse foo::<'b, Vec<_>, _, _, ()> as foo11;
582 | +++
583
584error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied
585 --> $DIR/infers.rs:117:11
586 |
587LL | reuse foo::<Vec<_>, _, _, ()> as foo11;
588 | ^^^------------------- help: remove the unnecessary generic argument
589 | |
590 | expected 3 generic arguments
591 |
592note: function defined here, with 3 generic parameters: `X`, `M`, `Y`
593 --> $DIR/infers.rs:79:8
594 |
595LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
596 | ^^^ - -------------- -
597
598error: inferred lifetimes are not allowed in delegations as we need to inherit signature
599 --> $DIR/infers.rs:117:11
600 |
601LL | reuse foo::<Vec<_>, _, _, ()> as foo11;
602 | ^^^
603
604error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
605 --> $DIR/infers.rs:117:21
606 |
607LL | reuse foo::<Vec<_>, _, _, ()> as foo11;
608 | ^ not allowed in type signatures
609
610error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
611 --> $DIR/infers.rs:128:25
612 |
613LL | reuse foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13;
614 | ^ not allowed in type signatures
615
616error[E0747]: type provided when a constant was expected
617 --> $DIR/infers.rs:128:29
618 |
619LL | reuse foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13;
620 | ^^^^^^^^^^^
621 |
622help: if this generic argument was intended as a const parameter, surround it with braces
623 |
624LL | reuse foo::<'_, Vec<_>, { Vec<Vec<_>> }, _> as foo13;
625 | + +
626
627error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied
628 --> $DIR/infers.rs:135:11
629 |
630LL | reuse foo::<_, _, _> as foo15;
631 | ^^^
632 | |
633 | expected 3 generic arguments
634 | supplied 2 generic arguments
635 |
636note: function defined here, with 3 generic parameters: `X`, `M`, `Y`
637 --> $DIR/infers.rs:79:8
638 |
639LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {}
640 | ^^^ - -------------- -
641help: add missing generic argument
642 |
643LL | reuse fooY::<_, _, _> as foo15;
644 | +
645
646error[E0207]: the type parameter `Some` is not constrained by the impl trait, self type, or predicates
647 --> $DIR/infers.rs:146:18
648 |
649LL | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {}
650 | ^^^^ unconstrained type parameter
651
652error[E0207]: the type parameter `Params` is not constrained by the impl trait, self type, or predicates
653 --> $DIR/infers.rs:146:24
654 |
655LL | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {}
656 | ^^^^^^ unconstrained type parameter
657
658error[E0107]: method takes 3 generic arguments but 5 generic arguments were supplied
659 --> $DIR/infers.rs:158:22
660 |
661LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5;
662 | ^^^---------------------- help: remove the unnecessary generic arguments
663 | |
664 | expected 3 generic arguments
665 |
666note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
667 --> $DIR/infers.rs:142:12
668 |
669LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
670 | ^^^ -- -------------- --
671
672error[E0107]: method takes 1 lifetime argument but 3 lifetime arguments were supplied
673 --> $DIR/infers.rs:163:22
674 |
675LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
676 | ^^^---------------------- help: remove the lifetime arguments
677 | |
678 | expected 1 lifetime argument
679 |
680note: method defined here, with 1 lifetime parameter: `'bb`
681 --> $DIR/infers.rs:142:12
682 |
683LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
684 | ^^^ ---
685
686error[E0107]: method takes 3 generic arguments but 6 generic arguments were supplied
687 --> $DIR/infers.rs:163:22
688 |
689LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
690 | ^^^------------------------------- help: remove the unnecessary generic arguments
691 | |
692 | expected 3 generic arguments
693 |
694note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
695 --> $DIR/infers.rs:142:12
696 |
697LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
698 | ^^^ -- -------------- --
699
700error[E0107]: method takes 3 generic arguments but 0 generic arguments were supplied
701 --> $DIR/infers.rs:178:22
702 |
703LL | reuse Trait::foo::<_> as foo9;
704 | ^^^ expected 3 generic arguments
705 |
706note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
707 --> $DIR/infers.rs:142:12
708 |
709LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
710 | ^^^ -- -------------- --
711help: add missing generic arguments
712 |
713LL | reuse Trait::fooXX, M, YY::<_> as foo9;
714 | +++++++++
715
716error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied
717 --> $DIR/infers.rs:182:22
718 |
719LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10;
720 | ^^^ expected 1 lifetime argument
721 |
722note: method defined here, with 1 lifetime parameter: `'bb`
723 --> $DIR/infers.rs:142:12
724 |
725LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
726 | ^^^ ---
727help: add missing lifetime argument
728 |
729LL | reuse Trait::foo::<'a, Vec<'_>, _, _, ()> as foo10;
730 | +++
731
732error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied
733 --> $DIR/infers.rs:182:22
734 |
735LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10;
736 | ^^^-------------------- help: remove the unnecessary generic argument
737 | |
738 | expected 3 generic arguments
739 |
740note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
741 --> $DIR/infers.rs:142:12
742 |
743LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
744 | ^^^ -- -------------- --
745
746error: inferred lifetimes are not allowed in delegations as we need to inherit signature
747 --> $DIR/infers.rs:182:22
748 |
749LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10;
750 | ^^^
751
752error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
753 --> $DIR/infers.rs:182:28
754 |
755LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10;
756 | ^^^---- help: remove the unnecessary generics
757 | |
758 | expected 0 lifetime arguments
759
760error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied
761 --> $DIR/infers.rs:182:28
762 |
763LL | reuse Trait::foo::<Vec<'_>, _, _, ()> as foo10;
764 | ^^^ expected at least 1 generic argument
765 |
766help: add missing generic argument
767 |
768LL | reuse Trait::foo::<Vec<'_, T>, _, _, ()> as foo10;
769 | +++
770
771error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied
772 --> $DIR/infers.rs:189:22
773 |
774LL | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11;
775 | ^^^ expected 1 lifetime argument
776 |
777note: method defined here, with 1 lifetime parameter: `'bb`
778 --> $DIR/infers.rs:142:12
779 |
780LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
781 | ^^^ ---
782help: add missing lifetime argument
783 |
784LL | reuse Trait::foo::<'a, Vec<_>, _, _, ()> as foo11;
785 | +++
786
787error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied
788 --> $DIR/infers.rs:189:22
789 |
790LL | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11;
791 | ^^^------------------- help: remove the unnecessary generic argument
792 | |
793 | expected 3 generic arguments
794 |
795note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
796 --> $DIR/infers.rs:142:12
797 |
798LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
799 | ^^^ -- -------------- --
800
801error: inferred lifetimes are not allowed in delegations as we need to inherit signature
802 --> $DIR/infers.rs:189:22
803 |
804LL | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11;
805 | ^^^
806
807error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
808 --> $DIR/infers.rs:189:32
809 |
810LL | reuse Trait::foo::<Vec<_>, _, _, ()> as foo11;
811 | ^ not allowed in type signatures
812
813error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
814 --> $DIR/infers.rs:200:36
815 |
816LL | reuse Trait::foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13;
817 | ^ not allowed in type signatures
818
819error[E0747]: type provided when a constant was expected
820 --> $DIR/infers.rs:200:40
821 |
822LL | reuse Trait::foo::<'_, Vec<_>, Vec<Vec<_>>, _> as foo13;
823 | ^^^^^^^^^^^
824 |
825help: if this generic argument was intended as a const parameter, surround it with braces
826 |
827LL | reuse Trait::foo::<'_, Vec<_>, { Vec<Vec<_>> }, _> as foo13;
828 | + +
829
830error[E0107]: method takes 3 generic arguments but 2 generic arguments were supplied
831 --> $DIR/infers.rs:207:22
832 |
833LL | reuse Trait::foo::<_, _, _> as foo15;
834 | ^^^
835 | |
836 | expected 3 generic arguments
837 | supplied 2 generic arguments
838 |
839note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
840 --> $DIR/infers.rs:142:12
841 |
842LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
843 | ^^^ -- -------------- --
844help: add missing generic argument
845 |
846LL | reuse Trait::fooYY::<_, _, _> as foo15;
847 | ++
848
849error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
850 --> $DIR/infers.rs:218:15
851 |
852LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3;
853 | ^^^^^ --- supplied 1 lifetime argument
854 | |
855 | expected 2 lifetime arguments
856 |
857note: trait defined here, with 2 lifetime parameters: `'a`, `'b`
858 --> $DIR/infers.rs:141:15
859 |
860LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
861 | ^^^^^ -- --
862help: add missing lifetime argument
863 |
864LL | reuse Trait::<'_, (), _, '_, _>::foo, 'a as foo3;
865 | ++++
866
867error[E0107]: trait takes 3 generic arguments but 4 generic arguments were supplied
868 --> $DIR/infers.rs:218:15
869 |
870LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3;
871 | ^^^^^ --- help: remove the unnecessary generic argument
872 | |
873 | expected 3 generic arguments
874 |
875note: trait defined here, with 3 generic parameters: `X`, `C`, `Y`
876 --> $DIR/infers.rs:141:15
877 |
878LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
879 | ^^^^^ - -------------- -
880
881error: inferred lifetimes are not allowed in delegations as we need to inherit signature
882 --> $DIR/infers.rs:218:15
883 |
884LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3;
885 | ^^^^^
886
887error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied
888 --> $DIR/infers.rs:226:15
889 |
890LL | reuse Trait::<_, _>::foo as foo5;
891 | ^^^^^ expected 3 generic arguments
892 |
893note: trait defined here, with 3 generic parameters: `X`, `C`, `Y`
894 --> $DIR/infers.rs:141:15
895 |
896LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
897 | ^^^^^ - -------------- -
898help: add missing generic arguments
899 |
900LL | reuse Trait::<_, _>::foo, X, C, Y as foo5;
901 | +++++++++
902
903error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
904 --> $DIR/infers.rs:231:15
905 |
906LL | reuse Trait::<'_, '_>::foo as foo6;
907 | ^^^^^ not allowed in type signatures
908
909error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
910 --> $DIR/infers.rs:234:35
911 |
912LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo as foo7;
913 | ^ not allowed in type signatures
914
915error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
916 --> $DIR/infers.rs:234:52
917 |
918LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo as foo7;
919 | ^ not allowed in type signatures
920
921error[E0107]: trait takes 3 generic arguments but 7 generic arguments were supplied
922 --> $DIR/infers.rs:241:15
923 |
924LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo as foo10;
925 | ^^^^^ expected 3 generic arguments ------- help: remove the unnecessary generic arguments
926 |
927note: trait defined here, with 3 generic parameters: `X`, `C`, `Y`
928 --> $DIR/infers.rs:141:15
929 |
930LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
931 | ^^^^^ - -------------- -
932
933error[E0107]: trait takes 2 lifetime arguments but 6 lifetime arguments were supplied
934 --> $DIR/infers.rs:244:15
935 |
936LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11;
937 | ^^^^^ --------------------------- help: remove the lifetime arguments
938 | |
939 | expected 2 lifetime arguments
940 |
941note: trait defined here, with 2 lifetime parameters: `'a`, `'b`
942 --> $DIR/infers.rs:141:15
943 |
944LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
945 | ^^^^^ -- --
946
947error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied
948 --> $DIR/infers.rs:250:15
949 |
950LL | reuse Trait::<'static, 'static, _>::foo as foo12;
951 | ^^^^^ --- supplied 1 generic argument
952 | |
953 | expected 3 generic arguments
954 |
955note: trait defined here, with 3 generic parameters: `X`, `C`, `Y`
956 --> $DIR/infers.rs:141:15
957 |
958LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
959 | ^^^^^ - -------------- -
960help: add missing generic arguments
961 |
962LL | reuse Trait::<'static, 'static, _>::foo, C, Y as foo12;
963 | ++++++
964
965error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
966 --> $DIR/infers.rs:260:15
967 |
968LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3;
969 | ^^^^^ --- supplied 1 lifetime argument
970 | |
971 | expected 2 lifetime arguments
972 |
973note: trait defined here, with 2 lifetime parameters: `'a`, `'b`
974 --> $DIR/infers.rs:141:15
975 |
976LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
977 | ^^^^^ -- --
978help: add missing lifetime argument
979 |
980LL | reuse Trait::<'_, (), _, '_, _>::foo, 'a::<'static, String, _, _> as foo3;
981 | ++++
982
983error[E0107]: trait takes 3 generic arguments but 4 generic arguments were supplied
984 --> $DIR/infers.rs:260:15
985 |
986LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3;
987 | ^^^^^ --- help: remove the unnecessary generic argument
988 | |
989 | expected 3 generic arguments
990 |
991note: trait defined here, with 3 generic parameters: `X`, `C`, `Y`
992 --> $DIR/infers.rs:141:15
993 |
994LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
995 | ^^^^^ - -------------- -
996
997error: inferred lifetimes are not allowed in delegations as we need to inherit signature
998 --> $DIR/infers.rs:260:15
999 |
1000LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3;
1001 | ^^^^^
1002
1003error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied
1004 --> $DIR/infers.rs:268:15
1005 |
1006LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5;
1007 | ^^^^^ expected 3 generic arguments
1008 |
1009note: trait defined here, with 3 generic parameters: `X`, `C`, `Y`
1010 --> $DIR/infers.rs:141:15
1011 |
1012LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
1013 | ^^^^^ - -------------- -
1014help: add missing generic arguments
1015 |
1016LL | reuse Trait::<_, _>::foo, X, C, Y::<'_, '_, '_, _, _, _,> as foo5;
1017 | +++++++++
1018
1019error[E0107]: method takes 3 generic arguments but 5 generic arguments were supplied
1020 --> $DIR/infers.rs:268:30
1021 |
1022LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5;
1023 | ^^^---------------------- help: remove the unnecessary generic arguments
1024 | |
1025 | expected 3 generic arguments
1026 |
1027note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
1028 --> $DIR/infers.rs:142:12
1029 |
1030LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
1031 | ^^^ -- -------------- --
1032
1033error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
1034 --> $DIR/infers.rs:276:15
1035 |
1036LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
1037 | ^^^^^ not allowed in type signatures
1038
1039error[E0107]: method takes 1 lifetime argument but 3 lifetime arguments were supplied
1040 --> $DIR/infers.rs:276:32
1041 |
1042LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
1043 | ^^^---------------------- help: remove the lifetime arguments
1044 | |
1045 | expected 1 lifetime argument
1046 |
1047note: method defined here, with 1 lifetime parameter: `'bb`
1048 --> $DIR/infers.rs:142:12
1049 |
1050LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
1051 | ^^^ ---
1052
1053error[E0107]: method takes 3 generic arguments but 6 generic arguments were supplied
1054 --> $DIR/infers.rs:276:32
1055 |
1056LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6;
1057 | ^^^------------------------------- help: remove the unnecessary generic arguments
1058 | |
1059 | expected 3 generic arguments
1060 |
1061note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
1062 --> $DIR/infers.rs:142:12
1063 |
1064LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
1065 | ^^^ -- -------------- --
1066
1067error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
1068 --> $DIR/infers.rs:283:35
1069 |
1070LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7;
1071 | ^ not allowed in type signatures
1072
1073error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
1074 --> $DIR/infers.rs:283:52
1075 |
1076LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec<Vec<_>>>::foo::<_, '_, _, _> as foo7;
1077 | ^ not allowed in type signatures
1078
1079error[E0107]: method takes 3 generic arguments but 0 generic arguments were supplied
1080 --> $DIR/infers.rs:294:51
1081 |
1082LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9;
1083 | ^^^ expected 3 generic arguments
1084 |
1085note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
1086 --> $DIR/infers.rs:142:12
1087 |
1088LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
1089 | ^^^ -- -------------- --
1090help: add missing generic arguments
1091 |
1092LL | reuse Trait::<'static, 'static, _, _, _>::fooXX, M, YY::<_> as foo9;
1093 | +++++++++
1094
1095error[E0107]: trait takes 3 generic arguments but 7 generic arguments were supplied
1096 --> $DIR/infers.rs:298:15
1097 |
1098LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10;
1099 | ^^^^^ expected 3 generic arguments ------- help: remove the unnecessary generic arguments
1100 |
1101note: trait defined here, with 3 generic parameters: `X`, `C`, `Y`
1102 --> $DIR/infers.rs:141:15
1103 |
1104LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
1105 | ^^^^^ - -------------- -
1106
1107error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied
1108 --> $DIR/infers.rs:298:63
1109 |
1110LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10;
1111 | ^^^ expected 1 lifetime argument
1112 |
1113note: method defined here, with 1 lifetime parameter: `'bb`
1114 --> $DIR/infers.rs:142:12
1115 |
1116LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
1117 | ^^^ ---
1118help: add missing lifetime argument
1119 |
1120LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<'bb, Vec<'_>, _, _, ()> as foo10;
1121 | ++++
1122
1123error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied
1124 --> $DIR/infers.rs:298:63
1125 |
1126LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10;
1127 | ^^^-------------------- help: remove the unnecessary generic argument
1128 | |
1129 | expected 3 generic arguments
1130 |
1131note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
1132 --> $DIR/infers.rs:142:12
1133 |
1134LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
1135 | ^^^ -- -------------- --
1136
1137error: inferred lifetimes are not allowed in delegations as we need to inherit signature
1138 --> $DIR/infers.rs:298:63
1139 |
1140LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10;
1141 | ^^^
1142
1143error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
1144 --> $DIR/infers.rs:298:69
1145 |
1146LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10;
1147 | ^^^---- help: remove the unnecessary generics
1148 | |
1149 | expected 0 lifetime arguments
1150
1151error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied
1152 --> $DIR/infers.rs:298:69
1153 |
1154LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_>, _, _, ()> as foo10;
1155 | ^^^ expected at least 1 generic argument
1156 |
1157help: add missing generic argument
1158 |
1159LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<Vec<'_, T>, _, _, ()> as foo10;
1160 | +++
1161
1162error[E0107]: trait takes 2 lifetime arguments but 5 lifetime arguments were supplied
1163 --> $DIR/infers.rs:306:15
1164 |
1165LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11;
1166 | ^^^^^ ----------------------- help: remove the lifetime arguments
1167 | |
1168 | expected 2 lifetime arguments
1169 |
1170note: trait defined here, with 2 lifetime parameters: `'a`, `'b`
1171 --> $DIR/infers.rs:141:15
1172 |
1173LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
1174 | ^^^^^ -- --
1175
1176error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied
1177 --> $DIR/infers.rs:306:65
1178 |
1179LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11;
1180 | ^^^ expected 1 lifetime argument
1181 |
1182note: method defined here, with 1 lifetime parameter: `'bb`
1183 --> $DIR/infers.rs:142:12
1184 |
1185LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
1186 | ^^^ ---
1187help: add missing lifetime argument
1188 |
1189LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<'bb, Vec<_>, _, _, ()> as foo11;
1190 | ++++
1191
1192error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied
1193 --> $DIR/infers.rs:306:65
1194 |
1195LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11;
1196 | ^^^------------------- help: remove the unnecessary generic argument
1197 | |
1198 | expected 3 generic arguments
1199 |
1200note: method defined here, with 3 generic parameters: `XX`, `M`, `YY`
1201 --> $DIR/infers.rs:142:12
1202 |
1203LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {}
1204 | ^^^ -- -------------- --
1205
1206error: inferred lifetimes are not allowed in delegations as we need to inherit signature
1207 --> $DIR/infers.rs:306:65
1208 |
1209LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11;
1210 | ^^^
1211
1212error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
1213 --> $DIR/infers.rs:306:75
1214 |
1215LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<Vec<_>, _, _, ()> as foo11;
1216 | ^ not allowed in type signatures
1217
1218error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied
1219 --> $DIR/infers.rs:316:15
1220 |
1221LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12;
1222 | ^^^^^ --- supplied 1 generic argument
1223 | |
1224 | expected 3 generic arguments
1225 |
1226note: trait defined here, with 3 generic parameters: `X`, `C`, `Y`
1227 --> $DIR/infers.rs:141:15
1228 |
1229LL | pub trait Trait<'a, 'b, X, const C: usize, Y> {
1230 | ^^^^^ - -------------- -
1231help: add missing generic arguments
1232 |
1233LL | reuse Trait::<'static, 'static, _>::foo, C, Y::<'____, ___, _, ___> as foo12;
1234 | ++++++
1235
1236error[E0308]: mismatched types
1237 --> $DIR/infers.rs:338:42
1238 |
1239LL | reuse to_reuse::foo::<_, _, _> { self.0 }
1240 | --- ^^^^^^ expected `()`, found `S`
1241 | |
1242 | arguments to this function are incorrect
1243 |
1244note: function defined here
1245 --> $DIR/infers.rs:333:16
1246 |
1247LL | pub fn foo<X, const M: usize, Y>(_: ()) {}
1248 | ^^^ -----
1249
1250error[E0107]: function takes 0 lifetime arguments but 1 lifetime argument was supplied
1251 --> $DIR/infers.rs:344:25
1252 |
1253LL | reuse to_reuse::foo { self.0 }
1254 | ^^^
1255 | |
1256 | expected 0 lifetime arguments
1257 | help: remove the lifetime argument
1258 |
1259note: function defined here, with 0 lifetime parameters
1260 --> $DIR/infers.rs:333:16
1261 |
1262LL | pub fn foo<X, const M: usize, Y>(_: ()) {}
1263 | ^^^
1264
1265error[E0308]: mismatched types
1266 --> $DIR/infers.rs:344:31
1267 |
1268LL | reuse to_reuse::foo { self.0 }
1269 | --- ^^^^^^ expected `()`, found `S`
1270 | |
1271 | arguments to this function are incorrect
1272 |
1273note: function defined here
1274 --> $DIR/infers.rs:333:16
1275 |
1276LL | pub fn foo<X, const M: usize, Y>(_: ()) {}
1277 | ^^^ -----
1278
1279error[E0308]: mismatched types
1280 --> $DIR/infers.rs:351:46
1281 |
1282LL | reuse to_reuse::foo::<(), 123, ()> { self.0 }
1283 | --- ^^^^^^ expected `()`, found `S`
1284 | |
1285 | arguments to this function are incorrect
1286 |
1287note: function defined here
1288 --> $DIR/infers.rs:333:16
1289 |
1290LL | pub fn foo<X, const M: usize, Y>(_: ()) {}
1291 | ^^^ -----
1292
1293error: aborting due to 138 previous errors
1294
1295Some errors have detailed explanations: E0107, E0121, E0207, E0214, E0224, E0261, E0308, E0425, E0747.
1296For 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 {
2626
2727 reuse to_reuse::bar1;
2828 //~^ 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
2930
3031 reuse to_reuse::bar2;
3132 //~^ ERROR: type annotations needed
......@@ -59,8 +60,10 @@ mod test_2 {
5960 impl Trait<String, 1> for X {
6061 reuse <X as Trait1>::bar;
6162 //~^ ERROR: missing generics for trait
63 //~| ERROR: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied
6264
6365 reuse <X as Trait1::<bool, bool>>::bar as bar1;
66 //~^ ERROR: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied
6467
6568 reuse <X as Trait1::<bool, bool>>::bar::<'static, u32, u32, 1> as bar2;
6669
......@@ -94,9 +97,11 @@ mod test_3 {
9497 impl Trait<String, 1> for X {
9598 reuse <X as Trait1::<(), ()>>::bar;
9699 //~^ 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
97101
98102 reuse <X as Trait1::<(), ()>>::bar as bar1;
99103 //~^ 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
100105
101106 reuse <X as Trait1::<(), ()>>::foo as bar2;
102107 //~^ 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`
1313LL | pub fn bar<'a: 'a, 'b: 'b, A, B>(x: &super::XX) {}
1414 | ^^^ - -
1515
16error[E0107]: function takes 0 lifetime arguments but 2 lifetime arguments were supplied
17 --> $DIR/trait-impl-wrong-args-count.rs:27:25
18 |
19LL | reuse to_reuse::bar1;
20 | ^^^^
21 | |
22 | expected 0 lifetime arguments
23 | help: remove the lifetime arguments
24 |
25note: function defined here, with 0 lifetime parameters
26 --> $DIR/trait-impl-wrong-args-count.rs:7:16
27 |
28LL | pub fn bar1(x: &super::XX) {}
29 | ^^^^
30
1631error[E0107]: function takes 0 generic arguments but 3 generic arguments were supplied
1732 --> $DIR/trait-impl-wrong-args-count.rs:27:25
1833 |
1934LL | reuse to_reuse::bar1;
20 | ^^^^ expected 0 generic arguments
35 | ^^^^
36 | |
37 | expected 0 generic arguments
38 | help: remove the unnecessary generic arguments
2139 |
2240note: function defined here, with 0 generic parameters
2341 --> $DIR/trait-impl-wrong-args-count.rs:7:16
......@@ -26,7 +44,7 @@ LL | pub fn bar1(x: &super::XX) {}
2644 | ^^^^
2745
2846error[E0284]: type annotations needed
29 --> $DIR/trait-impl-wrong-args-count.rs:30:25
47 --> $DIR/trait-impl-wrong-args-count.rs:31:25
3048 |
3149LL | reuse to_reuse::bar2;
3250 | ^^^^ 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>;
4260 | ++++++++++++++++++++++++++
4361
4462error[E0284]: type annotations needed
45 --> $DIR/trait-impl-wrong-args-count.rs:30:25
63 --> $DIR/trait-impl-wrong-args-count.rs:31:25
4664 |
4765LL | reuse to_reuse::bar2;
4866 | ^^^^ 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>;
5876 | ++++++++++++++++++++++++++
5977
6078error[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
6280 |
6381LL | reuse <X as Trait1>::bar;
6482 | ^^^^^^ expected 2 generic arguments
6583 |
6684note: 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
6886 |
6987LL | trait Trait1<A, B> {
7088 | ^^^^^^ - -
......@@ -73,14 +91,44 @@ help: add missing generic arguments
7391LL | reuse <X as Trait1<A, B>>::bar;
7492 | ++++++
7593
94error[E0107]: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied
95 --> $DIR/trait-impl-wrong-args-count.rs:61:30
96 |
97LL | reuse <X as Trait1>::bar;
98 | ^^^
99 | |
100 | expected 1 lifetime argument
101 | help: remove the lifetime argument
102 |
103note: associated function defined here, with 1 lifetime parameter: `'x`
104 --> $DIR/trait-impl-wrong-args-count.rs:53:12
105 |
106LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {}
107 | ^^^ --
108
109error[E0107]: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied
110 --> $DIR/trait-impl-wrong-args-count.rs:65:44
111 |
112LL | reuse <X as Trait1::<bool, bool>>::bar as bar1;
113 | ^^^
114 | |
115 | expected 1 lifetime argument
116 | help: remove the lifetime argument
117 |
118note: associated function defined here, with 1 lifetime parameter: `'x`
119 --> $DIR/trait-impl-wrong-args-count.rs:53:12
120 |
121LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {}
122 | ^^^ --
123
76124error[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
78126 |
79127LL | reuse <X as Trait1>::bar::<'static, u32, u32, 1> as bar3;
80128 | ^^^^^^ expected 2 generic arguments
81129 |
82130note: 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
84132 |
85133LL | trait Trait1<A, B> {
86134 | ^^^^^^ - -
......@@ -90,13 +138,13 @@ LL | reuse <X as Trait1<A, B>>::bar::<'static, u32, u32, 1> as bar3;
90138 | ++++++
91139
92140error[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
94142 |
95143LL | reuse <X as Trait1>::bar as bar4;
96144 | ^^^^^^ expected 2 generic arguments
97145 |
98146note: 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
100148 |
101149LL | trait Trait1<A, B> {
102150 | ^^^^^^ - -
......@@ -105,38 +153,74 @@ help: add missing generic arguments
105153LL | reuse <X as Trait1<A, B>>::bar as bar4;
106154 | ++++++
107155
156error[E0107]: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied
157 --> $DIR/trait-impl-wrong-args-count.rs:98:40
158 |
159LL | reuse <X as Trait1::<(), ()>>::bar;
160 | ^^^
161 | |
162 | expected 0 lifetime arguments
163 | help: remove the lifetime arguments
164 |
165note: associated function defined here, with 0 lifetime parameters
166 --> $DIR/trait-impl-wrong-args-count.rs:89:12
167 |
168LL | fn bar() {}
169 | ^^^
170
108171error[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
110173 |
111174LL | reuse <X as Trait1::<(), ()>>::bar;
112 | ^^^ expected 0 generic arguments
175 | ^^^
176 | |
177 | expected 0 generic arguments
178 | help: remove the unnecessary generic arguments
113179 |
114180note: 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 |
183LL | fn bar() {}
184 | ^^^
185
186error[E0107]: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied
187 --> $DIR/trait-impl-wrong-args-count.rs:102:40
188 |
189LL | reuse <X as Trait1::<(), ()>>::bar as bar1;
190 | ^^^
191 | |
192 | expected 0 lifetime arguments
193 | help: remove the lifetime arguments
194 |
195note: associated function defined here, with 0 lifetime parameters
196 --> $DIR/trait-impl-wrong-args-count.rs:89:12
116197 |
117198LL | fn bar() {}
118199 | ^^^
119200
120201error[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
122203 |
123204LL | 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
125209 |
126210note: 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
128212 |
129213LL | fn bar() {}
130214 | ^^^
131215
132216error[E0282]: type annotations needed
133 --> $DIR/trait-impl-wrong-args-count.rs:101:40
217 --> $DIR/trait-impl-wrong-args-count.rs:106:40
134218 |
135219LL | reuse <X as Trait1::<(), ()>>::foo as bar2;
136220 | ^^^ cannot infer type of the type parameter `X` declared on the associated function `foo`
137221
138222error[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
140224 |
141225LL | reuse <X as Trait1::<(), ()>>::foo as bar3;
142226 | ^^^
......@@ -145,12 +229,12 @@ LL | reuse <X as Trait1::<(), ()>>::foo as bar3;
145229 | help: remove the unnecessary generic argument
146230 |
147231note: 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
149233 |
150234LL | fn foo<X, Y>() {}
151235 | ^^^ - -
152236
153error: aborting due to 11 previous errors
237error: aborting due to 16 previous errors
154238
155239Some errors have detailed explanations: E0107, E0282, E0284.
156240For 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
12//@ compile-flags: -Z deduplicate-diagnostics=yes
23
34#![feature(fn_delegation)]
......@@ -12,11 +13,8 @@ impl Trait for F {}
1213struct S(F);
1314impl S {
1415 reuse Trait::foo::<> { self.0 }
15 //~^ ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
16
1617 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!
2018}
2119
2220fn main() {}
tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr deleted-27
......@@ -1,27 +0,0 @@
1error: 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 |
4LL | reuse Trait::foo::<> { self.0 }
5 | ^^^
6
7warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
8 --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:16:24
9 |
10LL | fn foo<'a: 'a>(&self) {}
11 | - the late bound lifetime parameter is introduced here
12...
13LL | 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
20error: 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 |
23LL | reuse Trait::foo::<'_> as bar { self.0 }
24 | ^^
25
26error: aborting due to 2 previous errors; 1 warning emitted
27
tests/ui/delegation/self-ty-ice-156388.rs+2-1
......@@ -1,8 +1,9 @@
11//@ compile-flags: -Z deduplicate-diagnostics=yes
22
3#![feature(const_trait_impl)]
34#![feature(fn_delegation)]
45
56reuse Default::default;
6//~^ ERROR: delegation self type is not specified
7//~^ ERROR: the trait bound `Self: [const] Default` is not satisfied
78
89fn main() {}
tests/ui/delegation/self-ty-ice-156388.stderr+7-3
......@@ -1,10 +1,14 @@
1error: delegation self type is not specified
2 --> $DIR/self-ty-ice-156388.rs:5:16
1error[E0277]: the trait bound `Self: [const] Default` is not satisfied
2 --> $DIR/self-ty-ice-156388.rs:6:16
33 |
44LL | reuse Default::default;
55 | ^^^^^^^
66 |
7 = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
7help: consider restricting type parameter `Self` with trait `Default`
8 |
9LL | reuse Default::default [const] std::default::Default;
10 | +++++++++++++++++++++++++++++
811
912error: aborting due to 1 previous error
1013
14For 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 }
1515
1616fn bar<T: Default>(_: T) {
1717 reuse Trait::static_method {
18 //~^ ERROR: delegation self type is not specified
1918 let _ = T::Default();
2019 //~^ ERROR can't use generic parameters from outer item
2120 }
tests/ui/delegation/target-expr.stderr+6-15
......@@ -1,18 +1,17 @@
11error[E0401]: can't use generic parameters from outer item
2 --> $DIR/target-expr.rs:19:17
2 --> $DIR/target-expr.rs:18:17
33 |
44LL | fn bar<T: Default>(_: T) {
55 | - type parameter from outer item
66LL | reuse Trait::static_method {
77 | ------------- generic parameter used in this inner delegated function
8LL |
98LL | let _ = T::Default();
109 | ^ use of generic parameter from outer item
1110 |
1211 = note: nested items are independent from their parent item for everything except for privacy and name resolution
1312
1413error[E0434]: can't capture dynamic environment in a fn item
15 --> $DIR/target-expr.rs:27:17
14 --> $DIR/target-expr.rs:26:17
1615 |
1716LL | let x = y;
1817 | ^
......@@ -20,7 +19,7 @@ LL | let x = y;
2019 = help: use the `|| { ... }` closure form instead
2120
2221error[E0424]: expected value, found module `self`
23 --> $DIR/target-expr.rs:34:5
22 --> $DIR/target-expr.rs:33:5
2423 |
2524LL | fn main() {
2625 | ---- this function can't have a `self` parameter
......@@ -29,26 +28,18 @@ LL | self.0;
2928 | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
3029
3130error[E0425]: cannot find value `x` in this scope
32 --> $DIR/target-expr.rs:36:13
31 --> $DIR/target-expr.rs:35:13
3332 |
3433LL | let z = x;
3534 | ^
3635 |
3736help: 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
3938 |
4039LL | let x = y;
4140 | ^
4241
43error: delegation self type is not specified
44 --> $DIR/target-expr.rs:17:18
45 |
46LL | reuse Trait::static_method {
47 | ^^^^^^^^^^^^^
48 |
49 = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
50
51error: aborting due to 5 previous errors
42error: aborting due to 4 previous errors
5243
5344Some errors have detailed explanations: E0401, E0424, E0425, E0434.
5445For 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;
2020 = note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret` is compatible with trait definition
2121 = 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>
2222
23error: delegation self type is not specified
24 --> $DIR/unsupported.rs:54:18
25 |
26LL | reuse Trait::foo;
27 | ^^^
28 |
29 = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
30
31error: aborting due to 3 previous errors
23error: aborting due to 2 previous errors
3224
3325For 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;
2020 = note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret` is compatible with trait definition
2121 = 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>
2222
23error: delegation self type is not specified
24 --> $DIR/unsupported.rs:54:18
25 |
26LL | reuse Trait::foo;
27 | ^^^
28 |
29 = help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
30
31error: aborting due to 3 previous errors
23error: aborting due to 2 previous errors
3224
3325For more information about this error, try `rustc --explain E0391`.
tests/ui/delegation/unsupported.rs-1
......@@ -52,7 +52,6 @@ mod effects {
5252 }
5353
5454 reuse Trait::foo;
55 //~^ ERROR: delegation self type is not specified
5655}
5756
5857fn 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)]
4struct 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)]
42struct 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)]
59struct 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
75fn 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)]
6enum Foo {}
7
8fn main() {}
tests/ui/derives/derive-error-identifies-unsafe-trait-name.stderr created+27
......@@ -0,0 +1,27 @@
1error: cannot find derive macro `Sync` in this scope
2 --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10
3 |
4LL | Sync,
5 | ^^^^
6 |
7note: unsafe traits like `Sync` should be implemented explicitly
8 --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10
9 |
10LL | Sync,
11 | ^^^^
12
13error: cannot find derive macro `Sync` in this scope
14 --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10
15 |
16LL | Sync,
17 | ^^^^
18 |
19note: unsafe traits like `Sync` should be implemented explicitly
20 --> $DIR/derive-error-identifies-unsafe-trait-name.rs:3:10
21 |
22LL | Sync,
23 | ^^^^
24 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
25
26error: 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
2struct Foo;
3#[derive(Copy, Clone)]
4struct Bar(Foo);
5//~^ ERROR: the trait `Copy` cannot be implemented for this type
6//~| ERROR: `Foo: Clone` is not satisfied
7
8fn main() {}
tests/ui/derives/derived-trait-requires-field-impl.stderr created+28
......@@ -0,0 +1,28 @@
1error[E0204]: the trait `Copy` cannot be implemented for this type
2 --> $DIR/derived-trait-requires-field-impl.rs:4:8
3 |
4LL | #[derive(Copy, Clone)]
5 | ---- in this derive macro expansion
6LL | struct Bar(Foo);
7 | ^^^ --- this field does not implement `Copy`
8
9error[E0277]: the trait bound `Foo: Clone` is not satisfied
10 --> $DIR/derived-trait-requires-field-impl.rs:4:12
11 |
12LL | #[derive(Copy, Clone)]
13 | ----- in this derive macro expansion
14LL | struct Bar(Foo);
15 | ^^^ the trait `Clone` is not implemented for `Foo`
16 |
17note: required by a bound in `std::clone::AssertParamIsClone`
18 --> $SRC_DIR/core/src/clone.rs:LL:COL
19help: consider annotating `Foo` with `#[derive(Clone)]`
20 |
21LL + #[derive(Clone)]
22LL | struct Foo;
23 |
24
25error: aborting due to 2 previous errors
26
27Some errors have detailed explanations: E0204, E0277.
28For 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
32//@ check-pass
43#![allow(dead_code)]
54
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
5trait Resources {
6 type Buffer: Copy;
7}
8
9#[derive(Copy, Clone)]
10struct ConstantBufferSet<R: Resources>(
11 pub R::Buffer
12);
13
14#[derive(Copy, Clone)]
15enum It {}
16impl Resources for It {
17 type Buffer = u8;
18}
19
20#[derive(Copy, Clone)]
21enum Command {
22 BindConstantBuffers(ConstantBufferSet<It>)
23}
24
25fn 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
2trait Foo {}
3#[derive(Foo::Anything)] //~ ERROR cannot find
4 //~| ERROR cannot find
5struct S;
6
7fn main() {}
tests/ui/derives/no-ice-on-path-style-derive-macro.stderr created+17
......@@ -0,0 +1,17 @@
1error[E0433]: cannot find derive macro `Anything` in trait `Foo`
2 --> $DIR/no-ice-on-path-style-derive-macro.rs:3:10
3 |
4LL | #[derive(Foo::Anything)]
5 | ^^^^^^^^^^^^^ a derive macro can't exist within a trait
6
7error[E0433]: cannot find derive macro `Anything` in trait `Foo`
8 --> $DIR/no-ice-on-path-style-derive-macro.rs:3:10
9 |
10LL | #[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
15error: aborting due to 2 previous errors
16
17For 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)]
6struct Foo;
7
8fn 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
12use std::rc::Rc;
13
14struct Foo<'r>(&'r mut i32);
15
16impl<'r> Drop for Foo<'r> {
17 fn drop(&mut self) {
18 *self.0 += 1;
19 }
20}
21
22fn 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
12pub fn noop_fold_impl_item() -> SmallVector<ImplItem> {
13 loop { }
14}
15
16pub struct SmallVector<T>(P<T>);
17pub struct ImplItem(P<S01_Method>);
18
19struct P<T>(Box<T>);
20
21struct S01_Method(P<S02_Generics>);
22struct S02_Generics(P<S03_TyParam>);
23struct S03_TyParam(P<S04_TyParamBound>);
24struct S04_TyParamBound(S05_PolyTraitRef);
25struct S05_PolyTraitRef(S06_TraitRef);
26struct S06_TraitRef(S07_Path);
27struct S07_Path(Vec<S08_PathSegment>);
28struct S08_PathSegment(S09_GenericArgs);
29struct S09_GenericArgs(P<S10_ParenthesizedParameterData>);
30struct S10_ParenthesizedParameterData(Option<P<S11_Ty>>);
31struct S11_Ty(P<S12_Expr>);
32struct S12_Expr(P<S13_Block>);
33struct S13_Block(Vec<P<S14_Stmt>>);
34struct S14_Stmt(P<S15_Decl>);
35struct S15_Decl(P<S16_Local>);
36struct S16_Local(P<S17_Pat>);
37struct S17_Pat(P<S18_Mac>);
38struct S18_Mac(Vec<P<S19_TokenTree>>);
39struct S19_TokenTree(P<S20_Token>);
40struct S20_Token(P<S21_Nonterminal>);
41struct S21_Nonterminal(P<S22_Item>);
42struct S22_Item(P<S23_EnumDef>);
43struct S23_EnumDef(Vec<P<S24_Variant>>);
44struct S24_Variant(P<S25_VariantKind>);
45struct S25_VariantKind(P<S26_StructDef>);
46struct S26_StructDef(Vec<P<S27_StructField>>);
47struct S27_StructField(P<S28_StructFieldKind>);
48struct S28_StructFieldKind;
49
50pub 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
5struct Foo<T: ?Sized> {
6 a: i32,
7 inner: T
8}
9
10trait Get {
11 fn get(&self) -> i32;
12}
13
14impl Get for i32 {
15 fn get(&self) -> i32 {
16 *self
17 }
18}
19
20fn check_val(val: &Foo<[u8]>) {
21 match *val {
22 Foo { a, .. } => {
23 assert_eq!(a, 32);
24 }
25 }
26}
27
28fn check_dst_val(val: &Foo<[u8]>) {
29 match *val {
30 Foo { ref inner, .. } => {
31 assert_eq!(inner, [1, 2, 3]);
32 }
33 }
34}
35
36fn 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
45fn 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
54fn 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
3trait MapLookup<Q> {
4 type MapValue;
5}
6
7impl<K> MapLookup<K> for K {
8 type MapValue = K;
9}
10
11trait Map: MapLookup<<Self as Map>::Key> {
12 type Key;
13}
14
15impl<K> Map for K {
16 type Key = K;
17}
18
19
20fn 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 @@
1error[E0038]: the trait `Map` is not dyn compatible
2 --> $DIR/supertrait-with-self-in-type-arg.rs:22:17
3 |
4LL | as &dyn Map<Key=u32,MapValue=u32>;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` is not dyn compatible
6 |
7note: 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 |
11LL | 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
16error: aborting due to 1 previous error
17
18For more information about this error, try `rustc --explain E0038`.
tests/ui/error-codes/E0264.rs+2-2
......@@ -1,8 +1,8 @@
11#![feature(lang_items)]
22
33extern "C" {
4 #[lang = "copy"]
5 fn copy(); //~ ERROR E0264
4 #[lang = "copy"] //~ ERROR E0264
5 fn copy();
66}
77
88fn main() {}
tests/ui/error-codes/E0264.stderr+3-3
......@@ -1,8 +1,8 @@
11error[E0264]: unknown external lang item: `copy`
2 --> $DIR/E0264.rs:5:5
2 --> $DIR/E0264.rs:4:5
33 |
4LL | fn copy();
5 | ^^^^^^^^^^
4LL | #[lang = "copy"]
5 | ^^^^^^^^^^^^^^^^
66
77error: aborting due to 1 previous error
88
tests/ui/error-codes/E0718.rs+1-1
......@@ -1,7 +1,7 @@
11#![feature(lang_items)]
22
33// 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
55static X: u32 = 42;
66
77fn main() {}
tests/ui/error-codes/E0718.stderr+4-3
......@@ -1,9 +1,10 @@
1error[E0718]: `owned_box` lang item must be applied to a struct
1error: `#[lang = "owned_box"]` attribute cannot be used on statics
22 --> $DIR/E0718.rs:4:1
33 |
44LL | #[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
68
79error: aborting due to 1 previous error
810
9For 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 @@
1error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2 --> $DIR/no-unsized-arguments.rs:40:42
3 |
4LL | 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]`
8help: function arguments must have a statically known size, borrowed slices always have a known size
9 |
10LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 {
11 | +
12
13error: unsized arguments cannot be used in a tail call
14 --> $DIR/no-unsized-arguments.rs:33:5
15 |
16LL | become unsized_argument(b);
17 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
18 |
19 = note: unsized argument of type `[u8]`
20
21error: unsized arguments cannot be used in a tail call
22 --> $DIR/no-unsized-arguments.rs:48:5
23 |
24LL | become unsized_argument(*b);
25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
26 |
27 = note: unsized argument of type `[u8]`
28
29error: aborting due to 3 previous errors
30
31For 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
18extern crate minicore;
19use minicore::*;
20
21extern "C" {
22 fn extract(_: [u8]) -> u8;
23}
24
25fn 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
37extern "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 @@
1error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2 --> $DIR/no-unsized-arguments.rs:40:42
3 |
4LL | 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]`
8help: function arguments must have a statically known size, borrowed slices always have a known size
9 |
10LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 {
11 | +
12
13error: unsized arguments cannot be used in a tail call
14 --> $DIR/no-unsized-arguments.rs:33:5
15 |
16LL | become unsized_argument(b);
17 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
18 |
19 = note: unsized argument of type `[u8]`
20
21error: unsized arguments cannot be used in a tail call
22 --> $DIR/no-unsized-arguments.rs:48:5
23 |
24LL | become unsized_argument(*b);
25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
26 |
27 = note: unsized argument of type `[u8]`
28
29error: aborting due to 3 previous errors
30
31For 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 @@
1error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2 --> $DIR/no-unsized-arguments.rs:40:42
3 |
4LL | 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]`
8help: function arguments must have a statically known size, borrowed slices always have a known size
9 |
10LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 {
11 | +
12
13error: unsized arguments cannot be used in a tail call
14 --> $DIR/no-unsized-arguments.rs:33:5
15 |
16LL | become unsized_argument(b);
17 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
18 |
19 = note: unsized argument of type `[u8]`
20
21error: unsized arguments cannot be used in a tail call
22 --> $DIR/no-unsized-arguments.rs:48:5
23 |
24LL | become unsized_argument(*b);
25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
26 |
27 = note: unsized argument of type `[u8]`
28
29error: aborting due to 3 previous errors
30
31For more information about this error, try `rustc --explain E0277`.
tests/ui/explicit-tail-calls/signature-mismatch.rs+8-4
......@@ -1,5 +1,5 @@
11#![expect(incomplete_features)]
2#![feature(explicit_tail_calls)]
2#![feature(explicit_tail_calls, rust_tail_cc)]
33#![feature(c_variadic)]
44
55fn _f0((): ()) {
......@@ -8,26 +8,30 @@ fn _f0((): ()) {
88
99fn _g0() {}
1010
11
1211fn _f1() {
1312 become _g1(()); //~ error: mismatched signatures
1413}
1514
1615fn _g1((): ()) {}
1716
18
1917extern "C" fn _f2() {
2018 become _g2(); //~ error: mismatched function ABIs
2119}
2220
2321fn _g2() {}
2422
25
2623fn _f3() {
2724 become _g3(); //~ error: mismatched function ABIs
2825}
2926
3027extern "C" fn _g3() {}
3128
29extern "tail" fn _tailcc() {}
30
31fn _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}
3236
3337fn main() {}
tests/ui/explicit-tail-calls/signature-mismatch.stderr+13-4
......@@ -9,7 +9,7 @@ LL | become _g0();
99 = note: callee signature: `fn()`
1010
1111error: mismatched signatures
12 --> $DIR/signature-mismatch.rs:13:5
12 --> $DIR/signature-mismatch.rs:12:5
1313 |
1414LL | become _g1(());
1515 | ^^^^^^^^^^^^^^
......@@ -19,7 +19,7 @@ LL | become _g1(());
1919 = note: callee signature: `fn(())`
2020
2121error: mismatched function ABIs
22 --> $DIR/signature-mismatch.rs:20:5
22 --> $DIR/signature-mismatch.rs:18:5
2323 |
2424LL | become _g2();
2525 | ^^^^^^^^^^^^
......@@ -28,7 +28,7 @@ LL | become _g2();
2828 = note: caller ABI is `"C"`, while callee ABI is `"Rust"`
2929
3030error: mismatched function ABIs
31 --> $DIR/signature-mismatch.rs:27:5
31 --> $DIR/signature-mismatch.rs:24:5
3232 |
3333LL | become _g3();
3434 | ^^^^^^^^^^^^
......@@ -36,5 +36,14 @@ LL | become _g3();
3636 = note: `become` requires caller and callee to have the same ABI
3737 = note: caller ABI is `"Rust"`, while callee ABI is `"C"`
3838
39error: aborting due to 4 previous errors
39error: mismatched function ABIs
40 --> $DIR/signature-mismatch.rs:34:5
41 |
42LL | 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
48error: aborting due to 5 previous errors
4049
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)]
12pub 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)]
22pub 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
42fn 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
3fn foo<T>() where for<'a> T: 'a {}
4
5fn bar<'a>() {
6 foo::<&'a i32>();
7 //~^ ERROR lifetime may not live long enough
8}
9
10fn main() {
11 bar();
12}
tests/ui/higher-ranked/forall-implies-static.stderr created+16
......@@ -0,0 +1,16 @@
1error: lifetime may not live long enough
2 --> $DIR/forall-implies-static.rs:6:5
3 |
4LL | fn bar<'a>() {
5 | -- lifetime `'a` defined here
6LL | foo::<&'a i32>();
7 | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
8 |
9note: due to a current limitation of the type system, this implies a `'static` lifetime
10 --> $DIR/forall-implies-static.rs:3:19
11 |
12LL | fn foo<T>() where for<'a> T: 'a {}
13 | ^^^^^^^^^^^^^
14
15error: 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
3trait Wrap<'b> {
4 fn foo(&'b mut self);
5}
6
7struct Wrapper<P>(P);
8
9impl<'b, P> Wrap<'b> for Wrapper<P>
10where P: Process<'b>,
11 <P as Process<'b>>::Item: Iterator {
12 fn foo(&mut self) {}
13}
14
15
16pub trait Process<'a> {
17 type Item;
18 fn bar(&'a self);
19}
20
21fn 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
26fn main() {}
tests/ui/higher-ranked/leak-check/trait-object-assoc-type-bound-unsatisfied.stderr created+24
......@@ -0,0 +1,24 @@
1error[E0277]: `<P as Process<'_>>::Item` is not an iterator
2 --> $DIR/trait-object-assoc-type-bound-unsatisfied.rs:22:40
3 |
4LL | 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`
8note: required for `Wrapper<P>` to implement `for<'b> Wrap<'b>`
9 --> $DIR/trait-object-assoc-type-bound-unsatisfied.rs:9:13
10 |
11LL | impl<'b, P> Wrap<'b> for Wrapper<P>
12 | ^^^^^^^^ ^^^^^^^^^^
13LL | where P: Process<'b>,
14LL | <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>>`
17help: consider further restricting the associated type
18 |
19LL | fn push_process<P>(process: P) where P: Process<'static>, <P as Process<'_>>::Item: Iterator {
20 | ++++++++++++++++++++++++++++++++++++
21
22error: aborting due to 1 previous error
23
24For 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
4fn main() {
5 let x = X(15);
6 let y = x.foo();
7 println!("{:?}",y);
8}
9
10trait Foo
11 where for<'a> &'a Self: Bar
12{
13 fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output;
14}
15
16trait Bar {
17 type Output;
18}
19
20struct X(i32);
21
22impl<'a> Bar for &'a X {
23 type Output = &'a i32;
24}
25
26impl 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
4use std::any::Any;
5fn 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 @@
1error[E0282]: type annotations needed
2 --> $DIR/downcast-fn-ptr-placeholder.rs:9:22
3 |
4LL | b.downcast_ref::<fn(_)->_>();
5 | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref`
6
7error: aborting due to 1 previous error
8
9For 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
5fn 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}
12fn main() {}
tests/ui/issues/issue-2150.stderr deleted-16
......@@ -1,16 +0,0 @@
1error: unreachable statement
2 --> $DIR/issue-2150.rs:8:5
3 |
4LL | panic!();
5 | -------- any code following this expression is unreachable
6LL | for x in &v { i += 1; }
7 | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
8 |
9note: the lint level is defined here
10 --> $DIR/issue-2150.rs:1:9
11 |
12LL | #![deny(unreachable_code)]
13 | ^^^^^^^^^^^^^^^^
14
15error: 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)]
4mod Foo { }
5
6#[allow(dead_code)]
7struct Foo;
8//~^ ERROR the name `Foo` is defined multiple times
9
10#[allow(non_snake_case)]
11mod Bar { }
12
13#[allow(dead_code)]
14struct Bar(i32);
15//~^ ERROR the name `Bar` is defined multiple times
16
17
18#[allow(dead_code)]
19struct Baz(i32);
20
21#[allow(non_snake_case)]
22mod Baz { }
23//~^ ERROR the name `Baz` is defined multiple times
24
25
26#[allow(dead_code)]
27struct Qux { x: bool }
28
29#[allow(non_snake_case)]
30mod Qux { }
31//~^ ERROR the name `Qux` is defined multiple times
32
33
34#[allow(dead_code)]
35struct Quux;
36
37#[allow(non_snake_case)]
38mod Quux { }
39//~^ ERROR the name `Quux` is defined multiple times
40
41
42#[allow(dead_code)]
43enum Corge { A, B }
44
45#[allow(non_snake_case)]
46mod Corge { }
47//~^ ERROR the name `Corge` is defined multiple times
48
49fn main() { }
tests/ui/issues/issue-21546.stderr deleted-69
......@@ -1,69 +0,0 @@
1error[E0428]: the name `Foo` is defined multiple times
2 --> $DIR/issue-21546.rs:7:1
3 |
4LL | mod Foo { }
5 | ------- previous definition of the module `Foo` here
6...
7LL | struct Foo;
8 | ^^^^^^^^^^^ `Foo` redefined here
9 |
10 = note: `Foo` must be defined only once in the type namespace of this module
11
12error[E0428]: the name `Bar` is defined multiple times
13 --> $DIR/issue-21546.rs:14:1
14 |
15LL | mod Bar { }
16 | ------- previous definition of the module `Bar` here
17...
18LL | struct Bar(i32);
19 | ^^^^^^^^^^^^^^^^ `Bar` redefined here
20 |
21 = note: `Bar` must be defined only once in the type namespace of this module
22
23error[E0428]: the name `Baz` is defined multiple times
24 --> $DIR/issue-21546.rs:22:1
25 |
26LL | struct Baz(i32);
27 | ---------------- previous definition of the type `Baz` here
28...
29LL | mod Baz { }
30 | ^^^^^^^ `Baz` redefined here
31 |
32 = note: `Baz` must be defined only once in the type namespace of this module
33
34error[E0428]: the name `Qux` is defined multiple times
35 --> $DIR/issue-21546.rs:30:1
36 |
37LL | struct Qux { x: bool }
38 | ---------- previous definition of the type `Qux` here
39...
40LL | mod Qux { }
41 | ^^^^^^^ `Qux` redefined here
42 |
43 = note: `Qux` must be defined only once in the type namespace of this module
44
45error[E0428]: the name `Quux` is defined multiple times
46 --> $DIR/issue-21546.rs:38:1
47 |
48LL | struct Quux;
49 | ------------ previous definition of the type `Quux` here
50...
51LL | mod Quux { }
52 | ^^^^^^^^ `Quux` redefined here
53 |
54 = note: `Quux` must be defined only once in the type namespace of this module
55
56error[E0428]: the name `Corge` is defined multiple times
57 --> $DIR/issue-21546.rs:46:1
58 |
59LL | enum Corge { A, B }
60 | ---------- previous definition of the type `Corge` here
61...
62LL | mod Corge { }
63 | ^^^^^^^^^ `Corge` redefined here
64 |
65 = note: `Corge` must be defined only once in the type namespace of this module
66
67error: aborting due to 6 previous errors
68
69For 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
5struct Index;
6
7impl Index {
8 fn new() -> Self { Index }
9}
10
11fn user() {
12 let new = Index::new;
13
14 fn inner() {
15 let index = Index::new();
16 }
17
18 let index2 = new();
19}
20
21fn 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"))]
4fn 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")))]
17fn main() {}
tests/ui/issues/issue-21701.rs deleted-15
......@@ -1,15 +0,0 @@
1fn foo<U>(t: U) {
2 let y = t();
3//~^ ERROR: expected function, found `U`
4}
5
6struct Bar;
7
8pub fn some_func() {
9 let f = Bar();
10//~^ ERROR: expected function, found struct `Bar`
11}
12
13fn main() {
14 foo(|| { 1 });
15}
tests/ui/issues/issue-21701.stderr deleted-30
......@@ -1,30 +0,0 @@
1error[E0618]: expected function, found `U`
2 --> $DIR/issue-21701.rs:2:13
3 |
4LL | fn foo<U>(t: U) {
5 | - `t` has type `U`
6LL | let y = t();
7 | ^--
8 | |
9 | call expression requires function
10
11error[E0618]: expected function, found struct `Bar`
12 --> $DIR/issue-21701.rs:9:13
13 |
14LL | struct Bar;
15 | ---------- struct `Bar` defined here
16...
17LL | let f = Bar();
18 | ^^^--
19 | |
20 | call expression requires function
21 |
22help: `Bar` is a unit struct, and does not take parentheses to be constructed
23 |
24LL - let f = Bar();
25LL + let f = Bar;
26 |
27
28error: aborting due to 2 previous errors
29
30For 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
5use std::collections::HashMap;
6use std::rc::Rc;
7
8fn foo<T: Send>() {}
9
10fn 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 @@
1error[E0277]: `Rc<()>` cannot be sent between threads safely
2 --> $DIR/issue-21763.rs:11:11
3 |
4LL | 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`
10note: required because it appears within the type `hashbrown::map::HashMap<Rc<()>, Rc<()>, RandomState>`
11 --> $HASHBROWN_SRC_LOCATION
12note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>`
13 --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
14note: required by a bound in `foo`
15 --> $DIR/issue-21763.rs:8:11
16 |
17LL | fn foo<T: Send>() {}
18 | ^^^^ required by this bound in `foo`
19
20error: aborting due to 1 previous error
21
22For more information about this error, try `rustc --explain E0277`.
tests/ui/issues/issue-21922.rs deleted-17
......@@ -1,17 +0,0 @@
1//@ run-pass
2use std::ops::Add;
3fn show(z: i32) {
4 println!("{}", z)
5}
6fn 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
6trait Foo {
7 fn foo(self);
8}
9
10fn 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
18fn main() { }
tests/ui/issues/issue-21974.stderr deleted-31
......@@ -1,31 +0,0 @@
1error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo`
2 --> $DIR/issue-21974.rs:11:19
3 |
4LL | where &'a T : Foo,
5 | ^^^
6 |
7note: multiple `impl`s or `where` clauses satisfying `&'a T: Foo` found
8 --> $DIR/issue-21974.rs:11:19
9 |
10LL | where &'a T : Foo,
11 | ^^^
12LL | &'b T : Foo
13 | ^^^
14
15error[E0283]: type annotations needed: cannot satisfy `&T: Foo`
16 --> $DIR/issue-21974.rs:14:7
17 |
18LL | x.foo();
19 | ^^^
20 |
21note: multiple `impl`s or `where` clauses satisfying `&T: Foo` found
22 --> $DIR/issue-21974.rs:11:19
23 |
24LL | where &'a T : Foo,
25 | ^^^
26LL | &'b T : Foo
27 | ^^^
28
29error: aborting due to 2 previous errors
30
31For more information about this error, try `rustc --explain E0283`.
tests/ui/issues/issue-22008.rs deleted-9
......@@ -1,9 +0,0 @@
1//@ run-pass
2pub 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 @@
1fn 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 @@
1error[E0277]: expected a `Fn()` closure, found `()`
2 --> $DIR/issue-22034.rs:4:16
3 |
4LL | &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
11error: aborting due to 1 previous error
12
13For 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
3trait 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
14impl<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
22fn 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
2use std::ops::Add;
3
4fn f<T: Add>(a: T, b: T) -> <T as Add>::Output {
5 a + b
6}
7
8fn 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
5use std::marker::PhantomData;
6
7pub struct Handle<T, I>(T, I);
8
9impl<T, I> Handle<T, I> {
10 pub fn get_info(&self) -> &I {
11 let Handle(_, ref info) = *self;
12 info
13 }
14}
15
16pub struct BufferHandle<D: Device, T> {
17 raw: RawBufferHandle<D>,
18 _marker: PhantomData<T>,
19}
20
21impl<D: Device, T> BufferHandle<D, T> {
22 pub fn get_info(&self) -> &String {
23 self.raw.get_info()
24 }
25}
26
27pub type RawBufferHandle<D: Device> = Handle<<D as Device>::Buffer, String>;
28
29pub trait Device {
30 type Buffer;
31}
32
33fn main() {}
tests/ui/issues/issue-22370.rs deleted-6
......@@ -1,6 +0,0 @@
1trait A<T=Self> {}
2
3fn f(a: &dyn A) {}
4//~^ ERROR E0393
5
6fn main() {}
tests/ui/issues/issue-22370.stderr deleted-18
......@@ -1,18 +0,0 @@
1error[E0393]: the type parameter `T` must be explicitly specified
2 --> $DIR/issue-22370.rs:3:14
3 |
4LL | trait A<T=Self> {}
5 | --------------- type parameter `T` must be specified for this
6LL |
7LL | 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
11help: explicitly specify the type parameter
12 |
13LL | fn f(a: &dyn A</* T */>) {}
14 | +++++++++
15
16error: aborting due to 1 previous error
17
18For 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
5type Foo<T> where T: Copy = Box<T>;
6
7fn main(){}
tests/ui/issues/issue-22603.rs deleted-15
......@@ -1,15 +0,0 @@
1//@ check-pass
2
3#![feature(unboxed_closures, fn_traits)]
4
5struct Foo;
6
7impl<A> FnOnce<(A,)> for Foo {
8 type Output = ();
9 extern "rust-call" fn call_once(self, (_,): (A,)) {
10 }
11}
12
13fn 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
7use std::borrow::{ToOwned, Cow};
8
9fn assert_send<T: Send>(_: T) {}
10
11fn 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)]
10struct A (B);
11
12impl 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)]
20enum B {
21 Variant1,
22 Variant2(C),
23}
24
25impl 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)]
37struct C (D);
38
39impl 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)]
49struct D (Box<A>);
50
51impl 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
59pub fn matches() {
60 A(B::Variant1).matches(&(|| ()))
61}
tests/ui/issues/issue-22638.stderr deleted-14
......@@ -1,14 +0,0 @@
1error: 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 |
4LL | a.matches(f)
5 | ^^^^^^^^^^^^
6 |
7note: `A::matches` defined here
8 --> $DIR/issue-22638.rs:13:5
9 |
10LL | pub fn matches<F: Fn()>(&self, f: &F) {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12
13error: aborting due to 1 previous error
14
tests/ui/issues/issue-22673.rs deleted-7
......@@ -1,7 +0,0 @@
1//@ check-pass
2
3trait Expr: PartialEq<Self::Item> {
4 type Item;
5}
6
7fn 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
9pub fn noop_fold_impl_item() -> SmallVector<ImplItem> {
10 loop { }
11}
12
13pub struct SmallVector<T>(P<T>);
14pub struct ImplItem(P<S01_Method>);
15
16struct P<T>(Box<T>);
17
18struct S01_Method(P<S02_Generics>);
19struct S02_Generics(P<S03_TyParam>);
20struct S03_TyParam(P<S04_TyParamBound>);
21struct S04_TyParamBound(S05_PolyTraitRef);
22struct S05_PolyTraitRef(S06_TraitRef);
23struct S06_TraitRef(S07_Path);
24struct S07_Path(Vec<S08_PathSegment>);
25struct S08_PathSegment(S09_GenericArgs);
26struct S09_GenericArgs(P<S10_ParenthesizedParameterData>);
27struct S10_ParenthesizedParameterData(Option<P<S11_Ty>>);
28struct S11_Ty(P<S12_Expr>);
29struct S12_Expr(P<S13_Block>);
30struct S13_Block(Vec<P<S14_Stmt>>);
31struct S14_Stmt(P<S15_Decl>);
32struct S15_Decl(P<S16_Local>);
33struct S16_Local(P<S17_Pat>);
34struct S17_Pat(P<S18_Mac>);
35struct S18_Mac(Vec<P<S19_TokenTree>>);
36struct S19_TokenTree(P<S20_Token>);
37struct S20_Token(P<S21_Nonterminal>);
38struct S21_Nonterminal(P<S22_Item>);
39struct S22_Item(P<S23_EnumDef>);
40struct S23_EnumDef(Vec<P<S24_Variant>>);
41struct S24_Variant(P<S25_VariantKind>);
42struct S25_VariantKind(P<S26_StructDef>);
43struct S26_StructDef(Vec<P<S27_StructField>>);
44struct S27_StructField(P<S28_StructFieldKind>);
45struct S28_StructFieldKind;
46
47pub fn main() {}
tests/ui/issues/issue-22781.rs deleted-15
......@@ -1,15 +0,0 @@
1//@ check-pass
2#![allow(unused_variables)]
3use std::collections::HashMap;
4use std::collections::hash_map::Entry::Vacant;
5
6pub 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
15fn main() {}
tests/ui/issues/issue-22814.rs deleted-13
......@@ -1,13 +0,0 @@
1//@ check-pass
2trait Test {}
3
4macro_rules! test {
5( $($name:ident)+) => (
6 impl<$($name: Test),+> Test for ($($name,)+) {
7 }
8)
9}
10
11test!(A B C);
12
13fn main() {}
tests/ui/issues/issue-22872.rs deleted-24
......@@ -1,24 +0,0 @@
1trait Wrap<'b> {
2 fn foo(&'b mut self);
3}
4
5struct Wrapper<P>(P);
6
7impl<'b, P> Wrap<'b> for Wrapper<P>
8where P: Process<'b>,
9 <P as Process<'b>>::Item: Iterator {
10 fn foo(&mut self) {}
11}
12
13
14pub trait Process<'a> {
15 type Item;
16 fn bar(&'a self);
17}
18
19fn 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
24fn main() {}
tests/ui/issues/issue-22872.stderr deleted-24
......@@ -1,24 +0,0 @@
1error[E0277]: `<P as Process<'_>>::Item` is not an iterator
2 --> $DIR/issue-22872.rs:20:40
3 |
4LL | 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`
8note: required for `Wrapper<P>` to implement `for<'b> Wrap<'b>`
9 --> $DIR/issue-22872.rs:7:13
10 |
11LL | impl<'b, P> Wrap<'b> for Wrapper<P>
12 | ^^^^^^^^ ^^^^^^^^^^
13LL | where P: Process<'b>,
14LL | <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>>`
17help: consider further restricting the associated type
18 |
19LL | fn push_process<P>(process: P) where P: Process<'static>, <P as Process<'_>>::Item: Iterator {
20 | ++++++++++++++++++++++++++++++++++++
21
22error: aborting due to 1 previous error
23
24For more information about this error, try `rustc --explain E0277`.
tests/ui/issues/issue-22874.rs deleted-11
......@@ -1,11 +0,0 @@
1struct Table {
2 rows: [[String]],
3 //~^ ERROR the size for values of type
4}
5
6fn f(table: &Table) -> &[String] {
7 &table.rows[0]
8 //~^ ERROR the size for values of type
9}
10
11fn main() {}
tests/ui/issues/issue-22874.stderr deleted-21
......@@ -1,21 +0,0 @@
1error[E0277]: the size for values of type `[String]` cannot be known at compilation time
2 --> $DIR/issue-22874.rs:2:11
3 |
4LL | 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
10error[E0277]: the size for values of type `[String]` cannot be known at compilation time
11 --> $DIR/issue-22874.rs:7:6
12 |
13LL | &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
19error: aborting due to 2 previous errors
20
21For 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
3fn 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
11struct Newtype(Option<Box<usize>>);
12
13impl<'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
21fn main() { }
tests/ui/issues/issue-22886.stderr deleted-16
......@@ -1,16 +0,0 @@
1error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
2 --> $DIR/issue-22886.rs:13:6
3 |
4LL | impl<'a> Iterator for Newtype {
5 | ^^ unconstrained lifetime parameter
6 |
7help: use the lifetime parameter `'a` in the `Newtype` type and use it in the type definition
8 |
9LL ~ struct Newtype<'a>(Option<Box<usize>>);
10LL |
11LL ~ impl<'a> Iterator for Newtype<'a> {
12 |
13
14error: aborting due to 1 previous error
15
16For more information about this error, try `rustc --explain E0207`.
tests/ui/issues/issue-23024.rs deleted-11
......@@ -1,11 +0,0 @@
1use std::any::Any;
2
3fn 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 @@
1error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
2 --> $DIR/issue-23024.rs:8:39
3 |
4LL | 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
11error[E0107]: missing generics for trait `Fn`
12 --> $DIR/issue-23024.rs:8:39
13 |
14LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
15 | ^^ expected 1 generic argument
16 |
17help: add missing generic argument
18 |
19LL | println!("{:?}",(vfnfer[0] as dyn Fn<Args>)(3));
20 | ++++++
21
22error: aborting due to 2 previous errors
23
24Some errors have detailed explanations: E0107, E0658.
25For more information about an error, try `rustc --explain E0107`.
tests/ui/issues/issue-23041.rs deleted-7
......@@ -1,7 +0,0 @@
1use std::any::Any;
2fn 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 @@
1error[E0282]: type annotations needed
2 --> $DIR/issue-23041.rs:6:22
3 |
4LL | b.downcast_ref::<fn(_)->_>();
5 | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref`
6
7error: aborting due to 1 previous error
8
9For 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
4struct Foo<T: ?Sized> {
5 a: i32,
6 inner: T
7}
8
9trait Get {
10 fn get(&self) -> i32;
11}
12
13impl Get for i32 {
14 fn get(&self) -> i32 {
15 *self
16 }
17}
18
19fn check_val(val: &Foo<[u8]>) {
20 match *val {
21 Foo { a, .. } => {
22 assert_eq!(a, 32);
23 }
24 }
25}
26
27fn check_dst_val(val: &Foo<[u8]>) {
28 match *val {
29 Foo { ref inner, .. } => {
30 assert_eq!(inner, [1, 2, 3]);
31 }
32 }
33}
34
35fn 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
44fn 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
53fn 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
5fn 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)]
6fn 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)]
6fn 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)]
3fn 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)]
3enum Expression {
4 Dummy,
5 Add(Box<Expression>),
6}
7
8use Expression::*;
9
10fn simplify(exp: Expression) -> Expression {
11 match exp {
12 Add(n) => *n.clone(),
13 _ => Dummy
14 }
15}
16
17fn 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
2use std::rc::Rc;
3
4struct Foo<'r>(&'r mut i32);
5
6impl<'r> Drop for Foo<'r> {
7 fn drop(&mut self) {
8 *self.0 += 1;
9 }
10}
11
12fn 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
2fn main() {
3 let x = X(15);
4 let y = x.foo();
5 println!("{:?}",y);
6}
7
8trait Foo
9 where for<'a> &'a Self: Bar
10{
11 fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output;
12}
13
14trait Bar {
15 type Output;
16}
17
18struct X(i32);
19
20impl<'a> Bar for &'a X {
21 type Output = &'a i32;
22}
23
24impl 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 @@
1struct Parser {
2 tokens: Vec<isize> ,
3}
4
5trait Parse {
6 fn parse(&self) -> Vec<isize> ;
7}
8
9impl Parse for Parser {
10 fn parse(&self) -> Vec<isize> {
11 self.tokens //~ ERROR cannot move out
12 }
13}
14
15fn main() {}
tests/ui/issues/issue-2590.stderr deleted-14
......@@ -1,14 +0,0 @@
1error[E0507]: cannot move out of `self.tokens` which is behind a shared reference
2 --> $DIR/issue-2590.rs:11:9
3 |
4LL | self.tokens
5 | ^^^^^^^^^^^ move occurs because `self.tokens` has type `Vec<isize>`, which does not implement the `Copy` trait
6 |
7help: consider cloning the value if the performance cost is acceptable
8 |
9LL | self.tokens.clone()
10 | ++++++++
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0507`.
tests/ui/issues/issue-26056.rs deleted-22
......@@ -1,22 +0,0 @@
1trait MapLookup<Q> {
2 type MapValue;
3}
4
5impl<K> MapLookup<K> for K {
6 type MapValue = K;
7}
8
9trait Map: MapLookup<<Self as Map>::Key> {
10 type Key;
11}
12
13impl<K> Map for K {
14 type Key = K;
15}
16
17
18fn 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 @@
1error[E0038]: the trait `Map` is not dyn compatible
2 --> $DIR/issue-26056.rs:20:17
3 |
4LL | as &dyn Map<Key=u32,MapValue=u32>;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` is not dyn compatible
6 |
7note: 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 |
11LL | 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
16error: aborting due to 1 previous error
17
18For more information about this error, try `rustc --explain E0038`.
tests/ui/issues/issue-26217.rs deleted-10
......@@ -1,10 +0,0 @@
1fn foo<T>() where for<'a> T: 'a {}
2
3fn bar<'a>() {
4 foo::<&'a i32>();
5 //~^ ERROR lifetime may not live long enough
6}
7
8fn main() {
9 bar();
10}
tests/ui/issues/issue-26217.stderr deleted-16
......@@ -1,16 +0,0 @@
1error: lifetime may not live long enough
2 --> $DIR/issue-26217.rs:4:5
3 |
4LL | fn bar<'a>() {
5 | -- lifetime `'a` defined here
6LL | foo::<&'a i32>();
7 | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
8 |
9note: due to a current limitation of the type system, this implies a `'static` lifetime
10 --> $DIR/issue-26217.rs:1:19
11 |
12LL | fn foo<T>() where for<'a> T: 'a {}
13 | ^^^^^^^^^^^^^
14
15error: aborting due to 1 previous error
16
tests/ui/issues/issue-26237.rs deleted-12
......@@ -1,12 +0,0 @@
1macro_rules! macro_panic {
2 ($not_a_function:expr, $some_argument:ident) => {
3 $not_a_function($some_argument)
4 }
5}
6
7fn 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 @@
1error[E0618]: expected function, found `{integer}`
2 --> $DIR/issue-26237.rs:10:18
3 |
4LL | $not_a_function($some_argument)
5 | ------------------------------- call expression requires function
6...
7LL | let mut value_a = 0;
8 | ----------- `value_a` has type `{integer}`
9LL | let mut value_b = 0;
10LL | macro_panic!(value_a, value_b);
11 | ^^^^^^^
12
13error: aborting due to 1 previous error
14
15For 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
4enum FooMode {
5 Check = 0x1001,
6}
7
8enum BarMode {
9 Check = 0x2001,
10}
11
12enum Mode {
13 Foo(FooMode),
14 Bar(BarMode),
15}
16
17#[inline(never)]
18fn 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
26fn 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 @@
1struct Foo;
2#[derive(Copy, Clone)]
3struct Bar(Foo);
4//~^ ERROR: the trait `Copy` cannot be implemented for this type
5//~| ERROR: `Foo: Clone` is not satisfied
6
7fn main() {}
tests/ui/issues/issue-27340.stderr deleted-28
......@@ -1,28 +0,0 @@
1error[E0204]: the trait `Copy` cannot be implemented for this type
2 --> $DIR/issue-27340.rs:3:8
3 |
4LL | #[derive(Copy, Clone)]
5 | ---- in this derive macro expansion
6LL | struct Bar(Foo);
7 | ^^^ --- this field does not implement `Copy`
8
9error[E0277]: the trait bound `Foo: Clone` is not satisfied
10 --> $DIR/issue-27340.rs:3:12
11 |
12LL | #[derive(Copy, Clone)]
13 | ----- in this derive macro expansion
14LL | struct Bar(Foo);
15 | ^^^ the trait `Clone` is not implemented for `Foo`
16 |
17note: required by a bound in `std::clone::AssertParamIsClone`
18 --> $SRC_DIR/core/src/clone.rs:LL:COL
19help: consider annotating `Foo` with `#[derive(Clone)]`
20 |
21LL + #[derive(Clone)]
22LL | struct Foo;
23 |
24
25error: aborting due to 2 previous errors
26
27Some errors have detailed explanations: E0204, E0277.
28For 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)]
3struct 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)]
41struct 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)]
58struct 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
74fn 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)]
5struct Foo;
6
7fn 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
4trait Resources {
5 type Buffer: Copy;
6}
7
8#[derive(Copy, Clone)]
9struct ConstantBufferSet<R: Resources>(
10 pub R::Buffer
11);
12
13#[derive(Copy, Clone)]
14enum It {}
15impl Resources for It {
16 type Buffer = u8;
17}
18
19#[derive(Copy, Clone)]
20enum Command {
21 BindConstantBuffers(ConstantBufferSet<It>)
22}
23
24fn 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)]
5enum Foo {}
6
7fn main() {}
tests/ui/issues/issue-33571.stderr deleted-27
......@@ -1,27 +0,0 @@
1error: cannot find derive macro `Sync` in this scope
2 --> $DIR/issue-33571.rs:2:10
3 |
4LL | Sync,
5 | ^^^^
6 |
7note: unsafe traits like `Sync` should be implemented explicitly
8 --> $DIR/issue-33571.rs:2:10
9 |
10LL | Sync,
11 | ^^^^
12
13error: cannot find derive macro `Sync` in this scope
14 --> $DIR/issue-33571.rs:2:10
15 |
16LL | Sync,
17 | ^^^^
18 |
19note: unsafe traits like `Sync` should be implemented explicitly
20 --> $DIR/issue-33571.rs:2:10
21 |
22LL | Sync,
23 | ^^^^
24 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
25
26error: aborting due to 2 previous errors
27
tests/ui/issues/issue-46101.rs deleted-6
......@@ -1,6 +0,0 @@
1trait Foo {}
2#[derive(Foo::Anything)] //~ ERROR cannot find
3 //~| ERROR cannot find
4struct S;
5
6fn main() {}
tests/ui/issues/issue-46101.stderr deleted-17
......@@ -1,17 +0,0 @@
1error[E0433]: cannot find derive macro `Anything` in trait `Foo`
2 --> $DIR/issue-46101.rs:2:10
3 |
4LL | #[derive(Foo::Anything)]
5 | ^^^^^^^^^^^^^ a derive macro can't exist within a trait
6
7error[E0433]: cannot find derive macro `Anything` in trait `Foo`
8 --> $DIR/issue-46101.rs:2:10
9 |
10LL | #[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
15error: aborting due to 2 previous errors
16
17For 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)]
7fn 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
22 --> $DIR/format-foreign-dollar-without-spec.rs:3:25
33 |
44LL | println!("%65536$", 1);
5 | ^ argument never used
5 | --------- ^ argument never used
6 | |
7 | formatting specifier missing
68 |
7note: format specifiers use curly braces, and the conversion specifier `
8 ` is unknown or unsupported
9 --> $DIR/format-foreign-dollar-without-spec.rs:3:15
9help: format specifiers use curly braces, consider adding a format specifier
1010 |
11LL | println!("%65536$", 1);
12 | ^^^^^^^^
13 = note: printf formatting is not supported; see the documentation for `std::fmt`
11LL | println!("%65536${}", 1);
12 | ++
1413
1514error: aborting due to 1 previous error
1615
tests/ui/macros/issue-92267.stderr+6-7
......@@ -2,15 +2,14 @@ error: argument never used
22 --> $DIR/issue-92267.rs:3:34
33 |
44LL | pub fn main() { println!("🦀%%%", 0) }
5 | ^ argument never used
5 | ------- ^ argument never used
6 | |
7 | formatting specifier missing
68 |
7note: format specifiers use curly braces, and the conversion specifier `
8 ` is unknown or unsupported
9 --> $DIR/issue-92267.rs:3:30
9help: format specifiers use curly braces, consider adding a format specifier
1010 |
11LL | pub fn main() { println!("🦀%%%", 0) }
12 | ^^
13 = note: printf formatting is not supported; see the documentation for `std::fmt`
11LL | pub fn main() { println!("🦀%%%{}", 0) }
12 | ++
1413
1514error: aborting due to 1 previous error
1615
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
3macro_rules! macro_panic {
4 ($not_a_function:expr, $some_argument:ident) => {
5 $not_a_function($some_argument)
6 }
7}
8
9fn 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 @@
1error[E0618]: expected function, found `{integer}`
2 --> $DIR/non-function-call-in-macro.rs:12:18
3 |
4LL | $not_a_function($some_argument)
5 | ------------------------------- call expression requires function
6...
7LL | let mut value_a = 0;
8 | ----------- `value_a` has type `{integer}`
9LL | let mut value_b = 0;
10LL | macro_panic!(value_a, value_b);
11 | ^^^^^^^
12
13error: aborting due to 1 previous error
14
15For 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
4pub 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 @@
1error: argument never used
2 --> $DIR/trailing-percent-format-hint-issue-158216.rs:5:27
3 |
4LL | println!("{x:>8.2}%", "foo");
5 | ----------- ^^^^^ argument never used
6 | |
7 | formatting specifier missing
8 |
9help: format specifiers use curly braces, consider adding a format specifier
10 |
11LL | println!("{x:>8.2}%{}", "foo");
12 | ++
13
14error: 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
4trait Test {}
5
6macro_rules! test {
7( $($name:ident)+) => (
8 impl<$($name: Test),+> Test for ($($name,)+) {
9 }
10)
11}
12
13test!(A B C);
14
15fn 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
7pub 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
7struct Index;
8
9impl Index {
10 fn new() -> Self { Index }
11}
12
13fn user() {
14 let new = Index::new;
15
16 fn inner() {
17 let index = Index::new();
18 }
19
20 let index2 = new();
21}
22
23fn 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
3struct Parser {
4 tokens: Vec<isize> ,
5}
6
7trait Parse {
8 fn parse(&self) -> Vec<isize> ;
9}
10
11impl Parse for Parser {
12 fn parse(&self) -> Vec<isize> {
13 self.tokens //~ ERROR cannot move out
14 }
15}
16
17fn main() {}
tests/ui/moves/move-field-out-of-shared-self.stderr created+14
......@@ -0,0 +1,14 @@
1error[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 |
4LL | self.tokens
5 | ^^^^^^^^^^^ move occurs because `self.tokens` has type `Vec<isize>`, which does not implement the `Copy` trait
6 |
7help: consider cloning the value if the performance cost is acceptable
8 |
9LL | self.tokens.clone()
10 | ++++++++
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0507`.
tests/ui/panic-handler/panic-handler-wrong-location.rs+1-1
......@@ -3,7 +3,7 @@
33#![no_std]
44#![no_main]
55
6#[panic_handler] //~ ERROR `panic_impl` lang item must be applied to a function
6#[panic_handler] //~ ERROR attribute cannot be used on statics
77static X: u32 = 42;
88
99//~? ERROR `#[panic_handler]` function required, but not found
tests/ui/panic-handler/panic-handler-wrong-location.stderr+6-5
......@@ -1,11 +1,12 @@
1error[E0718]: `panic_impl` lang item must be applied to a function
1error: `#[panic_handler]` function required, but not found
2
3error: `#[panic_handler]` attribute cannot be used on statics
24 --> $DIR/panic-handler-wrong-location.rs:6:1
35 |
46LL | #[panic_handler]
5 | ^^^^^^^^^^^^^^^^ attribute should be applied to a function, not a static
6
7error: `#[panic_handler]` function required, but not found
7 | ^^^^^^^^^^^^^^^^
8 |
9 = help: `#[panic_handler]` can only be applied to functions
810
911error: aborting due to 2 previous errors
1012
11For 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
5fn 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 {
1515 OtherWithPanic,
1616}
1717
18fn print_unspanned<T>(s: &str) -> Result<T, LexError>
19where
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
1832fn parse<T>(s: &str, mode: Mode)
1933where
2034 T: FromStr<Err = LexError> + Debug,
2135{
2236 match mode {
2337 NormalOk => {
24 let t = T::from_str(s);
25 println!("{:?}", t);
38 let t = print_unspanned::<T>(s);
2639 assert!(t.is_ok());
2740 }
2841 NormalErr => {
29 let t = T::from_str(s);
30 println!("{:?}", t);
42 let t = print_unspanned::<T>(s);
3143 assert!(t.is_err());
3244 }
3345 OtherError => {
34 println!("{:?}", T::from_str(s));
46 print_unspanned::<T>(s);
3547 }
3648 OtherWithPanic => {
37 if catch_unwind(|| println!("{:?}", T::from_str(s))).is_ok() {
49 if catch_unwind(|| print_unspanned::<T>(s)).is_ok() {
3850 eprintln!("{s} did not panic");
3951 }
4052 }
......@@ -64,7 +76,10 @@ fn lit(s: &str, mode: Mode) {
6476}
6577
6678pub fn run() {
79 assert_eq!("\'", "'");
6780 // returns Ok(valid instance)
81 lit("r\"g\"", NormalOk);
82 lit("r#\"g\"#", NormalOk);
6883 lit("123", NormalOk);
6984 lit("\"ab\"", NormalOk);
7085 lit("\'b\'", NormalOk);
......@@ -72,6 +87,7 @@ pub fn run() {
7287 lit("b\"b\"", NormalOk);
7388 lit("c\"b\"", NormalOk);
7489 lit("cr\"b\"", NormalOk);
90 lit("'\\''", NormalOk);
7591 lit("b'b'", NormalOk);
7692 lit("256u8", NormalOk);
7793 lit("-256u8", NormalOk);
......@@ -99,10 +115,13 @@ pub fn run() {
99115 NormalOk,
100116 );
101117 stream("/*a*/ //", NormalOk);
118 lit("\"\"", NormalOk);
119 stream("", NormalOk);
102120
103121 println!("### ERRORS");
104122
105123 // returns Err(LexError)
124 lit("", NormalErr);
106125 lit("\'c\'/**/", NormalErr);
107126 lit(" 0", NormalErr);
108127 lit("0 ", NormalErr);
......@@ -119,10 +138,12 @@ pub fn run() {
119138 // emits diagnostics and returns LexError
120139 lit("r'r'", OtherError);
121140 lit("c'r'", OtherError);
141 lit("\u{2000}", OtherError);
122142
123143 // emits diagnostic and returns a seemingly valid tokenstream
124144 stream("r'r'", OtherError);
125145 stream("c'r'", OtherError);
146 stream("\u{2000}", OtherError);
126147
127148 for parse in [stream as fn(&str, Mode), lit] {
128149 // emits diagnostic(s), then panics
tests/ui/proc-macro/nonfatal-parsing.stderr+25-1
......@@ -22,6 +22,17 @@ help: consider inserting whitespace here
2222LL | c 'r'
2323 | +
2424
25error: unknown start of token: \u{2000}
26 --> <proc-macro source code>:1:1
27 |
28LL |  
29 | ^
30 |
31help: Unicode character ' ' (En Quad) looks like ' ' (Space), but it is not
32 |
33LL |
34 |
35
2536error: prefix `r` is unknown
2637 --> $DIR/nonfatal-parsing.rs:15:5
2738 |
......@@ -40,6 +51,19 @@ LL | nonfatal_parsing::run!();
4051 = note: prefixed identifiers and literals are reserved since Rust 2021
4152 = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
4253
54error: unknown start of token: \u{2000}
55 --> $DIR/nonfatal-parsing.rs:15:5
56 |
57LL | 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)
61help: Unicode character ' ' (En Quad) looks like ' ' (Space), but it is not
62 --> <proc-macro source code>:1:1
63 |
64LL |
65 |
66
4367error: found invalid character; only `#` is allowed in raw string delimitation: \u{0}
4468 --> $DIR/nonfatal-parsing.rs:15:5
4569 |
......@@ -175,6 +199,6 @@ error: invalid digit for a base 2 literal
175199LL | /*a*/ 0b2 //
176200 | ^
177201
178error: aborting due to 20 previous errors
202error: aborting due to 22 previous errors
179203
180204For more information about this error, try `rustc --explain E0768`.
tests/ui/proc-macro/nonfatal-parsing.stdout+50-42
......@@ -1,34 +1,40 @@
1Ok(Literal { kind: Integer, symbol: "123", suffix: None, span: #44 bytes(361..385) })
2Ok(Literal { kind: Str, symbol: "ab", suffix: None, span: #44 bytes(361..385) })
3Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #44 bytes(361..385) })
4Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #44 bytes(361..385) })
5Ok(Literal { kind: ByteStr, symbol: "b", suffix: None, span: #44 bytes(361..385) })
6Ok(Literal { kind: CStr, symbol: "b", suffix: None, span: #44 bytes(361..385) })
7Ok(Literal { kind: CStrRaw(0), symbol: "b", suffix: None, span: #44 bytes(361..385) })
8Ok(Literal { kind: Byte, symbol: "b", suffix: None, span: #44 bytes(361..385) })
9Ok(Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #44 bytes(361..385) })
10Ok(Literal { kind: Integer, symbol: "-256", suffix: Some("u8"), span: #44 bytes(361..385) })
11Ok(TokenStream [Punct { ch: '-', spacing: Alone, span: #44 bytes(361..385) }, Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #44 bytes(361..385) }])
12Ok(Literal { kind: Integer, symbol: "0b11111000000001111", suffix: Some("i16"), span: #44 bytes(361..385) })
13Ok(Literal { kind: Integer, symbol: "0xf32", suffix: None, span: #44 bytes(361..385) })
14Ok(Literal { kind: Integer, symbol: "0b0", suffix: Some("f32"), span: #44 bytes(361..385) })
15Ok(Literal { kind: Float, symbol: "2E4", suffix: None, span: #44 bytes(361..385) })
16Ok(Literal { kind: Float, symbol: "2.2E-4", suffix: Some("f64"), span: #44 bytes(361..385) })
17Ok(Literal { kind: Integer, symbol: "18", suffix: Some("u8E"), span: #44 bytes(361..385) })
18Ok(Literal { kind: Float, symbol: "18.0", suffix: Some("u8E"), span: #44 bytes(361..385) })
19Ok(Literal { kind: CStrRaw(1), symbol: "// /* // \n */", suffix: None, span: #44 bytes(361..385) })
20Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #44 bytes(361..385) })
21Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #44 bytes(361..385) })
22Ok(Literal { kind: StrRaw(255), symbol: "a", suffix: None, span: #44 bytes(361..385) })
23Ok(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) }])
24Ok(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) }])
25Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f32"), span: #44 bytes(361..385) }])
26Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f34"), span: #44 bytes(361..385) }])
27Ok(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) }])
28Ok(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) }])
29Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: #44 bytes(361..385) }])
1Ok(Literal { kind: StrRaw(0), symbol: "g", suffix: None, span: Span })
2Ok(Literal { kind: StrRaw(1), symbol: "g", suffix: None, span: Span })
3Ok(Literal { kind: Integer, symbol: "123", suffix: None, span: Span })
4Ok(Literal { kind: Str, symbol: "ab", suffix: None, span: Span })
5Ok(Literal { kind: Char, symbol: "b", suffix: None, span: Span })
6Ok(Literal { kind: Char, symbol: "b", suffix: None, span: Span })
7Ok(Literal { kind: ByteStr, symbol: "b", suffix: None, span: Span })
8Ok(Literal { kind: CStr, symbol: "b", suffix: None, span: Span })
9Ok(Literal { kind: CStrRaw(0), symbol: "b", suffix: None, span: Span })
10Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span })
11Ok(Literal { kind: Byte, symbol: "b", suffix: None, span: Span })
12Ok(Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: Span })
13Ok(Literal { kind: Integer, symbol: "-256", suffix: Some("u8"), span: Span })
14Ok(TokenStream [Punct { ch: '-', spacing: Alone, span: Span }, Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: Span }])
15Ok(Literal { kind: Integer, symbol: "0b11111000000001111", suffix: Some("i16"), span: Span })
16Ok(Literal { kind: Integer, symbol: "0xf32", suffix: None, span: Span })
17Ok(Literal { kind: Integer, symbol: "0b0", suffix: Some("f32"), span: Span })
18Ok(Literal { kind: Float, symbol: "2E4", suffix: None, span: Span })
19Ok(Literal { kind: Float, symbol: "2.2E-4", suffix: Some("f64"), span: Span })
20Ok(Literal { kind: Integer, symbol: "18", suffix: Some("u8E"), span: Span })
21Ok(Literal { kind: Float, symbol: "18.0", suffix: Some("u8E"), span: Span })
22Ok(Literal { kind: CStrRaw(1), symbol: "// /* // \n */", suffix: None, span: Span })
23Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span })
24Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: Span })
25Ok(Literal { kind: StrRaw(255), symbol: "a", suffix: None, span: Span })
26Ok(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 }])
27Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: Span }, Punct { ch: '.', spacing: Alone, span: Span }, Ident { ident: "u8E", span: Span }])
28Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f32"), span: Span }])
29Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f34"), span: Span }])
30Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: Span }, Punct { ch: '.', spacing: Alone, span: Span }, Ident { ident: "bu8", span: Span }])
31Ok(TokenStream [Literal { kind: Integer, symbol: "3", suffix: None, span: Span }, Literal { kind: Integer, symbol: "4", suffix: None, span: Span }])
32Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: Span }])
33Ok(TokenStream [])
34Ok(Literal { kind: Str, symbol: "", suffix: None, span: Span })
3035Ok(TokenStream [])
3136### ERRORS
37Err(LexError("not a literal"))
3238Err(LexError("comment or whitespace around literal"))
3339Err(LexError("comment or whitespace around literal"))
3440Err(LexError("comment or whitespace around literal"))
......@@ -42,17 +48,19 @@ Err(LexError("unexpected closing delimiter: `)`"))
4248Err(LexError("unexpected closing delimiter: `]`"))
4349Err(LexError("not a literal"))
4450Err(LexError("not a literal"))
45Ok(TokenStream [Ident { ident: "r", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }])
46Ok(TokenStream [Ident { ident: "c", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }])
47Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }])
48Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 bytes(361..385) }])
49Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) }])
50Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) }])
51Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) }])
52Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }])
53Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) })
54Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 bytes(361..385) })
55Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) })
56Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) })
57Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) })
51Err(LexError("not a literal"))
52Ok(TokenStream [Ident { ident: "r", span: Span }, Literal { kind: Char, symbol: "r", suffix: None, span: Span }])
53Ok(TokenStream [Ident { ident: "c", span: Span }, Literal { kind: Char, symbol: "r", suffix: None, span: Span }])
54Ok(TokenStream [])
55Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }])
56Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: Span }])
57Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: Span }])
58Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: Span }])
59Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: Span }])
60Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }])
61Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span })
62Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: Span })
63Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: Span })
64Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: Span })
65Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: Span })
5866Err(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
7fn 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}
14fn main() {}
tests/ui/reachable/unreachable-ret-after-panic.stderr created+16
......@@ -0,0 +1,16 @@
1error: unreachable statement
2 --> $DIR/unreachable-ret-after-panic.rs:10:5
3 |
4LL | panic!();
5 | -------- any code following this expression is unreachable
6LL | for x in &v { i += 1; }
7 | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
8 |
9note: the lint level is defined here
10 --> $DIR/unreachable-ret-after-panic.rs:3:9
11 |
12LL | #![deny(unreachable_code)]
13 | ^^^^^^^^^^^^^^^^
14
15error: 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)]
11struct A (B);
12
13impl 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)]
21enum B {
22 Variant1,
23 Variant2(C),
24}
25
26impl 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)]
38struct C (D);
39
40impl 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)]
50struct D (Box<A>);
51
52impl 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
60pub fn matches() {
61 A(B::Variant1).matches(&(|| ()))
62}
tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr created+14
......@@ -0,0 +1,14 @@
1error: 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 |
4LL | a.matches(f)
5 | ^^^^^^^^^^^^
6 |
7note: `A::matches` defined here
8 --> $DIR/infinite-instantiation-via-nested-closures.rs:14:5
9 |
10LL | pub fn matches<F: Fn()>(&self, f: &F) {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12
13error: 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)]
7mod Foo { }
8
9#[allow(dead_code)]
10struct Foo;
11//~^ ERROR the name `Foo` is defined multiple times
12
13#[allow(non_snake_case)]
14mod Bar { }
15
16#[allow(dead_code)]
17struct Bar(i32);
18//~^ ERROR the name `Bar` is defined multiple times
19
20
21#[allow(dead_code)]
22struct Baz(i32);
23
24#[allow(non_snake_case)]
25mod Baz { }
26//~^ ERROR the name `Baz` is defined multiple times
27
28
29#[allow(dead_code)]
30struct Qux { x: bool }
31
32#[allow(non_snake_case)]
33mod Qux { }
34//~^ ERROR the name `Qux` is defined multiple times
35
36
37#[allow(dead_code)]
38struct Quux;
39
40#[allow(non_snake_case)]
41mod Quux { }
42//~^ ERROR the name `Quux` is defined multiple times
43
44
45#[allow(dead_code)]
46enum Corge { A, B }
47
48#[allow(non_snake_case)]
49mod Corge { }
50//~^ ERROR the name `Corge` is defined multiple times
51
52fn main() { }
tests/ui/resolve/module-type-name-conflict.stderr created+69
......@@ -0,0 +1,69 @@
1error[E0428]: the name `Foo` is defined multiple times
2 --> $DIR/module-type-name-conflict.rs:10:1
3 |
4LL | mod Foo { }
5 | ------- previous definition of the module `Foo` here
6...
7LL | struct Foo;
8 | ^^^^^^^^^^^ `Foo` redefined here
9 |
10 = note: `Foo` must be defined only once in the type namespace of this module
11
12error[E0428]: the name `Bar` is defined multiple times
13 --> $DIR/module-type-name-conflict.rs:17:1
14 |
15LL | mod Bar { }
16 | ------- previous definition of the module `Bar` here
17...
18LL | struct Bar(i32);
19 | ^^^^^^^^^^^^^^^^ `Bar` redefined here
20 |
21 = note: `Bar` must be defined only once in the type namespace of this module
22
23error[E0428]: the name `Baz` is defined multiple times
24 --> $DIR/module-type-name-conflict.rs:25:1
25 |
26LL | struct Baz(i32);
27 | ---------------- previous definition of the type `Baz` here
28...
29LL | mod Baz { }
30 | ^^^^^^^ `Baz` redefined here
31 |
32 = note: `Baz` must be defined only once in the type namespace of this module
33
34error[E0428]: the name `Qux` is defined multiple times
35 --> $DIR/module-type-name-conflict.rs:33:1
36 |
37LL | struct Qux { x: bool }
38 | ---------- previous definition of the type `Qux` here
39...
40LL | mod Qux { }
41 | ^^^^^^^ `Qux` redefined here
42 |
43 = note: `Qux` must be defined only once in the type namespace of this module
44
45error[E0428]: the name `Quux` is defined multiple times
46 --> $DIR/module-type-name-conflict.rs:41:1
47 |
48LL | struct Quux;
49 | ------------ previous definition of the type `Quux` here
50...
51LL | mod Quux { }
52 | ^^^^^^^^ `Quux` redefined here
53 |
54 = note: `Quux` must be defined only once in the type namespace of this module
55
56error[E0428]: the name `Corge` is defined multiple times
57 --> $DIR/module-type-name-conflict.rs:49:1
58 |
59LL | enum Corge { A, B }
60 | ---------- previous definition of the type `Corge` here
61...
62LL | mod Corge { }
63 | ^^^^^^^^^ `Corge` redefined here
64 |
65 = note: `Corge` must be defined only once in the type namespace of this module
66
67error: aborting due to 6 previous errors
68
69For 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
8trait Foo {
9 fn foo(self);
10}
11
12fn 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
20fn main() { }
tests/ui/traits/ambiguous-trait-matching-distinct-lifetimes.stderr created+31
......@@ -0,0 +1,31 @@
1error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo`
2 --> $DIR/ambiguous-trait-matching-distinct-lifetimes.rs:13:19
3 |
4LL | where &'a T : Foo,
5 | ^^^
6 |
7note: multiple `impl`s or `where` clauses satisfying `&'a T: Foo` found
8 --> $DIR/ambiguous-trait-matching-distinct-lifetimes.rs:13:19
9 |
10LL | where &'a T : Foo,
11 | ^^^
12LL | &'b T : Foo
13 | ^^^
14
15error[E0283]: type annotations needed: cannot satisfy `&T: Foo`
16 --> $DIR/ambiguous-trait-matching-distinct-lifetimes.rs:16:7
17 |
18LL | x.foo();
19 | ^^^
20 |
21note: multiple `impl`s or `where` clauses satisfying `&T: Foo` found
22 --> $DIR/ambiguous-trait-matching-distinct-lifetimes.rs:13:19
23 |
24LL | where &'a T : Foo,
25 | ^^^
26LL | &'b T : Foo
27 | ^^^
28
29error: aborting due to 2 previous errors
30
31For 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
6type Foo<T> where T: Copy = Box<T>;
7
8fn 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
7fn 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
13fn with_binop() {
14 let bad_idx = 0u8;
15 let _foo = 0 + [1, 2, 3][bad_idx.into()];
16 //~^ ERROR type annotations needed
17}
18
19fn standalone() {
20 let bad_idx = 0u8;
21 let _foo = [1, 2, 3][bad_idx.into()];
22 //~^ ERROR type annotations needed
23}
24
25fn with_known_index_type() {
26 let bad_idx = 0u8;
27 let _foo = [1, 2, 3][Into::<usize>::into(bad_idx)] as i32;
28}
29
30fn 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
36fn 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
42fn shift_with_ambiguous_index() {
43 let bad_idx = 0u8;
44 let _foo = 1u32 << [0u8][bad_idx.into()];
45 //~^ ERROR type annotations needed
46}
47
48fn 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
54fn main() {}
tests/ui/type-inference/index-expr-ambiguous-type.stderr created+70
......@@ -0,0 +1,70 @@
1error[E0282]: type annotations needed
2 --> $DIR/index-expr-ambiguous-type.rs:9:34
3 |
4LL | let _foo = [1, 2, 3][bad_idx.into()] as i32;
5 | ^^^^ cannot infer type
6
7error[E0284]: type annotations needed
8 --> $DIR/index-expr-ambiguous-type.rs:15:38
9 |
10LL | let _foo = 0 + [1, 2, 3][bad_idx.into()];
11 | ^^^^ cannot infer type
12 |
13 = note: cannot satisfy `<i32 as Add<_>>::Output == _`
14
15error[E0283]: type annotations needed
16 --> $DIR/index-expr-ambiguous-type.rs:21:34
17 |
18LL | 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<_>`
23help: try using a fully qualified path to specify the expected types
24 |
25LL - let _foo = [1, 2, 3][bad_idx.into()];
26LL + let _foo = [1, 2, 3][<u8 as Into<T>>::into(bad_idx)];
27 |
28
29error[E0369]: cannot add `_` to `bool`
30 --> $DIR/index-expr-ambiguous-type.rs:32:21
31 |
32LL | let _foo = true + [1, 2, 3][bad_idx.into()];
33 | ---- ^ ------------------------- _
34 | |
35 | bool
36
37error[E0284]: type annotations needed
38 --> $DIR/index-expr-ambiguous-type.rs:38:21
39 |
40LL | let _foo = 0u64 + [1i32, 2, 3][bad_idx.into()];
41 | ^ cannot infer type
42 |
43 = note: cannot satisfy `<u64 as Add<_>>::Output == _`
44
45error[E0284]: type annotations needed
46 --> $DIR/index-expr-ambiguous-type.rs:44:38
47 |
48LL | let _foo = 1u32 << [0u8][bad_idx.into()];
49 | ^^^^ cannot infer type
50 |
51 = note: cannot satisfy `<u32 as Shl<_>>::Output == _`
52
53error[E0283]: type annotations needed
54 --> $DIR/index-expr-ambiguous-type.rs:50:45
55 |
56LL | 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<_>`
61help: try using a fully qualified path to specify the expected types
62 |
63LL - let _foo = String::new() + [""][bad_idx.into()];
64LL + let _foo = String::new() + [""][<u8 as Into<T>>::into(bad_idx)];
65 |
66
67error: aborting due to 7 previous errors
68
69Some errors have detailed explanations: E0282, E0283, E0284, E0369.
70For 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
3fn foo<U>(t: U) {
4 let y = t();
5//~^ ERROR: expected function, found `U`
6}
7
8struct Bar;
9
10pub fn some_func() {
11 let f = Bar();
12//~^ ERROR: expected function, found struct `Bar`
13}
14
15fn main() {
16 foo(|| { 1 });
17}
tests/ui/typeck/call-non-fn-type-param.stderr created+30
......@@ -0,0 +1,30 @@
1error[E0618]: expected function, found `U`
2 --> $DIR/call-non-fn-type-param.rs:4:13
3 |
4LL | fn foo<U>(t: U) {
5 | - `t` has type `U`
6LL | let y = t();
7 | ^--
8 | |
9 | call expression requires function
10
11error[E0618]: expected function, found struct `Bar`
12 --> $DIR/call-non-fn-type-param.rs:11:13
13 |
14LL | struct Bar;
15 | ---------- struct `Bar` defined here
16...
17LL | let f = Bar();
18 | ^^^--
19 | |
20 | call expression requires function
21 |
22help: `Bar` is a unit struct, and does not take parentheses to be constructed
23 |
24LL - let f = Bar();
25LL + let f = Bar;
26 |
27
28error: aborting due to 2 previous errors
29
30For 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)]
5use std::collections::HashMap;
6use std::collections::hash_map::Entry::Vacant;
7
8pub 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
17fn 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
6struct Foo;
7
8impl<A> FnOnce<(A,)> for Foo {
9 type Output = ();
10 extern "rust-call" fn call_once(self, (_,): (A,)) {
11 }
12}
13
14fn main() {
15 println!("{:?}", Foo("bar"));
16}
tests/ui/uninhabited/void-branch.rs+9
......@@ -29,4 +29,13 @@ fn with_infallible() {
2929 println!()
3030}
3131
32fn infallible_with_arg<T>(x: T) -> (T, std::convert::Infallible) {
33 (x, loop {})
34 //~^ ERROR unreachable expression
35}
36
37fn 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
3241fn main() {}
tests/ui/uninhabited/void-branch.stderr+16-6
......@@ -1,3 +1,18 @@
1error: unreachable expression
2 --> $DIR/void-branch.rs:33:5
3 |
4LL | (x, loop {})
5 | ^^^^-------^
6 | | |
7 | | any code following this expression is unreachable
8 | unreachable expression
9 |
10note: the lint level is defined here
11 --> $DIR/void-branch.rs:1:9
12 |
13LL | #![deny(unreachable_code)]
14 | ^^^^^^^^^^^^^^^^
15
116error: unreachable expression
217 --> $DIR/void-branch.rs:10:13
318 |
......@@ -11,11 +26,6 @@ note: this expression has type `Void`, which is uninhabited
1126 |
1227LL | std::mem::uninitialized::<Void>();
1328 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14note: the lint level is defined here
15 --> $DIR/void-branch.rs:1:9
16 |
17LL | #![deny(unreachable_code)]
18 | ^^^^^^^^^^^^^^^^
1929
2030error: unreachable expression
2131 --> $DIR/void-branch.rs:25:9
......@@ -31,5 +41,5 @@ note: this expression has type `Infallible`, which is uninhabited
3141LL | infallible();
3242 | ^^^^^^^^^^^^
3343
34error: aborting due to 2 previous errors
44error: aborting due to 3 previous errors
3545
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
3struct Table {
4 rows: [[String]],
5 //~^ ERROR the size for values of type
6}
7
8fn f(table: &Table) -> &[String] {
9 &table.rows[0]
10 //~^ ERROR the size for values of type
11}
12
13fn main() {}
tests/ui/unsized/unsized-slice-element.stderr created+21
......@@ -0,0 +1,21 @@
1error[E0277]: the size for values of type `[String]` cannot be known at compilation time
2 --> $DIR/unsized-slice-element.rs:4:11
3 |
4LL | 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
10error[E0277]: the size for values of type `[String]` cannot be known at compilation time
11 --> $DIR/unsized-slice-element.rs:9:6
12 |
13LL | &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
19error: aborting due to 2 previous errors
20
21For 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.
11551155"""
11561156cc = [
11571157 "@CraftSpider",
1158 "@aDotInTheVoid",
11591158 "@Enselic",
11601159 "@obi1kenobi",
11611160]
......@@ -1313,7 +1312,7 @@ Please ensure that if you've changed the output:
13131312- It's intentional.
13141313- The `FORMAT_VERSION` in `src/librustdoc-json-types` is bumped if necessary.
13151314"""
1316cc = ["@aDotInTheVoid", "@obi1kenobi"]
1315cc = ["@obi1kenobi"]
13171316
13181317[mentions."tests/ui/derives/deriving-all-codegen.stdout"]
13191318message = "Changes to the code generated for builtin derived traits."
......@@ -1698,7 +1697,7 @@ dep-bumps = [
16981697"/tests/rustdoc-gui" = ["rustdoc"]
16991698"/tests/rustdoc-js-std" = ["rustdoc"]
17001699"/tests/rustdoc-js/" = ["rustdoc"]
1701"/tests/rustdoc-json" = ["@aDotInTheVoid"]
1700"/tests/rustdoc-json" = ["rustdoc"]
17021701"/tests/rustdoc-ui" = ["rustdoc"]
17031702"/tests/ui" = ["compiler"]
17041703"/tests/ui-fulldeps" = ["compiler"]