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.
"cargo-test-macro",
"cargo-test-support",
"cargo-util",
- "clap 3.0.6",
+ "clap",
"crates-io",
"crossbeam-utils",
"curl",
"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"
dependencies = [
"bytecount",
"cargo_metadata 0.14.0",
- "clap 2.34.0",
+ "clap",
"indoc",
"itertools 0.10.1",
"opener",
version = "0.0.0"
dependencies = [
"anyhow",
- "clap 2.34.0",
+ "clap",
"flate2",
"lazy_static",
"num_cpus",
"ammonia",
"anyhow",
"chrono",
- "clap 2.34.0",
+ "clap",
"elasticlunr-rs",
"env_logger 0.7.1",
"handlebars",
"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"
checksum = "b0b4b5faaf07040474e8af74a9e19ff167d5d204df5db5c5c765edecfb900358"
dependencies = [
"bitflags",
- "clap 2.34.0",
+ "clap",
"derive_more",
"env_logger 0.7.1",
"humantime 2.0.1",
name = "rustbook"
version = "0.1.0"
dependencies = [
- "clap 2.34.0",
+ "clap",
"env_logger 0.7.1",
"mdbook",
]
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",
]
"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"
};
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;
itctx,
);
- hir::TypeBindingKind::Equality { ty }
+ hir::TypeBindingKind::Equality { term: ty.into() }
})
} else {
// Desugar `AssocTy: Bounds` into a type binding where the
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 {
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),
}
}
[
hir::TypeBinding {
ident: Ident { name: sym::Output, .. },
- kind: hir::TypeBindingKind::Equality { ty },
+ kind:
+ hir::TypeBindingKind::Equality {
+ term: hir::Term::Ty(ty),
+ },
..
},
],
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,
})
}
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"),
}
}
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),
}
}
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};
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);
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;
{
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!(),
+ }
}
}
}
{
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);
}
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;
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!();
}
}
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,
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)]
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));
}
#[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> {
}
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
#[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>>;
}
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.
}
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> {
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;
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!(),
+ }
}
}
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;
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)
}
}
}
}
+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>> {
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 })
}
}
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;
item_def_id: self.item_def_id,
substs: tcx.mk_substs_trait(self_ty, self.substs),
},
- ty: self.ty,
+ term: self.ty.into(),
}
}
) -> 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,
}
}
}
) -> 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();
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:
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)
}
}
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()
debug!(
"report_projection_error normalized_ty={:?} data.ty={:?}",
- normalized_ty, data.ty
+ normalized_ty,
+ data.term.ty()
);
let is_normalized_ty_expected = !matches!(
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;
}
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;
}
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);
substs: trait_ref.substs,
item_def_id: obligation.predicate.item_def_id,
},
- ty,
+ term: ty.into(),
}
});
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
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)
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)
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!(
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;
}
}
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);
// 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)
{
{
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),
}
}
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),
}
}
}
.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,
})
.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)
}
//
// `<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,
));
// 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.
/// 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.
.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)
}
}
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);
// 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)
}
item_def_id: trait_ty.def_id,
substs: rebased_substs,
},
- ty: impl_ty_value,
+ term: impl_ty_value.into(),
},
bound_vars,
)
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);
// 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()
.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())
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))
})
}
if !relies_only_on_inputs {
continue;
}
- input_parameters.extend(parameters_for(&projection.ty, false));
+ input_parameters.extend(parameters_for(&projection.term, false));
} else {
continue;
}
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 {
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) }
}
}
.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)))
{
.ident
.name,
kind: TypeBindingKind::Equality {
- ty: proj.ty.clean(cx),
+ ty: proj.term.ty().clean(cx),
},
})
} else {
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(),
},
-Subproject commit 2abffbf977a9e8c6ca4174a08fe5c4d7781f0aac
+Subproject commit 6b3dbcc81a470e5da84576d63fcfc19e3b1154cd
const N: usize = 3;
}
+const TEST:usize = 3;
+
+
fn foo<F: Foo<N=3>>() {}
+fn bar<F: Foo<N={TEST}>>() {}
+
fn main() {}
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]
-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
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`.
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]
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
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`.
+// 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() {}
+++ /dev/null
-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
-
-Subproject commit 06b9d31743210b788b130c8a484c2838afa6fc27
+Subproject commit 358e79fe56fe374649275ca7aebaafd57ade0e8d
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};
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)
}
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;
}
}
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 {
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()));
}
}
-Subproject commit 0f8c96c92689af8378dbe9f466c6bf15a3a27458
+Subproject commit 8e9ccbf97a70259b6c6576e8fd7d77d28238737e