mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Use Term in ProjectionPredicate
ProjectionPredicate should be able to handle both associated types and consts so this adds the first step of that. It mainly just pipes types all the way down, not entirely sure how to handle consts, but hopefully that'll come with time.
This commit is contained in:
parent
fb57b7518d
commit
67f56671d0
54
Cargo.lock
54
Cargo.lock
@ -335,7 +335,7 @@ dependencies = [
|
||||
"cargo-test-macro",
|
||||
"cargo-test-support",
|
||||
"cargo-util",
|
||||
"clap 3.0.6",
|
||||
"clap",
|
||||
"crates-io",
|
||||
"crossbeam-utils",
|
||||
"curl",
|
||||
@ -615,28 +615,13 @@ dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim 0.8.0",
|
||||
"textwrap 0.11.0",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
"yaml-rust 0.3.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1957aa4a5fb388f0a0a73ce7556c5b42025b874e5cdc2c670775e346e97adec0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"indexmap",
|
||||
"os_str_bytes",
|
||||
"strsim 0.10.0",
|
||||
"termcolor",
|
||||
"textwrap 0.14.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
version = "0.1.60"
|
||||
@ -669,7 +654,7 @@ version = "0.0.1"
|
||||
dependencies = [
|
||||
"bytecount",
|
||||
"cargo_metadata 0.14.0",
|
||||
"clap 2.34.0",
|
||||
"clap",
|
||||
"indoc",
|
||||
"itertools 0.10.1",
|
||||
"opener",
|
||||
@ -1751,7 +1736,7 @@ name = "installer"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 2.34.0",
|
||||
"clap",
|
||||
"flate2",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
@ -2190,7 +2175,7 @@ dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"clap 2.34.0",
|
||||
"clap",
|
||||
"elasticlunr-rs",
|
||||
"env_logger 0.7.1",
|
||||
"handlebars",
|
||||
@ -2521,15 +2506,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "output_vt100"
|
||||
version = "0.1.2"
|
||||
@ -2934,7 +2910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0b4b5faaf07040474e8af74a9e19ff167d5d204df5db5c5c765edecfb900358"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap 2.34.0",
|
||||
"clap",
|
||||
"derive_more",
|
||||
"env_logger 0.7.1",
|
||||
"humantime 2.0.1",
|
||||
@ -3282,7 +3258,7 @@ dependencies = [
|
||||
name = "rustbook"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 2.34.0",
|
||||
"clap",
|
||||
"env_logger 0.7.1",
|
||||
"mdbook",
|
||||
]
|
||||
@ -4898,19 +4874,13 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
|
||||
dependencies = [
|
||||
"clap 2.34.0",
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
@ -5081,12 +5051,6 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
|
@ -997,10 +997,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
};
|
||||
|
||||
let kind = match constraint.kind {
|
||||
AssocConstraintKind::Equality { ref term } => match term {
|
||||
Term::Ty(ref ty) => hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) },
|
||||
Term::Const(ref c) => hir::TypeBindingKind::Const { c: self.lower_anon_const(c) },
|
||||
},
|
||||
AssocConstraintKind::Equality { ref term } => {
|
||||
let term = match term {
|
||||
Term::Ty(ref ty) => self.lower_ty(ty, itctx).into(),
|
||||
Term::Const(ref c) => self.lower_anon_const(c).into(),
|
||||
};
|
||||
hir::TypeBindingKind::Equality { term }
|
||||
}
|
||||
AssocConstraintKind::Bound { ref bounds } => {
|
||||
let mut capturable_lifetimes;
|
||||
let mut parent_def_id = self.current_hir_id_owner;
|
||||
@ -1079,7 +1082,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
itctx,
|
||||
);
|
||||
|
||||
hir::TypeBindingKind::Equality { ty }
|
||||
hir::TypeBindingKind::Equality { term: ty.into() }
|
||||
})
|
||||
} else {
|
||||
// Desugar `AssocTy: Bounds` into a type binding where the
|
||||
|
@ -420,7 +420,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
ty: &'hir hir::Ty<'hir>,
|
||||
) -> hir::TypeBinding<'hir> {
|
||||
let ident = Ident::with_dummy_span(hir::FN_OUTPUT_NAME);
|
||||
let kind = hir::TypeBindingKind::Equality { ty };
|
||||
let kind = hir::TypeBindingKind::Equality { term: ty.into() };
|
||||
let args = arena_vec![self;];
|
||||
let bindings = arena_vec![self;];
|
||||
let gen_args = self.arena.alloc(hir::GenericArgs {
|
||||
|
@ -964,9 +964,7 @@ impl<'a> State<'a> {
|
||||
Term::Const(c) => self.print_expr_anon_const(c),
|
||||
}
|
||||
}
|
||||
ast::AssocConstraintKind::Bound { bounds } => {
|
||||
self.print_type_bounds(":", &*bounds);
|
||||
}
|
||||
ast::AssocConstraintKind::Bound { bounds } => self.print_type_bounds(":", &*bounds),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,7 +779,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
[
|
||||
hir::TypeBinding {
|
||||
ident: Ident { name: sym::Output, .. },
|
||||
kind: hir::TypeBindingKind::Equality { ty },
|
||||
kind:
|
||||
hir::TypeBindingKind::Equality {
|
||||
term: hir::Term::Ty(ty),
|
||||
},
|
||||
..
|
||||
},
|
||||
],
|
||||
|
@ -377,7 +377,7 @@ impl GenericArgs<'_> {
|
||||
GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err),
|
||||
_ => false,
|
||||
}) || self.bindings.iter().any(|arg| match arg.kind {
|
||||
TypeBindingKind::Equality { ty } => matches!(ty.kind, TyKind::Err),
|
||||
TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err),
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
@ -2129,21 +2129,37 @@ pub struct TypeBinding<'hir> {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
pub enum Term<'hir> {
|
||||
Ty(&'hir Ty<'hir>),
|
||||
Const(AnonConst),
|
||||
}
|
||||
|
||||
impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
|
||||
fn from(ty: &'hir Ty<'hir>) -> Self {
|
||||
Term::Ty(ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'hir> From<AnonConst> for Term<'hir> {
|
||||
fn from(c: AnonConst) -> Self {
|
||||
Term::Const(c)
|
||||
}
|
||||
}
|
||||
|
||||
// Represents the two kinds of type bindings.
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
pub enum TypeBindingKind<'hir> {
|
||||
/// E.g., `Foo<Bar: Send>`.
|
||||
Constraint { bounds: &'hir [GenericBound<'hir>] },
|
||||
/// E.g., `Foo<Bar = ()>`.
|
||||
Equality { ty: &'hir Ty<'hir> },
|
||||
/// E.g., `Foo<N = 3>`.
|
||||
Const { c: AnonConst },
|
||||
/// E.g., `Foo<Bar = ()>`, `Foo<Bar = ()>`
|
||||
Equality { term: Term<'hir> },
|
||||
}
|
||||
|
||||
impl TypeBinding<'_> {
|
||||
pub fn ty(&self) -> &Ty<'_> {
|
||||
match self.kind {
|
||||
TypeBindingKind::Equality { ref ty } => ty,
|
||||
TypeBindingKind::Equality { term: Term::Ty(ref ty) } => ty,
|
||||
_ => panic!("expected equality type binding for parenthesized generic args"),
|
||||
}
|
||||
}
|
||||
|
@ -827,11 +827,11 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
|
||||
visitor.visit_ident(type_binding.ident);
|
||||
visitor.visit_generic_args(type_binding.span, type_binding.gen_args);
|
||||
match type_binding.kind {
|
||||
TypeBindingKind::Equality { ref ty } => visitor.visit_ty(ty),
|
||||
TypeBindingKind::Const { ref c } => visitor.visit_anon_const(c),
|
||||
TypeBindingKind::Constraint { bounds } => {
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
}
|
||||
TypeBindingKind::Equality { ref term } => match term {
|
||||
Term::Ty(ref ty) => visitor.visit_ty(ty),
|
||||
Term::Const(ref c) => visitor.visit_anon_const(c),
|
||||
},
|
||||
TypeBindingKind::Constraint { bounds } => walk_list!(visitor, visit_param_bound, bounds),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
|
||||
use rustc_ast_pretty::pp::{self, Breaks};
|
||||
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node};
|
||||
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node, Term};
|
||||
use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
|
||||
use rustc_span::source_map::{SourceMap, Spanned};
|
||||
use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
|
||||
@ -1752,13 +1752,12 @@ impl<'a> State<'a> {
|
||||
self.print_generic_args(binding.gen_args, false, false);
|
||||
self.space();
|
||||
match generic_args.bindings[0].kind {
|
||||
hir::TypeBindingKind::Equality { ref ty } => {
|
||||
hir::TypeBindingKind::Equality { ref term } => {
|
||||
self.word_space("=");
|
||||
self.print_type(ty);
|
||||
}
|
||||
hir::TypeBindingKind::Const { ref c } => {
|
||||
self.word_space("=");
|
||||
self.print_anon_const(c);
|
||||
match term {
|
||||
Term::Ty(ref ty) => self.print_type(ty),
|
||||
Term::Const(ref c) => self.print_anon_const(c),
|
||||
}
|
||||
}
|
||||
hir::TypeBindingKind::Constraint { bounds } => {
|
||||
self.print_bounds(":", bounds);
|
||||
|
@ -69,7 +69,7 @@ use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::{
|
||||
self,
|
||||
subst::{GenericArgKind, Subst, SubstsRef},
|
||||
Region, Ty, TyCtxt, TypeFoldable,
|
||||
Region, Term, Ty, TyCtxt, TypeFoldable,
|
||||
};
|
||||
use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
|
||||
use rustc_target::spec::abi;
|
||||
@ -1780,7 +1780,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
{
|
||||
if projection_predicate.projection_ty.item_def_id == item_def_id {
|
||||
// We don't account for multiple `Future::Output = Ty` contraints.
|
||||
return Some(projection_predicate.ty);
|
||||
match projection_predicate.term {
|
||||
Term::Ty(ty) => return Some(ty),
|
||||
// Can return None, but not sure if that makes sense?
|
||||
Term::Const(_c) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,8 +122,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
{
|
||||
for type_binding in generic_args.bindings.iter() {
|
||||
if type_binding.ident.name == rustc_span::sym::Output {
|
||||
if let hir::TypeBindingKind::Equality { ty } =
|
||||
type_binding.kind
|
||||
if let hir::TypeBindingKind::Equality {
|
||||
term: hir::Term::Ty(ty),
|
||||
} = type_binding.kind
|
||||
{
|
||||
return Some(ty);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::ty::fold::BottomUpFolder;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor};
|
||||
use rustc_middle::ty::{self, OpaqueTypeKey, Term, Ty, TyCtxt, TypeFoldable, TypeVisitor};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::ops::ControlFlow;
|
||||
@ -584,9 +584,13 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
debug!(?predicate);
|
||||
|
||||
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
|
||||
if projection.ty.references_error() {
|
||||
// No point on adding these obligations since there's a type error involved.
|
||||
return tcx.ty_error();
|
||||
if let Term::Ty(ty) = projection.term {
|
||||
if ty.references_error() {
|
||||
// No point on adding these obligations since there's a type error involved.
|
||||
return tcx.ty_error();
|
||||
}
|
||||
} else {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
kind: TypeVariableOriginKind::NormalizeProjectionType,
|
||||
span: self.tcx.def_span(def_id),
|
||||
});
|
||||
let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var });
|
||||
let projection =
|
||||
ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, term: ty_var.into() });
|
||||
let obligation = Obligation::with_depth(
|
||||
cause,
|
||||
recursion_depth,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::ty::subst::{GenericArg, GenericArgKind};
|
||||
use crate::ty::{self, InferConst, Ty, TypeFlags};
|
||||
use crate::ty::{self, InferConst, Term, Ty, TypeFlags};
|
||||
use std::slice;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -241,9 +241,12 @@ impl FlagComputation {
|
||||
self.add_ty(a);
|
||||
self.add_ty(b);
|
||||
}
|
||||
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
|
||||
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
|
||||
self.add_projection_ty(projection_ty);
|
||||
self.add_ty(ty);
|
||||
match term {
|
||||
Term::Ty(ty) => self.add_ty(ty),
|
||||
Term::Const(_c) => todo!(),
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::WellFormed(arg) => {
|
||||
self.add_substs(slice::from_ref(&arg));
|
||||
|
@ -484,7 +484,7 @@ crate struct PredicateInner<'tcx> {
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(PredicateInner<'_>, 48);
|
||||
static_assert_size!(PredicateInner<'_>, 56);
|
||||
|
||||
#[derive(Clone, Copy, Lift)]
|
||||
pub struct Predicate<'tcx> {
|
||||
@ -795,11 +795,35 @@ pub struct CoercePredicate<'tcx> {
|
||||
}
|
||||
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable)]
|
||||
pub enum Term<'tcx> {
|
||||
Ty(Ty<'tcx>),
|
||||
Const(&'tcx Const<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
|
||||
fn from(ty: Ty<'tcx>) -> Self {
|
||||
Term::Ty(ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> From<&'tcx Const<'tcx>> for Term<'tcx> {
|
||||
fn from(c: &'tcx Const<'tcx>) -> Self {
|
||||
Term::Const(c)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Term<'tcx> {
|
||||
pub fn ty(&self) -> Ty<'tcx> {
|
||||
if let Term::Ty(ty) = self { ty } else { panic!("Expected type") }
|
||||
}
|
||||
}
|
||||
|
||||
/// This kind of predicate has no *direct* correspondent in the
|
||||
/// syntax, but it roughly corresponds to the syntactic forms:
|
||||
///
|
||||
/// 1. `T: TraitRef<..., Item = Type>`
|
||||
/// - Or `T: TraitRef<..., Item = Const>`
|
||||
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
|
||||
///
|
||||
/// In particular, form #1 is "desugared" to the combination of a
|
||||
@ -812,26 +836,7 @@ pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
|
||||
#[derive(HashStable, TypeFoldable)]
|
||||
pub struct ProjectionPredicate<'tcx> {
|
||||
pub projection_ty: ProjectionTy<'tcx>,
|
||||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
/// This kind of predicate has no *direct* correspondent in the
|
||||
/// syntax, but it roughly corresponds to the syntactic forms:
|
||||
///
|
||||
/// 1. `T: TraitRef<..., Item = Const>`
|
||||
/// 2. `<T as TraitRef<...>>::Item == Const` (NYI)
|
||||
///
|
||||
/// In particular, form #1 is "desugared" to the combination of a
|
||||
/// normal trait predicate (`T: TraitRef<...>`) and one of these
|
||||
/// predicates. Form #2 is a broader form in that it also permits
|
||||
/// equality between arbitrary types. Processing an instance of
|
||||
/// Form #2 eventually yields one of these `ProjectionPredicate`
|
||||
/// instances to normalize the LHS.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug)]
|
||||
#[derive(HashStable, TypeFoldable)]
|
||||
pub struct ConstPredicate<'tcx> {
|
||||
pub projection: ProjectionTy<'tcx>,
|
||||
pub c: &'tcx Const<'tcx>,
|
||||
pub term: Term<'tcx>,
|
||||
}
|
||||
|
||||
pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;
|
||||
@ -857,7 +862,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
|
||||
}
|
||||
|
||||
pub fn ty(&self) -> Binder<'tcx, Ty<'tcx>> {
|
||||
self.map_bound(|predicate| predicate.ty)
|
||||
self.map_bound(|predicate| if let Term::Ty(ty) = predicate.term { ty } else { todo!() })
|
||||
}
|
||||
|
||||
/// The `DefId` of the `TraitItem` for the associated type.
|
||||
|
@ -2499,7 +2499,14 @@ define_print_and_forward_display! {
|
||||
}
|
||||
|
||||
ty::ProjectionPredicate<'tcx> {
|
||||
p!(print(self.projection_ty), " == ", print(self.ty))
|
||||
p!(print(self.projection_ty), " == ", print(self.term))
|
||||
}
|
||||
|
||||
ty::Term<'tcx> {
|
||||
match self {
|
||||
ty::Term::Ty(ty) => p!(print(ty)),
|
||||
ty::Term::Const(c) => p!(print(c)),
|
||||
}
|
||||
}
|
||||
|
||||
ty::ProjectionTy<'tcx> {
|
||||
|
@ -7,7 +7,7 @@
|
||||
use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar};
|
||||
use crate::ty::error::{ExpectedFound, TypeError};
|
||||
use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
|
||||
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use crate::ty::{self, Term, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_hir as ast;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_span::DUMMY_SP;
|
||||
@ -839,10 +839,13 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
|
||||
a: ty::ProjectionPredicate<'tcx>,
|
||||
b: ty::ProjectionPredicate<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
|
||||
Ok(ty::ProjectionPredicate {
|
||||
projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
|
||||
ty: relation.relate(a.ty, b.ty)?,
|
||||
})
|
||||
match (a.term, b.term) {
|
||||
(Term::Ty(a_ty), Term::Ty(b_ty)) => Ok(ty::ProjectionPredicate {
|
||||
projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
|
||||
term: relation.relate(a_ty, b_ty)?.into(),
|
||||
}),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use crate::mir::interpret;
|
||||
use crate::mir::ProjectionKind;
|
||||
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor};
|
||||
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
||||
use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
|
||||
use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt};
|
||||
use rustc_data_structures::functor::IdFunctor;
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_hir::def_id::CRATE_DEF_INDEX;
|
||||
@ -158,7 +158,7 @@ impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty)
|
||||
write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term)
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,6 +356,16 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
|
||||
type Lifted = ty::Term<'tcx>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
Some(match self {
|
||||
Term::Ty(ty) => Term::Ty(tcx.lift(ty)?),
|
||||
Term::Const(c) => Term::Const(tcx.lift(c)?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
|
||||
type Lifted = ty::TraitPredicate<'tcx>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
|
||||
@ -403,8 +413,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
|
||||
impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
|
||||
type Lifted = ty::ProjectionPredicate<'tcx>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
|
||||
tcx.lift((self.projection_ty, self.ty))
|
||||
.map(|(projection_ty, ty)| ty::ProjectionPredicate { projection_ty, ty })
|
||||
tcx.lift((self.projection_ty, self.term))
|
||||
.map(|(projection_ty, term)| ty::ProjectionPredicate { projection_ty, term })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ use crate::infer::canonical::Canonical;
|
||||
use crate::ty::fold::ValidateBoundVars;
|
||||
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
|
||||
use crate::ty::InferTy::{self, *};
|
||||
use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable};
|
||||
use crate::ty::{self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable};
|
||||
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
|
||||
use polonius_engine::Atom;
|
||||
use rustc_data_structures::captures::Captures;
|
||||
@ -1570,7 +1570,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
|
||||
item_def_id: self.item_def_id,
|
||||
substs: tcx.mk_substs_trait(self_ty, self.substs),
|
||||
},
|
||||
ty: self.ty,
|
||||
term: self.ty.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1580,11 +1580,16 @@ impl<'tcx> ExistentialProjection<'tcx> {
|
||||
) -> Self {
|
||||
// Assert there is a Self.
|
||||
projection_predicate.projection_ty.substs.type_at(0);
|
||||
let ty = if let Term::Ty(ty) = projection_predicate.term {
|
||||
ty
|
||||
} else {
|
||||
todo!();
|
||||
};
|
||||
|
||||
Self {
|
||||
item_def_id: projection_predicate.projection_ty.item_def_id,
|
||||
substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
|
||||
ty: projection_predicate.ty,
|
||||
ty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -503,17 +503,15 @@ impl<'a> Parser<'a> {
|
||||
) -> PResult<'a, AssocConstraintKind> {
|
||||
let arg = self.parse_generic_arg(None)?;
|
||||
let span = ident.span.to(self.prev_token.span);
|
||||
let ty = match arg {
|
||||
Some(GenericArg::Type(ty)) => ty,
|
||||
Some(GenericArg::Const(c)) => {
|
||||
return Ok(AssocConstraintKind::Equality { term: c.into() });
|
||||
}
|
||||
let term = match arg {
|
||||
Some(GenericArg::Type(ty)) => ty.into(),
|
||||
Some(GenericArg::Const(c)) => c.into(),
|
||||
Some(GenericArg::Lifetime(lt)) => {
|
||||
self.struct_span_err(span, "associated lifetimes are not supported")
|
||||
.span_label(lt.ident.span, "the lifetime is given here")
|
||||
.help("if you meant to specify a trait object, write `dyn Trait + 'lifetime`")
|
||||
.emit();
|
||||
self.mk_ty(span, ast::TyKind::Err)
|
||||
self.mk_ty(span, ast::TyKind::Err).into()
|
||||
}
|
||||
None => {
|
||||
let after_eq = eq.shrink_to_hi();
|
||||
@ -542,7 +540,7 @@ impl<'a> Parser<'a> {
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
Ok(AssocConstraintKind::Equality { term: ty.into() })
|
||||
Ok(AssocConstraintKind::Equality { term })
|
||||
}
|
||||
|
||||
/// We do not permit arbitrary expressions as const arguments. They must be one of:
|
||||
|
@ -127,7 +127,8 @@ where
|
||||
constness: _,
|
||||
polarity: _,
|
||||
}) => self.visit_trait(trait_ref),
|
||||
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
|
||||
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
|
||||
let ty = term.ty();
|
||||
ty.visit_with(self)?;
|
||||
self.visit_projection_ty(projection_ty)
|
||||
}
|
||||
@ -1185,7 +1186,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||
}
|
||||
|
||||
for (poly_predicate, _) in bounds.projection_bounds {
|
||||
if self.visit(poly_predicate.skip_binder().ty).is_break()
|
||||
if self.visit(poly_predicate.skip_binder().term.ty()).is_break()
|
||||
|| self
|
||||
.visit_projection_ty(poly_predicate.skip_binder().projection_ty)
|
||||
.is_break()
|
||||
|
@ -1304,7 +1304,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||
|
||||
debug!(
|
||||
"report_projection_error normalized_ty={:?} data.ty={:?}",
|
||||
normalized_ty, data.ty
|
||||
normalized_ty,
|
||||
data.term.ty()
|
||||
);
|
||||
|
||||
let is_normalized_ty_expected = !matches!(
|
||||
@ -1318,12 +1319,12 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||
if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
|
||||
is_normalized_ty_expected,
|
||||
normalized_ty,
|
||||
data.ty,
|
||||
data.term.ty(),
|
||||
) {
|
||||
values = Some(infer::ValuePairs::Types(ExpectedFound::new(
|
||||
is_normalized_ty_expected,
|
||||
normalized_ty,
|
||||
data.ty,
|
||||
data.term.ty(),
|
||||
)));
|
||||
|
||||
err_buf = error;
|
||||
@ -1803,7 +1804,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
ty::PredicateKind::Projection(data) => {
|
||||
let self_ty = data.projection_ty.self_ty();
|
||||
let ty = data.ty;
|
||||
let ty = data.term.ty();
|
||||
if predicate.references_error() || self.is_tainted_by_errors() {
|
||||
return;
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ fn project_and_unify_type<'cx, 'tcx>(
|
||||
let infcx = selcx.infcx();
|
||||
match infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(normalized_ty, obligation.predicate.ty)
|
||||
.eq(normalized_ty, obligation.predicate.term.ty())
|
||||
{
|
||||
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
|
||||
obligations.extend(inferred_obligations);
|
||||
@ -1615,7 +1615,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
|
||||
substs: trait_ref.substs,
|
||||
item_def_id: obligation.predicate.item_def_id,
|
||||
},
|
||||
ty,
|
||||
term: ty.into(),
|
||||
}
|
||||
});
|
||||
|
||||
@ -1641,7 +1641,7 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
||||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
|
||||
ty: self_ty.discriminant_ty(tcx),
|
||||
term: self_ty.discriminant_ty(tcx).into(),
|
||||
};
|
||||
|
||||
// We get here from `poly_project_and_unify_type` which replaces bound vars
|
||||
@ -1674,7 +1674,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
||||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
|
||||
ty: metadata_ty,
|
||||
term: metadata_ty.into(),
|
||||
};
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||
@ -1747,7 +1747,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
|
||||
substs: trait_ref.substs,
|
||||
item_def_id: fn_once_output_def_id,
|
||||
},
|
||||
ty: ret_type,
|
||||
term: ret_type.into(),
|
||||
});
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, predicate, true)
|
||||
@ -1803,7 +1803,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
|
||||
Ok(InferOk { value: _, obligations }) => {
|
||||
nested_obligations.extend(obligations);
|
||||
assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
|
||||
Progress { ty: cache_entry.ty, obligations: nested_obligations }
|
||||
Progress { ty: cache_entry.term.ty(), obligations: nested_obligations }
|
||||
}
|
||||
Err(e) => {
|
||||
let msg = format!(
|
||||
|
@ -62,7 +62,7 @@ pub(crate) fn update<'tcx, T>(
|
||||
if let ty::PredicateKind::Projection(predicate) = obligation.predicate.kind().skip_binder() {
|
||||
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
|
||||
// we need to make it into one.
|
||||
if let Some(vid) = predicate.ty.ty_vid() {
|
||||
if let Some(vid) = predicate.term.ty().ty_vid() {
|
||||
debug!("relationship: {:?}.output = true", vid);
|
||||
engine.relationships().entry(vid).or_default().output = true;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ pub fn predicate_obligations<'a, 'tcx>(
|
||||
}
|
||||
ty::PredicateKind::Projection(t) => {
|
||||
wf.compute_projection(t.projection_ty);
|
||||
wf.compute(t.ty.into());
|
||||
wf.compute(t.term.ty().into());
|
||||
}
|
||||
ty::PredicateKind::WellFormed(arg) => {
|
||||
wf.compute(arg);
|
||||
@ -219,7 +219,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
|
||||
// projection coming from another associated type. See
|
||||
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
|
||||
// `traits-assoc-type-in-supertrait-bad.rs`.
|
||||
if let ty::Projection(projection_ty) = proj.ty.kind() {
|
||||
if let ty::Projection(projection_ty) = proj.term.ty().kind() {
|
||||
if let Some(&impl_item_id) =
|
||||
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_id)
|
||||
{
|
||||
|
@ -227,7 +227,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq<RustInterner<'tcx>>>
|
||||
{
|
||||
fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::AliasEq<RustInterner<'tcx>> {
|
||||
chalk_ir::AliasEq {
|
||||
ty: self.ty.lower_into(interner),
|
||||
ty: self.term.ty().lower_into(interner),
|
||||
alias: self.projection_ty.lower_into(interner),
|
||||
}
|
||||
}
|
||||
@ -787,7 +787,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>
|
||||
trait_bound: trait_ref.lower_into(interner),
|
||||
associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.item_def_id),
|
||||
parameters: own_substs.iter().map(|arg| arg.lower_into(interner)).collect(),
|
||||
value: self.ty.lower_into(interner),
|
||||
value: self.term.ty().lower_into(interner),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,8 +151,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.bindings
|
||||
.iter()
|
||||
.find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
|
||||
(true, hir::TypeBindingKind::Equality { ty }) => {
|
||||
sess.source_map().span_to_snippet(ty.span).ok()
|
||||
(true, hir::TypeBindingKind::Equality { term }) => {
|
||||
let span = match term {
|
||||
hir::Term::Ty(ty) => ty.span,
|
||||
hir::Term::Const(c) => self.tcx().hir().span(c.hir_id),
|
||||
};
|
||||
sess.source_map().span_to_snippet(span).ok()
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
|
@ -602,14 +602,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.iter()
|
||||
.map(|binding| {
|
||||
let kind = match binding.kind {
|
||||
hir::TypeBindingKind::Equality { ty } => {
|
||||
ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty))
|
||||
}
|
||||
hir::TypeBindingKind::Const { ref c } => {
|
||||
let local_did = self.tcx().hir().local_def_id(c.hir_id);
|
||||
let c = Const::from_anon_const(self.tcx(), local_did);
|
||||
ConvertedBindingKind::Const(&c)
|
||||
}
|
||||
hir::TypeBindingKind::Equality { ref term } => match term {
|
||||
hir::Term::Ty(ref ty) => {
|
||||
ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty))
|
||||
}
|
||||
hir::Term::Const(ref c) => {
|
||||
let local_did = self.tcx().hir().local_def_id(c.hir_id);
|
||||
let c = Const::from_anon_const(self.tcx(), local_did);
|
||||
ConvertedBindingKind::Const(&c)
|
||||
}
|
||||
},
|
||||
hir::TypeBindingKind::Constraint { ref bounds } => {
|
||||
ConvertedBindingKind::Constraint(bounds)
|
||||
}
|
||||
@ -1227,21 +1229,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
//
|
||||
// `<T as Iterator>::Item = u32`
|
||||
bounds.projection_bounds.push((
|
||||
projection_ty.map_bound(|projection_ty| {
|
||||
debug!(
|
||||
"add_predicates_for_ast_type_binding: projection_ty {:?}, substs: {:?}",
|
||||
projection_ty, projection_ty.substs
|
||||
);
|
||||
ty::ProjectionPredicate { projection_ty, ty }
|
||||
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
|
||||
projection_ty,
|
||||
term: ty.into(),
|
||||
}),
|
||||
binding.span,
|
||||
));
|
||||
}
|
||||
ConvertedBindingKind::Const(c) => {
|
||||
bounds.const_bounds.push((
|
||||
projection_ty.map_bound(|projection_ty| ty::ConstPredicate {
|
||||
projection: projection_ty,
|
||||
c,
|
||||
bounds.projection_bounds.push((
|
||||
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
|
||||
projection_ty,
|
||||
term: c.into(),
|
||||
}),
|
||||
binding.span,
|
||||
));
|
||||
@ -1393,7 +1392,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// A `Self` within the original bound will be substituted with a
|
||||
// `trait_object_dummy_self`, so check for that.
|
||||
let references_self =
|
||||
pred.skip_binder().ty.walk().any(|arg| arg == dummy_self.into());
|
||||
pred.skip_binder().term.ty().walk().any(|arg| arg == dummy_self.into());
|
||||
|
||||
// If the projection output contains `Self`, force the user to
|
||||
// elaborate it explicitly to avoid a lot of complexity.
|
||||
|
@ -37,12 +37,6 @@ pub struct Bounds<'tcx> {
|
||||
/// here.
|
||||
pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>,
|
||||
|
||||
/// A list of const equality bounds. So if you had `T:
|
||||
/// Iterator<N = 4>` this would include `<T as
|
||||
/// Iterator>::N => 4`. Note that the self-type is explicit
|
||||
/// here.
|
||||
pub const_bounds: Vec<(ty::Binder<'tcx, ty::ConstPredicate<'tcx>>, Span)>,
|
||||
|
||||
/// `Some` if there is *no* `?Sized` predicate. The `span`
|
||||
/// is the location in the source of the `T` declaration which can
|
||||
/// be cited as the source of the `T: Sized` requirement.
|
||||
@ -90,24 +84,7 @@ impl<'tcx> Bounds<'tcx> {
|
||||
.projection_bounds
|
||||
.iter()
|
||||
.map(move |&(projection, span)| (projection.to_predicate(tcx), span));
|
||||
let const_bounds = self.const_bounds.iter().map(move |&(bound, span)| {
|
||||
// FIXME(...): what about the projection's generics?
|
||||
// Is this the right local defid? Or should I get the self ty then
|
||||
let pred = bound
|
||||
.map_bound(|cp| {
|
||||
let got =
|
||||
ty::Const::from_anon_const(tcx, cp.projection.item_def_id.expect_local());
|
||||
ty::PredicateKind::ConstEquate(cp.c, got)
|
||||
})
|
||||
.to_predicate(tcx);
|
||||
(pred, span)
|
||||
});
|
||||
|
||||
sized_predicate
|
||||
.into_iter()
|
||||
.chain(region_preds)
|
||||
.chain(trait_bounds)
|
||||
.chain(projection_bounds)
|
||||
.chain(const_bounds)
|
||||
sized_predicate.into_iter().chain(region_preds).chain(trait_bounds).chain(projection_bounds)
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return None;
|
||||
};
|
||||
|
||||
let ret_param_ty = projection.skip_binder().ty;
|
||||
let ret_param_ty = projection.skip_binder().term.ty();
|
||||
let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty);
|
||||
debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty);
|
||||
|
||||
@ -706,7 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Extract the type from the projection. Note that there can
|
||||
// be no bound variables in this type because the "self type"
|
||||
// does not have any regions in it.
|
||||
let output_ty = self.resolve_vars_if_possible(predicate.ty);
|
||||
let output_ty = self.resolve_vars_if_possible(predicate.term.ty());
|
||||
debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty);
|
||||
Some(output_ty)
|
||||
}
|
||||
|
@ -1360,7 +1360,7 @@ pub fn check_type_bounds<'tcx>(
|
||||
item_def_id: trait_ty.def_id,
|
||||
substs: rebased_substs,
|
||||
},
|
||||
ty: impl_ty_value,
|
||||
term: impl_ty_value.into(),
|
||||
},
|
||||
bound_vars,
|
||||
)
|
||||
|
@ -789,7 +789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
item_def_id: projection_ty.item_def_id,
|
||||
};
|
||||
|
||||
let ty = pred.skip_binder().ty;
|
||||
let ty: Ty<'_> = pred.skip_binder().term.ty();
|
||||
|
||||
let obligation = format!("{} = {}", projection_ty, ty);
|
||||
let quiet = format!("{} = {}", quiet_projection_ty, ty);
|
||||
|
@ -691,7 +691,11 @@ fn bounds_from_generic_predicates<'tcx>(
|
||||
// insert the associated types where they correspond, but for now let's be "lazy" and
|
||||
// propose this instead of the following valid resugaring:
|
||||
// `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
|
||||
where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
|
||||
where_clauses.push(format!(
|
||||
"{} = {}",
|
||||
tcx.def_path_str(p.projection_ty.item_def_id),
|
||||
p.term.ty()
|
||||
));
|
||||
}
|
||||
let where_clauses = if where_clauses.is_empty() {
|
||||
String::new()
|
||||
|
@ -664,7 +664,11 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKind::Type { .. } if param.hir_id == param_id => Some(¶m.bounds),
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. }
|
||||
if param.hir_id == param_id =>
|
||||
{
|
||||
Some(¶m.bounds)
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.flat_map(|bounds| bounds.iter())
|
||||
|
@ -67,11 +67,7 @@ fn opaque_type_bounds<'tcx>(
|
||||
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
|
||||
let preds = bounds.predicates(tcx, item_ty);
|
||||
|
||||
let bounds = tcx.arena.alloc_from_iter(preds);
|
||||
debug!("opaque_type_bounds({}) = {:?}", tcx.def_path_str(opaque_def_id), bounds);
|
||||
bounds
|
||||
tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ pub fn setup_constraining_predicates<'tcx>(
|
||||
if !relies_only_on_inputs {
|
||||
continue;
|
||||
}
|
||||
input_parameters.extend(parameters_for(&projection.ty, false));
|
||||
input_parameters.extend(parameters_for(&projection.term, false));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ fn unconstrained_parent_impl_substs<'tcx>(
|
||||
for (predicate, _) in impl_generic_predicates.predicates.iter() {
|
||||
if let ty::PredicateKind::Projection(proj) = predicate.kind().skip_binder() {
|
||||
let projection_ty = proj.projection_ty;
|
||||
let projected_ty = proj.ty;
|
||||
let projected_ty = proj.term.ty();
|
||||
|
||||
let unbound_trait_ref = projection_ty.trait_ref(tcx);
|
||||
if Some(unbound_trait_ref) == impl_trait_ref {
|
||||
|
@ -354,7 +354,8 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
|
||||
|
||||
impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate {
|
||||
let ty::ProjectionPredicate { projection_ty, ty } = self;
|
||||
let ty::ProjectionPredicate { projection_ty, term } = self;
|
||||
let ty = term.ty();
|
||||
WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) }
|
||||
}
|
||||
}
|
||||
@ -623,8 +624,9 @@ fn clean_ty_generics(
|
||||
.filter(|b| !b.is_sized_bound(cx)),
|
||||
);
|
||||
|
||||
let proj = projection
|
||||
.map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty));
|
||||
let proj = projection.map(|p| {
|
||||
(p.skip_binder().projection_ty.clean(cx), p.skip_binder().term.ty())
|
||||
});
|
||||
if let Some(((_, trait_did, name), rhs)) =
|
||||
proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
|
||||
{
|
||||
@ -1566,7 +1568,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
.ident
|
||||
.name,
|
||||
kind: TypeBindingKind::Equality {
|
||||
ty: proj.ty.clean(cx),
|
||||
ty: proj.term.ty().clean(cx),
|
||||
},
|
||||
})
|
||||
} else {
|
||||
@ -2114,10 +2116,10 @@ impl Clean<TypeBinding> for hir::TypeBinding<'_> {
|
||||
impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind {
|
||||
match *self {
|
||||
hir::TypeBindingKind::Equality { ref ty } => {
|
||||
TypeBindingKind::Equality { ty: ty.clean(cx) }
|
||||
}
|
||||
hir::TypeBindingKind::Const { c: _ } => todo!(),
|
||||
hir::TypeBindingKind::Equality { ref term } => match term {
|
||||
hir::Term::Ty(ref ty) => TypeBindingKind::Equality { ty: ty.clean(cx) },
|
||||
hir::Term::Const(ref _c) => todo!(),
|
||||
},
|
||||
hir::TypeBindingKind::Constraint { ref bounds } => TypeBindingKind::Constraint {
|
||||
bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(),
|
||||
},
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 2abffbf977a9e8c6ca4174a08fe5c4d7781f0aac
|
||||
Subproject commit 6b3dbcc81a470e5da84576d63fcfc19e3b1154cd
|
@ -10,5 +10,10 @@ impl Foo for Bar {
|
||||
const N: usize = 3;
|
||||
}
|
||||
|
||||
const TEST:usize = 3;
|
||||
|
||||
|
||||
fn foo<F: Foo<N=3>>() {}
|
||||
fn bar<F: Foo<N={TEST}>>() {}
|
||||
|
||||
fn main() {}
|
||||
|
@ -7,7 +7,7 @@ struct Bar;
|
||||
const T: usize = 42;
|
||||
|
||||
impl Foo<N = 3> for Bar {
|
||||
//~^ ERROR cannot constrain an associated constant to a value
|
||||
//~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||
//~| ERROR associated type bindings are not allowed here
|
||||
fn do_x(&self) -> [u8; 3] {
|
||||
[0u8; 3]
|
||||
|
@ -1,11 +1,18 @@
|
||||
error: cannot constrain an associated constant to a value
|
||||
--> $DIR/issue-89013-no-kw.rs:9:10
|
||||
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||
--> $DIR/issue-89013-no-kw.rs:9:6
|
||||
|
|
||||
LL | impl Foo<N = 3> for Bar {
|
||||
| -^^^-
|
||||
| | |
|
||||
| | ...cannot be constrained to this value
|
||||
| this associated constant...
|
||||
| ^^^ expected 1 generic argument
|
||||
|
|
||||
note: trait defined here, with 1 generic parameter: `N`
|
||||
--> $DIR/issue-89013-no-kw.rs:1:7
|
||||
|
|
||||
LL | trait Foo<const N: usize> {
|
||||
| ^^^ -
|
||||
help: add missing generic argument
|
||||
|
|
||||
LL | impl Foo<N, N = 3> for Bar {
|
||||
| ++
|
||||
|
||||
error[E0229]: associated type bindings are not allowed here
|
||||
--> $DIR/issue-89013-no-kw.rs:9:10
|
||||
@ -15,4 +22,5 @@ LL | impl Foo<N = 3> for Bar {
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0229`.
|
||||
Some errors have detailed explanations: E0107, E0229.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
@ -8,7 +8,7 @@ const T: usize = 42;
|
||||
|
||||
impl Foo<N = const 3> for Bar {
|
||||
//~^ ERROR expected lifetime, type, or constant, found keyword `const`
|
||||
//~| ERROR cannot constrain an associated constant to a value
|
||||
//~| ERROR this trait takes 1 generic
|
||||
//~| ERROR associated type bindings are not allowed here
|
||||
fn do_x(&self) -> [u8; 3] {
|
||||
[0u8; 3]
|
||||
|
@ -10,14 +10,21 @@ LL - impl Foo<N = const 3> for Bar {
|
||||
LL + impl Foo<N = 3> for Bar {
|
||||
|
|
||||
|
||||
error: cannot constrain an associated constant to a value
|
||||
--> $DIR/issue-89013.rs:9:10
|
||||
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||
--> $DIR/issue-89013.rs:9:6
|
||||
|
|
||||
LL | impl Foo<N = const 3> for Bar {
|
||||
| -^^^^^^^^^-
|
||||
| | |
|
||||
| | ...cannot be constrained to this value
|
||||
| this associated constant...
|
||||
| ^^^ expected 1 generic argument
|
||||
|
|
||||
note: trait defined here, with 1 generic parameter: `N`
|
||||
--> $DIR/issue-89013.rs:1:7
|
||||
|
|
||||
LL | trait Foo<const N: usize> {
|
||||
| ^^^ -
|
||||
help: add missing generic argument
|
||||
|
|
||||
LL | impl Foo<N, N = const 3> for Bar {
|
||||
| ++
|
||||
|
||||
error[E0229]: associated type bindings are not allowed here
|
||||
--> $DIR/issue-89013.rs:9:10
|
||||
@ -27,4 +34,5 @@ LL | impl Foo<N = const 3> for Bar {
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0229`.
|
||||
Some errors have detailed explanations: E0107, E0229.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
@ -1,7 +1,9 @@
|
||||
// run-pass
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn syntax() {
|
||||
bar::<Item = 42>(); //~ ERROR cannot constrain an associated constant to a value
|
||||
bar::<Item = { 42 }>(); //~ ERROR cannot constrain an associated constant to a value
|
||||
bar::<Item = 42>();
|
||||
bar::<Item = { 42 }>();
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,20 +0,0 @@
|
||||
error: cannot constrain an associated constant to a value
|
||||
--> $DIR/recover-assoc-const-constraint.rs:3:11
|
||||
|
|
||||
LL | bar::<Item = 42>();
|
||||
| ----^^^--
|
||||
| | |
|
||||
| | ...cannot be constrained to this value
|
||||
| this associated constant...
|
||||
|
||||
error: cannot constrain an associated constant to a value
|
||||
--> $DIR/recover-assoc-const-constraint.rs:4:11
|
||||
|
|
||||
LL | bar::<Item = { 42 }>();
|
||||
| ----^^^------
|
||||
| | |
|
||||
| | ...cannot be constrained to this value
|
||||
| this associated constant...
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 06b9d31743210b788b130c8a484c2838afa6fc27
|
||||
Subproject commit 358e79fe56fe374649275ca7aebaafd57ade0e8d
|
@ -6,7 +6,7 @@ use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId,
|
||||
Term, AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId,
|
||||
IsAsync, ItemKind, LifetimeName, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
@ -140,7 +140,7 @@ fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'t
|
||||
if args.bindings.len() == 1;
|
||||
let binding = &args.bindings[0];
|
||||
if binding.ident.name == sym::Output;
|
||||
if let TypeBindingKind::Equality{ty: output} = binding.kind;
|
||||
if let TypeBindingKind::Equality{term: Term::Ty(output)} = binding.kind;
|
||||
then {
|
||||
return Some(output)
|
||||
}
|
||||
|
@ -2143,10 +2143,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||
if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
|
||||
// walk the associated type and check for Self
|
||||
if let Some(self_adt) = self_ty.ty_adt_def() {
|
||||
if contains_adt_constructor(projection_predicate.ty, self_adt) {
|
||||
if contains_adt_constructor(projection_predicate.term.ty(), self_adt) {
|
||||
return;
|
||||
}
|
||||
} else if contains_ty(projection_predicate.ty, self_ty) {
|
||||
} else if contains_ty(projection_predicate.term.ty(), self_ty) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ fn check_other_call_arg<'tcx>(
|
||||
if if trait_predicate.def_id() == deref_trait_id {
|
||||
if let [projection_predicate] = projection_predicates[..] {
|
||||
let normalized_ty =
|
||||
cx.tcx.subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.ty);
|
||||
cx.tcx.subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.term.ty());
|
||||
implements_trait(cx, receiver_ty, deref_trait_id, &[])
|
||||
&& get_associated_type(cx, receiver_ty, deref_trait_id, "Target") == Some(normalized_ty)
|
||||
} else {
|
||||
|
@ -98,9 +98,9 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve
|
||||
if trait_pred.self_ty() == inp;
|
||||
if let Some(return_ty_pred) = get_projection_pred(cx, generics, *trait_pred);
|
||||
then {
|
||||
if ord_preds.iter().any(|ord| ord.self_ty() == return_ty_pred.ty) {
|
||||
if ord_preds.iter().any(|ord| ord.self_ty() == return_ty_pred.term.ty()) {
|
||||
args_to_check.push((i, "Ord".to_string()));
|
||||
} else if partial_ord_preds.iter().any(|pord| pord.self_ty() == return_ty_pred.ty) {
|
||||
} else if partial_ord_preds.iter().any(|pord| pord.self_ty() == return_ty_pred.term.ty()) {
|
||||
args_to_check.push((i, "PartialOrd".to_string()));
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 0f8c96c92689af8378dbe9f466c6bf15a3a27458
|
||||
Subproject commit 8e9ccbf97a70259b6c6576e8fd7d77d28238737e
|
Loading…
Reference in New Issue
Block a user