Rollup merge of #93810 - matthewjasper:chalk-and-canonical-universes, r=jackh726
Improve chalk integration - Support subtype bounds in chalk lowering - Handle universes in canonicalization - Handle type parameters in chalk responses - Use `chalk_ir::LifetimeData::Empty` for `ty::ReEmpty` - Remove `ignore-compare-mode-chalk` for tests that no longer hang (they may still fail or ICE) This is enough to get a hello world program to compile with `-Zchalk` now. Some of the remaining issues that are needed to get Chalk integration working on larger programs are: - rust-lang/chalk#234 - rust-lang/chalk#548 - rust-lang/chalk#734 - Generators are handled differently in chalk and rustc r? `@jackh726`
This commit is contained in:
commit
aff74a1697
51 changed files with 362 additions and 219 deletions
compiler
rustc_infer/src/infer/canonical
rustc_middle/src/infer
rustc_trait_selection/src/traits
rustc_traits/src/chalk
src/test/ui
associated-type-bounds
associated-types
associated-types-stream.rshr-associated-type-bound-param-2.rshr-associated-type-bound-param-2.stderrhr-associated-type-bound-param-5.rshr-associated-type-bound-param-5.stderrissue-50301.rs
chalkify
consts/const-eval
deriving
impl-trait
issues
issue-23122-1.rsissue-23122-2.rsissue-23122-2.stderrissue-28561.rsissue-33187.rsissue-37051.rsissue-55796.nll.stderrissue-55796.rsissue-55796.stderrissue-74564-if-expr-stack-overflow.rs
nll/ty-outlives
specialization
default-associated-type-bound-1.rsdefault-associated-type-bound-1.stderrdefault-associated-type-bound-2.rsdefault-associated-type-bound-2.stderrdefault-generic-associated-type-bound.rsdefault-generic-associated-type-bound.stderr
type-alias-impl-trait
|
@ -49,6 +49,31 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
|||
Canonicalizer::canonicalize(value, self, self.tcx, &CanonicalizeAllFreeRegions, query_state)
|
||||
}
|
||||
|
||||
/// Like [Self::canonicalize_query], but preserves distinct universes. For
|
||||
/// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and
|
||||
/// `'?1` is in `U3` would be canonicalized to have ?0` in `U1` and `'?1`
|
||||
/// in `U2`.
|
||||
///
|
||||
/// This is used for Chalk integration.
|
||||
pub fn canonicalize_query_preserving_universes<V>(
|
||||
&self,
|
||||
value: V,
|
||||
query_state: &mut OriginalQueryValues<'tcx>,
|
||||
) -> Canonicalized<'tcx, V>
|
||||
where
|
||||
V: TypeFoldable<'tcx>,
|
||||
{
|
||||
self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
Canonicalizer::canonicalize(
|
||||
value,
|
||||
self,
|
||||
self.tcx,
|
||||
&CanonicalizeAllFreeRegionsPreservingUniverses,
|
||||
query_state,
|
||||
)
|
||||
}
|
||||
|
||||
/// Canonicalizes a query *response* `V`. When we canonicalize a
|
||||
/// query response, we only canonicalize unbound inference
|
||||
/// variables, and we leave other free regions alone. So,
|
||||
|
@ -133,7 +158,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
|||
/// maximally general query. But if we are canonicalizing a *query
|
||||
/// response*, then we don't typically replace free regions, as they
|
||||
/// must have been introduced from other parts of the system.
|
||||
trait CanonicalizeRegionMode {
|
||||
trait CanonicalizeMode {
|
||||
fn canonicalize_free_region<'tcx>(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
|
||||
|
@ -141,11 +166,14 @@ trait CanonicalizeRegionMode {
|
|||
) -> ty::Region<'tcx>;
|
||||
|
||||
fn any(&self) -> bool;
|
||||
|
||||
// Do we preserve universe of variables.
|
||||
fn preserve_universes(&self) -> bool;
|
||||
}
|
||||
|
||||
struct CanonicalizeQueryResponse;
|
||||
|
||||
impl CanonicalizeRegionMode for CanonicalizeQueryResponse {
|
||||
impl CanonicalizeMode for CanonicalizeQueryResponse {
|
||||
fn canonicalize_free_region<'tcx>(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
|
||||
|
@ -198,11 +226,15 @@ impl CanonicalizeRegionMode for CanonicalizeQueryResponse {
|
|||
fn any(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn preserve_universes(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
struct CanonicalizeUserTypeAnnotation;
|
||||
|
||||
impl CanonicalizeRegionMode for CanonicalizeUserTypeAnnotation {
|
||||
impl CanonicalizeMode for CanonicalizeUserTypeAnnotation {
|
||||
fn canonicalize_free_region<'tcx>(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
|
||||
|
@ -221,11 +253,15 @@ impl CanonicalizeRegionMode for CanonicalizeUserTypeAnnotation {
|
|||
fn any(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn preserve_universes(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct CanonicalizeAllFreeRegions;
|
||||
|
||||
impl CanonicalizeRegionMode for CanonicalizeAllFreeRegions {
|
||||
impl CanonicalizeMode for CanonicalizeAllFreeRegions {
|
||||
fn canonicalize_free_region<'tcx>(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
|
||||
|
@ -237,11 +273,39 @@ impl CanonicalizeRegionMode for CanonicalizeAllFreeRegions {
|
|||
fn any(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn preserve_universes(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct CanonicalizeAllFreeRegionsPreservingUniverses;
|
||||
|
||||
impl CanonicalizeMode for CanonicalizeAllFreeRegionsPreservingUniverses {
|
||||
fn canonicalize_free_region<'tcx>(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
let universe = canonicalizer.infcx.universe_of_region(r);
|
||||
canonicalizer.canonical_var_for_region(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) },
|
||||
r,
|
||||
)
|
||||
}
|
||||
|
||||
fn any(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn preserve_universes(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
struct CanonicalizeFreeRegionsOtherThanStatic;
|
||||
|
||||
impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic {
|
||||
impl CanonicalizeMode for CanonicalizeFreeRegionsOtherThanStatic {
|
||||
fn canonicalize_free_region<'tcx>(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
|
||||
|
@ -257,6 +321,10 @@ impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic {
|
|||
fn any(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn preserve_universes(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct Canonicalizer<'cx, 'tcx> {
|
||||
|
@ -267,7 +335,7 @@ struct Canonicalizer<'cx, 'tcx> {
|
|||
// Note that indices is only used once `var_values` is big enough to be
|
||||
// heap-allocated.
|
||||
indices: FxHashMap<GenericArg<'tcx>, BoundVar>,
|
||||
canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode,
|
||||
canonicalize_mode: &'cx dyn CanonicalizeMode,
|
||||
needs_canonical_flags: TypeFlags,
|
||||
|
||||
binder_index: ty::DebruijnIndex,
|
||||
|
@ -311,7 +379,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
|||
vid, r
|
||||
);
|
||||
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
|
||||
self.canonicalize_region_mode.canonicalize_free_region(self, r)
|
||||
self.canonicalize_mode.canonicalize_free_region(self, r)
|
||||
}
|
||||
|
||||
ty::ReStatic
|
||||
|
@ -319,7 +387,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
|||
| ty::ReFree(_)
|
||||
| ty::ReEmpty(_)
|
||||
| ty::RePlaceholder(..)
|
||||
| ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r),
|
||||
| ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,8 +405,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
|||
// `TyVar(vid)` is unresolved, track its universe index in the canonicalized
|
||||
// result.
|
||||
Err(mut ui) => {
|
||||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
if !self.canonicalize_mode.preserve_universes() {
|
||||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
}
|
||||
self.canonicalize_ty_var(
|
||||
CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||
|
@ -422,8 +492,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
|||
// `ConstVar(vid)` is unresolved, track its universe index in the
|
||||
// canonicalized result
|
||||
Err(mut ui) => {
|
||||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
if !self.canonicalize_mode.preserve_universes() {
|
||||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
}
|
||||
return self.canonicalize_const_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty) },
|
||||
ct,
|
||||
|
@ -462,7 +534,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
value: V,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
canonicalize_region_mode: &dyn CanonicalizeRegionMode,
|
||||
canonicalize_region_mode: &dyn CanonicalizeMode,
|
||||
query_state: &mut OriginalQueryValues<'tcx>,
|
||||
) -> Canonicalized<'tcx, V>
|
||||
where
|
||||
|
@ -493,7 +565,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
let mut canonicalizer = Canonicalizer {
|
||||
infcx,
|
||||
tcx,
|
||||
canonicalize_region_mode,
|
||||
canonicalize_mode: canonicalize_region_mode,
|
||||
needs_canonical_flags,
|
||||
variables: SmallVec::new(),
|
||||
query_state,
|
||||
|
@ -504,10 +576,11 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
|
||||
// Once we have canonicalized `out_value`, it should not
|
||||
// contain anything that ties it to this inference context
|
||||
// anymore, so it should live in the global arena.
|
||||
debug_assert!(!out_value.needs_infer());
|
||||
// anymore.
|
||||
debug_assert!(!out_value.needs_infer() && !out_value.has_placeholders());
|
||||
|
||||
let canonical_variables = tcx.intern_canonical_var_infos(&canonicalizer.variables);
|
||||
let canonical_variables =
|
||||
tcx.intern_canonical_var_infos(&canonicalizer.universe_canonicalized_variables());
|
||||
|
||||
let max_universe = canonical_variables
|
||||
.iter()
|
||||
|
@ -527,6 +600,19 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
|
||||
let var_values = &mut query_state.var_values;
|
||||
|
||||
let universe = info.universe();
|
||||
if universe != ty::UniverseIndex::ROOT {
|
||||
assert!(self.canonicalize_mode.preserve_universes());
|
||||
|
||||
// Insert universe into the universe map. To preserve the order of the
|
||||
// universes in the value being canonicalized, we don't update the
|
||||
// universe in `info` until we have finished canonicalizing.
|
||||
match query_state.universe_map.binary_search(&universe) {
|
||||
Err(idx) => query_state.universe_map.insert(idx, universe),
|
||||
Ok(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
// This code is hot. `variables` and `var_values` are usually small
|
||||
// (fewer than 8 elements ~95% of the time). They are SmallVec's to
|
||||
// avoid allocations in those cases. We also don't use `indices` to
|
||||
|
@ -569,6 +655,61 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Replaces the universe indexes used in `var_values` with their index in
|
||||
/// `query_state.universe_map`. This minimizes the maximum universe used in
|
||||
/// the canonicalized value.
|
||||
fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarInfo<'tcx>; 8]> {
|
||||
if self.query_state.universe_map.len() == 1 {
|
||||
return self.variables;
|
||||
}
|
||||
|
||||
let reverse_universe_map: FxHashMap<ty::UniverseIndex, ty::UniverseIndex> = self
|
||||
.query_state
|
||||
.universe_map
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, universe)| (*universe, ty::UniverseIndex::from_usize(idx)))
|
||||
.collect();
|
||||
|
||||
self.variables
|
||||
.iter()
|
||||
.map(|v| CanonicalVarInfo {
|
||||
kind: match v.kind {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
|
||||
return *v;
|
||||
}
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(reverse_universe_map[&u]))
|
||||
}
|
||||
CanonicalVarKind::Region(u) => {
|
||||
CanonicalVarKind::Region(reverse_universe_map[&u])
|
||||
}
|
||||
CanonicalVarKind::Const(u, t) => {
|
||||
CanonicalVarKind::Const(reverse_universe_map[&u], t)
|
||||
}
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderTy(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderRegion(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
CanonicalVarKind::PlaceholderConst(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderConst(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Shorthand helper that creates a canonical region variable for
|
||||
/// `r` (always in the root universe). The reason that we always
|
||||
/// put these variables into the root universe is because this
|
||||
|
|
|
@ -64,9 +64,9 @@ pub struct CanonicalVarValues<'tcx> {
|
|||
/// result.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OriginalQueryValues<'tcx> {
|
||||
/// Map from the universes that appear in the query to the
|
||||
/// universes in the caller context. For the time being, we only
|
||||
/// ever put ROOT values into the query, so this map is very
|
||||
/// Map from the universes that appear in the query to the universes in the
|
||||
/// caller context. For all queries except `evaluate_goal` (used by Chalk),
|
||||
/// we only ever put ROOT values into the query, so this map is very
|
||||
/// simple.
|
||||
pub universe_map: SmallVec<[ty::UniverseIndex; 4]>,
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::traits::{
|
|||
PredicateObligation, SelectionError, TraitEngine,
|
||||
};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::ty::{self, Ty, TypeFoldable};
|
||||
|
||||
pub struct FulfillmentContext<'tcx> {
|
||||
obligations: FxIndexSet<PredicateObligation<'tcx>>,
|
||||
|
@ -91,7 +91,12 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||
let environment = obligation.param_env.caller_bounds();
|
||||
let goal = ChalkEnvironmentAndGoal { environment, goal: obligation.predicate };
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
let canonical_goal = infcx.canonicalize_query(goal, &mut orig_values);
|
||||
if goal.references_error() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let canonical_goal =
|
||||
infcx.canonicalize_query_preserving_universes(goal, &mut orig_values);
|
||||
|
||||
match infcx.tcx.evaluate_goal(canonical_goal) {
|
||||
Ok(response) => {
|
||||
|
|
|
@ -20,11 +20,10 @@ use rustc_span::symbol::sym;
|
|||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::chalk::lowering::{self, LowerInto};
|
||||
use crate::chalk::lowering::LowerInto;
|
||||
|
||||
pub struct RustIrDatabase<'tcx> {
|
||||
pub(crate) interner: RustInterner<'tcx>,
|
||||
pub(crate) reempty_placeholder: ty::Region<'tcx>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for RustIrDatabase<'_> {
|
||||
|
@ -40,12 +39,9 @@ impl<'tcx> RustIrDatabase<'tcx> {
|
|||
bound_vars: SubstsRef<'tcx>,
|
||||
) -> Vec<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> {
|
||||
let predicates = self.interner.tcx.predicates_defined_on(def_id).predicates;
|
||||
let mut regions_substitutor =
|
||||
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
||||
predicates
|
||||
.iter()
|
||||
.map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars))
|
||||
.map(|wc| wc.fold_with(&mut regions_substitutor))
|
||||
.filter_map(|wc| LowerInto::<
|
||||
Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>
|
||||
>::lower_into(wc, self.interner)).collect()
|
||||
|
@ -287,9 +283,6 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
|
||||
let trait_ref = self.interner.tcx.impl_trait_ref(def_id).expect("not an impl");
|
||||
let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars);
|
||||
let mut regions_substitutor =
|
||||
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
||||
let trait_ref = trait_ref.fold_with(&mut regions_substitutor);
|
||||
|
||||
let where_clauses = self.where_clauses_for(def_id, bound_vars);
|
||||
|
||||
|
@ -335,9 +328,6 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
|
||||
let self_ty = trait_ref.self_ty();
|
||||
let self_ty = self_ty.subst(self.interner.tcx, bound_vars);
|
||||
let mut regions_substitutor =
|
||||
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
||||
let self_ty = self_ty.fold_with(&mut regions_substitutor);
|
||||
let lowered_ty = self_ty.lower_into(self.interner);
|
||||
|
||||
parameters[0].assert_ty_ref(self.interner).could_match(
|
||||
|
@ -556,11 +546,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
Fn => lang_items.fn_trait(),
|
||||
FnMut => lang_items.fn_mut_trait(),
|
||||
FnOnce => lang_items.fn_once_trait(),
|
||||
Generator => lang_items.gen_trait(),
|
||||
Unsize => lang_items.unsize_trait(),
|
||||
Unpin => lang_items.unpin_trait(),
|
||||
CoerceUnsized => lang_items.coerce_unsized_trait(),
|
||||
DiscriminantKind => lang_items.discriminant_kind_trait(),
|
||||
Generator => lang_items.generator_return(),
|
||||
};
|
||||
def_id.map(chalk_ir::TraitId)
|
||||
}
|
||||
|
@ -684,28 +674,18 @@ impl<'tcx> chalk_ir::UnificationDatabase<RustInterner<'tcx>> for RustIrDatabase<
|
|||
let variances = self.interner.tcx.variances_of(def_id.0);
|
||||
chalk_ir::Variances::from_iter(
|
||||
self.interner,
|
||||
variances.iter().map(|v| match v {
|
||||
ty::Variance::Invariant => chalk_ir::Variance::Invariant,
|
||||
ty::Variance::Covariant => chalk_ir::Variance::Covariant,
|
||||
ty::Variance::Contravariant => chalk_ir::Variance::Contravariant,
|
||||
ty::Variance::Bivariant => unimplemented!(),
|
||||
}),
|
||||
variances.iter().map(|v| v.lower_into(self.interner)),
|
||||
)
|
||||
}
|
||||
|
||||
fn adt_variance(
|
||||
&self,
|
||||
def_id: chalk_ir::AdtId<RustInterner<'tcx>>,
|
||||
adt_id: chalk_ir::AdtId<RustInterner<'tcx>>,
|
||||
) -> chalk_ir::Variances<RustInterner<'tcx>> {
|
||||
let variances = self.interner.tcx.variances_of(def_id.0.did);
|
||||
let variances = self.interner.tcx.variances_of(adt_id.0.did);
|
||||
chalk_ir::Variances::from_iter(
|
||||
self.interner,
|
||||
variances.iter().map(|v| match v {
|
||||
ty::Variance::Invariant => chalk_ir::Variance::Invariant,
|
||||
ty::Variance::Covariant => chalk_ir::Variance::Covariant,
|
||||
ty::Variance::Contravariant => chalk_ir::Variance::Contravariant,
|
||||
ty::Variance::Bivariant => unimplemented!(),
|
||||
}),
|
||||
variances.iter().map(|v| v.lower_into(self.interner)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,12 +188,18 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
|
|||
chalk_ir::DomainGoal::ObjectSafe(chalk_ir::TraitId(t)),
|
||||
),
|
||||
|
||||
ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) => {
|
||||
chalk_ir::GoalData::SubtypeGoal(chalk_ir::SubtypeGoal {
|
||||
a: a.lower_into(interner),
|
||||
b: b.lower_into(interner),
|
||||
})
|
||||
}
|
||||
|
||||
// FIXME(chalk): other predicates
|
||||
//
|
||||
// We can defer this, but ultimately we'll want to express
|
||||
// some of these in terms of chalk operations.
|
||||
ty::PredicateKind::ClosureKind(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..) => {
|
||||
|
@ -464,9 +470,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
|
|||
})
|
||||
.intern(interner)
|
||||
}
|
||||
ReEmpty(_) => unimplemented!(),
|
||||
// FIXME(chalk): need to handle ReErased
|
||||
ReErased => unimplemented!(),
|
||||
ReEmpty(ui) => {
|
||||
chalk_ir::LifetimeData::Empty(chalk_ir::UniverseIndex { counter: ui.index() })
|
||||
.intern(interner)
|
||||
}
|
||||
ReErased => chalk_ir::LifetimeData::Erased.intern(interner),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -488,12 +496,12 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
|
|||
name: ty::BoundRegionKind::BrAnon(p.idx as u32),
|
||||
})
|
||||
}
|
||||
chalk_ir::LifetimeData::Static => ty::RegionKind::ReStatic,
|
||||
chalk_ir::LifetimeData::Phantom(_, _) => unimplemented!(),
|
||||
chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static,
|
||||
chalk_ir::LifetimeData::Empty(ui) => {
|
||||
ty::RegionKind::ReEmpty(ty::UniverseIndex::from_usize(ui.counter))
|
||||
ty::ReEmpty(ty::UniverseIndex::from_usize(ui.counter))
|
||||
}
|
||||
chalk_ir::LifetimeData::Erased => ty::RegionKind::ReErased,
|
||||
chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased,
|
||||
chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
|
||||
};
|
||||
interner.tcx.mk_region(kind)
|
||||
}
|
||||
|
@ -788,6 +796,16 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::Polarity> for ty::ImplPolarity
|
|||
}
|
||||
}
|
||||
}
|
||||
impl<'tcx> LowerInto<'tcx, chalk_ir::Variance> for ty::Variance {
|
||||
fn lower_into(self, _interner: RustInterner<'tcx>) -> chalk_ir::Variance {
|
||||
match self {
|
||||
ty::Variance::Covariant => chalk_ir::Variance::Covariant,
|
||||
ty::Variance::Invariant => chalk_ir::Variance::Invariant,
|
||||
ty::Variance::Contravariant => chalk_ir::Variance::Contravariant,
|
||||
ty::Variance::Bivariant => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>>>
|
||||
for ty::ProjectionPredicate<'tcx>
|
||||
|
@ -1016,10 +1034,6 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
|||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match *t.kind() {
|
||||
// FIXME(chalk): currently we convert params to placeholders starting at
|
||||
// index `0`. To support placeholders, we'll actually need to do a
|
||||
// first pass to collect placeholders. Then we can insert params after.
|
||||
ty::Placeholder(_) => unimplemented!(),
|
||||
ty::Param(param) => match self.list.iter().position(|r| r == ¶m) {
|
||||
Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||
universe: ty::UniverseIndex::from_usize(0),
|
||||
|
@ -1035,15 +1049,15 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
|||
}))
|
||||
}
|
||||
},
|
||||
|
||||
_ => t.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||
match r {
|
||||
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests.
|
||||
// This covers any region variables in a goal, right?
|
||||
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests,
|
||||
// since canonicalization will already change these to canonical
|
||||
// variables (ty::ReLateBound).
|
||||
ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) {
|
||||
Some(idx) => {
|
||||
let br = ty::BoundRegion {
|
||||
|
@ -1066,6 +1080,39 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
crate struct ReverseParamsSubstitutor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
|
||||
}
|
||||
|
||||
impl<'tcx> ReverseParamsSubstitutor<'tcx> {
|
||||
crate fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
|
||||
) -> Self {
|
||||
Self { tcx, params }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match *t.kind() {
|
||||
ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name }) => {
|
||||
match self.params.get(&name.as_usize()) {
|
||||
Some(param) => self.tcx.mk_ty(ty::Param(*param)),
|
||||
None => t,
|
||||
}
|
||||
}
|
||||
|
||||
_ => t.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to collect `Placeholder`s.
|
||||
crate struct PlaceholdersCollector {
|
||||
universe_index: ty::UniverseIndex,
|
||||
|
@ -1110,32 +1157,3 @@ impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector {
|
|||
r.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to substitute specific `Regions`s with placeholders.
|
||||
crate struct RegionsSubstitutor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
reempty_placeholder: ty::Region<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> RegionsSubstitutor<'tcx> {
|
||||
crate fn new(tcx: TyCtxt<'tcx>, reempty_placeholder: ty::Region<'tcx>) -> Self {
|
||||
RegionsSubstitutor { tcx, reempty_placeholder }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||
match r {
|
||||
ty::ReEmpty(ui) => {
|
||||
assert_eq!(ui.as_usize(), 0);
|
||||
self.reempty_placeholder
|
||||
}
|
||||
|
||||
_ => r.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,9 +22,8 @@ use rustc_infer::infer::canonical::{
|
|||
use rustc_infer::traits::{self, CanonicalChalkEnvironmentAndGoal};
|
||||
|
||||
use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase;
|
||||
use crate::chalk::lowering::{
|
||||
LowerInto, ParamsSubstitutor, PlaceholdersCollector, RegionsSubstitutor,
|
||||
};
|
||||
use crate::chalk::lowering::LowerInto;
|
||||
use crate::chalk::lowering::{ParamsSubstitutor, PlaceholdersCollector, ReverseParamsSubstitutor};
|
||||
|
||||
use chalk_solve::Solution;
|
||||
|
||||
|
@ -42,19 +41,10 @@ crate fn evaluate_goal<'tcx>(
|
|||
let mut placeholders_collector = PlaceholdersCollector::new();
|
||||
obligation.visit_with(&mut placeholders_collector);
|
||||
|
||||
let reempty_placeholder = tcx.mk_region(ty::RegionKind::RePlaceholder(ty::Placeholder {
|
||||
universe: ty::UniverseIndex::ROOT,
|
||||
name: ty::BoundRegionKind::BrAnon(placeholders_collector.next_anon_region_placeholder + 1),
|
||||
}));
|
||||
|
||||
let mut params_substitutor =
|
||||
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
|
||||
let obligation = obligation.fold_with(&mut params_substitutor);
|
||||
// FIXME(chalk): we really should be substituting these back in the solution
|
||||
let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
|
||||
|
||||
let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder);
|
||||
let obligation = obligation.fold_with(&mut regions_substitutor);
|
||||
let params: FxHashMap<usize, ParamTy> = params_substitutor.params;
|
||||
|
||||
let max_universe = obligation.max_universe.index();
|
||||
|
||||
|
@ -96,7 +86,8 @@ crate fn evaluate_goal<'tcx>(
|
|||
|
||||
use chalk_solve::Solver;
|
||||
let mut solver = chalk_engine::solve::SLGSolver::new(32, None);
|
||||
let db = ChalkRustIrDatabase { interner, reempty_placeholder };
|
||||
let db = ChalkRustIrDatabase { interner };
|
||||
debug!(?lowered_goal);
|
||||
let solution = solver.solve(&db, &lowered_goal);
|
||||
debug!(?obligation, ?solution, "evaluate goal");
|
||||
|
||||
|
@ -110,8 +101,9 @@ crate fn evaluate_goal<'tcx>(
|
|||
use rustc_middle::infer::canonical::CanonicalVarInfo;
|
||||
|
||||
let mut var_values: IndexVec<BoundVar, GenericArg<'tcx>> = IndexVec::new();
|
||||
let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params);
|
||||
subst.as_slice(interner).iter().for_each(|p| {
|
||||
var_values.push(p.lower_into(interner));
|
||||
var_values.push(p.lower_into(interner).fold_with(&mut reverse_param_substitutor));
|
||||
});
|
||||
let variables: Vec<_> = binders
|
||||
.iter(interner)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// NOTE: rustc cannot currently handle bounds of the form `for<'a> <Foo as Bar<'a>>::Assoc: Baz`.
|
||||
// This should hopefully be fixed with Chalk.
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
|
||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:27:36
|
||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:26:36
|
||||
|
|
||||
LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
|
||||
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
|
||||
|
@ -11,7 +11,7 @@ LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Send {
|
|||
| ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` is not an iterator
|
||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:27:43
|
||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:26:43
|
||||
|
|
||||
LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<<Self as Case1>::C as Iterator>::Item` is not an iterator
|
||||
|
@ -23,7 +23,7 @@ LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Iterator {
|
|||
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
|
||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:27:93
|
||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:26:93
|
||||
|
|
||||
LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
|
||||
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// run-pass
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(untagged_unions)]
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// run-pass
|
||||
// Test references to the trait `Stream` in the bounds for associated
|
||||
// types defined on `Stream`. Issue #20551.
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
|
||||
trait Stream {
|
||||
type Car;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// ignore-compare-mode-chalk
|
||||
trait Z<'a, T: ?Sized>
|
||||
where
|
||||
T: Z<'a, u16>,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0277]: the trait bound `str: Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:4:8
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:3:8
|
||||
|
|
||||
LL | T: Z<'a, u16>,
|
||||
| ^^^^^^^^^^ the trait `Clone` is not implemented for `str`
|
||||
|
|
||||
note: required by a bound in `Z`
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:7:35
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:6:35
|
||||
|
|
||||
LL | trait Z<'a, T: ?Sized>
|
||||
| - required by a bound in this
|
||||
|
@ -14,13 +14,13 @@ LL | for<'b> <T as Z<'b, u16>>::W: Clone,
|
|||
| ^^^^^ required by this bound in `Z`
|
||||
|
||||
error[E0277]: the trait bound `str: Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:4:8
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:3:8
|
||||
|
|
||||
LL | T: Z<'a, u16>,
|
||||
| ^^^^^^^^^^ the trait `Clone` is not implemented for `str`
|
||||
|
|
||||
note: required by a bound in `Z`
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:7:35
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:6:35
|
||||
|
|
||||
LL | trait Z<'a, T: ?Sized>
|
||||
| - required by a bound in this
|
||||
|
@ -29,13 +29,13 @@ LL | for<'b> <T as Z<'b, u16>>::W: Clone,
|
|||
| ^^^^^ required by this bound in `Z`
|
||||
|
||||
error[E0277]: the trait bound `str: Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:16:14
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:15:14
|
||||
|
|
||||
LL | type W = str;
|
||||
| ^^^ the trait `Clone` is not implemented for `str`
|
||||
|
|
||||
note: required by a bound in `Z`
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:7:35
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:6:35
|
||||
|
|
||||
LL | trait Z<'a, T: ?Sized>
|
||||
| - required by a bound in this
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// ignore-compare-mode-chalk
|
||||
trait Cycle: Sized {
|
||||
type Next: Cycle<Next = Self>;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0277]: the trait bound `str: Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:27:14
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:26:14
|
||||
|
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `Clone` is not implemented for `str`
|
||||
|
|
||||
note: required by a bound in `X`
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:18:45
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:17:45
|
||||
|
|
||||
LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
|
||||
| - required by a bound in this
|
||||
|
@ -14,13 +14,13 @@ LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
|
|||
| ^^^^^ required by this bound in `X`
|
||||
|
||||
error[E0277]: the trait bound `str: Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:32:14
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:31:14
|
||||
|
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `Clone` is not implemented for `str`
|
||||
|
|
||||
note: required by a bound in `X`
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:18:45
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:17:45
|
||||
|
|
||||
LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
|
||||
| - required by a bound in this
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Tests that HRTBs are correctly accepted -- https://github.com/rust-lang/rust/issues/50301
|
||||
// check-pass
|
||||
// ignore-compare-mode-chalk
|
||||
trait Trait
|
||||
where
|
||||
for<'a> &'a Self::IntoIter: IntoIterator<Item = u32>,
|
||||
|
|
6
src/test/ui/chalkify/assert.rs
Normal file
6
src/test/ui/chalkify/assert.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
// run-pass
|
||||
// compile-flags: -Z chalk
|
||||
|
||||
fn main() {
|
||||
assert_eq!(1, 1);
|
||||
}
|
|
@ -2,6 +2,5 @@
|
|||
// compile-flags: -Z chalk
|
||||
|
||||
fn main() {
|
||||
// FIXME(chalk): Require `RegionOutlives`/`TypeOutlives`/`Subtype` support
|
||||
//println!("hello");
|
||||
println!("hello");
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ use std::fmt::Display;
|
|||
|
||||
fn main() {
|
||||
let d: &dyn Display = &mut 3;
|
||||
// FIXME(chalk) should be able to call d.to_string() as well, but doing so
|
||||
// requires Chalk to be able to prove trait object well-formed goals.
|
||||
d.to_string();
|
||||
(&d).to_string();
|
||||
let f: &dyn Fn(i32) -> _ = &|x| x + x;
|
||||
f(2);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
error[E0284]: type annotations needed: cannot satisfy `<usize as SliceIndex<[u8]>>::Output == _`
|
||||
--> $DIR/ub-nonnull.rs:19:30
|
||||
|
|
||||
LL | let out_of_bounds_ptr = &ptr[255];
|
||||
| ^^^^^^^^ cannot satisfy `<usize as SliceIndex<[u8]>>::Output == _`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0284`.
|
|
@ -0,0 +1,9 @@
|
|||
error[E0282]: type annotations needed
|
||||
--> $DIR/ub-wide-ptr.rs:90:67
|
||||
|
|
||||
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
|
||||
| ^^^^^^^^^^^^^^ cannot infer type for type parameter `U` declared on the function `transmute`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
|
@ -1,5 +1,4 @@
|
|||
// run-pass
|
||||
// ignore-compare-mode-chalk
|
||||
pub trait DeclaredTrait {
|
||||
type Type;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// run-pass
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
#![feature(fn_traits,
|
||||
step_trait,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// edition:2018
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0277]: the trait bound `impl Future<Output = [async output]>: Copy` is not satisfied
|
||||
--> $DIR/issue-55872-2.rs:14:20
|
||||
--> $DIR/issue-55872-2.rs:13:20
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = [async output]>`
|
||||
|
||||
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
--> $DIR/issue-55872-2.rs:14:28
|
||||
--> $DIR/issue-55872-2.rs:13:28
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ____________________________^
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// ignore-compare-mode-chalk
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub trait Bar {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
--> $DIR/issue-55872.rs:13:28
|
||||
--> $DIR/issue-55872.rs:12:28
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ____________________________^
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// check-pass
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// ignore-compare-mode-chalk
|
||||
|
||||
trait Next {
|
||||
type Next: Next;
|
||||
}
|
||||
|
||||
struct GetNext<T: Next> { t: T }
|
||||
struct GetNext<T: Next> {
|
||||
t: T,
|
||||
}
|
||||
|
||||
impl<T: Next> Next for GetNext<T> {
|
||||
type Next = <GetNext<T> as Next>::Next;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// ignore-compare-mode-chalk
|
||||
trait Next {
|
||||
type Next: Next;
|
||||
}
|
||||
|
||||
struct GetNext<T: Next> { t: T }
|
||||
struct GetNext<T: Next> {
|
||||
t: T,
|
||||
}
|
||||
|
||||
impl<T: Next> Next for GetNext<T> {
|
||||
type Next = <GetNext<T::Next> as Next>::Next;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
|
||||
--> $DIR/issue-23122-2.rs:9:17
|
||||
--> $DIR/issue-23122-2.rs:10:17
|
||||
|
|
||||
LL | type Next = <GetNext<T::Next> as Next>::Next;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
|
||||
note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>`
|
||||
--> $DIR/issue-23122-2.rs:8:15
|
||||
--> $DIR/issue-23122-2.rs:9:15
|
||||
|
|
||||
LL | impl<T: Next> Next for GetNext<T> {
|
||||
| ^^^^ ^^^^^^^^^^
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// check-pass
|
||||
// ignore-compare-mode-chalk
|
||||
#[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
struct Array<T> {
|
||||
f00: [T; 00],
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
// run-pass
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
struct Foo<A: Repr>(<A as Repr>::Data);
|
||||
|
||||
impl<A> Copy for Foo<A> where <A as Repr>::Data: Copy { }
|
||||
impl<A> Clone for Foo<A> where <A as Repr>::Data: Clone {
|
||||
fn clone(&self) -> Self { Foo(self.0.clone()) }
|
||||
impl<A> Copy for Foo<A> where <A as Repr>::Data: Copy {}
|
||||
impl<A> Clone for Foo<A>
|
||||
where
|
||||
<A as Repr>::Data: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Foo(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
trait Repr {
|
||||
|
@ -15,5 +20,4 @@ impl<A> Repr for A {
|
|||
type Data = u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// check-pass
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
#![feature(associated_type_defaults)]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-55796.rs:18:9
|
||||
--> $DIR/issue-55796.rs:16:9
|
||||
|
|
||||
LL | pub trait Graph<'a> {
|
||||
| -- lifetime `'a` defined here
|
||||
|
@ -8,7 +8,7 @@ LL | Box::new(self.out_edges(u).map(|e| e.target()))
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-55796.rs:23:9
|
||||
--> $DIR/issue-55796.rs:21:9
|
||||
|
|
||||
LL | pub trait Graph<'a> {
|
||||
| -- lifetime `'a` defined here
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// ignore-compare-mode-chalk
|
||||
|
||||
pub trait EdgeTrait<N> {
|
||||
fn target(&self) -> N;
|
||||
}
|
||||
|
@ -16,12 +14,12 @@ pub trait Graph<'a> {
|
|||
|
||||
fn out_neighbors(&'a self, u: &Self::Node) -> Box<dyn Iterator<Item = Self::Node>> {
|
||||
Box::new(self.out_edges(u).map(|e| e.target()))
|
||||
//~^ ERROR cannot infer
|
||||
//~^ ERROR cannot infer
|
||||
}
|
||||
|
||||
fn in_neighbors(&'a self, u: &Self::Node) -> Box<dyn Iterator<Item = Self::Node>> {
|
||||
Box::new(self.in_edges(u).map(|e| e.target()))
|
||||
//~^ ERROR cannot infer
|
||||
//~^ ERROR cannot infer
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
|
||||
--> $DIR/issue-55796.rs:18:9
|
||||
--> $DIR/issue-55796.rs:16:9
|
||||
|
|
||||
LL | Box::new(self.out_edges(u).map(|e| e.target()))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
|
||||
--> $DIR/issue-55796.rs:7:17
|
||||
--> $DIR/issue-55796.rs:5:17
|
||||
|
|
||||
LL | pub trait Graph<'a> {
|
||||
| ^^
|
||||
note: ...so that the type `Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:18:40: 18:54]>` will meet its required lifetime bounds
|
||||
--> $DIR/issue-55796.rs:18:9
|
||||
note: ...so that the type `Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:16:40: 16:54]>` will meet its required lifetime bounds
|
||||
--> $DIR/issue-55796.rs:16:9
|
||||
|
|
||||
LL | Box::new(self.out_edges(u).map(|e| e.target()))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: but, the lifetime must be valid for the static lifetime...
|
||||
note: ...so that the types are compatible
|
||||
--> $DIR/issue-55796.rs:18:9
|
||||
--> $DIR/issue-55796.rs:16:9
|
||||
|
|
||||
LL | Box::new(self.out_edges(u).map(|e| e.target()))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -24,24 +24,24 @@ LL | Box::new(self.out_edges(u).map(|e| e.target()))
|
|||
found `Box<dyn Iterator<Item = <Self as Graph<'a>>::Node>>`
|
||||
|
||||
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
|
||||
--> $DIR/issue-55796.rs:23:9
|
||||
--> $DIR/issue-55796.rs:21:9
|
||||
|
|
||||
LL | Box::new(self.in_edges(u).map(|e| e.target()))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
|
||||
--> $DIR/issue-55796.rs:7:17
|
||||
--> $DIR/issue-55796.rs:5:17
|
||||
|
|
||||
LL | pub trait Graph<'a> {
|
||||
| ^^
|
||||
note: ...so that the type `Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:23:39: 23:53]>` will meet its required lifetime bounds
|
||||
--> $DIR/issue-55796.rs:23:9
|
||||
note: ...so that the type `Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:21:39: 21:53]>` will meet its required lifetime bounds
|
||||
--> $DIR/issue-55796.rs:21:9
|
||||
|
|
||||
LL | Box::new(self.in_edges(u).map(|e| e.target()))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: but, the lifetime must be valid for the static lifetime...
|
||||
note: ...so that the types are compatible
|
||||
--> $DIR/issue-55796.rs:23:9
|
||||
--> $DIR/issue-55796.rs:21:9
|
||||
|
|
||||
LL | Box::new(self.in_edges(u).map(|e| e.target()))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// build-pass
|
||||
// ignore-tidy-filelength
|
||||
// ignore-compare-mode-chalk
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
fn banana(v: &str) -> u32 {
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
// Regression test for #53789.
|
||||
//
|
||||
// check-pass
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
use std::cmp::Ord;
|
||||
use std::collections::BTreeMap;
|
||||
use std::ops::Range;
|
||||
use std::cmp::Ord;
|
||||
|
||||
macro_rules! valuetree {
|
||||
() => {
|
||||
type ValueTree =
|
||||
<Self::Strategy as $crate::Strategy>::Value;
|
||||
type ValueTree = <Self::Strategy as $crate::Strategy>::Value;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -41,7 +39,9 @@ macro_rules! product_type {
|
|||
macro_rules! default {
|
||||
($type: ty, $val: expr) => {
|
||||
impl Default for $type {
|
||||
fn default() -> Self { $val.into() }
|
||||
fn default() -> Self {
|
||||
$val.into()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -90,21 +90,17 @@ trait ValueTree {
|
|||
}
|
||||
|
||||
trait Strategy {
|
||||
type Value : ValueTree;
|
||||
type Value: ValueTree;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct VecStrategy<T : Strategy> {
|
||||
struct VecStrategy<T: Strategy> {
|
||||
element: T,
|
||||
size: Range<usize>,
|
||||
}
|
||||
|
||||
fn vec<T : Strategy>(element: T, size: Range<usize>)
|
||||
-> VecStrategy<T> {
|
||||
VecStrategy {
|
||||
element: element,
|
||||
size: size,
|
||||
}
|
||||
fn vec<T: Strategy>(element: T, size: Range<usize>) -> VecStrategy<T> {
|
||||
VecStrategy { element: element, size: size }
|
||||
}
|
||||
|
||||
type ValueFor<S> = <<S as Strategy>::Value as ValueTree>::Value;
|
||||
|
@ -124,7 +120,6 @@ type StrategyType<'a, A> = <A as Arbitrary<'a>>::Strategy;
|
|||
struct SizeBounds(Range<usize>);
|
||||
default!(SizeBounds, 0..100);
|
||||
|
||||
|
||||
impl From<Range<usize>> for SizeBounds {
|
||||
fn from(high: Range<usize>) -> Self {
|
||||
unimplemented!()
|
||||
|
@ -137,24 +132,26 @@ impl From<SizeBounds> for Range<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn any_with<'a, A: Arbitrary<'a>>(args: A::Parameters)
|
||||
-> StrategyType<'a, A> {
|
||||
fn any_with<'a, A: Arbitrary<'a>>(args: A::Parameters) -> StrategyType<'a, A> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
impl<K: ValueTree, V: ValueTree> Strategy for (K, V) where
|
||||
<K as ValueTree>::Value: Ord {
|
||||
impl<K: ValueTree, V: ValueTree> Strategy for (K, V)
|
||||
where
|
||||
<K as ValueTree>::Value: Ord,
|
||||
{
|
||||
type Value = TupleValueTree<(K, V)>;
|
||||
}
|
||||
|
||||
impl<K: ValueTree, V: ValueTree> ValueTree for TupleValueTree<(K, V)> where
|
||||
<K as ValueTree>::Value: Ord {
|
||||
impl<K: ValueTree, V: ValueTree> ValueTree for TupleValueTree<(K, V)>
|
||||
where
|
||||
<K as ValueTree>::Value: Ord,
|
||||
{
|
||||
type Value = BTreeMapValueTree<K, V>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct VecValueTree<T : ValueTree> {
|
||||
struct VecValueTree<T: ValueTree> {
|
||||
elements: Vec<T>,
|
||||
}
|
||||
|
||||
|
@ -185,8 +182,8 @@ impl<'a, A, B> Arbitrary<'a> for BTreeMap<A, B>
|
|||
where
|
||||
A: Arbitrary<'static> + Ord,
|
||||
B: Arbitrary<'static>,
|
||||
StrategyFor<A>: 'static,
|
||||
StrategyFor<B>: 'static,
|
||||
StrategyFor<A>: 'static,
|
||||
StrategyFor<B>: 'static,
|
||||
{
|
||||
valuetree!();
|
||||
type Parameters = RangedParams2<A::Parameters, B::Parameters>;
|
||||
|
@ -208,10 +205,14 @@ mapfn! {
|
|||
}
|
||||
}
|
||||
|
||||
fn btree_map<K : Strategy + 'static, V : Strategy + 'static>
|
||||
(key: K, value: V, size: Range<usize>)
|
||||
-> BTreeMapStrategy<K, V>
|
||||
where ValueFor<K> : Ord {
|
||||
fn btree_map<K: Strategy + 'static, V: Strategy + 'static>(
|
||||
key: K,
|
||||
value: V,
|
||||
size: Range<usize>,
|
||||
) -> BTreeMapStrategy<K, V>
|
||||
where
|
||||
ValueFor<K>: Ord,
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
@ -245,4 +246,4 @@ mod statics {
|
|||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Check that we check that default associated types satisfy the required
|
||||
// bounds on them.
|
||||
// ignore-compare-mode-chalk
|
||||
|
||||
#![feature(specialization)]
|
||||
//~^ WARNING `specialization` is incomplete
|
|
@ -1,5 +1,5 @@
|
|||
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/deafult-associated-type-bound-1.rs:5:12
|
||||
--> $DIR/default-associated-type-bound-1.rs:4:12
|
||||
|
|
||||
LL | #![feature(specialization)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -9,13 +9,13 @@ LL | #![feature(specialization)]
|
|||
= help: consider using `min_specialization` instead, which is more stable and complete
|
||||
|
||||
error[E0277]: the trait bound `str: Clone` is not satisfied
|
||||
--> $DIR/deafult-associated-type-bound-1.rs:19:22
|
||||
--> $DIR/default-associated-type-bound-1.rs:18:22
|
||||
|
|
||||
LL | default type U = str;
|
||||
| ^^^ the trait `Clone` is not implemented for `str`
|
||||
|
|
||||
note: required by a bound in `X::U`
|
||||
--> $DIR/deafult-associated-type-bound-1.rs:9:13
|
||||
--> $DIR/default-associated-type-bound-1.rs:8:13
|
||||
|
|
||||
LL | type U: Clone;
|
||||
| ^^^^^ required by this bound in `X::U`
|
|
@ -1,5 +1,5 @@
|
|||
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/deafult-associated-type-bound-2.rs:2:12
|
||||
--> $DIR/default-associated-type-bound-2.rs:2:12
|
||||
|
|
||||
LL | #![feature(specialization)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -9,14 +9,14 @@ LL | #![feature(specialization)]
|
|||
= help: consider using `min_specialization` instead, which is more stable and complete
|
||||
|
||||
error[E0277]: can't compare `&'static B` with `B`
|
||||
--> $DIR/deafult-associated-type-bound-2.rs:16:22
|
||||
--> $DIR/default-associated-type-bound-2.rs:16:22
|
||||
|
|
||||
LL | default type U = &'static B;
|
||||
| ^^^^^^^^^^ no implementation for `&'static B == B`
|
||||
|
|
||||
= help: the trait `PartialEq<B>` is not implemented for `&'static B`
|
||||
note: required by a bound in `X::U`
|
||||
--> $DIR/deafult-associated-type-bound-2.rs:6:13
|
||||
--> $DIR/default-associated-type-bound-2.rs:6:13
|
||||
|
|
||||
LL | type U: PartialEq<T>;
|
||||
| ^^^^^^^^^^^^ required by this bound in `X::U`
|
|
@ -1,5 +1,5 @@
|
|||
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/deafult-generic-associated-type-bound.rs:3:12
|
||||
--> $DIR/default-generic-associated-type-bound.rs:3:12
|
||||
|
|
||||
LL | #![feature(specialization)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -9,14 +9,14 @@ LL | #![feature(specialization)]
|
|||
= help: consider using `min_specialization` instead, which is more stable and complete
|
||||
|
||||
error[E0277]: can't compare `T` with `T`
|
||||
--> $DIR/deafult-generic-associated-type-bound.rs:18:26
|
||||
--> $DIR/default-generic-associated-type-bound.rs:18:26
|
||||
|
|
||||
LL | default type U<'a> = &'a T;
|
||||
| ^^^^^ no implementation for `T == T`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `PartialEq` for `&'a T`
|
||||
note: required by a bound in `X::U`
|
||||
--> $DIR/deafult-generic-associated-type-bound.rs:8:17
|
||||
--> $DIR/default-generic-associated-type-bound.rs:8:17
|
||||
|
|
||||
LL | type U<'a>: PartialEq<&'a Self> where Self: 'a;
|
||||
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `X::U`
|
|
@ -1,4 +1,3 @@
|
|||
// ignore-compare-mode-chalk
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
--> $DIR/issue-53598.rs:20:42
|
||||
--> $DIR/issue-53598.rs:19:42
|
||||
|
|
||||
LL | fn foo<T: Debug>(_: T) -> Self::Item {
|
||||
| __________________________________________^
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// ignore-compare-mode-chalk
|
||||
#![feature(arbitrary_self_types)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
--> $DIR/issue-57700.rs:16:58
|
||||
--> $DIR/issue-57700.rs:15:58
|
||||
|
|
||||
LL | fn foo(self: impl Deref<Target = Self>) -> Self::Bar {
|
||||
| __________________________________________________________^
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// ignore-compare-mode-chalk
|
||||
|
||||
trait Bug {
|
||||
type Item: Bug;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/issue-60371.rs:10:17
|
||||
--> $DIR/issue-60371.rs:8:17
|
||||
|
|
||||
LL | type Item = impl Bug;
|
||||
| ^^^^^^^^
|
||||
|
@ -8,7 +8,7 @@ LL | type Item = impl Bug;
|
|||
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error[E0277]: the trait bound `(): Bug` is not satisfied
|
||||
--> $DIR/issue-60371.rs:12:40
|
||||
--> $DIR/issue-60371.rs:10:40
|
||||
|
|
||||
LL | const FUN: fn() -> Self::Item = || ();
|
||||
| ^ the trait `Bug` is not implemented for `()`
|
||||
|
@ -17,7 +17,7 @@ LL | const FUN: fn() -> Self::Item = || ();
|
|||
<&() as Bug>
|
||||
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/issue-60371.rs:12:37
|
||||
--> $DIR/issue-60371.rs:10:37
|
||||
|
|
||||
LL | impl Bug for &() {
|
||||
| - cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
|
||||
|
|
Loading…
Add table
Reference in a new issue