trait_sel: skip elaboration of sizedness supertrait
As a performance optimization, skip elaborating the supertraits of `Sized`, and if a `MetaSized` obligation is being checked, then look for a `Sized` predicate in the parameter environment. This makes the `ParamEnv` smaller which should improve compiler performance as it avoids all the iteration over the larger `ParamEnv`.
This commit is contained in:
parent
47abf2e144
commit
607eb322a8
16 changed files with 268 additions and 40 deletions
|
|
@ -6,7 +6,7 @@ use rustc_type_ir::inherent::*;
|
|||
use rustc_type_ir::lang_items::TraitSolverLangItem;
|
||||
use rustc_type_ir::solve::{CanonicalResponse, SizedTraitKind};
|
||||
use rustc_type_ir::{
|
||||
self as ty, Interner, Movability, TraitPredicate, TypeVisitableExt as _, TypingMode,
|
||||
self as ty, Interner, Movability, TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode,
|
||||
Upcast as _, elaborate,
|
||||
};
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
|
@ -131,9 +131,11 @@ where
|
|||
assumption: I::Clause,
|
||||
) -> Result<(), NoSolution> {
|
||||
if let Some(trait_clause) = assumption.as_trait_clause() {
|
||||
if trait_clause.def_id() == goal.predicate.def_id()
|
||||
&& trait_clause.polarity() == goal.predicate.polarity
|
||||
{
|
||||
if trait_clause.polarity() != goal.predicate.polarity {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
if trait_clause.def_id() == goal.predicate.def_id() {
|
||||
if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
|
||||
goal.predicate.trait_ref.args,
|
||||
trait_clause.skip_binder().trait_ref.args,
|
||||
|
|
@ -141,6 +143,17 @@ where
|
|||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
// PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
|
||||
// check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
|
||||
// are syntactic sugar for a lack of bounds so don't need this.
|
||||
if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized)
|
||||
&& ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized)
|
||||
{
|
||||
let meta_sized_clause =
|
||||
trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id());
|
||||
return Self::fast_reject_assumption(ecx, goal, meta_sized_clause);
|
||||
}
|
||||
}
|
||||
|
||||
Err(NoSolution)
|
||||
|
|
@ -154,6 +167,17 @@ where
|
|||
) -> QueryResult<I> {
|
||||
let trait_clause = assumption.as_trait_clause().unwrap();
|
||||
|
||||
// PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
|
||||
// check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
|
||||
// are syntactic sugar for a lack of bounds so don't need this.
|
||||
if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized)
|
||||
&& ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized)
|
||||
{
|
||||
let meta_sized_clause =
|
||||
trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id());
|
||||
return Self::match_assumption(ecx, goal, meta_sized_clause, then);
|
||||
}
|
||||
|
||||
let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
|
||||
ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
|
||||
|
||||
|
|
@ -817,6 +841,25 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Small helper function to change the `def_id` of a trait predicate - this is not normally
|
||||
/// something that you want to do, as different traits will require different args and so making
|
||||
/// it easy to change the trait is something of a footgun, but it is useful in the narrow
|
||||
/// circumstance of changing from `MetaSized` to `Sized`, which happens as part of the lazy
|
||||
/// elaboration of sizedness candidates.
|
||||
#[inline(always)]
|
||||
fn trait_predicate_with_def_id<I: Interner>(
|
||||
cx: I,
|
||||
clause: ty::Binder<I, ty::TraitPredicate<I>>,
|
||||
did: I::DefId,
|
||||
) -> I::Clause {
|
||||
clause
|
||||
.map_bound(|c| TraitPredicate {
|
||||
trait_ref: TraitRef::new_from_args(cx, did, c.trait_ref.args),
|
||||
polarity: c.polarity,
|
||||
})
|
||||
.upcast(cx)
|
||||
}
|
||||
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
D: SolverDelegate<Interner = I>,
|
||||
|
|
|
|||
|
|
@ -462,6 +462,7 @@ fn impl_intersection_has_negative_obligation(
|
|||
let param_env = infcx.resolve_vars_if_possible(param_env);
|
||||
|
||||
util::elaborate(tcx, tcx.predicates_of(impl2_def_id).instantiate(tcx, impl2_header.impl_args))
|
||||
.elaborate_sized()
|
||||
.any(|(clause, _)| try_prove_negated_where_clause(infcx, clause, param_env))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,6 +215,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
selcx.infcx.probe(|_| {
|
||||
let bound = util::lazily_elaborate_sizedness_candidate(
|
||||
selcx.infcx,
|
||||
obligation,
|
||||
bound,
|
||||
);
|
||||
|
||||
// We checked the polarity already
|
||||
match selcx.match_normalize_trait_ref(
|
||||
obligation,
|
||||
|
|
@ -259,14 +265,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
.caller_bounds()
|
||||
.iter()
|
||||
.filter_map(|p| p.as_trait_clause())
|
||||
// Micro-optimization: filter out predicates relating to different traits.
|
||||
.filter(|p| p.def_id() == stack.obligation.predicate.def_id())
|
||||
// Micro-optimization: filter out predicates with different polarities.
|
||||
.filter(|p| p.polarity() == stack.obligation.predicate.polarity());
|
||||
|
||||
let drcx = DeepRejectCtxt::relate_rigid_rigid(self.tcx());
|
||||
let obligation_args = stack.obligation.predicate.skip_binder().trait_ref.args;
|
||||
// Keep only those bounds which may apply, and propagate overflow if it occurs.
|
||||
for bound in bounds {
|
||||
let bound =
|
||||
util::lazily_elaborate_sizedness_candidate(self.infcx, stack.obligation, bound);
|
||||
|
||||
// Micro-optimization: filter out predicates relating to different traits.
|
||||
if bound.def_id() != stack.obligation.predicate.def_id() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let bound_trait_ref = bound.map_bound(|t| t.trait_ref);
|
||||
if !drcx.args_may_unify(obligation_args, bound_trait_ref.skip_binder().args) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -166,10 +166,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
)
|
||||
.break_value()
|
||||
.expect("expected to index into clause that exists");
|
||||
let candidate = candidate_predicate
|
||||
let candidate_predicate = candidate_predicate
|
||||
.as_trait_clause()
|
||||
.expect("projection candidate is not a trait predicate")
|
||||
.map_bound(|t| t.trait_ref);
|
||||
.expect("projection candidate is not a trait predicate");
|
||||
let candidate_predicate =
|
||||
util::lazily_elaborate_sizedness_candidate(self.infcx, obligation, candidate_predicate);
|
||||
|
||||
let candidate = candidate_predicate.map_bound(|t| t.trait_ref);
|
||||
|
||||
let candidate = self.infcx.instantiate_binder_with_fresh_vars(
|
||||
obligation.cause.span,
|
||||
|
|
@ -226,6 +229,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
) -> PredicateObligations<'tcx> {
|
||||
debug!(?obligation, ?param, "confirm_param_candidate");
|
||||
|
||||
let param = util::lazily_elaborate_sizedness_candidate(
|
||||
self.infcx,
|
||||
obligation,
|
||||
param.upcast(self.infcx.tcx),
|
||||
)
|
||||
.map_bound(|p| p.trait_ref);
|
||||
|
||||
// During evaluation, we already checked that this
|
||||
// where-clause trait-ref could be unified with the obligation
|
||||
// trait-ref. Repeat that unification now without any
|
||||
|
|
|
|||
|
|
@ -4,10 +4,13 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
|||
use rustc_hir::LangItem;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_infer::traits::PolyTraitObligation;
|
||||
pub use rustc_infer::traits::util::*;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::{
|
||||
self, SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||
self, PolyTraitPredicate, SizedTraitKind, TraitPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
|
||||
TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||
};
|
||||
pub use rustc_next_trait_solver::placeholder::BoundVarReplacer;
|
||||
use rustc_span::Span;
|
||||
|
|
@ -382,3 +385,39 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
|||
|
||||
false
|
||||
}
|
||||
|
||||
/// To improve performance, sizedness traits are not elaborated and so special-casing is required
|
||||
/// in the trait solver to find a `Sized` candidate for a `MetaSized` obligation. Returns the
|
||||
/// predicate to used in the candidate for such a `obligation`, given a `candidate`.
|
||||
pub(crate) fn lazily_elaborate_sizedness_candidate<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
obligation: &PolyTraitObligation<'tcx>,
|
||||
candidate: PolyTraitPredicate<'tcx>,
|
||||
) -> PolyTraitPredicate<'tcx> {
|
||||
if !infcx.tcx.is_lang_item(obligation.predicate.def_id(), LangItem::MetaSized)
|
||||
|| !infcx.tcx.is_lang_item(candidate.def_id(), LangItem::Sized)
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
|
||||
if obligation.predicate.polarity() != candidate.polarity() {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
let drcx = DeepRejectCtxt::relate_rigid_rigid(infcx.tcx);
|
||||
if !drcx.args_may_unify(
|
||||
obligation.predicate.skip_binder().trait_ref.args,
|
||||
candidate.skip_binder().trait_ref.args,
|
||||
) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
candidate.map_bound(|c| TraitPredicate {
|
||||
trait_ref: TraitRef::new_from_args(
|
||||
infcx.tcx,
|
||||
obligation.predicate.def_id(),
|
||||
c.trait_ref.args,
|
||||
),
|
||||
polarity: c.polarity,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use smallvec::smallvec;
|
|||
|
||||
use crate::data_structures::HashSet;
|
||||
use crate::inherent::*;
|
||||
use crate::lang_items::TraitSolverLangItem;
|
||||
use crate::outlives::{Component, push_outlives_components};
|
||||
use crate::{self as ty, Interner, Upcast as _};
|
||||
|
||||
|
|
@ -18,6 +19,7 @@ pub struct Elaborator<I: Interner, O> {
|
|||
stack: Vec<O>,
|
||||
visited: HashSet<ty::Binder<I, ty::PredicateKind<I>>>,
|
||||
mode: Filter,
|
||||
elaborate_sized: ElaborateSized,
|
||||
}
|
||||
|
||||
enum Filter {
|
||||
|
|
@ -25,6 +27,12 @@ enum Filter {
|
|||
OnlySelf,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
enum ElaborateSized {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
/// Describes how to elaborate an obligation into a sub-obligation.
|
||||
pub trait Elaboratable<I: Interner> {
|
||||
fn predicate(&self) -> I::Predicate;
|
||||
|
|
@ -77,13 +85,19 @@ pub fn elaborate<I: Interner, O: Elaboratable<I>>(
|
|||
cx: I,
|
||||
obligations: impl IntoIterator<Item = O>,
|
||||
) -> Elaborator<I, O> {
|
||||
let mut elaborator =
|
||||
Elaborator { cx, stack: Vec::new(), visited: HashSet::default(), mode: Filter::All };
|
||||
let mut elaborator = Elaborator {
|
||||
cx,
|
||||
stack: Vec::new(),
|
||||
visited: HashSet::default(),
|
||||
mode: Filter::All,
|
||||
elaborate_sized: ElaborateSized::No,
|
||||
};
|
||||
elaborator.extend_deduped(obligations);
|
||||
elaborator
|
||||
}
|
||||
|
||||
impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
|
||||
/// Adds `obligations` to the stack.
|
||||
fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = O>) {
|
||||
// Only keep those bounds that we haven't already seen.
|
||||
// This is necessary to prevent infinite recursion in some
|
||||
|
|
@ -103,6 +117,13 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Start elaborating `Sized` - reqd during coherence checking, normally skipped to improve
|
||||
/// compiler performance.
|
||||
pub fn elaborate_sized(mut self) -> Self {
|
||||
self.elaborate_sized = ElaborateSized::Yes;
|
||||
self
|
||||
}
|
||||
|
||||
fn elaborate(&mut self, elaboratable: &O) {
|
||||
let cx = self.cx;
|
||||
|
||||
|
|
@ -111,6 +132,19 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
|
|||
return;
|
||||
};
|
||||
|
||||
// PERF(sized-hierarchy): To avoid iterating over sizedness supertraits in
|
||||
// parameter environments, as an optimisation, sizedness supertraits aren't
|
||||
// elaborated, so check if a `Sized` obligation is being elaborated to a
|
||||
// `MetaSized` obligation and emit it. Candidate assembly and confirmation
|
||||
// are modified to check for the `Sized` subtrait when a `MetaSized` obligation
|
||||
// is present.
|
||||
if self.elaborate_sized == ElaborateSized::No
|
||||
&& let Some(did) = clause.as_trait_clause().map(|c| c.def_id())
|
||||
&& self.cx.is_lang_item(did, TraitSolverLangItem::Sized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let bound_clause = clause.kind();
|
||||
match bound_clause.skip_binder() {
|
||||
ty::ClauseKind::Trait(data) => {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()>
|
|||
= note: Binder { value: ProjectionPredicate(AliasTerm { args: [Alias(Projection, AliasTy { args: [Self/#0, T/#1, P/#2], def_id: DefId(..), .. })], def_id: DefId(..), .. }, Term::Ty(())), bound_vars: [] }
|
||||
= note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::ops::Deref>, polarity:Positive), bound_vars: [] }
|
||||
= note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, polarity:Positive), bound_vars: [] }
|
||||
= note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::MetaSized>, polarity:Positive), bound_vars: [] }
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
2
tests/ui/extern/extern-types-unsized.rs
vendored
2
tests/ui/extern/extern-types-unsized.rs
vendored
|
|
@ -27,7 +27,9 @@ fn main() {
|
|||
|
||||
assert_sized::<Bar<A>>();
|
||||
//~^ ERROR the size for values of type
|
||||
//~| ERROR the size for values of type
|
||||
|
||||
assert_sized::<Bar<Bar<A>>>();
|
||||
//~^ ERROR the size for values of type
|
||||
//~| ERROR the size for values of type
|
||||
}
|
||||
|
|
|
|||
30
tests/ui/extern/extern-types-unsized.stderr
vendored
30
tests/ui/extern/extern-types-unsized.stderr
vendored
|
|
@ -59,8 +59,21 @@ help: consider relaxing the implicit `Sized` restriction
|
|||
LL | fn assert_sized<T: ?Sized>() {}
|
||||
| ++++++++
|
||||
|
||||
error[E0277]: the size for values of type `A` cannot be known
|
||||
--> $DIR/extern-types-unsized.rs:28:20
|
||||
|
|
||||
LL | assert_sized::<Bar<A>>();
|
||||
| ^^^^^^ doesn't have a known size
|
||||
|
|
||||
= help: the trait `MetaSized` is not implemented for `A`
|
||||
note: required by a bound in `Bar`
|
||||
--> $DIR/extern-types-unsized.rs:14:12
|
||||
|
|
||||
LL | struct Bar<T: ?Sized> {
|
||||
| ^ required by this bound in `Bar`
|
||||
|
||||
error[E0277]: the size for values of type `A` cannot be known at compilation time
|
||||
--> $DIR/extern-types-unsized.rs:31:20
|
||||
--> $DIR/extern-types-unsized.rs:32:20
|
||||
|
|
||||
LL | assert_sized::<Bar<Bar<A>>>();
|
||||
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -81,6 +94,19 @@ help: consider relaxing the implicit `Sized` restriction
|
|||
LL | fn assert_sized<T: ?Sized>() {}
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error[E0277]: the size for values of type `A` cannot be known
|
||||
--> $DIR/extern-types-unsized.rs:32:20
|
||||
|
|
||||
LL | assert_sized::<Bar<Bar<A>>>();
|
||||
| ^^^^^^^^^^^ doesn't have a known size
|
||||
|
|
||||
= help: the trait `MetaSized` is not implemented for `A`
|
||||
note: required by a bound in `Bar`
|
||||
--> $DIR/extern-types-unsized.rs:14:12
|
||||
|
|
||||
LL | struct Bar<T: ?Sized> {
|
||||
| ^ required by this bound in `Bar`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ trait A {
|
|||
type X: ?Sized;
|
||||
}
|
||||
|
||||
fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) //~ ERROR mismatched types
|
||||
fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) //~ ERROR
|
||||
where
|
||||
for<'b> &'b T: A,
|
||||
<&'static T as A>::X: Sized
|
||||
|
|
|
|||
18
tests/ui/sized-hierarchy/elaboration-opt-regions-1.rs
Normal file
18
tests/ui/sized-hierarchy/elaboration-opt-regions-1.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//@ check-pass
|
||||
//@ compile-flags: --crate-type=lib
|
||||
//@ revisions: old next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
#![feature(sized_hierarchy)]
|
||||
|
||||
use std::marker::{PhantomData, MetaSized, PointeeSized};
|
||||
|
||||
struct Foo<'a, T: PointeeSized>(*mut &'a (), T);
|
||||
|
||||
fn requires_metasized<'a, T: MetaSized>(f: &'a T) {}
|
||||
|
||||
fn foo<'a, T: PointeeSized>(f: &Foo<'a, T>)
|
||||
where
|
||||
Foo<'a, T>: Sized
|
||||
{
|
||||
requires_metasized(f);
|
||||
}
|
||||
18
tests/ui/sized-hierarchy/elaboration-opt-regions.rs
Normal file
18
tests/ui/sized-hierarchy/elaboration-opt-regions.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//@ check-pass
|
||||
//@ compile-flags: --crate-type=lib
|
||||
//@ revisions: old next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
#![feature(sized_hierarchy)]
|
||||
|
||||
use std::marker::{PhantomData, MetaSized, PointeeSized};
|
||||
|
||||
struct Foo<'a, T: PointeeSized>(PhantomData<&'a T>, T);
|
||||
|
||||
fn requires_metasized<T: MetaSized>() {}
|
||||
|
||||
fn foo<'a, T: 'a + PointeeSized>()
|
||||
where
|
||||
Foo<'a, T>: Sized
|
||||
{
|
||||
requires_metasized::<Foo<'_, T>>();
|
||||
}
|
||||
|
|
@ -207,6 +207,7 @@ fn main() {
|
|||
//~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time
|
||||
needs_metasized::<(Foo, Foo)>();
|
||||
//~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time
|
||||
//~| ERROR the size for values of type `main::Foo` cannot be known
|
||||
needs_pointeesized::<(Foo, Foo)>();
|
||||
//~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:239:42
|
||||
--> $DIR/impls.rs:240:42
|
||||
|
|
||||
LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] }
|
||||
| ^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -17,7 +17,7 @@ LL | struct StructAllFieldsMetaSized { x: Box<[u8]>, y: [u8] }
|
|||
| ++++ +
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:247:40
|
||||
--> $DIR/impls.rs:248:40
|
||||
|
|
||||
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -35,7 +35,7 @@ LL | struct StructAllFieldsUnsized { x: Box<Foo>, y: Foo }
|
|||
| ++++ +
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:283:44
|
||||
--> $DIR/impls.rs:284:44
|
||||
|
|
||||
LL | enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } }
|
||||
| ^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -53,7 +53,7 @@ LL | enum EnumAllFieldsMetaSized { Qux { x: Box<[u8]>, y: [u8] } }
|
|||
| ++++ +
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:290:42
|
||||
--> $DIR/impls.rs:291:42
|
||||
|
|
||||
LL | enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } }
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -71,7 +71,7 @@ LL | enum EnumAllFieldsUnsized { Qux { x: Box<Foo>, y: Foo } }
|
|||
| ++++ +
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:297:52
|
||||
--> $DIR/impls.rs:298:52
|
||||
|
|
||||
LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } }
|
||||
| ^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -89,7 +89,7 @@ LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: Box<[u8]> } }
|
|||
| ++++ +
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:304:50
|
||||
--> $DIR/impls.rs:305:50
|
||||
|
|
||||
LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } }
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -216,8 +216,22 @@ LL | needs_metasized::<(Foo, Foo)>();
|
|||
= help: the trait `Sized` is not implemented for `main::Foo`
|
||||
= note: only the last element of a tuple may have a dynamically sized type
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known
|
||||
--> $DIR/impls.rs:208:23
|
||||
|
|
||||
LL | needs_metasized::<(Foo, Foo)>();
|
||||
| ^^^^^^^^^^ doesn't have a known size
|
||||
|
|
||||
= help: within `(main::Foo, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo`
|
||||
= note: required because it appears within the type `(main::Foo, main::Foo)`
|
||||
note: required by a bound in `needs_metasized`
|
||||
--> $DIR/impls.rs:16:23
|
||||
|
|
||||
LL | fn needs_metasized<T: MetaSized>() { }
|
||||
| ^^^^^^^^^ required by this bound in `needs_metasized`
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:210:26
|
||||
--> $DIR/impls.rs:211:26
|
||||
|
|
||||
LL | needs_pointeesized::<(Foo, Foo)>();
|
||||
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -226,7 +240,7 @@ LL | needs_pointeesized::<(Foo, Foo)>();
|
|||
= note: only the last element of a tuple may have a dynamically sized type
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:214:19
|
||||
--> $DIR/impls.rs:215:19
|
||||
|
|
||||
LL | needs_sized::<(u32, [u8])>();
|
||||
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -240,7 +254,7 @@ LL | fn needs_sized<T: Sized>() { }
|
|||
| ^^^^^ required by this bound in `needs_sized`
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:220:19
|
||||
--> $DIR/impls.rs:221:19
|
||||
|
|
||||
LL | needs_sized::<(u32, Foo)>();
|
||||
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -254,7 +268,7 @@ LL | fn needs_sized<T: Sized>() { }
|
|||
| ^^^^^ required by this bound in `needs_sized`
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known
|
||||
--> $DIR/impls.rs:222:23
|
||||
--> $DIR/impls.rs:223:23
|
||||
|
|
||||
LL | needs_metasized::<(u32, Foo)>();
|
||||
| ^^^^^^^^^^ doesn't have a known size
|
||||
|
|
@ -268,14 +282,14 @@ LL | fn needs_metasized<T: MetaSized>() { }
|
|||
| ^^^^^^^^^ required by this bound in `needs_metasized`
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:241:19
|
||||
--> $DIR/impls.rs:242:19
|
||||
|
|
||||
LL | needs_sized::<StructAllFieldsMetaSized>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `StructAllFieldsMetaSized`, the trait `Sized` is not implemented for `[u8]`
|
||||
note: required because it appears within the type `StructAllFieldsMetaSized`
|
||||
--> $DIR/impls.rs:239:12
|
||||
--> $DIR/impls.rs:240:12
|
||||
|
|
||||
LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -286,14 +300,14 @@ LL | fn needs_sized<T: Sized>() { }
|
|||
| ^^^^^ required by this bound in `needs_sized`
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:249:19
|
||||
--> $DIR/impls.rs:250:19
|
||||
|
|
||||
LL | needs_sized::<StructAllFieldsUnsized>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `StructAllFieldsUnsized`, the trait `Sized` is not implemented for `main::Foo`
|
||||
note: required because it appears within the type `StructAllFieldsUnsized`
|
||||
--> $DIR/impls.rs:247:12
|
||||
--> $DIR/impls.rs:248:12
|
||||
|
|
||||
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -304,14 +318,14 @@ LL | fn needs_sized<T: Sized>() { }
|
|||
| ^^^^^ required by this bound in `needs_sized`
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known
|
||||
--> $DIR/impls.rs:251:23
|
||||
--> $DIR/impls.rs:252:23
|
||||
|
|
||||
LL | needs_metasized::<StructAllFieldsUnsized>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
|
||||
|
|
||||
= help: within `StructAllFieldsUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
|
||||
note: required because it appears within the type `StructAllFieldsUnsized`
|
||||
--> $DIR/impls.rs:247:12
|
||||
--> $DIR/impls.rs:248:12
|
||||
|
|
||||
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -322,14 +336,14 @@ LL | fn needs_metasized<T: MetaSized>() { }
|
|||
| ^^^^^^^^^ required by this bound in `needs_metasized`
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:257:19
|
||||
--> $DIR/impls.rs:258:19
|
||||
|
|
||||
LL | needs_sized::<StructLastFieldMetaSized>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `StructLastFieldMetaSized`, the trait `Sized` is not implemented for `[u8]`
|
||||
note: required because it appears within the type `StructLastFieldMetaSized`
|
||||
--> $DIR/impls.rs:256:12
|
||||
--> $DIR/impls.rs:257:12
|
||||
|
|
||||
LL | struct StructLastFieldMetaSized { x: u32, y: [u8] }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -340,14 +354,14 @@ LL | fn needs_sized<T: Sized>() { }
|
|||
| ^^^^^ required by this bound in `needs_sized`
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
|
||||
--> $DIR/impls.rs:264:19
|
||||
--> $DIR/impls.rs:265:19
|
||||
|
|
||||
LL | needs_sized::<StructLastFieldUnsized>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `StructLastFieldUnsized`, the trait `Sized` is not implemented for `main::Foo`
|
||||
note: required because it appears within the type `StructLastFieldUnsized`
|
||||
--> $DIR/impls.rs:263:12
|
||||
--> $DIR/impls.rs:264:12
|
||||
|
|
||||
LL | struct StructLastFieldUnsized { x: u32, y: Foo }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -358,14 +372,14 @@ LL | fn needs_sized<T: Sized>() { }
|
|||
| ^^^^^ required by this bound in `needs_sized`
|
||||
|
||||
error[E0277]: the size for values of type `main::Foo` cannot be known
|
||||
--> $DIR/impls.rs:266:23
|
||||
--> $DIR/impls.rs:267:23
|
||||
|
|
||||
LL | needs_metasized::<StructLastFieldUnsized>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
|
||||
|
|
||||
= help: within `StructLastFieldUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
|
||||
note: required because it appears within the type `StructLastFieldUnsized`
|
||||
--> $DIR/impls.rs:263:12
|
||||
--> $DIR/impls.rs:264:12
|
||||
|
|
||||
LL | struct StructLastFieldUnsized { x: u32, y: Foo }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -375,6 +389,6 @@ note: required by a bound in `needs_metasized`
|
|||
LL | fn needs_metasized<T: MetaSized>() { }
|
||||
| ^^^^^^^^^ required by this bound in `needs_metasized`
|
||||
|
||||
error: aborting due to 26 previous errors
|
||||
error: aborting due to 27 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ pub fn pointeesized() -> Box<impl Tr + PointeeSized> {
|
|||
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
|
||||
let y: Box<dyn Tr> = x;
|
||||
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
|
||||
//~| ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
|
||||
}
|
||||
Box::new(1u32)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,15 @@ LL | let y: Box<dyn Tr> = x;
|
|||
= help: the trait `Sized` is not implemented for `impl Tr + PointeeSized`
|
||||
= note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known
|
||||
--> $DIR/pretty-print-opaque.rs:40:30
|
||||
|
|
||||
LL | let y: Box<dyn Tr> = x;
|
||||
| ^ doesn't have a known size
|
||||
|
|
||||
= help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
|
||||
= note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue