Skip to content

Commit ba1d7f4

Browse files
committedJun 29, 2024
Auto merge of rust-lang#120639 - fee1-dead-contrib:new-effects-desugaring, r=oli-obk
Implement new effects desugaring cc `@rust-lang/project-const-traits.` Will write down notes once I have finished. * [x] See if we want `T: Tr` to desugar into `T: Tr, T::Effects: Compat<true>` * [x] Fix ICEs on `type Assoc: ~const Tr` and `type Assoc<T: ~const Tr>` * [ ] add types and traits to minicore test * [ ] update rustc-dev-guide Fixes rust-lang#119717 Fixes rust-lang#123664 Fixes rust-lang#124857 Fixes rust-lang#126148
2 parents d1b7355 + 65a0bee commit ba1d7f4

File tree

175 files changed

+2225
-1567
lines changed

Some content is hidden

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

175 files changed

+2225
-1567
lines changed
 

‎compiler/rustc_ast_lowering/src/expr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
103103
ParamMode::Optional,
104104
ParenthesizedGenericArgs::Err,
105105
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
106-
None,
107106
// Method calls can't have bound modifiers
108107
None,
109108
));

‎compiler/rustc_ast_lowering/src/item.rs

+74-37
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
5656
owner: NodeId,
5757
f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>,
5858
) {
59-
let mut lctx = LoweringContext::new(self.tcx, self.resolver);
59+
let mut lctx = LoweringContext::new(self.tcx, self.resolver, self.ast_index);
6060
lctx.with_hir_id_owner(owner, |lctx| f(lctx));
6161

6262
for (def_id, info) in lctx.children {
@@ -190,6 +190,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
190190
let (generics, (ty, body_id)) = self.lower_generics(
191191
generics,
192192
Const::No,
193+
false,
193194
id,
194195
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
195196
|this| {
@@ -221,7 +222,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
221222

222223
let itctx = ImplTraitContext::Universal;
223224
let (generics, decl) =
224-
this.lower_generics(generics, header.constness, id, itctx, |this| {
225+
this.lower_generics(generics, header.constness, false, id, itctx, |this| {
225226
this.lower_fn_decl(
226227
decl,
227228
id,
@@ -265,6 +266,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
265266
let (generics, ty) = self.lower_generics(
266267
&generics,
267268
Const::No,
269+
false,
268270
id,
269271
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
270272
|this| match ty {
@@ -293,6 +295,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
293295
let (generics, variants) = self.lower_generics(
294296
generics,
295297
Const::No,
298+
false,
296299
id,
297300
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
298301
|this| {
@@ -307,6 +310,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
307310
let (generics, struct_def) = self.lower_generics(
308311
generics,
309312
Const::No,
313+
false,
310314
id,
311315
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
312316
|this| this.lower_variant_data(hir_id, struct_def),
@@ -317,6 +321,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
317321
let (generics, vdata) = self.lower_generics(
318322
generics,
319323
Const::No,
324+
false,
320325
id,
321326
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
322327
|this| this.lower_variant_data(hir_id, vdata),
@@ -348,12 +353,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
348353
// parent lifetime.
349354
let itctx = ImplTraitContext::Universal;
350355
let (generics, (trait_ref, lowered_ty)) =
351-
self.lower_generics(ast_generics, *constness, id, itctx, |this| {
356+
self.lower_generics(ast_generics, Const::No, false, id, itctx, |this| {
352357
let modifiers = TraitBoundModifiers {
353-
constness: match *constness {
354-
Const::Yes(span) => BoundConstness::Maybe(span),
355-
Const::No => BoundConstness::Never,
356-
},
358+
constness: BoundConstness::Never,
357359
asyncness: BoundAsyncness::Normal,
358360
// we don't use this in bound lowering
359361
polarity: BoundPolarity::Positive,
@@ -389,6 +391,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
389391
ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)),
390392
};
391393
hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
394+
constness: self.lower_constness(*constness),
392395
safety: self.lower_safety(*safety, hir::Safety::Safe),
393396
polarity,
394397
defaultness,
@@ -400,15 +403,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
400403
}))
401404
}
402405
ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => {
403-
// FIXME(const_trait_impl, effects, fee1-dead) this should be simplified if possible
404-
let constness = attrs
405-
.unwrap_or(&[])
406-
.iter()
407-
.find(|x| x.has_name(sym::const_trait))
408-
.map_or(Const::No, |x| Const::Yes(x.span));
409406
let (generics, (safety, items, bounds)) = self.lower_generics(
410407
generics,
411-
constness,
408+
Const::No,
409+
false,
412410
id,
413411
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
414412
|this| {
@@ -429,6 +427,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
429427
let (generics, bounds) = self.lower_generics(
430428
generics,
431429
Const::No,
430+
false,
432431
id,
433432
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
434433
|this| {
@@ -609,30 +608,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
609608
// This is used to track which lifetimes have already been defined,
610609
// and which need to be replicated when lowering an async fn.
611610

612-
let generics = match parent_hir.node().expect_item().kind {
611+
let parent_item = parent_hir.node().expect_item();
612+
let constness = match parent_item.kind {
613613
hir::ItemKind::Impl(impl_) => {
614614
self.is_in_trait_impl = impl_.of_trait.is_some();
615-
&impl_.generics
615+
// N.B. the impl should always lower to methods that have `const host: bool` params if the trait
616+
// is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from
617+
// calling non-const impls are done through associated types.
618+
if let Some(def_id) = impl_.of_trait.and_then(|tr| tr.trait_def_id()) {
619+
if let Some(local_def) = def_id.as_local() {
620+
match &self.ast_index[local_def] {
621+
AstOwner::Item(ast::Item { attrs, .. }) => attrs
622+
.iter()
623+
.find(|attr| attr.has_name(sym::const_trait))
624+
.map_or(Const::No, |attr| Const::Yes(attr.span)),
625+
_ => Const::No,
626+
}
627+
} else {
628+
self.tcx
629+
.get_attr(def_id, sym::const_trait)
630+
.map_or(Const::No, |attr| Const::Yes(attr.span))
631+
}
632+
} else {
633+
Const::No
634+
}
616635
}
617-
hir::ItemKind::Trait(_, _, generics, _, _) => generics,
636+
hir::ItemKind::Trait(_, _, _, _, _) => parent_hir
637+
.attrs
638+
.get(parent_item.hir_id().local_id)
639+
.iter()
640+
.find(|attr| attr.has_name(sym::const_trait))
641+
.map_or(Const::No, |attr| Const::Yes(attr.span)),
618642
kind => {
619643
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
620644
}
621645
};
622646

623-
if self.tcx.features().effects {
624-
self.host_param_id = generics
625-
.params
626-
.iter()
627-
.find(|param| {
628-
matches!(param.kind, hir::GenericParamKind::Const { is_host_effect: true, .. })
629-
})
630-
.map(|param| param.def_id);
631-
}
632-
633647
match ctxt {
634-
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
635-
AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)),
648+
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item, constness)),
649+
AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item, constness)),
636650
}
637651
}
638652

@@ -648,7 +662,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
648662
let fdec = &sig.decl;
649663
let itctx = ImplTraitContext::Universal;
650664
let (generics, (fn_dec, fn_args)) =
651-
self.lower_generics(generics, Const::No, i.id, itctx, |this| {
665+
self.lower_generics(generics, Const::No, false, i.id, itctx, |this| {
652666
(
653667
// Disallow `impl Trait` in foreign items.
654668
this.lower_fn_decl(
@@ -765,7 +779,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
765779
}
766780
}
767781

768-
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
782+
fn lower_trait_item(
783+
&mut self,
784+
i: &AssocItem,
785+
trait_constness: Const,
786+
) -> &'hir hir::TraitItem<'hir> {
769787
let hir_id = self.lower_node_id(i.id);
770788
self.lower_attrs(hir_id, &i.attrs);
771789
let trait_item_def_id = hir_id.expect_owner();
@@ -775,6 +793,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
775793
let (generics, kind) = self.lower_generics(
776794
generics,
777795
Const::No,
796+
false,
778797
i.id,
779798
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
780799
|this| {
@@ -795,6 +814,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
795814
i.id,
796815
FnDeclKind::Trait,
797816
sig.header.coroutine_kind,
817+
trait_constness,
798818
);
799819
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
800820
}
@@ -813,6 +833,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
813833
i.id,
814834
FnDeclKind::Trait,
815835
sig.header.coroutine_kind,
836+
trait_constness,
816837
);
817838
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
818839
}
@@ -822,6 +843,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
822843
let (generics, kind) = self.lower_generics(
823844
&generics,
824845
Const::No,
846+
false,
825847
i.id,
826848
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
827849
|this| {
@@ -894,7 +916,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
894916
self.expr(span, hir::ExprKind::Err(guar))
895917
}
896918

897-
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
919+
fn lower_impl_item(
920+
&mut self,
921+
i: &AssocItem,
922+
constness_of_trait: Const,
923+
) -> &'hir hir::ImplItem<'hir> {
898924
// Since `default impl` is not yet implemented, this is always true in impls.
899925
let has_value = true;
900926
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
@@ -905,6 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
905931
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
906932
generics,
907933
Const::No,
934+
false,
908935
i.id,
909936
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
910937
|this| {
@@ -930,6 +957,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
930957
i.id,
931958
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
932959
sig.header.coroutine_kind,
960+
constness_of_trait,
933961
);
934962

935963
(generics, hir::ImplItemKind::Fn(sig, body_id))
@@ -940,6 +968,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
940968
self.lower_generics(
941969
&generics,
942970
Const::No,
971+
false,
943972
i.id,
944973
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
945974
|this| match ty {
@@ -1352,15 +1381,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
13521381
id: NodeId,
13531382
kind: FnDeclKind,
13541383
coroutine_kind: Option<CoroutineKind>,
1384+
parent_constness: Const,
13551385
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
13561386
let header = self.lower_fn_header(sig.header);
13571387
// Don't pass along the user-provided constness of trait associated functions; we don't want to
13581388
// synthesize a host effect param for them. We reject `const` on them during AST validation.
1359-
let constness = if kind == FnDeclKind::Inherent { sig.header.constness } else { Const::No };
1389+
let constness =
1390+
if kind == FnDeclKind::Inherent { sig.header.constness } else { parent_constness };
13601391
let itctx = ImplTraitContext::Universal;
1361-
let (generics, decl) = self.lower_generics(generics, constness, id, itctx, |this| {
1362-
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
1363-
});
1392+
let (generics, decl) =
1393+
self.lower_generics(generics, constness, kind == FnDeclKind::Impl, id, itctx, |this| {
1394+
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
1395+
});
13641396
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
13651397
}
13661398

@@ -1436,6 +1468,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14361468
&mut self,
14371469
generics: &Generics,
14381470
constness: Const,
1471+
force_append_constness: bool,
14391472
parent_node_id: NodeId,
14401473
itctx: ImplTraitContext,
14411474
f: impl FnOnce(&mut Self) -> T,
@@ -1496,7 +1529,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
14961529
// if the effects feature is enabled. This needs to be done before we lower where
14971530
// clauses since where clauses need to bind to the DefId of the host param
14981531
let host_param_parts = if let Const::Yes(span) = constness
1499-
&& self.tcx.features().effects
1532+
// if this comes from implementing a `const` trait, we must force constness to be appended
1533+
// to the impl item, no matter whether effects is enabled.
1534+
&& (self.tcx.features().effects || force_append_constness)
15001535
{
15011536
let span = self.lower_span(span);
15021537
let param_node_id = self.next_node_id();
@@ -1609,13 +1644,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
16091644
}),
16101645
)),
16111646
)),
1647+
// FIXME(effects) we might not need a default.
16121648
default: Some(self.arena.alloc(hir::AnonConst {
16131649
def_id: anon_const,
16141650
hir_id: const_id,
16151651
body: const_body,
16161652
span,
16171653
})),
16181654
is_host_effect: true,
1655+
synthetic: true,
16191656
},
16201657
colon_span: None,
16211658
pure_wrt_drop: false,

0 commit comments

Comments
 (0)