Skip to content

Commit c5d6267

Browse files
committed
Auto merge of rust-lang#120639 - fee1-dead-contrib:new-effects-desugaring, r=<try>
[WIP] experiment with a new way of effects desugaring cc `@rust-lang/project-const-traits.` Will write down notes once I have finished. * [ ] See if we want `T: Tr` to desugar into `T: Tr, T::Effects: Compat<true>` * [ ] Fix ICEs on `type Assoc: ~const Tr` and `type Assoc<T: ~const Tr>` * [ ] add types and traits to minicore test * [ ] update rustc-dev-guide
2 parents 0250ef2 + f1cd746 commit c5d6267

File tree

41 files changed

+531
-208
lines changed

Some content is hidden

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

41 files changed

+531
-208
lines changed

compiler/rustc_ast_lowering/src/expr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
100100
ParamMode::Optional,
101101
ParenthesizedGenericArgs::Err,
102102
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
103-
None,
104103
// Method calls can't have bound modifiers
105104
None,
106105
));

compiler/rustc_ast_lowering/src/item.rs

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

6060
for (def_id, info) in lctx.children {
@@ -188,6 +188,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
188188
let (generics, (ty, body_id)) = self.lower_generics(
189189
generics,
190190
Const::No,
191+
false,
191192
id,
192193
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
193194
|this| {
@@ -218,7 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
218219

219220
let itctx = ImplTraitContext::Universal;
220221
let (generics, decl) =
221-
this.lower_generics(generics, header.constness, id, itctx, |this| {
222+
this.lower_generics(generics, header.constness, false, id, itctx, |this| {
222223
this.lower_fn_decl(
223224
decl,
224225
id,
@@ -262,6 +263,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
262263
let (generics, ty) = self.lower_generics(
263264
&generics,
264265
Const::No,
266+
false,
265267
id,
266268
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
267269
|this| match ty {
@@ -284,6 +286,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
284286
let (generics, variants) = self.lower_generics(
285287
generics,
286288
Const::No,
289+
false,
287290
id,
288291
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
289292
|this| {
@@ -298,6 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
298301
let (generics, struct_def) = self.lower_generics(
299302
generics,
300303
Const::No,
304+
false,
301305
id,
302306
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
303307
|this| this.lower_variant_data(hir_id, struct_def),
@@ -308,6 +312,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
308312
let (generics, vdata) = self.lower_generics(
309313
generics,
310314
Const::No,
315+
false,
311316
id,
312317
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
313318
|this| this.lower_variant_data(hir_id, vdata),
@@ -339,12 +344,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
339344
// parent lifetime.
340345
let itctx = ImplTraitContext::Universal;
341346
let (generics, (trait_ref, lowered_ty)) =
342-
self.lower_generics(ast_generics, *constness, id, itctx, |this| {
347+
self.lower_generics(ast_generics, Const::No, false, id, itctx, |this| {
343348
let modifiers = TraitBoundModifiers {
344-
constness: match *constness {
345-
Const::Yes(span) => BoundConstness::Maybe(span),
346-
Const::No => BoundConstness::Never,
347-
},
349+
constness: BoundConstness::Never,
348350
asyncness: BoundAsyncness::Normal,
349351
// we don't use this in bound lowering
350352
polarity: BoundPolarity::Positive,
@@ -379,6 +381,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
379381
ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)),
380382
};
381383
hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
384+
constness: self.lower_constness(*constness),
382385
unsafety: self.lower_unsafety(*unsafety),
383386
polarity,
384387
defaultness,
@@ -390,15 +393,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
390393
}))
391394
}
392395
ItemKind::Trait(box Trait { is_auto, unsafety, generics, bounds, items }) => {
393-
// FIXME(const_trait_impl, effects, fee1-dead) this should be simplified if possible
394-
let constness = attrs
395-
.unwrap_or(&[])
396-
.iter()
397-
.find(|x| x.has_name(sym::const_trait))
398-
.map_or(Const::No, |x| Const::Yes(x.span));
399396
let (generics, (unsafety, items, bounds)) = self.lower_generics(
400397
generics,
401-
constness,
398+
Const::No,
399+
false,
402400
id,
403401
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
404402
|this| {
@@ -419,6 +417,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
419417
let (generics, bounds) = self.lower_generics(
420418
generics,
421419
Const::No,
420+
false,
422421
id,
423422
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
424423
|this| {
@@ -599,30 +598,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
599598
// This is used to track which lifetimes have already been defined,
600599
// and which need to be replicated when lowering an async fn.
601600

602-
let generics = match parent_hir.node().expect_item().kind {
601+
let parent_item = parent_hir.node().expect_item();
602+
let constness = match parent_item.kind {
603603
hir::ItemKind::Impl(impl_) => {
604604
self.is_in_trait_impl = impl_.of_trait.is_some();
605-
&impl_.generics
605+
// N.B. the impl should always lower to methods that have `const host: bool` params if the trait
606+
// is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from
607+
// calling non-const impls are done through associated types.
608+
if let Some(def_id) = impl_.of_trait.and_then(|tr| tr.trait_def_id()) {
609+
if let Some(local_def) = def_id.as_local() {
610+
match &self.ast_index[local_def] {
611+
AstOwner::Item(ast::Item { attrs, .. }) => attrs
612+
.iter()
613+
.find(|attr| attr.has_name(sym::const_trait))
614+
.map_or(Const::No, |attr| Const::Yes(attr.span)),
615+
_ => Const::No,
616+
}
617+
} else {
618+
self.tcx
619+
.get_attr(def_id, sym::const_trait)
620+
.map_or(Const::No, |attr| Const::Yes(attr.span))
621+
}
622+
} else {
623+
Const::No
624+
}
606625
}
607-
hir::ItemKind::Trait(_, _, generics, _, _) => generics,
626+
hir::ItemKind::Trait(_, _, _, _, _) => parent_hir
627+
.attrs
628+
.get(parent_item.hir_id().local_id)
629+
.iter()
630+
.find(|attr| attr.has_name(sym::const_trait))
631+
.map_or(Const::No, |attr| Const::Yes(attr.span)),
608632
kind => {
609633
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
610634
}
611635
};
612636

613-
if self.tcx.features().effects {
614-
self.host_param_id = generics
615-
.params
616-
.iter()
617-
.find(|param| {
618-
matches!(param.kind, hir::GenericParamKind::Const { is_host_effect: true, .. })
619-
})
620-
.map(|param| param.def_id);
621-
}
622-
623637
match ctxt {
624-
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
625-
AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)),
638+
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item, constness)),
639+
AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item, constness)),
626640
}
627641
}
628642

@@ -638,7 +652,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
638652
let fdec = &sig.decl;
639653
let itctx = ImplTraitContext::Universal;
640654
let (generics, (fn_dec, fn_args)) =
641-
self.lower_generics(generics, Const::No, i.id, itctx, |this| {
655+
self.lower_generics(generics, Const::No, false, i.id, itctx, |this| {
642656
(
643657
// Disallow `impl Trait` in foreign items.
644658
this.lower_fn_decl(
@@ -752,7 +766,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
752766
}
753767
}
754768

755-
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
769+
fn lower_trait_item(
770+
&mut self,
771+
i: &AssocItem,
772+
trait_constness: Const,
773+
) -> &'hir hir::TraitItem<'hir> {
756774
let hir_id = self.lower_node_id(i.id);
757775
self.lower_attrs(hir_id, &i.attrs);
758776
let trait_item_def_id = hir_id.expect_owner();
@@ -762,6 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
762780
let (generics, kind) = self.lower_generics(
763781
generics,
764782
Const::No,
783+
false,
765784
i.id,
766785
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
767786
|this| {
@@ -782,6 +801,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
782801
i.id,
783802
FnDeclKind::Trait,
784803
sig.header.coroutine_kind,
804+
trait_constness,
785805
);
786806
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
787807
}
@@ -799,6 +819,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
799819
i.id,
800820
FnDeclKind::Trait,
801821
sig.header.coroutine_kind,
822+
trait_constness,
802823
);
803824
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
804825
}
@@ -808,6 +829,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
808829
let (generics, kind) = self.lower_generics(
809830
&generics,
810831
Const::No,
832+
false,
811833
i.id,
812834
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
813835
|this| {
@@ -876,7 +898,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
876898
self.expr(span, hir::ExprKind::Err(guar))
877899
}
878900

879-
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
901+
fn lower_impl_item(
902+
&mut self,
903+
i: &AssocItem,
904+
constness_of_trait: Const,
905+
) -> &'hir hir::ImplItem<'hir> {
880906
// Since `default impl` is not yet implemented, this is always true in impls.
881907
let has_value = true;
882908
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
@@ -887,6 +913,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
887913
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
888914
generics,
889915
Const::No,
916+
false,
890917
i.id,
891918
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
892919
|this| {
@@ -911,6 +938,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911938
i.id,
912939
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
913940
sig.header.coroutine_kind,
941+
constness_of_trait,
914942
);
915943

916944
(generics, hir::ImplItemKind::Fn(sig, body_id))
@@ -921,6 +949,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
921949
self.lower_generics(
922950
&generics,
923951
Const::No,
952+
false,
924953
i.id,
925954
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
926955
|this| match ty {
@@ -1323,15 +1352,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
13231352
id: NodeId,
13241353
kind: FnDeclKind,
13251354
coroutine_kind: Option<CoroutineKind>,
1355+
parent_constness: Const,
13261356
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
13271357
let header = self.lower_fn_header(sig.header);
13281358
// Don't pass along the user-provided constness of trait associated functions; we don't want to
13291359
// synthesize a host effect param for them. We reject `const` on them during AST validation.
1330-
let constness = if kind == FnDeclKind::Inherent { sig.header.constness } else { Const::No };
1360+
let constness =
1361+
if kind == FnDeclKind::Inherent { sig.header.constness } else { parent_constness };
13311362
let itctx = ImplTraitContext::Universal;
1332-
let (generics, decl) = self.lower_generics(generics, constness, id, itctx, |this| {
1333-
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
1334-
});
1363+
let (generics, decl) =
1364+
self.lower_generics(generics, constness, kind == FnDeclKind::Impl, id, itctx, |this| {
1365+
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
1366+
});
13351367
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
13361368
}
13371369

@@ -1406,6 +1438,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14061438
&mut self,
14071439
generics: &Generics,
14081440
constness: Const,
1441+
force_append_constness: bool,
14091442
parent_node_id: NodeId,
14101443
itctx: ImplTraitContext,
14111444
f: impl FnOnce(&mut Self) -> T,
@@ -1466,7 +1499,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
14661499
// if the effects feature is enabled. This needs to be done before we lower where
14671500
// clauses since where clauses need to bind to the DefId of the host param
14681501
let host_param_parts = if let Const::Yes(span) = constness
1469-
&& self.tcx.features().effects
1502+
// if this comes from implementing a `const` trait, we must force constness to be appended
1503+
// to the impl item, no matter whether effects is enabled.
1504+
&& (self.tcx.features().effects || force_append_constness)
14701505
{
14711506
let span = self.lower_span(span);
14721507
let param_node_id = self.next_node_id();
@@ -1579,12 +1614,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
15791614
}),
15801615
)),
15811616
)),
1617+
// FIXME(effects) we might not need a default.
15821618
default: Some(hir::AnonConst {
15831619
def_id: anon_const,
15841620
hir_id: const_id,
15851621
body: const_body,
15861622
}),
15871623
is_host_effect: true,
1624+
synthetic: true,
15881625
},
15891626
colon_span: None,
15901627
pure_wrt_drop: false,

0 commit comments

Comments
 (0)