Skip to content

Commit 4c0f2d0

Browse files
oli-obkfee1-dead
authored andcommitted
Actually substitute constness params
1 parent 2b7ec4f commit 4c0f2d0

18 files changed

+141
-99
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1824,7 +1824,7 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable
18241824
// This is the impl for `&'a InternalSubsts<'a>`.
18251825
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
18261826

1827-
CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
1827+
CloneLiftImpls! { for<'tcx> { ty::ConstnessArg, Constness, traits::WellFormedLoc, } }
18281828

18291829
pub mod tls {
18301830
use super::{ptr_eq, GlobalCtxt, TyCtxt};

compiler/rustc_middle/src/ty/fold.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> {
131131
uv.super_fold_with(self)
132132
}
133133

134+
fn fold_constness(&mut self, c: ty::ConstnessArg) -> ty::ConstnessArg {
135+
c.super_fold_with(self)
136+
}
137+
134138
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
135139
p.super_fold_with(self)
136140
}
@@ -178,6 +182,10 @@ pub trait FallibleTypeFolder<'tcx>: Sized {
178182
c.try_super_fold_with(self)
179183
}
180184

185+
fn try_fold_constness(&mut self, c: ty::ConstnessArg) -> Result<ty::ConstnessArg, Self::Error> {
186+
c.try_super_fold_with(self)
187+
}
188+
181189
fn try_fold_predicate(
182190
&mut self,
183191
p: ty::Predicate<'tcx>,
@@ -224,6 +232,10 @@ where
224232
Ok(self.fold_const(c))
225233
}
226234

235+
fn try_fold_constness(&mut self, c: ty::ConstnessArg) -> Result<ty::ConstnessArg, !> {
236+
Ok(self.fold_constness(c))
237+
}
238+
227239
fn try_fold_unevaluated(
228240
&mut self,
229241
c: ty::Unevaluated<'tcx>,

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2519,6 +2519,13 @@ define_print_and_forward_display! {
25192519
}
25202520

25212521
TraitRefPrintOnlyTraitPath<'tcx> {
2522+
if cx.tcx().sess.verbose() {
2523+
match self.0.constness() {
2524+
ty::ConstnessArg::Not => {},
2525+
ty::ConstnessArg::Required => p!(write("const ")),
2526+
ty::ConstnessArg::Param => p!(write("~const ")),
2527+
}
2528+
}
25222529
p!(print_def_path(self.0.def_id, self.0.substs));
25232530
}
25242531

compiler/rustc_middle/src/ty/structural_impls.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ TrivialTypeTraversalAndLiftImpls! {
215215
crate::ty::adjustment::AutoBorrowMutability,
216216
crate::ty::AdtKind,
217217
crate::ty::BoundConstness,
218-
crate::ty::ConstnessArg,
219218
// Including `BoundRegionKind` is a *bit* dubious, but direct
220219
// references to bound region appear in `ty::Error`, and aren't
221220
// really meant to be folded. In general, we can only fold a fully
@@ -1107,6 +1106,33 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> {
11071106
}
11081107
}
11091108

1109+
impl<'tcx> TypeFoldable<'tcx> for ty::ConstnessArg {
1110+
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
1111+
folder.try_fold_constness(self)
1112+
}
1113+
}
1114+
1115+
impl<'tcx> TypeSuperFoldable<'tcx> for ty::ConstnessArg {
1116+
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1117+
self,
1118+
_folder: &mut F,
1119+
) -> Result<Self, F::Error> {
1120+
Ok(self)
1121+
}
1122+
}
1123+
1124+
impl<'tcx> TypeVisitable<'tcx> for ty::ConstnessArg {
1125+
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1126+
visitor.visit_constness_arg(*self)
1127+
}
1128+
}
1129+
1130+
impl<'tcx> TypeSuperVisitable<'tcx> for ty::ConstnessArg {
1131+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
1132+
ControlFlow::CONTINUE
1133+
}
1134+
}
1135+
11101136
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
11111137
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
11121138
folder.try_fold_predicate(self)

compiler/rustc_middle/src/ty/subst.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> {
227227
GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into),
228228
GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into),
229229
GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
230-
GenericArgKind::Constness(_) => Ok(self),
230+
GenericArgKind::Constness(cn) => cn.try_fold_with(folder).map(Into::into),
231231
}
232232
}
233233
}
@@ -238,7 +238,7 @@ impl<'tcx> TypeVisitable<'tcx> for GenericArg<'tcx> {
238238
GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
239239
GenericArgKind::Type(ty) => ty.visit_with(visitor),
240240
GenericArgKind::Const(ct) => ct.visit_with(visitor),
241-
GenericArgKind::Constness(_) => ControlFlow::CONTINUE,
241+
GenericArgKind::Constness(cn) => cn.visit_with(visitor),
242242
}
243243
}
244244
}
@@ -610,6 +610,20 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
610610
}
611611
}
612612

613+
fn fold_constness(&mut self, c: ty::ConstnessArg) -> ty::ConstnessArg {
614+
if let ty::ConstnessArg::Param = c {
615+
self.substs
616+
.iter()
617+
.find_map(|param| match param.unpack() {
618+
GenericArgKind::Constness(c) => Some(c),
619+
_ => None,
620+
})
621+
.unwrap_or(c)
622+
} else {
623+
c.super_fold_with(self)
624+
}
625+
}
626+
613627
#[inline]
614628
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
615629
c.super_fold_with(self)

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
713713
&self,
714714
trait_ref: &hir::TraitRef<'_>,
715715
self_ty: Ty<'tcx>,
716+
constness: hir::Constness,
716717
) -> ty::TraitRef<'tcx> {
717718
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
718719

@@ -722,6 +723,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
722723
self_ty,
723724
trait_ref.path.segments.last().unwrap(),
724725
true,
726+
match constness {
727+
hir::Constness::Const => ty::ConstnessArg::Param,
728+
hir::Constness::NotConst => ty::ConstnessArg::Not,
729+
},
725730
)
726731
}
727732

@@ -877,13 +882,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
877882
self_ty: Ty<'tcx>,
878883
trait_segment: &hir::PathSegment<'_>,
879884
is_impl: bool,
885+
constness: ty::ConstnessArg,
880886
) -> ty::TraitRef<'tcx> {
881887
let (substs, _) = self.create_substs_for_ast_trait_ref(
882888
span,
883889
trait_def_id,
884890
self_ty,
885891
trait_segment,
886892
is_impl,
893+
constness,
887894
);
888895
let assoc_bindings = self.create_assoc_bindings_for_generic_args(trait_segment.args());
889896
if let Some(b) = assoc_bindings.first() {
@@ -900,6 +907,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
900907
self_ty: Ty<'tcx>,
901908
trait_segment: &'a hir::PathSegment<'a>,
902909
is_impl: bool,
910+
constness: ty::ConstnessArg,
903911
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
904912
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
905913

@@ -911,7 +919,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
911919
trait_segment.args(),
912920
trait_segment.infer_args,
913921
Some(self_ty),
914-
Some(ty::ConstnessArg::Not),
922+
Some(constness),
915923
)
916924
}
917925

@@ -2122,8 +2130,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
21222130

21232131
debug!("qpath_to_ty: self_type={:?}", self_ty);
21242132

2125-
let trait_ref =
2126-
self.ast_path_to_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false);
2133+
let trait_ref = self.ast_path_to_mono_trait_ref(
2134+
span,
2135+
trait_def_id,
2136+
self_ty,
2137+
trait_segment,
2138+
false,
2139+
ty::ConstnessArg::Not,
2140+
);
21272141

21282142
let item_substs = self.create_substs_for_associated_item(
21292143
tcx,
@@ -2926,8 +2940,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
29262940
let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) =
29272941
hir.get(hir.get_parent_node(fn_hir_id)) else { bug!("ImplItem should have Impl parent") };
29282942

2929-
let trait_ref =
2930-
self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
2943+
let trait_ref = self.instantiate_mono_trait_ref(
2944+
i.of_trait.as_ref()?,
2945+
self.ast_ty_to_ty(i.self_ty),
2946+
hir::Constness::NotConst,
2947+
);
29312948

29322949
let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
29332950
tcx,

compiler/rustc_typeck/src/collect.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1990,7 +1990,12 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
19901990
match tcx.hir().expect_item(def_id.expect_local()).kind {
19911991
hir::ItemKind::Impl(ref impl_) => impl_.of_trait.as_ref().map(|ast_trait_ref| {
19921992
let selfty = tcx.type_of(def_id);
1993-
<dyn AstConv<'_>>::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1993+
<dyn AstConv<'_>>::instantiate_mono_trait_ref(
1994+
&icx,
1995+
ast_trait_ref,
1996+
selfty,
1997+
impl_.constness,
1998+
)
19941999
}),
19952000
_ => bug!(),
19962001
}

src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![feature(const_trait_impl)]
22

3+
#[const_trait]
34
pub trait Plus {
45
fn plus(self, rhs: Self) -> Self;
56
}
@@ -22,8 +23,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
2223

2324
pub const fn add_u32(a: u32, b: u32) -> u32 {
2425
a.plus(b)
25-
//~^ ERROR the trait bound
26-
//~| ERROR cannot call non-const fn
26+
//~^ ERROR no method named `plus` found for type `u32` in the current scope
2727
}
2828

2929
fn main() {}
Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
1-
error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
2-
--> $DIR/call-const-trait-method-fail.rs:24:7
1+
error[E0599]: no method named `plus` found for type `u32` in the current scope
2+
--> $DIR/call-const-trait-method-fail.rs:25:7
33
|
44
LL | a.plus(b)
5-
| ^^^^^^^ the trait `~const Plus` is not implemented for `u32`
5+
| ^^^^ method not found in `u32`
66
|
7-
note: the trait `Plus` is implemented for `u32`, but that implementation is not `const`
8-
--> $DIR/call-const-trait-method-fail.rs:24:7
7+
= help: items from traits can only be used if the trait is implemented and in scope
8+
note: `Plus` defines an item `plus`, perhaps you need to implement it
9+
--> $DIR/call-const-trait-method-fail.rs:4:1
910
|
10-
LL | a.plus(b)
11-
| ^^^^^^^
12-
13-
error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
14-
--> $DIR/call-const-trait-method-fail.rs:24:7
15-
|
16-
LL | a.plus(b)
17-
| ^^^^^^^
18-
|
19-
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
11+
LL | pub trait Plus {
12+
| ^^^^^^^^^^^^^^
2013

2114
error: aborting due to 2 previous errors
2215

23-
Some errors have detailed explanations: E0015, E0277.
24-
For more information about an error, try `rustc --explain E0015`.
16+
For more information about this error, try `rustc --explain E0599`.

src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
44
*t == *t
5-
//~^ ERROR can't compare
6-
//~| ERROR cannot call non-const
5+
//~^ ERROR cannot call non-const
76
}
87

98
fn main() {}

0 commit comments

Comments
 (0)