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
51 changed files with 274 additions and 259 deletions
54
Cargo.lock
54
Cargo.lock
|
@ -335,7 +335,7 @@ dependencies = [
|
||||||
"cargo-test-macro",
|
"cargo-test-macro",
|
||||||
"cargo-test-support",
|
"cargo-test-support",
|
||||||
"cargo-util",
|
"cargo-util",
|
||||||
"clap 3.0.6",
|
"clap",
|
||||||
"crates-io",
|
"crates-io",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"curl",
|
"curl",
|
||||||
|
@ -615,28 +615,13 @@ dependencies = [
|
||||||
"ansi_term 0.12.1",
|
"ansi_term 0.12.1",
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"strsim 0.8.0",
|
"strsim",
|
||||||
"textwrap 0.11.0",
|
"textwrap",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"vec_map",
|
"vec_map",
|
||||||
"yaml-rust 0.3.5",
|
"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]]
|
[[package]]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.1.60"
|
version = "0.1.60"
|
||||||
|
@ -669,7 +654,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytecount",
|
"bytecount",
|
||||||
"cargo_metadata 0.14.0",
|
"cargo_metadata 0.14.0",
|
||||||
"clap 2.34.0",
|
"clap",
|
||||||
"indoc",
|
"indoc",
|
||||||
"itertools 0.10.1",
|
"itertools 0.10.1",
|
||||||
"opener",
|
"opener",
|
||||||
|
@ -1751,7 +1736,7 @@ name = "installer"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap 2.34.0",
|
"clap",
|
||||||
"flate2",
|
"flate2",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
@ -2190,7 +2175,7 @@ dependencies = [
|
||||||
"ammonia",
|
"ammonia",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 2.34.0",
|
"clap",
|
||||||
"elasticlunr-rs",
|
"elasticlunr-rs",
|
||||||
"env_logger 0.7.1",
|
"env_logger 0.7.1",
|
||||||
"handlebars",
|
"handlebars",
|
||||||
|
@ -2521,15 +2506,6 @@ dependencies = [
|
||||||
"winapi",
|
"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]]
|
[[package]]
|
||||||
name = "output_vt100"
|
name = "output_vt100"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -2934,7 +2910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0b4b5faaf07040474e8af74a9e19ff167d5d204df5db5c5c765edecfb900358"
|
checksum = "b0b4b5faaf07040474e8af74a9e19ff167d5d204df5db5c5c765edecfb900358"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"clap 2.34.0",
|
"clap",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"env_logger 0.7.1",
|
"env_logger 0.7.1",
|
||||||
"humantime 2.0.1",
|
"humantime 2.0.1",
|
||||||
|
@ -3282,7 +3258,7 @@ dependencies = [
|
||||||
name = "rustbook"
|
name = "rustbook"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.34.0",
|
"clap",
|
||||||
"env_logger 0.7.1",
|
"env_logger 0.7.1",
|
||||||
"mdbook",
|
"mdbook",
|
||||||
]
|
]
|
||||||
|
@ -4898,19 +4874,13 @@ version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strsim"
|
|
||||||
version = "0.10.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "structopt"
|
name = "structopt"
|
||||||
version = "0.3.25"
|
version = "0.3.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
|
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.34.0",
|
"clap",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"structopt-derive",
|
"structopt-derive",
|
||||||
]
|
]
|
||||||
|
@ -5081,12 +5051,6 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "textwrap"
|
|
||||||
version = "0.14.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.30"
|
version = "1.0.30"
|
||||||
|
|
|
@ -997,10 +997,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let kind = match constraint.kind {
|
let kind = match constraint.kind {
|
||||||
AssocConstraintKind::Equality { ref term } => match term {
|
AssocConstraintKind::Equality { ref term } => {
|
||||||
Term::Ty(ref ty) => hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) },
|
let term = match term {
|
||||||
Term::Const(ref c) => hir::TypeBindingKind::Const { c: self.lower_anon_const(c) },
|
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 } => {
|
AssocConstraintKind::Bound { ref bounds } => {
|
||||||
let mut capturable_lifetimes;
|
let mut capturable_lifetimes;
|
||||||
let mut parent_def_id = self.current_hir_id_owner;
|
let mut parent_def_id = self.current_hir_id_owner;
|
||||||
|
@ -1079,7 +1082,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
itctx,
|
itctx,
|
||||||
);
|
);
|
||||||
|
|
||||||
hir::TypeBindingKind::Equality { ty }
|
hir::TypeBindingKind::Equality { term: ty.into() }
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Desugar `AssocTy: Bounds` into a type binding where the
|
// Desugar `AssocTy: Bounds` into a type binding where the
|
||||||
|
|
|
@ -420,7 +420,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
ty: &'hir hir::Ty<'hir>,
|
ty: &'hir hir::Ty<'hir>,
|
||||||
) -> hir::TypeBinding<'hir> {
|
) -> hir::TypeBinding<'hir> {
|
||||||
let ident = Ident::with_dummy_span(hir::FN_OUTPUT_NAME);
|
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 args = arena_vec![self;];
|
||||||
let bindings = arena_vec![self;];
|
let bindings = arena_vec![self;];
|
||||||
let gen_args = self.arena.alloc(hir::GenericArgs {
|
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),
|
Term::Const(c) => self.print_expr_anon_const(c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::AssocConstraintKind::Bound { bounds } => {
|
ast::AssocConstraintKind::Bound { bounds } => self.print_type_bounds(":", &*bounds),
|
||||||
self.print_type_bounds(":", &*bounds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -779,7 +779,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
[
|
[
|
||||||
hir::TypeBinding {
|
hir::TypeBinding {
|
||||||
ident: Ident { name: sym::Output, .. },
|
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),
|
GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err),
|
||||||
_ => false,
|
_ => false,
|
||||||
}) || self.bindings.iter().any(|arg| match arg.kind {
|
}) || 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,
|
_ => false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2129,21 +2129,37 @@ pub struct TypeBinding<'hir> {
|
||||||
pub span: Span,
|
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.
|
// Represents the two kinds of type bindings.
|
||||||
#[derive(Debug, HashStable_Generic)]
|
#[derive(Debug, HashStable_Generic)]
|
||||||
pub enum TypeBindingKind<'hir> {
|
pub enum TypeBindingKind<'hir> {
|
||||||
/// E.g., `Foo<Bar: Send>`.
|
/// E.g., `Foo<Bar: Send>`.
|
||||||
Constraint { bounds: &'hir [GenericBound<'hir>] },
|
Constraint { bounds: &'hir [GenericBound<'hir>] },
|
||||||
/// E.g., `Foo<Bar = ()>`.
|
/// E.g., `Foo<Bar = ()>`, `Foo<Bar = ()>`
|
||||||
Equality { ty: &'hir Ty<'hir> },
|
Equality { term: Term<'hir> },
|
||||||
/// E.g., `Foo<N = 3>`.
|
|
||||||
Const { c: AnonConst },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeBinding<'_> {
|
impl TypeBinding<'_> {
|
||||||
pub fn ty(&self) -> &Ty<'_> {
|
pub fn ty(&self) -> &Ty<'_> {
|
||||||
match self.kind {
|
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"),
|
_ => 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_ident(type_binding.ident);
|
||||||
visitor.visit_generic_args(type_binding.span, type_binding.gen_args);
|
visitor.visit_generic_args(type_binding.span, type_binding.gen_args);
|
||||||
match type_binding.kind {
|
match type_binding.kind {
|
||||||
TypeBindingKind::Equality { ref ty } => visitor.visit_ty(ty),
|
TypeBindingKind::Equality { ref term } => match term {
|
||||||
TypeBindingKind::Const { ref c } => visitor.visit_anon_const(c),
|
Term::Ty(ref ty) => visitor.visit_ty(ty),
|
||||||
TypeBindingKind::Constraint { bounds } => {
|
Term::Const(ref c) => visitor.visit_anon_const(c),
|
||||||
walk_list!(visitor, visit_param_bound, bounds);
|
},
|
||||||
}
|
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::pp::{self, Breaks};
|
||||||
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
||||||
use rustc_hir as hir;
|
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_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
|
||||||
use rustc_span::source_map::{SourceMap, Spanned};
|
use rustc_span::source_map::{SourceMap, Spanned};
|
||||||
use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
|
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.print_generic_args(binding.gen_args, false, false);
|
||||||
self.space();
|
self.space();
|
||||||
match generic_args.bindings[0].kind {
|
match generic_args.bindings[0].kind {
|
||||||
hir::TypeBindingKind::Equality { ref ty } => {
|
hir::TypeBindingKind::Equality { ref term } => {
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
self.print_type(ty);
|
match term {
|
||||||
}
|
Term::Ty(ref ty) => self.print_type(ty),
|
||||||
hir::TypeBindingKind::Const { ref c } => {
|
Term::Const(ref c) => self.print_anon_const(c),
|
||||||
self.word_space("=");
|
}
|
||||||
self.print_anon_const(c);
|
|
||||||
}
|
}
|
||||||
hir::TypeBindingKind::Constraint { bounds } => {
|
hir::TypeBindingKind::Constraint { bounds } => {
|
||||||
self.print_bounds(":", bounds);
|
self.print_bounds(":", bounds);
|
||||||
|
|
|
@ -69,7 +69,7 @@ use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self,
|
self,
|
||||||
subst::{GenericArgKind, Subst, SubstsRef},
|
subst::{GenericArgKind, Subst, SubstsRef},
|
||||||
Region, Ty, TyCtxt, TypeFoldable,
|
Region, Term, Ty, TyCtxt, TypeFoldable,
|
||||||
};
|
};
|
||||||
use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
|
use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
|
||||||
use rustc_target::spec::abi;
|
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 {
|
if projection_predicate.projection_ty.item_def_id == item_def_id {
|
||||||
// We don't account for multiple `Future::Output = Ty` contraints.
|
// 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() {
|
for type_binding in generic_args.bindings.iter() {
|
||||||
if type_binding.ident.name == rustc_span::sym::Output {
|
if type_binding.ident.name == rustc_span::sym::Output {
|
||||||
if let hir::TypeBindingKind::Equality { ty } =
|
if let hir::TypeBindingKind::Equality {
|
||||||
type_binding.kind
|
term: hir::Term::Ty(ty),
|
||||||
|
} = type_binding.kind
|
||||||
{
|
{
|
||||||
return Some(ty);
|
return Some(ty);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_middle::ty::fold::BottomUpFolder;
|
use rustc_middle::ty::fold::BottomUpFolder;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, Subst};
|
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 rustc_span::Span;
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
@ -584,9 +584,13 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||||
debug!(?predicate);
|
debug!(?predicate);
|
||||||
|
|
||||||
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
|
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
|
||||||
if projection.ty.references_error() {
|
if let Term::Ty(ty) = projection.term {
|
||||||
// No point on adding these obligations since there's a type error involved.
|
if ty.references_error() {
|
||||||
return tcx.ty_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,
|
kind: TypeVariableOriginKind::NormalizeProjectionType,
|
||||||
span: self.tcx.def_span(def_id),
|
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(
|
let obligation = Obligation::with_depth(
|
||||||
cause,
|
cause,
|
||||||
recursion_depth,
|
recursion_depth,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::ty::subst::{GenericArg, GenericArgKind};
|
use crate::ty::subst::{GenericArg, GenericArgKind};
|
||||||
use crate::ty::{self, InferConst, Ty, TypeFlags};
|
use crate::ty::{self, InferConst, Term, Ty, TypeFlags};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -241,9 +241,12 @@ impl FlagComputation {
|
||||||
self.add_ty(a);
|
self.add_ty(a);
|
||||||
self.add_ty(b);
|
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_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) => {
|
ty::PredicateKind::WellFormed(arg) => {
|
||||||
self.add_substs(slice::from_ref(&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"))]
|
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||||
static_assert_size!(PredicateInner<'_>, 48);
|
static_assert_size!(PredicateInner<'_>, 56);
|
||||||
|
|
||||||
#[derive(Clone, Copy, Lift)]
|
#[derive(Clone, Copy, Lift)]
|
||||||
pub struct Predicate<'tcx> {
|
pub struct Predicate<'tcx> {
|
||||||
|
@ -795,11 +795,35 @@ pub struct CoercePredicate<'tcx> {
|
||||||
}
|
}
|
||||||
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, 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
|
/// This kind of predicate has no *direct* correspondent in the
|
||||||
/// syntax, but it roughly corresponds to the syntactic forms:
|
/// syntax, but it roughly corresponds to the syntactic forms:
|
||||||
///
|
///
|
||||||
/// 1. `T: TraitRef<..., Item = Type>`
|
/// 1. `T: TraitRef<..., Item = Type>`
|
||||||
/// - Or `T: TraitRef<..., Item = Const>`
|
|
||||||
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
|
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
|
||||||
///
|
///
|
||||||
/// In particular, form #1 is "desugared" to the combination of a
|
/// 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)]
|
#[derive(HashStable, TypeFoldable)]
|
||||||
pub struct ProjectionPredicate<'tcx> {
|
pub struct ProjectionPredicate<'tcx> {
|
||||||
pub projection_ty: ProjectionTy<'tcx>,
|
pub projection_ty: ProjectionTy<'tcx>,
|
||||||
pub ty: Ty<'tcx>,
|
pub term: Term<'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 type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'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>> {
|
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.
|
/// The `DefId` of the `TraitItem` for the associated type.
|
||||||
|
|
|
@ -2499,7 +2499,14 @@ define_print_and_forward_display! {
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ProjectionPredicate<'tcx> {
|
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> {
|
ty::ProjectionTy<'tcx> {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar};
|
use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar};
|
||||||
use crate::ty::error::{ExpectedFound, TypeError};
|
use crate::ty::error::{ExpectedFound, TypeError};
|
||||||
use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
|
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 as ast;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
|
@ -839,10 +839,13 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
|
||||||
a: ty::ProjectionPredicate<'tcx>,
|
a: ty::ProjectionPredicate<'tcx>,
|
||||||
b: ty::ProjectionPredicate<'tcx>,
|
b: ty::ProjectionPredicate<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
|
) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
|
||||||
Ok(ty::ProjectionPredicate {
|
match (a.term, b.term) {
|
||||||
projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
|
(Term::Ty(a_ty), Term::Ty(b_ty)) => Ok(ty::ProjectionPredicate {
|
||||||
ty: relation.relate(a.ty, b.ty)?,
|
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::mir::ProjectionKind;
|
||||||
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor};
|
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor};
|
||||||
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
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_data_structures::functor::IdFunctor;
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
use rustc_hir::def_id::CRATE_DEF_INDEX;
|
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> {
|
impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
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> {
|
impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
|
||||||
type Lifted = ty::TraitPredicate<'tcx>;
|
type Lifted = ty::TraitPredicate<'tcx>;
|
||||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<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> {
|
impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
|
||||||
type Lifted = ty::ProjectionPredicate<'tcx>;
|
type Lifted = ty::ProjectionPredicate<'tcx>;
|
||||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
|
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
|
||||||
tcx.lift((self.projection_ty, self.ty))
|
tcx.lift((self.projection_ty, self.term))
|
||||||
.map(|(projection_ty, ty)| ty::ProjectionPredicate { projection_ty, ty })
|
.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::fold::ValidateBoundVars;
|
||||||
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
|
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
|
||||||
use crate::ty::InferTy::{self, *};
|
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 crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
|
||||||
use polonius_engine::Atom;
|
use polonius_engine::Atom;
|
||||||
use rustc_data_structures::captures::Captures;
|
use rustc_data_structures::captures::Captures;
|
||||||
|
@ -1570,7 +1570,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
|
||||||
item_def_id: self.item_def_id,
|
item_def_id: self.item_def_id,
|
||||||
substs: tcx.mk_substs_trait(self_ty, self.substs),
|
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 {
|
) -> Self {
|
||||||
// Assert there is a Self.
|
// Assert there is a Self.
|
||||||
projection_predicate.projection_ty.substs.type_at(0);
|
projection_predicate.projection_ty.substs.type_at(0);
|
||||||
|
let ty = if let Term::Ty(ty) = projection_predicate.term {
|
||||||
|
ty
|
||||||
|
} else {
|
||||||
|
todo!();
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
item_def_id: projection_predicate.projection_ty.item_def_id,
|
item_def_id: projection_predicate.projection_ty.item_def_id,
|
||||||
substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
|
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> {
|
) -> PResult<'a, AssocConstraintKind> {
|
||||||
let arg = self.parse_generic_arg(None)?;
|
let arg = self.parse_generic_arg(None)?;
|
||||||
let span = ident.span.to(self.prev_token.span);
|
let span = ident.span.to(self.prev_token.span);
|
||||||
let ty = match arg {
|
let term = match arg {
|
||||||
Some(GenericArg::Type(ty)) => ty,
|
Some(GenericArg::Type(ty)) => ty.into(),
|
||||||
Some(GenericArg::Const(c)) => {
|
Some(GenericArg::Const(c)) => c.into(),
|
||||||
return Ok(AssocConstraintKind::Equality { term: c.into() });
|
|
||||||
}
|
|
||||||
Some(GenericArg::Lifetime(lt)) => {
|
Some(GenericArg::Lifetime(lt)) => {
|
||||||
self.struct_span_err(span, "associated lifetimes are not supported")
|
self.struct_span_err(span, "associated lifetimes are not supported")
|
||||||
.span_label(lt.ident.span, "the lifetime is given here")
|
.span_label(lt.ident.span, "the lifetime is given here")
|
||||||
.help("if you meant to specify a trait object, write `dyn Trait + 'lifetime`")
|
.help("if you meant to specify a trait object, write `dyn Trait + 'lifetime`")
|
||||||
.emit();
|
.emit();
|
||||||
self.mk_ty(span, ast::TyKind::Err)
|
self.mk_ty(span, ast::TyKind::Err).into()
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let after_eq = eq.shrink_to_hi();
|
let after_eq = eq.shrink_to_hi();
|
||||||
|
@ -542,7 +540,7 @@ impl<'a> Parser<'a> {
|
||||||
return Err(err);
|
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:
|
/// We do not permit arbitrary expressions as const arguments. They must be one of:
|
||||||
|
|
|
@ -127,7 +127,8 @@ where
|
||||||
constness: _,
|
constness: _,
|
||||||
polarity: _,
|
polarity: _,
|
||||||
}) => self.visit_trait(trait_ref),
|
}) => 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)?;
|
ty.visit_with(self)?;
|
||||||
self.visit_projection_ty(projection_ty)
|
self.visit_projection_ty(projection_ty)
|
||||||
}
|
}
|
||||||
|
@ -1185,7 +1186,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (poly_predicate, _) in bounds.projection_bounds {
|
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
|
|| self
|
||||||
.visit_projection_ty(poly_predicate.skip_binder().projection_ty)
|
.visit_projection_ty(poly_predicate.skip_binder().projection_ty)
|
||||||
.is_break()
|
.is_break()
|
||||||
|
|
|
@ -1304,7 +1304,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"report_projection_error normalized_ty={:?} data.ty={:?}",
|
"report_projection_error normalized_ty={:?} data.ty={:?}",
|
||||||
normalized_ty, data.ty
|
normalized_ty,
|
||||||
|
data.term.ty()
|
||||||
);
|
);
|
||||||
|
|
||||||
let is_normalized_ty_expected = !matches!(
|
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(
|
if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
|
||||||
is_normalized_ty_expected,
|
is_normalized_ty_expected,
|
||||||
normalized_ty,
|
normalized_ty,
|
||||||
data.ty,
|
data.term.ty(),
|
||||||
) {
|
) {
|
||||||
values = Some(infer::ValuePairs::Types(ExpectedFound::new(
|
values = Some(infer::ValuePairs::Types(ExpectedFound::new(
|
||||||
is_normalized_ty_expected,
|
is_normalized_ty_expected,
|
||||||
normalized_ty,
|
normalized_ty,
|
||||||
data.ty,
|
data.term.ty(),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
err_buf = error;
|
err_buf = error;
|
||||||
|
@ -1803,7 +1804,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Projection(data) => {
|
ty::PredicateKind::Projection(data) => {
|
||||||
let self_ty = data.projection_ty.self_ty();
|
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() {
|
if predicate.references_error() || self.is_tainted_by_errors() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ fn project_and_unify_type<'cx, 'tcx>(
|
||||||
let infcx = selcx.infcx();
|
let infcx = selcx.infcx();
|
||||||
match infcx
|
match infcx
|
||||||
.at(&obligation.cause, obligation.param_env)
|
.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: () }) => {
|
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
|
||||||
obligations.extend(inferred_obligations);
|
obligations.extend(inferred_obligations);
|
||||||
|
@ -1615,7 +1615,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
|
||||||
substs: trait_ref.substs,
|
substs: trait_ref.substs,
|
||||||
item_def_id: obligation.predicate.item_def_id,
|
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 {
|
let predicate = ty::ProjectionPredicate {
|
||||||
projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
|
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
|
// 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 {
|
let predicate = ty::ProjectionPredicate {
|
||||||
projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
|
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)
|
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,
|
substs: trait_ref.substs,
|
||||||
item_def_id: fn_once_output_def_id,
|
item_def_id: fn_once_output_def_id,
|
||||||
},
|
},
|
||||||
ty: ret_type,
|
term: ret_type.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
confirm_param_env_candidate(selcx, obligation, predicate, true)
|
confirm_param_env_candidate(selcx, obligation, predicate, true)
|
||||||
|
@ -1803,7 +1803,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
|
||||||
Ok(InferOk { value: _, obligations }) => {
|
Ok(InferOk { value: _, obligations }) => {
|
||||||
nested_obligations.extend(obligations);
|
nested_obligations.extend(obligations);
|
||||||
assoc_ty_own_obligations(selcx, obligation, &mut nested_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) => {
|
Err(e) => {
|
||||||
let msg = format!(
|
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 let ty::PredicateKind::Projection(predicate) = obligation.predicate.kind().skip_binder() {
|
||||||
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
|
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
|
||||||
// we need to make it into one.
|
// 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);
|
debug!("relationship: {:?}.output = true", vid);
|
||||||
engine.relationships().entry(vid).or_default().output = true;
|
engine.relationships().entry(vid).or_default().output = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ pub fn predicate_obligations<'a, 'tcx>(
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Projection(t) => {
|
ty::PredicateKind::Projection(t) => {
|
||||||
wf.compute_projection(t.projection_ty);
|
wf.compute_projection(t.projection_ty);
|
||||||
wf.compute(t.ty.into());
|
wf.compute(t.term.ty().into());
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::WellFormed(arg) => {
|
||||||
wf.compute(arg);
|
wf.compute(arg);
|
||||||
|
@ -219,7 +219,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
|
||||||
// projection coming from another associated type. See
|
// projection coming from another associated type. See
|
||||||
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
|
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
|
||||||
// `traits-assoc-type-in-supertrait-bad.rs`.
|
// `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) =
|
if let Some(&impl_item_id) =
|
||||||
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_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>> {
|
fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::AliasEq<RustInterner<'tcx>> {
|
||||||
chalk_ir::AliasEq {
|
chalk_ir::AliasEq {
|
||||||
ty: self.ty.lower_into(interner),
|
ty: self.term.ty().lower_into(interner),
|
||||||
alias: self.projection_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),
|
trait_bound: trait_ref.lower_into(interner),
|
||||||
associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.item_def_id),
|
associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.item_def_id),
|
||||||
parameters: own_substs.iter().map(|arg| arg.lower_into(interner)).collect(),
|
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
|
.bindings
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
|
.find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
|
||||||
(true, hir::TypeBindingKind::Equality { ty }) => {
|
(true, hir::TypeBindingKind::Equality { term }) => {
|
||||||
sess.source_map().span_to_snippet(ty.span).ok()
|
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,
|
_ => None,
|
||||||
})
|
})
|
||||||
|
|
|
@ -602,14 +602,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|binding| {
|
.map(|binding| {
|
||||||
let kind = match binding.kind {
|
let kind = match binding.kind {
|
||||||
hir::TypeBindingKind::Equality { ty } => {
|
hir::TypeBindingKind::Equality { ref term } => match term {
|
||||||
ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty))
|
hir::Term::Ty(ref 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);
|
hir::Term::Const(ref c) => {
|
||||||
let c = Const::from_anon_const(self.tcx(), local_did);
|
let local_did = self.tcx().hir().local_def_id(c.hir_id);
|
||||||
ConvertedBindingKind::Const(&c)
|
let c = Const::from_anon_const(self.tcx(), local_did);
|
||||||
}
|
ConvertedBindingKind::Const(&c)
|
||||||
|
}
|
||||||
|
},
|
||||||
hir::TypeBindingKind::Constraint { ref bounds } => {
|
hir::TypeBindingKind::Constraint { ref bounds } => {
|
||||||
ConvertedBindingKind::Constraint(bounds)
|
ConvertedBindingKind::Constraint(bounds)
|
||||||
}
|
}
|
||||||
|
@ -1227,21 +1229,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
//
|
//
|
||||||
// `<T as Iterator>::Item = u32`
|
// `<T as Iterator>::Item = u32`
|
||||||
bounds.projection_bounds.push((
|
bounds.projection_bounds.push((
|
||||||
projection_ty.map_bound(|projection_ty| {
|
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
|
||||||
debug!(
|
projection_ty,
|
||||||
"add_predicates_for_ast_type_binding: projection_ty {:?}, substs: {:?}",
|
term: ty.into(),
|
||||||
projection_ty, projection_ty.substs
|
|
||||||
);
|
|
||||||
ty::ProjectionPredicate { projection_ty, ty }
|
|
||||||
}),
|
}),
|
||||||
binding.span,
|
binding.span,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
ConvertedBindingKind::Const(c) => {
|
ConvertedBindingKind::Const(c) => {
|
||||||
bounds.const_bounds.push((
|
bounds.projection_bounds.push((
|
||||||
projection_ty.map_bound(|projection_ty| ty::ConstPredicate {
|
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
|
||||||
projection: projection_ty,
|
projection_ty,
|
||||||
c,
|
term: c.into(),
|
||||||
}),
|
}),
|
||||||
binding.span,
|
binding.span,
|
||||||
));
|
));
|
||||||
|
@ -1393,7 +1392,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// A `Self` within the original bound will be substituted with a
|
// A `Self` within the original bound will be substituted with a
|
||||||
// `trait_object_dummy_self`, so check for that.
|
// `trait_object_dummy_self`, so check for that.
|
||||||
let references_self =
|
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
|
// If the projection output contains `Self`, force the user to
|
||||||
// elaborate it explicitly to avoid a lot of complexity.
|
// elaborate it explicitly to avoid a lot of complexity.
|
||||||
|
|
|
@ -37,12 +37,6 @@ pub struct Bounds<'tcx> {
|
||||||
/// here.
|
/// here.
|
||||||
pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>,
|
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`
|
/// `Some` if there is *no* `?Sized` predicate. The `span`
|
||||||
/// is the location in the source of the `T` declaration which can
|
/// is the location in the source of the `T` declaration which can
|
||||||
/// be cited as the source of the `T: Sized` requirement.
|
/// be cited as the source of the `T: Sized` requirement.
|
||||||
|
@ -90,24 +84,7 @@ impl<'tcx> Bounds<'tcx> {
|
||||||
.projection_bounds
|
.projection_bounds
|
||||||
.iter()
|
.iter()
|
||||||
.map(move |&(projection, span)| (projection.to_predicate(tcx), span));
|
.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
|
sized_predicate.into_iter().chain(region_preds).chain(trait_bounds).chain(projection_bounds)
|
||||||
.into_iter()
|
|
||||||
.chain(region_preds)
|
|
||||||
.chain(trait_bounds)
|
|
||||||
.chain(projection_bounds)
|
|
||||||
.chain(const_bounds)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
return None;
|
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);
|
let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty);
|
||||||
debug!("deduce_sig_from_projection: ret_param_ty={:?}", 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
|
// Extract the type from the projection. Note that there can
|
||||||
// be no bound variables in this type because the "self type"
|
// be no bound variables in this type because the "self type"
|
||||||
// does not have any regions in it.
|
// 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);
|
debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty);
|
||||||
Some(output_ty)
|
Some(output_ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1360,7 +1360,7 @@ pub fn check_type_bounds<'tcx>(
|
||||||
item_def_id: trait_ty.def_id,
|
item_def_id: trait_ty.def_id,
|
||||||
substs: rebased_substs,
|
substs: rebased_substs,
|
||||||
},
|
},
|
||||||
ty: impl_ty_value,
|
term: impl_ty_value.into(),
|
||||||
},
|
},
|
||||||
bound_vars,
|
bound_vars,
|
||||||
)
|
)
|
||||||
|
|
|
@ -789,7 +789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
item_def_id: projection_ty.item_def_id,
|
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 obligation = format!("{} = {}", projection_ty, ty);
|
||||||
let quiet = format!("{} = {}", quiet_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
|
// insert the associated types where they correspond, but for now let's be "lazy" and
|
||||||
// propose this instead of the following valid resugaring:
|
// propose this instead of the following valid resugaring:
|
||||||
// `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
|
// `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() {
|
let where_clauses = if where_clauses.is_empty() {
|
||||||
String::new()
|
String::new()
|
||||||
|
|
|
@ -664,7 +664,11 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|param| match param.kind {
|
.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,
|
_ => None,
|
||||||
})
|
})
|
||||||
.flat_map(|bounds| bounds.iter())
|
.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);
|
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
||||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||||
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
|
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
|
||||||
let preds = bounds.predicates(tcx, item_ty);
|
tcx.arena.alloc_from_iter(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
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ pub fn setup_constraining_predicates<'tcx>(
|
||||||
if !relies_only_on_inputs {
|
if !relies_only_on_inputs {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
input_parameters.extend(parameters_for(&projection.ty, false));
|
input_parameters.extend(parameters_for(&projection.term, false));
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ fn unconstrained_parent_impl_substs<'tcx>(
|
||||||
for (predicate, _) in impl_generic_predicates.predicates.iter() {
|
for (predicate, _) in impl_generic_predicates.predicates.iter() {
|
||||||
if let ty::PredicateKind::Projection(proj) = predicate.kind().skip_binder() {
|
if let ty::PredicateKind::Projection(proj) = predicate.kind().skip_binder() {
|
||||||
let projection_ty = proj.projection_ty;
|
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);
|
let unbound_trait_ref = projection_ty.trait_ref(tcx);
|
||||||
if Some(unbound_trait_ref) == impl_trait_ref {
|
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> {
|
impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
|
||||||
fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate {
|
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) }
|
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)),
|
.filter(|b| !b.is_sized_bound(cx)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let proj = projection
|
let proj = projection.map(|p| {
|
||||||
.map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty));
|
(p.skip_binder().projection_ty.clean(cx), p.skip_binder().term.ty())
|
||||||
|
});
|
||||||
if let Some(((_, trait_did, name), rhs)) =
|
if let Some(((_, trait_did, name), rhs)) =
|
||||||
proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
|
proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
|
||||||
{
|
{
|
||||||
|
@ -1566,7 +1568,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||||
.ident
|
.ident
|
||||||
.name,
|
.name,
|
||||||
kind: TypeBindingKind::Equality {
|
kind: TypeBindingKind::Equality {
|
||||||
ty: proj.ty.clean(cx),
|
ty: proj.term.ty().clean(cx),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -2114,10 +2116,10 @@ impl Clean<TypeBinding> for hir::TypeBinding<'_> {
|
||||||
impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> {
|
impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> {
|
||||||
fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind {
|
fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind {
|
||||||
match *self {
|
match *self {
|
||||||
hir::TypeBindingKind::Equality { ref ty } => {
|
hir::TypeBindingKind::Equality { ref term } => match term {
|
||||||
TypeBindingKind::Equality { ty: ty.clean(cx) }
|
hir::Term::Ty(ref ty) => TypeBindingKind::Equality { ty: ty.clean(cx) },
|
||||||
}
|
hir::Term::Const(ref _c) => todo!(),
|
||||||
hir::TypeBindingKind::Const { c: _ } => todo!(),
|
},
|
||||||
hir::TypeBindingKind::Constraint { ref bounds } => TypeBindingKind::Constraint {
|
hir::TypeBindingKind::Constraint { ref bounds } => TypeBindingKind::Constraint {
|
||||||
bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(),
|
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 N: usize = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TEST:usize = 3;
|
||||||
|
|
||||||
|
|
||||||
fn foo<F: Foo<N=3>>() {}
|
fn foo<F: Foo<N=3>>() {}
|
||||||
|
fn bar<F: Foo<N={TEST}>>() {}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -7,7 +7,7 @@ struct Bar;
|
||||||
const T: usize = 42;
|
const T: usize = 42;
|
||||||
|
|
||||||
impl Foo<N = 3> for Bar {
|
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
|
//~| ERROR associated type bindings are not allowed here
|
||||||
fn do_x(&self) -> [u8; 3] {
|
fn do_x(&self) -> [u8; 3] {
|
||||||
[0u8; 3]
|
[0u8; 3]
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
error: cannot constrain an associated constant to a value
|
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||||
--> $DIR/issue-89013-no-kw.rs:9:10
|
--> $DIR/issue-89013-no-kw.rs:9:6
|
||||||
|
|
|
|
||||||
LL | impl Foo<N = 3> for Bar {
|
LL | impl Foo<N = 3> for Bar {
|
||||||
| -^^^-
|
| ^^^ expected 1 generic argument
|
||||||
| | |
|
|
|
||||||
| | ...cannot be constrained to this value
|
note: trait defined here, with 1 generic parameter: `N`
|
||||||
| this associated constant...
|
--> $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
|
error[E0229]: associated type bindings are not allowed here
|
||||||
--> $DIR/issue-89013-no-kw.rs:9:10
|
--> $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
|
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 {
|
impl Foo<N = const 3> for Bar {
|
||||||
//~^ ERROR expected lifetime, type, or constant, found keyword `const`
|
//~^ 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
|
//~| ERROR associated type bindings are not allowed here
|
||||||
fn do_x(&self) -> [u8; 3] {
|
fn do_x(&self) -> [u8; 3] {
|
||||||
[0u8; 3]
|
[0u8; 3]
|
||||||
|
|
|
@ -10,14 +10,21 @@ LL - impl Foo<N = const 3> for Bar {
|
||||||
LL + impl Foo<N = 3> for Bar {
|
LL + impl Foo<N = 3> for Bar {
|
||||||
|
|
|
|
||||||
|
|
||||||
error: cannot constrain an associated constant to a value
|
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||||
--> $DIR/issue-89013.rs:9:10
|
--> $DIR/issue-89013.rs:9:6
|
||||||
|
|
|
|
||||||
LL | impl Foo<N = const 3> for Bar {
|
LL | impl Foo<N = const 3> for Bar {
|
||||||
| -^^^^^^^^^-
|
| ^^^ expected 1 generic argument
|
||||||
| | |
|
|
|
||||||
| | ...cannot be constrained to this value
|
note: trait defined here, with 1 generic parameter: `N`
|
||||||
| this associated constant...
|
--> $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
|
error[E0229]: associated type bindings are not allowed here
|
||||||
--> $DIR/issue-89013.rs:9:10
|
--> $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
|
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)]
|
#[cfg(FALSE)]
|
||||||
fn syntax() {
|
fn syntax() {
|
||||||
bar::<Item = 42>(); //~ ERROR cannot constrain an associated constant to a value
|
bar::<Item = 42>();
|
||||||
bar::<Item = { 42 }>(); //~ ERROR cannot constrain an associated constant to a value
|
bar::<Item = { 42 }>();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
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_errors::Applicability;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{
|
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,
|
IsAsync, ItemKind, LifetimeName, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
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;
|
if args.bindings.len() == 1;
|
||||||
let binding = &args.bindings[0];
|
let binding = &args.bindings[0];
|
||||||
if binding.ident.name == sym::Output;
|
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 {
|
then {
|
||||||
return Some(output)
|
return Some(output)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2143,10 +2143,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||||
if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
|
if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
|
||||||
// walk the associated type and check for Self
|
// walk the associated type and check for Self
|
||||||
if let Some(self_adt) = self_ty.ty_adt_def() {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
} else if contains_ty(projection_predicate.ty, self_ty) {
|
} else if contains_ty(projection_predicate.term.ty(), self_ty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,7 @@ fn check_other_call_arg<'tcx>(
|
||||||
if if trait_predicate.def_id() == deref_trait_id {
|
if if trait_predicate.def_id() == deref_trait_id {
|
||||||
if let [projection_predicate] = projection_predicates[..] {
|
if let [projection_predicate] = projection_predicates[..] {
|
||||||
let normalized_ty =
|
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, &[])
|
implements_trait(cx, receiver_ty, deref_trait_id, &[])
|
||||||
&& get_associated_type(cx, receiver_ty, deref_trait_id, "Target") == Some(normalized_ty)
|
&& get_associated_type(cx, receiver_ty, deref_trait_id, "Target") == Some(normalized_ty)
|
||||||
} else {
|
} 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 trait_pred.self_ty() == inp;
|
||||||
if let Some(return_ty_pred) = get_projection_pred(cx, generics, *trait_pred);
|
if let Some(return_ty_pred) = get_projection_pred(cx, generics, *trait_pred);
|
||||||
then {
|
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()));
|
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()));
|
args_to_check.push((i, "PartialOrd".to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0f8c96c92689af8378dbe9f466c6bf15a3a27458
|
Subproject commit 8e9ccbf97a70259b6c6576e8fd7d77d28238737e
|
Loading…
Add table
Add a link
Reference in a new issue