1use std::sync::Arc;
2
3use rustc_ast::{self as ast, *};
4use rustc_errors::StashKey;
5use rustc_hir::def::{DefKind, PartialRes, PerNS, Res};
6use rustc_hir::def_id::DefId;
7use rustc_hir::{self as hir, GenericArg};
8use rustc_middle::{span_bug, ty};
9use rustc_session::parse::add_feature_diagnostics;
10use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym};
11use smallvec::smallvec;
12use tracing::{debug, instrument};
13
14use super::errors::{
15 AsyncBoundNotOnTrait, AsyncBoundOnlyForFnTraits, BadReturnTypeNotation,
16 GenericTypeWithParentheses, RTNSuggestion, UseAngleBrackets,
17};
18use super::{
19 AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition,
20 LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt,
21};
22
23impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
24 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("lower_qpath",
"rustc_ast_lowering::path", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ast_lowering/src/path.rs"),
::tracing_core::__macro_support::Option::Some(24u32),
::tracing_core::__macro_support::Option::Some("rustc_ast_lowering::path"),
::tracing_core::field::FieldSet::new(&["id", "qself", "p",
"param_mode", "allow_return_type_notation", "itctx",
"modifiers"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&qself)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&p)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(¶m_mode)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&allow_return_type_notation)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&itctx)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&modifiers)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: hir::QPath<'hir> = loop {};
return __tracing_attr_fake_return;
}
{
let qself_position = qself.as_ref().map(|q| q.position);
let qself =
qself.as_ref().map(|q|
{
self.lower_ty_alloc(&q.ty,
ImplTraitContext::Disallowed(ImplTraitPosition::Path))
});
let partial_res =
self.resolver.get_partial_res(id).unwrap_or_else(||
PartialRes::new(Res::Err));
let base_res = partial_res.base_res();
let unresolved_segments = partial_res.unresolved_segments();
let mut res = self.lower_res(base_res);
if let Some(TraitBoundModifiers {
asyncness: BoundAsyncness::Async(_), .. }) = modifiers {
match res {
Res::Def(DefKind::Trait, def_id) => {
if let Some(async_def_id) =
self.map_trait_to_async_trait(def_id) {
res = Res::Def(DefKind::Trait, async_def_id);
} else {
self.dcx().emit_err(AsyncBoundOnlyForFnTraits {
span: p.span,
});
}
}
Res::Err => {}
_ => {
self.dcx().emit_err(AsyncBoundNotOnTrait {
span: p.span,
descr: res.descr(),
});
}
}
}
let bound_modifier_allowed_features =
if let Res::Def(DefKind::Trait, async_def_id) = res &&
self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some()
{
Some(Arc::clone(&self.allow_async_fn_traits))
} else { None };
let itctx =
|i|
{
if i + 1 == p.segments.len() {
itctx
} else {
ImplTraitContext::Disallowed(ImplTraitPosition::Path)
}
};
let path_span_lo = p.span.shrink_to_lo();
let proj_start = p.segments.len() - unresolved_segments;
let path =
self.arena.alloc(hir::Path {
res,
segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map(|(i,
segment)|
{
let param_mode =
match (qself_position, param_mode) {
(Some(j), ParamMode::Optional) if i < j => {
ParamMode::Explicit
}
_ => param_mode,
};
let generic_args_mode =
match base_res {
Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
GenericArgsMode::ParenSugar
}
Res::Def(DefKind::AssocFn, _) |
Res::Def(DefKind::AssocConst { .. }, _) |
Res::Def(DefKind::AssocTy, _) if i + 2 == proj_start => {
GenericArgsMode::ParenSugar
}
Res::Def(DefKind::AssocFn, _) if i + 1 == proj_start => {
match allow_return_type_notation {
AllowReturnTypeNotation::Yes =>
GenericArgsMode::ReturnTypeNotation,
AllowReturnTypeNotation::No => GenericArgsMode::Err,
}
}
Res::Err => GenericArgsMode::Silence,
_ => GenericArgsMode::Err,
};
self.lower_path_segment(p.span, segment, param_mode,
generic_args_mode, itctx(i),
bound_modifier_allowed_features.clone())
})),
span: self.lower_span(p.segments[..proj_start].last().map_or(path_span_lo,
|segment| path_span_lo.to(segment.span()))),
});
if let Some(bound_modifier_allowed_features) =
bound_modifier_allowed_features {
path.span =
self.mark_span_with_reason(DesugaringKind::BoundModifier,
path.span, Some(bound_modifier_allowed_features));
}
if unresolved_segments == 0 {
return hir::QPath::Resolved(qself, path);
}
let mut ty =
if path.segments.is_empty() {
qself.expect("missing QSelf for <T>::...")
} else {
let new_id = self.next_id();
self.arena.alloc(self.ty_path(new_id, path.span,
hir::QPath::Resolved(qself, path)))
};
for (i, segment) in p.segments.iter().enumerate().skip(proj_start)
{
let generic_args_mode =
if i + 1 == p.segments.len() &&
#[allow(non_exhaustive_omitted_patterns)] match allow_return_type_notation
{
AllowReturnTypeNotation::Yes => true,
_ => false,
} {
GenericArgsMode::ReturnTypeNotation
} else { GenericArgsMode::Err };
let hir_segment =
self.arena.alloc(self.lower_path_segment(p.span, segment,
param_mode, generic_args_mode, itctx(i), None));
let qpath = hir::QPath::TypeRelative(ty, hir_segment);
if i == p.segments.len() - 1 { return qpath; }
let new_id = self.next_id();
ty =
self.arena.alloc(self.ty_path(new_id,
path_span_lo.to(segment.span()), qpath));
}
self.dcx().span_bug(p.span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("lower_qpath: no final extension segment in {0}..{1}",
proj_start, p.segments.len()))
}));
}
}
}#[instrument(level = "trace", skip(self))]
25 pub(crate) fn lower_qpath(
26 &mut self,
27 id: NodeId,
28 qself: &Option<Box<QSelf>>,
29 p: &Path,
30 param_mode: ParamMode,
31 allow_return_type_notation: AllowReturnTypeNotation,
32 itctx: ImplTraitContext,
33 modifiers: Option<ast::TraitBoundModifiers>,
35 ) -> hir::QPath<'hir> {
36 let qself_position = qself.as_ref().map(|q| q.position);
37 let qself = qself
38 .as_ref()
39 .map(|q| {
41 self.lower_ty_alloc(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path))
42 });
43
44 let partial_res =
45 self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
46 let base_res = partial_res.base_res();
47 let unresolved_segments = partial_res.unresolved_segments();
48
49 let mut res = self.lower_res(base_res);
50
51 if let Some(TraitBoundModifiers { asyncness: BoundAsyncness::Async(_), .. }) = modifiers {
53 match res {
54 Res::Def(DefKind::Trait, def_id) => {
55 if let Some(async_def_id) = self.map_trait_to_async_trait(def_id) {
56 res = Res::Def(DefKind::Trait, async_def_id);
57 } else {
58 self.dcx().emit_err(AsyncBoundOnlyForFnTraits { span: p.span });
59 }
60 }
61 Res::Err => {
62 }
64 _ => {
65 self.dcx().emit_err(AsyncBoundNotOnTrait { span: p.span, descr: res.descr() });
69 }
70 }
71 }
72
73 let bound_modifier_allowed_features = if let Res::Def(DefKind::Trait, async_def_id) = res
76 && self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some()
77 {
78 Some(Arc::clone(&self.allow_async_fn_traits))
79 } else {
80 None
81 };
82
83 let itctx = |i| {
86 if i + 1 == p.segments.len() {
87 itctx
88 } else {
89 ImplTraitContext::Disallowed(ImplTraitPosition::Path)
90 }
91 };
92
93 let path_span_lo = p.span.shrink_to_lo();
94 let proj_start = p.segments.len() - unresolved_segments;
95 let path = self.arena.alloc(hir::Path {
96 res,
97 segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map(
98 |(i, segment)| {
99 let param_mode = match (qself_position, param_mode) {
100 (Some(j), ParamMode::Optional) if i < j => {
101 ParamMode::Explicit
105 }
106 _ => param_mode,
107 };
108
109 let generic_args_mode = match base_res {
110 Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
112 GenericArgsMode::ParenSugar
113 }
114 Res::Def(DefKind::AssocFn, _)
116 | Res::Def(DefKind::AssocConst { .. }, _)
117 | Res::Def(DefKind::AssocTy, _)
118 if i + 2 == proj_start =>
119 {
120 GenericArgsMode::ParenSugar
121 }
122 Res::Def(DefKind::AssocFn, _) if i + 1 == proj_start => {
123 match allow_return_type_notation {
124 AllowReturnTypeNotation::Yes => GenericArgsMode::ReturnTypeNotation,
125 AllowReturnTypeNotation::No => GenericArgsMode::Err,
126 }
127 }
128 Res::Err => GenericArgsMode::Silence,
130 _ => GenericArgsMode::Err,
132 };
133
134 self.lower_path_segment(
135 p.span,
136 segment,
137 param_mode,
138 generic_args_mode,
139 itctx(i),
140 bound_modifier_allowed_features.clone(),
141 )
142 },
143 )),
144 span: self.lower_span(
145 p.segments[..proj_start]
146 .last()
147 .map_or(path_span_lo, |segment| path_span_lo.to(segment.span())),
148 ),
149 });
150
151 if let Some(bound_modifier_allowed_features) = bound_modifier_allowed_features {
152 path.span = self.mark_span_with_reason(
153 DesugaringKind::BoundModifier,
154 path.span,
155 Some(bound_modifier_allowed_features),
156 );
157 }
158
159 if unresolved_segments == 0 {
162 return hir::QPath::Resolved(qself, path);
163 }
164
165 let mut ty = if path.segments.is_empty() {
167 qself.expect("missing QSelf for <T>::...")
170 } else {
171 let new_id = self.next_id();
175 self.arena.alloc(self.ty_path(new_id, path.span, hir::QPath::Resolved(qself, path)))
176 };
177
178 for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
189 let generic_args_mode = if i + 1 == p.segments.len()
191 && matches!(allow_return_type_notation, AllowReturnTypeNotation::Yes)
192 {
193 GenericArgsMode::ReturnTypeNotation
194 } else {
195 GenericArgsMode::Err
196 };
197
198 let hir_segment = self.arena.alloc(self.lower_path_segment(
199 p.span,
200 segment,
201 param_mode,
202 generic_args_mode,
203 itctx(i),
204 None,
205 ));
206 let qpath = hir::QPath::TypeRelative(ty, hir_segment);
207
208 if i == p.segments.len() - 1 {
210 return qpath;
211 }
212
213 let new_id = self.next_id();
215 ty = self.arena.alloc(self.ty_path(new_id, path_span_lo.to(segment.span()), qpath));
216 }
217
218 self.dcx().span_bug(
221 p.span,
222 format!(
223 "lower_qpath: no final extension segment in {}..{}",
224 proj_start,
225 p.segments.len()
226 ),
227 );
228 }
229
230 pub(crate) fn lower_use_path(
231 &mut self,
232 res: PerNS<Option<Res>>,
233 p: &Path,
234 param_mode: ParamMode,
235 ) -> &'hir hir::UsePath<'hir> {
236 if !!res.is_empty() {
::core::panicking::panic("assertion failed: !res.is_empty()")
};assert!(!res.is_empty());
237 self.arena.alloc(hir::UsePath {
238 res,
239 segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
240 self.lower_path_segment(
241 p.span,
242 segment,
243 param_mode,
244 GenericArgsMode::Err,
245 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
246 None,
247 )
248 })),
249 span: self.lower_span(p.span),
250 })
251 }
252
253 pub(crate) fn lower_path_segment(
254 &mut self,
255 path_span: Span,
256 segment: &PathSegment,
257 param_mode: ParamMode,
258 generic_args_mode: GenericArgsMode,
259 itctx: ImplTraitContext,
260 bound_modifier_allowed_features: Option<Arc<[Symbol]>>,
264 ) -> hir::PathSegment<'hir> {
265 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ast_lowering/src/path.rs:265",
"rustc_ast_lowering::path", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ast_lowering/src/path.rs"),
::tracing_core::__macro_support::Option::Some(265u32),
::tracing_core::__macro_support::Option::Some("rustc_ast_lowering::path"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("path_span: {0:?}, lower_path_segment(segment: {1:?})",
path_span, segment) as &dyn Value))])
});
} else { ; }
};debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment);
266 let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() {
267 match generic_args {
268 GenericArgs::AngleBracketed(data) => {
269 self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
270 }
271 GenericArgs::Parenthesized(data) => match generic_args_mode {
272 GenericArgsMode::ReturnTypeNotation => {
273 let err = match (&data.inputs[..], &data.output) {
274 ([_, ..], FnRetTy::Default(_)) => {
275 BadReturnTypeNotation::Inputs { span: data.inputs_span }
276 }
277 ([], FnRetTy::Default(_)) => {
278 BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
279 }
280 (_, FnRetTy::Ty(ty)) => {
282 let span = data.inputs_span.shrink_to_hi().to(ty.span);
283 BadReturnTypeNotation::Output {
284 span,
285 suggestion: RTNSuggestion {
286 output: span,
287 input: data.inputs_span,
288 },
289 }
290 }
291 };
292 let mut err = self.dcx().create_err(err);
293 if !self.tcx.features().return_type_notation()
294 && self.tcx.sess.is_nightly_build()
295 {
296 add_feature_diagnostics(
297 &mut err,
298 &self.tcx.sess,
299 sym::return_type_notation,
300 );
301 }
302 err.stash(path_span, StashKey::ReturnTypeNotation);
303 (
304 GenericArgsCtor {
305 args: Default::default(),
306 constraints: &[],
307 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
308 span: path_span,
309 },
310 false,
311 )
312 }
313 GenericArgsMode::ParenSugar | GenericArgsMode::Silence => self
314 .lower_parenthesized_parameter_data(
315 data,
316 itctx,
317 bound_modifier_allowed_features,
318 ),
319 GenericArgsMode::Err => {
320 let sub = if !data.inputs.is_empty() {
322 let open_param = data.inputs_span.shrink_to_lo().to(data
324 .inputs
325 .first()
326 .unwrap()
327 .span
328 .shrink_to_lo());
329 let close_param = data
331 .inputs
332 .last()
333 .unwrap()
334 .span
335 .shrink_to_hi()
336 .to(data.inputs_span.shrink_to_hi());
337
338 Some(UseAngleBrackets { open_param, close_param })
339 } else {
340 None
341 };
342 self.dcx().emit_err(GenericTypeWithParentheses { span: data.span, sub });
343 (
344 self.lower_angle_bracketed_parameter_data(
345 &data.as_angle_bracketed_args(),
346 param_mode,
347 itctx,
348 )
349 .0,
350 false,
351 )
352 }
353 },
354 GenericArgs::ParenthesizedElided(span) => {
355 match generic_args_mode {
356 GenericArgsMode::ReturnTypeNotation | GenericArgsMode::Silence => {
357 }
359 GenericArgsMode::ParenSugar | GenericArgsMode::Err => {
360 self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span });
361 }
362 }
363 (
364 GenericArgsCtor {
365 args: Default::default(),
366 constraints: &[],
367 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
368 span: *span,
369 },
370 false,
371 )
372 }
373 }
374 } else {
375 (
376 GenericArgsCtor {
377 args: Default::default(),
378 constraints: &[],
379 parenthesized: hir::GenericArgsParentheses::No,
380 span: path_span.shrink_to_hi(),
381 },
382 param_mode == ParamMode::Optional,
383 )
384 };
385
386 let has_lifetimes =
387 generic_args.args.iter().any(|arg| #[allow(non_exhaustive_omitted_patterns)] match arg {
GenericArg::Lifetime(_) => true,
_ => false,
}matches!(arg, GenericArg::Lifetime(_)));
388
389 if generic_args.parenthesized != hir::GenericArgsParentheses::ParenSugar && !has_lifetimes {
391 self.maybe_insert_elided_lifetimes_in_path(
392 path_span,
393 segment.id,
394 segment.ident.span,
395 &mut generic_args,
396 );
397 }
398
399 let res = self.expect_full_res(segment.id);
400 let hir_id = self.lower_node_id(segment.id);
401 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ast_lowering/src/path.rs:401",
"rustc_ast_lowering::path", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ast_lowering/src/path.rs"),
::tracing_core::__macro_support::Option::Some(401u32),
::tracing_core::__macro_support::Option::Some("rustc_ast_lowering::path"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("lower_path_segment: ident={0:?} original-id={1:?} new-id={2:?}",
segment.ident, segment.id, hir_id) as &dyn Value))])
});
} else { ; }
};debug!(
402 "lower_path_segment: ident={:?} original-id={:?} new-id={:?}",
403 segment.ident, segment.id, hir_id,
404 );
405
406 hir::PathSegment {
407 ident: self.lower_ident(segment.ident),
408 hir_id,
409 res: self.lower_res(res),
410 infer_args,
411 args: if generic_args.is_empty() && generic_args.span.is_empty() {
412 None
413 } else {
414 Some(generic_args.into_generic_args(self))
415 },
416 }
417 }
418
419 fn maybe_insert_elided_lifetimes_in_path(
420 &mut self,
421 path_span: Span,
422 segment_id: NodeId,
423 segment_ident_span: Span,
424 generic_args: &mut GenericArgsCtor<'hir>,
425 ) {
426 let (start, end) = match self.resolver.get_lifetime_res(segment_id) {
427 Some(LifetimeRes::ElidedAnchor { start, end }) => (start, end),
428 None => return,
429 Some(res) => {
430 ::rustc_middle::util::bug::span_bug_fmt(path_span,
format_args!("expected an elided lifetime to insert. found {0:?}", res))span_bug!(path_span, "expected an elided lifetime to insert. found {res:?}")
431 }
432 };
433 let expected_lifetimes = end.as_usize() - start.as_usize();
434 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ast_lowering/src/path.rs:434",
"rustc_ast_lowering::path", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ast_lowering/src/path.rs"),
::tracing_core::__macro_support::Option::Some(434u32),
::tracing_core::__macro_support::Option::Some("rustc_ast_lowering::path"),
::tracing_core::field::FieldSet::new(&["expected_lifetimes"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&expected_lifetimes
as &dyn Value))])
});
} else { ; }
};debug!(expected_lifetimes);
435
436 let (elided_lifetime_span, angle_brackets) = if generic_args.span.is_empty() {
439 (
443 segment_ident_span.find_ancestor_inside(path_span).unwrap_or(path_span),
444 hir::AngleBrackets::Missing,
445 )
446 } else {
447 (
449 generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo(),
450 if generic_args.is_empty() {
451 hir::AngleBrackets::Empty
452 } else {
453 hir::AngleBrackets::Full
454 },
455 )
456 };
457
458 generic_args.args.insert_many(
459 0,
460 (start..end).map(|id| {
461 let l =
462 self.lower_lifetime_hidden_in_path(id, elided_lifetime_span, angle_brackets);
463 GenericArg::Lifetime(l)
464 }),
465 );
466 }
467
468 pub(crate) fn lower_angle_bracketed_parameter_data(
469 &mut self,
470 data: &AngleBracketedArgs,
471 param_mode: ParamMode,
472 itctx: ImplTraitContext,
473 ) -> (GenericArgsCtor<'hir>, bool) {
474 let has_non_lt_args = data.args.iter().any(|arg| match arg {
475 AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_))
476 | AngleBracketedArg::Constraint(_) => false,
477 AngleBracketedArg::Arg(ast::GenericArg::Type(_) | ast::GenericArg::Const(_)) => true,
478 });
479 let args = data
480 .args
481 .iter()
482 .filter_map(|arg| match arg {
483 AngleBracketedArg::Arg(arg) => Some(self.lower_generic_arg(arg, itctx)),
484 AngleBracketedArg::Constraint(_) => None,
485 })
486 .collect();
487 let constraints =
488 self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
489 AngleBracketedArg::Constraint(c) => {
490 Some(self.lower_assoc_item_constraint(c, itctx))
491 }
492 AngleBracketedArg::Arg(_) => None,
493 }));
494 let ctor = GenericArgsCtor {
495 args,
496 constraints,
497 parenthesized: hir::GenericArgsParentheses::No,
498 span: data.span,
499 };
500 (ctor, !has_non_lt_args && param_mode == ParamMode::Optional)
501 }
502
503 fn lower_parenthesized_parameter_data(
504 &mut self,
505 data: &ParenthesizedArgs,
506 itctx: ImplTraitContext,
507 bound_modifier_allowed_features: Option<Arc<[Symbol]>>,
508 ) -> (GenericArgsCtor<'hir>, bool) {
509 let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
515 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| {
516 self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
517 }));
518 let output_ty = match output {
519 FnRetTy::Ty(ty) if #[allow(non_exhaustive_omitted_patterns)] match itctx {
ImplTraitContext::OpaqueTy { .. } => true,
_ => false,
}matches!(itctx, ImplTraitContext::OpaqueTy { .. }) => {
525 if self.tcx.features().impl_trait_in_fn_trait_return() {
526 self.lower_ty_alloc(ty, itctx)
527 } else {
528 self.lower_ty_alloc(
529 ty,
530 ImplTraitContext::FeatureGated(
531 ImplTraitPosition::FnTraitReturn,
532 sym::impl_trait_in_fn_trait_return,
533 ),
534 )
535 }
536 }
537 FnRetTy::Ty(ty) => self
538 .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)),
539 FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
540 };
541 let args = {
let count = 0usize + 1usize;
let mut vec = ::smallvec::SmallVec::new();
if count <= vec.inline_size() {
vec.push(GenericArg::Type(self.arena.alloc(self.ty_tup(*inputs_span,
inputs)).try_as_ambig_ty().unwrap()));
vec
} else {
::smallvec::SmallVec::from_vec(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[GenericArg::Type(self.arena.alloc(self.ty_tup(*inputs_span,
inputs)).try_as_ambig_ty().unwrap())])))
}
}smallvec![GenericArg::Type(
542 self.arena.alloc(self.ty_tup(*inputs_span, inputs)).try_as_ambig_ty().unwrap()
543 )];
544
545 let mut output_span = output_ty.span;
548 if let Some(bound_modifier_allowed_features) = bound_modifier_allowed_features {
549 output_span = self.mark_span_with_reason(
550 DesugaringKind::BoundModifier,
551 output_span,
552 Some(bound_modifier_allowed_features),
553 );
554 }
555 let constraint = self.assoc_ty_binding(sym::Output, output_span, output_ty);
556
557 (
558 GenericArgsCtor {
559 args,
560 constraints: self.arena.alloc_from_iter([constraint])arena_vec![self; constraint],
561 parenthesized: hir::GenericArgsParentheses::ParenSugar,
562 span: data.inputs_span,
563 },
564 false,
565 )
566 }
567
568 pub(crate) fn assoc_ty_binding(
570 &mut self,
571 assoc_ty_name: rustc_span::Symbol,
572 span: Span,
573 ty: &'hir hir::Ty<'hir>,
574 ) -> hir::AssocItemConstraint<'hir> {
575 let ident = Ident::with_dummy_span(assoc_ty_name);
576 let kind = hir::AssocItemConstraintKind::Equality { term: ty.into() };
577 let args = self.arena.alloc_from_iter([])arena_vec![self;];
578 let constraints = self.arena.alloc_from_iter([])arena_vec![self;];
579 let gen_args = self.arena.alloc(hir::GenericArgs {
580 args,
581 constraints,
582 parenthesized: hir::GenericArgsParentheses::No,
583 span_ext: DUMMY_SP,
584 });
585 hir::AssocItemConstraint {
586 hir_id: self.next_id(),
587 gen_args,
588 span: self.lower_span(span),
589 ident,
590 kind,
591 }
592 }
593
594 fn map_trait_to_async_trait(&self, def_id: DefId) -> Option<DefId> {
601 let lang_items = self.tcx.lang_items();
602 match self.tcx.fn_trait_kind_from_def_id(def_id)? {
603 ty::ClosureKind::Fn => lang_items.async_fn_trait(),
604 ty::ClosureKind::FnMut => lang_items.async_fn_mut_trait(),
605 ty::ClosureKind::FnOnce => lang_items.async_fn_once_trait(),
606 }
607 }
608}