Skip to content

Commit 0b1760a

Browse files
committed
Auto merge of #162487 - JonathanBrouwer:rollup-3MKwguM, r=JonathanBrouwer
Rollup of 6 pull requests Successful merges: - #162309 (offload: automate manual clang-linker-wrapper step) - #160505 (delegation: supporting inherent impls) - #160712 (windows-gnullvm: always link libunwind statically) - #161423 (trait_selection: Keep type-op region constraints in borrowck) - #162461 (limit the api of `fold_predicate` and `visit_predicate`) - #162475 (Fix unsoundness bug on next trait solver for dyn const generics placeholder)
2 parents b505807 + faf7381 commit 0b1760a

102 files changed

Lines changed: 2718 additions & 1455 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_ast/src/ast.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,14 @@ impl GenericArg {
294294
GenericArg::Const(ct) => ct.value.span,
295295
}
296296
}
297+
298+
pub fn is_maybe_parenthesised_infer(&self) -> bool {
299+
match self {
300+
GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime,
301+
GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(),
302+
GenericArg::Const(_) => false,
303+
}
304+
}
297305
}
298306

299307
/// A path like `Foo<'a, T>`.

compiler/rustc_ast_lowering/src/delegation/generics.rs

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::assert_matches;
2+
13
use hir::HirId;
24
use hir::def::{DefKind, Res};
35
use rustc_ast::*;
@@ -11,7 +13,10 @@ use rustc_span::{ErrorGuaranteed, Ident, Span, sym};
1113

1214
use crate::LoweringContext;
1315
use crate::delegation::resolution::resolver::DelegationResolver;
14-
use crate::diagnostics::DelegationInfersMismatch;
16+
use crate::diagnostics::{
17+
DelegationInfersMismatch, DelegationToInherentImplMustContainParentGenerics,
18+
DelegationToInherentImplParentContainsInfer,
19+
};
1520

1621
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1722
pub(super) enum GenericsPosition {
@@ -25,6 +30,7 @@ pub(super) enum GenericArgSlot<T> {
2530
Generate(T, Option<usize> /* Infer arg index from AST */),
2631
}
2732

33+
#[derive(Debug)]
2834
pub(super) struct DelegationGenerics<T> {
2935
data: T,
3036
pos: GenericsPosition,
@@ -57,11 +63,13 @@ impl<'hir> DelegationGenerics<TyGenerics<'hir>> {
5763
/// meaning we did not propagate them and thus we do not need to generate generic params
5864
/// (i.e., method call scenarios), in such a case this approach helps
5965
/// a lot as if `into_hir_generics` will not be called then uplifting will not happen.
66+
#[derive(Debug)]
6067
pub(super) enum HirOrTyGenerics<'hir> {
6168
Ty(DelegationGenerics<TyGenerics<'hir>>),
6269
Hir(DelegationGenerics<&'hir hir::Generics<'hir>>),
6370
}
6471

72+
#[derive(Debug)]
6573
pub(super) struct GenericsGenerationResult<'hir> {
6674
pub(super) generics: HirOrTyGenerics<'hir>,
6775
pub(super) args_segment_id: HirId,
@@ -80,6 +88,7 @@ pub(super) struct GenericsGenerationResults<'hir> {
8088
pub(super) self_ty_propagation_kind: Option<hir::DelegationSelfTyPropagationKind>,
8189
}
8290

91+
#[derive(Debug)]
8392
pub(super) struct DelegationGenericArgsIterator<'hir> {
8493
index: usize = Default::default(),
8594
params: &'hir [hir::GenericParam<'hir>],
@@ -145,6 +154,7 @@ impl<'hir> DelegationGenericArgsIterator<'hir> {
145154
ctx: &mut LoweringContext<'_, 'hir>,
146155
) -> Vec<hir::GenericArg<'hir>> {
147156
let mut args = vec![];
157+
148158
while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) {
149159
args.push(arg);
150160
}
@@ -238,6 +248,7 @@ impl<'hir> GenericsGenerationResult<'hir> {
238248
}
239249
}
240250

251+
#[derive(Debug)]
241252
enum ParentSegmentArgs<'a> {
242253
/// Parent segment is valid and generic args are specified:
243254
/// `reuse Trait::<'static, ()>::foo;`.
@@ -273,7 +284,7 @@ struct GenericsResolution<'a, 'tcx> {
273284
/// `reuse <_ as Trait>::foo;`.
274285
qself_is_infer: bool,
275286
/// Whether we should generate `Self` generic param.
276-
generate_self: bool,
287+
generate_free_to_trait_self: bool,
277288
}
278289

279290
impl<'hir> DelegationResolver<'_, 'hir> {
@@ -288,8 +299,7 @@ impl<'hir> DelegationResolver<'_, 'hir> {
288299
let delegation_in_free_ctx =
289300
!matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. });
290301

291-
let sig_parent = tcx.parent(sig_id);
292-
let sig_in_trait = matches!(tcx.def_kind(sig_parent), DefKind::Trait);
302+
let sig_in_trait = matches!(tcx.def_kind(tcx.parent(sig_id)), DefKind::Trait);
293303
let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait;
294304

295305
let mut sig_parent_params: &[ty::GenericParamDef] = &[];
@@ -301,8 +311,13 @@ impl<'hir> DelegationResolver<'_, 'hir> {
301311

302312
let parent_args = if let [.., parent_segment, _] = &delegation.path.segments[..] {
303313
let res = self.get_resolution_id(parent_segment.id)?;
304-
if matches!(tcx.def_kind(res), DefKind::Trait | DefKind::TraitAlias) {
305-
sig_parent_params = &tcx.generics_of(sig_parent).own_params;
314+
if !matches!(tcx.def_kind(res), DefKind::Mod) {
315+
assert_matches!(
316+
tcx.def_kind(res),
317+
DefKind::Trait | DefKind::Struct | DefKind::Enum
318+
);
319+
320+
sig_parent_params = &tcx.generics_of(res).own_params;
306321
self.get_user_args(parent_segment)
307322
.map(|args| ParentSegmentArgs::Specified(args))
308323
.unwrap_or(ParentSegmentArgs::NotSpecified)
@@ -319,7 +334,8 @@ impl<'hir> DelegationResolver<'_, 'hir> {
319334
qself_is_none,
320335
qself_is_infer,
321336
free_to_trait_delegation,
322-
generate_self: free_to_trait_delegation && (qself_is_none || qself_is_infer),
337+
generate_free_to_trait_self: free_to_trait_delegation
338+
&& (qself_is_none || qself_is_infer),
323339
trait_impl: matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }),
324340
sig_child_params: &tcx.generics_of(sig_id).own_params,
325341
child_args: self.get_user_args(
@@ -349,10 +365,11 @@ impl<'hir> DelegationResolver<'_, 'hir> {
349365
&self,
350366
delegation: &Delegation,
351367
sig_id: DefId,
368+
span: Span,
352369
) -> Result<GenericsGenerationResults<'hir>, ErrorGuaranteed> {
353370
let res @ GenericsResolution {
354371
trait_impl,
355-
generate_self,
372+
generate_free_to_trait_self,
356373
sig_child_params,
357374
sig_parent_params,
358375
..
@@ -376,20 +393,27 @@ impl<'hir> DelegationResolver<'_, 'hir> {
376393
return Ok(GenericsGenerationResults { parent, child, self_ty_propagation_kind: None });
377394
}
378395

396+
self.check_delegation_to_inherent_impl(&res.parent_args, sig_id, span)?;
397+
379398
let tcx = self.tcx();
399+
400+
// If parent is inherent impl then there is no `Self` param to skip, so add additional check.
401+
let skip_self =
402+
!generate_free_to_trait_self && tcx.def_kind(tcx.parent(sig_id)) == DefKind::Trait;
403+
380404
let parent_generics = match res.parent_args {
381405
ParentSegmentArgs::Specified(args) => DelegationGenerics {
382406
data: Self::create_slots_from_args(
383407
tcx,
384408
args,
385-
&sig_parent_params[usize::from(!generate_self)..],
386-
generate_self,
409+
&sig_parent_params[usize::from(skip_self)..],
410+
generate_free_to_trait_self,
387411
),
388412
pos: GenericsPosition::Parent,
389413
trait_impl,
390414
},
391415
ParentSegmentArgs::NotSpecified => DelegationGenerics::generate_all(
392-
&sig_parent_params[usize::from(!generate_self)..],
416+
&sig_parent_params[usize::from(skip_self)..],
393417
GenericsPosition::Parent,
394418
trait_impl,
395419
),
@@ -437,6 +461,46 @@ impl<'hir> DelegationResolver<'_, 'hir> {
437461
})
438462
}
439463

464+
fn check_delegation_to_inherent_impl(
465+
&self,
466+
parent_args: &ParentSegmentArgs<'_>,
467+
sig_id: DefId,
468+
span: Span,
469+
) -> Result<(), ErrorGuaranteed> {
470+
let tcx = self.tcx();
471+
472+
if !(tcx.def_kind(sig_id) == DefKind::AssocFn
473+
&& matches!(tcx.def_kind(tcx.parent(sig_id)), DefKind::Impl { of_trait: false }))
474+
{
475+
return Ok(());
476+
}
477+
478+
let ty::Adt(def, _) = tcx.type_of(tcx.parent(sig_id)).skip_binder().kind() else {
479+
unreachable!("parent of inherent function can be only struct or enum")
480+
};
481+
482+
match parent_args {
483+
ParentSegmentArgs::Invalid => unreachable!(),
484+
ParentSegmentArgs::Specified(args) => args
485+
.args
486+
.iter()
487+
.all(|arg| {
488+
let AngleBracketedArg::Arg(arg) = arg else { return false };
489+
!arg.is_maybe_parenthesised_infer()
490+
})
491+
.ok_or_else(|| {
492+
self.tcx().dcx().emit_err(DelegationToInherentImplParentContainsInfer { span })
493+
}),
494+
ParentSegmentArgs::NotSpecified => match tcx.generics_of(def.did()).own_params.len() {
495+
0 => Ok(()),
496+
_ => Err(self
497+
.tcx()
498+
.dcx()
499+
.emit_err(DelegationToInherentImplMustContainParentGenerics { span })),
500+
},
501+
}
502+
}
503+
440504
/// Generates generic argument slots for user-specified `args` and
441505
/// generic `params` of the signature function. This function checks whether
442506
/// there are infers (`kw::UnderscoreLifetime` or `kw::Underscore`) in
@@ -459,12 +523,7 @@ impl<'hir> DelegationResolver<'_, 'hir> {
459523
let params = &params[usize::from(add_first_self)..];
460524
for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() {
461525
let AngleBracketedArg::Arg(arg) = arg else { continue };
462-
463-
let is_infer = match arg {
464-
GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime,
465-
GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(),
466-
GenericArg::Const(_) => false,
467-
};
526+
let is_infer = arg.is_maybe_parenthesised_infer();
468527

469528
// If `'_` is used instead of `_` (or vice versa) we emit a meaningful
470529
// error instead of processing this infer or leaving it as is for signature

compiler/rustc_ast_lowering/src/delegation/mod.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use rustc_ast as ast;
4747
use rustc_ast::*;
4848
use rustc_hir::attrs::lang_items::LangItem;
4949
use rustc_hir::def::DefKind;
50-
use rustc_hir::{self as hir, FnDeclFlags};
50+
use rustc_hir::{self as hir, FnDeclFlags, QPath};
5151
use rustc_middle::ty::Asyncness;
5252
use rustc_span::def_id::DefId;
5353
use rustc_span::symbol::kw;
@@ -62,7 +62,7 @@ use crate::{
6262

6363
mod attributes;
6464
mod generics;
65-
mod resolution;
65+
pub(crate) mod resolution;
6666

6767
pub(crate) struct DelegationResults<'hir> {
6868
pub body_id: hir::BodyId,
@@ -416,7 +416,37 @@ impl<'hir> LoweringContext<'_, 'hir> {
416416

417417
hir::QPath::Resolved(ty, self.arena.alloc(new_path))
418418
}
419-
hir::QPath::TypeRelative(..) => unreachable!("until inherent methods are supported"),
419+
hir::QPath::TypeRelative(mut ty, segment) => {
420+
let mut segment = self.process_segment(span, segment, &mut generics.child);
421+
segment.res = Res::Def(self.tcx.def_kind(res.call_path_res), res.call_path_res);
422+
423+
let ty_hir_id = ty.hir_id;
424+
425+
// Propagating child generics if needed.
426+
ty = if let hir::TyKind::Path(QPath::Resolved(ty, path)) = ty.kind {
427+
let mut new_path = path.clone();
428+
429+
new_path.segments = self.arena.alloc_from_iter(
430+
new_path.segments.iter().enumerate().map(|(idx, segment)| {
431+
if idx + 1 == new_path.segments.len() {
432+
self.process_segment(span, segment, &mut generics.parent)
433+
} else {
434+
segment.clone()
435+
}
436+
}),
437+
);
438+
439+
self.arena.alloc(hir::Ty {
440+
hir_id: ty_hir_id,
441+
span,
442+
kind: hir::TyKind::Path(QPath::Resolved(ty, self.arena.alloc(new_path))),
443+
})
444+
} else {
445+
ty
446+
};
447+
448+
hir::QPath::TypeRelative(ty, self.arena.alloc(segment))
449+
}
420450
};
421451

422452
if let Some(hir::DelegationSelfTyPropagationKind::SelfTy(id)) =
@@ -491,6 +521,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
491521
result.generics.into_hir_generics(self, span);
492522

493523
let mut segment = segment.clone();
524+
494525
let mut args_iter = result.generics.create_args_iterator();
495526

496527
let new_args = segment

0 commit comments

Comments
 (0)