Skip to content

Commit 206f1f6

Browse files
committed
hir_analysis: change {Meta,}Sized bounds to const
With const sizedness traits, the correct migration is from `Sized` to `const Sized` and from `?Sized` to `const MetaSized`.
1 parent a918e27 commit 206f1f6

File tree

6 files changed

+53
-36
lines changed

6 files changed

+53
-36
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ fn collect_sizedness_bounds<'tcx>(
113113
(CollectedSizednessBounds { sized, meta_sized, pointee_sized }, unbounds)
114114
}
115115

116-
/// Add a trait bound for `did`.
117-
fn add_trait_bound<'tcx>(
116+
/// Add a trait predicate for `did`.
117+
fn add_trait_predicate<'tcx>(
118118
tcx: TyCtxt<'tcx>,
119119
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
120120
self_ty: Ty<'tcx>,
@@ -127,6 +127,23 @@ fn add_trait_bound<'tcx>(
127127
bounds.insert(0, (trait_ref.upcast(tcx), span));
128128
}
129129

130+
/// Add a host effect predicate for `did`.
131+
fn add_host_effect_predicate<'tcx>(
132+
tcx: TyCtxt<'tcx>,
133+
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
134+
self_ty: Ty<'tcx>,
135+
did: DefId,
136+
span: Span,
137+
) {
138+
let trait_ref = ty::TraitRef::new(tcx, did, [self_ty]);
139+
let clause = ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
140+
trait_ref,
141+
constness: ty::BoundConstness::Const,
142+
})
143+
.upcast(tcx);
144+
bounds.insert(1, (clause, span));
145+
}
146+
130147
/// Remove any bounds of `did`.
131148
fn remove_lang_item_bound<'tcx>(bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, did: DefId) {
132149
bounds.retain(|(clause, _)| {
@@ -153,8 +170,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
153170
remove_lang_item_bound(bounds, pointee_sized_did);
154171
}
155172

156-
/// Adds a `MetaSized` bound to `bounds` (of a trait definition) if there are no other sizedness
157-
/// bounds. Also removes `PointeeSized` params - see doc comment on
173+
/// Adds a `const MetaSized` bound to `bounds` (of a trait definition) if there are no other
174+
/// sizedness bounds. Also removes `PointeeSized` params - see doc comment on
158175
/// `adjust_sizedness_predicates`.
159176
pub(crate) fn adjust_sizedness_supertraits(
160177
&self,
@@ -177,16 +194,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
177194

178195
let (collected, _unbounds) = collect_sizedness_bounds(tcx, hir_bounds, None, span);
179196
if !collected.any() && trait_did != pointee_sized_did {
180-
// If there are no explicit sizedness bounds then add a default `MetaSized` supertrait.
181-
add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span);
197+
// If there are no explicit sizedness bounds then add a default `const MetaSized`
198+
// supertrait.
199+
add_trait_predicate(tcx, bounds, self_ty, meta_sized_did, span);
200+
add_host_effect_predicate(tcx, bounds, self_ty, meta_sized_did, span);
182201
}
183202

184203
// See doc comment on `adjust_sizedness_predicates`.
185204
remove_lang_item_bound(bounds, pointee_sized_did);
186205
}
187206

188-
/// Add a default `Sized` bound if there are no other sizedness bounds and rewrite `?Sized`
189-
/// to `MetaSized`. Also removes `PointeeSized` params - see doc comment on
207+
/// Add a default `const Sized` bound if there are no other sizedness bounds and rewrite
208+
/// `?Sized` to `MetaSized`. Also removes `PointeeSized` params - see doc comment on
190209
/// `adjust_sizedness_predicates`.
191210
pub(crate) fn adjust_sizedness_params_and_assoc_types(
192211
&self,
@@ -211,12 +230,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
211230
&& !collected.meta_sized.any()
212231
&& !collected.pointee_sized.any()
213232
{
214-
// `?Sized` is equivalent to `MetaSized` (but only add the bound if there aren't any
215-
// other explicit ones)
216-
add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span);
233+
// `?Sized` is equivalent to `const MetaSized` (but only add the bound if there aren't
234+
// any other explicit ones)
235+
add_trait_predicate(tcx, bounds, self_ty, meta_sized_did, span);
236+
add_host_effect_predicate(tcx, bounds, self_ty, meta_sized_did, span);
217237
} else if !collected.any() {
218-
// If there are no explicit sizedness bounds then add a default `Sized` bound.
219-
add_trait_bound(tcx, bounds, self_ty, sized_did, span);
238+
// If there are no explicit sizedness bounds then add a default `const Sized` bound.
239+
add_trait_predicate(tcx, bounds, self_ty, sized_did, span);
240+
add_host_effect_predicate(tcx, bounds, self_ty, sized_did, span);
220241
}
221242

222243
// See doc comment on `adjust_sizedness_predicates`.

tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ fn take(
1212
K = { () }
1313
>,
1414
) {}
15-
//~^^^^^^ ERROR implementation of `Project` is not general enough
16-
//~^^^^ ERROR higher-ranked subtype error
15+
//~^^^ ERROR higher-ranked subtype error
1716
//~| ERROR higher-ranked subtype error
1817

1918
trait Project { type Out; }

tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,5 @@ LL | K = { () }
1212
|
1313
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
1414

15-
error: implementation of `Project` is not general enough
16-
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:9:4
17-
|
18-
LL | fn take(
19-
| ^^^^ implementation of `Project` is not general enough
20-
|
21-
= note: `Project` would have to be implemented for the type `for<'a> fn(&'a str) -> &'a str`
22-
= note: ...but `Project` is actually implemented for the type `fn(&'0 str) -> &'0 str`, for some specific lifetime `'0`
23-
24-
error: aborting due to 3 previous errors
15+
error: aborting due to 2 previous errors
2516

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ check-pass
2+
//@ compile-flags: --crate-type=lib
3+
#![feature(const_trait_impl)]
4+
5+
// This test can fail because of the implicit const bounds/supertraits.
6+
7+
pub struct Bar;
8+
9+
#[const_trait]
10+
pub trait Foo {}
11+
12+
impl const Foo for Bar {}
13+
14+
pub const fn bar<T: ~const Foo>() {}

tests/ui/where-clauses/ignore-err-clauses.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::ops::Add;
22

33
fn dbl<T>(x: T) -> <T as Add>::Output
4-
//~^ ERROR type annotations needed
54
where
65
T: Copy + Add,
76
UUU: Copy,
Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
error[E0412]: cannot find type `UUU` in this scope
2-
--> $DIR/ignore-err-clauses.rs:7:5
2+
--> $DIR/ignore-err-clauses.rs:6:5
33
|
44
LL | UUU: Copy,
55
| ^^^ not found in this scope
66

7-
error[E0282]: type annotations needed
8-
--> $DIR/ignore-err-clauses.rs:3:14
9-
|
10-
LL | fn dbl<T>(x: T) -> <T as Add>::Output
11-
| ^ cannot infer type for type parameter `T`
12-
13-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
148

15-
Some errors have detailed explanations: E0282, E0412.
16-
For more information about an error, try `rustc --explain E0282`.
9+
For more information about this error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)