Skip to content

Commit 6faaf91

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 d322a54 commit 6faaf91

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
@@ -122,8 +122,8 @@ fn collect_sizedness_bounds<'tcx>(
122122
(CollectedSizednessBounds { sized, metasized, pointeesized }, unbounds)
123123
}
124124

125-
/// Add a trait bound for `did`.
126-
fn add_trait_bound<'tcx>(
125+
/// Add a trait predicate for `did`.
126+
fn add_trait_predicate<'tcx>(
127127
tcx: TyCtxt<'tcx>,
128128
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
129129
self_ty: Ty<'tcx>,
@@ -136,6 +136,23 @@ fn add_trait_bound<'tcx>(
136136
bounds.insert(0, (trait_ref.upcast(tcx), span));
137137
}
138138

139+
/// Add a host effect predicate for `did`.
140+
fn add_host_effect_predicate<'tcx>(
141+
tcx: TyCtxt<'tcx>,
142+
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
143+
self_ty: Ty<'tcx>,
144+
did: DefId,
145+
span: Span,
146+
) {
147+
let trait_ref = ty::TraitRef::new(tcx, did, [self_ty]);
148+
let clause = ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
149+
trait_ref,
150+
constness: ty::BoundConstness::Const,
151+
})
152+
.upcast(tcx);
153+
bounds.insert(1, (clause, span));
154+
}
155+
139156
/// Remove any bounds of `did`.
140157
fn remove_lang_item_bound<'tcx>(bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, did: DefId) {
141158
let mut idx = None;
@@ -171,8 +188,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
171188
remove_lang_item_bound(bounds, pointeesized_did);
172189
}
173190

174-
/// Adds a `MetaSized` bound to `bounds` (of a trait definition) if there are no other sizedness
175-
/// bounds. Also removes `PointeeSized` params - see doc comment on
191+
/// Adds a `const MetaSized` bound to `bounds` (of a trait definition) if there are no other
192+
/// sizedness bounds. Also removes `PointeeSized` params - see doc comment on
176193
/// `adjust_sizedness_predicates`.
177194
pub(crate) fn adjust_sizedness_supertraits(
178195
&self,
@@ -195,16 +212,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
195212

196213
let (collected, _unbounds) = collect_sizedness_bounds(tcx, hir_bounds, None, span);
197214
if !collected.any() && trait_did != pointeesized_did {
198-
// If there are no explicit sizedness bounds then add a default `MetaSized` supertrait.
199-
add_trait_bound(tcx, bounds, self_ty, metasized_did, span);
215+
// If there are no explicit sizedness bounds then add a default `const MetaSized`
216+
// supertrait.
217+
add_trait_predicate(tcx, bounds, self_ty, metasized_did, span);
218+
add_host_effect_predicate(tcx, bounds, self_ty, metasized_did, span);
200219
}
201220

202221
// See doc comment on `adjust_sizedness_predicates`.
203222
remove_lang_item_bound(bounds, pointeesized_did);
204223
}
205224

206-
/// Add a default `Sized` bound if there are no other sizedness bounds and rewrite `?Sized`
207-
/// to `MetaSized`. Also removes `PointeeSized` params - see doc comment on
225+
/// Add a default `const Sized` bound if there are no other sizedness bounds and rewrite
226+
/// `?Sized` to `MetaSized`. Also removes `PointeeSized` params - see doc comment on
208227
/// `adjust_sizedness_predicates`.
209228
pub(crate) fn adjust_sizedness_params_and_assoc_types(
210229
&self,
@@ -229,12 +248,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
229248
&& !collected.metasized.any()
230249
&& !collected.pointeesized.any()
231250
{
232-
// `?Sized` is equivalent to `MetaSized` (but only add the bound if there aren't any
233-
// other explicit ones)
234-
add_trait_bound(tcx, bounds, self_ty, metasized_did, span);
251+
// `?Sized` is equivalent to `const MetaSized` (but only add the bound if there aren't
252+
// any other explicit ones)
253+
add_trait_predicate(tcx, bounds, self_ty, metasized_did, span);
254+
add_host_effect_predicate(tcx, bounds, self_ty, metasized_did, span);
235255
} else if !collected.any() {
236-
// If there are no explicit sizedness bounds then add a default `Sized` bound.
237-
add_trait_bound(tcx, bounds, self_ty, sized_did, span);
256+
// If there are no explicit sizedness bounds then add a default `const Sized` bound.
257+
add_trait_predicate(tcx, bounds, self_ty, sized_did, span);
258+
add_host_effect_predicate(tcx, bounds, self_ty, sized_did, span);
238259
}
239260

240261
// 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)